From e9ef08bdc189e98610bc4b9a6e6f19bc3793b2c8 Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Fri, 8 Dec 2006 16:06:01 -0800 Subject: [IA64] Itanium MC Error Injection Tool: Kernel configuration This patch has kenrel configuration changes for the MC Error Injection Tool. Signed-off-by: Fenghua Yu Signed-off-by: Tony Luck --- arch/ia64/Kconfig | 10 ++++++++++ arch/ia64/defconfig | 1 + 2 files changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index fcacfe291b9b..f1e7cc1389b0 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -429,6 +429,16 @@ config IA64_PALINFO To use this option, you have to ensure that the "/proc file system support" (CONFIG_PROC_FS) is enabled, too. +config IA64_MC_ERR_INJECT + tristate "MC error injection support" + help + Selets whether support for MC error injection. By enabling the + support, kernel provide sysfs interface for user application to + call MC error injection PAL procedure to inject various errors. + This is a useful tool for MCA testing. + + If you're unsure, do not select this option. + config SGI_SN def_bool y if (IA64_SGI_SN2 || IA64_GENERIC) diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig index 9001b3fbaa32..327e1f511f8c 100644 --- a/arch/ia64/defconfig +++ b/arch/ia64/defconfig @@ -144,6 +144,7 @@ CONFIG_COMPAT=y CONFIG_IA64_MCA_RECOVERY=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y +# CONFIG_MC_ERR_INJECT is not set CONFIG_SGI_SN=y # -- cgit v1.2.3-59-g8ed1b From 62fa562af36d32431ac8d7432b2c3ffbb7cf82df Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Fri, 8 Dec 2006 16:15:16 -0800 Subject: [IA64] Itanium MC Error Injection Tool: Driver sysfs interface This kernel driver patch provides sysfs interface for user application to call pal_mc_error_inject() procedure. Signed-off-by: Fenghua Yu Signed-off-by: Tony Luck --- arch/ia64/kernel/err_inject.c | 293 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 293 insertions(+) create mode 100644 arch/ia64/kernel/err_inject.c (limited to 'arch') diff --git a/arch/ia64/kernel/err_inject.c b/arch/ia64/kernel/err_inject.c new file mode 100644 index 000000000000..d3e9f33e8bdd --- /dev/null +++ b/arch/ia64/kernel/err_inject.c @@ -0,0 +1,293 @@ +/* + * err_inject.c - + * 1.) Inject errors to a processor. + * 2.) Query error injection capabilities. + * This driver along with user space code can be acting as an error + * injection tool. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Written by: Fenghua Yu , Intel Corporation + * Copyright (C) 2006, Intel Corp. All rights reserved. + * + */ +#include +#include +#include +#include +#include + +#define ERR_INJ_DEBUG + +#define ERR_DATA_BUFFER_SIZE 3 // Three 8-byte; + +#define define_one_ro(name) \ +static SYSDEV_ATTR(name, 0444, show_##name, NULL) + +#define define_one_rw(name) \ +static SYSDEV_ATTR(name, 0644, show_##name, store_##name) + +static u64 call_start[NR_CPUS]; +static u64 phys_addr[NR_CPUS]; +static u64 err_type_info[NR_CPUS]; +static u64 err_struct_info[NR_CPUS]; +static struct { + u64 data1; + u64 data2; + u64 data3; +} __attribute__((__aligned__(16))) err_data_buffer[NR_CPUS]; +static s64 status[NR_CPUS]; +static u64 capabilities[NR_CPUS]; +static u64 resources[NR_CPUS]; + +#define show(name) \ +static ssize_t \ +show_##name(struct sys_device *dev, char *buf) \ +{ \ + u32 cpu=dev->id; \ + return sprintf(buf, "%lx\n", name[cpu]); \ +} + +#define store(name) \ +static ssize_t \ +store_##name(struct sys_device *dev, const char *buf, size_t size) \ +{ \ + unsigned int cpu=dev->id; \ + name[cpu] = simple_strtoull(buf, NULL, 16); \ + return size; \ +} + +show(call_start) + +/* It's user's responsibility to call the PAL procedure on a specific + * processor. The cpu number in driver is only used for storing data. + */ +static ssize_t +store_call_start(struct sys_device *dev, const char *buf, size_t size) +{ + unsigned int cpu=dev->id; + unsigned long call_start = simple_strtoull(buf, NULL, 16); + +#ifdef ERR_INJ_DEBUG + printk(KERN_DEBUG "pal_mc_err_inject for cpu%d:\n", cpu); + printk(KERN_DEBUG "err_type_info=%lx,\n", err_type_info[cpu]); + printk(KERN_DEBUG "err_struct_info=%lx,\n", err_struct_info[cpu]); + printk(KERN_DEBUG "err_data_buffer=%lx, %lx, %lx.\n", + err_data_buffer[cpu].data1, + err_data_buffer[cpu].data2, + err_data_buffer[cpu].data3); +#endif + switch (call_start) { + case 0: /* Do nothing. */ + break; + case 1: /* Call pal_mc_error_inject in physical mode. */ + status[cpu]=ia64_pal_mc_error_inject_phys(err_type_info[cpu], + err_struct_info[cpu], + ia64_tpa(&err_data_buffer[cpu]), + &capabilities[cpu], + &resources[cpu]); + break; + case 2: /* Call pal_mc_error_inject in virtual mode. */ + status[cpu]=ia64_pal_mc_error_inject_virt(err_type_info[cpu], + err_struct_info[cpu], + ia64_tpa(&err_data_buffer[cpu]), + &capabilities[cpu], + &resources[cpu]); + break; + default: + status[cpu] = -EINVAL; + break; + } + +#ifdef ERR_INJ_DEBUG + printk(KERN_DEBUG "Returns: status=%d,\n", (int)status[cpu]); + printk(KERN_DEBUG "capapbilities=%lx,\n", capabilities[cpu]); + printk(KERN_DEBUG "resources=%lx\n", resources[cpu]); +#endif + return size; +} + +show(err_type_info) +store(err_type_info) + +static ssize_t +show_virtual_to_phys(struct sys_device *dev, char *buf) +{ + unsigned int cpu=dev->id; + return sprintf(buf, "%lx\n", phys_addr[cpu]); +} + +static ssize_t +store_virtual_to_phys(struct sys_device *dev, const char *buf, size_t size) +{ + unsigned int cpu=dev->id; + u64 virt_addr=simple_strtoull(buf, NULL, 16); + int ret; + + ret = get_user_pages(current, current->mm, virt_addr, + 1, VM_READ, 0, NULL, NULL); + if (ret<=0) { +#ifdef ERR_INJ_DEBUG + printk("Virtual address %lx is not existing.\n",virt_addr); +#endif + return -EINVAL; + } + + phys_addr[cpu] = ia64_tpa(virt_addr); + return size; +} + +show(err_struct_info) +store(err_struct_info) + +static ssize_t +show_err_data_buffer(struct sys_device *dev, char *buf) +{ + unsigned int cpu=dev->id; + + return sprintf(buf, "%lx, %lx, %lx\n", + err_data_buffer[cpu].data1, + err_data_buffer[cpu].data2, + err_data_buffer[cpu].data3); +} + +static ssize_t +store_err_data_buffer(struct sys_device *dev, const char *buf, size_t size) +{ + unsigned int cpu=dev->id; + int ret; + +#ifdef ERR_INJ_DEBUG + printk("write err_data_buffer=[%lx,%lx,%lx] on cpu%d\n", + err_data_buffer[cpu].data1, + err_data_buffer[cpu].data2, + err_data_buffer[cpu].data3, + cpu); +#endif + ret=sscanf(buf, "%lx, %lx, %lx", + &err_data_buffer[cpu].data1, + &err_data_buffer[cpu].data2, + &err_data_buffer[cpu].data3); + if (ret!=ERR_DATA_BUFFER_SIZE) + return -EINVAL; + + return size; +} + +show(status) +show(capabilities) +show(resources) + +define_one_rw(call_start); +define_one_rw(err_type_info); +define_one_rw(err_struct_info); +define_one_rw(err_data_buffer); +define_one_rw(virtual_to_phys); +define_one_ro(status); +define_one_ro(capabilities); +define_one_ro(resources); + +static struct attribute *default_attrs[] = { + &attr_call_start.attr, + &attr_virtual_to_phys.attr, + &attr_err_type_info.attr, + &attr_err_struct_info.attr, + &attr_err_data_buffer.attr, + &attr_status.attr, + &attr_capabilities.attr, + &attr_resources.attr, + NULL +}; + +static struct attribute_group err_inject_attr_group = { + .attrs = default_attrs, + .name = "err_inject" +}; +/* Add/Remove err_inject interface for CPU device */ +static int __cpuinit err_inject_add_dev(struct sys_device * sys_dev) +{ + return sysfs_create_group(&sys_dev->kobj, &err_inject_attr_group); +} + +static int __cpuinit err_inject_remove_dev(struct sys_device * sys_dev) +{ + sysfs_remove_group(&sys_dev->kobj, &err_inject_attr_group); + return 0; +} +static int __cpuinit err_inject_cpu_callback(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned long)hcpu; + struct sys_device *sys_dev; + + sys_dev = get_cpu_sysdev(cpu); + switch (action) { + case CPU_ONLINE: + err_inject_add_dev(sys_dev); + break; + case CPU_DEAD: + err_inject_remove_dev(sys_dev); + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block __cpuinitdata err_inject_cpu_notifier = +{ + .notifier_call = err_inject_cpu_callback, +}; + +static int __init +err_inject_init(void) +{ + int i; + +#ifdef ERR_INJ_DEBUG + printk(KERN_INFO "Enter error injection driver.\n"); +#endif + for_each_online_cpu(i) { + err_inject_cpu_callback(&err_inject_cpu_notifier, CPU_ONLINE, + (void *)(long)i); + } + + register_hotcpu_notifier(&err_inject_cpu_notifier); + + return 0; +} + +static void __exit +err_inject_exit(void) +{ + int i; + struct sys_device *sys_dev; + +#ifdef ERR_INJ_DEBUG + printk(KERN_INFO "Exit error injection driver.\n"); +#endif + for_each_online_cpu(i) { + sys_dev = get_cpu_sysdev(i); + sysfs_remove_group(&sys_dev->kobj, &err_inject_attr_group); + } + unregister_hotcpu_notifier(&err_inject_cpu_notifier); +} + +module_init(err_inject_init); +module_exit(err_inject_exit); + +MODULE_AUTHOR("Fenghua Yu "); +MODULE_DESCRIPTION("MC error injection kenrel sysfs interface"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-59-g8ed1b From 539d517ad10bbaac2c04e0ee22916a360c5bcc0d Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Fri, 8 Dec 2006 16:16:24 -0800 Subject: [IA64] Itanium MC Error Injection Tool: Makefile changes This patch has Makefile changes. Signed-off-by: Fenghua Yu Signed-off-by: Tony Luck --- arch/ia64/kernel/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 098ee605bf5e..33e5a598672d 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o obj-$(CONFIG_AUDIT) += audit.o obj-$(CONFIG_PCI_MSI) += msi_ia64.o mca_recovery-y += mca_drv.o mca_drv_asm.o +obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o obj-$(CONFIG_IA64_ESI) += esi.o ifneq ($(CONFIG_IA64_ESI),) -- cgit v1.2.3-59-g8ed1b From a0776ec8e97bf109e7d973d09fc3e1814eb32bfb Mon Sep 17 00:00:00 2001 From: "Chen, Kenneth W" Date: Fri, 13 Oct 2006 10:05:45 -0700 Subject: [IA64] remove per-cpu ia64_phys_stacked_size_p8 It's not efficient to use a per-cpu variable just to store how many physical stack register a cpu has. Ever since the incarnation of ia64 up till upcoming Montecito processor, that variable has "glued" to 96. Having a variable in memory means that the kernel is burning an extra cacheline access on every syscall and kernel exit path. Such "static" value is better served with the instruction patching utility exists today. Convert ia64_phys_stacked_size_p8 into dynamic insn patching. This also has a pleasant side effect of eliminating access to per-cpu area while psr.ic=0 in the kernel exit path. (fixable for per-cpu DTC work, but why bother?) There are some concerns with the default value that the instruc- tion encoded in the kernel image. It shouldn't be concerned. The reasons are: (1) cpu_init() is called at CPU initialization. In there, we find out physical stack register size from PAL and patch two instructions in kernel exit code. The code in question can not be executed before the patching is done. (2) current implementation stores zero in ia64_phys_stacked_size_p8, and that's what the current kernel exit path loads the value with. With the new code, it is equivalent that we store reg size 96 in ia64_phys_stacked_size_p8, thus creating a better safety net. Given (1) above can never fail, having (2) is just a bonus. All in all, this patch allow one less memory reference in the kernel exit path, thus reducing syscall and interrupt return latency; and avoid polluting potential useful data in the CPU cache. Signed-off-by: Ken Chen Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 7 ++----- arch/ia64/kernel/patch.c | 20 ++++++++++++++++++++ arch/ia64/kernel/setup.c | 7 +++++-- arch/ia64/kernel/vmlinux.lds.S | 7 +++++++ include/asm-ia64/asmmacro.h | 10 ++++++++++ include/asm-ia64/patch.h | 1 + include/asm-ia64/processor.h | 1 + include/asm-ia64/sections.h | 1 + 8 files changed, 47 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 15234ed3a341..ac4b304bea30 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -767,7 +767,7 @@ ENTRY(ia64_leave_syscall) ld8.fill r15=[r3] // M0|1 restore r15 mov b6=r18 // I0 restore b6 - addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A + LOAD_PHYS_STACK_REG_SIZE(r17) mov f9=f0 // F clear f9 (pKStk) br.cond.dpnt.many skip_rbs_switch // B @@ -775,7 +775,6 @@ ENTRY(ia64_leave_syscall) shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition cover // B add current frame into dirty partition & set cr.ifs ;; -(pUStk) ld4 r17=[r17] // M0|1 r17 = cpu_data->phys_stacked_size_p8 mov r19=ar.bsp // M2 get new backing store pointer mov f10=f0 // F clear f10 @@ -953,9 +952,7 @@ GLOBAL_ENTRY(ia64_leave_kernel) shr.u r18=r19,16 // get byte size of existing "dirty" partition ;; mov r16=ar.bsp // get existing backing store pointer - addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 - ;; - ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8 + LOAD_PHYS_STACK_REG_SIZE(r17) (pKStk) br.cond.dpnt skip_rbs_switch /* diff --git a/arch/ia64/kernel/patch.c b/arch/ia64/kernel/patch.c index bc11bb096f58..e796e29f8e15 100644 --- a/arch/ia64/kernel/patch.c +++ b/arch/ia64/kernel/patch.c @@ -195,3 +195,23 @@ ia64_patch_gate (void) ia64_patch_vtop(START(vtop), END(vtop)); ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9)); } + +void ia64_patch_phys_stack_reg(unsigned long val) +{ + s32 * offp = (s32 *) __start___phys_stack_reg_patchlist; + s32 * end = (s32 *) __end___phys_stack_reg_patchlist; + u64 ip, mask, imm; + + /* see instruction format A4: adds r1 = imm13, r3 */ + mask = (0x3fUL << 27) | (0x7f << 13); + imm = (((val >> 7) & 0x3f) << 27) | (val & 0x7f) << 13; + + while (offp < end) { + ip = (u64) offp + *offp; + ia64_patch(ip, mask, imm); + ia64_fc(ip); + ++offp; + } + ia64_sync_i(); + ia64_srlz_i(); +} diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index ad567b8d432e..f167b89f24eb 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -75,7 +75,6 @@ extern void ia64_setup_printk_clock(void); DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info); DEFINE_PER_CPU(unsigned long, local_per_cpu_offset); -DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8); unsigned long ia64_cycles_per_usec; struct ia64_boot_param *ia64_boot_param; struct screen_info screen_info; @@ -836,6 +835,7 @@ void __cpuinit cpu_init (void) { extern void __cpuinit ia64_mmu_init (void *); + static unsigned long max_num_phys_stacked = IA64_NUM_PHYS_STACK_REG; unsigned long num_phys_stacked; pal_vm_info_2_u_t vmi; unsigned int max_ctx; @@ -949,7 +949,10 @@ cpu_init (void) num_phys_stacked = 96; } /* size of physical stacked register partition plus 8 bytes: */ - __get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8; + if (num_phys_stacked > max_num_phys_stacked) { + ia64_patch_phys_stack_reg(num_phys_stacked*8 + 8); + max_num_phys_stacked = num_phys_stacked; + } platform_cpu_init(); pm_idle = default_idle; } diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index d6083a0936f4..d9599dcac787 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -78,6 +78,13 @@ SECTIONS __stop___mca_table = .; } + .data.patch.phys_stack_reg : AT(ADDR(.data.patch.phys_stack_reg) - LOAD_OFFSET) + { + __start___phys_stack_reg_patchlist = .; + *(.data.patch.phys_stack_reg) + __end___phys_stack_reg_patchlist = .; + } + /* Global data */ _data = .; diff --git a/include/asm-ia64/asmmacro.h b/include/asm-ia64/asmmacro.h index c22b4658fc61..c1642fd64029 100644 --- a/include/asm-ia64/asmmacro.h +++ b/include/asm-ia64/asmmacro.h @@ -103,6 +103,16 @@ name: # define FSYS_RETURN br.ret.sptk.many b6 #endif +/* + * If physical stack register size is different from DEF_NUM_STACK_REG, + * dynamically patch the kernel for correct size. + */ + .section ".data.patch.phys_stack_reg", "a" + .previous +#define LOAD_PHYS_STACK_REG_SIZE(reg) \ +[1:] adds reg=IA64_NUM_PHYS_STACK_REG*8+8,r0; \ + .xdata4 ".data.patch.phys_stack_reg", 1b-. + /* * Up until early 2004, use of .align within a function caused bad unwind info. * TEXT_ALIGN(n) expands into ".align n" if a fixed GAS is available or into nothing diff --git a/include/asm-ia64/patch.h b/include/asm-ia64/patch.h index 4797f3535e6d..a71543084fb4 100644 --- a/include/asm-ia64/patch.h +++ b/include/asm-ia64/patch.h @@ -20,6 +20,7 @@ extern void ia64_patch_imm60 (u64 insn_addr, u64 val); /* patch "brl" w/ip-rel extern void ia64_patch_mckinley_e9 (unsigned long start, unsigned long end); extern void ia64_patch_vtop (unsigned long start, unsigned long end); +extern void ia64_patch_phys_stack_reg(unsigned long val); extern void ia64_patch_gate (void); #endif /* _ASM_IA64_PATCH_H */ diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h index 5830d36fd8e6..88c728b9ff45 100644 --- a/include/asm-ia64/processor.h +++ b/include/asm-ia64/processor.h @@ -19,6 +19,7 @@ #include #include +#define IA64_NUM_PHYS_STACK_REG 96 #define IA64_NUM_DBG_REGS 8 #define DEFAULT_MAP_BASE __IA64_UL_CONST(0x2000000000000000) diff --git a/include/asm-ia64/sections.h b/include/asm-ia64/sections.h index e9eb7f62d32b..dc42a359894f 100644 --- a/include/asm-ia64/sections.h +++ b/include/asm-ia64/sections.h @@ -11,6 +11,7 @@ extern char __per_cpu_start[], __per_cpu_end[], __phys_per_cpu_start[]; extern char __start___vtop_patchlist[], __end___vtop_patchlist[]; extern char __start___mckinley_e9_bundles[], __end___mckinley_e9_bundles[]; +extern char __start___phys_stack_reg_patchlist[], __end___phys_stack_reg_patchlist[]; extern char __start_gate_section[]; extern char __start_gate_mckinley_e9_patchlist[], __end_gate_mckinley_e9_patchlist[]; extern char __start_gate_vtop_patchlist[], __end_gate_vtop_patchlist[]; -- cgit v1.2.3-59-g8ed1b From 00b65985fb2fc542b855b03fcda0d0f2bab4f442 Mon Sep 17 00:00:00 2001 From: "Chen, Kenneth W" Date: Fri, 13 Oct 2006 10:08:13 -0700 Subject: [IA64] relax per-cpu TLB requirement to DTC Instead of pinning per-cpu TLB into a DTR, use DTC. This will free up one TLB entry for application, or even kernel if access pattern to per-cpu data area has high temporal locality. Since per-cpu is mapped at the top of region 7 address, we just need to add special case in alt_dtlb_miss. The physical address of per-cpu data is already conveniently stored in IA64_KR(PER_CPU_DATA). Latency for alt_dtlb_miss is not affected as we can hide all the latency. It was measured that alt_dtlb_miss handler has 23 cycles latency before and after the patch. The performance effect is massive for applications that put lots of tlb pressure on CPU. Workload environment like database online transaction processing or application uses tera-byte of memory would benefit the most. Measurement with industry standard database benchmark shown an upward of 1.6% gain. While smaller workloads like cpu, java also showing small improvement. Signed-off-by: Ken Chen Signed-off-by: Tony Luck --- arch/ia64/kernel/ivt.S | 19 ++++++++++++++----- arch/ia64/kernel/mca_asm.S | 24 ------------------------ arch/ia64/mm/init.c | 11 +---------- include/asm-ia64/kregs.h | 3 +-- 4 files changed, 16 insertions(+), 41 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index 6b7fcbd3f6f1..34f44d8be00d 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -374,6 +374,7 @@ ENTRY(alt_dtlb_miss) movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) mov r21=cr.ipsr mov r31=pr + mov r24=PERCPU_ADDR ;; #ifdef CONFIG_DISABLE_VHPT shr.u r22=r16,61 // get the region number into r21 @@ -386,22 +387,30 @@ ENTRY(alt_dtlb_miss) (p8) mov r29=b0 // save b0 (p8) br.cond.dptk dtlb_fault #endif + cmp.ge p10,p11=r16,r24 // access to per_cpu_data? + tbit.z p12,p0=r16,61 // access to region 6? + mov r25=PERCPU_PAGE_SHIFT << 2 + mov r26=PERCPU_PAGE_SIZE + nop.m 0 + nop.b 0 + ;; +(p10) mov r19=IA64_KR(PER_CPU_DATA) +(p11) and r19=r19,r16 // clear non-ppn fields extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl and r22=IA64_ISR_CODE_MASK,r20 // get the isr.code field tbit.nz p6,p7=r20,IA64_ISR_SP_BIT // is speculation bit on? - shr.u r18=r16,57 // move address bit 61 to bit 4 - and r19=r19,r16 // clear ed, reserved bits, and PTE control bits tbit.nz p9,p0=r20,IA64_ISR_NA_BIT // is non-access bit on? ;; - andcm r18=0x10,r18 // bit 4=~address-bit(61) +(p10) sub r19=r19,r26 +(p10) mov cr.itir=r25 cmp.ne p8,p0=r0,r23 (p9) cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22 // check isr.code field +(p12) dep r17=-1,r17,4,1 // set ma=UC for region 6 addr (p8) br.cond.spnt page_fault dep r21=-1,r21,IA64_PSR_ED_BIT,1 - or r19=r19,r17 // insert PTE control bits into r19 ;; - or r19=r19,r18 // set bit 4 (uncached) if the access was to region 6 + or r19=r19,r17 // insert PTE control bits into r19 (p6) mov cr.ipsr=r21 ;; (p7) itc.d r19 // insert the TLB entry diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S index c6b607c00dee..8c9c26aa6ae0 100644 --- a/arch/ia64/kernel/mca_asm.S +++ b/arch/ia64/kernel/mca_asm.S @@ -101,14 +101,6 @@ ia64_do_tlb_purge: ;; srlz.d ;; - // 2. Purge DTR for PERCPU data. - movl r16=PERCPU_ADDR - mov r18=PERCPU_PAGE_SHIFT<<2 - ;; - ptr.d r16,r18 - ;; - srlz.d - ;; // 3. Purge ITR for PAL code. GET_THIS_PADDR(r2, ia64_mca_pal_base) ;; @@ -196,22 +188,6 @@ ia64_reload_tr: srlz.i srlz.d ;; - // 2. Reload DTR register for PERCPU data. - GET_THIS_PADDR(r2, ia64_mca_per_cpu_pte) - ;; - movl r16=PERCPU_ADDR // vaddr - movl r18=PERCPU_PAGE_SHIFT<<2 - ;; - mov cr.itir=r18 - mov cr.ifa=r16 - ;; - ld8 r18=[r2] // load per-CPU PTE - mov r16=IA64_TR_PERCPU_DATA; - ;; - itr.d dtr[r16]=r18 - ;; - srlz.d - ;; // 3. Reload ITR for PAL code. GET_THIS_PADDR(r2, ia64_mca_pal_pte) ;; diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 1373fae7657f..07d82cd7cbdd 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -337,7 +337,7 @@ setup_gate (void) void __devinit ia64_mmu_init (void *my_cpu_data) { - unsigned long psr, pta, impl_va_bits; + unsigned long pta, impl_va_bits; extern void __devinit tlb_init (void); #ifdef CONFIG_DISABLE_VHPT @@ -346,15 +346,6 @@ ia64_mmu_init (void *my_cpu_data) # define VHPT_ENABLE_BIT 1 #endif - /* Pin mapping for percpu area into TLB */ - psr = ia64_clear_ic(); - ia64_itr(0x2, IA64_TR_PERCPU_DATA, PERCPU_ADDR, - pte_val(pfn_pte(__pa(my_cpu_data) >> PAGE_SHIFT, PAGE_KERNEL)), - PERCPU_PAGE_SHIFT); - - ia64_set_psr(psr); - ia64_srlz_i(); - /* * Check if the virtually mapped linear page table (VMLPT) overlaps with a mapped * address space. The IA-64 architecture guarantees that at least 50 bits of diff --git a/include/asm-ia64/kregs.h b/include/asm-ia64/kregs.h index 221b5cb564b2..7e55a584975c 100644 --- a/include/asm-ia64/kregs.h +++ b/include/asm-ia64/kregs.h @@ -29,8 +29,7 @@ */ #define IA64_TR_KERNEL 0 /* itr0, dtr0: maps kernel image (code & data) */ #define IA64_TR_PALCODE 1 /* itr1: maps PALcode as required by EFI */ -#define IA64_TR_PERCPU_DATA 1 /* dtr1: percpu data */ -#define IA64_TR_CURRENT_STACK 2 /* dtr2: maps kernel's memory- & register-stacks */ +#define IA64_TR_CURRENT_STACK 1 /* dtr1: maps kernel's memory- & register-stacks */ /* Processor status register bits: */ #define IA64_PSR_BE_BIT 1 -- cgit v1.2.3-59-g8ed1b From c4add2e537e6f60048dce8dc518254e7e605301d Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 30 Mar 2007 10:33:11 -0600 Subject: [IA64] rename ioremap variables to match i386 No functional change, just use the same names as i386. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- arch/ia64/mm/ioremap.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c index 4280c074d64e..1bc0c172726f 100644 --- a/arch/ia64/mm/ioremap.c +++ b/arch/ia64/mm/ioremap.c @@ -14,13 +14,13 @@ #include static inline void __iomem * -__ioremap (unsigned long offset, unsigned long size) +__ioremap (unsigned long phys_addr, unsigned long size) { - return (void __iomem *) (__IA64_UNCACHED_OFFSET | offset); + return (void __iomem *) (__IA64_UNCACHED_OFFSET | phys_addr); } void __iomem * -ioremap (unsigned long offset, unsigned long size) +ioremap (unsigned long phys_addr, unsigned long size) { u64 attr; unsigned long gran_base, gran_size; @@ -30,31 +30,31 @@ ioremap (unsigned long offset, unsigned long size) * as the rest of the kernel. For more details, see * Documentation/ia64/aliasing.txt. */ - attr = kern_mem_attribute(offset, size); + attr = kern_mem_attribute(phys_addr, size); if (attr & EFI_MEMORY_WB) - return (void __iomem *) phys_to_virt(offset); + return (void __iomem *) phys_to_virt(phys_addr); else if (attr & EFI_MEMORY_UC) - return __ioremap(offset, size); + return __ioremap(phys_addr, size); /* * Some chipsets don't support UC access to memory. If * WB is supported for the whole granule, we prefer that. */ - gran_base = GRANULEROUNDDOWN(offset); - gran_size = GRANULEROUNDUP(offset + size) - gran_base; + gran_base = GRANULEROUNDDOWN(phys_addr); + gran_size = GRANULEROUNDUP(phys_addr + size) - gran_base; if (efi_mem_attribute(gran_base, gran_size) & EFI_MEMORY_WB) - return (void __iomem *) phys_to_virt(offset); + return (void __iomem *) phys_to_virt(phys_addr); - return __ioremap(offset, size); + return __ioremap(phys_addr, size); } EXPORT_SYMBOL(ioremap); void __iomem * -ioremap_nocache (unsigned long offset, unsigned long size) +ioremap_nocache (unsigned long phys_addr, unsigned long size) { - if (kern_mem_attribute(offset, size) & EFI_MEMORY_WB) + if (kern_mem_attribute(phys_addr, size) & EFI_MEMORY_WB) return NULL; - return __ioremap(offset, size); + return __ioremap(phys_addr, size); } EXPORT_SYMBOL(ioremap_nocache); -- cgit v1.2.3-59-g8ed1b From 9b50ffb0c0281bc5a08ccd56ae9bb84296c28f38 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 30 Mar 2007 10:34:05 -0600 Subject: [IA64] make ioremap avoid unsupported attributes Example memory map (from HP sx1000 with VGA enabled): 0x00000 - 0x9FFFF supports only WB (cacheable) access 0xA0000 - 0xBFFFF supports only UC (uncacheable) access 0xC0000 - 0xFFFFF supports only WB (cacheable) access pci_read_rom() indirectly uses ioremap(0xC0000) to read the shadow VGA option ROM. ioremap() used to default to a 16MB or 64MB UC kernel identity mapping, which would cause an MCA when reading 0xC0000 since only WB is supported there. X uses reads the option ROM to initialize devices. A smaller test case is: # echo 1 > /sys/bus/pci/devices/0000:aa:03.0/rom # cp /sys/bus/pci/devices/0000:aa:03.0/rom x To avoid this, we can use the same ioremap_page_range() strategy that most architectures use for all ioremaps. These page table mappings come out of the vmalloc area. On ia64, these are in region 5 (0xA... addresses) and typically use 16KB or 64KB mappings instead of 16MB or 64MB mappings. The smaller mappings give more flexibility to use the correct attributes. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- arch/ia64/mm/ioremap.c | 60 +++++++++++++++++++++++++++++++++++++++++++++----- include/asm-ia64/io.h | 6 +---- 2 files changed, 56 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c index 1bc0c172726f..2a140627dfd6 100644 --- a/arch/ia64/mm/ioremap.c +++ b/arch/ia64/mm/ioremap.c @@ -1,5 +1,5 @@ /* - * (c) Copyright 2006 Hewlett-Packard Development Company, L.P. + * (c) Copyright 2006, 2007 Hewlett-Packard Development Company, L.P. * Bjorn Helgaas * * This program is free software; you can redistribute it and/or modify @@ -10,11 +10,13 @@ #include #include #include +#include +#include #include #include static inline void __iomem * -__ioremap (unsigned long phys_addr, unsigned long size) +__ioremap (unsigned long phys_addr) { return (void __iomem *) (__IA64_UNCACHED_OFFSET | phys_addr); } @@ -22,8 +24,13 @@ __ioremap (unsigned long phys_addr, unsigned long size) void __iomem * ioremap (unsigned long phys_addr, unsigned long size) { + void __iomem *addr; + struct vm_struct *area; + unsigned long offset; + pgprot_t prot; u64 attr; unsigned long gran_base, gran_size; + unsigned long page_base; /* * For things in kern_memmap, we must use the same attribute @@ -34,7 +41,7 @@ ioremap (unsigned long phys_addr, unsigned long size) if (attr & EFI_MEMORY_WB) return (void __iomem *) phys_to_virt(phys_addr); else if (attr & EFI_MEMORY_UC) - return __ioremap(phys_addr, size); + return __ioremap(phys_addr); /* * Some chipsets don't support UC access to memory. If @@ -45,7 +52,42 @@ ioremap (unsigned long phys_addr, unsigned long size) if (efi_mem_attribute(gran_base, gran_size) & EFI_MEMORY_WB) return (void __iomem *) phys_to_virt(phys_addr); - return __ioremap(phys_addr, size); + /* + * WB is not supported for the whole granule, so we can't use + * the region 7 identity mapping. If we can safely cover the + * area with kernel page table mappings, we can use those + * instead. + */ + page_base = phys_addr & PAGE_MASK; + size = PAGE_ALIGN(phys_addr + size) - page_base; + if (efi_mem_attribute(page_base, size) & EFI_MEMORY_WB) { + prot = PAGE_KERNEL; + + /* + * Mappings have to be page-aligned + */ + offset = phys_addr & ~PAGE_MASK; + phys_addr &= PAGE_MASK; + + /* + * Ok, go for it.. + */ + area = get_vm_area(size, VM_IOREMAP); + if (!area) + return NULL; + + area->phys_addr = phys_addr; + addr = (void __iomem *) area->addr; + if (ioremap_page_range((unsigned long) addr, + (unsigned long) addr + size, phys_addr, prot)) { + vunmap((void __force *) addr); + return NULL; + } + + return (void __iomem *) (offset + (char __iomem *)addr); + } + + return __ioremap(phys_addr); } EXPORT_SYMBOL(ioremap); @@ -55,6 +97,14 @@ ioremap_nocache (unsigned long phys_addr, unsigned long size) if (kern_mem_attribute(phys_addr, size) & EFI_MEMORY_WB) return NULL; - return __ioremap(phys_addr, size); + return __ioremap(phys_addr); } EXPORT_SYMBOL(ioremap_nocache); + +void +iounmap (volatile void __iomem *addr) +{ + if (REGION_NUMBER(addr) == RGN_GATE) + vunmap((void *) ((unsigned long) addr & PAGE_MASK)); +} +EXPORT_SYMBOL(iounmap); diff --git a/include/asm-ia64/io.h b/include/asm-ia64/io.h index 6311e168cd34..eb17a8692967 100644 --- a/include/asm-ia64/io.h +++ b/include/asm-ia64/io.h @@ -421,11 +421,7 @@ __writeq (unsigned long val, volatile void __iomem *addr) extern void __iomem * ioremap(unsigned long offset, unsigned long size); extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size); - -static inline void -iounmap (volatile void __iomem *addr) -{ -} +extern void iounmap (volatile void __iomem *addr); /* Use normal IO mappings for DMI */ #define dmi_ioremap ioremap -- cgit v1.2.3-59-g8ed1b From 2cb22e23a5fcbcac2de49493aa57c7694028a06a Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 30 Mar 2007 10:34:44 -0600 Subject: [IA64] allow WB /sys/.../legacy_mem mmaps Allow cacheable mmaps of legacy_mem if WB access is supported for the region. The "legacy_mem" file often contains a shadow option ROM, and some versions of X depend on this. Tim Yamin reported that this change fixes X on a Dell PowerEdge 3250. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- arch/ia64/pci/pci.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 0e83f3b419b5..9f635896d252 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -659,8 +659,6 @@ pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma) return -EINVAL; prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size, vma->vm_page_prot); - if (pgprot_val(prot) != pgprot_val(pgprot_noncached(vma->vm_page_prot))) - return -EINVAL; addr = pci_get_legacy_mem(bus); if (IS_ERR(addr)) -- cgit v1.2.3-59-g8ed1b From 6d40fc514c9ea886dc18ddd20043a411816b63d1 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 30 Mar 2007 10:35:43 -0600 Subject: [IA64] fail mmaps that span areas with incompatible attributes Example memory map (from HP sx1000 with VGA enabled): 0x00000 - 0x9FFFF supports only WB (cacheable) access 0xA0000 - 0xBFFFF supports only UC (uncacheable) access 0xC0000 - 0xFFFFF supports only WB (cacheable) access Some versions of X map the entire 0x00000-0xFFFFF area at once. With the example above, this mmap must fail because there's no memory attribute that's safe for the entire area. Prior to this patch, we performed the mmap with a UC mapping. When X accessed the WB memory at 0xC0000, it caused an MCA. The crash can happen when mapping 0xC0000 from either /dev/mem or a /sys/.../legacy_mem file. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- arch/ia64/kernel/efi.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index f45f91d38cab..78d29b79947d 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -660,6 +660,29 @@ efi_memory_descriptor (unsigned long phys_addr) return NULL; } +static int +efi_memmap_intersects (unsigned long phys_addr, unsigned long size) +{ + void *efi_map_start, *efi_map_end, *p; + efi_memory_desc_t *md; + u64 efi_desc_size; + unsigned long end; + + efi_map_start = __va(ia64_boot_param->efi_memmap); + efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; + efi_desc_size = ia64_boot_param->efi_memdesc_size; + + end = phys_addr + size; + + for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { + md = p; + + if (md->phys_addr < end && efi_md_end(md) > phys_addr) + return 1; + } + return 0; +} + u32 efi_mem_type (unsigned long phys_addr) { @@ -766,11 +789,28 @@ valid_phys_addr_range (unsigned long phys_addr, unsigned long size) int valid_mmap_phys_addr_range (unsigned long pfn, unsigned long size) { + unsigned long phys_addr = pfn << PAGE_SHIFT; + u64 attr; + + attr = efi_mem_attribute(phys_addr, size); + /* - * MMIO regions are often missing from the EFI memory map. - * We must allow mmap of them for programs like X, so we - * currently can't do any useful validation. + * /dev/mem mmap uses normal user pages, so we don't need the entire + * granule, but the entire region we're mapping must support the same + * attribute. */ + if (attr & EFI_MEMORY_WB || attr & EFI_MEMORY_UC) + return 1; + + /* + * Intel firmware doesn't tell us about all the MMIO regions, so + * in general we have to allow mmap requests. But if EFI *does* + * tell us about anything inside this region, we should deny it. + * The user can always map a smaller region to avoid the overlap. + */ + if (efi_memmap_intersects(phys_addr, size)) + return 0; + return 1; } -- cgit v1.2.3-59-g8ed1b From d0a0515fc30b55d4b09395d44762c5f41d6d02d5 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:36:12 -0400 Subject: Input: cobalt buttons - separate device and driver registration Create platform device for cobalt buttons as part of arch setup. This makes the driver follow current driver model more closely. Signed-off-by: Dmitry Torokhov Acked-by: Yoichi Yuasa --- arch/mips/cobalt/Makefile | 2 +- arch/mips/cobalt/buttons.c | 54 ++++++++++++++++++++++++++++++++++++++++ drivers/input/misc/cobalt_btns.c | 24 +----------------- 3 files changed, 56 insertions(+), 24 deletions(-) create mode 100644 arch/mips/cobalt/buttons.c (limited to 'arch') diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile index 225ac8f34ccd..c35ee25e5578 100644 --- a/arch/mips/cobalt/Makefile +++ b/arch/mips/cobalt/Makefile @@ -2,7 +2,7 @@ # Makefile for the Cobalt micro systems family specific parts of the kernel # -obj-y := irq.o reset.o setup.o +obj-y := irq.o reset.o setup.o buttons.o obj-$(CONFIG_EARLY_PRINTK) += console.o diff --git a/arch/mips/cobalt/buttons.c b/arch/mips/cobalt/buttons.c new file mode 100644 index 000000000000..9e143989c7b8 --- /dev/null +++ b/arch/mips/cobalt/buttons.c @@ -0,0 +1,54 @@ +/* + * Cobalt buttons platform device. + * + * Copyright (C) 2007 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +static struct resource cobalt_buttons_resource __initdata = { + .start = 0x1d000000, + .end = 0x1d000003, + .flags = IORESOURCE_MEM, +}; + +static __init int cobalt_add_buttons(void) +{ + struct platform_device *pd; + int error; + + pd = platform_device_alloc("Cobalt buttons", -1); + if (!pd) + return -ENOMEM; + + error = platform_device_add_resources(pd, &cobalt_buttons_resource, 1); + if (error) + goto err_free_device; + + error = platform_device_add(pd); + if (error) + goto err_free_device; + + return 0; + + err_free_device: + platform_device_put(pd); + return error; +} +device_initcall(cobalt_add_buttons); diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c index b14f49e768cc..b9b2d7764e73 100644 --- a/drivers/input/misc/cobalt_btns.c +++ b/drivers/input/misc/cobalt_btns.c @@ -50,14 +50,6 @@ static struct buttons_map buttons_map[] = { { 0x80000000, KEY_SELECT, }, }; -static struct resource cobalt_buttons_resource __initdata = { - .start = 0x1d000000, - .end = 0x1d000003, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device *cobalt_buttons_device; - static struct timer_list buttons_timer; static void handle_buttons(unsigned long data) @@ -183,26 +175,12 @@ static struct platform_driver cobalt_buttons_driver = { static int __init cobalt_buttons_init(void) { - int retval; - - cobalt_buttons_device = platform_device_register_simple("Cobalt buttons", -1, - &cobalt_buttons_resource, 1); - if (IS_ERR(cobalt_buttons_device)) { - retval = PTR_ERR(cobalt_buttons_device); - return retval; - } - - retval = platform_driver_register(&cobalt_buttons_driver); - if (retval < 0) - platform_device_unregister(cobalt_buttons_device); - - return retval; + return platform_driver_register(&cobalt_buttons_driver); } static void __exit cobalt_buttons_exit(void) { platform_driver_unregister(&cobalt_buttons_driver); - platform_device_unregister(cobalt_buttons_device); } module_init(cobalt_buttons_init); -- cgit v1.2.3-59-g8ed1b From 7ab3f8d595a1b1e5cf8d726b72fd476fe0d0226c Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 2 Mar 2007 15:01:36 +0000 Subject: [ARM] Add ability to dump exception stacks to kernel backtraces Signed-off-by: Russell King --- arch/arm/kernel/irq.c | 2 +- arch/arm/kernel/traps.c | 18 ++++- arch/arm/kernel/vmlinux.lds.S | 3 + arch/arm/lib/backtrace.S | 165 +++++++++++++++++++++--------------------- arch/arm/mm/fault.c | 4 +- include/asm-arm/system.h | 2 + 6 files changed, 105 insertions(+), 89 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index e101846ab7dd..a72b82e727f1 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -109,7 +109,7 @@ static struct irq_desc bad_irq_desc = { * come via this function. Instead, they should provide their * own 'handler' */ -asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) +asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); struct irq_desc *desc = irq_desc + irq; diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 24095601359b..ba1c1884e68e 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -45,7 +45,18 @@ static int __init user_debug_setup(char *str) __setup("user_debug=", user_debug_setup); #endif -void dump_backtrace_entry(unsigned long where, unsigned long from) +static void dump_mem(const char *str, unsigned long bottom, unsigned long top); + +static inline int in_exception_text(unsigned long ptr) +{ + extern char __exception_text_start[]; + extern char __exception_text_end[]; + + return ptr >= (unsigned long)&__exception_text_start && + ptr < (unsigned long)&__exception_text_end; +} + +void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) { #ifdef CONFIG_KALLSYMS printk("[<%08lx>] ", where); @@ -55,6 +66,9 @@ void dump_backtrace_entry(unsigned long where, unsigned long from) #else printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); #endif + + if (in_exception_text(where)) + dump_mem("Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs)); } /* @@ -266,7 +280,7 @@ void unregister_undef_hook(struct undef_hook *hook) spin_unlock_irqrestore(&undef_lock, flags); } -asmlinkage void do_undefinstr(struct pt_regs *regs) +asmlinkage void __exception do_undefinstr(struct pt_regs *regs) { unsigned int correction = thumb_mode(regs) ? 2 : 4; unsigned int instr; diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index ddbdad48f5b2..b295f6a85cf1 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -83,6 +83,9 @@ SECTIONS .text : { /* Real text segment */ _text = .; /* Text and read-only data */ + __exception_text_start = .; + *(.exception.text) + __exception_text_end = .; *(.text) SCHED_TEXT LOCK_TEXT diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S index 74230083cbf4..84dc890d2bf3 100644 --- a/arch/arm/lib/backtrace.S +++ b/arch/arm/lib/backtrace.S @@ -17,8 +17,8 @@ @ fp is 0 or stack frame #define frame r4 -#define next r5 -#define save r6 +#define sv_fp r5 +#define sv_pc r6 #define mask r7 #define offset r8 @@ -31,108 +31,106 @@ ENTRY(c_backtrace) #if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK) mov pc, lr #else - stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location... - tst r1, #0x10 @ 26 or 32-bit? - moveq mask, #0xfc000003 - movne mask, #0 - tst mask, r0 - movne r0, #0 - movs frame, r0 -1: moveq r0, #-2 - ldmeqfd sp!, {r4 - r8, pc} - -2: stmfd sp!, {pc} @ calculate offset of PC in STMIA instruction - ldr r0, [sp], #4 - adr r1, 2b - 4 + movs frame, r0 @ if frame pointer is zero + beq no_frame @ we have no stack frames + + tst r1, #0x10 @ 26 or 32-bit mode? + moveq mask, #0xfc000003 @ mask for 26-bit + movne mask, #0 @ mask for 32-bit + +1: stmfd sp!, {pc} @ calculate offset of PC stored + ldr r0, [sp], #4 @ by stmfd for this CPU + adr r1, 1b sub offset, r0, r1 -3: tst frame, mask @ Check for address exceptions... - bne 1b +/* + * Stack frame layout: + * optionally saved caller registers (r4 - r10) + * saved fp + * saved sp + * saved lr + * frame => saved pc + * optionally saved arguments (r0 - r3) + * saved sp => + * + * Functions start with the following code sequence: + * mov ip, sp + * stmfd sp!, {r0 - r3} (optional) + * corrected pc => stmfd sp!, {..., fp, ip, lr, pc} + */ +for_each_frame: tst frame, mask @ Check for address exceptions + bne no_frame + +1001: ldr sv_pc, [frame, #0] @ get saved pc +1002: ldr sv_fp, [frame, #-12] @ get saved fp -1001: ldr next, [frame, #-12] @ get fp -1002: ldr r2, [frame, #-4] @ get lr -1003: ldr r3, [frame, #0] @ get pc - sub save, r3, offset @ Correct PC for prefetching - bic save, save, mask -1004: ldr r1, [save, #0] @ get instruction at function - mov r1, r1, lsr #10 - ldr r3, .Ldsi+4 - teq r1, r3 - subeq save, save, #4 - mov r0, save - bic r1, r2, mask + sub sv_pc, sv_pc, offset @ Correct PC for prefetching + bic sv_pc, sv_pc, mask @ mask PC/LR for the mode + +1003: ldr r2, [sv_pc, #-4] @ if stmfd sp!, {args} exists, + ldr r3, .Ldsi+4 @ adjust saved 'pc' back one + teq r3, r2, lsr #10 @ instruction + subne r0, sv_pc, #4 @ allow for mov + subeq r0, sv_pc, #8 @ allow for mov + stmia + + ldr r1, [frame, #-4] @ get saved lr + mov r2, frame + bic r1, r1, mask @ mask PC/LR for the mode bl dump_backtrace_entry - ldr r0, [frame, #-8] @ get sp - sub r0, r0, #4 -1005: ldr r1, [save, #4] @ get instruction at function+4 - mov r3, r1, lsr #10 - ldr r2, .Ldsi+4 - teq r3, r2 @ Check for stmia sp!, {args} - addeq save, save, #4 @ next instruction - bleq .Ldumpstm - - sub r0, frame, #16 -1006: ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction - mov r3, r1, lsr #10 - ldr r2, .Ldsi - teq r3, r2 - bleq .Ldumpstm - - /* - * A zero next framepointer means we're done. - */ - teq next, #0 - ldmeqfd sp!, {r4 - r8, pc} - - /* - * The next framepointer must be above the - * current framepointer. - */ - cmp next, frame - mov frame, next - bhi 3b - b 1007f + ldr r1, [sv_pc, #-4] @ if stmfd sp!, {args} exists, + ldr r3, .Ldsi+4 + teq r3, r1, lsr #10 + ldreq r0, [frame, #-8] @ get sp + subeq r0, r0, #4 @ point at the last arg + bleq .Ldumpstm @ dump saved registers -/* - * Fixup for LDMDB. Note that this must not be in the fixup section. - */ -1007: ldr r0, =.Lbad +1004: ldr r1, [sv_pc, #0] @ if stmfd sp!, {..., fp, ip, lr, pc} + ldr r3, .Ldsi @ instruction exists, + teq r3, r1, lsr #10 + subeq r0, frame, #16 + bleq .Ldumpstm @ dump saved registers + + teq sv_fp, #0 @ zero saved fp means + beq no_frame @ no further frames + + cmp sv_fp, frame @ next frame must be + mov frame, sv_fp @ above the current frame + bhi for_each_frame + +1006: adr r0, .Lbad mov r1, frame bl printk - ldmfd sp!, {r4 - r8, pc} - .ltorg +no_frame: ldmfd sp!, {r4 - r8, pc} .section __ex_table,"a" .align 3 - .long 1001b, 1007b - .long 1002b, 1007b - .long 1003b, 1007b - .long 1004b, 1007b - .long 1005b, 1007b - .long 1006b, 1007b + .long 1001b, 1006b + .long 1002b, 1006b + .long 1003b, 1006b + .long 1004b, 1006b .previous #define instr r4 #define reg r5 #define stack r6 -.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, r8, lr} +.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr} mov stack, r0 mov instr, r1 - mov reg, #9 + mov reg, #10 mov r7, #0 1: mov r3, #1 tst instr, r3, lsl reg beq 2f add r7, r7, #1 - teq r7, #4 - moveq r7, #0 - moveq r3, #'\n' - movne r3, #' ' - ldr r2, [stack], #-4 - mov r1, reg + teq r7, #6 + moveq r7, #1 + moveq r1, #'\n' + movne r1, #' ' + ldr r3, [stack], #-4 + mov r2, reg adr r0, .Lfp bl printk 2: subs reg, reg, #1 @@ -140,14 +138,13 @@ ENTRY(c_backtrace) teq r7, #0 adrne r0, .Lcr blne printk - mov r0, stack - ldmfd sp!, {instr, reg, stack, r7, r8, pc} + ldmfd sp!, {instr, reg, stack, r7, pc} -.Lfp: .asciz " r%d = %08X%c" +.Lfp: .asciz "%cr%d:%08x" .Lcr: .asciz "\n" .Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n" .align -.Ldsi: .word 0x00e92dd8 >> 2 - .word 0x00e92d00 >> 2 +.Ldsi: .word 0xe92dd800 >> 10 @ stmfd sp!, {... fp, ip, lr, pc} + .word 0xe92d0000 >> 10 @ stmfd sp!, {} #endif diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 9fd6d2eafb40..fa2d107f0d44 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -438,7 +438,7 @@ hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *) /* * Dispatch a data abort to the relevant handler. */ -asmlinkage void +asmlinkage void __exception do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6); @@ -457,7 +457,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) notify_die("", regs, &info, fsr, 0); } -asmlinkage void +asmlinkage void __exception do_PrefetchAbort(unsigned long addr, struct pt_regs *regs) { do_translation_fault(addr, 0, regs); diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index 69134c7518c1..63b3080bdac4 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -76,6 +76,8 @@ #include #include +#define __exception __attribute__((section(".exception.text"))) + struct thread_info; struct task_struct; -- cgit v1.2.3-59-g8ed1b From 27350afdfc94a78adbdee20bb00f6058a0ef1eab Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 3 Mar 2007 11:51:31 +0000 Subject: [ARM] EBSA110: Add readsw/readsl/writesw/writesl Signed-off-by: Russell King --- arch/arm/mach-ebsa110/io.c | 40 +++++++++++++++++++++++++++++++++++++++ include/asm-arm/arch-ebsa110/io.h | 8 ++++++++ 2 files changed, 48 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c index db38afb2aa88..bbf0d332407e 100644 --- a/arch/arm/mach-ebsa110/io.c +++ b/arch/arm/mach-ebsa110/io.c @@ -102,6 +102,26 @@ EXPORT_SYMBOL(__readb); EXPORT_SYMBOL(__readw); EXPORT_SYMBOL(__readl); +void readsw(void __iomem *addr, void *data, int len) +{ + void __iomem *a = __isamem_convert_addr(addr); + + BUG_ON((unsigned long)addr & 1); + + __raw_readsw(a, data, len); +} +EXPORT_SYMBOL(readsw); + +void readsl(void __iomem *addr, void *data, int len) +{ + void __iomem *a = __isamem_convert_addr(addr); + + BUG_ON((unsigned long)addr & 3); + + __raw_readsl(a, data, len); +} +EXPORT_SYMBOL(readsl); + void __writeb(u8 val, void __iomem *addr) { void __iomem *a = __isamem_convert_addr(addr); @@ -137,6 +157,26 @@ EXPORT_SYMBOL(__writeb); EXPORT_SYMBOL(__writew); EXPORT_SYMBOL(__writel); +void writesw(void __iomem *addr, void *data, int len) +{ + void __iomem *a = __isamem_convert_addr(addr); + + BUG_ON((unsigned long)addr & 1); + + __raw_writesw(a, data, len); +} +EXPORT_SYMBOL(writesw); + +void writesl(void __iomem *addr, void *data, int len) +{ + void __iomem *a = __isamem_convert_addr(addr); + + BUG_ON((unsigned long)addr & 3); + + __raw_writesl(a, data, len); +} +EXPORT_SYMBOL(writesl); + #define SUPERIO_PORT(p) \ (((p) >> 3) == (0x3f8 >> 3) || \ ((p) >> 3) == (0x2f8 >> 3) || \ diff --git a/include/asm-arm/arch-ebsa110/io.h b/include/asm-arm/arch-ebsa110/io.h index 722c5e086285..44a4001de807 100644 --- a/include/asm-arm/arch-ebsa110/io.h +++ b/include/asm-arm/arch-ebsa110/io.h @@ -81,4 +81,12 @@ extern void outsb(unsigned int port, const void *buf, int sz); extern void outsw(unsigned int port, const void *buf, int sz); extern void outsl(unsigned int port, const void *buf, int sz); +/* can't support writesb atm */ +extern void writesw(void __iomem *addr, const void *data, int wordlen); +extern void writesl(void __iomem *addr, const void *data, int longlen); + +/* can't support readsb atm */ +extern void readsw(const void __iomem *addr, void *data, int wordlen); +extern void readsl(const void __iomem *addr, void *data, int longlen); + #endif -- cgit v1.2.3-59-g8ed1b From 0f0a00beb80624a446ba7c0152cd171008eeab2e Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 3 Mar 2007 19:45:25 +0000 Subject: [ARM] Remove needless linux/ptrace.h includes Lots of places in arch/arm were needlessly including linux/ptrace.h, resumably because we used to pass a struct pt_regs to interrupt handlers. Now that we don't, all these ptrace.h includes are redundant. Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 1 - arch/arm/common/via82c505.c | 1 - arch/arm/kernel/irq.c | 1 - arch/arm/kernel/process.c | 1 - arch/arm/kernel/traps.c | 1 - arch/arm/mach-footbridge/dc21285.c | 1 - arch/arm/mach-integrator/pci.c | 1 - arch/arm/mach-integrator/pci_v3.c | 1 - arch/arm/mach-lh7a40x/irq-lh7a400.c | 1 - arch/arm/mach-lh7a40x/irq-lh7a404.c | 1 - arch/arm/mach-lh7a40x/irq-lpd7a40x.c | 1 - arch/arm/mach-omap1/irq.c | 1 - arch/arm/mach-pxa/irq.c | 1 - arch/arm/mach-s3c2410/bast-irq.c | 1 - arch/arm/mach-s3c2410/irq.c | 1 - arch/arm/mach-s3c2412/irq.c | 1 - arch/arm/mach-s3c2440/irq.c | 1 - arch/arm/mach-s3c2443/irq.c | 1 - arch/arm/mach-sa1100/irq.c | 1 - arch/arm/mach-sa1100/neponset.c | 1 - arch/arm/mach-shark/irq.c | 1 - arch/arm/mach-versatile/pci.c | 1 - arch/arm/mm/alignment.c | 1 - arch/arm/mm/fault.c | 1 - arch/arm/mm/init.c | 1 - arch/arm/plat-omap/gpio.c | 1 - arch/arm/plat-s3c24xx/irq.c | 1 - arch/arm/plat-s3c24xx/s3c244x-irq.c | 1 - 28 files changed, 28 deletions(-) (limited to 'arch') diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index fe3f05901a23..798bbfccafb7 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/common/via82c505.c b/arch/arm/common/via82c505.c index ba2e62986a57..79a8206e62ac 100644 --- a/arch/arm/common/via82c505.c +++ b/arch/arm/common/via82c505.c @@ -1,6 +1,5 @@ #include #include -#include #include #include #include diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index a72b82e727f1..11dcd52e51be 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 782af3cb213f..8afd83d0cbdd 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index ba1c1884e68e..6055ab4b58d9 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c index 1463330ed8ee..d0dc51e81338 100644 --- a/arch/arm/mach-footbridge/dc21285.c +++ b/arch/arm/mach-footbridge/dc21285.c @@ -10,7 +10,6 @@ */ #include #include -#include #include #include #include diff --git a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c index 394ec9261c4e..af7d3ff013ec 100644 --- a/arch/arm/mach-integrator/pci.c +++ b/arch/arm/mach-integrator/pci.c @@ -23,7 +23,6 @@ */ #include #include -#include #include #include diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index fb8c6d97b22b..af9ebccac7c1 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -22,7 +22,6 @@ */ #include #include -#include #include #include #include diff --git a/arch/arm/mach-lh7a40x/irq-lh7a400.c b/arch/arm/mach-lh7a40x/irq-lh7a400.c index 0b938e8b4d98..9472bbebd8ab 100644 --- a/arch/arm/mach-lh7a40x/irq-lh7a400.c +++ b/arch/arm/mach-lh7a40x/irq-lh7a400.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-lh7a40x/irq-lh7a404.c b/arch/arm/mach-lh7a40x/irq-lh7a404.c index 5760f8c53e89..9b28389035e6 100644 --- a/arch/arm/mach-lh7a40x/irq-lh7a404.c +++ b/arch/arm/mach-lh7a40x/irq-lh7a404.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c index 15b9577023c9..66e1ed3961ea 100644 --- a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c +++ b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c index 410d3e78dd0f..0733078940fa 100644 --- a/arch/arm/mach-omap1/irq.c +++ b/arch/arm/mach-omap1/irq.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index f815678a9d63..9f7499b6d435 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c index daeba427d781..76a7cb15f3be 100644 --- a/arch/arm/mach-s3c2410/bast-irq.c +++ b/arch/arm/mach-s3c2410/bast-irq.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index 53cbdaa43ac6..f5c5c53e1cc1 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c index e89dbdcb1b7b..f0d66828f965 100644 --- a/arch/arm/mach-s3c2412/irq.c +++ b/arch/arm/mach-s3c2412/irq.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-s3c2440/irq.c b/arch/arm/mach-s3c2440/irq.c index 1069d13d8c57..a87608bc1a03 100644 --- a/arch/arm/mach-s3c2440/irq.c +++ b/arch/arm/mach-s3c2440/irq.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c index 756573595b88..6cd4818f3f0d 100644 --- a/arch/arm/mach-s3c2443/irq.c +++ b/arch/arm/mach-s3c2443/irq.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c index 5642aeca079e..edf3347d9c5b 100644 --- a/arch/arm/mach-sa1100/irq.c +++ b/arch/arm/mach-sa1100/irq.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 075d4d1d63be..d7c038a0256b 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -4,7 +4,6 @@ */ #include #include -#include #include #include #include diff --git a/arch/arm/mach-shark/irq.c b/arch/arm/mach-shark/irq.c index 00a6c1466867..5b0c6af44ec6 100644 --- a/arch/arm/mach-shark/irq.c +++ b/arch/arm/mach-shark/irq.c @@ -10,7 +10,6 @@ #include #include -#include #include #include diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c index 5cd0b5d9e7eb..ba58223f12be 100644 --- a/arch/arm/mach-versatile/pci.c +++ b/arch/arm/mach-versatile/pci.c @@ -16,7 +16,6 @@ */ #include #include -#include #include #include #include diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index aa109f074dd9..19ca333240ec 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index fa2d107f0d44..5d9ce7deb4a7 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -10,7 +10,6 @@ */ #include #include -#include #include #include diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 7760193e74cc..c0ad7c0fbae0 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -9,7 +9,6 @@ */ #include #include -#include #include #include #include diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index b8c01de208b4..8bedc8f9b6e5 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c index ce186398e3fd..8fbc88470261 100644 --- a/arch/arm/plat-s3c24xx/irq.c +++ b/arch/arm/plat-s3c24xx/irq.c @@ -54,7 +54,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/plat-s3c24xx/s3c244x-irq.c b/arch/arm/plat-s3c24xx/s3c244x-irq.c index a0e39d894014..2dbb2606d448 100644 --- a/arch/arm/plat-s3c24xx/s3c244x-irq.c +++ b/arch/arm/plat-s3c24xx/s3c244x-irq.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3-59-g8ed1b From b2a0d36fde90fa9dd20b7dde21dbcff09b130b38 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 4 Mar 2007 09:50:28 +0000 Subject: [ARM] ptrace: clean up single stepping support Signed-off-by: Russell King --- arch/arm/kernel/ptrace.c | 15 ++++----------- arch/arm/kernel/ptrace.h | 39 +++++++++++++++++++++++++++++++++++++++ arch/arm/kernel/signal.c | 22 +++++----------------- 3 files changed, 48 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 9254ba2f46fc..e594b84cca83 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -457,13 +457,10 @@ void ptrace_cancel_bpt(struct task_struct *child) /* * Called by kernel/ptrace.c when detaching.. - * - * Make sure the single step bit is not set. */ void ptrace_disable(struct task_struct *child) { - child->ptrace &= ~PT_SINGLESTEP; - ptrace_cancel_bpt(child); + single_step_disable(child); } /* @@ -712,9 +709,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) else clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); child->exit_code = data; - /* make sure single-step breakpoint is gone. */ - child->ptrace &= ~PT_SINGLESTEP; - ptrace_cancel_bpt(child); + single_step_disable(child); wake_up_process(child); ret = 0; break; @@ -725,9 +720,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) * exit. */ case PTRACE_KILL: - /* make sure single-step breakpoint is gone. */ - child->ptrace &= ~PT_SINGLESTEP; - ptrace_cancel_bpt(child); + single_step_disable(child); if (child->exit_state != EXIT_ZOMBIE) { child->exit_code = SIGKILL; wake_up_process(child); @@ -742,7 +735,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = -EIO; if (!valid_signal(data)) break; - child->ptrace |= PT_SINGLESTEP; + single_step_enable(child); clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); child->exit_code = data; /* give it a chance to run. */ diff --git a/arch/arm/kernel/ptrace.h b/arch/arm/kernel/ptrace.h index f7cad13a22e9..def3b6184a79 100644 --- a/arch/arm/kernel/ptrace.h +++ b/arch/arm/kernel/ptrace.h @@ -7,6 +7,45 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include + extern void ptrace_cancel_bpt(struct task_struct *); extern void ptrace_set_bpt(struct task_struct *); extern void ptrace_break(struct task_struct *, struct pt_regs *); + +/* + * make sure single-step breakpoint is gone. + */ +static inline void single_step_disable(struct task_struct *task) +{ + task->ptrace &= ~PT_SINGLESTEP; + ptrace_cancel_bpt(task); +} + +static inline void single_step_enable(struct task_struct *task) +{ + task->ptrace |= PT_SINGLESTEP; +} + +/* + * Send SIGTRAP if we're single-stepping + */ +static inline void single_step_trap(struct task_struct *task) +{ + if (task->ptrace & PT_SINGLESTEP) { + ptrace_cancel_bpt(task); + send_sig(SIGTRAP, task, 1); + } +} + +static inline void single_step_clear(struct task_struct *task) +{ + if (task->ptrace & PT_SINGLESTEP) + ptrace_cancel_bpt(task); +} + +static inline void single_step_set(struct task_struct *task) +{ + if (task->ptrace & PT_SINGLESTEP) + ptrace_set_bpt(task); +} diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 3843d3bab2dd..54cdf1aeefc3 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -9,7 +9,6 @@ */ #include #include -#include #include #include @@ -285,11 +284,7 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs) if (restore_sigframe(regs, frame)) goto badframe; - /* Send SIGTRAP if we're single-stepping */ - if (current->ptrace & PT_SINGLESTEP) { - ptrace_cancel_bpt(current); - send_sig(SIGTRAP, current, 1); - } + single_step_trap(current); return regs->ARM_r0; @@ -324,11 +319,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT) goto badframe; - /* Send SIGTRAP if we're single-stepping */ - if (current->ptrace & PT_SINGLESTEP) { - ptrace_cancel_bpt(current); - send_sig(SIGTRAP, current, 1); - } + single_step_trap(current); return regs->ARM_r0; @@ -644,14 +635,12 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) if (try_to_freeze()) goto no_signal; - if (current->ptrace & PT_SINGLESTEP) - ptrace_cancel_bpt(current); + single_step_clear(current); signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { handle_signal(signr, &ka, &info, oldset, regs, syscall); - if (current->ptrace & PT_SINGLESTEP) - ptrace_set_bpt(current); + single_step_set(current); return 1; } @@ -705,8 +694,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) restart_syscall(regs); } } - if (current->ptrace & PT_SINGLESTEP) - ptrace_set_bpt(current); + single_step_set(current); return 0; } -- cgit v1.2.3-59-g8ed1b From 235b185ce47ce64793362bd3ae4bcd8afc6b57b8 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 4 Mar 2007 20:44:59 +0000 Subject: [ARM] getuser.S and putuser.S don't need thread_info.h nor asm-offsets.h Signed-off-by: Russell King --- arch/arm/lib/getuser.S | 2 -- arch/arm/lib/putuser.S | 2 -- 2 files changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S index c03ea8e666ba..1dd8ea4f9a9c 100644 --- a/arch/arm/lib/getuser.S +++ b/arch/arm/lib/getuser.S @@ -26,8 +26,6 @@ * Note that ADDR_LIMIT is either 0 or 0xc0000000. * Note also that it is intended that __get_user_bad is not global. */ -#include -#include #include .global __get_user_1 diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S index 4593e9c07f05..8620afe54f72 100644 --- a/arch/arm/lib/putuser.S +++ b/arch/arm/lib/putuser.S @@ -26,8 +26,6 @@ * Note that ADDR_LIMIT is either 0 or 0xc0000000 * Note also that it is intended that __put_user_bad is not global. */ -#include -#include #include .global __put_user_1 -- cgit v1.2.3-59-g8ed1b From 2497f0a8125e307cf1fd4222bab53f66305eba27 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Apr 2007 09:59:44 +0100 Subject: [ARM] mm 1: Combine mem_type domain into prot_* at init time Rather than combining the domain for a particular memory type with the protection information each time we want to use it, do so when we fix up the mem_type array at initialisation time. Rename struct mem_types to be mem_type - each structure is one memory type description, not several. Signed-off-by: Russell King --- arch/arm/mm/mmu.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 94fd4bf5cb9e..6178be0242f2 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -176,14 +176,14 @@ void adjust_cr(unsigned long mask, unsigned long set) } #endif -struct mem_types { +struct mem_type { unsigned int prot_pte; unsigned int prot_l1; unsigned int prot_sect; unsigned int domain; }; -static struct mem_types mem_types[] __initdata = { +static struct mem_type mem_types[] __initdata = { [MT_DEVICE] = { .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE, @@ -368,6 +368,14 @@ static void __init build_mem_type_table(void) } printk("Memory policy: ECC %sabled, Data cache %s\n", ecc_mask ? "en" : "dis", cp->policy); + + for (i = 0; i < ARRAY_SIZE(mem_types); i++) { + struct mem_type *t = &mem_types[i]; + if (t->prot_l1) + t->prot_l1 |= PMD_DOMAIN(t->domain); + if (t->prot_sect) + t->prot_sect |= PMD_DOMAIN(t->domain); + } } #define vectors_base() (vectors_high() ? 0xffff0000 : 0) @@ -458,8 +466,8 @@ void __init create_mapping(struct map_desc *md) domain = mem_types[md->type].domain; prot_pte = __pgprot(mem_types[md->type].prot_pte); - prot_l1 = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain); - prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain); + prot_l1 = mem_types[md->type].prot_l1; + prot_sect = mem_types[md->type].prot_sect; /* * Catch 36-bit addresses -- cgit v1.2.3-59-g8ed1b From d5c98176ef34b8b78645646593c17e10f62f53ff Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Apr 2007 10:05:32 +0100 Subject: [ARM] mm 2: clean up create_mapping() There's now no need to carry around each protection separately. Instead, pass around the pointer to the entry in the mem_types array which we're interested in. Signed-off-by: Russell King --- arch/arm/mm/mmu.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 6178be0242f2..e359f3685433 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -420,7 +420,7 @@ alloc_init_supersection(unsigned long virt, unsigned long phys, int prot) * the hardware pte table. */ static inline void -alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot) +alloc_init_page(unsigned long virt, unsigned long phys, const struct mem_type *type) { pmd_t *pmdp = pmd_off_k(virt); pte_t *ptep; @@ -429,11 +429,11 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t)); - __pmd_populate(pmdp, __pa(ptep) | prot_l1); + __pmd_populate(pmdp, __pa(ptep) | type->prot_l1); } ptep = pte_offset_kernel(pmdp, virt); - set_pte_ext(ptep, pfn_pte(phys >> PAGE_SHIFT, prot), 0); + set_pte_ext(ptep, pfn_pte(phys >> PAGE_SHIFT, __pgprot(type->prot_pte)), 0); } /* @@ -446,9 +446,8 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg void __init create_mapping(struct map_desc *md) { unsigned long virt, length; - int prot_sect, prot_l1, domain; - pgprot_t prot_pte; unsigned long off = (u32)__pfn_to_phys(md->pfn); + const struct mem_type *type; if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { printk(KERN_WARNING "BUG: not creating mapping for " @@ -464,16 +463,13 @@ void __init create_mapping(struct map_desc *md) __pfn_to_phys((u64)md->pfn), md->virtual); } - domain = mem_types[md->type].domain; - prot_pte = __pgprot(mem_types[md->type].prot_pte); - prot_l1 = mem_types[md->type].prot_l1; - prot_sect = mem_types[md->type].prot_sect; + type = &mem_types[md->type]; /* * Catch 36-bit addresses */ if(md->pfn >= 0x100000) { - if(domain) { + if (type->domain) { printk(KERN_ERR "MM: invalid domain in supersection " "mapping for 0x%08llx at 0x%08lx\n", __pfn_to_phys((u64)md->pfn), md->virtual); @@ -498,7 +494,7 @@ void __init create_mapping(struct map_desc *md) off -= virt; length = md->length; - if (mem_types[md->type].prot_l1 == 0 && + if (type->prot_l1 == 0 && (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) { printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not " "be mapped using pages, ignoring.\n", @@ -507,7 +503,7 @@ void __init create_mapping(struct map_desc *md) } while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) { - alloc_init_page(virt, virt + off, prot_l1, prot_pte); + alloc_init_page(virt, virt + off, type); virt += PAGE_SIZE; length -= PAGE_SIZE; @@ -520,7 +516,7 @@ void __init create_mapping(struct map_desc *md) * of the actual domain assignments in use. */ if ((cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3()) - && domain == 0) { + && type->domain == 0) { /* * Align to supersection boundary if !high pages. * High pages have already been checked for proper @@ -532,7 +528,7 @@ void __init create_mapping(struct map_desc *md) while ((virt & ~SUPERSECTION_MASK || (virt + off) & ~SUPERSECTION_MASK) && length >= (PGDIR_SIZE / 2)) { - alloc_init_section(virt, virt + off, prot_sect); + alloc_init_section(virt, virt + off, type->prot_sect); virt += (PGDIR_SIZE / 2); length -= (PGDIR_SIZE / 2); @@ -540,7 +536,7 @@ void __init create_mapping(struct map_desc *md) } while (length >= SUPERSECTION_SIZE) { - alloc_init_supersection(virt, virt + off, prot_sect); + alloc_init_supersection(virt, virt + off, type->prot_sect); virt += SUPERSECTION_SIZE; length -= SUPERSECTION_SIZE; @@ -551,14 +547,14 @@ void __init create_mapping(struct map_desc *md) * A section mapping covers half a "pgdir" entry. */ while (length >= (PGDIR_SIZE / 2)) { - alloc_init_section(virt, virt + off, prot_sect); + alloc_init_section(virt, virt + off, type->prot_sect); virt += (PGDIR_SIZE / 2); length -= (PGDIR_SIZE / 2); } while (length >= PAGE_SIZE) { - alloc_init_page(virt, virt + off, prot_l1, prot_pte); + alloc_init_page(virt, virt + off, type); virt += PAGE_SIZE; length -= PAGE_SIZE; -- cgit v1.2.3-59-g8ed1b From 4a56c1e41f19393577bdd5c774c289c199b7269d Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Apr 2007 10:16:48 +0100 Subject: [ARM] mm 3: separate out supersection mappings, avoid for <4GB Catalin Marinas at ARM Ltd says: > The CPU architects in ARM intended supersections only as a way to map > addresses >= 4GB. Supersections are not mandated by the architecture > and there is no easy way to detect their hardware support at run-time > (other than checking for a specific core). From the analysis done in > ARM, there wasn't a clear performance gain by using supersections > rather than sections (no significant improvement in the TLB misses). Therefore, we should avoid using supersections unless there's a real need (iow, we're mapping addresses >= 4GB). This means that we can simplify create_mapping() a bit since we will only use supersection mappings for addresses >= 4GB, which means that the physical, virtual and length must be multiples of the supersection mapping size. Signed-off-by: Russell King --- arch/arm/mm/ioremap.c | 2 +- arch/arm/mm/mmu.c | 130 +++++++++++++++++++++++--------------------------- 2 files changed, 62 insertions(+), 70 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index 0ac615c0f798..800855b2dc83 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -302,7 +302,7 @@ __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, #ifndef CONFIG_SMP if (DOMAIN_IO == 0 && (((cpu_architecture() >= CPU_ARCH_ARMv6) && (get_cr() & CR_XP)) || - cpu_is_xsc3()) && + cpu_is_xsc3()) && pfn >= 0x100000 && !((__pfn_to_phys(pfn) | size | addr) & ~SUPERSECTION_MASK)) { area->flags |= VM_ARM_SECTION_MAPPING; err = remap_area_supersections(addr, pfn, size, flags); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index e359f3685433..32139800d939 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -397,21 +397,6 @@ alloc_init_section(unsigned long virt, unsigned long phys, int prot) flush_pmd_entry(pmdp); } -/* - * Create a SUPER SECTION PGD between VIRT and PHYS with protection PROT - */ -static inline void -alloc_init_supersection(unsigned long virt, unsigned long phys, int prot) -{ - int i; - - for (i = 0; i < 16; i += 1) { - alloc_init_section(virt, phys, prot | PMD_SECT_SUPER); - - virt += (PGDIR_SIZE / 2); - } -} - /* * Add a PAGE mapping between VIRT and PHYS in domain * DOMAIN with protection PROT. Note that due to the @@ -436,6 +421,64 @@ alloc_init_page(unsigned long virt, unsigned long phys, const struct mem_type *t set_pte_ext(ptep, pfn_pte(phys >> PAGE_SHIFT, __pgprot(type->prot_pte)), 0); } +static void __init create_36bit_mapping(struct map_desc *md, + const struct mem_type *type) +{ + unsigned long phys, addr, length, end; + pgd_t *pgd; + + addr = md->virtual; + phys = (unsigned long)__pfn_to_phys(md->pfn); + length = PAGE_ALIGN(md->length); + + if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) { + printk(KERN_ERR "MM: CPU does not support supersection " + "mapping for 0x%08llx at 0x%08lx\n", + __pfn_to_phys((u64)md->pfn), addr); + return; + } + + /* N.B. ARMv6 supersections are only defined to work with domain 0. + * Since domain assignments can in fact be arbitrary, the + * 'domain == 0' check below is required to insure that ARMv6 + * supersections are only allocated for domain 0 regardless + * of the actual domain assignments in use. + */ + if (type->domain) { + printk(KERN_ERR "MM: invalid domain in supersection " + "mapping for 0x%08llx at 0x%08lx\n", + __pfn_to_phys((u64)md->pfn), addr); + return; + } + + if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) { + printk(KERN_ERR "MM: cannot create mapping for " + "0x%08llx at 0x%08lx invalid alignment\n", + __pfn_to_phys((u64)md->pfn), addr); + return; + } + + /* + * Shift bits [35:32] of address into bits [23:20] of PMD + * (See ARMv6 spec). + */ + phys |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20); + + pgd = pgd_offset_k(addr); + end = addr + length; + do { + pmd_t *pmd = pmd_offset(pgd, addr); + int i; + + for (i = 0; i < 16; i++) + *pmd++ = __pmd(phys | type->prot_sect | PMD_SECT_SUPER); + + addr += SUPERSECTION_SIZE; + phys += SUPERSECTION_SIZE; + pgd += SUPERSECTION_SIZE >> PGDIR_SHIFT; + } while (addr != end); +} + /* * Create the page directory entries and any necessary * page tables for the mapping specified by `md'. We @@ -468,26 +511,9 @@ void __init create_mapping(struct map_desc *md) /* * Catch 36-bit addresses */ - if(md->pfn >= 0x100000) { - if (type->domain) { - printk(KERN_ERR "MM: invalid domain in supersection " - "mapping for 0x%08llx at 0x%08lx\n", - __pfn_to_phys((u64)md->pfn), md->virtual); - return; - } - if((md->virtual | md->length | __pfn_to_phys(md->pfn)) - & ~SUPERSECTION_MASK) { - printk(KERN_ERR "MM: cannot create mapping for " - "0x%08llx at 0x%08lx invalid alignment\n", - __pfn_to_phys((u64)md->pfn), md->virtual); - return; - } - - /* - * Shift bits [35:32] of address into bits [23:20] of PMD - * (See ARMv6 spec). - */ - off |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20); + if (md->pfn >= 0x100000) { + create_36bit_mapping(md, type); + return; } virt = md->virtual; @@ -509,40 +535,6 @@ void __init create_mapping(struct map_desc *md) length -= PAGE_SIZE; } - /* N.B. ARMv6 supersections are only defined to work with domain 0. - * Since domain assignments can in fact be arbitrary, the - * 'domain == 0' check below is required to insure that ARMv6 - * supersections are only allocated for domain 0 regardless - * of the actual domain assignments in use. - */ - if ((cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3()) - && type->domain == 0) { - /* - * Align to supersection boundary if !high pages. - * High pages have already been checked for proper - * alignment above and they will fail the SUPSERSECTION_MASK - * check because of the way the address is encoded into - * offset. - */ - if (md->pfn <= 0x100000) { - while ((virt & ~SUPERSECTION_MASK || - (virt + off) & ~SUPERSECTION_MASK) && - length >= (PGDIR_SIZE / 2)) { - alloc_init_section(virt, virt + off, type->prot_sect); - - virt += (PGDIR_SIZE / 2); - length -= (PGDIR_SIZE / 2); - } - } - - while (length >= SUPERSECTION_SIZE) { - alloc_init_supersection(virt, virt + off, type->prot_sect); - - virt += SUPERSECTION_SIZE; - length -= SUPERSECTION_SIZE; - } - } - /* * A section mapping covers half a "pgdir" entry. */ -- cgit v1.2.3-59-g8ed1b From 24e6c6996fb6e0e716c1dda1def1bb023a0fe43b Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Apr 2007 10:21:28 +0100 Subject: [ARM] mm 4: make create_mapping() more conventional Rather than our three separate loops to setup mappings (by page mappings up to a section boundary, then section mappings, and the remainder by page mappings) convert this to a more conventional Linux style of a loop over each page table level. Signed-off-by: Russell King --- arch/arm/mm/mmu.c | 114 ++++++++++++++++++++++++++---------------------------- 1 file changed, 55 insertions(+), 59 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 32139800d939..5821e67cf8c2 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -380,45 +380,55 @@ static void __init build_mem_type_table(void) #define vectors_base() (vectors_high() ? 0xffff0000 : 0) -/* - * Create a SECTION PGD between VIRT and PHYS in domain - * DOMAIN with protection PROT. This operates on half- - * pgdir entry increments. - */ -static inline void -alloc_init_section(unsigned long virt, unsigned long phys, int prot) +static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, + unsigned long end, unsigned long pfn, + const struct mem_type *type) { - pmd_t *pmdp = pmd_off_k(virt); + pte_t *pte; - if (virt & (1 << 20)) - pmdp++; + if (pmd_none(*pmd)) { + pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t)); + __pmd_populate(pmd, __pa(pte) | type->prot_l1); + } - *pmdp = __pmd(phys | prot); - flush_pmd_entry(pmdp); + pte = pte_offset_kernel(pmd, addr); + do { + set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0); + pfn++; + } while (pte++, addr += PAGE_SIZE, addr != end); } -/* - * Add a PAGE mapping between VIRT and PHYS in domain - * DOMAIN with protection PROT. Note that due to the - * way we map the PTEs, we must allocate two PTE_SIZE'd - * blocks - one for the Linux pte table, and one for - * the hardware pte table. - */ -static inline void -alloc_init_page(unsigned long virt, unsigned long phys, const struct mem_type *type) +static void __init alloc_init_section(pgd_t *pgd, unsigned long addr, + unsigned long end, unsigned long phys, + const struct mem_type *type) { - pmd_t *pmdp = pmd_off_k(virt); - pte_t *ptep; + pmd_t *pmd = pmd_offset(pgd, addr); - if (pmd_none(*pmdp)) { - ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * - sizeof(pte_t)); + /* + * Try a section mapping - end, addr and phys must all be aligned + * to a section boundary. Note that PMDs refer to the individual + * L1 entries, whereas PGDs refer to a group of L1 entries making + * up one logical pointer to an L2 table. + */ + if (((addr | end | phys) & ~SECTION_MASK) == 0) { + pmd_t *p = pmd; - __pmd_populate(pmdp, __pa(ptep) | type->prot_l1); - } - ptep = pte_offset_kernel(pmdp, virt); + if (addr & SECTION_SIZE) + pmd++; + + do { + *pmd = __pmd(phys | type->prot_sect); + phys += SECTION_SIZE; + } while (pmd++, addr += SECTION_SIZE, addr != end); - set_pte_ext(ptep, pfn_pte(phys >> PAGE_SHIFT, __pgprot(type->prot_pte)), 0); + flush_pmd_entry(p); + } else { + /* + * No need to loop; pte's aren't interested in the + * individual L1 entries. + */ + alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type); + } } static void __init create_36bit_mapping(struct map_desc *md, @@ -488,9 +498,9 @@ static void __init create_36bit_mapping(struct map_desc *md, */ void __init create_mapping(struct map_desc *md) { - unsigned long virt, length; - unsigned long off = (u32)__pfn_to_phys(md->pfn); + unsigned long phys, addr, length, end; const struct mem_type *type; + pgd_t *pgd; if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { printk(KERN_WARNING "BUG: not creating mapping for " @@ -516,41 +526,27 @@ void __init create_mapping(struct map_desc *md) return; } - virt = md->virtual; - off -= virt; - length = md->length; + addr = md->virtual; + phys = (unsigned long)__pfn_to_phys(md->pfn); + length = PAGE_ALIGN(md->length); - if (type->prot_l1 == 0 && - (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) { + if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) { printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not " "be mapped using pages, ignoring.\n", - __pfn_to_phys(md->pfn), md->virtual); + __pfn_to_phys(md->pfn), addr); return; } - while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) { - alloc_init_page(virt, virt + off, type); - - virt += PAGE_SIZE; - length -= PAGE_SIZE; - } - - /* - * A section mapping covers half a "pgdir" entry. - */ - while (length >= (PGDIR_SIZE / 2)) { - alloc_init_section(virt, virt + off, type->prot_sect); - - virt += (PGDIR_SIZE / 2); - length -= (PGDIR_SIZE / 2); - } + pgd = pgd_offset_k(addr); + end = addr + length; + do { + unsigned long next = pgd_addr_end(addr, end); - while (length >= PAGE_SIZE) { - alloc_init_page(virt, virt + off, type); + alloc_init_section(pgd, addr, next, phys, type); - virt += PAGE_SIZE; - length -= PAGE_SIZE; - } + phys += next - addr; + addr = next; + } while (pgd++, addr != end); } /* -- cgit v1.2.3-59-g8ed1b From b29e9f5e64fb90d2e4be1c7ef8c925b56669c74a Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Apr 2007 10:47:29 +0100 Subject: [ARM] mm 5: Use mem_types table in ioremap We really want to be using the memory type table in ioremap, so we only have to do the CPU type fixups in one place. Signed-off-by: Russell King --- arch/arm/mm/ioremap.c | 65 +++++++++++++++++++++------------------------------ arch/arm/mm/mm.h | 9 +++++++ arch/arm/mm/mmu.c | 14 +++++------ 3 files changed, 42 insertions(+), 46 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index 800855b2dc83..b26b36109d54 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -32,6 +32,9 @@ #include #include +#include +#include "mm.h" + /* * Used by ioremap() and iounmap() code to mark (super)section-mapped * I/O regions in vm_struct->flags field. @@ -39,8 +42,9 @@ #define VM_ARM_SECTION_MAPPING 0x80000000 static int remap_area_pte(pmd_t *pmd, unsigned long addr, unsigned long end, - unsigned long phys_addr, pgprot_t prot) + unsigned long phys_addr, const struct mem_type *type) { + pgprot_t prot = __pgprot(type->prot_pte); pte_t *pte; pte = pte_alloc_kernel(pmd, addr); @@ -63,7 +67,7 @@ static int remap_area_pte(pmd_t *pmd, unsigned long addr, unsigned long end, static inline int remap_area_pmd(pgd_t *pgd, unsigned long addr, unsigned long end, unsigned long phys_addr, - pgprot_t prot) + const struct mem_type *type) { unsigned long next; pmd_t *pmd; @@ -75,7 +79,7 @@ static inline int remap_area_pmd(pgd_t *pgd, unsigned long addr, do { next = pmd_addr_end(addr, end); - ret = remap_area_pte(pmd, addr, next, phys_addr, prot); + ret = remap_area_pte(pmd, addr, next, phys_addr, type); if (ret) return ret; phys_addr += next - addr; @@ -84,13 +88,11 @@ static inline int remap_area_pmd(pgd_t *pgd, unsigned long addr, } static int remap_area_pages(unsigned long start, unsigned long pfn, - unsigned long size, unsigned long flags) + size_t size, const struct mem_type *type) { unsigned long addr = start; unsigned long next, end = start + size; unsigned long phys_addr = __pfn_to_phys(pfn); - pgprot_t prot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | - L_PTE_DIRTY | L_PTE_WRITE | flags); pgd_t *pgd; int err = 0; @@ -98,7 +100,7 @@ static int remap_area_pages(unsigned long start, unsigned long pfn, pgd = pgd_offset_k(addr); do { next = pgd_addr_end(addr, end); - err = remap_area_pmd(pgd, addr, next, phys_addr, prot); + err = remap_area_pmd(pgd, addr, next, phys_addr, type); if (err) break; phys_addr += next - addr; @@ -178,9 +180,9 @@ static void unmap_area_sections(unsigned long virt, unsigned long size) static int remap_area_sections(unsigned long virt, unsigned long pfn, - unsigned long size, unsigned long flags) + size_t size, const struct mem_type *type) { - unsigned long prot, addr = virt, end = virt + size; + unsigned long addr = virt, end = virt + size; pgd_t *pgd; /* @@ -189,23 +191,13 @@ remap_area_sections(unsigned long virt, unsigned long pfn, */ unmap_area_sections(virt, size); - prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_DOMAIN(DOMAIN_IO) | - (flags & (L_PTE_CACHEABLE | L_PTE_BUFFERABLE)); - - /* - * ARMv6 and above need XN set to prevent speculative prefetches - * hitting IO. - */ - if (cpu_architecture() >= CPU_ARCH_ARMv6) - prot |= PMD_SECT_XN; - pgd = pgd_offset_k(addr); do { pmd_t *pmd = pmd_offset(pgd, addr); - pmd[0] = __pmd(__pfn_to_phys(pfn) | prot); + pmd[0] = __pmd(__pfn_to_phys(pfn) | type->prot_sect); pfn += SZ_1M >> PAGE_SHIFT; - pmd[1] = __pmd(__pfn_to_phys(pfn) | prot); + pmd[1] = __pmd(__pfn_to_phys(pfn) | type->prot_sect); pfn += SZ_1M >> PAGE_SHIFT; flush_pmd_entry(pmd); @@ -218,9 +210,9 @@ remap_area_sections(unsigned long virt, unsigned long pfn, static int remap_area_supersections(unsigned long virt, unsigned long pfn, - unsigned long size, unsigned long flags) + size_t size, const struct mem_type *type) { - unsigned long prot, addr = virt, end = virt + size; + unsigned long addr = virt, end = virt + size; pgd_t *pgd; /* @@ -229,22 +221,12 @@ remap_area_supersections(unsigned long virt, unsigned long pfn, */ unmap_area_sections(virt, size); - prot = PMD_TYPE_SECT | PMD_SECT_SUPER | PMD_SECT_AP_WRITE | - PMD_DOMAIN(DOMAIN_IO) | - (flags & (L_PTE_CACHEABLE | L_PTE_BUFFERABLE)); - - /* - * ARMv6 and above need XN set to prevent speculative prefetches - * hitting IO. - */ - if (cpu_architecture() >= CPU_ARCH_ARMv6) - prot |= PMD_SECT_XN; - pgd = pgd_offset_k(virt); do { unsigned long super_pmd_val, i; - super_pmd_val = __pfn_to_phys(pfn) | prot; + super_pmd_val = __pfn_to_phys(pfn) | type->prot_sect | + PMD_SECT_SUPER; super_pmd_val |= ((pfn >> (32 - PAGE_SHIFT)) & 0xf) << 20; for (i = 0; i < 8; i++) { @@ -282,6 +264,8 @@ void __iomem * __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, unsigned long flags) { + const struct mem_type *type; + struct mem_type t; int err; unsigned long addr; struct vm_struct * area; @@ -292,6 +276,11 @@ __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, if (pfn >= 0x100000 && (__pfn_to_phys(pfn) & ~SUPERSECTION_MASK)) return NULL; + t = *get_mem_type(MT_DEVICE); + t.prot_sect |= flags; + t.prot_pte |= flags; + type = &t; + size = PAGE_ALIGN(size); area = get_vm_area(size, VM_IOREMAP); @@ -305,13 +294,13 @@ __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, cpu_is_xsc3()) && pfn >= 0x100000 && !((__pfn_to_phys(pfn) | size | addr) & ~SUPERSECTION_MASK)) { area->flags |= VM_ARM_SECTION_MAPPING; - err = remap_area_supersections(addr, pfn, size, flags); + err = remap_area_supersections(addr, pfn, size, type); } else if (!((__pfn_to_phys(pfn) | size | addr) & ~PMD_MASK)) { area->flags |= VM_ARM_SECTION_MAPPING; - err = remap_area_sections(addr, pfn, size, flags); + err = remap_area_sections(addr, pfn, size, type); } else #endif - err = remap_area_pages(addr, pfn, size, flags); + err = remap_area_pages(addr, pfn, size, type); if (err) { vunmap((void *)addr); diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index a44e30970635..66f8612c5e5b 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -16,6 +16,15 @@ static inline pmd_t *pmd_off_k(unsigned long virt) return pmd_off(pgd_offset_k(virt), virt); } +struct mem_type { + unsigned int prot_pte; + unsigned int prot_l1; + unsigned int prot_sect; + unsigned int domain; +}; + +const struct mem_type *get_mem_type(unsigned int type); + #endif struct map_desc; diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 5821e67cf8c2..6cb80b4973d2 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -176,14 +176,7 @@ void adjust_cr(unsigned long mask, unsigned long set) } #endif -struct mem_type { - unsigned int prot_pte; - unsigned int prot_l1; - unsigned int prot_sect; - unsigned int domain; -}; - -static struct mem_type mem_types[] __initdata = { +static struct mem_type mem_types[] = { [MT_DEVICE] = { .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE, @@ -237,6 +230,11 @@ static struct mem_type mem_types[] __initdata = { } }; +const struct mem_type *get_mem_type(unsigned int type) +{ + return type < ARRAY_SIZE(mem_types) ? &mem_types[type] : NULL; +} + /* * Adjust the PMD section entries according to the CPU in use. */ -- cgit v1.2.3-59-g8ed1b From c172cc92c87103c98b5cd359205b684bf99b5067 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Apr 2007 10:52:32 +0100 Subject: [ARM] mm 6: allow mem_types table to specify extended pte attributes Add prot_pte_ext to the mem_types table to allow the extended pte attributes to be passed to set_pte_ext(), thereby permitting us to specify memory type information for the hardware PTE entries. Signed-off-by: Russell King --- arch/arm/mm/ioremap.c | 3 ++- arch/arm/mm/mm.h | 1 + arch/arm/mm/mmu.c | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index b26b36109d54..216623eece35 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -55,7 +55,8 @@ static int remap_area_pte(pmd_t *pmd, unsigned long addr, unsigned long end, if (!pte_none(*pte)) goto bad; - set_pte_ext(pte, pfn_pte(phys_addr >> PAGE_SHIFT, prot), 0); + set_pte_ext(pte, pfn_pte(phys_addr >> PAGE_SHIFT, prot), + type->prot_pte_ext); phys_addr += PAGE_SIZE; } while (pte++, addr += PAGE_SIZE, addr != end); return 0; diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index 66f8612c5e5b..7647c597fc59 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -18,6 +18,7 @@ static inline pmd_t *pmd_off_k(unsigned long virt) struct mem_type { unsigned int prot_pte; + unsigned int prot_pte_ext; unsigned int prot_l1; unsigned int prot_sect; unsigned int domain; diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 6cb80b4973d2..360405515bbd 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -391,7 +391,8 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, pte = pte_offset_kernel(pmd, addr); do { - set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0); + set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), + type->prot_pte_ext); pfn++; } while (pte++, addr += PAGE_SIZE, addr != end); } -- cgit v1.2.3-59-g8ed1b From 4fe4a2bf9a687fc87ea796c234da8c59df763aab Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 26 Feb 2007 01:44:57 +0100 Subject: [ARM] 4236/2: basic {enable,disable}_irq_wake() support for PXA pxa_set_gpio_wake handles GPIOs > 1, so IRQ_TO_GPIO has to be used instead of just substracting IRQ_GPIO0 from the irq number. --- arch/arm/mach-pxa/irq.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 9f7499b6d435..4619d5fe606c 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -38,11 +38,33 @@ static void pxa_unmask_low_irq(unsigned int irq) ICMR |= (1 << (irq + PXA_IRQ_SKIP)); } +static int pxa_set_wake(unsigned int irq, unsigned int on) +{ + u32 mask; + + switch (irq) { + case IRQ_RTCAlrm: + mask = PWER_RTC; + break; +#ifdef CONFIG_PXA27x + /* REVISIT can handle USBH1, USBH2, USB, MSL, USIM, ... */ +#endif + default: + return -EINVAL; + } + if (on) + PWER |= mask; + else + PWER &= ~mask; + return 0; +} + static struct irq_chip pxa_internal_chip_low = { .name = "SC", .ack = pxa_mask_low_irq, .mask = pxa_mask_low_irq, .unmask = pxa_unmask_low_irq, + .set_wake = pxa_set_wake, }; #if PXA_INTERNAL_IRQS > 32 @@ -70,6 +92,26 @@ static struct irq_chip pxa_internal_chip_high = { #endif +/* Note that if an input/irq line ever gets changed to an output during + * suspend, the relevant PWER, PRER, and PFER bits should be cleared. + */ +#ifdef CONFIG_PXA27x + +/* PXA27x: Various gpios can issue wakeup events. This logic only + * handles the simple cases, not the WEMUX2 and WEMUX3 options + */ +#define PXA27x_GPIO_NOWAKE_MASK \ + ((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2)) +#define WAKEMASK(gpio) \ + (((gpio) <= 15) \ + ? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \ + : ((gpio == 35) ? (1 << 24) : 0)) +#else + +/* pxa 210, 250, 255, 26x: gpios 0..15 can issue wakeups */ +#define WAKEMASK(gpio) (((gpio) <= 15) ? (1 << (gpio)) : 0) +#endif + /* * PXA GPIO edge detection for IRQs: * IRQs are generated on Falling-Edge, Rising-Edge, or both. @@ -83,9 +125,11 @@ static long GPIO_IRQ_mask[4]; static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) { int gpio, idx; + u32 mask; gpio = IRQ_TO_GPIO(irq); idx = gpio >> 5; + mask = WAKEMASK(gpio); if (type == IRQT_PROBE) { /* Don't mess with enabled GPIOs using preconfigured edges or @@ -105,14 +149,20 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) if (type & __IRQT_RISEDGE) { /* printk("rising "); */ __set_bit (gpio, GPIO_IRQ_rising_edge); - } else + PRER |= mask; + } else { __clear_bit (gpio, GPIO_IRQ_rising_edge); + PRER &= ~mask; + } if (type & __IRQT_FALEDGE) { /* printk("falling "); */ __set_bit (gpio, GPIO_IRQ_falling_edge); - } else + PFER |= mask; + } else { __clear_bit (gpio, GPIO_IRQ_falling_edge); + PFER &= ~mask; + } /* printk("edges\n"); */ @@ -130,12 +180,29 @@ static void pxa_ack_low_gpio(unsigned int irq) GEDR0 = (1 << (irq - IRQ_GPIO0)); } +static int pxa_set_gpio_wake(unsigned int irq, unsigned int on) +{ + int gpio = IRQ_TO_GPIO(irq); + u32 mask = WAKEMASK(gpio); + + if (!mask) + return -EINVAL; + + if (on) + PWER |= mask; + else + PWER &= ~mask; + return 0; +} + + static struct irq_chip pxa_low_gpio_chip = { .name = "GPIO-l", .ack = pxa_ack_low_gpio, .mask = pxa_mask_low_irq, .unmask = pxa_unmask_low_irq, .set_type = pxa_gpio_irq_type, + .set_wake = pxa_set_gpio_wake, }; /* @@ -244,6 +311,7 @@ static struct irq_chip pxa_muxed_gpio_chip = { .mask = pxa_mask_muxed_gpio, .unmask = pxa_unmask_muxed_gpio, .set_type = pxa_gpio_irq_type, + .set_wake = pxa_set_gpio_wake, }; -- cgit v1.2.3-59-g8ed1b From 25735d10ba477d5128b1e5ccef42062bea429075 Mon Sep 17 00:00:00 2001 From: Milan Svoboda Date: Wed, 21 Mar 2007 14:04:08 +0100 Subject: [ARM] 4275/1: generic gpio layer for ixp4xx This patch brings generic gpio layer support to ixp4xx. It creates functions needed for gpio->irq and irq->gpio translation. It expects and initial value to be passed to gpio_direction_output() which has been introduced by commit 28735a7253a6c24364765e80a5428b4a151fccc2 in Linus git tree. Generic gpio layer is going to be used by pxa2xx_udc driver. Signed-off-by: Milan Svoboda Signed-off-by: Russell King --- arch/arm/mach-ixp4xx/common.c | 23 ++++++++++++ include/asm-arm/arch-ixp4xx/gpio.h | 73 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 include/asm-arm/arch-ixp4xx/gpio.h (limited to 'arch') diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 45068c3d8dcc..39f2eeb219b4 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -102,6 +102,29 @@ static signed char irq2gpio[32] = { 7, 8, 9, 10, 11, 12, -1, -1, }; +int gpio_to_irq(int gpio) +{ + int irq; + + for (irq = 0; irq < 32; irq++) { + if (irq2gpio[irq] == gpio) + return irq; + } + return -EINVAL; +} +EXPORT_SYMBOL(gpio_to_irq); + +int irq_to_gpio(int irq) +{ + int gpio = (irq < 32) ? irq2gpio[irq] : -EINVAL; + + if (gpio == -1) + return -EINVAL; + + return gpio; +} +EXPORT_SYMBOL(irq_to_gpio); + static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type) { int line = irq2gpio[irq]; diff --git a/include/asm-arm/arch-ixp4xx/gpio.h b/include/asm-arm/arch-ixp4xx/gpio.h new file mode 100644 index 000000000000..3a4c5b8ae9e1 --- /dev/null +++ b/include/asm-arm/arch-ixp4xx/gpio.h @@ -0,0 +1,73 @@ +/* + * linux/include/asm-arm/arch-ixp4xx/gpio.h + * + * IXP4XX GPIO wrappers for arch-neutral GPIO calls + * + * Written by Milan Svoboda + * Based on PXA implementation by Philipp Zabel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARCH_IXP4XX_GPIO_H +#define __ASM_ARCH_IXP4XX_GPIO_H + +#include + +static inline int gpio_request(unsigned gpio, const char *label) +{ + return 0; +} + +static inline void gpio_free(unsigned gpio) +{ + return; +} + +static inline int gpio_direction_input(unsigned gpio) +{ + gpio_line_config(gpio, IXP4XX_GPIO_IN); + return 0; +} + +static inline int gpio_direction_output(unsigned gpio, int level) +{ + gpio_line_set(gpio, level); + gpio_line_config(gpio, IXP4XX_GPIO_OUT); + return 0; +} + +static inline int gpio_get_value(unsigned gpio) +{ + int value; + + gpio_line_get(gpio, &value); + + return value; +} + +static inline void gpio_set_value(unsigned gpio, int value) +{ + gpio_line_set(gpio, value); +} + +#include /* cansleep wrappers */ + +extern int gpio_to_irq(int gpio); +extern int irq_to_gpio(int gpio); + +#endif + -- cgit v1.2.3-59-g8ed1b From 45fba0846f5a5a48ed3c394aa4f8ca93699e7655 Mon Sep 17 00:00:00 2001 From: "Ruslan V. Sushko" Date: Fri, 6 Apr 2007 15:00:31 +0100 Subject: [ARM] 4311/1: ixp4xx: add KIXRP435 platform Add Intel KIXRP435 Reference Platform based on IXP43x processor. Fixed after review : access to cp15 removed in identification functions, used access to global processor_id instead Signed-off-by: Vladimir Barinov Signed-off-by: Ruslan Sushko Signed-off-by: Russell King --- arch/arm/configs/ixp4xx_defconfig | 2 ++ arch/arm/mach-ixp4xx/Kconfig | 13 ++++++++++- arch/arm/mach-ixp4xx/common-pci.c | 4 ++-- arch/arm/mach-ixp4xx/common.c | 6 +++--- arch/arm/mach-ixp4xx/ixdp425-pci.c | 2 +- arch/arm/mach-ixp4xx/ixdp425-setup.c | 18 ++++++++++++++++ arch/arm/mm/proc-xscale.S | 28 ++++++++++++++++++++++++ include/asm-arm/arch-ixp4xx/entry-macro.S | 4 ++-- include/asm-arm/arch-ixp4xx/hardware.h | 4 ++-- include/asm-arm/arch-ixp4xx/io.h | 2 +- include/asm-arm/arch-ixp4xx/irqs.h | 6 +++--- include/asm-arm/arch-ixp4xx/ixp4xx-regs.h | 36 +++++++++++++++++++++++++++---- 12 files changed, 106 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig index fabf74c51a88..db850a5689eb 100644 --- a/arch/arm/configs/ixp4xx_defconfig +++ b/arch/arm/configs/ixp4xx_defconfig @@ -117,11 +117,13 @@ CONFIG_ARCH_ADI_COYOTE=y CONFIG_ARCH_IXDP425=y CONFIG_MACH_IXDPG425=y CONFIG_MACH_IXDP465=y +CONFIG_MACH_KIXRP435=y CONFIG_ARCH_IXCDP1100=y CONFIG_ARCH_PRPMC1100=y CONFIG_MACH_NAS100D=y CONFIG_ARCH_IXDP4XX=y CONFIG_CPU_IXP46X=y +CONFIG_CPU_IXP43X=y # CONFIG_MACH_GTWX5715 is not set # diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index 8a339cdfe222..dd0fb7239a80 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig @@ -62,6 +62,12 @@ config MACH_IXDP465 IXDP465 Development Platform (Also known as BMP). For more information on this platform, see . +config MACH_KIXRP435 + bool "KIXRP435" + help + Say 'Y' here if you want your kernel to support Intel's + KIXRP435 Reference Platform. + For more information on this platform, see . # # IXCDP1100 is the exact same HW as IXDP425, but with a different machine @@ -94,7 +100,7 @@ config MACH_NAS100D # config ARCH_IXDP4XX bool - depends on ARCH_IXDP425 || MACH_IXDP465 + depends on ARCH_IXDP425 || MACH_IXDP465 || MACH_KIXRP435 default y # @@ -105,6 +111,11 @@ config CPU_IXP46X depends on MACH_IXDP465 default y +config CPU_IXP43X + bool + depends on MACH_KIXRP435 + default y + config MACH_GTWX5715 bool "Gemtek WX5715 (Linksys WRV54G)" depends on ARCH_IXP4XX diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 9562177b5fe1..bf04121d1a31 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -374,7 +374,7 @@ void __init ixp4xx_pci_preinit(void) * Determine which PCI read method to use. * Rev 0 IXP425 requires workaround. */ - if (!(processor_id & 0xf) && !cpu_is_ixp46x()) { + if (!(processor_id & 0xf) && cpu_is_ixp42x()) { printk("PCI: IXP42x A0 silicon detected - " "PCI Non-Prefetch Workaround Enabled\n"); ixp4xx_pci_read = ixp4xx_pci_read_errata; @@ -480,7 +480,7 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys) res[0].flags = IORESOURCE_IO; res[1].name = "PCI Memory Space"; - res[1].start = 0x48000000; + res[1].start = PCIBIOS_MIN_MEM; #ifndef CONFIG_IXP4XX_INDIRECT_PCI res[1].end = 0x4bffffff; #else diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 39f2eeb219b4..030dd75d053a 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -192,7 +192,7 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type) static void ixp4xx_irq_mask(unsigned int irq) { - if (cpu_is_ixp46x() && irq >= 32) + if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32) *IXP4XX_ICMR2 &= ~(1 << (irq - 32)); else *IXP4XX_ICMR &= ~(1 << irq); @@ -215,7 +215,7 @@ static void ixp4xx_irq_unmask(unsigned int irq) if (!(ixp4xx_irq_edge & (1 << irq))) ixp4xx_irq_ack(irq); - if (cpu_is_ixp46x() && irq >= 32) + if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32) *IXP4XX_ICMR2 |= (1 << (irq - 32)); else *IXP4XX_ICMR |= (1 << irq); @@ -239,7 +239,7 @@ void __init ixp4xx_init_irq(void) /* Disable all interrupt */ *IXP4XX_ICMR = 0x0; - if (cpu_is_ixp46x()) { + if (cpu_is_ixp46x() || cpu_is_ixp43x()) { /* Route upper 32 sources to IRQ instead of FIQ */ *IXP4XX_ICLR2 = 0x00; diff --git a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c index 99c1dc8033c8..408796004812 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-pci.c +++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c @@ -66,7 +66,7 @@ struct hw_pci ixdp425_pci __initdata = { int __init ixdp425_pci_init(void) { if (machine_is_ixdp425() || machine_is_ixcdp1100() || - machine_is_ixdp465()) + machine_is_ixdp465() || machine_is_kixrp435()) pci_common_init(&ixdp425_pci); return 0; } diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index 04b1d56396a0..ec4f07950ec6 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -115,6 +115,11 @@ static void __init ixdp425_init(void) ixdp425_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; + if (cpu_is_ixp43x()) { + ixdp425_uart.num_resources = 1; + ixdp425_uart_data[1].flags = 0; + } + platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices)); } @@ -156,3 +161,16 @@ MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform") .init_machine = ixdp425_init, MACHINE_END #endif + +#ifdef CONFIG_MACH_KIXRP435 +MACHINE_START(KIXRP435, "Intel KIXRP435 Reference Platform") + /* Maintainer: MontaVista Software, Inc. */ + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = ixp4xx_map_io, + .init_irq = ixp4xx_init_irq, + .timer = &ixp4xx_timer, + .boot_params = 0x0100, + .init_machine = ixdp425_init, +MACHINE_END +#endif diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index d29fe927ee9e..c156ddab9a2d 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S @@ -584,6 +584,11 @@ cpu_ixp42x_name: .asciz "XScale-IXP42x Family" .size cpu_ixp42x_name, . - cpu_ixp42x_name + .type cpu_ixp43x_name, #object +cpu_ixp43x_name: + .asciz "XScale-IXP43x Family" + .size cpu_ixp43x_name, . - cpu_ixp43x_name + .type cpu_ixp46x_name, #object cpu_ixp46x_name: .asciz "XScale-IXP46x Family" @@ -843,6 +848,29 @@ __ixp42x_proc_info: .long xscale_cache_fns .size __ixp42x_proc_info, . - __ixp42x_proc_info + .type __ixp43x_proc_info, #object +__ixp43x_proc_info: + .long 0x69054040 + .long 0xfffffff0 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + .long PMD_TYPE_SECT | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __xscale_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_ixp43x_name + .long xscale_processor_functions + .long v4wbi_tlb_fns + .long xscale_mc_user_fns + .long xscale_cache_fns + .size __ixp43x_proc_info, . - __ixp43x_proc_info + .type __ixp46x_proc_info, #object __ixp46x_proc_info: .long 0x69054200 diff --git a/include/asm-arm/arch-ixp4xx/entry-macro.S b/include/asm-arm/arch-ixp4xx/entry-macro.S index dadb568b7ef0..f144a005ed95 100644 --- a/include/asm-arm/arch-ixp4xx/entry-macro.S +++ b/include/asm-arm/arch-ixp4xx/entry-macro.S @@ -31,9 +31,9 @@ 1001: /* - * IXP465 has an upper IRQ status register + * IXP465/IXP435 has an upper IRQ status register */ -#if defined(CONFIG_CPU_IXP46X) +#if defined(CONFIG_CPU_IXP46X) || defined(CONFIG_CPU_IXP43X) ldr \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP2_OFFSET) ldr \irqstat, [\irqstat] @ get upper interrupts mov \irqnr, #63 diff --git a/include/asm-arm/arch-ixp4xx/hardware.h b/include/asm-arm/arch-ixp4xx/hardware.h index 88fd0877dcc1..24bc5883fa56 100644 --- a/include/asm-arm/arch-ixp4xx/hardware.h +++ b/include/asm-arm/arch-ixp4xx/hardware.h @@ -17,8 +17,8 @@ #ifndef __ASM_ARCH_HARDWARE_H__ #define __ASM_ARCH_HARDWARE_H__ -#define PCIBIOS_MIN_IO 0x00001000 -#define PCIBIOS_MIN_MEM 0x48000000 +#define PCIBIOS_MIN_IO 0x00001000 +#define PCIBIOS_MIN_MEM (cpu_is_ixp43x() ? 0x40000000 : 0x48000000) /* * We override the standard dma-mask routines for bouncing. diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h index a41ba229c564..b8b3cbcd2d3a 100644 --- a/include/asm-arm/arch-ixp4xx/io.h +++ b/include/asm-arm/arch-ixp4xx/io.h @@ -61,7 +61,7 @@ extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data); static inline void __iomem * __ixp4xx_ioremap(unsigned long addr, size_t size, unsigned long flags) { - if((addr < 0x48000000) || (addr > 0x4fffffff)) + if((addr < PCIBIOS_MIN_MEM) || (addr > 0x4fffffff)) return __ioremap(addr, size, flags); return (void *)addr; diff --git a/include/asm-arm/arch-ixp4xx/irqs.h b/include/asm-arm/arch-ixp4xx/irqs.h index e44a563d00ff..73a9aa583745 100644 --- a/include/asm-arm/arch-ixp4xx/irqs.h +++ b/include/asm-arm/arch-ixp4xx/irqs.h @@ -62,10 +62,10 @@ /* * Only first 32 sources are valid if running on IXP42x systems */ -#ifndef CONFIG_CPU_IXP46X -#define NR_IRQS 32 -#else +#if defined(CONFIG_CPU_IXP46X) || defined(CONFIG_CPU_IXP43X) #define NR_IRQS 64 +#else +#define NR_IRQS 32 #endif #define XSCALE_PMU_IRQ (IRQ_IXP4XX_XSCALE_PMU) diff --git a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h index ed35e5c94f40..deb989950c52 100644 --- a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h +++ b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h @@ -607,15 +607,43 @@ #define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */ +/* Processor id value in CP15 Register 0 */ +#define IXP425_PROCESSOR_ID_VALUE 0x690541c0 +#define IXP435_PROCESSOR_ID_VALUE 0x69054040 +#define IXP465_PROCESSOR_ID_VALUE 0x69054200 +#define IXP4XX_PROCESSOR_ID_MASK 0xfffffff0 + #ifndef __ASSEMBLY__ +static inline int cpu_is_ixp42x(void) +{ + extern unsigned int processor_id; + + if ((processor_id & IXP4XX_PROCESSOR_ID_MASK) == + IXP425_PROCESSOR_ID_VALUE ) + return 1; + + return 0; +} + +static inline int cpu_is_ixp43x(void) +{ +#ifdef CONFIG_CPU_IXP43X + extern unsigned int processor_id; + + if ((processor_id & IXP4XX_PROCESSOR_ID_MASK) == + IXP435_PROCESSOR_ID_VALUE ) + return 1; +#endif + return 0; +} + static inline int cpu_is_ixp46x(void) { #ifdef CONFIG_CPU_IXP46X - unsigned int processor_id; - - asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :); + extern unsigned int processor_id; - if ((processor_id & 0xffffff00) == 0x69054200) + if ((processor_id & IXP4XX_PROCESSOR_ID_MASK) == + IXP465_PROCESSOR_ID_VALUE ) return 1; #endif return 0; -- cgit v1.2.3-59-g8ed1b From 13ea55b04eaafb60cd7df759c8d92566d1f19351 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 2 Apr 2007 21:09:31 +0100 Subject: [ARM] 4301/1: add mach type cc9p9360js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The support for that machine is not yet complete, but it's enough to be useful as a test platform for the serial and ethernet driver. Moreover a typo in the product name is fixed that I missed in the last patch. Signed-off-by: Uwe Kleine-König Signed-off-by: Russell King --- arch/arm/mach-ns9xxx/Kconfig | 15 +++++++++++++-- arch/arm/mach-ns9xxx/Makefile | 1 + arch/arm/mach-ns9xxx/board-jscc9p9360.c | 17 +++++++++++++++++ arch/arm/mach-ns9xxx/board-jscc9p9360.h | 13 +++++++++++++ arch/arm/mach-ns9xxx/mach-cc9p9360js.c | 29 +++++++++++++++++++++++++++++ include/asm-arm/arch-ns9xxx/board.h | 2 ++ include/asm-arm/arch-ns9xxx/processor.h | 3 ++- 7 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-ns9xxx/board-jscc9p9360.c create mode 100644 arch/arm/mach-ns9xxx/board-jscc9p9360.h create mode 100644 arch/arm/mach-ns9xxx/mach-cc9p9360js.c (limited to 'arch') diff --git a/arch/arm/mach-ns9xxx/Kconfig b/arch/arm/mach-ns9xxx/Kconfig index 8175ba92a2fa..8584ed107991 100644 --- a/arch/arm/mach-ns9xxx/Kconfig +++ b/arch/arm/mach-ns9xxx/Kconfig @@ -3,19 +3,30 @@ if ARCH_NS9XXX menu "NS9xxx Implementations" config MACH_CC9P9360DEV - bool "Connect Core 9P 9360 on an A9M9750 Devboard" + bool "ConnectCore 9P 9360 on an A9M9750 Devboard" select PROCESSOR_NS9360 select BOARD_A9M9750DEV help - Say Y here if you are using the Digi Connect Core 9P 9360 + Say Y here if you are using the Digi ConnectCore 9P 9360 on an A9M9750 Development Board. +config MACH_CC9P9360JS + bool "ConnectCore 9P 9360 on a JSCC9P9360 Devboard" + select PROCESSOR_NS9360 + select BOARD_JSCC9P9360 + help + Say Y here if you are using the Digi ConnectCore 9P 9360 + on an JSCC9P9360 Development Board. + config PROCESSOR_NS9360 bool config BOARD_A9M9750DEV bool +config BOARD_JSCC9P9360 + bool + endmenu endif diff --git a/arch/arm/mach-ns9xxx/Makefile b/arch/arm/mach-ns9xxx/Makefile index 91e945f5e16d..53213a69f601 100644 --- a/arch/arm/mach-ns9xxx/Makefile +++ b/arch/arm/mach-ns9xxx/Makefile @@ -3,3 +3,4 @@ obj-y := irq.o time.o generic.o obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o obj-$(CONFIG_BOARD_A9M9750DEV) += board-a9m9750dev.o +obj-$(CONFIG_BOARD_JSCC9P9360) += board-jscc9p9360.o diff --git a/arch/arm/mach-ns9xxx/board-jscc9p9360.c b/arch/arm/mach-ns9xxx/board-jscc9p9360.c new file mode 100644 index 000000000000..4bd3eec04bfe --- /dev/null +++ b/arch/arm/mach-ns9xxx/board-jscc9p9360.c @@ -0,0 +1,17 @@ +/* + * arch/arm/mach-ns9xxx/board-jscc9p9360.c + * + * Copyright (C) 2006,2007 by Digi International Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#include "board-jscc9p9360.h" + +void __init board_jscc9p9360_init_machine(void) +{ + /* TODO: reserve GPIOs for push buttons, etc pp */ +} + diff --git a/arch/arm/mach-ns9xxx/board-jscc9p9360.h b/arch/arm/mach-ns9xxx/board-jscc9p9360.h new file mode 100644 index 000000000000..1a81a074df45 --- /dev/null +++ b/arch/arm/mach-ns9xxx/board-jscc9p9360.h @@ -0,0 +1,13 @@ +/* + * arch/arm/mach-ns9xxx/board-jscc9p9360.h + * + * Copyright (C) 2006 by Digi International Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#include + +void __init board_jscc9p9360_init_machine(void); diff --git a/arch/arm/mach-ns9xxx/mach-cc9p9360js.c b/arch/arm/mach-ns9xxx/mach-cc9p9360js.c new file mode 100644 index 000000000000..d09d5fa5620a --- /dev/null +++ b/arch/arm/mach-ns9xxx/mach-cc9p9360js.c @@ -0,0 +1,29 @@ +/* + * arch/arm/mach-ns9xxx/mach-cc9p9360js.c + * + * Copyright (C) 2006 by Digi International Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#include +#include + +#include "board-jscc9p9360.h" +#include "generic.h" + +static void __init mach_cc9p9360js_init_machine(void) +{ + ns9xxx_init_machine(); + board_jscc9p9360_init_machine(); +} + +MACHINE_START(CC9P9360DEV, "Digi ConnectCore 9P 9360 on an JSCC9P9360 Devboard") + .map_io = ns9xxx_map_io, + .init_irq = ns9xxx_init_irq, + .init_machine = mach_cc9p9360js_init_machine, + .timer = &ns9xxx_timer, + .boot_params = 0x100, +MACHINE_END diff --git a/include/asm-arm/arch-ns9xxx/board.h b/include/asm-arm/arch-ns9xxx/board.h index 91dc8fb1027f..716f34fdb716 100644 --- a/include/asm-arm/arch-ns9xxx/board.h +++ b/include/asm-arm/arch-ns9xxx/board.h @@ -15,4 +15,6 @@ #define board_is_a9m9750dev() (machine_is_cc9p9360dev()) +#define board_is_jscc9p9360() (machine_is_cc9p9360js()) + #endif /* ifndef __ASM_ARCH_BOARD_H */ diff --git a/include/asm-arm/arch-ns9xxx/processor.h b/include/asm-arm/arch-ns9xxx/processor.h index 716c106ac0bf..223e51b8e104 100644 --- a/include/asm-arm/arch-ns9xxx/processor.h +++ b/include/asm-arm/arch-ns9xxx/processor.h @@ -13,6 +13,7 @@ #include -#define processor_is_ns9360() (machine_is_cc9p9360dev()) +#define processor_is_ns9360() (machine_is_cc9p9360dev() \ + || machine_is_cc9p9360js()) #endif /* ifndef __ASM_ARCH_PROCESSOR_H */ -- cgit v1.2.3-59-g8ed1b From ce89c206ac03dfec700cfa538dcbcc347c0683ce Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 20 Apr 2007 11:15:27 +0100 Subject: [ARM] 4324/1: S3C24XX: remove clocks from s3c24xx_board Remove the clocks from the s3c24xx_board as part of the process of simplifying the initialisation sequence by removing struct s3c24xx_board. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/mach-bast.c | 4 ++-- arch/arm/mach-s3c2410/mach-vr1000.c | 4 ++-- arch/arm/mach-s3c2440/mach-anubis.c | 4 ++-- arch/arm/mach-s3c2440/mach-osiris.c | 4 ++-- arch/arm/plat-s3c24xx/clock.c | 12 ++++++++++++ arch/arm/plat-s3c24xx/cpu.c | 9 --------- include/asm-arm/plat-s3c24xx/clock.h | 1 + include/asm-arm/plat-s3c24xx/cpu.h | 3 --- 8 files changed, 21 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 7b81296427eb..0bb2e8b2dd28 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -467,8 +467,6 @@ static struct clk *bast_clocks[] = { static struct s3c24xx_board bast_board __initdata = { .devices = bast_devices, .devices_count = ARRAY_SIZE(bast_devices), - .clocks = bast_clocks, - .clocks_count = ARRAY_SIZE(bast_clocks), }; static void __init bast_map_io(void) @@ -486,6 +484,8 @@ static void __init bast_map_io(void) s3c24xx_uclk.parent = &s3c24xx_clkout1; + s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks)); + s3c_device_nand.dev.platform_data = &bast_nand_info; s3c_device_i2c.dev.platform_data = &bast_i2c_info; diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index c947c75bcbf0..9380a1360890 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c @@ -387,8 +387,6 @@ static struct clk *vr1000_clocks[] = { static struct s3c24xx_board vr1000_board __initdata = { .devices = vr1000_devices, .devices_count = ARRAY_SIZE(vr1000_devices), - .clocks = vr1000_clocks, - .clocks_count = ARRAY_SIZE(vr1000_clocks), }; static void vr1000_power_off(void) @@ -412,6 +410,8 @@ static void __init vr1000_map_io(void) s3c24xx_uclk.parent = &s3c24xx_clkout1; + s3c24xx_register_clocks(vr1000_clocks, ARRAY_SIZE(vr1000_clocks)); + pm_power_off = vr1000_power_off; s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc)); diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c index 3f0288eb1ed5..0f4e2882aa13 100644 --- a/arch/arm/mach-s3c2440/mach-anubis.c +++ b/arch/arm/mach-s3c2440/mach-anubis.c @@ -284,8 +284,6 @@ static struct clk *anubis_clocks[] = { static struct s3c24xx_board anubis_board __initdata = { .devices = anubis_devices, .devices_count = ARRAY_SIZE(anubis_devices), - .clocks = anubis_clocks, - .clocks_count = ARRAY_SIZE(anubis_clocks), }; static void __init anubis_map_io(void) @@ -303,6 +301,8 @@ static void __init anubis_map_io(void) s3c24xx_uclk.parent = &s3c24xx_clkout1; + s3c24xx_register_clocks(anubis_clocks, ARRAY_SIZE(anubis_clocks)); + s3c_device_nand.dev.platform_data = &anubis_nand_info; s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc)); diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c index 2ed8e51f20c8..c9872210ab5a 100644 --- a/arch/arm/mach-s3c2440/mach-osiris.c +++ b/arch/arm/mach-s3c2440/mach-osiris.c @@ -254,8 +254,6 @@ static struct clk *osiris_clocks[] = { static struct s3c24xx_board osiris_board __initdata = { .devices = osiris_devices, .devices_count = ARRAY_SIZE(osiris_devices), - .clocks = osiris_clocks, - .clocks_count = ARRAY_SIZE(osiris_clocks), }; static void __init osiris_map_io(void) @@ -275,6 +273,8 @@ static void __init osiris_map_io(void) s3c24xx_uclk.parent = &s3c24xx_clkout1; + s3c24xx_register_clocks(osiris_clocks, ARRAY_SIZE(osiris_clocks)); + s3c_device_nand.dev.platform_data = &osiris_nand_info; s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc)); diff --git a/arch/arm/plat-s3c24xx/clock.c b/arch/arm/plat-s3c24xx/clock.c index d3dc03a7383a..79cda0faec86 100644 --- a/arch/arm/plat-s3c24xx/clock.c +++ b/arch/arm/plat-s3c24xx/clock.c @@ -404,6 +404,18 @@ int s3c24xx_register_clock(struct clk *clk) return 0; } +int s3c24xx_register_clocks(struct clk **clks, int nr_clks) +{ + int fails = 0; + + for (; nr_clks > 0; nr_clks--, clks++) { + if (s3c24xx_register_clock(*clks) < 0) + fails++; + } + + return fails; +} + /* initalise all the clocks */ int __init s3c24xx_setup_clocks(unsigned long xtal, diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c index 6a2d1070e5a0..3e314a296255 100644 --- a/arch/arm/plat-s3c24xx/cpu.c +++ b/arch/arm/plat-s3c24xx/cpu.c @@ -187,16 +187,7 @@ static struct s3c24xx_board *board; void s3c24xx_set_board(struct s3c24xx_board *b) { - int i; - board = b; - - if (b->clocks_count != 0) { - struct clk **ptr = b->clocks; - - for (i = b->clocks_count; i > 0; i--, ptr++) - s3c24xx_register_clock(*ptr); - } } /* cpu information */ diff --git a/include/asm-arm/plat-s3c24xx/clock.h b/include/asm-arm/plat-s3c24xx/clock.h index f6135dbb9fa9..235b753cd877 100644 --- a/include/asm-arm/plat-s3c24xx/clock.h +++ b/include/asm-arm/plat-s3c24xx/clock.h @@ -56,6 +56,7 @@ extern struct mutex clocks_mutex; extern int s3c2410_clkcon_enable(struct clk *clk, int enable); extern int s3c24xx_register_clock(struct clk *clk); +extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks); extern int s3c24xx_setup_clocks(unsigned long xtal, unsigned long fclk, diff --git a/include/asm-arm/plat-s3c24xx/cpu.h b/include/asm-arm/plat-s3c24xx/cpu.h index 15dd18810905..8c17ca4348f1 100644 --- a/include/asm-arm/plat-s3c24xx/cpu.h +++ b/include/asm-arm/plat-s3c24xx/cpu.h @@ -49,9 +49,6 @@ extern void s3c24xx_init_uartdevs(char *name, struct s3c24xx_board { struct platform_device **devices; unsigned int devices_count; - - struct clk **clocks; - unsigned int clocks_count; }; extern void s3c24xx_set_board(struct s3c24xx_board *board); -- cgit v1.2.3-59-g8ed1b From 57e5171c9ff817d56344d8473e484d6870ae2bf3 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 20 Apr 2007 11:19:16 +0100 Subject: [ARM] 4325/1: S3C24XX: remove s3c24xx_board Remove the use of struct s3c24xx_board as this is just as easily done by using the platform device registration functions to make the initialisation sequence easier. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/mach-amlm5900.c | 7 +------ arch/arm/mach-s3c2410/mach-bast.c | 8 ++------ arch/arm/mach-s3c2410/mach-h1940.c | 9 ++------- arch/arm/mach-s3c2410/mach-n30.c | 8 ++------ arch/arm/mach-s3c2410/mach-otom.c | 12 +++++------- arch/arm/mach-s3c2410/mach-qt2410.c | 7 +------ arch/arm/mach-s3c2410/mach-smdk2410.c | 14 +++++++------- arch/arm/mach-s3c2410/mach-vr1000.c | 12 +++++------- arch/arm/mach-s3c2412/mach-smdk2413.c | 7 +------ arch/arm/mach-s3c2412/mach-vstms.c | 12 ++++++------ arch/arm/mach-s3c2440/mach-anubis.c | 13 +++++++------ arch/arm/mach-s3c2440/mach-nexcoder.c | 13 ++++++------- arch/arm/mach-s3c2440/mach-osiris.c | 12 ++++++------ arch/arm/mach-s3c2440/mach-rx3715.c | 8 +------- arch/arm/mach-s3c2440/mach-smdk2440.c | 7 +------ arch/arm/mach-s3c2443/mach-smdk2443.c | 7 +------ arch/arm/plat-s3c24xx/cpu.c | 29 ----------------------------- include/asm-arm/plat-s3c24xx/cpu.h | 13 ------------- 18 files changed, 54 insertions(+), 144 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c index 72f2cc4fcd03..bc308ceb91c3 100644 --- a/arch/arm/mach-s3c2410/mach-amlm5900.c +++ b/arch/arm/mach-s3c2410/mach-amlm5900.c @@ -160,17 +160,11 @@ static struct platform_device *amlm5900_devices[] __initdata = { #endif }; -static struct s3c24xx_board amlm5900_board __initdata = { - .devices = amlm5900_devices, - .devices_count = ARRAY_SIZE(amlm5900_devices) -}; - void __init amlm5900_map_io(void) { s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs)); - s3c24xx_set_board(&amlm5900_board); } #ifdef CONFIG_FB_S3C2410 @@ -247,6 +241,7 @@ static void __init amlm5900_init(void) #ifdef CONFIG_FB_S3C2410 s3c24xx_fb_set_platdata(&amlm5900_lcd_info); #endif + platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices)); } MACHINE_START(AML_M5900, "AML_M5900") diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 0bb2e8b2dd28..f01de807b72f 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -464,11 +464,6 @@ static struct clk *bast_clocks[] = { &s3c24xx_uclk, }; -static struct s3c24xx_board bast_board __initdata = { - .devices = bast_devices, - .devices_count = ARRAY_SIZE(bast_devices), -}; - static void __init bast_map_io(void) { /* initialise the clocks */ @@ -492,13 +487,14 @@ static void __init bast_map_io(void) s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs)); - s3c24xx_set_board(&bast_board); + usb_simtec_init(); } static void __init bast_init(void) { s3c24xx_fb_set_platdata(&bast_lcd_info); + platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices)); } MACHINE_START(BAST, "Simtec-BAST") diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index d052ab2d9377..5d5f00e9c462 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -129,7 +129,6 @@ static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = { }; - /** * Set lcd on or off **/ @@ -188,17 +187,11 @@ static struct platform_device *h1940_devices[] __initdata = { &s3c_device_leds, }; -static struct s3c24xx_board h1940_board __initdata = { - .devices = h1940_devices, - .devices_count = ARRAY_SIZE(h1940_devices) -}; - static void __init h1940_map_io(void) { s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs)); - s3c24xx_set_board(&h1940_board); /* setup PM */ @@ -232,6 +225,8 @@ static void __init h1940_init(void) | (0x02 << S3C2410_PLLCON_PDIVSHIFT) | (0x03 << S3C2410_PLLCON_SDIVSHIFT); writel(tmp, S3C2410_UPLLCON); + + platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices)); } MACHINE_START(H1940, "IPAQ-H1940") diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 261aa4cc0770..412e50c3d28a 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -90,17 +90,11 @@ static struct s3c2410_platform_i2c n30_i2ccfg = { .max_freq = 10*1000, }; -static struct s3c24xx_board n30_board __initdata = { - .devices = n30_devices, - .devices_count = ARRAY_SIZE(n30_devices) -}; - static void __init n30_map_io(void) { s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs)); - s3c24xx_set_board(&n30_board); } static void __init n30_init_irq(void) @@ -120,6 +114,8 @@ static void __init n30_init(void) s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST | S3C2410_MISCCR_USBSUSPND0 | S3C2410_MISCCR_USBSUSPND1, 0x0); + + platform_add_devices(n30_devices, ARRAY_SIZE(n30_devices)); } MACHINE_START(N30, "Acer-N30") diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c index c78ab75b44f3..1f899fa588df 100644 --- a/arch/arm/mach-s3c2410/mach-otom.c +++ b/arch/arm/mach-s3c2410/mach-otom.c @@ -100,20 +100,17 @@ static struct platform_device *otom11_devices[] __initdata = { &otom_device_nor, }; -static struct s3c24xx_board otom11_board __initdata = { - .devices = otom11_devices, - .devices_count = ARRAY_SIZE(otom11_devices) -}; - - static void __init otom11_map_io(void) { s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs)); - s3c24xx_set_board(&otom11_board); } +static void __init otom11_init(void) +{ + platform_add_devices(otom11_devices, ARRAY_SIZE(otom11_devices)); +} MACHINE_START(OTOM, "Nex Vision - Otom 1.1") /* Maintainer: Guillaume GOURAT */ @@ -121,6 +118,7 @@ MACHINE_START(OTOM, "Nex Vision - Otom 1.1") .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = otom11_map_io, + .init_machine = otom11_init, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c index c6a41593de21..caf6778472d3 100644 --- a/arch/arm/mach-s3c2410/mach-qt2410.c +++ b/arch/arm/mach-s3c2410/mach-qt2410.c @@ -331,11 +331,6 @@ static struct platform_device *qt2410_devices[] __initdata = { &qt2410_led, }; -static struct s3c24xx_board qt2410_board __initdata = { - .devices = qt2410_devices, - .devices_count = ARRAY_SIZE(qt2410_devices) -}; - static struct mtd_partition qt2410_nand_part[] = { [0] = { .name = "U-Boot", @@ -405,7 +400,6 @@ static void __init qt2410_map_io(void) s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc)); s3c24xx_init_clocks(12*1000*1000); s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs)); - s3c24xx_set_board(&qt2410_board); } static void __init qt2410_machine_init(void) @@ -432,6 +426,7 @@ static void __init qt2410_machine_init(void) s3c2410_gpio_cfgpin(S3C2410_GPB5, S3C2410_GPIO_OUTPUT); + platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices)); s3c2410_pm_init(); } diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c index 57b8a80f33d0..5852d300d52f 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2410.c +++ b/arch/arm/mach-s3c2410/mach-smdk2410.c @@ -94,17 +94,17 @@ static struct platform_device *smdk2410_devices[] __initdata = { &s3c_device_iis, }; -static struct s3c24xx_board smdk2410_board __initdata = { - .devices = smdk2410_devices, - .devices_count = ARRAY_SIZE(smdk2410_devices) -}; - static void __init smdk2410_map_io(void) { s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs)); - s3c24xx_set_board(&smdk2410_board); +} + +static void __init smdk2410_init(void) +{ + platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices)); + smdk_machine_init(); } MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch @@ -115,7 +115,7 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = smdk2410_map_io, .init_irq = s3c24xx_init_irq, - .init_machine = smdk_machine_init, + .init_machine = smdk2410_init, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index 9380a1360890..7b624bb00490 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c @@ -384,11 +384,6 @@ static struct clk *vr1000_clocks[] = { &s3c24xx_uclk, }; -static struct s3c24xx_board vr1000_board __initdata = { - .devices = vr1000_devices, - .devices_count = ARRAY_SIZE(vr1000_devices), -}; - static void vr1000_power_off(void) { s3c2410_gpio_cfgpin(S3C2410_GPB9, S3C2410_GPB9_OUTP); @@ -417,10 +412,12 @@ static void __init vr1000_map_io(void) s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs)); - s3c24xx_set_board(&vr1000_board); - usb_simtec_init(); } +static void __init vr1000_init(void) +{ + platform_add_devices(vr1000_devices, ARRAY_SIZE(vr1000_devices)); +} MACHINE_START(VR1000, "Thorcom-VR1000") /* Maintainer: Ben Dooks */ @@ -428,6 +425,7 @@ MACHINE_START(VR1000, "Thorcom-VR1000") .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = vr1000_map_io, + .init_machine = vr1000_init, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c index b5befce6c8d3..063af09f899d 100644 --- a/arch/arm/mach-s3c2412/mach-smdk2413.c +++ b/arch/arm/mach-s3c2412/mach-smdk2413.c @@ -110,11 +110,6 @@ static struct platform_device *smdk2413_devices[] __initdata = { &s3c_device_usbgadget, }; -static struct s3c24xx_board smdk2413_board __initdata = { - .devices = smdk2413_devices, - .devices_count = ARRAY_SIZE(smdk2413_devices) -}; - static void __init smdk2413_fixup(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi) @@ -132,7 +127,6 @@ static void __init smdk2413_map_io(void) s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs)); - s3c24xx_set_board(&smdk2413_board); } static void __init smdk2413_machine_init(void) @@ -149,6 +143,7 @@ static void __init smdk2413_machine_init(void) s3c24xx_udc_set_platdata(&smdk2413_udc_cfg); + platform_add_devices(smdk2413_devices, ARRAY_SIZE(smdk2413_devices)); smdk_machine_init(); } diff --git a/arch/arm/mach-s3c2412/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c index 4231b549d797..f2fbd65956ac 100644 --- a/arch/arm/mach-s3c2412/mach-vstms.c +++ b/arch/arm/mach-s3c2412/mach-vstms.c @@ -129,11 +129,6 @@ static struct platform_device *vstms_devices[] __initdata = { &s3c_device_nand, }; -static struct s3c24xx_board vstms_board __initdata = { - .devices = vstms_devices, - .devices_count = ARRAY_SIZE(vstms_devices) -}; - static void __init vstms_fixup(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi) @@ -153,7 +148,11 @@ static void __init vstms_map_io(void) s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs)); - s3c24xx_set_board(&vstms_board); +} + +static void __init vstms_init(void) +{ + platform_add_devices(vstms_devices, ARRAY_SIZE(vstms_devices)); } MACHINE_START(VSTMS, "VSTMS") @@ -163,6 +162,7 @@ MACHINE_START(VSTMS, "VSTMS") .fixup = vstms_fixup, .init_irq = s3c24xx_init_irq, + .init_machine = vstms_init, .map_io = vstms_map_io, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c index 0f4e2882aa13..b5d387ef37e1 100644 --- a/arch/arm/mach-s3c2440/mach-anubis.c +++ b/arch/arm/mach-s3c2440/mach-anubis.c @@ -281,11 +281,6 @@ static struct clk *anubis_clocks[] = { &s3c24xx_uclk, }; -static struct s3c24xx_board anubis_board __initdata = { - .devices = anubis_devices, - .devices_count = ARRAY_SIZE(anubis_devices), -}; - static void __init anubis_map_io(void) { /* initialise the clocks */ @@ -308,18 +303,24 @@ static void __init anubis_map_io(void) s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs)); - s3c24xx_set_board(&anubis_board); /* ensure that the GPIO is setup */ s3c2410_gpio_setpin(S3C2410_GPA0, 1); } +static void __init anubis_init(void) +{ + platform_add_devices(anubis_devices, ARRAY_SIZE(anubis_devices)); +} + + MACHINE_START(ANUBIS, "Simtec-Anubis") /* Maintainer: Ben Dooks */ .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = anubis_map_io, + .init_machine = anubis_init, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c index 6d551d88330b..5e61f2166c76 100644 --- a/arch/arm/mach-s3c2440/mach-nexcoder.c +++ b/arch/arm/mach-s3c2440/mach-nexcoder.c @@ -116,12 +116,6 @@ static struct platform_device *nexcoder_devices[] __initdata = { &nexcoder_device_nor, }; -static struct s3c24xx_board nexcoder_board __initdata = { - .devices = nexcoder_devices, - .devices_count = ARRAY_SIZE(nexcoder_devices), -}; - - static void __init nexcoder_sensorboard_init(void) { // Initialize SCCB bus @@ -142,10 +136,14 @@ static void __init nexcoder_map_io(void) s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs)); - s3c24xx_set_board(&nexcoder_board); + nexcoder_sensorboard_init(); } +static void __init nexcoder_init(void) +{ + platform_add_devices(nexcoder_devices, ARRAY_SIZE(nexcoder_devices)); +}; MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440") /* Maintainer: Guillaume GOURAT */ @@ -153,6 +151,7 @@ MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440") .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = nexcoder_map_io, + .init_machine = nexcoder_init, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c index c9872210ab5a..324f5a237921 100644 --- a/arch/arm/mach-s3c2440/mach-osiris.c +++ b/arch/arm/mach-s3c2440/mach-osiris.c @@ -251,11 +251,6 @@ static struct clk *osiris_clocks[] = { &s3c24xx_uclk, }; -static struct s3c24xx_board osiris_board __initdata = { - .devices = osiris_devices, - .devices_count = ARRAY_SIZE(osiris_devices), -}; - static void __init osiris_map_io(void) { unsigned long flags; @@ -280,7 +275,6 @@ static void __init osiris_map_io(void) s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs)); - s3c24xx_set_board(&osiris_board); /* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */ @@ -292,12 +286,18 @@ static void __init osiris_map_io(void) s3c2410_gpio_setpin(S3C2410_GPA0, 1); } +static void __init osiris_init(void) +{ + platform_add_devices(osiris_devices, ARRAY_SIZE(osiris_devices)); +}; + MACHINE_START(OSIRIS, "Simtec-OSIRIS") /* Maintainer: Ben Dooks */ .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = osiris_map_io, + .init_machine = osiris_init, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c index ae1d0a81fd6a..c3cc4bf158f6 100644 --- a/arch/arm/mach-s3c2440/mach-rx3715.c +++ b/arch/arm/mach-s3c2440/mach-rx3715.c @@ -202,11 +202,6 @@ static struct platform_device *rx3715_devices[] __initdata = { &s3c_device_nand, }; -static struct s3c24xx_board rx3715_board __initdata = { - .devices = rx3715_devices, - .devices_count = ARRAY_SIZE(rx3715_devices) -}; - static void __init rx3715_map_io(void) { s3c_device_nand.dev.platform_data = &rx3715_nand_info; @@ -214,7 +209,6 @@ static void __init rx3715_map_io(void) s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc)); s3c24xx_init_clocks(16934000); s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs)); - s3c24xx_set_board(&rx3715_board); } static void __init rx3715_init_irq(void) @@ -230,9 +224,9 @@ static void __init rx3715_init_machine(void) s3c2410_pm_init(); s3c24xx_fb_set_platdata(&rx3715_lcdcfg); + platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices)); } - MACHINE_START(RX3715, "IPAQ-RX3715") /* Maintainer: Ben Dooks */ .phys_io = S3C2410_PA_UART, diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c index c17eb5b1f6b4..e167254e232e 100644 --- a/arch/arm/mach-s3c2440/mach-smdk2440.c +++ b/arch/arm/mach-s3c2440/mach-smdk2440.c @@ -174,23 +174,18 @@ static struct platform_device *smdk2440_devices[] __initdata = { &s3c_device_iis, }; -static struct s3c24xx_board smdk2440_board __initdata = { - .devices = smdk2440_devices, - .devices_count = ARRAY_SIZE(smdk2440_devices) -}; - static void __init smdk2440_map_io(void) { s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc)); s3c24xx_init_clocks(16934400); s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs)); - s3c24xx_set_board(&smdk2440_board); } static void __init smdk2440_machine_init(void) { s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg); + platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices)); smdk_machine_init(); } diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c2443/mach-smdk2443.c index e82aaff7dee4..b71ee53c2865 100644 --- a/arch/arm/mach-s3c2443/mach-smdk2443.c +++ b/arch/arm/mach-s3c2443/mach-smdk2443.c @@ -106,21 +106,16 @@ static struct platform_device *smdk2443_devices[] __initdata = { &s3c_device_i2c, }; -static struct s3c24xx_board smdk2443_board __initdata = { - .devices = smdk2443_devices, - .devices_count = ARRAY_SIZE(smdk2443_devices) -}; - static void __init smdk2443_map_io(void) { s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs)); - s3c24xx_set_board(&smdk2443_board); } static void __init smdk2443_machine_init(void) { + platform_add_devices(smdk2443_devices, ARRAY_SIZE(smdk2443_devices)); smdk_machine_init(); } diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c index 3e314a296255..8ce4904d3131 100644 --- a/arch/arm/plat-s3c24xx/cpu.c +++ b/arch/arm/plat-s3c24xx/cpu.c @@ -181,15 +181,6 @@ s3c_lookup_cpu(unsigned long idcode) return NULL; } -/* board information */ - -static struct s3c24xx_board *board; - -void s3c24xx_set_board(struct s3c24xx_board *b) -{ - board = b; -} - /* cpu information */ static struct cpu_table *cpu; @@ -333,26 +324,6 @@ static int __init s3c_arch_init(void) return ret; ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts); - if (ret != 0) - return ret; - - if (board != NULL) { - struct platform_device **ptr = board->devices; - int i; - - for (i = 0; i < board->devices_count; i++, ptr++) { - ret = platform_device_register(*ptr); - - if (ret) { - printk(KERN_ERR "s3c24xx: failed to add board device %s (%d) @%p\n", (*ptr)->name, ret, *ptr); - } - } - - /* mask any error, we may not need all these board - * devices */ - ret = 0; - } - return ret; } diff --git a/include/asm-arm/plat-s3c24xx/cpu.h b/include/asm-arm/plat-s3c24xx/cpu.h index 8c17ca4348f1..23e420e8bd5b 100644 --- a/include/asm-arm/plat-s3c24xx/cpu.h +++ b/include/asm-arm/plat-s3c24xx/cpu.h @@ -40,19 +40,6 @@ extern void s3c24xx_init_uartdevs(char *name, struct s3c24xx_uart_resources *res, struct s3c2410_uartcfg *cfg, int no); -/* the board structure is used at first initialsation time - * to get info such as the devices to register for this - * board. This is done because platfrom_add_devices() cannot - * be called from the map_io entry. -*/ - -struct s3c24xx_board { - struct platform_device **devices; - unsigned int devices_count; -}; - -extern void s3c24xx_set_board(struct s3c24xx_board *board); - /* timer for 2410/2440 */ struct sys_timer; -- cgit v1.2.3-59-g8ed1b From a7717435656c874843b1742383cc37540f5ff91e Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 20 Apr 2007 11:39:46 +0100 Subject: [ARM] 4326/1: S3C24XX: fix sparse errors in DMA code Fix the following sparse errors in arch/arm/plat-s3c24xx/dma.c: dma.c:47:30: warning: symbol 'dma_sel' was not declared. Should it be static? dma.c:883:6: warning: symbol 's3c2410_dma_waitforstop' was not declared. Should it be static? dma.c:961:1: warning: symbol 's3c2410_dma_started' was not declared. Should it be static? dma.c:1283:12: warning: symbol 's3c24xx_dma_sysclass_init' was not declared. Should it be static? dma.c:1295:12: warning: symbol 's3c24xx_dma_sysdev_register' was not declared. Should it be static? dma.c:1399:25: warning: symbol 's3c2410_dma_map_channel' was not declared. Should it be static? The patch makes all the relevant functions static. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/plat-s3c24xx/dma.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 4540a806f522..6f03c9370979 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -44,7 +44,7 @@ static struct kmem_cache *dma_kmem; static int dma_channels; -struct s3c24xx_dma_selection dma_sel; +static struct s3c24xx_dma_selection dma_sel; /* dma channel state information */ struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; @@ -880,7 +880,7 @@ static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan) return 0; } -void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan) +static void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan) { unsigned long tmp; unsigned int timeout = 0x10000; @@ -957,8 +957,7 @@ static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan) return 0; } -int -s3c2410_dma_started(struct s3c2410_dma_chan *chan) +static int s3c2410_dma_started(struct s3c2410_dma_chan *chan) { unsigned long flags; @@ -1280,7 +1279,7 @@ static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long /* initialisation code */ -int __init s3c24xx_dma_sysclass_init(void) +static int __init s3c24xx_dma_sysclass_init(void) { int ret = sysdev_class_register(&dma_sysclass); @@ -1292,7 +1291,7 @@ int __init s3c24xx_dma_sysclass_init(void) core_initcall(s3c24xx_dma_sysclass_init); -int __init s3c24xx_dma_sysdev_register(void) +static int __init s3c24xx_dma_sysdev_register(void) { struct s3c2410_dma_chan *cp = s3c2410_chans; int channel, ret; @@ -1396,7 +1395,7 @@ static struct s3c24xx_dma_order *dma_order; * channel */ -struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel) +static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel) { struct s3c24xx_dma_order_ch *ord = NULL; struct s3c24xx_dma_map *ch_map; -- cgit v1.2.3-59-g8ed1b From 6f621885feba507d40dd1bba253378ae04f9fe8e Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 11 Apr 2007 12:42:09 +0100 Subject: [ARM] 4319/1: S3C2412: Add kconfig for MACH_SMDK2412 Add Kconfig entry for SMDK2412 to go with the SMDK2413 Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2412/Kconfig | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig index befc5fdbb613..d5be5d053264 100644 --- a/arch/arm/mach-s3c2412/Kconfig +++ b/arch/arm/mach-s3c2412/Kconfig @@ -47,6 +47,15 @@ config MACH_S3C2413 machine_is_s3c2413() will work when MACH_SMDK2413 is selected +config MACH_SMDK2412 + bool "SMDK2412" + select MACH_SMDK2413 + help + Say Y here if you are using an SMDK2412 + + Note, this shares support with SMDK2413, so will automatically + select MACH_SMDK2413. + config MACH_VSTMS bool "VMSTMS" select CPU_S3C2412 -- cgit v1.2.3-59-g8ed1b From 5d01f133412b0e27b340ab1bbb2cf0017329ae61 Mon Sep 17 00:00:00 2001 From: Simon Richter Date: Mon, 2 Apr 2007 14:06:29 +0100 Subject: [ARM] 4300/1: Add picotux 200 ARM board Add the picotux 200 ARM board: - Enable its machine type in the filter in head.S - Add configuration option - Add board initialisation - Add default configuration Signed-off-by: Simon Richter Signed-off-by: Russell King --- arch/arm/boot/compressed/head-at91rm9200.S | 6 + arch/arm/configs/picotux200_defconfig | 1386 ++++++++++++++++++++++++++++ arch/arm/mach-at91/Kconfig | 7 + arch/arm/mach-at91/Makefile | 1 + arch/arm/mach-at91/board-picotux200.c | 166 ++++ 5 files changed, 1566 insertions(+) create mode 100644 arch/arm/configs/picotux200_defconfig create mode 100644 arch/arm/mach-at91/board-picotux200.c (limited to 'arch') diff --git a/arch/arm/boot/compressed/head-at91rm9200.S b/arch/arm/boot/compressed/head-at91rm9200.S index d68b9acd826e..11782ccd93a1 100644 --- a/arch/arm/boot/compressed/head-at91rm9200.S +++ b/arch/arm/boot/compressed/head-at91rm9200.S @@ -61,6 +61,12 @@ cmp r7, r3 beq 99f + @ picotux 200 : 963 + mov r3, #(MACH_TYPE_PICOTUX2XX & 0xff) + orr r3, r3, #(MACH_TYPE_PICOTUX2XX & 0xff00) + cmp r7, r3 + beq 99f + @ Ajeco 1ARM : 1075 mov r3, #(MACH_TYPE_ONEARM & 0xff) orr r3, r3, #(MACH_TYPE_ONEARM & 0xff00) diff --git a/arch/arm/configs/picotux200_defconfig b/arch/arm/configs/picotux200_defconfig new file mode 100644 index 000000000000..339c48953a62 --- /dev/null +++ b/arch/arm/configs/picotux200_defconfig @@ -0,0 +1,1386 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.21-rc4 +# Wed Mar 28 16:19:50 2007 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +# CONFIG_GENERIC_TIME is not set +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=m +CONFIG_IKCONFIG_PROC=y +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RELAY is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +# CONFIG_KALLSYMS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +CONFIG_ARCH_AT91=y +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set + +# +# Atmel AT91 System-on-Chip +# +CONFIG_ARCH_AT91RM9200=y +# CONFIG_ARCH_AT91SAM9260 is not set +# CONFIG_ARCH_AT91SAM9261 is not set +# CONFIG_ARCH_AT91SAM9263 is not set + +# +# AT91RM9200 Board Type +# +# CONFIG_MACH_ONEARM is not set +# CONFIG_ARCH_AT91RM9200DK is not set +# CONFIG_MACH_AT91RM9200EK is not set +# CONFIG_MACH_CSB337 is not set +# CONFIG_MACH_CSB637 is not set +# CONFIG_MACH_CARMEVA is not set +# CONFIG_MACH_ATEB9200 is not set +# CONFIG_MACH_KB9200 is not set +CONFIG_MACH_PICOTUX2XX=y +# CONFIG_MACH_KAFA is not set + +# +# AT91 Board Options +# + +# +# AT91 Feature Selections +# +CONFIG_AT91_PROGRAMMABLE_CLOCKS=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4T=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_NO_IDLE_HZ=y +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +CONFIG_KEXEC=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=m + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=y +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +# CONFIG_BT_HCIUART is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +# CONFIG_BT_HCIVHCI is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=m +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_ARM_AT91_ETHER=y +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLHC=m +CONFIG_SLIP_SMART=y +CONFIG_SLIP_MODE_SLIP6=y +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_ATMEL=y +CONFIG_SERIAL_ATMEL_CONSOLE=y +# CONFIG_SERIAL_ATMEL_TTYAT is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_AT91RM9200_WATCHDOG=m + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_HW_RANDOM=m +# CONFIG_NVRAM is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=m +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +CONFIG_I2C_AT91=m +CONFIG_I2C_ISA=m +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8591=m +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=m +CONFIG_HWMON_VID=m +# CONFIG_SENSORS_ABITUGURU is not set +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +CONFIG_SENSORS_DS1621=m +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_MAX1619=m +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +CONFIG_SENSORS_SMSC47B397=m +# CONFIG_SENSORS_VT1211 is not set +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# HID Devices +# +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=m +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set +# CONFIG_USB_GTCO is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET_MII=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_ZAURUS=m +# CONFIG_USB_MON is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_AIRPRIME is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP2101 is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_BLOCK=m +CONFIG_MMC_AT91=m + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=m + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=m +CONFIG_RTC_INTF_PROC=m +CONFIG_RTC_INTF_DEV=m +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set + +# +# RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_M48T86 is not set +CONFIG_RTC_DRV_AT91RM9200=m +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# File systems +# +CONFIG_EXT2_FS=m +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +CONFIG_AMIGA_PARTITION=y +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="utf-8" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +# CONFIG_FORCED_INLINING is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_HASH=m +CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_HMAC=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_TEST=m + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +CONFIG_CRC32=y +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index bf0d96272e3a..e238ad8cfd8f 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -81,6 +81,13 @@ config MACH_KB9200 Select this if you are using KwikByte's KB920x board. +config MACH_PICOTUX2XX + bool "picotux 200" + depends on ARCH_AT91RM9200 + help + Select this if you are using a picotux 200. + + config MACH_KAFA bool "Sperry-Sun KAFA board" depends on ARCH_AT91RM9200 diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 05de6cdc88f1..a412ae18a421 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_MACH_CARMEVA) += board-carmeva.o obj-$(CONFIG_MACH_KB9200) += board-kb9202.o obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o obj-$(CONFIG_MACH_KAFA) += board-kafa.o +obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o # AT91SAM9260 board-specific support obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c new file mode 100644 index 000000000000..49cfe7ab4a85 --- /dev/null +++ b/arch/arm/mach-at91/board-picotux200.c @@ -0,0 +1,166 @@ +/* + * linux/arch/arm/mach-at91/board-picotux200.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2007 Kleinhenz Elektronik GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "generic.h" + + +/* + * Serial port configuration. + * 0 .. 3 = USART0 .. USART3 + * 4 = DBGU + */ +static struct at91_uart_config __initdata picotux200_uart_config = { + .console_tty = 0, /* ttyS0 */ + .nr_tty = 2, + .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */ +}; + +static void __init picotux200_map_io(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000, AT91RM9200_BGA); + + /* Setup the serial ports and console */ + at91_init_serial(&picotux200_uart_config); +} + +static void __init picotux200_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + +static struct at91_eth_data __initdata picotux200_eth_data = { + .phy_irq_pin = AT91_PIN_PC4, + .is_rmii = 1, +}; + +static struct at91_usbh_data __initdata picotux200_usbh_data = { + .ports = 1, +}; + +// static struct at91_udc_data __initdata picotux200_udc_data = { +// .vbus_pin = AT91_PIN_PD4, +// .pullup_pin = AT91_PIN_PD5, +// }; + +static struct at91_mmc_data __initdata picotux200_mmc_data = { + .det_pin = AT91_PIN_PB27, + .slot_b = 0, + .wire4 = 1, + .wp_pin = AT91_PIN_PA17, +}; + +// static struct spi_board_info picotux200_spi_devices[] = { +// { /* DataFlash chip */ +// .modalias = "mtd_dataflash", +// .chip_select = 0, +// .max_speed_hz = 15 * 1000 * 1000, +// }, +// #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD +// { /* DataFlash card */ +// .modalias = "mtd_dataflash", +// .chip_select = 3, +// .max_speed_hz = 15 * 1000 * 1000, +// }, +// #endif +// }; + +#define PICOTUX200_FLASH_BASE AT91_CHIPSELECT_0 +#define PICOTUX200_FLASH_SIZE 0x400000 + +static struct physmap_flash_data picotux200_flash_data = { + .width = 2, +}; + +static struct resource picotux200_flash_resource = { + .start = PICOTUX200_FLASH_BASE, + .end = PICOTUX200_FLASH_BASE + PICOTUX200_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device picotux200_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &picotux200_flash_data, + }, + .resource = &picotux200_flash_resource, + .num_resources = 1, +}; + +static void __init picotux200_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* Ethernet */ + at91_add_device_eth(&picotux200_eth_data); + /* USB Host */ + at91_add_device_usbh(&picotux200_usbh_data); + /* USB Device */ + // at91_add_device_udc(&picotux200_udc_data); + // at91_set_multi_drive(picotux200_udc_data.pullup_pin, 1); /* pullup_pin is connected to reset */ + /* I2C */ + at91_add_device_i2c(); + /* SPI */ + // at91_add_device_spi(picotux200_spi_devices, ARRAY_SIZE(picotux200_spi_devices)); +#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD + /* DataFlash card */ + at91_set_gpio_output(AT91_PIN_PB22, 0); +#else + /* MMC */ + at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ + at91_add_device_mmc(0, &picotux200_mmc_data); +#endif + /* NOR Flash */ + platform_device_register(&picotux200_flash); +} + +MACHINE_START(PICOTUX2XX, "picotux 200") + /* Maintainer: Kleinhenz Elektronik GmbH */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91rm9200_timer, + .map_io = picotux200_map_io, + .init_irq = picotux200_init_irq, + .init_machine = picotux200_board_init, +MACHINE_END -- cgit v1.2.3-59-g8ed1b From 0567a0c022d5b343370a343121f38fd89925de55 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Tue, 13 Mar 2007 20:29:24 +0100 Subject: [ARM] 4257/2: Kconfig support for GENERIC_CLOCKEVENTS This time with LEDS_TIMER set with !GENERIC_CLOCKEVENTS Signed-off-by: Kevin Hilman Acked-by: Thomas Gleixner Signed-off-by: Russell King --- arch/arm/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e7baca29f3fb..2d13b0166121 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -29,6 +29,10 @@ config GENERIC_TIME bool default n +config GENERIC_CLOCKEVENTS + bool + default n + config MMU bool default y @@ -513,6 +517,8 @@ endmenu menu "Kernel Features" +source "kernel/time/Kconfig" + config SMP bool "Symmetric Multi-Processing (EXPERIMENTAL)" depends on EXPERIMENTAL && REALVIEW_MPCORE @@ -572,6 +578,7 @@ config PREEMPT config NO_IDLE_HZ bool "Dynamic tick timer" + depends on !GENERIC_CLOCKEVENTS help Select this option if you want to disable continuous timer ticks and have them programmed to occur as required. This option saves @@ -669,6 +676,7 @@ config LEDS_TIMER bool "Timer LED" if (!ARCH_CDB89712 && !ARCH_OMAP) || \ MACH_OMAP_H2 || MACH_OMAP_PERSEUS2 depends on LEDS + depends on !GENERIC_CLOCKEVENTS default y if ARCH_EBSA110 help If you say Y here, one of the system LEDs (the green one on the -- cgit v1.2.3-59-g8ed1b From 9e4559ddffc012a73ea0b54ed3b6a219c1483ae9 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 14 Mar 2007 17:33:24 +0100 Subject: [ARM] 4258/2: Support for dynticks in idle loop And, wrap timer_tick() and sysdev suspend/resume in !GENERIC_CLOCKEVENTS since clockevent layer takes care of these. Signed-off-by: Kevin Hilman Acked-by: Thomas Gleixner Signed-off-by: Russell King --- arch/arm/kernel/process.c | 3 +++ arch/arm/kernel/time.c | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 8afd83d0cbdd..5d6e6523598b 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -159,9 +160,11 @@ void cpu_idle(void) if (!idle) idle = default_idle; leds_event(led_idle_start); + tick_nohz_stop_sched_tick(); while (!need_resched()) idle(); leds_event(led_idle_end); + tick_nohz_restart_sched_tick(); preempt_enable_no_resched(); schedule(); preempt_disable(); diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index f61decb89ba2..d0540e4eaf5b 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -327,6 +327,7 @@ void restore_time_delta(struct timespec *delta, struct timespec *rtc) } EXPORT_SYMBOL(restore_time_delta); +#ifndef CONFIG_GENERIC_CLOCKEVENTS /* * Kernel system timer support. */ @@ -340,8 +341,9 @@ void timer_tick(void) update_process_times(user_mode(get_irq_regs())); #endif } +#endif -#ifdef CONFIG_PM +#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS) static int timer_suspend(struct sys_device *dev, pm_message_t state) { struct sys_timer *timer = container_of(dev, struct sys_timer, dev); -- cgit v1.2.3-59-g8ed1b From e32f1502be3fa459723b1e4105e014f0828f7513 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 8 Mar 2007 20:23:59 +0100 Subject: [ARM] 4259/1: clockevent support for ixp4xx platform Update ixp4xx timer support to use new clockevent infrastructure. Signed-off-by: Kevin Hilman Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-ixp4xx/common.c | 93 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 75 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2d13b0166121..2aadd0e1e586 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -266,6 +266,7 @@ config ARCH_IXP4XX bool "IXP4xx-based" depends on MMU select GENERIC_TIME + select GENERIC_CLOCKEVENTS help Support for Intel's IXP4XX (XScale) family of processors. diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 45068c3d8dcc..09edea9779e6 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -41,6 +42,8 @@ #include static int __init ixp4xx_clocksource_init(void); +static int __init ixp4xx_clockevent_init(void); +static struct clock_event_device clockevent_ixp4xx; /************************************************************************* * IXP4xx chipset I/O mapping @@ -239,52 +242,40 @@ void __init ixp4xx_init_irq(void) * counter as a source of real clock ticks to account for missed jiffies. *************************************************************************/ -static unsigned volatile last_jiffy_time; - -#define CLOCK_TICKS_PER_USEC ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC) - static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); + struct clock_event_device *evt = &clockevent_ixp4xx; /* Clear Pending Interrupt by writing '1' to it */ *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND; - /* - * Catch up with the real idea of time - */ - while ((signed long)(*IXP4XX_OSTS - last_jiffy_time) >= LATCH) { - timer_tick(); - last_jiffy_time += LATCH; - } - - write_sequnlock(&xtime_lock); + evt->event_handler(evt); return IRQ_HANDLED; } static struct irqaction ixp4xx_timer_irq = { - .name = "IXP4xx Timer Tick", + .name = "timer1", .flags = IRQF_DISABLED | IRQF_TIMER, .handler = ixp4xx_timer_interrupt, }; static void __init ixp4xx_timer_init(void) { + /* Reset/disable counter */ + *IXP4XX_OSRT1 = 0; + /* Clear Pending Interrupt by writing '1' to it */ *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND; - /* Setup the Timer counter value */ - *IXP4XX_OSRT1 = (LATCH & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE; - /* Reset time-stamp counter */ *IXP4XX_OSTS = 0; - last_jiffy_time = 0; /* Connect the interrupt handler and enable the interrupt */ setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq); ixp4xx_clocksource_init(); + ixp4xx_clockevent_init(); } struct sys_timer ixp4xx_timer = { @@ -384,6 +375,9 @@ void __init ixp4xx_sys_init(void) ixp4xx_exp_bus_size >> 20); } +/* + * clocksource + */ cycle_t ixp4xx_get_cycles(void) { return *IXP4XX_OSTS; @@ -408,3 +402,64 @@ static int __init ixp4xx_clocksource_init(void) return 0; } + +/* + * clockevents + */ +static int ixp4xx_set_next_event(unsigned long evt, + struct clock_event_device *unused) +{ + unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK; + + *IXP4XX_OSRT1 = (evt & ~IXP4XX_OST_RELOAD_MASK) | opts; + + return 0; +} + +static void ixp4xx_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + unsigned long opts, osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK; + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + osrt = LATCH & ~IXP4XX_OST_RELOAD_MASK; + opts = IXP4XX_OST_ENABLE; + break; + case CLOCK_EVT_MODE_ONESHOT: + /* period set by 'set next_event' */ + osrt = 0; + opts = IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT; + break; + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + default: + osrt = opts = 0; + break; + } + + *IXP4XX_OSRT1 = osrt | opts; +} + +static struct clock_event_device clockevent_ixp4xx = { + .name = "ixp4xx timer1", + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .rating = 200, + .shift = 24, + .set_mode = ixp4xx_set_mode, + .set_next_event = ixp4xx_set_next_event, +}; + +static int __init ixp4xx_clockevent_init(void) +{ + clockevent_ixp4xx.mult = div_sc(FREQ, NSEC_PER_SEC, + clockevent_ixp4xx.shift); + clockevent_ixp4xx.max_delta_ns = + clockevent_delta2ns(0xfffffffe, &clockevent_ixp4xx); + clockevent_ixp4xx.min_delta_ns = + clockevent_delta2ns(0xf, &clockevent_ixp4xx); + clockevent_ixp4xx.cpumask = cpumask_of_cpu(0); + + clockevents_register_device(&clockevent_ixp4xx); + return 0; +} -- cgit v1.2.3-59-g8ed1b From b49c87c2a5059af14b68ee5f596ac0e9c93678bb Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 8 Mar 2007 20:25:13 +0100 Subject: [ARM] 4260/1: clocksource support for Versatile platform Update Versatile to use new clocksource infrastructure for basic timekeeping. Signed-off-by: Kevin Hilman Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-versatile/core.c | 75 +++++++++++++++++++----------------------- 2 files changed, 35 insertions(+), 41 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2aadd0e1e586..cddd054676c0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -166,6 +166,7 @@ config ARCH_VERSATILE select ARM_AMBA select ARM_VIC select ICST307 + select GENERIC_TIME help This enables support for ARM Ltd Versatile board. diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index bf71507c76fd..08a9fe6eeadb 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -828,46 +829,6 @@ void __init versatile_init(void) #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) #endif -/* - * Returns number of ms since last clock interrupt. Note that interrupts - * will have been disabled by do_gettimeoffset() - */ -static unsigned long versatile_gettimeoffset(void) -{ - unsigned long ticks1, ticks2, status; - - /* - * Get the current number of ticks. Note that there is a race - * condition between us reading the timer and checking for - * an interrupt. We get around this by ensuring that the - * counter has not reloaded between our two reads. - */ - ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; - do { - ticks1 = ticks2; - status = __raw_readl(VA_IC_BASE + VIC_RAW_STATUS); - ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; - } while (ticks2 > ticks1); - - /* - * Number of ticks since last interrupt. - */ - ticks1 = TIMER_RELOAD - ticks2; - - /* - * Interrupt pending? If so, we've reloaded once already. - * - * FIXME: Need to check this is effectively timer 0 that expires - */ - if (status & IRQMASK_TIMERINT0_1) - ticks1 += TIMER_RELOAD; - - /* - * Convert the ticks to usecs - */ - return TICKS2USECS(ticks1); -} - /* * IRQ handler for the timer */ @@ -891,6 +852,36 @@ static struct irqaction versatile_timer_irq = { .handler = versatile_timer_interrupt, }; +static cycle_t versatile_get_cycles(void) +{ + return ~readl(TIMER3_VA_BASE + TIMER_VALUE); +} + +static struct clocksource clocksource_versatile = { + .name = "timer3", + .rating = 200, + .read = versatile_get_cycles, + .mask = CLOCKSOURCE_MASK(32), + .shift = 20, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static int __init versatile_clocksource_init(void) +{ + /* setup timer3 as free-running clocksource */ + writel(0, TIMER3_VA_BASE + TIMER_CTRL); + writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD); + writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE); + writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, + TIMER3_VA_BASE + TIMER_CTRL); + + clocksource_versatile.mult = + clocksource_khz2mult(1000, clocksource_versatile.shift); + clocksource_register(&clocksource_versatile); + + return 0; +} + /* * Set up timer interrupt, and return the current time in seconds. */ @@ -927,9 +918,11 @@ static void __init versatile_timer_init(void) * Make irqs happen for the system timer */ setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq); + + versatile_clocksource_init(); } struct sys_timer versatile_timer = { .init = versatile_timer_init, - .offset = versatile_gettimeoffset, }; + -- cgit v1.2.3-59-g8ed1b From 89df127246f23add865f4a8f719c990e41151843 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 8 Mar 2007 20:30:38 +0100 Subject: [ARM] 4261/1: clockevent support for Versatile platform Update Versatile platform to use new clockevent infrastructure. Signed-off-by: Kevin Hilman Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-versatile/core.c | 68 +++++++++++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index cddd054676c0..d1f24aa89deb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -167,6 +167,7 @@ config ARCH_VERSATILE select ARM_VIC select ICST307 select GENERIC_TIME + select GENERIC_CLOCKEVENTS help This enables support for ARM Ltd Versatile board. diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 08a9fe6eeadb..1275aa7d2eb1 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -829,19 +830,61 @@ void __init versatile_init(void) #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) #endif +static void timer_set_mode(enum clock_event_mode mode, + struct clock_event_device *clk) +{ + unsigned long ctrl; + + switch(mode) { + case CLOCK_EVT_MODE_PERIODIC: + writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD); + + ctrl = TIMER_CTRL_PERIODIC; + ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE; + break; + case CLOCK_EVT_MODE_ONESHOT: + /* period set, and timer enabled in 'next_event' hook */ + ctrl = TIMER_CTRL_ONESHOT; + ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE; + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + default: + ctrl = 0; + } + + writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL); +} + +static int timer_set_next_event(unsigned long evt, + struct clock_event_device *unused) +{ + unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL); + + writel(evt, TIMER0_VA_BASE + TIMER_LOAD); + writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL); + + return 0; +} + +static struct clock_event_device timer0_clockevent = { + .name = "timer0", + .shift = 32, + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_mode = timer_set_mode, + .set_next_event = timer_set_next_event, +}; + /* * IRQ handler for the timer */ static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); + struct clock_event_device *evt = &timer0_clockevent; - // ...clear the interrupt writel(1, TIMER0_VA_BASE + TIMER_INTCLR); - timer_tick(); - - write_sequnlock(&xtime_lock); + evt->event_handler(evt); return IRQ_HANDLED; } @@ -909,17 +952,22 @@ static void __init versatile_timer_init(void) writel(0, TIMER2_VA_BASE + TIMER_CTRL); writel(0, TIMER3_VA_BASE + TIMER_CTRL); - writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD); - writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE); - writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC | - TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL); - /* * Make irqs happen for the system timer */ setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq); versatile_clocksource_init(); + + timer0_clockevent.mult = + div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift); + timer0_clockevent.max_delta_ns = + clockevent_delta2ns(0xffffffff, &timer0_clockevent); + timer0_clockevent.min_delta_ns = + clockevent_delta2ns(0xf, &timer0_clockevent); + + timer0_clockevent.cpumask = cpumask_of_cpu(0); + clockevents_register_device(&timer0_clockevent); } struct sys_timer versatile_timer = { -- cgit v1.2.3-59-g8ed1b From 075192ae807579448afcc0833bd349ccce057825 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 8 Mar 2007 20:32:19 +0100 Subject: [ARM] 4262/1: OMAP: clocksource and clockevent support Update OMAP1 to enable support for hrtimers and dynticks by using new clocksource and clockevent infrastructure. Signed-off-by: Kevin Hilman Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-omap1/time.c | 206 +++++++++++++++++++++++++++--------------- arch/arm/plat-omap/Kconfig | 1 + arch/arm/plat-omap/common.c | 50 ++++++++++ arch/arm/plat-omap/timer32k.c | 139 ++++++++-------------------- 5 files changed, 224 insertions(+), 173 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d1f24aa89deb..3116bafc7533 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -370,6 +370,7 @@ config ARCH_LH7A40X config ARCH_OMAP bool "TI OMAP" select GENERIC_GPIO + select GENERIC_TIME help Support for TI's OMAP platform (OMAP1 and OMAP2). diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c index 1b7e4a506c26..85e048b259f5 100644 --- a/arch/arm/mach-omap1/time.c +++ b/arch/arm/mach-omap1/time.c @@ -39,6 +39,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -48,13 +52,7 @@ #include #include -struct sys_timer omap_timer; -/* - * --------------------------------------------------------------------------- - * MPU timer - * --------------------------------------------------------------------------- - */ #define OMAP_MPU_TIMER_BASE OMAP_MPU_TIMER1_BASE #define OMAP_MPU_TIMER_OFFSET 0x100 @@ -88,21 +86,6 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc) return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; } -/* - * MPU_TICKS_PER_SEC must be an even number, otherwise machinecycles_to_usecs - * will break. On P2, the timer count rate is 6.5 MHz after programming PTV - * with 0. This divides the 13MHz input by 2, and is undocumented. - */ -#if defined(CONFIG_MACH_OMAP_PERSEUS2) || defined(CONFIG_MACH_OMAP_FSAMPLE) -/* REVISIT: This ifdef construct should be replaced by a query to clock - * framework to see if timer base frequency is 12.0, 13.0 or 19.2 MHz. - */ -#define MPU_TICKS_PER_SEC (13000000 / 2) -#else -#define MPU_TICKS_PER_SEC (12000000 / 2) -#endif - -#define MPU_TIMER_TICK_PERIOD ((MPU_TICKS_PER_SEC / HZ) - 1) typedef struct { u32 cntl; /* CNTL_TIMER, R/W */ @@ -120,98 +103,164 @@ static inline unsigned long omap_mpu_timer_read(int nr) return timer->read_tim; } -static inline void omap_mpu_timer_start(int nr, unsigned long load_val) +static inline void omap_mpu_set_autoreset(int nr) { volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr); - timer->cntl = MPU_TIMER_CLOCK_ENABLE; - udelay(1); - timer->load_tim = load_val; - udelay(1); - timer->cntl = (MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_AR | MPU_TIMER_ST); + timer->cntl = timer->cntl | MPU_TIMER_AR; } -unsigned long omap_mpu_timer_ticks_to_usecs(unsigned long nr_ticks) +static inline void omap_mpu_remove_autoreset(int nr) { - unsigned long long nsec; + volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr); - nsec = cycles_2_ns((unsigned long long)nr_ticks); - return (unsigned long)nsec / 1000; + timer->cntl = timer->cntl & ~MPU_TIMER_AR; } -/* - * Last processed system timer interrupt - */ -static unsigned long omap_mpu_timer_last = 0; +static inline void omap_mpu_timer_start(int nr, unsigned long load_val, + int autoreset) +{ + volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr); + unsigned int timerflags = (MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_ST); + + if (autoreset) timerflags |= MPU_TIMER_AR; + + timer->cntl = MPU_TIMER_CLOCK_ENABLE; + udelay(1); + timer->load_tim = load_val; + udelay(1); + timer->cntl = timerflags; +} /* - * Returns elapsed usecs since last system timer interrupt + * --------------------------------------------------------------------------- + * MPU timer 1 ... count down to zero, interrupt, reload + * --------------------------------------------------------------------------- */ -static unsigned long omap_mpu_timer_gettimeoffset(void) +static int omap_mpu_set_next_event(unsigned long cycles, + struct clock_event_device *evt) { - unsigned long now = 0 - omap_mpu_timer_read(0); - unsigned long elapsed = now - omap_mpu_timer_last; + omap_mpu_timer_start(0, cycles, 0); + return 0; +} - return omap_mpu_timer_ticks_to_usecs(elapsed); +static void omap_mpu_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + omap_mpu_set_autoreset(0); + break; + case CLOCK_EVT_MODE_ONESHOT: + omap_mpu_remove_autoreset(0); + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + break; + } } -/* - * Elapsed time between interrupts is calculated using timer0. - * Latency during the interrupt is calculated using timer1. - * Both timer0 and timer1 are counting at 6MHz (P2 6.5MHz). - */ -static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id) +static struct clock_event_device clockevent_mpu_timer1 = { + .name = "mpu_timer1", + .features = CLOCK_EVT_FEAT_PERIODIC, CLOCK_EVT_FEAT_ONESHOT, + .shift = 32, + .set_next_event = omap_mpu_set_next_event, + .set_mode = omap_mpu_set_mode, +}; + +static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id) { - unsigned long now, latency; + struct clock_event_device *evt = &clockevent_mpu_timer1; - write_seqlock(&xtime_lock); - now = 0 - omap_mpu_timer_read(0); - latency = MPU_TICKS_PER_SEC / HZ - omap_mpu_timer_read(1); - omap_mpu_timer_last = now - latency; - timer_tick(); - write_sequnlock(&xtime_lock); + evt->event_handler(evt); return IRQ_HANDLED; } -static struct irqaction omap_mpu_timer_irq = { - .name = "mpu timer", +static struct irqaction omap_mpu_timer1_irq = { + .name = "mpu_timer1", .flags = IRQF_DISABLED | IRQF_TIMER, - .handler = omap_mpu_timer_interrupt, + .handler = omap_mpu_timer1_interrupt, }; -static unsigned long omap_mpu_timer1_overflows; -static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id) +static __init void omap_init_mpu_timer(unsigned long rate) +{ + set_cyc2ns_scale(rate / 1000); + + setup_irq(INT_TIMER1, &omap_mpu_timer1_irq); + omap_mpu_timer_start(0, (rate / HZ) - 1, 1); + + clockevent_mpu_timer1.mult = div_sc(rate, NSEC_PER_SEC, + clockevent_mpu_timer1.shift); + clockevent_mpu_timer1.max_delta_ns = + clockevent_delta2ns(-1, &clockevent_mpu_timer1); + clockevent_mpu_timer1.min_delta_ns = + clockevent_delta2ns(1, &clockevent_mpu_timer1); + + clockevent_mpu_timer1.cpumask = cpumask_of_cpu(0); + clockevents_register_device(&clockevent_mpu_timer1); +} + + +/* + * --------------------------------------------------------------------------- + * MPU timer 2 ... free running 32-bit clock source and scheduler clock + * --------------------------------------------------------------------------- + */ + +static unsigned long omap_mpu_timer2_overflows; + +static irqreturn_t omap_mpu_timer2_interrupt(int irq, void *dev_id) { - omap_mpu_timer1_overflows++; + omap_mpu_timer2_overflows++; return IRQ_HANDLED; } -static struct irqaction omap_mpu_timer1_irq = { - .name = "mpu timer1 overflow", +static struct irqaction omap_mpu_timer2_irq = { + .name = "mpu_timer2", .flags = IRQF_DISABLED, - .handler = omap_mpu_timer1_interrupt, + .handler = omap_mpu_timer2_interrupt, }; -static __init void omap_init_mpu_timer(void) +static cycle_t mpu_read(void) { - set_cyc2ns_scale(MPU_TICKS_PER_SEC / 1000); - omap_timer.offset = omap_mpu_timer_gettimeoffset; - setup_irq(INT_TIMER1, &omap_mpu_timer1_irq); - setup_irq(INT_TIMER2, &omap_mpu_timer_irq); - omap_mpu_timer_start(0, 0xffffffff); - omap_mpu_timer_start(1, MPU_TIMER_TICK_PERIOD); + return ~omap_mpu_timer_read(1); +} + +static struct clocksource clocksource_mpu = { + .name = "mpu_timer2", + .rating = 300, + .read = mpu_read, + .mask = CLOCKSOURCE_MASK(32), + .shift = 24, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static void __init omap_init_clocksource(unsigned long rate) +{ + static char err[] __initdata = KERN_ERR + "%s: can't register clocksource!\n"; + + clocksource_mpu.mult + = clocksource_khz2mult(rate/1000, clocksource_mpu.shift); + + setup_irq(INT_TIMER2, &omap_mpu_timer2_irq); + omap_mpu_timer_start(1, ~0, 1); + + if (clocksource_register(&clocksource_mpu)) + printk(err, clocksource_mpu.name); } + /* * Scheduler clock - returns current time in nanosec units. */ unsigned long long sched_clock(void) { - unsigned long ticks = 0 - omap_mpu_timer_read(0); + unsigned long ticks = 0 - omap_mpu_timer_read(1); unsigned long long ticks64; - ticks64 = omap_mpu_timer1_overflows; + ticks64 = omap_mpu_timer2_overflows; ticks64 <<= 32; ticks64 |= ticks; @@ -225,10 +274,21 @@ unsigned long long sched_clock(void) */ static void __init omap_timer_init(void) { - omap_init_mpu_timer(); + struct clk *ck_ref = clk_get(NULL, "ck_ref"); + unsigned long rate; + + BUG_ON(IS_ERR(ck_ref)); + + rate = clk_get_rate(ck_ref); + clk_put(ck_ref); + + /* PTV = 0 */ + rate /= 2; + + omap_init_mpu_timer(rate); + omap_init_clocksource(rate); } struct sys_timer omap_timer = { .init = omap_timer_init, - .offset = NULL, /* Initialized later */ }; diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index f2dc363de66b..9e8d21eca4ec 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -11,6 +11,7 @@ choice config ARCH_OMAP1 bool "TI OMAP1" + select GENERIC_CLOCKEVENTS config ARCH_OMAP2 bool "TI OMAP2" diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c index 57b7b93674a4..fecd3d625995 100644 --- a/arch/arm/plat-omap/common.c +++ b/arch/arm/plat-omap/common.c @@ -156,3 +156,53 @@ static int __init omap_add_serial_console(void) return add_preferred_console("ttyS", line, opt); } console_initcall(omap_add_serial_console); + + +/* + * 32KHz clocksource ... always available, on pretty most chips except + * OMAP 730 and 1510. Other timers could be used as clocksources, with + * higher resolution in free-running counter modes (e.g. 12 MHz xtal), + * but systems won't necessarily want to spend resources that way. + */ + +#if defined(CONFIG_ARCH_OMAP16XX) +#define TIMER_32K_SYNCHRONIZED 0xfffbc410 +#elif defined(CONFIG_ARCH_OMAP24XX) +#define TIMER_32K_SYNCHRONIZED 0x48004010 +#endif + +#ifdef TIMER_32K_SYNCHRONIZED + +#include + +static cycle_t omap_32k_read(void) +{ + return omap_readl(TIMER_32K_SYNCHRONIZED); +} + +static struct clocksource clocksource_32k = { + .name = "32k_counter", + .rating = 250, + .read = omap_32k_read, + .mask = CLOCKSOURCE_MASK(32), + .shift = 10, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static int __init omap_init_clocksource_32k(void) +{ + static char err[] __initdata = KERN_ERR + "%s: can't register clocksource!\n"; + + if (cpu_is_omap16xx() || cpu_is_omap24xx()) { + clocksource_32k.mult = clocksource_hz2mult(32768, + clocksource_32k.shift); + + if (clocksource_register(&clocksource_32k)) + printk(err, clocksource_32k.name); + } + return 0; +} +arch_initcall(omap_init_clocksource_32k); + +#endif /* TIMER_32K_SYNCHRONIZED */ diff --git a/arch/arm/plat-omap/timer32k.c b/arch/arm/plat-omap/timer32k.c index 265310601161..114f87151d60 100644 --- a/arch/arm/plat-omap/timer32k.c +++ b/arch/arm/plat-omap/timer32k.c @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include #include @@ -80,13 +82,13 @@ struct sys_timer omap_timer; #define OMAP1_32K_TIMER_TVR 0x00 #define OMAP1_32K_TIMER_TCR 0x04 -#define OMAP_32K_TICKS_PER_HZ (32768 / HZ) +#define OMAP_32K_TICKS_PER_SEC (32768) /* * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1 * so with HZ = 128, TVR = 255. */ -#define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1) +#define OMAP_32K_TIMER_TICK_PERIOD ((OMAP_32K_TICKS_PER_SEC / HZ) - 1) #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ (((nr_jiffies) * (clock_rate)) / HZ) @@ -142,6 +144,28 @@ static inline void omap_32k_timer_ack_irq(void) #endif +static void omap_32k_timer_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + switch (mode) { + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_PERIODIC: + omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + omap_32k_timer_stop(); + break; + } +} + +static struct clock_event_device clockevent_32k_timer = { + .name = "32k-timer", + .features = CLOCK_EVT_FEAT_PERIODIC, + .shift = 32, + .set_mode = omap_32k_timer_set_mode, +}; + /* * The 32KHz synchronized timer is an additional timer on 16xx. * It is always running. @@ -170,15 +194,6 @@ omap_32k_ticks_to_nsecs(unsigned long ticks_32k) static unsigned long omap_32k_last_tick = 0; -/* - * Returns elapsed usecs since last 32k timer interrupt - */ -static unsigned long omap_32k_timer_gettimeoffset(void) -{ - unsigned long now = omap_32k_sync_timer_read(); - return omap_32k_ticks_to_usecs(now - omap_32k_last_tick); -} - /* * Returns current time from boot in nsecs. It's OK for this to wrap * around for now, as it's just a relative time stamp. @@ -188,95 +203,16 @@ unsigned long long sched_clock(void) return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read()); } -/* - * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this - * function is also called from other interrupts to remove latency - * issues with dynamic tick. In the dynamic tick case, we need to lock - * with irqsave. - */ -static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id) -{ - unsigned long now; - - omap_32k_timer_ack_irq(); - now = omap_32k_sync_timer_read(); - - while ((signed long)(now - omap_32k_last_tick) - >= OMAP_32K_TICKS_PER_HZ) { - omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; - timer_tick(); - } - - /* Restart timer so we don't drift off due to modulo or dynamic tick. - * By default we program the next timer to be continuous to avoid - * latencies during high system load. During dynamic tick operation the - * continuous timer can be overridden from pm_idle to be longer. - */ - omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now); - - return IRQ_HANDLED; -} - -static irqreturn_t omap_32k_timer_handler(int irq, void *dev_id) -{ - return _omap_32k_timer_interrupt(irq, dev_id); -} - static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id) { - unsigned long flags; + struct clock_event_device *evt = &clockevent_32k_timer; + omap_32k_timer_ack_irq(); - write_seqlock_irqsave(&xtime_lock, flags); - _omap_32k_timer_interrupt(irq, dev_id); - write_sequnlock_irqrestore(&xtime_lock, flags); + evt->event_handler(evt); return IRQ_HANDLED; } -#ifdef CONFIG_NO_IDLE_HZ -/* - * Programs the next timer interrupt needed. Called when dynamic tick is - * enabled, and to reprogram the ticks to skip from pm_idle. Note that - * we can keep the timer continuous, and don't need to set it to run in - * one-shot mode. This is because the timer will get reprogrammed again - * after next interrupt. - */ -void omap_32k_timer_reprogram(unsigned long next_tick) -{ - unsigned long ticks = JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1; - unsigned long now = omap_32k_sync_timer_read(); - unsigned long idled = now - omap_32k_last_tick; - - if (idled + 1 < ticks) - ticks -= idled; - else - ticks = 1; - omap_32k_timer_start(ticks); -} - -static struct irqaction omap_32k_timer_irq; -extern struct timer_update_handler timer_update; - -static int omap_32k_timer_enable_dyn_tick(void) -{ - /* No need to reprogram timer, just use the next interrupt */ - return 0; -} - -static int omap_32k_timer_disable_dyn_tick(void) -{ - omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); - return 0; -} - -static struct dyn_tick_timer omap_dyn_tick_timer = { - .enable = omap_32k_timer_enable_dyn_tick, - .disable = omap_32k_timer_disable_dyn_tick, - .reprogram = omap_32k_timer_reprogram, - .handler = omap_32k_timer_handler, -}; -#endif /* CONFIG_NO_IDLE_HZ */ - static struct irqaction omap_32k_timer_irq = { .name = "32KHz timer", .flags = IRQF_DISABLED | IRQF_TIMER, @@ -285,13 +221,8 @@ static struct irqaction omap_32k_timer_irq = { static __init void omap_init_32k_timer(void) { -#ifdef CONFIG_NO_IDLE_HZ - omap_timer.dyn_tick = &omap_dyn_tick_timer; -#endif - if (cpu_class_is_omap1()) setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); - omap_timer.offset = omap_32k_timer_gettimeoffset; omap_32k_last_tick = omap_32k_sync_timer_read(); #ifdef CONFIG_ARCH_OMAP2 @@ -308,7 +239,16 @@ static __init void omap_init_32k_timer(void) } #endif - omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); + clockevent_32k_timer.mult = div_sc(OMAP_32K_TICKS_PER_SEC, + NSEC_PER_SEC, + clockevent_32k_timer.shift); + clockevent_32k_timer.max_delta_ns = + clockevent_delta2ns(0xfffffffe, &clockevent_32k_timer); + clockevent_32k_timer.min_delta_ns = + clockevent_delta2ns(1, &clockevent_32k_timer); + + clockevent_32k_timer.cpumask = cpumask_of_cpu(0); + clockevents_register_device(&clockevent_32k_timer); } /* @@ -326,5 +266,4 @@ static void __init omap_timer_init(void) struct sys_timer omap_timer = { .init = omap_timer_init, - .offset = NULL, /* Initialized later */ }; -- cgit v1.2.3-59-g8ed1b From 7053acbd78336abf5d4bc3d8a875a03624cfb83f Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Thu, 5 Apr 2007 04:07:20 +0100 Subject: [ARM] 4304/1: removes the unnecessary bit number from CKENnn_XXXX This patch removes the unnecessary bit number from CKENnn_XXXX definitions for PXA, so that CKEN0_PWM0 --> CKEN_PWM0 CKEN1_PWM1 --> CKEN_PWM1 ... CKEN24_CAMERA --> CKEN_CAMERA The reasons for the change of these defitions are: 1. they do not scale - they are currently valid for pxa2xx, but definitely not valid for pxa3xx, e.g., pxa3xx has bit 3 for camera instead of bit 24 2. they are unnecessary - the peripheral name within the definition has already announced its usage, we don't need those bit numbers to know which peripheral we are going to enable/disable clock for 3. they are inconvenient - think about this: a driver programmer for pxa has to remember which bit in the CKEN register to turn on/off Another change in the patch is to make the definitions equal to its clock bit index, so that #define CKEN_CAMERA (24) instead of #define CKEN_CAMERA (1 << 24) this change, however, will add a run-time bit shift operation in pxa_set_cken(), but the benefit of this change is that it scales when bit index exceeds 32, e.g., pxa3xx has two registers CKENA and CKENB, totally 64 bit for this, suppose CAMERA clock enabling bit is CKENB:10, one can simply define CKEN_CAMERA to be (32 + 10) and so that pxa_set_cken() need minimum change to adapt to that. Signed-off-by: eric miao Signed-off-by: Russell King --- Documentation/spi/pxa2xx | 2 +- arch/arm/mach-pxa/generic.c | 4 +-- arch/arm/mach-pxa/lpd270.c | 4 +-- arch/arm/mach-pxa/lubbock.c | 2 +- arch/arm/mach-pxa/mainstone.c | 4 +-- arch/arm/mach-pxa/pxa27x.c | 4 +-- arch/arm/mach-pxa/ssp.c | 12 ++++---- drivers/i2c/busses/i2c-pxa.c | 12 ++++---- drivers/mmc/pxamci.c | 4 +-- drivers/net/irda/pxaficp_ir.c | 12 ++++---- drivers/serial/pxa.c | 8 ++--- drivers/usb/gadget/pxa2xx_udc.c | 4 +-- drivers/usb/host/ohci-pxa27x.c | 4 +-- drivers/video/pxafb.c | 4 +-- include/asm-arm/arch-pxa/pxa-regs.h | 58 ++++++++++++++++++------------------- sound/arm/pxa2xx-ac97.c | 12 ++++---- sound/soc/pxa/pxa2xx-ac97.c | 12 ++++---- sound/soc/pxa/pxa2xx-i2s.c | 4 +-- 18 files changed, 83 insertions(+), 83 deletions(-) (limited to 'arch') diff --git a/Documentation/spi/pxa2xx b/Documentation/spi/pxa2xx index f9717fe9bd85..215e3b8e7266 100644 --- a/Documentation/spi/pxa2xx +++ b/Documentation/spi/pxa2xx @@ -62,7 +62,7 @@ static struct resource pxa_spi_nssp_resources[] = { static struct pxa2xx_spi_master pxa_nssp_master_info = { .ssp_type = PXA25x_NSSP, /* Type of SSP */ - .clock_enable = CKEN9_NSSP, /* NSSP Peripheral clock */ + .clock_enable = CKEN_NSSP, /* NSSP Peripheral clock */ .num_chipselect = 1, /* Matches the number of chips attached to NSSP */ .enable_dma = 1, /* Enables NSSP DMA */ }; diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index b8cb79f899d5..64b08b744f9f 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -164,9 +164,9 @@ void pxa_set_cken(int clock, int enable) local_irq_save(flags); if (enable) - CKEN |= clock; + CKEN |= (1 << clock); else - CKEN &= ~clock; + CKEN &= ~(1 << clock); local_irq_restore(flags); } diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index 8e27a64fa9f4..e3097664ffe1 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -234,7 +234,7 @@ static void lpd270_backlight_power(int on) { if (on) { pxa_gpio_mode(GPIO16_PWM0_MD); - pxa_set_cken(CKEN0_PWM0, 1); + pxa_set_cken(CKEN_PWM0, 1); PWM_CTRL0 = 0; PWM_PWDUTY0 = 0x3ff; PWM_PERVAL0 = 0x3ff; @@ -242,7 +242,7 @@ static void lpd270_backlight_power(int on) PWM_CTRL0 = 0; PWM_PWDUTY0 = 0x0; PWM_PERVAL0 = 0x3FF; - pxa_set_cken(CKEN0_PWM0, 0); + pxa_set_cken(CKEN_PWM0, 0); } } diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 055de7f4f00a..6377b2e29ff0 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -220,7 +220,7 @@ static struct resource pxa_ssp_resources[] = { static struct pxa2xx_spi_master pxa_ssp_master_info = { .ssp_type = PXA25x_SSP, - .clock_enable = CKEN3_SSP, + .clock_enable = CKEN_SSP, .num_chipselect = 0, }; diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 56d94d88d5ca..ed99a81b98f3 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -266,7 +266,7 @@ static void mainstone_backlight_power(int on) { if (on) { pxa_gpio_mode(GPIO16_PWM0_MD); - pxa_set_cken(CKEN0_PWM0, 1); + pxa_set_cken(CKEN_PWM0, 1); PWM_CTRL0 = 0; PWM_PWDUTY0 = 0x3ff; PWM_PERVAL0 = 0x3ff; @@ -274,7 +274,7 @@ static void mainstone_backlight_power(int on) PWM_CTRL0 = 0; PWM_PWDUTY0 = 0x0; PWM_PERVAL0 = 0x3FF; - pxa_set_cken(CKEN0_PWM0, 0); + pxa_set_cken(CKEN_PWM0, 0); } } diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 74eeada1e2fc..c64bab49efc4 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -140,9 +140,9 @@ void pxa_cpu_pm_enter(suspend_state_t state) extern void pxa_cpu_resume(void); if (state == PM_SUSPEND_STANDBY) - CKEN = CKEN22_MEMC | CKEN9_OSTIMER | CKEN16_LCD |CKEN0_PWM0; + CKEN = CKEN_MEMC | CKEN_OSTIMER | CKEN_LCD | CKEN_PWM0; else - CKEN = CKEN22_MEMC | CKEN9_OSTIMER; + CKEN = CKEN_MEMC | CKEN_OSTIMER; /* ensure voltage-change sequencer not initiated, which hangs */ PCFR &= ~PCFR_FVC; diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c index 6cc202755fb4..71766ac0328b 100644 --- a/arch/arm/mach-pxa/ssp.c +++ b/arch/arm/mach-pxa/ssp.c @@ -52,13 +52,13 @@ struct ssp_info_ { */ static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = { #if defined (CONFIG_PXA27x) - {IRQ_SSP, CKEN23_SSP1}, - {IRQ_SSP2, CKEN3_SSP2}, - {IRQ_SSP3, CKEN4_SSP3}, + {IRQ_SSP, CKEN_SSP1}, + {IRQ_SSP2, CKEN_SSP2}, + {IRQ_SSP3, CKEN_SSP3}, #else - {IRQ_SSP, CKEN3_SSP}, - {IRQ_NSSP, CKEN9_NSSP}, - {IRQ_ASSP, CKEN10_ASSP}, + {IRQ_SSP, CKEN_SSP}, + {IRQ_NSSP, CKEN_NSSP}, + {IRQ_ASSP, CKEN_ASSP}, #endif }; diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 11c7477a0ffa..4443d3bb3fbf 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -887,14 +887,14 @@ static int i2c_pxa_probe(struct platform_device *dev) pxa_gpio_mode(GPIO117_I2CSCL_MD); pxa_gpio_mode(GPIO118_I2CSDA_MD); #endif - pxa_set_cken(CKEN14_I2C, 1); + pxa_set_cken(CKEN_I2C, 1); break; #ifdef CONFIG_PXA27x case 1: local_irq_disable(); PCFR |= PCFR_PI2CEN; local_irq_enable(); - pxa_set_cken(CKEN15_PWRI2C, 1); + pxa_set_cken(CKEN_PWRI2C, 1); #endif } @@ -935,11 +935,11 @@ eadapt: ereqirq: switch (dev->id) { case 0: - pxa_set_cken(CKEN14_I2C, 0); + pxa_set_cken(CKEN_I2C, 0); break; #ifdef CONFIG_PXA27x case 1: - pxa_set_cken(CKEN15_PWRI2C, 0); + pxa_set_cken(CKEN_PWRI2C, 0); local_irq_disable(); PCFR &= ~PCFR_PI2CEN; local_irq_enable(); @@ -962,11 +962,11 @@ static int i2c_pxa_remove(struct platform_device *dev) free_irq(i2c->irq, i2c); switch (dev->id) { case 0: - pxa_set_cken(CKEN14_I2C, 0); + pxa_set_cken(CKEN_I2C, 0); break; #ifdef CONFIG_PXA27x case 1: - pxa_set_cken(CKEN15_PWRI2C, 0); + pxa_set_cken(CKEN_PWRI2C, 0); local_irq_disable(); PCFR &= ~PCFR_PI2CEN; local_irq_enable(); diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c index 9774fc68b61a..fca894e55f4a 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/pxamci.c @@ -369,14 +369,14 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (CLOCKRATE / clk > ios->clock) clk <<= 1; host->clkrt = fls(clk) - 1; - pxa_set_cken(CKEN12_MMC, 1); + pxa_set_cken(CKEN_MMC, 1); /* * we write clkrt on the next command */ } else { pxamci_stop_clock(host); - pxa_set_cken(CKEN12_MMC, 0); + pxa_set_cken(CKEN_MMC, 0); } if (host->power_mode != ios->power_mode) { diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index 2272156af31e..d6d5361f0936 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -134,7 +134,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) DCSR(si->rxdma) &= ~DCSR_RUN; /* disable FICP */ ICCR0 = 0; - pxa_set_cken(CKEN13_FICP, 0); + pxa_set_cken(CKEN_FICP, 0); /* set board transceiver to SIR mode */ si->pdata->transceiver_mode(si->dev, IR_SIRMODE); @@ -144,7 +144,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) pxa_gpio_mode(GPIO47_STTXD_MD); /* enable the STUART clock */ - pxa_set_cken(CKEN5_STUART, 1); + pxa_set_cken(CKEN_STUART, 1); } /* disable STUART first */ @@ -169,7 +169,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) /* disable STUART */ STIER = 0; STISR = 0; - pxa_set_cken(CKEN5_STUART, 0); + pxa_set_cken(CKEN_STUART, 0); /* disable FICP first */ ICCR0 = 0; @@ -182,7 +182,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) pxa_gpio_mode(GPIO47_ICPTXD_MD); /* enable the FICP clock */ - pxa_set_cken(CKEN13_FICP, 1); + pxa_set_cken(CKEN_FICP, 1); si->speed = speed; pxa_irda_fir_dma_rx_start(si); @@ -593,7 +593,7 @@ static void pxa_irda_shutdown(struct pxa_irda *si) /* disable STUART SIR mode */ STISR = 0; /* disable the STUART clock */ - pxa_set_cken(CKEN5_STUART, 0); + pxa_set_cken(CKEN_STUART, 0); /* disable DMA */ DCSR(si->txdma) &= ~DCSR_RUN; @@ -601,7 +601,7 @@ static void pxa_irda_shutdown(struct pxa_irda *si) /* disable FICP */ ICCR0 = 0; /* disable the FICP clock */ - pxa_set_cken(CKEN13_FICP, 0); + pxa_set_cken(CKEN_FICP, 0); DRCMR17 = 0; DRCMR18 = 0; diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index d403aaa55092..e9c6cb391a23 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c @@ -717,7 +717,7 @@ struct uart_ops serial_pxa_pops = { static struct uart_pxa_port serial_pxa_ports[] = { { /* FFUART */ .name = "FFUART", - .cken = CKEN6_FFUART, + .cken = CKEN_FFUART, .port = { .type = PORT_PXA, .iotype = UPIO_MEM, @@ -731,7 +731,7 @@ static struct uart_pxa_port serial_pxa_ports[] = { }, }, { /* BTUART */ .name = "BTUART", - .cken = CKEN7_BTUART, + .cken = CKEN_BTUART, .port = { .type = PORT_PXA, .iotype = UPIO_MEM, @@ -745,7 +745,7 @@ static struct uart_pxa_port serial_pxa_ports[] = { }, }, { /* STUART */ .name = "STUART", - .cken = CKEN5_STUART, + .cken = CKEN_STUART, .port = { .type = PORT_PXA, .iotype = UPIO_MEM, @@ -759,7 +759,7 @@ static struct uart_pxa_port serial_pxa_ports[] = { }, }, { /* HWUART */ .name = "HWUART", - .cken = CKEN4_HWUART, + .cken = CKEN_HWUART, .port = { .type = PORT_PXA, .iotype = UPIO_MEM, diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index f01890dc8751..018b0d65765a 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -1497,7 +1497,7 @@ static void udc_disable(struct pxa2xx_udc *dev) #ifdef CONFIG_ARCH_PXA /* Disable clock for USB device */ - pxa_set_cken(CKEN11_USB, 0); + pxa_set_cken(CKEN_USB, 0); #endif ep0_idle (dev); @@ -1543,7 +1543,7 @@ static void udc_enable (struct pxa2xx_udc *dev) #ifdef CONFIG_ARCH_PXA /* Enable clock for USB device */ - pxa_set_cken(CKEN11_USB, 1); + pxa_set_cken(CKEN_USB, 1); udelay(5); #endif diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index f1563dc319d3..23d2fe5a62f4 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -80,7 +80,7 @@ static int pxa27x_start_hc(struct device *dev) inf = dev->platform_data; - pxa_set_cken(CKEN10_USBHOST, 1); + pxa_set_cken(CKEN_USBHOST, 1); UHCHR |= UHCHR_FHR; udelay(11); @@ -123,7 +123,7 @@ static void pxa27x_stop_hc(struct device *dev) UHCCOMS |= 1; udelay(10); - pxa_set_cken(CKEN10_USBHOST, 0); + pxa_set_cken(CKEN_USBHOST, 0); } diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index b4947c810706..0b195f33f84f 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -803,7 +803,7 @@ static void pxafb_enable_controller(struct pxafb_info *fbi) pr_debug("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3); /* enable LCD controller clock */ - pxa_set_cken(CKEN16_LCD, 1); + pxa_set_cken(CKEN_LCD, 1); /* Sequence from 11.7.10 */ LCCR3 = fbi->reg_lccr3; @@ -840,7 +840,7 @@ static void pxafb_disable_controller(struct pxafb_info *fbi) remove_wait_queue(&fbi->ctrlr_wait, &wait); /* disable LCD controller clock */ - pxa_set_cken(CKEN16_LCD, 0); + pxa_set_cken(CKEN_LCD, 0); } /* diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 139c9d954818..dbcc9298b0c8 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -1801,35 +1801,35 @@ #define CCCR_M_MASK 0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */ #define CCCR_L_MASK 0x001f /* Crystal Frequency to Memory Frequency Multiplier */ -#define CKEN24_CAMERA (1 << 24) /* Camera Interface Clock Enable */ -#define CKEN23_SSP1 (1 << 23) /* SSP1 Unit Clock Enable */ -#define CKEN22_MEMC (1 << 22) /* Memory Controller Clock Enable */ -#define CKEN21_MEMSTK (1 << 21) /* Memory Stick Host Controller */ -#define CKEN20_IM (1 << 20) /* Internal Memory Clock Enable */ -#define CKEN19_KEYPAD (1 << 19) /* Keypad Interface Clock Enable */ -#define CKEN18_USIM (1 << 18) /* USIM Unit Clock Enable */ -#define CKEN17_MSL (1 << 17) /* MSL Unit Clock Enable */ -#define CKEN16_LCD (1 << 16) /* LCD Unit Clock Enable */ -#define CKEN15_PWRI2C (1 << 15) /* PWR I2C Unit Clock Enable */ -#define CKEN14_I2C (1 << 14) /* I2C Unit Clock Enable */ -#define CKEN13_FICP (1 << 13) /* FICP Unit Clock Enable */ -#define CKEN12_MMC (1 << 12) /* MMC Unit Clock Enable */ -#define CKEN11_USB (1 << 11) /* USB Unit Clock Enable */ -#define CKEN10_ASSP (1 << 10) /* ASSP (SSP3) Clock Enable */ -#define CKEN10_USBHOST (1 << 10) /* USB Host Unit Clock Enable */ -#define CKEN9_OSTIMER (1 << 9) /* OS Timer Unit Clock Enable */ -#define CKEN9_NSSP (1 << 9) /* NSSP (SSP2) Clock Enable */ -#define CKEN8_I2S (1 << 8) /* I2S Unit Clock Enable */ -#define CKEN7_BTUART (1 << 7) /* BTUART Unit Clock Enable */ -#define CKEN6_FFUART (1 << 6) /* FFUART Unit Clock Enable */ -#define CKEN5_STUART (1 << 5) /* STUART Unit Clock Enable */ -#define CKEN4_HWUART (1 << 4) /* HWUART Unit Clock Enable */ -#define CKEN4_SSP3 (1 << 4) /* SSP3 Unit Clock Enable */ -#define CKEN3_SSP (1 << 3) /* SSP Unit Clock Enable */ -#define CKEN3_SSP2 (1 << 3) /* SSP2 Unit Clock Enable */ -#define CKEN2_AC97 (1 << 2) /* AC97 Unit Clock Enable */ -#define CKEN1_PWM1 (1 << 1) /* PWM1 Clock Enable */ -#define CKEN0_PWM0 (1 << 0) /* PWM0 Clock Enable */ +#define CKEN_CAMERA (24) /* Camera Interface Clock Enable */ +#define CKEN_SSP1 (23) /* SSP1 Unit Clock Enable */ +#define CKEN_MEMC (22) /* Memory Controller Clock Enable */ +#define CKEN_MEMSTK (21) /* Memory Stick Host Controller */ +#define CKEN_IM (20) /* Internal Memory Clock Enable */ +#define CKEN_KEYPAD (19) /* Keypad Interface Clock Enable */ +#define CKEN_USIM (18) /* USIM Unit Clock Enable */ +#define CKEN_MSL (17) /* MSL Unit Clock Enable */ +#define CKEN_LCD (16) /* LCD Unit Clock Enable */ +#define CKEN_PWRI2C (15) /* PWR I2C Unit Clock Enable */ +#define CKEN_I2C (14) /* I2C Unit Clock Enable */ +#define CKEN_FICP (13) /* FICP Unit Clock Enable */ +#define CKEN_MMC (12) /* MMC Unit Clock Enable */ +#define CKEN_USB (11) /* USB Unit Clock Enable */ +#define CKEN_ASSP (10) /* ASSP (SSP3) Clock Enable */ +#define CKEN_USBHOST (10) /* USB Host Unit Clock Enable */ +#define CKEN_OSTIMER (9) /* OS Timer Unit Clock Enable */ +#define CKEN_NSSP (9) /* NSSP (SSP2) Clock Enable */ +#define CKEN_I2S (8) /* I2S Unit Clock Enable */ +#define CKEN_BTUART (7) /* BTUART Unit Clock Enable */ +#define CKEN_FFUART (6) /* FFUART Unit Clock Enable */ +#define CKEN_STUART (5) /* STUART Unit Clock Enable */ +#define CKEN_HWUART (4) /* HWUART Unit Clock Enable */ +#define CKEN_SSP3 (4) /* SSP3 Unit Clock Enable */ +#define CKEN_SSP (3) /* SSP Unit Clock Enable */ +#define CKEN_SSP2 (3) /* SSP2 Unit Clock Enable */ +#define CKEN_AC97 (2) /* AC97 Unit Clock Enable */ +#define CKEN_PWM1 (1) /* PWM1 Clock Enable */ +#define CKEN_PWM0 (0) /* PWM0 Clock Enable */ #define OSCC_OON (1 << 1) /* 32.768kHz OON (write-once only bit) */ #define OSCC_OOK (1 << 0) /* 32.768kHz OOK (read-only bit) */ diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 28db4be7a16f..19c65a8d86a7 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c @@ -260,7 +260,7 @@ static int pxa2xx_ac97_do_suspend(struct snd_card *card, pm_message_t state) if (platform_ops && platform_ops->suspend) platform_ops->suspend(platform_ops->priv); GCR |= GCR_ACLINK_OFF; - pxa_set_cken(CKEN2_AC97, 0); + pxa_set_cken(CKEN_AC97, 0); return 0; } @@ -269,7 +269,7 @@ static int pxa2xx_ac97_do_resume(struct snd_card *card) { pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data; - pxa_set_cken(CKEN2_AC97, 1); + pxa_set_cken(CKEN_AC97, 1); if (platform_ops && platform_ops->resume) platform_ops->resume(platform_ops->priv); snd_ac97_resume(pxa2xx_ac97_ac97); @@ -337,7 +337,7 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) /* Use GPIO 113 as AC97 Reset on Bulverde */ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); #endif - pxa_set_cken(CKEN2_AC97, 1); + pxa_set_cken(CKEN_AC97, 1); ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus); if (ret) @@ -361,10 +361,10 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) err: if (card) snd_card_free(card); - if (CKEN & CKEN2_AC97) { + if (CKEN & CKEN_AC97) { GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN2_AC97, 0); + pxa_set_cken(CKEN_AC97, 0); } return ret; } @@ -378,7 +378,7 @@ static int __devexit pxa2xx_ac97_remove(struct platform_device *dev) platform_set_drvdata(dev, NULL); GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN2_AC97, 0); + pxa_set_cken(CKEN_AC97, 0); } return 0; diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index 1bbbeff84ef0..b222755763e7 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -256,7 +256,7 @@ static int pxa2xx_ac97_suspend(struct platform_device *pdev, struct snd_soc_cpu_dai *dai) { GCR |= GCR_ACLINK_OFF; - pxa_set_cken(CKEN2_AC97, 0); + pxa_set_cken(CKEN_AC97, 0); return 0; } @@ -271,7 +271,7 @@ static int pxa2xx_ac97_resume(struct platform_device *pdev, /* Use GPIO 113 as AC97 Reset on Bulverde */ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); #endif - pxa_set_cken(CKEN2_AC97, 1); + pxa_set_cken(CKEN_AC97, 1); return 0; } @@ -296,14 +296,14 @@ static int pxa2xx_ac97_probe(struct platform_device *pdev) /* Use GPIO 113 as AC97 Reset on Bulverde */ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); #endif - pxa_set_cken(CKEN2_AC97, 1); + pxa_set_cken(CKEN_AC97, 1); return 0; err: - if (CKEN & CKEN2_AC97) { + if (CKEN & CKEN_AC97) { GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN2_AC97, 0); + pxa_set_cken(CKEN_AC97, 0); } return ret; } @@ -312,7 +312,7 @@ static void pxa2xx_ac97_remove(struct platform_device *pdev) { GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN2_AC97, 0); + pxa_set_cken(CKEN_AC97, 0); } static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 575a6137c040..50c5c83f67db 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -149,7 +149,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, pxa_gpio_mode(gpio_bus[pxa_i2s.master].tx); pxa_gpio_mode(gpio_bus[pxa_i2s.master].frm); pxa_gpio_mode(gpio_bus[pxa_i2s.master].clk); - pxa_set_cken(CKEN8_I2S, 1); + pxa_set_cken(CKEN_I2S, 1); pxa_i2s_wait(); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) @@ -234,7 +234,7 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream) if (SACR1 & (SACR1_DREC | SACR1_DRPL)) { SACR0 &= ~SACR0_ENB; pxa_i2s_wait(); - pxa_set_cken(CKEN8_I2S, 0); + pxa_set_cken(CKEN_I2S, 0); } } -- cgit v1.2.3-59-g8ed1b From d0a9d75b9cd9cc8097c746611cc57cc8438b94be Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 22 Apr 2007 10:08:58 +0100 Subject: [ARM] sa1100: use mutexes rather than semaphores Use a mutex in the sa1100 clock support rather than a semaphore. Remove the unused "module" field. Signed-off-by: Russell King --- arch/arm/mach-sa1100/clock.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c index b1e8fd766c1a..fc97fe57ee6f 100644 --- a/arch/arm/mach-sa1100/clock.c +++ b/arch/arm/mach-sa1100/clock.c @@ -9,14 +9,17 @@ #include #include #include +#include #include -#include +/* + * Very simple clock implementation - we only have one clock to + * deal with at the moment, so we only match using the "name". + */ struct clk { struct list_head node; unsigned long rate; - struct module *owner; const char *name; unsigned int enabled; void (*enable)(void); @@ -24,21 +27,21 @@ struct clk { }; static LIST_HEAD(clocks); -static DECLARE_MUTEX(clocks_sem); +static DEFINE_MUTEX(clocks_mutex); static DEFINE_SPINLOCK(clocks_lock); struct clk *clk_get(struct device *dev, const char *id) { struct clk *p, *clk = ERR_PTR(-ENOENT); - down(&clocks_sem); + mutex_lock(&clocks_mutex); list_for_each_entry(p, &clocks, node) { - if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { + if (strcmp(id, p->name) == 0) { clk = p; break; } } - up(&clocks_sem); + mutex_unlock(&clocks_mutex); return clk; } @@ -46,7 +49,6 @@ EXPORT_SYMBOL(clk_get); void clk_put(struct clk *clk) { - module_put(clk->owner); } EXPORT_SYMBOL(clk_put); @@ -109,18 +111,18 @@ static struct clk clk_gpio27 = { int clk_register(struct clk *clk) { - down(&clocks_sem); + mutex_lock(&clocks_mutex); list_add(&clk->node, &clocks); - up(&clocks_sem); + mutex_unlock(&clocks_mutex); return 0; } EXPORT_SYMBOL(clk_register); void clk_unregister(struct clk *clk) { - down(&clocks_sem); + mutex_lock(&clocks_mutex); list_del(&clk->node); - up(&clocks_sem); + mutex_unlock(&clocks_mutex); } EXPORT_SYMBOL(clk_unregister); -- cgit v1.2.3-59-g8ed1b From 7531a1c2c4477f63688871c1648d828f55313d42 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 22 Apr 2007 10:56:40 +0100 Subject: [ARM] Remove unnecessary asm/ptrace.h from VFP support code Signed-off-by: Russell King --- arch/arm/vfp/vfpdouble.c | 1 - arch/arm/vfp/vfpsingle.c | 1 - 2 files changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index e44b9ed0f81f..74e89f8fb3ab 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c @@ -34,7 +34,6 @@ #include #include -#include #include #include "vfpinstr.h" diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index 0221ba3bc799..b252631b406b 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c @@ -34,7 +34,6 @@ #include #include -#include #include #include "vfpinstr.h" -- cgit v1.2.3-59-g8ed1b From ed519dede3d705e1c0012acd5b8de4074aa30fa4 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 22 Apr 2007 12:30:41 +0100 Subject: [ARM] Convert AMBA PL010 driver to use the clk infrastructure Convert the AMBA PL010 serial driver to use the clock infrastructure to allow EP93xx platforms to properly gate the clock to the UARTs. Signed-off-by: Russell King --- arch/arm/mach-ep93xx/clock.c | 5 +++++ drivers/serial/amba-pl010.c | 39 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index f174d1a3b11c..9d7515c36bff 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c @@ -27,6 +27,10 @@ struct clk { u32 enable_mask; }; +static struct clk clk_uart = { + .name = "UARTCLK", + .rate = 14745600, +}; static struct clk clk_pll1 = { .name = "pll1", }; @@ -50,6 +54,7 @@ static struct clk clk_usb_host = { static struct clk *clocks[] = { + &clk_uart, &clk_pll1, &clk_f, &clk_h, diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index ea49aafd66bf..1a9a24b82636 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c @@ -48,6 +48,7 @@ #include #include #include +#include #include @@ -70,6 +71,7 @@ */ struct uart_amba_port { struct uart_port port; + struct clk *clk; struct amba_device *dev; struct amba_pl010_data *data; unsigned int old_status; @@ -312,12 +314,21 @@ static int pl010_startup(struct uart_port *port) struct uart_amba_port *uap = (struct uart_amba_port *)port; int retval; + /* + * Try to enable the clock producer. + */ + retval = clk_enable(uap->clk); + if (retval) + goto out; + + uap->port.uartclk = clk_get_rate(uap->clk); + /* * Allocate the IRQ */ retval = request_irq(uap->port.irq, pl010_int, 0, "uart-pl010", uap); if (retval) - return retval; + goto clk_dis; /* * initialise the old status of the modem signals @@ -331,6 +342,11 @@ static int pl010_startup(struct uart_port *port) uap->port.membase + UART010_CR); return 0; + + clk_dis: + clk_disable(uap->clk); + out: + return retval; } static void pl010_shutdown(struct uart_port *port) @@ -351,6 +367,11 @@ static void pl010_shutdown(struct uart_port *port) writel(readb(uap->port.membase + UART010_LCRH) & ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN), uap->port.membase + UART010_LCRH); + + /* + * Shut down the clock producer + */ + clk_disable(uap->clk); } static void @@ -540,6 +561,8 @@ pl010_console_write(struct console *co, const char *s, unsigned int count) struct uart_amba_port *uap = amba_ports[co->index]; unsigned int status, old_cr; + clk_enable(uap->clk); + /* * First save the CR then disable the interrupts */ @@ -557,6 +580,8 @@ pl010_console_write(struct console *co, const char *s, unsigned int count) barrier(); } while (status & UART01x_FR_BUSY); writel(old_cr, uap->port.membase + UART010_CR); + + clk_disable(uap->clk); } static void __init @@ -605,6 +630,8 @@ static int __init pl010_console_setup(struct console *co, char *options) if (!uap) return -ENODEV; + uap->port.uartclk = clk_get_rate(uap->clk); + if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); else @@ -666,12 +693,17 @@ static int pl010_probe(struct amba_device *dev, void *id) goto free; } + uap->clk = clk_get(&dev->dev, "UARTCLK"); + if (IS_ERR(uap->clk)) { + ret = PTR_ERR(uap->clk); + goto unmap; + } + uap->port.dev = &dev->dev; uap->port.mapbase = dev->res.start; uap->port.membase = base; uap->port.iotype = UPIO_MEM; uap->port.irq = dev->irq[0]; - uap->port.uartclk = 14745600; uap->port.fifosize = 16; uap->port.ops = &amba_pl010_pops; uap->port.flags = UPF_BOOT_AUTOCONF; @@ -686,6 +718,8 @@ static int pl010_probe(struct amba_device *dev, void *id) if (ret) { amba_set_drvdata(dev, NULL); amba_ports[i] = NULL; + clk_put(uap->clk); + unmap: iounmap(base); free: kfree(uap); @@ -708,6 +742,7 @@ static int pl010_remove(struct amba_device *dev) amba_ports[i] = NULL; iounmap(uap->port.membase); + clk_put(uap->clk); kfree(uap); return 0; } -- cgit v1.2.3-59-g8ed1b From 551948bc44260a5ab3ad63546506b2062f77eaa0 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 19 Mar 2007 19:17:00 +0300 Subject: [CPUFREQ] p4-clockmod: switch to rdmsr_on_cpu/wrmsr_on_cpu Dances with cpumasks go away. Signed-off-by: Alexey Dobriyan Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/p4-clockmod.c | 31 ++++++------------------------ 1 file changed, 6 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c index 4786fedca6eb..4c76b511e194 100644 --- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c @@ -27,7 +27,6 @@ #include #include #include -#include /* current / set_cpus_allowed() */ #include #include @@ -62,7 +61,7 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) if (!cpu_online(cpu) || (newstate > DC_DISABLE) || (newstate == DC_RESV)) return -EINVAL; - rdmsr(MSR_IA32_THERM_STATUS, l, h); + rdmsr_on_cpu(cpu, MSR_IA32_THERM_STATUS, &l, &h); if (l & 0x01) dprintk("CPU#%d currently thermal throttled\n", cpu); @@ -70,10 +69,10 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) if (has_N44_O17_errata[cpu] && (newstate == DC_25PT || newstate == DC_DFLT)) newstate = DC_38PT; - rdmsr(MSR_IA32_THERM_CONTROL, l, h); + rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h); if (newstate == DC_DISABLE) { dprintk("CPU#%d disabling modulation\n", cpu); - wrmsr(MSR_IA32_THERM_CONTROL, l & ~(1<<4), h); + wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, l & ~(1<<4), h); } else { dprintk("CPU#%d setting duty cycle to %d%%\n", cpu, ((125 * newstate) / 10)); @@ -84,7 +83,7 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) */ l = (l & ~14); l = l | (1<<4) | ((newstate & 0x7)<<1); - wrmsr(MSR_IA32_THERM_CONTROL, l, h); + wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, l, h); } return 0; @@ -111,7 +110,6 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy, { unsigned int newstate = DC_RESV; struct cpufreq_freqs freqs; - cpumask_t cpus_allowed; int i; if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0], target_freq, relation, &newstate)) @@ -132,17 +130,8 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy, /* run on each logical CPU, see section 13.15.3 of IA32 Intel Architecture Software * Developer's Manual, Volume 3 */ - cpus_allowed = current->cpus_allowed; - - for_each_cpu_mask(i, policy->cpus) { - cpumask_t this_cpu = cpumask_of_cpu(i); - - set_cpus_allowed(current, this_cpu); - BUG_ON(smp_processor_id() != i); - + for_each_cpu_mask(i, policy->cpus) cpufreq_p4_setdc(i, p4clockmod_table[newstate].index); - } - set_cpus_allowed(current, cpus_allowed); /* notifiers */ for_each_cpu_mask(i, policy->cpus) { @@ -256,17 +245,9 @@ static int cpufreq_p4_cpu_exit(struct cpufreq_policy *policy) static unsigned int cpufreq_p4_get(unsigned int cpu) { - cpumask_t cpus_allowed; u32 l, h; - cpus_allowed = current->cpus_allowed; - - set_cpus_allowed(current, cpumask_of_cpu(cpu)); - BUG_ON(smp_processor_id() != cpu); - - rdmsr(MSR_IA32_THERM_CONTROL, l, h); - - set_cpus_allowed(current, cpus_allowed); + rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h); if (l & 0x10) { l = l >> 1; -- cgit v1.2.3-59-g8ed1b From fb48e15645fb702cb2ec02c84f82ece2fbc1574d Mon Sep 17 00:00:00 2001 From: RafaÅ‚ Bilski Date: Fri, 2 Mar 2007 20:12:27 +0100 Subject: [CPUFREQ] Longhaul - Correct PCI code Replace obsolete pci_find_device with pci_get_device. Signed-off-by: Rafal Bilski Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/longhaul.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index 2b030d6ccbf7..e5fee7266348 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -590,20 +590,23 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle, static int enable_arbiter_disable(void) { struct pci_dev *dev; + int status; int reg; u8 pci_cmd; + status = 1; /* Find PLE133 host bridge */ reg = 0x78; - dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, NULL); + dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, + NULL); /* Find CLE266 host bridge */ if (dev == NULL) { reg = 0x76; - dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_862X_0, NULL); + dev = pci_get_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_862X_0, NULL); /* Find CN400 V-Link host bridge */ if (dev == NULL) - dev = pci_find_device(PCI_VENDOR_ID_VIA, 0x7259, NULL); - + dev = pci_get_device(PCI_VENDOR_ID_VIA, 0x7259, NULL); } if (dev != NULL) { /* Enable access to port 0x22 */ @@ -615,10 +618,11 @@ static int enable_arbiter_disable(void) if (!(pci_cmd & 1<<7)) { printk(KERN_ERR PFX "Can't enable access to port 0x22.\n"); - return 0; + status = 0; } } - return 1; + pci_dev_put(dev); + return status; } return 0; } @@ -629,7 +633,7 @@ static int longhaul_setup_vt8235(void) u8 pci_cmd; /* Find VT8235 southbridge */ - dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL); + dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL); if (dev != NULL) { /* Set transition time to max */ pci_read_config_byte(dev, 0xec, &pci_cmd); @@ -641,6 +645,7 @@ static int longhaul_setup_vt8235(void) pci_read_config_byte(dev, 0xe5, &pci_cmd); pci_cmd |= 1 << 7; pci_write_config_byte(dev, 0xe5, pci_cmd); + pci_dev_put(dev); return 1; } return 0; -- cgit v1.2.3-59-g8ed1b From e8e49190f64896afe79f7136a67c2bdefbd3e322 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 11 Apr 2007 18:22:34 -0400 Subject: Fix preemption warnings in speedstep-centrino.c BUG: using smp_processor_id() in preemptible [00000001] code: kondemand/0/2473 caller is centrino_target+0xfb/0x600 [<401e3646>] debug_smp_processor_id+0x9e/0xb0 [<40112afb>] centrino_target+0xfb/0x600 [<40112a00>] centrino_target+0x0/0x600 [<40305bd9>] __cpufreq_driver_target+0x5c/0x6b [] do_dbs_timer+0x1bc/0x208 [cpufreq_ondemand] [<40134a46>] run_workqueue+0x85/0x125 [<40374f7f>] _spin_lock_irqsave+0x18/0x66 [] do_dbs_timer+0x0/0x208 [cpufreq_ondemand] [<401353fb>] worker_thread+0xf9/0x124 [<401213b9>] default_wake_function+0x0/0xc [<40135302>] worker_thread+0x0/0x124 [<40137b37>] kthread+0xb0/0xd9 [<40137a87>] kthread+0x0/0xd9 [<40104b2f>] kernel_thread_helper+0x7/0x10 Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index f43b987f952b..35489fd68852 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c @@ -720,6 +720,7 @@ static int centrino_target (struct cpufreq_policy *policy, cpu_set(j, set_mask); set_cpus_allowed(current, set_mask); + preempt_disable(); if (unlikely(!cpu_isset(smp_processor_id(), set_mask))) { dprintk("couldn't limit to CPUs in this domain\n"); retval = -EAGAIN; @@ -727,6 +728,7 @@ static int centrino_target (struct cpufreq_policy *policy, /* We haven't started the transition yet. */ goto migrate_end; } + preempt_enable(); break; } @@ -761,10 +763,13 @@ static int centrino_target (struct cpufreq_policy *policy, } wrmsr(MSR_IA32_PERF_CTL, oldmsr, h); - if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) + if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { + preempt_enable(); break; + } cpu_set(j, covered_cpus); + preempt_enable(); } for_each_cpu_mask(k, online_policy_cpus) { @@ -796,8 +801,11 @@ static int centrino_target (struct cpufreq_policy *policy, cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); } } + set_cpus_allowed(current, saved_mask); + return 0; migrate_end: + preempt_enable(); set_cpus_allowed(current, saved_mask); return 0; } -- cgit v1.2.3-59-g8ed1b From 07844252ffd81ec192a62014bada1016c9703765 Mon Sep 17 00:00:00 2001 From: Rafal Bilski Date: Sun, 22 Apr 2007 12:26:04 +0200 Subject: [CPUFREQ] Longhaul - Revert Longhaul ver. 2 There is something wrong with this code. It needs more testing. It is better to disable it for now because support for some machines will be broken. Signed-off-by: Rafal Bilski Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/longhaul.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index e5fee7266348..a3df9c039bd4 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -683,7 +683,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) sizeof(samuel2_eblcr)); break; case 1 ... 15: - longhaul_version = TYPE_LONGHAUL_V2; + longhaul_version = TYPE_LONGHAUL_V1; if (c->x86_mask < 8) { cpu_model = CPU_SAMUEL2; cpuname = "C3 'Samuel 2' [C5B]"; -- cgit v1.2.3-59-g8ed1b From 9101be532a3c60c7e8773868395e3b75259d84c3 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 18 Apr 2007 16:18:13 -0400 Subject: [CPUFREQ] cleanup kconfig options Adds proper lines to help output of kconfig so people can find the module names. Also fixed some broken leading spaces versus tabs. Signed-off-by: Mike Frysinger Signed-off-by: Dave Jones --- arch/x86_64/kernel/cpufreq/Kconfig | 19 +++++++++--- drivers/cpufreq/Kconfig | 61 +++++++++++++++++++++++++++----------- 2 files changed, 58 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/cpufreq/Kconfig b/arch/x86_64/kernel/cpufreq/Kconfig index 40acb67fb882..c0749d2479f5 100644 --- a/arch/x86_64/kernel/cpufreq/Kconfig +++ b/arch/x86_64/kernel/cpufreq/Kconfig @@ -16,6 +16,9 @@ config X86_POWERNOW_K8 help This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors. + To compile this driver as a module, choose M here: the + module will be called powernow-k8. + For details, take a look at . If in doubt, say N. @@ -38,6 +41,9 @@ config X86_SPEEDSTEP_CENTRINO mobile CPUs. This means Intel Pentium M (Centrino) CPUs or 64bit enabled Intel Xeons. + To compile this driver as a module, choose M here: the + module will be called speedstep-centrino. + For details, take a look at . If in doubt, say N. @@ -55,6 +61,9 @@ config X86_ACPI_CPUFREQ Processor Performance States. This driver also supports Intel Enhanced Speedstep. + To compile this driver as a module, choose M here: the + module will be called acpi-cpufreq. + For details, take a look at . If in doubt, say N. @@ -62,7 +71,7 @@ config X86_ACPI_CPUFREQ comment "shared options" config X86_ACPI_CPUFREQ_PROC_INTF - bool "/proc/acpi/processor/../performance interface (deprecated)" + bool "/proc/acpi/processor/../performance interface (deprecated)" depends on PROC_FS depends on X86_ACPI_CPUFREQ || X86_SPEEDSTEP_CENTRINO_ACPI || X86_POWERNOW_K8_ACPI help @@ -86,16 +95,18 @@ config X86_P4_CLOCKMOD slowdowns and noticeable latencies. Normally Speedstep should be used instead. + To compile this driver as a module, choose M here: the + module will be called p4-clockmod. + For details, take a look at . Unless you are absolutely sure say N. config X86_SPEEDSTEP_LIB - tristate - default X86_P4_CLOCKMOD + tristate + default X86_P4_CLOCKMOD endif endmenu - diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index d155e81b5c97..993fa7b89253 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -9,6 +9,9 @@ config CPU_FREQ clock speed, you need to either enable a dynamic cpufreq governor (see below) after boot, or use a userspace tool. + To compile this driver as a module, choose M here: the + module will be called cpufreq. + For details, take a look at . If in doubt, say N. @@ -16,7 +19,7 @@ config CPU_FREQ if CPU_FREQ config CPU_FREQ_TABLE - tristate + tristate config CPU_FREQ_DEBUG bool "Enable CPUfreq debugging" @@ -32,19 +35,26 @@ config CPU_FREQ_DEBUG 4 to activate CPUfreq governor debugging config CPU_FREQ_STAT - tristate "CPU frequency translation statistics" - select CPU_FREQ_TABLE - default y - help - This driver exports CPU frequency statistics information through sysfs - file system + tristate "CPU frequency translation statistics" + select CPU_FREQ_TABLE + default y + help + This driver exports CPU frequency statistics information through sysfs + file system. + + To compile this driver as a module, choose M here: the + module will be called cpufreq_stats. + + If in doubt, say N. config CPU_FREQ_STAT_DETAILS - bool "CPU frequency translation statistics details" - depends on CPU_FREQ_STAT - help - This will show detail CPU frequency translation table in sysfs file - system + bool "CPU frequency translation statistics details" + depends on CPU_FREQ_STAT + help + This will show detail CPU frequency translation table in sysfs file + system. + + If in doubt, say N. # Note that it is not currently possible to set the other governors (such as ondemand) # as the default, since if they fail to initialise, cpufreq will be @@ -78,29 +88,38 @@ config CPU_FREQ_DEFAULT_GOV_USERSPACE endchoice config CPU_FREQ_GOV_PERFORMANCE - tristate "'performance' governor" - help + tristate "'performance' governor" + help This cpufreq governor sets the frequency statically to the highest available CPU frequency. + To compile this driver as a module, choose M here: the + module will be called cpufreq_performance. + If in doubt, say Y. config CPU_FREQ_GOV_POWERSAVE - tristate "'powersave' governor" - help + tristate "'powersave' governor" + help This cpufreq governor sets the frequency statically to the lowest available CPU frequency. + To compile this driver as a module, choose M here: the + module will be called cpufreq_powersave. + If in doubt, say Y. config CPU_FREQ_GOV_USERSPACE - tristate "'userspace' governor for userspace frequency scaling" - help + tristate "'userspace' governor for userspace frequency scaling" + help Enable this cpufreq governor when you either want to set the CPU frequency manually or when an userspace program shall be able to set the CPU dynamically, like on LART . + To compile this driver as a module, choose M here: the + module will be called cpufreq_userspace. + For details, take a look at . If in doubt, say Y. @@ -116,6 +135,9 @@ config CPU_FREQ_GOV_ONDEMAND do fast frequency switching (i.e, very low latency frequency transitions). + To compile this driver as a module, choose M here: the + module will be called cpufreq_ondemand. + For details, take a look at linux/Documentation/cpu-freq. If in doubt, say N. @@ -136,6 +158,9 @@ config CPU_FREQ_GOV_CONSERVATIVE step-by-step latency issues between the minimum and maximum frequency transitions in the CPU) you will probably want to use this governor. + To compile this driver as a module, choose M here: the + module will be called cpufreq_conservative. + For details, take a look at linux/Documentation/cpu-freq. If in doubt, say N. -- cgit v1.2.3-59-g8ed1b From f16fb1ecc5a1cb2f7cc595179d1fe55e711e599f Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 28 Apr 2007 09:59:37 +0100 Subject: [ARM] Add stacktrace support and make oprofile use it Add support for stacktrace. Use the new stacktrace code with oprofile instead of it's version; there's no point having multiple versions of stacktracing in the kernel. Signed-off-by: Russell King --- arch/arm/Kconfig | 8 +++++ arch/arm/kernel/Makefile | 4 +-- arch/arm/kernel/stacktrace.c | 73 +++++++++++++++++++++++++++++++++++++++++++ arch/arm/kernel/stacktrace.h | 9 ++++++ arch/arm/oprofile/backtrace.c | 69 ++++++++++------------------------------ 5 files changed, 109 insertions(+), 54 deletions(-) create mode 100644 arch/arm/kernel/stacktrace.c create mode 100644 arch/arm/kernel/stacktrace.h (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e7baca29f3fb..e25a197af6e8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -67,6 +67,14 @@ config GENERIC_HARDIRQS bool default y +config STACKTRACE_SUPPORT + bool + default y + +config LOCKDEP_SUPPORT + bool + default y + config TRACE_IRQFLAGS_SUPPORT bool default y diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index bb28087bf818..593b56509f4f 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -7,8 +7,8 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) # Object file lists. obj-y := compat.o entry-armv.o entry-common.o irq.o \ - process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \ - time.o traps.o + process.o ptrace.o semaphore.o setup.o signal.o \ + sys_arm.o stacktrace.o time.o traps.o obj-$(CONFIG_ISA_DMA_API) += dma.o obj-$(CONFIG_ARCH_ACORN) += ecard.o diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c new file mode 100644 index 000000000000..77ef35efaa8d --- /dev/null +++ b/arch/arm/kernel/stacktrace.c @@ -0,0 +1,73 @@ +#include +#include + +#include "stacktrace.h" + +int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high, + int (*fn)(struct stackframe *, void *), void *data) +{ + struct stackframe *frame; + + do { + /* + * Check current frame pointer is within bounds + */ + if ((fp - 12) < low || fp + 4 >= high) + break; + + frame = (struct stackframe *)(fp - 12); + + if (fn(frame, data)) + break; + + /* + * Update the low bound - the next frame must always + * be at a higher address than the current frame. + */ + low = fp + 4; + fp = frame->fp; + } while (fp); + + return 0; +} + +#ifdef CONFIG_STACKTRACE +struct stack_trace_data { + struct stack_trace *trace; + unsigned int skip; +}; + +static int save_trace(struct stackframe *frame, void *d) +{ + struct stack_trace_data *data = d; + struct stack_trace *trace = data->trace; + + if (data->skip) { + data->skip--; + return 0; + } + + trace->entries[trace->nr_entries++] = frame->lr; + + return trace->nr_entries >= trace->max_entries; +} + +void save_stack_trace(struct stack_trace *trace, struct task_struct *task) +{ + struct stack_trace_data data; + unsigned long fp, base; + + data.trace = trace; + data.skip = trace->skip; + + if (task) { + base = (unsigned long)task_stack_page(task); + fp = 0; /* FIXME */ + } else { + base = (unsigned long)task_stack_page(current); + asm("mov %0, fp" : "=r" (fp)); + } + + walk_stackframe(fp, base, base + THREAD_SIZE, save_trace, &data); +} +#endif diff --git a/arch/arm/kernel/stacktrace.h b/arch/arm/kernel/stacktrace.h new file mode 100644 index 000000000000..e9fd20cb5662 --- /dev/null +++ b/arch/arm/kernel/stacktrace.h @@ -0,0 +1,9 @@ +struct stackframe { + unsigned long fp; + unsigned long sp; + unsigned long lr; + unsigned long pc; +}; + +int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high, + int (*fn)(struct stackframe *, void *), void *data); diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c index 7c22c12618cc..f5ebf30151fa 100644 --- a/arch/arm/oprofile/backtrace.c +++ b/arch/arm/oprofile/backtrace.c @@ -19,6 +19,19 @@ #include #include +#include "../kernel/stacktrace.h" + +static int report_trace(struct stackframe *frame, void *d) +{ + unsigned int *depth = d; + + if (*depth) { + oprofile_add_trace(frame->lr); + (*depth)--; + } + + return *depth == 0; +} /* * The registers we're interested in are at the end of the variable @@ -32,21 +45,6 @@ struct frame_tail { unsigned long lr; } __attribute__((packed)); - -#ifdef CONFIG_FRAME_POINTER -static struct frame_tail* kernel_backtrace(struct frame_tail *tail) -{ - oprofile_add_trace(tail->lr); - - /* frame pointers should strictly progress back up the stack - * (towards higher addresses) */ - if (tail >= tail->fp) - return NULL; - - return tail->fp-1; -} -#endif - static struct frame_tail* user_backtrace(struct frame_tail *tail) { struct frame_tail buftail[2]; @@ -67,47 +65,14 @@ static struct frame_tail* user_backtrace(struct frame_tail *tail) return buftail[0].fp-1; } -/* - * | | /\ Higher addresses - * | | - * --------------- stack base (address of current_thread_info) - * | thread info | - * . . - * | stack | - * --------------- saved regs->ARM_fp value if valid (frame_tail address) - * . . - * --------------- struct pt_regs stored on stack (struct pt_regs *) - * | | - * . . - * | | - * --------------- %esp - * | | - * | | \/ Lower addresses - * - * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values - */ -static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs) -{ - unsigned long tailaddr = (unsigned long)tail; - unsigned long stack = (unsigned long)regs; - unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE; - - return (tailaddr > stack) && (tailaddr < stack_base); -} - void arm_backtrace(struct pt_regs * const regs, unsigned int depth) { - struct frame_tail *tail; - - tail = ((struct frame_tail *) regs->ARM_fp) - 1; + struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1; if (!user_mode(regs)) { - -#ifdef CONFIG_FRAME_POINTER - while (depth-- && tail && valid_kernel_stack(tail, regs)) { - tail = kernel_backtrace(tail); - } -#endif + unsigned long base = ((unsigned long)regs) & ~(THREAD_SIZE - 1); + walk_stackframe(regs->ARM_fp, base, base + THREAD_SIZE, + report_trace, &depth); return; } -- cgit v1.2.3-59-g8ed1b From 3e18c8dd0d3456f96e13bc2e72197bfae11d8501 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Thu, 26 Apr 2007 00:04:39 -0700 Subject: [ARM] fix section mismatch warning in board-sam9260 Andrew Morton found a section mismatch warning in x86_64 triggered by a wrongly placed __initdata marker. git grep "struct __initdata" revealed that board-sam9260.c had the same problem. This patch fixes this by placing the __initdata marker correct. It was checked with objdump that the variable was moved to .init.data by this change. Fixed an unrelated section mismatch warning while touching the file. Both changes are only compile tested but obvious correct. [Used at91sam9260ek_defconfig to get compile coverage] Signed-off-by: Sam Ravnborg Signed-off-by: Andrew Morton Signed-off-by: Russell King --- arch/arm/mach-at91/board-sam9260ek.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c index 57fb4499d969..7a31db01b6fe 100644 --- a/arch/arm/mach-at91/board-sam9260ek.c +++ b/arch/arm/mach-at91/board-sam9260ek.c @@ -118,7 +118,7 @@ static struct spi_board_info ek_spi_devices[] = { /* * MACB Ethernet device */ -static struct __initdata at91_eth_data ek_macb_data = { +static struct at91_eth_data __initdata ek_macb_data = { .phy_irq_pin = AT91_PIN_PA7, .is_rmii = 1, }; @@ -140,7 +140,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { }, }; -static struct mtd_partition *nand_partitions(int size, int *num_partitions) +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) { *num_partitions = ARRAY_SIZE(ek_nand_partition); return ek_nand_partition; -- cgit v1.2.3-59-g8ed1b From 8903fcce9b91bab6bb98adbb57a4edfc372c8bff Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 29 Apr 2007 09:31:21 +0100 Subject: [ARM] 4340/1: iop: fix iop_getttimeoffset Fix a typo which causes a necessary cpwait to be missed on iop3xx, Michael Brunner Save a register in the assembly routine, rmk Cc: Lennert Buytenhek Signed-off-by: Dan Williams Signed-off-by: Russell King --- arch/arm/plat-iop/time.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c index 16300adfb4de..0cc26da034a1 100644 --- a/arch/arm/plat-iop/time.c +++ b/arch/arm/plat-iop/time.c @@ -32,22 +32,22 @@ static unsigned long next_jiffy_time; unsigned long iop_gettimeoffset(void) { - unsigned long offset, temp1, temp2; + unsigned long offset, temp; /* enable cp6, if necessary, to avoid taking the overhead of an * undefined instruction trap */ asm volatile ( "mrc p15, 0, %0, c15, c1, 0\n\t" - "ands %1, %0, #(1 << 6)\n\t" + "tst %0, #(1 << 6)\n\t" "orreq %0, %0, #(1 << 6)\n\t" "mcreq p15, 0, %0, c15, c1, 0\n\t" -#ifdef CONFIG_XSCALE +#ifdef CONFIG_CPU_XSCALE "mrceq p15, 0, %0, c15, c1, 0\n\t" "moveq %0, %0\n\t" "subeq pc, pc, #4\n\t" #endif - : "=r"(temp1), "=r"(temp2) : : "cc"); + : "=r"(temp) : : "cc"); offset = next_jiffy_time - read_tcr1(); -- cgit v1.2.3-59-g8ed1b From 7dcad376e85b6eff56f29ee21e10e1fe855f1ed7 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 29 Apr 2007 09:31:51 +0100 Subject: [ARM] 4341/1: iop13xx: fix i/o address translation PCI devices were being programmed with an incorrect base address value. This patch moves I/O space into a 16-bit addressable region and corrects the i/o offset. Much thanks to Martin Michlmayr for tracking this issue and testing debug patches. Cc: Martin Michlmayr Signed-off-by: Dan Williams Signed-off-by: Russell King --- arch/arm/mach-iop13xx/pci.c | 8 ++++---- include/asm-arm/arch-iop13xx/iop13xx.h | 22 +++++++++++++--------- 2 files changed, 17 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c index 89ec70ea3187..d907a2aadfe6 100644 --- a/arch/arm/mach-iop13xx/pci.c +++ b/arch/arm/mach-iop13xx/pci.c @@ -1023,7 +1023,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) << IOP13XX_ATUX_PCIXSR_FUNC_NUM; __raw_writel(pcixsr, IOP13XX_ATUX_PCIXSR); - res[0].start = IOP13XX_PCIX_LOWER_IO_PA; + res[0].start = IOP13XX_PCIX_LOWER_IO_PA + IOP13XX_PCIX_IO_BUS_OFFSET; res[0].end = IOP13XX_PCIX_UPPER_IO_PA; res[0].name = "IQ81340 ATUX PCI I/O Space"; res[0].flags = IORESOURCE_IO; @@ -1033,7 +1033,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) res[1].name = "IQ81340 ATUX PCI Memory Space"; res[1].flags = IORESOURCE_MEM; sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET; - sys->io_offset = IOP13XX_PCIX_IO_OFFSET; + sys->io_offset = IOP13XX_PCIX_LOWER_IO_PA; break; case IOP13XX_INIT_ATU_ATUE: /* Note: the function number field in the PCSR is ro */ @@ -1044,7 +1044,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) __raw_writel(pcsr, IOP13XX_ATUE_PCSR); - res[0].start = IOP13XX_PCIE_LOWER_IO_PA; + res[0].start = IOP13XX_PCIE_LOWER_IO_PA + IOP13XX_PCIE_IO_BUS_OFFSET; res[0].end = IOP13XX_PCIE_UPPER_IO_PA; res[0].name = "IQ81340 ATUE PCI I/O Space"; res[0].flags = IORESOURCE_IO; @@ -1054,7 +1054,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) res[1].name = "IQ81340 ATUE PCI Memory Space"; res[1].flags = IORESOURCE_MEM; sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET; - sys->io_offset = IOP13XX_PCIE_IO_OFFSET; + sys->io_offset = IOP13XX_PCIE_LOWER_IO_PA; sys->map_irq = iop13xx_pcie_map_irq; break; default: diff --git a/include/asm-arm/arch-iop13xx/iop13xx.h b/include/asm-arm/arch-iop13xx/iop13xx.h index d26b755a9879..2d1e23ba67c6 100644 --- a/include/asm-arm/arch-iop13xx/iop13xx.h +++ b/include/asm-arm/arch-iop13xx/iop13xx.h @@ -27,19 +27,24 @@ static inline int iop13xx_cpu_id(void) #define IOP13XX_PCI_OFFSET IOP13XX_MAX_RAM_SIZE /* PCI MAP - * 0x0000.0000 - 0x8000.0000 1:1 mapping with Physical RAM - * 0x8000.0000 - 0x8800.0000 PCIX/PCIE memory window (128MB) -*/ + * bus range cpu phys cpu virt note + * 0x0000.0000 + 2GB (n/a) (n/a) inbound, 1:1 mapping with Physical RAM + * 0x8000.0000 + 928M 0x1.8000.0000 (ioremap) PCIX outbound memory window + * 0x8000.0000 + 928M 0x2.8000.0000 (ioremap) PCIE outbound memory window + * + * IO MAP + * 0x1000 + 64K 0x0.fffb.1000 0xfec6.1000 PCIX outbound i/o window + * 0x1000 + 64K 0x0.fffd.1000 0xfed7.1000 PCIE outbound i/o window + */ #define IOP13XX_PCIX_IO_WINDOW_SIZE 0x10000UL #define IOP13XX_PCIX_LOWER_IO_PA 0xfffb0000UL #define IOP13XX_PCIX_LOWER_IO_VA 0xfec60000UL -#define IOP13XX_PCIX_LOWER_IO_BA 0x0fff0000UL +#define IOP13XX_PCIX_LOWER_IO_BA 0x0UL /* OIOTVR */ +#define IOP13XX_PCIX_IO_BUS_OFFSET 0x1000UL #define IOP13XX_PCIX_UPPER_IO_PA (IOP13XX_PCIX_LOWER_IO_PA +\ IOP13XX_PCIX_IO_WINDOW_SIZE - 1) #define IOP13XX_PCIX_UPPER_IO_VA (IOP13XX_PCIX_LOWER_IO_VA +\ IOP13XX_PCIX_IO_WINDOW_SIZE - 1) -#define IOP13XX_PCIX_IO_OFFSET (IOP13XX_PCIX_LOWER_IO_VA -\ - IOP13XX_PCIX_LOWER_IO_BA) #define IOP13XX_PCIX_IO_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\ (IOP13XX_PCIX_LOWER_IO_PA\ - IOP13XX_PCIX_LOWER_IO_VA)) @@ -65,15 +70,14 @@ static inline int iop13xx_cpu_id(void) #define IOP13XX_PCIE_IO_WINDOW_SIZE 0x10000UL #define IOP13XX_PCIE_LOWER_IO_PA 0xfffd0000UL #define IOP13XX_PCIE_LOWER_IO_VA 0xfed70000UL -#define IOP13XX_PCIE_LOWER_IO_BA 0x0fff0000UL +#define IOP13XX_PCIE_LOWER_IO_BA 0x0UL /* OIOTVR */ +#define IOP13XX_PCIE_IO_BUS_OFFSET 0x1000UL #define IOP13XX_PCIE_UPPER_IO_PA (IOP13XX_PCIE_LOWER_IO_PA +\ IOP13XX_PCIE_IO_WINDOW_SIZE - 1) #define IOP13XX_PCIE_UPPER_IO_VA (IOP13XX_PCIE_LOWER_IO_VA +\ IOP13XX_PCIE_IO_WINDOW_SIZE - 1) #define IOP13XX_PCIE_UPPER_IO_BA (IOP13XX_PCIE_LOWER_IO_BA +\ IOP13XX_PCIE_IO_WINDOW_SIZE - 1) -#define IOP13XX_PCIE_IO_OFFSET (IOP13XX_PCIE_LOWER_IO_VA -\ - IOP13XX_PCIE_LOWER_IO_BA) #define IOP13XX_PCIE_IO_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\ (IOP13XX_PCIE_LOWER_IO_PA\ - IOP13XX_PCIE_LOWER_IO_VA)) -- cgit v1.2.3-59-g8ed1b From 84c981ffb371828ad6d1d220f076453b54734302 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 29 Apr 2007 09:32:51 +0100 Subject: [ARM] 4343/1: iop13xx: automatically detect the internal bus frequency Signed-off-by: Dan Williams Signed-off-by: Russell King --- arch/arm/mach-iop13xx/iq81340mc.c | 4 ++- arch/arm/mach-iop13xx/iq81340sc.c | 4 ++- include/asm-arm/arch-iop13xx/iop13xx.h | 1 + include/asm-arm/arch-iop13xx/time.h | 56 ++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c index a519d707571c..1ae08cc04b48 100644 --- a/arch/arm/mach-iop13xx/iq81340mc.c +++ b/arch/arm/mach-iop13xx/iq81340mc.c @@ -79,7 +79,9 @@ static void __init iq81340mc_init(void) static void __init iq81340mc_timer_init(void) { - iop_init_time(400000000); + unsigned long bus_freq = iop13xx_core_freq() / iop13xx_xsi_bus_ratio(); + printk(KERN_DEBUG "%s: bus frequency: %lu\n", __FUNCTION__, bus_freq); + iop_init_time(bus_freq); } static struct sys_timer iq81340mc_timer = { diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c index 0e71fbcabe00..0f8801406f23 100644 --- a/arch/arm/mach-iop13xx/iq81340sc.c +++ b/arch/arm/mach-iop13xx/iq81340sc.c @@ -81,7 +81,9 @@ static void __init iq81340sc_init(void) static void __init iq81340sc_timer_init(void) { - iop_init_time(400000000); + unsigned long bus_freq = iop13xx_core_freq() / iop13xx_xsi_bus_ratio(); + printk(KERN_DEBUG "%s: bus frequency: %lu\n", __FUNCTION__, bus_freq); + iop_init_time(bus_freq); } static struct sys_timer iq81340sc_timer = { diff --git a/include/asm-arm/arch-iop13xx/iop13xx.h b/include/asm-arm/arch-iop13xx/iop13xx.h index 2d1e23ba67c6..c8762ae8f628 100644 --- a/include/asm-arm/arch-iop13xx/iop13xx.h +++ b/include/asm-arm/arch-iop13xx/iop13xx.h @@ -455,4 +455,5 @@ static inline int iop13xx_cpu_id(void) #define IOP13XX_PBI_BAR1 IOP13XX_PBI_OFFSET(0x10) #define IOP13XX_PBI_LR1 IOP13XX_PBI_OFFSET(0x14) +#define IOP13XX_PROCESSOR_FREQ IOP13XX_REG_ADDR32(0x2180) #endif /* _IOP13XX_HW_H_ */ diff --git a/include/asm-arm/arch-iop13xx/time.h b/include/asm-arm/arch-iop13xx/time.h index 77a837a02dec..49213d9d7cad 100644 --- a/include/asm-arm/arch-iop13xx/time.h +++ b/include/asm-arm/arch-iop13xx/time.h @@ -7,9 +7,65 @@ #define IOP_TMR_PRIVILEGED 0x08 #define IOP_TMR_RATIO_1_1 0x00 +#define IOP13XX_XSI_FREQ_RATIO_MASK (3 << 19) +#define IOP13XX_XSI_FREQ_RATIO_2 (0 << 19) +#define IOP13XX_XSI_FREQ_RATIO_3 (1 << 19) +#define IOP13XX_XSI_FREQ_RATIO_4 (2 << 19) +#define IOP13XX_CORE_FREQ_MASK (7 << 16) +#define IOP13XX_CORE_FREQ_600 (0 << 16) +#define IOP13XX_CORE_FREQ_667 (1 << 16) +#define IOP13XX_CORE_FREQ_800 (2 << 16) +#define IOP13XX_CORE_FREQ_933 (3 << 16) +#define IOP13XX_CORE_FREQ_1000 (4 << 16) +#define IOP13XX_CORE_FREQ_1200 (5 << 16) + void iop_init_time(unsigned long tickrate); unsigned long iop_gettimeoffset(void); +static inline unsigned long iop13xx_core_freq(void) +{ + unsigned long freq = __raw_readl(IOP13XX_PROCESSOR_FREQ); + freq &= IOP13XX_CORE_FREQ_MASK; + switch (freq) { + case IOP13XX_CORE_FREQ_600: + return 600000000; + case IOP13XX_CORE_FREQ_667: + return 667000000; + case IOP13XX_CORE_FREQ_800: + return 800000000; + case IOP13XX_CORE_FREQ_933: + return 933000000; + case IOP13XX_CORE_FREQ_1000: + return 1000000000; + case IOP13XX_CORE_FREQ_1200: + return 1200000000; + default: + printk("%s: warning unknown frequency, defaulting to 800Mhz\n", + __FUNCTION__); + } + + return 800000000; +} + +static inline unsigned long iop13xx_xsi_bus_ratio(void) +{ + unsigned long ratio = __raw_readl(IOP13XX_PROCESSOR_FREQ); + ratio &= IOP13XX_XSI_FREQ_RATIO_MASK; + switch (ratio) { + case IOP13XX_XSI_FREQ_RATIO_2: + return 2; + case IOP13XX_XSI_FREQ_RATIO_3: + return 3; + case IOP13XX_XSI_FREQ_RATIO_4: + return 4; + default: + printk("%s: warning unknown ratio, defaulting to 2\n", + __FUNCTION__); + } + + return 2; +} + static inline void write_tmr0(u32 val) { asm volatile("mcr p6, 0, %0, c0, c9, 0" : : "r" (val)); -- cgit v1.2.3-59-g8ed1b From fa543f005de175080640266ca536d45b4b0b1a61 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 29 Apr 2007 09:33:22 +0100 Subject: [ARM] 4344/1: iop13xx: do not claim both uarts by default on iop342 Signed-off-by: Dan Williams Signed-off-by: Russell King --- arch/arm/mach-iop13xx/setup.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-iop13xx/setup.c b/arch/arm/mach-iop13xx/setup.c index 9a46bcd5f18e..bc4871553f6a 100644 --- a/arch/arm/mach-iop13xx/setup.c +++ b/arch/arm/mach-iop13xx/setup.c @@ -258,15 +258,11 @@ void __init iop13xx_platform_init(void) if (init_uart == IOP13XX_INIT_UART_DEFAULT) { switch (iop13xx_dev_id()) { - /* enable both uarts on iop341 and iop342 */ + /* enable both uarts on iop341 */ case 0x3380: case 0x3384: case 0x3388: case 0x338c: - case 0x3382: - case 0x3386: - case 0x338a: - case 0x338e: init_uart |= IOP13XX_INIT_UART_0; init_uart |= IOP13XX_INIT_UART_1; break; -- cgit v1.2.3-59-g8ed1b From 0293ca814b74e20e77cf719074ee15372204fc55 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Mon, 30 Apr 2007 11:24:05 -0500 Subject: [VOYAGER] add smp_call_function_single This apparently has msr users now, so add it to the voyager HAL Signed-off-by: James Bottomley --- arch/i386/mach-voyager/voyager_smp.c | 57 ++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index 74aeedf277f4..a126baeaa423 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c @@ -1082,20 +1082,11 @@ smp_call_function_interrupt(void) } } -/* Call this function on all CPUs using the function_interrupt above - The function to run. This must be fast and non-blocking. - An arbitrary pointer to pass to the function. - If true, keep retrying until ready. - If true, wait until function has completed on other CPUs. - [RETURNS] 0 on success, else a negative status code. Does not return until - remote CPUs are nearly ready to execute <> or are or have executed. -*/ -int -smp_call_function (void (*func) (void *info), void *info, int retry, - int wait) +static int +__smp_call_function_mask (void (*func) (void *info), void *info, int retry, + int wait, __u32 mask) { struct call_data_struct data; - __u32 mask = cpus_addr(cpu_online_map)[0]; mask &= ~(1< The function to run. This must be fast and non-blocking. + An arbitrary pointer to pass to the function. + If true, keep retrying until ready. + If true, wait until function has completed on other CPUs. + [RETURNS] 0 on success, else a negative status code. Does not return until + remote CPUs are nearly ready to execute <> or are or have executed. +*/ +int +smp_call_function(void (*func) (void *info), void *info, int retry, + int wait) +{ + __u32 mask = cpus_addr(cpu_online_map)[0]; + + return __smp_call_function_mask(func, info, retry, wait, mask); +} EXPORT_SYMBOL(smp_call_function); +/* + * smp_call_function_single - Run a function on another CPU + * @func: The function to run. This must be fast and non-blocking. + * @info: An arbitrary pointer to pass to the function. + * @nonatomic: Currently unused. + * @wait: If true, wait until function has completed on other CPUs. + * + * Retrurns 0 on success, else a negative status code. + * + * Does not return until the remote CPU is nearly ready to execute + * or is or has executed. + */ + +int +smp_call_function_single(int cpu, void (*func) (void *info), void *info, + int nonatomic, int wait) +{ + __u32 mask = 1 << cpu; + + return __smp_call_function_mask(func, info, nonatomic, wait, mask); +} +EXPORT_SYMBOL(smp_call_function_single); + /* Sorry about the name. In an APIC based system, the APICs * themselves are programmed to send a timer interrupt. This is used * by linux to reschedule the processor. Voyager doesn't have this, -- cgit v1.2.3-59-g8ed1b From b96e80e3237777e5d7994a720ab722eb8f7edc60 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 30 Apr 2007 07:34:37 -0700 Subject: [CPUFREQ] do not declare undefined functions fill_powernow_table_pstate() and fill_powernow_table_fidvid() are only defined and used for X86_POWERNOW_K8_ACPI. Signed-off-by: David Rientjes Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k8.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h index 0fb2a3001ba5..95be5013c984 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h @@ -215,8 +215,10 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid); static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index); +#ifdef CONFIG_X86_POWERNOW_K8_ACPI static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table); static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table); +#endif #ifdef CONFIG_SMP static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[]) -- cgit v1.2.3-59-g8ed1b From 2e4976206396274cf66590328c6913811c271495 Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Mon, 30 Apr 2007 14:15:05 -0500 Subject: [CPUFREQ] Report the number of processors in PowerNow-k8 correctly The PowerNow! driver for Opteron reports the number of cores in the system, but claims to report the number of processors. Fix this minor cosmetic bug. Signed-off-by: Bhavana Nagendra Acked-by: Mark Langsdorf Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index fe3b67005ebb..7cf3d207b6b3 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -661,7 +661,8 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst, dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid); data->powernow_table = powernow_table; - print_basics(data); + if (first_cpu(cpu_core_map[data->cpu]) == data->cpu) + print_basics(data); for (j = 0; j < data->numps; j++) if ((pst[j].fid==data->currfid) && (pst[j].vid==data->currvid)) @@ -814,7 +815,8 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) /* fill in data */ data->numps = data->acpi_data.state_count; - print_basics(data); + if (first_cpu(cpu_core_map[data->cpu]) == data->cpu) + print_basics(data); powernow_k8_acpi_pst_values(data, 0); /* notify BIOS that we exist */ -- cgit v1.2.3-59-g8ed1b From 2feae2158a96aa5e02ca2e630896e6f553c36dc0 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Mon, 30 Apr 2007 11:27:25 -0500 Subject: [VOYAGER] clockevents: correct boot cpu is zero assumption This isn't true for voyager, so alter setup_pit_timer() to initialise the cpumask from the current processor id (which should be the boot processor) rather than defaulting to zero. Acked-by: Thomas Gleixner Signed-off-by: James Bottomley --- arch/i386/kernel/i8253.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/i8253.c b/arch/i386/kernel/i8253.c index 10cef5ca8a5b..f8a3c4054c70 100644 --- a/arch/i386/kernel/i8253.c +++ b/arch/i386/kernel/i8253.c @@ -110,7 +110,7 @@ void __init setup_pit_timer(void) * Start pit with the boot cpu mask and make it global after the * IO_APIC has been initialized. */ - pit_clockevent.cpumask = cpumask_of_cpu(0); + pit_clockevent.cpumask = cpumask_of_cpu(smp_processor_id()); pit_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, 32); pit_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFF, &pit_clockevent); -- cgit v1.2.3-59-g8ed1b From 9f483519be82420e308b9a90a96a9c62f28032ae Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Mon, 30 Apr 2007 11:30:10 -0500 Subject: [VOYAGER] clockevents driver: bring voyager in to line The irq0 timer interrupt should be initiallised identically with mach-default. Signed-off-by: James Bottomley --- arch/i386/mach-voyager/setup.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/mach-voyager/setup.c b/arch/i386/mach-voyager/setup.c index cfa16c151c8f..447bb105cf58 100644 --- a/arch/i386/mach-voyager/setup.c +++ b/arch/i386/mach-voyager/setup.c @@ -40,10 +40,16 @@ void __init trap_init_hook(void) { } -static struct irqaction irq0 = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL}; +static struct irqaction irq0 = { + .handler = timer_interrupt, + .flags = IRQF_DISABLED | IRQF_NOBALANCING, + .mask = CPU_MASK_NONE, + .name = "timer" +}; void __init time_init_hook(void) { + irq0.mask = cpumask_of_cpu(safe_smp_processor_id()); setup_irq(0, &irq0); } -- cgit v1.2.3-59-g8ed1b From f3402a4e52fc1bdfc386a7f512e6e384cd69ecad Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sun, 22 Apr 2007 20:30:43 +0100 Subject: [VOYAGER] Convert the monitor thread to use the kthread API full kthread conversion on the voyager power switch handling thread. Signed-off-by: Christoph Hellwig Signed-off-by: James Bottomley --- arch/i386/mach-voyager/voyager_cat.c | 4 +- arch/i386/mach-voyager/voyager_thread.c | 69 ++++++++++----------------------- include/asm-i386/voyager.h | 6 +-- 3 files changed, 24 insertions(+), 55 deletions(-) (limited to 'arch') diff --git a/arch/i386/mach-voyager/voyager_cat.c b/arch/i386/mach-voyager/voyager_cat.c index 943a9473b138..26a2d4c54b68 100644 --- a/arch/i386/mach-voyager/voyager_cat.c +++ b/arch/i386/mach-voyager/voyager_cat.c @@ -1111,7 +1111,7 @@ voyager_cat_do_common_interrupt(void) printk(KERN_ERR "Voyager front panel switch turned off\n"); voyager_status.switch_off = 1; voyager_status.request_from_kernel = 1; - up(&kvoyagerd_sem); + wake_up_process(voyager_thread); } /* Tell the hardware we're taking care of the * shutdown, otherwise it will power the box off @@ -1157,7 +1157,7 @@ voyager_cat_do_common_interrupt(void) outb(VOYAGER_CAT_END, CAT_CMD); voyager_status.power_fail = 1; voyager_status.request_from_kernel = 1; - up(&kvoyagerd_sem); + wake_up_process(voyager_thread); } diff --git a/arch/i386/mach-voyager/voyager_thread.c b/arch/i386/mach-voyager/voyager_thread.c index f39887359e8e..fdc1d926fb2a 100644 --- a/arch/i386/mach-voyager/voyager_thread.c +++ b/arch/i386/mach-voyager/voyager_thread.c @@ -24,33 +24,16 @@ #include #include #include +#include #include #include #include #include #include -#define THREAD_NAME "kvoyagerd" -/* external variables */ -int kvoyagerd_running = 0; -DECLARE_MUTEX_LOCKED(kvoyagerd_sem); - -static int thread(void *); - -static __u8 set_timeout = 0; - -/* Start the machine monitor thread. Return 1 if OK, 0 if fail */ -static int __init -voyager_thread_start(void) -{ - if(kernel_thread(thread, NULL, CLONE_KERNEL) < 0) { - /* This is serious, but not fatal */ - printk(KERN_ERR "Voyager: Failed to create system monitor thread!!!\n"); - return 1; - } - return 0; -} +struct task_struct *voyager_thread; +static __u8 set_timeout; static int execute(const char *string) @@ -110,31 +93,15 @@ check_continuing_condition(void) } } -static void -wakeup(unsigned long unused) -{ - up(&kvoyagerd_sem); -} - static int thread(void *unused) { - struct timer_list wakeup_timer; - - kvoyagerd_running = 1; - - daemonize(THREAD_NAME); - - set_timeout = 0; - - init_timer(&wakeup_timer); - - sigfillset(¤t->blocked); - printk(KERN_NOTICE "Voyager starting monitor thread\n"); - for(;;) { - down_interruptible(&kvoyagerd_sem); + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(set_timeout ? HZ : MAX_SCHEDULE_TIMEOUT); + VDEBUG(("Voyager Daemon awoken\n")); if(voyager_status.request_from_kernel == 0) { /* probably awoken from timeout */ @@ -143,20 +110,26 @@ thread(void *unused) check_from_kernel(); voyager_status.request_from_kernel = 0; } - if(set_timeout) { - del_timer(&wakeup_timer); - wakeup_timer.expires = HZ + jiffies; - wakeup_timer.function = wakeup; - add_timer(&wakeup_timer); - } } } +static int __init +voyager_thread_start(void) +{ + voyager_thread = kthread_run(thread, NULL, "kvoyagerd"); + if (IS_ERR(voyager_thread)) { + printk(KERN_ERR "Voyager: Failed to create system monitor thread.\n"); + return PTR_ERR(voyager_thread); + } + return 0; +} + + static void __exit voyager_thread_stop(void) { - /* FIXME: do nothing at the moment */ + kthread_stop(voyager_thread); } module_init(voyager_thread_start); -//module_exit(voyager_thread_stop); +module_exit(voyager_thread_stop); diff --git a/include/asm-i386/voyager.h b/include/asm-i386/voyager.h index 5b27838905b2..91a9932937ab 100644 --- a/include/asm-i386/voyager.h +++ b/include/asm-i386/voyager.h @@ -487,15 +487,11 @@ extern struct voyager_qic_cpi *voyager_quad_cpi_addr[NR_CPUS]; extern struct voyager_SUS *voyager_SUS; /* variables exported always */ +extern struct task_struct *voyager_thread; extern int voyager_level; -extern int kvoyagerd_running; -extern struct semaphore kvoyagerd_sem; extern struct voyager_status voyager_status; - - /* functions exported by the voyager and voyager_smp modules */ - extern int voyager_cat_readb(__u8 module, __u8 asic, int reg); extern void voyager_cat_init(void); extern void voyager_detect(struct voyager_bios_info *); -- cgit v1.2.3-59-g8ed1b From 9d0e59a34116f5ee48efc9a397fb09aaedc3b2f0 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Mon, 30 Apr 2007 09:57:40 -0600 Subject: [VOYAGER] Use modern techniques to setup and teardown low identiy mappings. This is a trivial and hopefully obviously correct patch to setup and teardown the identity mappings the way the rest of arch/i386 does. My new page table setup code will break some assumptions below so this is my attempt to keep voyager working. Signed-off-by: Eric W. Biederman Signed-off-by: James Bottomley --- arch/i386/mach-voyager/voyager_smp.c | 38 ++++++------------------------------ 1 file changed, 6 insertions(+), 32 deletions(-) (limited to 'arch') diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index a126baeaa423..535fb9e754fb 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c @@ -536,15 +536,6 @@ do_boot_cpu(__u8 cpu) & ~( voyager_extended_vic_processors & voyager_allowed_boot_processors); - /* For the 486, we can't use the 4Mb page table trick, so - * must map a region of memory */ -#ifdef CONFIG_M486 - int i; - unsigned long *page_table_copies = (unsigned long *) - __get_free_page(GFP_KERNEL); -#endif - pgd_t orig_swapper_pg_dir0; - /* This is an area in head.S which was used to set up the * initial kernel stack. We need to alter this to give the * booting CPU a new stack (taken from its idle process) */ @@ -595,24 +586,11 @@ do_boot_cpu(__u8 cpu) VDEBUG(("VOYAGER SMP: Booting CPU%d at 0x%lx[%x:%x], stack %p\n", cpu, (unsigned long)hijack_source.val, hijack_source.idt.Segment, hijack_source.idt.Offset, stack_start.esp)); - /* set the original swapper_pg_dir[0] to map 0 to 4Mb transparently - * (so that the booting CPU can find start_32 */ - orig_swapper_pg_dir0 = swapper_pg_dir[0]; -#ifdef CONFIG_M486 - if(page_table_copies == NULL) - panic("No free memory for 486 page tables\n"); - for(i = 0; i < PAGE_SIZE/sizeof(unsigned long); i++) - page_table_copies[i] = (i * PAGE_SIZE) - | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; - - ((unsigned long *)swapper_pg_dir)[0] = - ((virt_to_phys(page_table_copies)) & PAGE_MASK) - | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; -#else - ((unsigned long *)swapper_pg_dir)[0] = - (virt_to_phys(pg0) & PAGE_MASK) - | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; -#endif + + /* init lowmem identity mapping */ + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, + min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS)); + flush_tlb_all(); if(quad_boot) { printk("CPU %d: non extended Quad boot\n", cpu); @@ -655,11 +633,7 @@ do_boot_cpu(__u8 cpu) udelay(100); } /* reset the page table */ - swapper_pg_dir[0] = orig_swapper_pg_dir0; - local_flush_tlb(); -#ifdef CONFIG_M486 - free_page((unsigned long)page_table_copies); -#endif + zap_low_mappings(); if (cpu_booted_map) { VDEBUG(("CPU%d: Booted successfully, back in CPU %d\n", -- cgit v1.2.3-59-g8ed1b From d6444514b89098284099c17b9f168ef6236d3e8f Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 1 May 2007 10:13:46 -0500 Subject: [VOYAGER] add smp alternatives It's about time voyager had them Signed-off-by: James Bottomley --- arch/i386/mach-voyager/voyager_smp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index 535fb9e754fb..fe0ed393294c 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c @@ -564,6 +564,8 @@ do_boot_cpu(__u8 cpu) hijack_source.idt.Segment = (start_phys_address >> 4) & 0xFFFF; cpucount++; + alternatives_smp_switch(1); + idle = fork_idle(cpu); if(IS_ERR(idle)) panic("failed fork for CPU%d", cpu); -- cgit v1.2.3-59-g8ed1b From 7c59b6615fed9d3006b1e7b865fb07e483129611 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 1 May 2007 23:26:29 +0200 Subject: i2c: Cleanup the includes of Clean up the includes of . Only include this header file when we actually need it. Signed-off-by: Jean Delvare --- arch/powerpc/platforms/powermac/cpufreq_32.c | 1 - drivers/media/video/cx2341x.c | 1 - drivers/media/video/ovcamchip/ovcamchip_priv.h | 1 + drivers/media/video/usbvision/usbvision-cards.c | 1 - include/media/ovcamchip.h | 1 - include/media/tuner.h | 1 + sound/oss/dmasound/tas_ioctl.h | 1 - 7 files changed, 2 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c index 8943a9456bb7..1fe35dab0e9e 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_32.c +++ b/arch/powerpc/platforms/powermac/cpufreq_32.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c index 88dbdddeec42..d73c86aeeaac 100644 --- a/drivers/media/video/cx2341x.c +++ b/drivers/media/video/cx2341x.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/drivers/media/video/ovcamchip/ovcamchip_priv.h b/drivers/media/video/ovcamchip/ovcamchip_priv.h index 1231335a9f4a..50c7763d44b3 100644 --- a/drivers/media/video/ovcamchip/ovcamchip_priv.h +++ b/drivers/media/video/ovcamchip/ovcamchip_priv.h @@ -15,6 +15,7 @@ #ifndef __LINUX_OVCAMCHIP_PRIV_H #define __LINUX_OVCAMCHIP_PRIV_H +#include #include #ifdef DEBUG diff --git a/drivers/media/video/usbvision/usbvision-cards.c b/drivers/media/video/usbvision/usbvision-cards.c index 13f69fe6360d..51ab265d566a 100644 --- a/drivers/media/video/usbvision/usbvision-cards.c +++ b/drivers/media/video/usbvision/usbvision-cards.c @@ -24,7 +24,6 @@ #include -#include #include #include #include "usbvision.h" diff --git a/include/media/ovcamchip.h b/include/media/ovcamchip.h index 0f43451f8bb3..05b9569ef1c8 100644 --- a/include/media/ovcamchip.h +++ b/include/media/ovcamchip.h @@ -16,7 +16,6 @@ #include #include -#include /* --------------------------------- */ /* ENUMERATIONS */ diff --git a/include/media/tuner.h b/include/media/tuner.h index a41ac41113ac..6dcf3c45707d 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -23,6 +23,7 @@ #define _TUNER_H #include +#include #include extern int tuner_debug; diff --git a/sound/oss/dmasound/tas_ioctl.h b/sound/oss/dmasound/tas_ioctl.h index dccae3a40e01..9d12b373b4a9 100644 --- a/sound/oss/dmasound/tas_ioctl.h +++ b/sound/oss/dmasound/tas_ioctl.h @@ -1,7 +1,6 @@ #ifndef _TAS_IOCTL_H_ #define _TAS_IOCTL_H_ -#include #include -- cgit v1.2.3-59-g8ed1b From 2ca8c1a1269630473840835d1585adf2582b7c0b Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:04 +0200 Subject: [PATCH] x86-64: Update defconfig Signed-off-by: Andi Kleen --- arch/x86_64/defconfig | 183 ++++++++++++++------------------------------------ 1 file changed, 49 insertions(+), 134 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index b26378815b91..941a7e3aa5fb 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc3 -# Wed Mar 7 15:29:47 2007 +# Linux kernel version: 2.6.21-git3 +# Tue May 1 07:30:48 2007 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -118,11 +118,11 @@ CONFIG_X86_PC=y # CONFIG_X86_VSMP is not set # CONFIG_MK8 is not set # CONFIG_MPSC is not set -# CONFIG_MCORE2 is not set -CONFIG_GENERIC_CPU=y -CONFIG_X86_L1_CACHE_BYTES=128 -CONFIG_X86_L1_CACHE_SHIFT=7 -CONFIG_X86_INTERNODE_CACHE_BYTES=128 +CONFIG_MCORE2=y +# CONFIG_GENERIC_CPU is not set +CONFIG_X86_L1_CACHE_BYTES=64 +CONFIG_X86_L1_CACHE_SHIFT=6 +CONFIG_X86_INTERNODE_CACHE_BYTES=64 CONFIG_X86_TSC=y CONFIG_X86_GOOD_APIC=y # CONFIG_MICROCODE is not set @@ -174,6 +174,7 @@ CONFIG_X86_MCE_INTEL=y CONFIG_X86_MCE_AMD=y # CONFIG_KEXEC is not set # CONFIG_CRASH_DUMP is not set +# CONFIG_RELOCATABLE is not set CONFIG_PHYSICAL_START=0x200000 CONFIG_SECCOMP=y # CONFIG_CC_STACKPROTECTOR is not set @@ -182,7 +183,6 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 -# CONFIG_REORDER is not set CONFIG_K8_NB=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y @@ -218,7 +218,6 @@ CONFIG_ACPI_HOTPLUG_CPU=y CONFIG_ACPI_THERMAL=y CONFIG_ACPI_NUMA=y # CONFIG_ACPI_ASUS is not set -# CONFIG_ACPI_IBM is not set # CONFIG_ACPI_TOSHIBA is not set CONFIG_ACPI_BLACKLIST_YEAR=0 # CONFIG_ACPI_DEBUG is not set @@ -243,7 +242,7 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y # # CPUFreq processor drivers @@ -299,7 +298,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -334,6 +332,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set # CONFIG_INET6_AH is not set # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set @@ -389,6 +388,13 @@ CONFIG_IPV6_SIT=y # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set # CONFIG_IEEE80211 is not set # @@ -409,10 +415,6 @@ CONFIG_FW_LOADER=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -459,6 +461,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set # CONFIG_SONY_LAPTOP is not set +# CONFIG_THINKPAD_ACPI is not set # # ATA/ATAPI/MFM/RLL support @@ -494,7 +497,6 @@ CONFIG_BLK_DEV_IDEPCI=y # CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_IDEDMA_ONLYDISK is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set @@ -525,7 +527,6 @@ CONFIG_BLK_DEV_PDC202XX_NEW=y # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y # CONFIG_BLK_DEV_HD is not set # @@ -584,11 +585,9 @@ CONFIG_AIC79XX_DEBUG_MASK=0 # CONFIG_AIC79XX_REG_PRETTY_PRINT is not set # CONFIG_SCSI_AIC94XX is not set # CONFIG_SCSI_ARCMSR is not set -CONFIG_MEGARAID_NEWGEN=y -CONFIG_MEGARAID_MM=y -CONFIG_MEGARAID_MAILBOX=y +# CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set -CONFIG_MEGARAID_SAS=y +# CONFIG_MEGARAID_SAS is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set @@ -608,6 +607,7 @@ CONFIG_MEGARAID_SAS=y # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_ESP_CORE is not set # CONFIG_SCSI_SRP is not set # @@ -636,6 +636,7 @@ CONFIG_SATA_ACPI=y # CONFIG_PATA_AMD is not set # CONFIG_PATA_ARTOP is not set # CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set # CONFIG_PATA_CMD64X is not set # CONFIG_PATA_CS5520 is not set # CONFIG_PATA_CS5530 is not set @@ -687,7 +688,7 @@ CONFIG_BLK_DEV_DM=y CONFIG_FUSION=y CONFIG_FUSION_SPI=y # CONFIG_FUSION_FC is not set -CONFIG_FUSION_SAS=y +# CONFIG_FUSION_SAS is not set CONFIG_FUSION_MAX_SGE=128 # CONFIG_FUSION_CTL is not set @@ -700,19 +701,22 @@ CONFIG_IEEE1394=y # Subsystem Options # # CONFIG_IEEE1394_VERBOSEDEBUG is not set -# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set # -# Device Drivers +# Controllers +# + +# +# Texas Instruments PCILynx requires I2C # -# CONFIG_IEEE1394_PCILYNX is not set CONFIG_IEEE1394_OHCI1394=y # -# Protocol Drivers +# Protocols # # CONFIG_IEEE1394_VIDEO1394 is not set # CONFIG_IEEE1394_SBP2 is not set +# CONFIG_IEEE1394_ETH1394_ROM_ENTRY is not set # CONFIG_IEEE1394_ETH1394 is not set # CONFIG_IEEE1394_DV1394 is not set CONFIG_IEEE1394_RAWIO=y @@ -775,7 +779,8 @@ CONFIG_TULIP=y # CONFIG_HP100 is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set +CONFIG_AMD8111_ETH=y +# CONFIG_AMD8111E_NAPI is not set # CONFIG_ADAPTEC_STARFIRE is not set CONFIG_B44=y CONFIG_FORCEDETH=y @@ -837,9 +842,10 @@ CONFIG_S2IO=m # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) +# Wireless LAN # -# CONFIG_NET_RADIO is not set +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # # Wan interfaces @@ -853,7 +859,6 @@ CONFIG_S2IO=m # CONFIG_SHAPER is not set CONFIG_NETCONSOLE=y CONFIG_NETPOLL=y -# CONFIG_NETPOLL_RX is not set # CONFIG_NETPOLL_TRAP is not set CONFIG_NET_POLL_CONTROLLER=y @@ -987,57 +992,7 @@ CONFIG_HPET_MMAP=y # # I2C support # -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -CONFIG_I2C_ISA=m -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PASEMI is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C is not set # # SPI support @@ -1053,54 +1008,8 @@ CONFIG_I2C_ISA=m # # Hardware Monitoring support # -CONFIG_HWMON=y +# CONFIG_HWMON is not set # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_K8TEMP is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -CONFIG_SENSORS_SMSC47B397=m -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_SENSORS_HDAPS is not set -# CONFIG_HWMON_DEBUG_CHIP is not set # # Multifunction device drivers @@ -1147,8 +1056,9 @@ CONFIG_SOUND=y # Open Sound System # CONFIG_SOUND_PRIME=y -# CONFIG_OBSOLETE_OSS is not set +CONFIG_OBSOLETE_OSS=y # CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_ES1371 is not set CONFIG_SOUND_ICH=y # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set @@ -1162,6 +1072,14 @@ CONFIG_SOUND_ICH=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set + # # USB support # @@ -1175,6 +1093,7 @@ CONFIG_USB=y # Miscellaneous USB options # CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set @@ -1225,10 +1144,6 @@ CONFIG_USB_STORAGE=y # # USB Input Devices # -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set # CONFIG_USB_ACECAD is not set @@ -1556,7 +1471,7 @@ CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=18 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set +CONFIG_TIMER_STATS=y # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set -- cgit v1.2.3-59-g8ed1b From bdd0dc5210b5bb35dbddd5b0bc742e65a812a067 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:04 +0200 Subject: [PATCH] i386: Update defconfig Signed-off-by: Andi Kleen --- arch/i386/defconfig | 73 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/i386/defconfig b/arch/i386/defconfig index c96911c37aea..9da84412a831 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc3 -# Wed Mar 7 15:29:47 2007 +# Linux kernel version: 2.6.21-git3 +# Tue May 1 07:30:51 2007 # CONFIG_X86_32=y CONFIG_GENERIC_TIME=y @@ -108,9 +108,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # # Processor type and features # -# CONFIG_TICK_ONESHOT is not set -# CONFIG_NO_HZ is not set -# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_SMP=y # CONFIG_X86_PC is not set # CONFIG_X86_ELAN is not set @@ -146,9 +146,11 @@ CONFIG_MPENTIUMIII=y # CONFIG_MGEODE_LX is not set # CONFIG_MCYRIXIII is not set # CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set CONFIG_X86_GENERIC=y CONFIG_X86_CMPXCHG=y CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_XADD=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set @@ -162,6 +164,8 @@ CONFIG_X86_GOOD_APIC=y CONFIG_X86_INTEL_USERCOPY=y CONFIG_X86_USE_PPRO_CHECKSUM=y CONFIG_X86_TSC=y +CONFIG_X86_CMOV=y +CONFIG_X86_MINIMUM_CPU_MODEL=4 CONFIG_HPET_TIMER=y CONFIG_HPET_EMULATE_RTC=y CONFIG_NR_CPUS=32 @@ -248,7 +252,6 @@ CONFIG_ACPI_FAN=y CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_THERMAL=y # CONFIG_ACPI_ASUS is not set -# CONFIG_ACPI_IBM is not set # CONFIG_ACPI_TOSHIBA is not set CONFIG_ACPI_BLACKLIST_YEAR=2001 CONFIG_ACPI_DEBUG=y @@ -257,10 +260,7 @@ CONFIG_ACPI_POWER=y CONFIG_ACPI_SYSTEM=y CONFIG_X86_PM_TIMER=y # CONFIG_ACPI_CONTAINER is not set - -# -# APM (Advanced Power Management) BIOS Support -# +# CONFIG_ACPI_SBS is not set # CONFIG_APM is not set # @@ -277,7 +277,7 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y # # CPUFreq processor drivers @@ -349,7 +349,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -388,6 +387,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set # CONFIG_INET6_AH is not set # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set @@ -443,6 +443,13 @@ CONFIG_IPV6_SIT=y # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set # CONFIG_IEEE80211 is not set # @@ -463,10 +470,6 @@ CONFIG_FW_LOADER=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -513,6 +516,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set # CONFIG_SONY_LAPTOP is not set +# CONFIG_THINKPAD_ACPI is not set # # ATA/ATAPI/MFM/RLL support @@ -548,7 +552,6 @@ CONFIG_BLK_DEV_IDEPCI=y # CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_IDEDMA_ONLYDISK is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set @@ -580,7 +583,6 @@ CONFIG_BLK_DEV_PIIX=y # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y # CONFIG_BLK_DEV_HD is not set # @@ -669,6 +671,7 @@ CONFIG_AIC79XX_DEBUG_MASK=0 # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_ESP_CORE is not set # CONFIG_SCSI_SRP is not set # @@ -697,6 +700,7 @@ CONFIG_SATA_ACPI=y # CONFIG_PATA_AMD is not set # CONFIG_PATA_ARTOP is not set # CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set # CONFIG_PATA_CMD64X is not set # CONFIG_PATA_CS5520 is not set # CONFIG_PATA_CS5530 is not set @@ -762,10 +766,9 @@ CONFIG_IEEE1394=y # Subsystem Options # # CONFIG_IEEE1394_VERBOSEDEBUG is not set -# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set # -# Device Drivers +# Controllers # # @@ -774,10 +777,11 @@ CONFIG_IEEE1394=y CONFIG_IEEE1394_OHCI1394=y # -# Protocol Drivers +# Protocols # # CONFIG_IEEE1394_VIDEO1394 is not set # CONFIG_IEEE1394_SBP2 is not set +# CONFIG_IEEE1394_ETH1394_ROM_ENTRY is not set # CONFIG_IEEE1394_ETH1394 is not set # CONFIG_IEEE1394_DV1394 is not set CONFIG_IEEE1394_RAWIO=y @@ -820,7 +824,9 @@ CONFIG_MII=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set +CONFIG_NET_VENDOR_3COM=y +CONFIG_VORTEX=y +# CONFIG_TYPHOON is not set # # Tulip family network device support @@ -901,9 +907,10 @@ CONFIG_BNX2=y # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) +# Wireless LAN # -# CONFIG_NET_RADIO is not set +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # # Wan interfaces @@ -917,7 +924,6 @@ CONFIG_BNX2=y # CONFIG_SHAPER is not set CONFIG_NETCONSOLE=y CONFIG_NETPOLL=y -# CONFIG_NETPOLL_RX is not set # CONFIG_NETPOLL_TRAP is not set CONFIG_NET_POLL_CONTROLLER=y @@ -1050,7 +1056,7 @@ CONFIG_MAX_RAW_DEVS=256 CONFIG_HPET=y # CONFIG_HPET_RTC_IRQ is not set CONFIG_HPET_MMAP=y -CONFIG_HANGCHECK_TIMER=y +# CONFIG_HANGCHECK_TIMER is not set # # TPM devices @@ -1141,6 +1147,14 @@ CONFIG_SOUND_ICH=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set + # # USB support # @@ -1154,6 +1168,7 @@ CONFIG_USB=y # Miscellaneous USB options # CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set @@ -1204,10 +1219,6 @@ CONFIG_USB_STORAGE=y # # USB Input Devices # -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set # CONFIG_USB_ACECAD is not set @@ -1528,7 +1539,7 @@ CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=18 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set +CONFIG_TIMER_STATS=y # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set -- cgit v1.2.3-59-g8ed1b From fb27145d6ad2548d2d770f33ffa0a268c0afba85 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 2 May 2007 19:27:04 +0200 Subject: [PATCH] i386: revert i386-fix-the-verify_quirk_intel_irqbalance This is unneeded with Ingo's genapic rework. Cc: Suresh Siddha Cc: Andi Kleen Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/kernel/quirks.c | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/quirks.c b/arch/i386/kernel/quirks.c index 34874c398b44..a01320a7b636 100644 --- a/arch/i386/kernel/quirks.c +++ b/arch/i386/kernel/quirks.c @@ -10,38 +10,13 @@ #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI) static void __devinit verify_quirk_intel_irqbalance(struct pci_dev *dev) { - u8 config, rev; - u32 word; - - /* BIOS may enable hardware IRQ balancing for - * E7520/E7320/E7525(revision ID 0x9 and below) - * based platforms. - * For those platforms, make sure that the genapic is set to 'flat' - */ - pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev); - if (rev > 0x9) - return; - - /* enable access to config space*/ - pci_read_config_byte(dev, 0xf4, &config); - pci_write_config_byte(dev, 0xf4, config|0x2); - - /* read xTPR register */ - raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); - - if (!(word & (1 << 13))) { #ifdef CONFIG_X86_64 - if (genapic != &apic_flat) - panic("APIC mode must be flat on this system\n"); + if (genapic != &apic_flat) + panic("APIC mode must be flat on this system\n"); #elif defined(CONFIG_X86_GENERICARCH) - if (genapic != &apic_default) - panic("APIC mode must be default(flat) on this system. Use apic=default\n"); + if (genapic != &apic_default) + panic("APIC mode must be default(flat) on this system. Use apic=default\n"); #endif - } - - /* put back the original value for config space*/ - if (!(config & 0x2)) - pci_write_config_byte(dev, 0xf4, config); } void __init quirk_intel_irqbalance(void) -- cgit v1.2.3-59-g8ed1b From 3dc68d9b58ae644cee8e218e3dcde0dceb5c47a3 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 2 May 2007 19:27:04 +0200 Subject: [PATCH] x86-64: revert x86_64-mm-add-genapic_force This is obsoleted by new Ingo genapic patches. Cc: Suresh Siddha Cc: Andi Kleen Cc: "Li, Shaohua" Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/x86_64/kernel/genapic.c | 9 +-------- include/asm-x86_64/genapic.h | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/genapic.c b/arch/x86_64/kernel/genapic.c index 0b3603adf56d..7312ddb84fb4 100644 --- a/arch/x86_64/kernel/genapic.c +++ b/arch/x86_64/kernel/genapic.c @@ -33,7 +33,7 @@ extern struct genapic apic_flat; extern struct genapic apic_physflat; struct genapic *genapic = &apic_flat; -struct genapic *genapic_force; + /* * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. @@ -46,13 +46,6 @@ void __init clustered_apic_check(void) u8 cluster_cnt[NUM_APIC_CLUSTERS]; int max_apic = 0; - /* genapic selection can be forced because of certain quirks. - */ - if (genapic_force) { - genapic = genapic_force; - goto print; - } - #if defined(CONFIG_ACPI) /* * Some x86_64 machines use physical APIC mode regardless of how many diff --git a/include/asm-x86_64/genapic.h b/include/asm-x86_64/genapic.h index b80f4bb5f273..a0e9a4b93484 100644 --- a/include/asm-x86_64/genapic.h +++ b/include/asm-x86_64/genapic.h @@ -30,6 +30,6 @@ struct genapic { }; -extern struct genapic *genapic, *genapic_force, apic_flat; +extern struct genapic *genapic; #endif -- cgit v1.2.3-59-g8ed1b From a86f34b49f32b238d16b2e3bf6c9a5391a3f683f Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 2 May 2007 19:27:04 +0200 Subject: [PATCH] x86: revert x86_64-mm-fix-the-irqbalance-quirk-for-e7320-e7520-e7525 Obsoleted by Ingo's genapic stuff. Cc: Ingo Molnar Cc: Suresh Siddha Cc: Andi Kleen Cc: "Li, Shaohua" Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/kernel/acpi/earlyquirk.c | 21 ----------------- arch/i386/kernel/quirks.c | 46 +++++++++----------------------------- arch/i386/kernel/smpboot.c | 6 ----- arch/x86_64/kernel/early-quirks.c | 13 ----------- arch/x86_64/kernel/smpboot.c | 8 ------- include/asm-i386/genapic.h | 2 +- include/asm-i386/irq.h | 2 -- include/asm-x86_64/proto.h | 1 - 8 files changed, 12 insertions(+), 87 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index 8f7efd38254d..23f78efc577d 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c @@ -10,7 +10,6 @@ #include #include #include -#include #ifdef CONFIG_ACPI @@ -48,24 +47,6 @@ static int __init check_bridge(int vendor, int device) return 0; } -static void check_intel(void) -{ - u16 vendor, device; - - vendor = read_pci_config_16(0, 0, 0, PCI_VENDOR_ID); - - if (vendor != PCI_VENDOR_ID_INTEL) - return; - - device = read_pci_config_16(0, 0, 0, PCI_DEVICE_ID); -#ifdef CONFIG_SMP - if (device == PCI_DEVICE_ID_INTEL_E7320_MCH || - device == PCI_DEVICE_ID_INTEL_E7520_MCH || - device == PCI_DEVICE_ID_INTEL_E7525_MCH) - quirk_intel_irqbalance(); -#endif -} - void __init check_acpi_pci(void) { int num, slot, func; @@ -77,8 +58,6 @@ void __init check_acpi_pci(void) if (!early_pci_allowed()) return; - check_intel(); - /* Poor man's PCI discovery */ for (num = 0; num < 32; num++) { for (slot = 0; slot < 32; slot++) { diff --git a/arch/i386/kernel/quirks.c b/arch/i386/kernel/quirks.c index a01320a7b636..9f6ab1789bb0 100644 --- a/arch/i386/kernel/quirks.c +++ b/arch/i386/kernel/quirks.c @@ -3,23 +3,10 @@ */ #include #include -#include -#include -#include #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI) -static void __devinit verify_quirk_intel_irqbalance(struct pci_dev *dev) -{ -#ifdef CONFIG_X86_64 - if (genapic != &apic_flat) - panic("APIC mode must be flat on this system\n"); -#elif defined(CONFIG_X86_GENERICARCH) - if (genapic != &apic_default) - panic("APIC mode must be default(flat) on this system. Use apic=default\n"); -#endif -} -void __init quirk_intel_irqbalance(void) +static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) { u8 config, rev; u32 word; @@ -29,18 +16,18 @@ void __init quirk_intel_irqbalance(void) * based platforms. * Disable SW irqbalance/affinity on those platforms. */ - rev = read_pci_config_byte(0, 0, 0, PCI_CLASS_REVISION); + pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev); if (rev > 0x9) return; printk(KERN_INFO "Intel E7520/7320/7525 detected."); - /* enable access to config space */ - config = read_pci_config_byte(0, 0, 0, 0xf4); - write_pci_config_byte(0, 0, 0, 0xf4, config|0x2); + /* enable access to config space*/ + pci_read_config_byte(dev, 0xf4, &config); + pci_write_config_byte(dev, 0xf4, config|0x2); /* read xTPR register */ - word = read_pci_config_16(0, 0, 0x40, 0x4c); + raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); if (!(word & (1 << 13))) { printk(KERN_INFO "Disabling irq balancing and affinity\n"); @@ -50,25 +37,14 @@ void __init quirk_intel_irqbalance(void) noirqdebug_setup(""); #ifdef CONFIG_PROC_FS no_irq_affinity = 1; -#endif -#ifdef CONFIG_HOTPLUG_CPU - printk(KERN_INFO "Disabling cpu hotplug control\n"); - enable_cpu_hotplug = 0; -#endif -#ifdef CONFIG_X86_64 - /* force the genapic selection to flat mode so that - * interrupts can be redirected to more than one CPU. - */ - genapic_force = &apic_flat; #endif } - /* put back the original value for config space */ + /* put back the original value for config space*/ if (!(config & 0x2)) - write_pci_config_byte(0, 0, 0, 0xf4, config); + pci_write_config_byte(dev, 0xf4, config); } -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, verify_quirk_intel_irqbalance); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, verify_quirk_intel_irqbalance); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, verify_quirk_intel_irqbalance); - +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance); #endif diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 4ff55e675576..7b14e88b555f 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -54,7 +54,6 @@ #include #include #include -#include #include #include @@ -1319,11 +1318,6 @@ int __cpuinit __cpu_up(unsigned int cpu) touch_nmi_watchdog(); } -#ifdef CONFIG_X86_GENERICARCH - if (num_online_cpus() > 8 && genapic == &apic_default) - panic("Default flat APIC routing can't be used with > 8 cpus\n"); -#endif - return 0; } diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c index fede55a53995..990d9c218a5d 100644 --- a/arch/x86_64/kernel/early-quirks.c +++ b/arch/x86_64/kernel/early-quirks.c @@ -71,18 +71,6 @@ static void __init ati_bugs(void) } } -static void intel_bugs(void) -{ - u16 device = read_pci_config_16(0, 0, 0, PCI_DEVICE_ID); - -#ifdef CONFIG_SMP - if (device == PCI_DEVICE_ID_INTEL_E7320_MCH || - device == PCI_DEVICE_ID_INTEL_E7520_MCH || - device == PCI_DEVICE_ID_INTEL_E7525_MCH) - quirk_intel_irqbalance(); -#endif -} - struct chipset { u16 vendor; void (*f)(void); @@ -92,7 +80,6 @@ static struct chipset early_qrk[] __initdata = { { PCI_VENDOR_ID_NVIDIA, nvidia_bugs }, { PCI_VENDOR_ID_VIA, via_bugs }, { PCI_VENDOR_ID_ATI, ati_bugs }, - { PCI_VENDOR_ID_INTEL, intel_bugs}, {} }; diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index cd4643a37022..14724be48bec 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -60,7 +60,6 @@ #include #include #include -#include /* Number of siblings per CPU package */ int smp_num_siblings = 1; @@ -965,13 +964,6 @@ int __cpuinit __cpu_up(unsigned int cpu) while (!cpu_isset(cpu, cpu_online_map)) cpu_relax(); - - if (num_online_cpus() > 8 && genapic == &apic_flat) { - printk(KERN_WARNING - "flat APIC routing can't be used with > 8 cpus\n"); - BUG(); - } - err = 0; return err; diff --git a/include/asm-i386/genapic.h b/include/asm-i386/genapic.h index fd2be593b06e..8ffbb0f07457 100644 --- a/include/asm-i386/genapic.h +++ b/include/asm-i386/genapic.h @@ -122,6 +122,6 @@ struct genapic { APICFUNC(phys_pkg_id) \ } -extern struct genapic *genapic, apic_default; +extern struct genapic *genapic; #endif diff --git a/include/asm-i386/irq.h b/include/asm-i386/irq.h index 11761cdaae19..9e15ce0006eb 100644 --- a/include/asm-i386/irq.h +++ b/include/asm-i386/irq.h @@ -37,8 +37,6 @@ static __inline__ int irq_canonicalize(int irq) extern int irqbalance_disable(char *str); #endif -extern void quirk_intel_irqbalance(void); - #ifdef CONFIG_HOTPLUG_CPU extern void fixup_irqs(cpumask_t map); #endif diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index b6e65a699f2a..6688cf9eb27b 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h @@ -82,7 +82,6 @@ extern void syscall32_cpu_init(void); extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long end); extern void early_quirks(void); -extern void quirk_intel_irqbalance(void); extern void check_efer(void); extern int unhandled_signal(struct task_struct *tsk, int sig); -- cgit v1.2.3-59-g8ed1b From f18d397e6aa5cde638d164b1d519c3ee903f4867 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 2 May 2007 19:27:04 +0200 Subject: [PATCH] x86-64: optimize & fix APIC mode setup Fix a couple of inconsistencies/problems I found while reviewing the x86_64 genapic code (when I was chasing mysterious eth0 timeouts that would only trigger if CPU_HOTPLUG is enabled): - AMD systems defaulted to the slower flat-physical mode instead of the flat-logical mode. The only restriction on AMD systems is that they should not use clustered APIC mode. - removed the CPU hotplug hacks, switching the default for small systems back from phys-flat to logical-flat. The switching to logical flat mode on small systems fixed sporadic ethernet driver timeouts i was getting on a dual-core Athlon64 system: NETDEV WATCHDOG: eth0: transmit timed out eth0: Transmit timeout, status 0c 0005 c07f media 80. eth0: Tx queue start entry 32 dirty entry 28. eth0: Tx descriptor 0 is 0008a04a. (queue head) eth0: Tx descriptor 1 is 0008a04a. eth0: Tx descriptor 2 is 0008a04a. eth0: Tx descriptor 3 is 0008a04a. eth0: link up, 100Mbps, full-duplex, lpa 0xC5E1 - The use of '<= 8' was a bug by itself (the valid APIC ids for logical flat mode go from 0 to 7, not 0 to 8). The new logic is to use logical flat mode on both AMD and Intel systems, and to only switch to physical mode when logical mode cannot be used. If CPU hotplug is racy wrt. APIC shutdown then CPU hotplug needs fixing, not the whole IRQ system be made inconsistent and slowed down. - minor cleanups: simplified some code constructs build & booted on a couple of AMD and Intel SMP systems. Signed-off-by: Ingo Molnar Signed-off-by: Andi Kleen Cc: Suresh Siddha Cc: Andi Kleen Cc: "Li, Shaohua" Cc: "Eric W. Biederman" Signed-off-by: Andrew Morton --- arch/x86_64/kernel/genapic.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/genapic.c b/arch/x86_64/kernel/genapic.c index 7312ddb84fb4..2f2b8fc6e2f3 100644 --- a/arch/x86_64/kernel/genapic.c +++ b/arch/x86_64/kernel/genapic.c @@ -32,21 +32,20 @@ extern struct genapic apic_cluster; extern struct genapic apic_flat; extern struct genapic apic_physflat; -struct genapic *genapic = &apic_flat; - +struct genapic __read_mostly *genapic = &apic_flat; /* * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. */ void __init clustered_apic_check(void) { - long i; + int i; u8 clusters, max_cluster; u8 id; u8 cluster_cnt[NUM_APIC_CLUSTERS]; int max_apic = 0; -#if defined(CONFIG_ACPI) +#ifdef CONFIG_ACPI /* * Some x86_64 machines use physical APIC mode regardless of how many * procs/clusters are present (x86_64 ES7000 is an example). @@ -68,20 +67,17 @@ void __init clustered_apic_check(void) cluster_cnt[APIC_CLUSTERID(id)]++; } - /* Don't use clustered mode on AMD platforms. */ + /* + * Don't use clustered mode on AMD platforms, default + * to flat logical mode. + */ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { - genapic = &apic_physflat; -#ifndef CONFIG_HOTPLUG_CPU - /* In the CPU hotplug case we cannot use broadcast mode - because that opens a race when a CPU is removed. - Stay at physflat mode in this case. - It is bad to do this unconditionally though. Once - we have ACPI platform support for CPU hotplug - we should detect hotplug capablity from ACPI tables and - only do this when really needed. -AK */ - if (max_apic <= 8) - genapic = &apic_flat; -#endif + /* + * Switch to physical flat mode if more than 8 APICs + * (In the case of 8 CPUs APIC ID goes from 0 to 7): + */ + if (max_apic >= 8) + genapic = &apic_physflat; goto print; } @@ -103,14 +99,9 @@ void __init clustered_apic_check(void) * (We don't use lowest priority delivery + HW APIC IRQ steering, so * can ignore the clustered logical case and go straight to physical.) */ - if (clusters <= 1 && max_cluster <= 8 && cluster_cnt[0] == max_cluster) { -#ifdef CONFIG_HOTPLUG_CPU - /* Don't use APIC shortcuts in CPU hotplug to avoid races */ - genapic = &apic_physflat; -#else + if (clusters <= 1 && max_cluster <= 8 && cluster_cnt[0] == max_cluster) genapic = &apic_flat; -#endif - } else + else genapic = &apic_cluster; print: -- cgit v1.2.3-59-g8ed1b From 07c7c4744400f93a7c52b32159c31d823e1747a5 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 2 May 2007 19:27:04 +0200 Subject: [PATCH] x86-64: always use physical delivery mode on > 8 CPUs Remove clustered APIC mode. There's little point in the use of clustered APIC mode, broadcasting is limited to within the cluster only, and chipsets have bugs in this area as well. So default to physical APIC mode when the CPU count is large, and default to logical APIC mode when the CPU count is 8 or smaller. (this patch only removes the use of genapic_cluster and cleans up the resulting genapic.c file - removal of all remaining traces of clustered mode will be done by another patch.) Signed-off-by: Ingo Molnar Signed-off-by: Andi Kleen Cc: Suresh Siddha Cc: Andi Kleen Cc: "Li, Shaohua" Cc: "Eric W. Biederman" Signed-off-by: Andrew Morton --- arch/x86_64/kernel/genapic.c | 71 ++++++++++---------------------------------- include/asm-x86_64/genapic.h | 4 ++- 2 files changed, 18 insertions(+), 57 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/genapic.c b/arch/x86_64/kernel/genapic.c index 2f2b8fc6e2f3..025f26ebb8d7 100644 --- a/arch/x86_64/kernel/genapic.c +++ b/arch/x86_64/kernel/genapic.c @@ -11,26 +11,24 @@ #include #include #include +#include #include #include #include -#include #include #include -#if defined(CONFIG_ACPI) +#ifdef CONFIG_ACPI #include #endif /* which logical CPU number maps to which CPU (physical APIC ID) */ -u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; +u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly + = { [0 ... NR_CPUS-1] = BAD_APICID }; EXPORT_SYMBOL(x86_cpu_to_apicid); -u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; -extern struct genapic apic_cluster; -extern struct genapic apic_flat; -extern struct genapic apic_physflat; +u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; struct genapic __read_mostly *genapic = &apic_flat; @@ -39,76 +37,37 @@ struct genapic __read_mostly *genapic = &apic_flat; */ void __init clustered_apic_check(void) { - int i; - u8 clusters, max_cluster; + unsigned int i, max_apic = 0; u8 id; - u8 cluster_cnt[NUM_APIC_CLUSTERS]; - int max_apic = 0; #ifdef CONFIG_ACPI /* - * Some x86_64 machines use physical APIC mode regardless of how many - * procs/clusters are present (x86_64 ES7000 is an example). + * Quirk: some x86_64 machines can only use physical APIC mode + * regardless of how many processors are present (x86_64 ES7000 + * is an example). */ - if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID) - if (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL) { - genapic = &apic_cluster; - goto print; - } + if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID && + (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) + genapic = &apic_physflat; #endif - memset(cluster_cnt, 0, sizeof(cluster_cnt)); for (i = 0; i < NR_CPUS; i++) { id = bios_cpu_apicid[i]; if (id == BAD_APICID) continue; if (id > max_apic) max_apic = id; - cluster_cnt[APIC_CLUSTERID(id)]++; } - /* - * Don't use clustered mode on AMD platforms, default - * to flat logical mode. - */ - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { - /* - * Switch to physical flat mode if more than 8 APICs - * (In the case of 8 CPUs APIC ID goes from 0 to 7): - */ - if (max_apic >= 8) - genapic = &apic_physflat; - goto print; - } - - clusters = 0; - max_cluster = 0; - - for (i = 0; i < NUM_APIC_CLUSTERS; i++) { - if (cluster_cnt[i] > 0) { - ++clusters; - if (cluster_cnt[i] > max_cluster) - max_cluster = cluster_cnt[i]; - } - } - - /* - * If we have clusters <= 1 and CPUs <= 8 in cluster 0, then flat mode, - * else if max_cluster <= 4 and cluster_cnt[15] == 0, clustered logical - * else physical mode. - * (We don't use lowest priority delivery + HW APIC IRQ steering, so - * can ignore the clustered logical case and go straight to physical.) - */ - if (clusters <= 1 && max_cluster <= 8 && cluster_cnt[0] == max_cluster) + if (max_apic < 8) genapic = &apic_flat; else - genapic = &apic_cluster; + genapic = &apic_physflat; -print: printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name); } -/* Same for both flat and clustered. */ +/* Same for both flat and physical. */ void send_IPI_self(int vector) { diff --git a/include/asm-x86_64/genapic.h b/include/asm-x86_64/genapic.h index a0e9a4b93484..d7e516ccbaa4 100644 --- a/include/asm-x86_64/genapic.h +++ b/include/asm-x86_64/genapic.h @@ -29,7 +29,9 @@ struct genapic { unsigned int (*phys_pkg_id)(int index_msb); }; - extern struct genapic *genapic; +extern struct genapic apic_flat; +extern struct genapic apic_physflat; + #endif -- cgit v1.2.3-59-g8ed1b From 424df390101f9dfe015f0633aaec696c159b37a8 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 2 May 2007 19:27:04 +0200 Subject: [PATCH] x86-64: remove clustered APIC mode Remove now unused clustered APIC mode code. Signed-off-by: Ingo Molnar Signed-off-by: Andi Kleen Cc: Suresh Siddha Cc: Andi Kleen Cc: "Li, Shaohua" Cc: "Eric W. Biederman" Signed-off-by: Andrew Morton --- arch/x86_64/kernel/Makefile | 3 +- arch/x86_64/kernel/genapic_cluster.c | 137 ----------------------------------- 2 files changed, 1 insertion(+), 139 deletions(-) delete mode 100644 arch/x86_64/kernel/genapic_cluster.c (limited to 'arch') diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index bb47e86f3d02..6879b4f01e88 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile @@ -21,8 +21,7 @@ obj-$(CONFIG_MICROCODE) += microcode.o obj-$(CONFIG_X86_CPUID) += cpuid.o obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o tsc_sync.o obj-y += apic.o nmi.o -obj-y += io_apic.o mpparse.o \ - genapic.o genapic_cluster.o genapic_flat.o +obj-y += io_apic.o mpparse.o genapic.o genapic_flat.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_PM) += suspend.o diff --git a/arch/x86_64/kernel/genapic_cluster.c b/arch/x86_64/kernel/genapic_cluster.c deleted file mode 100644 index 73d76308b955..000000000000 --- a/arch/x86_64/kernel/genapic_cluster.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2004 James Cleverdon, IBM. - * Subject to the GNU Public License, v.2 - * - * Clustered APIC subarch code. Up to 255 CPUs, physical delivery. - * (A more realistic maximum is around 230 CPUs.) - * - * Hacked for x86-64 by James Cleverdon from i386 architecture code by - * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and - * James Cleverdon. - */ -#include -#include -#include -#include -#include -#include -#include -#include - - -/* - * Set up the logical destination ID. - * - * Intel recommends to set DFR, LDR and TPR before enabling - * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel - * document number 292116). So here it goes... - */ -static void cluster_init_apic_ldr(void) -{ - unsigned long val, id; - long i, count; - u8 lid; - u8 my_id = hard_smp_processor_id(); - u8 my_cluster = APIC_CLUSTER(my_id); - - /* Create logical APIC IDs by counting CPUs already in cluster. */ - for (count = 0, i = NR_CPUS; --i >= 0; ) { - lid = x86_cpu_to_log_apicid[i]; - if (lid != BAD_APICID && APIC_CLUSTER(lid) == my_cluster) - ++count; - } - /* - * We only have a 4 wide bitmap in cluster mode. There's no way - * to get above 60 CPUs and still give each one it's own bit. - * But, we're using physical IRQ delivery, so we don't care. - * Use bit 3 for the 4th through Nth CPU in each cluster. - */ - if (count >= XAPIC_DEST_CPUS_SHIFT) - count = 3; - id = my_cluster | (1UL << count); - x86_cpu_to_log_apicid[smp_processor_id()] = id; - apic_write(APIC_DFR, APIC_DFR_CLUSTER); - val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; - val |= SET_APIC_LOGICAL_ID(id); - apic_write(APIC_LDR, val); -} - -/* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ - -static cpumask_t cluster_target_cpus(void) -{ - return cpumask_of_cpu(0); -} - -static cpumask_t cluster_vector_allocation_domain(int cpu) -{ - cpumask_t domain = CPU_MASK_NONE; - cpu_set(cpu, domain); - return domain; -} - -static void cluster_send_IPI_mask(cpumask_t mask, int vector) -{ - send_IPI_mask_sequence(mask, vector); -} - -static void cluster_send_IPI_allbutself(int vector) -{ - cpumask_t mask = cpu_online_map; - - cpu_clear(smp_processor_id(), mask); - - if (!cpus_empty(mask)) - cluster_send_IPI_mask(mask, vector); -} - -static void cluster_send_IPI_all(int vector) -{ - cluster_send_IPI_mask(cpu_online_map, vector); -} - -static int cluster_apic_id_registered(void) -{ - return 1; -} - -static unsigned int cluster_cpu_mask_to_apicid(cpumask_t cpumask) -{ - int cpu; - - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - cpu = first_cpu(cpumask); - if ((unsigned)cpu < NR_CPUS) - return x86_cpu_to_apicid[cpu]; - else - return BAD_APICID; -} - -/* cpuid returns the value latched in the HW at reset, not the APIC ID - * register's value. For any box whose BIOS changes APIC IDs, like - * clustered APIC systems, we must use hard_smp_processor_id. - * - * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID. - */ -static unsigned int phys_pkg_id(int index_msb) -{ - return hard_smp_processor_id() >> index_msb; -} - -struct genapic apic_cluster = { - .name = "clustered", - .int_delivery_mode = dest_Fixed, - .int_dest_mode = (APIC_DEST_PHYSICAL != 0), - .target_cpus = cluster_target_cpus, - .vector_allocation_domain = cluster_vector_allocation_domain, - .apic_id_registered = cluster_apic_id_registered, - .init_apic_ldr = cluster_init_apic_ldr, - .send_IPI_all = cluster_send_IPI_all, - .send_IPI_allbutself = cluster_send_IPI_allbutself, - .send_IPI_mask = cluster_send_IPI_mask, - .cpu_mask_to_apicid = cluster_cpu_mask_to_apicid, - .phys_pkg_id = phys_pkg_id, -}; -- cgit v1.2.3-59-g8ed1b From 3c43f03908de98fa8f7a9e8fc9411ebf4c2de298 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 2 May 2007 19:27:04 +0200 Subject: [PATCH] x86: default to physical mode on hotplug CPU kernels Default to physical mode on hotplug CPU kernels. Furher simplify and clean up the APIC initialization code. Signed-off-by: Ingo Molnar Signed-off-by: Andi Kleen Cc: Suresh Siddha Cc: Andi Kleen Cc: "Li, Shaohua" Cc: "Eric W. Biederman" Signed-off-by: Andrew Morton --- arch/i386/kernel/acpi/boot.c | 2 +- arch/i386/kernel/mpparse.c | 2 +- arch/x86_64/kernel/genapic.c | 16 +++------------- arch/x86_64/kernel/mpparse.c | 2 +- include/asm-i386/genapic.h | 4 ++-- include/asm-i386/mach-bigsmp/mach_apic.h | 2 +- include/asm-i386/mach-default/mach_apic.h | 2 +- include/asm-i386/mach-es7000/mach_apic.h | 2 +- include/asm-i386/mach-generic/mach_apic.h | 2 +- include/asm-i386/mach-numaq/mach_apic.h | 2 +- include/asm-i386/mach-summit/mach_apic.h | 2 +- include/asm-i386/mach-visws/mach_apic.h | 2 +- include/asm-x86_64/apic.h | 2 +- 13 files changed, 16 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 9ea5b8ecc7e1..280898b045b2 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -874,7 +874,7 @@ static void __init acpi_process_madt(void) acpi_ioapic = 1; smp_found_config = 1; - clustered_apic_check(); + setup_apic_routing(); } } if (error == -EINVAL) { diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index 4f5983c98669..0952eccd8f28 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c @@ -477,7 +477,7 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) } ++mpc_record; } - clustered_apic_check(); + setup_apic_routing(); if (!num_processors) printk(KERN_ERR "SMP mptable: no processors registered!\n"); return num_processors; diff --git a/arch/x86_64/kernel/genapic.c b/arch/x86_64/kernel/genapic.c index 025f26ebb8d7..c08650a427e2 100644 --- a/arch/x86_64/kernel/genapic.c +++ b/arch/x86_64/kernel/genapic.c @@ -35,11 +35,8 @@ struct genapic __read_mostly *genapic = &apic_flat; /* * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. */ -void __init clustered_apic_check(void) +void __init setup_apic_routing(void) { - unsigned int i, max_apic = 0; - u8 id; - #ifdef CONFIG_ACPI /* * Quirk: some x86_64 machines can only use physical APIC mode @@ -49,17 +46,10 @@ void __init clustered_apic_check(void) if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID && (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) genapic = &apic_physflat; + else #endif - for (i = 0; i < NR_CPUS; i++) { - id = bios_cpu_apicid[i]; - if (id == BAD_APICID) - continue; - if (id > max_apic) - max_apic = id; - } - - if (max_apic < 8) + if (cpus_weight(cpu_possible_map) <= 8) genapic = &apic_flat; else genapic = &apic_physflat; diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c index 455aa0b932f0..d0dc4891599b 100644 --- a/arch/x86_64/kernel/mpparse.c +++ b/arch/x86_64/kernel/mpparse.c @@ -300,7 +300,7 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) } } } - clustered_apic_check(); + setup_apic_routing(); if (!num_processors) printk(KERN_ERR "MPTABLE: no processors registered!\n"); return num_processors; diff --git a/include/asm-i386/genapic.h b/include/asm-i386/genapic.h index 8ffbb0f07457..33e3ffe1766c 100644 --- a/include/asm-i386/genapic.h +++ b/include/asm-i386/genapic.h @@ -36,7 +36,7 @@ struct genapic { void (*init_apic_ldr)(void); physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map); - void (*clustered_apic_check)(void); + void (*setup_apic_routing)(void); int (*multi_timer_check)(int apic, int irq); int (*apicid_to_node)(int logical_apicid); int (*cpu_to_logical_apicid)(int cpu); @@ -99,7 +99,7 @@ struct genapic { APICFUNC(check_apicid_present) \ APICFUNC(init_apic_ldr) \ APICFUNC(ioapic_phys_id_map) \ - APICFUNC(clustered_apic_check) \ + APICFUNC(setup_apic_routing) \ APICFUNC(multi_timer_check) \ APICFUNC(apicid_to_node) \ APICFUNC(cpu_to_logical_apicid) \ diff --git a/include/asm-i386/mach-bigsmp/mach_apic.h b/include/asm-i386/mach-bigsmp/mach_apic.h index 18b19a773440..ebd319f838ab 100644 --- a/include/asm-i386/mach-bigsmp/mach_apic.h +++ b/include/asm-i386/mach-bigsmp/mach_apic.h @@ -71,7 +71,7 @@ static inline void init_apic_ldr(void) apic_write_around(APIC_LDR, val); } -static inline void clustered_apic_check(void) +static inline void setup_apic_routing(void) { printk("Enabling APIC mode: %s. Using %d I/O APICs\n", "Physflat", nr_ioapics); diff --git a/include/asm-i386/mach-default/mach_apic.h b/include/asm-i386/mach-default/mach_apic.h index 3ef6292db780..6db1c3babe9a 100644 --- a/include/asm-i386/mach-default/mach_apic.h +++ b/include/asm-i386/mach-default/mach_apic.h @@ -54,7 +54,7 @@ static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map) return phys_map; } -static inline void clustered_apic_check(void) +static inline void setup_apic_routing(void) { printk("Enabling APIC mode: %s. Using %d I/O APICs\n", "Flat", nr_ioapics); diff --git a/include/asm-i386/mach-es7000/mach_apic.h b/include/asm-i386/mach-es7000/mach_apic.h index 26333685a7fb..8e8b3949173a 100644 --- a/include/asm-i386/mach-es7000/mach_apic.h +++ b/include/asm-i386/mach-es7000/mach_apic.h @@ -81,7 +81,7 @@ static inline void enable_apic_mode(void) } extern int apic_version [MAX_APICS]; -static inline void clustered_apic_check(void) +static inline void setup_apic_routing(void) { int apic = bios_cpu_apicid[smp_processor_id()]; printk("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", diff --git a/include/asm-i386/mach-generic/mach_apic.h b/include/asm-i386/mach-generic/mach_apic.h index d9dc039da94a..a236e7021528 100644 --- a/include/asm-i386/mach-generic/mach_apic.h +++ b/include/asm-i386/mach-generic/mach_apic.h @@ -13,7 +13,7 @@ #define apic_id_registered (genapic->apic_id_registered) #define init_apic_ldr (genapic->init_apic_ldr) #define ioapic_phys_id_map (genapic->ioapic_phys_id_map) -#define clustered_apic_check (genapic->clustered_apic_check) +#define setup_apic_routing (genapic->setup_apic_routing) #define multi_timer_check (genapic->multi_timer_check) #define apicid_to_node (genapic->apicid_to_node) #define cpu_to_logical_apicid (genapic->cpu_to_logical_apicid) diff --git a/include/asm-i386/mach-numaq/mach_apic.h b/include/asm-i386/mach-numaq/mach_apic.h index 9d158095da82..5e5e7dd2692e 100644 --- a/include/asm-i386/mach-numaq/mach_apic.h +++ b/include/asm-i386/mach-numaq/mach_apic.h @@ -34,7 +34,7 @@ static inline void init_apic_ldr(void) /* Already done in NUMA-Q firmware */ } -static inline void clustered_apic_check(void) +static inline void setup_apic_routing(void) { printk("Enabling APIC mode: %s. Using %d I/O APICs\n", "NUMA-Q", nr_ioapics); diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h index 43e5bd8f4a19..732f776aab8e 100644 --- a/include/asm-i386/mach-summit/mach_apic.h +++ b/include/asm-i386/mach-summit/mach_apic.h @@ -80,7 +80,7 @@ static inline int apic_id_registered(void) return 1; } -static inline void clustered_apic_check(void) +static inline void setup_apic_routing(void) { printk("Enabling APIC mode: Summit. Using %d I/O APICs\n", nr_ioapics); diff --git a/include/asm-i386/mach-visws/mach_apic.h b/include/asm-i386/mach-visws/mach_apic.h index 18afe6b6fc4d..efac6f0d139f 100644 --- a/include/asm-i386/mach-visws/mach_apic.h +++ b/include/asm-i386/mach-visws/mach_apic.h @@ -47,7 +47,7 @@ static inline void summit_check(char *oem, char *productid) { } -static inline void clustered_apic_check(void) +static inline void setup_apic_routing(void) { } diff --git a/include/asm-x86_64/apic.h b/include/asm-x86_64/apic.h index 7cfb39cbd918..2f3b013595ab 100644 --- a/include/asm-x86_64/apic.h +++ b/include/asm-x86_64/apic.h @@ -83,7 +83,7 @@ extern void setup_secondary_APIC_clock (void); extern int APIC_init_uniprocessor (void); extern void disable_APIC_timer(void); extern void enable_APIC_timer(void); -extern void clustered_apic_check(void); +extern void setup_apic_routing(void); extern void setup_APIC_extened_lvt(unsigned char lvt_off, unsigned char vector, unsigned char msg_type, unsigned char mask); -- cgit v1.2.3-59-g8ed1b From 28609f6e4921ebb75ceaf5317454b8047b07cef4 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 2 May 2007 19:27:04 +0200 Subject: [PATCH] i386: adjustments to page table dump during oops (v4) - make the page table contents printing PAE capable - make sure the address stored in current->thread.cr2 is unmodified from what was read from CR2 - don't call oops_may_print() multiple times, when one time suffices - print pte even in highpte case, as long as the pte page isn't in actually in high memory (which is specifically the case for all page tables covering kernel space) (Changes to v3: Use sizeof()*2 rather than the suggested sizeof()*4 for printing width, use fixed 16-nibble width for PAE, and also apply the max_low_pfn range check to the middle level lookup on PAE.) Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/i386/mm/fault.c | 55 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index b8c4e259fc8b..c6a0a06258e6 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c @@ -20,6 +20,7 @@ #include #include /* For unblank_screen() */ #include +#include /* for max_low_pfn */ #include #include #include @@ -301,7 +302,6 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, struct mm_struct *mm; struct vm_area_struct * vma; unsigned long address; - unsigned long page; int write, si_code; /* get the address */ @@ -510,7 +510,9 @@ no_context: bust_spinlocks(1); if (oops_may_print()) { - #ifdef CONFIG_X86_PAE + __typeof__(pte_val(__pte(0))) page; + +#ifdef CONFIG_X86_PAE if (error_code & 16) { pte_t *pte = lookup_address(address); @@ -519,7 +521,7 @@ no_context: "NX-protected page - exploit attempt? " "(uid: %d)\n", current->uid); } - #endif +#endif if (address < PAGE_SIZE) printk(KERN_ALERT "BUG: unable to handle kernel NULL " "pointer dereference"); @@ -529,25 +531,38 @@ no_context: printk(" at virtual address %08lx\n",address); printk(KERN_ALERT " printing eip:\n"); printk("%08lx\n", regs->eip); - } - page = read_cr3(); - page = ((unsigned long *) __va(page))[address >> 22]; - if (oops_may_print()) + + page = read_cr3(); + page = ((__typeof__(page) *) __va(page))[address >> PGDIR_SHIFT]; +#ifdef CONFIG_X86_PAE + printk(KERN_ALERT "*pdpt = %016Lx\n", page); + if ((page >> PAGE_SHIFT) < max_low_pfn + && page & _PAGE_PRESENT) { + page &= PAGE_MASK; + page = ((__typeof__(page) *) __va(page))[(address >> PMD_SHIFT) + & (PTRS_PER_PMD - 1)]; + printk(KERN_ALERT "*pde = %016Lx\n", page); + page &= ~_PAGE_NX; + } +#else printk(KERN_ALERT "*pde = %08lx\n", page); - /* - * We must not directly access the pte in the highpte - * case, the page table might be allocated in highmem. - * And lets rather not kmap-atomic the pte, just in case - * it's allocated already. - */ -#ifndef CONFIG_HIGHPTE - if ((page & 1) && oops_may_print()) { - page &= PAGE_MASK; - address &= 0x003ff000; - page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT]; - printk(KERN_ALERT "*pte = %08lx\n", page); - } #endif + + /* + * We must not directly access the pte in the highpte + * case if the page table is located in highmem. + * And let's rather not kmap-atomic the pte, just in case + * it's allocated already. + */ + if ((page >> PAGE_SHIFT) < max_low_pfn + && (page & _PAGE_PRESENT)) { + page &= PAGE_MASK; + page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT) + & (PTRS_PER_PTE - 1)]; + printk(KERN_ALERT "*pte = %0*Lx\n", sizeof(page)*2, (u64)page); + } + } + tsk->thread.cr2 = address; tsk->thread.trap_no = 14; tsk->thread.error_code = error_code; -- cgit v1.2.3-59-g8ed1b From 00f1ea696702163b7411d2316264525996c66ed3 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 2 May 2007 19:27:04 +0200 Subject: [PATCH] x86: adjust inclusion of asm/fixmap.h Move inclusion of asm/fixmap.h to where it is really used rather than where it may have been used long ago (requires a few other adjustments to includes due to previous implicit dependencies). Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/x86_64/kernel/genapic.c | 1 + arch/x86_64/kernel/genapic_flat.c | 1 + include/asm-i386/hpet.h | 2 -- include/asm-i386/kexec.h | 5 ----- include/asm-i386/pgalloc.h | 1 - include/asm-i386/smp.h | 7 ++----- include/asm-x86_64/ipi.h | 4 +--- include/asm-x86_64/pgalloc.h | 1 - include/asm-x86_64/pgtable.h | 1 - include/asm-x86_64/smp.h | 3 +-- 10 files changed, 6 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/genapic.c b/arch/x86_64/kernel/genapic.c index c08650a427e2..47496a40e84f 100644 --- a/arch/x86_64/kernel/genapic.c +++ b/arch/x86_64/kernel/genapic.c @@ -18,6 +18,7 @@ #include #include +#include #ifdef CONFIG_ACPI #include diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c index 7c01db8fa9d1..9e0a552f0e4a 100644 --- a/arch/x86_64/kernel/genapic_flat.c +++ b/arch/x86_64/kernel/genapic_flat.c @@ -16,6 +16,7 @@ #include #include #include +#include static cpumask_t flat_target_cpus(void) { diff --git a/include/asm-i386/hpet.h b/include/asm-i386/hpet.h index fc03cf9de5c4..dddeedf504b7 100644 --- a/include/asm-i386/hpet.h +++ b/include/asm-i386/hpet.h @@ -28,8 +28,6 @@ #include -#include - /* * Documentation on HPET can be found at: * http://www.intel.com/ial/home/sp/pcmmspec.htm diff --git a/include/asm-i386/kexec.h b/include/asm-i386/kexec.h index 4dfc9f5ed031..c5b4ab95bdc2 100644 --- a/include/asm-i386/kexec.h +++ b/include/asm-i386/kexec.h @@ -21,7 +21,6 @@ #ifndef __ASSEMBLY__ -#include #include #include @@ -29,10 +28,6 @@ * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return. * I.e. Maximum page that is mapped directly into kernel memory, * and kmap is not required. - * - * Someone correct me if FIXADDR_START - PAGEOFFSET is not the correct - * calculation for the amount of memory directly mappable into the - * kernel memory space. */ /* Maximum physical address we can use pages from */ diff --git a/include/asm-i386/pgalloc.h b/include/asm-i386/pgalloc.h index c8dc2d0141a7..47430175b75f 100644 --- a/include/asm-i386/pgalloc.h +++ b/include/asm-i386/pgalloc.h @@ -1,7 +1,6 @@ #ifndef _I386_PGALLOC_H #define _I386_PGALLOC_H -#include #include #include /* for struct page */ diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h index 6bf0033a301c..9cab1531c613 100644 --- a/include/asm-i386/smp.h +++ b/include/asm-i386/smp.h @@ -11,16 +11,13 @@ #include #endif -#ifdef CONFIG_X86_LOCAL_APIC -#ifndef __ASSEMBLY__ -#include +#if defined(CONFIG_X86_LOCAL_APIC) && !defined(__ASSEMBLY__) #include #include +#include #ifdef CONFIG_X86_IO_APIC #include #endif -#include -#endif #endif #define BAD_APICID 0xFFu diff --git a/include/asm-x86_64/ipi.h b/include/asm-x86_64/ipi.h index 2a5c162b7d92..ffa6f1517f1a 100644 --- a/include/asm-x86_64/ipi.h +++ b/include/asm-x86_64/ipi.h @@ -18,10 +18,8 @@ * Subject to the GNU Public License, v.2 */ -#include #include -#include -#include +#include /* * the following functions deal with sending IPIs between CPUs. diff --git a/include/asm-x86_64/pgalloc.h b/include/asm-x86_64/pgalloc.h index 4e28b6060a5e..31d497171969 100644 --- a/include/asm-x86_64/pgalloc.h +++ b/include/asm-x86_64/pgalloc.h @@ -1,7 +1,6 @@ #ifndef _X86_64_PGALLOC_H #define _X86_64_PGALLOC_H -#include #include #include #include diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h index 730bd6028416..5957361782fe 100644 --- a/include/asm-x86_64/pgtable.h +++ b/include/asm-x86_64/pgtable.h @@ -6,7 +6,6 @@ * the x86-64 page table tree. */ #include -#include #include #include #include diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h index de592a408c07..f4236d7789aa 100644 --- a/include/asm-x86_64/smp.h +++ b/include/asm-x86_64/smp.h @@ -10,10 +10,9 @@ #include extern int disable_apic; -#include #include -#include #include +#include #include #ifdef CONFIG_SMP -- cgit v1.2.3-59-g8ed1b From b0354795c9c8fef2fadf8f867586c78efd9a1dc9 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 2 May 2007 19:27:04 +0200 Subject: [PATCH] x86-64: adjust inclusion of asm/vsyscall32.h Avoid including asm/vsyscall32.h in virtually every source file. Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/x86_64/ia32/syscall32.c | 1 + include/asm-x86_64/fixmap.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c index 568ff0df89e7..fc4419ff0355 100644 --- a/arch/x86_64/ia32/syscall32.c +++ b/arch/x86_64/ia32/syscall32.c @@ -13,6 +13,7 @@ #include #include #include +#include extern unsigned char syscall32_syscall[], syscall32_syscall_end[]; extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[]; diff --git a/include/asm-x86_64/fixmap.h b/include/asm-x86_64/fixmap.h index 1b620db5b9e3..e90e1677531b 100644 --- a/include/asm-x86_64/fixmap.h +++ b/include/asm-x86_64/fixmap.h @@ -15,7 +15,6 @@ #include #include #include -#include /* * Here we define all the compile-time 'special' virtual -- cgit v1.2.3-59-g8ed1b From 9964cf7d776600724ef5f1b33303ceadc588b8ba Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 2 May 2007 19:27:05 +0200 Subject: [PATCH] x86: consolidate smp_send_stop() Synchronize i386's smp_send_stop() with x86-64's in only try-locking the call lock to prevent deadlocks when called from panic(). In both version, disable interrupts before clearing the CPU off the online map to eliminate races with IRQ handlers inspecting this map. Also in both versions, save/restore interrupts rather than disabling/ enabling them. On x86-64, eliminate one function used here by folding it into its single caller, convert to static, and rename for consistency with i386 (lkcd may like this). Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/i386/kernel/smp.c | 68 +++++++++++++++++++++++++++--------------------- arch/x86_64/kernel/smp.c | 28 +++++++------------- include/asm-x86_64/smp.h | 1 - 3 files changed, 48 insertions(+), 49 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 0e8977871b1f..0cd459baad68 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -515,35 +515,14 @@ void unlock_ipi_call_lock(void) static struct call_data_struct *call_data; -/** - * smp_call_function(): Run a function on all other CPUs. - * @func: The function to run. This must be fast and non-blocking. - * @info: An arbitrary pointer to pass to the function. - * @nonatomic: currently unused. - * @wait: If true, wait (atomically) until function has completed on other CPUs. - * - * Returns 0 on success, else a negative status code. Does not return until - * remote CPUs are nearly ready to execute <> or are or have executed. - * - * You must not call this function with disabled interrupts or from a - * hardware interrupt handler or from a bottom half handler. - */ -int smp_call_function (void (*func) (void *info), void *info, int nonatomic, - int wait) +static void __smp_call_function(void (*func) (void *info), void *info, + int nonatomic, int wait) { struct call_data_struct data; - int cpus; - - /* Holding any lock stops cpus from going down. */ - spin_lock(&call_lock); - cpus = num_online_cpus() - 1; - if (!cpus) { - spin_unlock(&call_lock); - return 0; - } + int cpus = num_online_cpus() - 1; - /* Can deadlock when called with interrupts disabled */ - WARN_ON(irqs_disabled()); + if (!cpus) + return; data.func = func; data.info = info; @@ -565,6 +544,30 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, if (wait) while (atomic_read(&data.finished) != cpus) cpu_relax(); +} + +/** + * smp_call_function(): Run a function on all other CPUs. + * @func: The function to run. This must be fast and non-blocking. + * @info: An arbitrary pointer to pass to the function. + * @nonatomic: currently unused. + * @wait: If true, wait (atomically) until function has completed on other CPUs. + * + * Returns 0 on success, else a negative status code. Does not return until + * remote CPUs are nearly ready to execute <> or are or have executed. + * + * You must not call this function with disabled interrupts or from a + * hardware interrupt handler or from a bottom half handler. + */ +int smp_call_function (void (*func) (void *info), void *info, int nonatomic, + int wait) +{ + /* Can deadlock when called with interrupts disabled */ + WARN_ON(irqs_disabled()); + + /* Holding any lock stops cpus from going down. */ + spin_lock(&call_lock); + __smp_call_function(func, info, nonatomic, wait); spin_unlock(&call_lock); return 0; @@ -573,11 +576,11 @@ EXPORT_SYMBOL(smp_call_function); static void stop_this_cpu (void * dummy) { + local_irq_disable(); /* * Remove this CPU: */ cpu_clear(smp_processor_id(), cpu_online_map); - local_irq_disable(); disable_local_APIC(); if (cpu_data[smp_processor_id()].hlt_works_ok) for(;;) halt(); @@ -590,11 +593,16 @@ static void stop_this_cpu (void * dummy) void smp_send_stop(void) { - smp_call_function(stop_this_cpu, NULL, 1, 0); + /* Don't deadlock on the call lock in panic */ + int nolock = !spin_trylock(&call_lock); + unsigned long flags; - local_irq_disable(); + local_irq_save(flags); + __smp_call_function(stop_this_cpu, NULL, 0, 0); + if (!nolock) + spin_unlock(&call_lock); disable_local_APIC(); - local_irq_enable(); + local_irq_restore(flags); } /* diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c index af1ec4d23cf8..bd1d123947ce 100644 --- a/arch/x86_64/kernel/smp.c +++ b/arch/x86_64/kernel/smp.c @@ -452,42 +452,34 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, } EXPORT_SYMBOL(smp_call_function); -void smp_stop_cpu(void) +static void stop_this_cpu(void *dummy) { - unsigned long flags; + local_irq_disable(); /* * Remove this CPU: */ cpu_clear(smp_processor_id(), cpu_online_map); - local_irq_save(flags); disable_local_APIC(); - local_irq_restore(flags); -} - -static void smp_really_stop_cpu(void *dummy) -{ - smp_stop_cpu(); for (;;) halt(); } void smp_send_stop(void) { - int nolock = 0; + int nolock; + unsigned long flags; + if (reboot_force) return; + /* Don't deadlock on the call lock in panic */ - if (!spin_trylock(&call_lock)) { - /* ignore locking because we have panicked anyways */ - nolock = 1; - } - __smp_call_function(smp_really_stop_cpu, NULL, 0, 0); + nolock = !spin_trylock(&call_lock); + local_irq_save(flags); + __smp_call_function(stop_this_cpu, NULL, 0, 0); if (!nolock) spin_unlock(&call_lock); - - local_irq_disable(); disable_local_APIC(); - local_irq_enable(); + local_irq_restore(flags); } /* diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h index f4236d7789aa..d5704421456b 100644 --- a/include/asm-x86_64/smp.h +++ b/include/asm-x86_64/smp.h @@ -37,7 +37,6 @@ extern void lock_ipi_call_lock(void); extern void unlock_ipi_call_lock(void); extern int smp_num_siblings; extern void smp_send_reschedule(int cpu); -void smp_stop_cpu(void); extern cpumask_t cpu_sibling_map[NR_CPUS]; extern cpumask_t cpu_core_map[NR_CPUS]; -- cgit v1.2.3-59-g8ed1b From f76c392380a40008ee6ecaea4e5a51a3a10282c4 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:05 +0200 Subject: [PATCH] i386: No need to use -traditional for processing asm in i386/kernel/ No need to use -traditional for processing asm in i386/kernel/ Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen --- arch/i386/kernel/Makefile | 2 -- arch/i386/kernel/entry.S | 2 +- include/asm-i386/percpu.h | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 4ae3dcf1d2f0..bd7753cb9e69 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile @@ -43,8 +43,6 @@ obj-$(CONFIG_VMI) += vmi.o vmitime.o obj-$(CONFIG_PARAVIRT) += paravirt.o obj-y += pcspeaker.o -EXTRA_AFLAGS := -traditional - obj-$(CONFIG_SCx200) += scx200.o # vsyscall.o contains the vsyscall DSO images as __initdata. diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 18bddcb8e9e8..922cc38dc405 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -635,7 +635,7 @@ ENTRY(name) \ SAVE_ALL; \ TRACE_IRQS_OFF \ movl %esp,%eax; \ - call smp_/**/name; \ + call smp_##name; \ jmp ret_from_intr; \ CFI_ENDPROC; \ ENDPROC(name) diff --git a/include/asm-i386/percpu.h b/include/asm-i386/percpu.h index 510ae1d3486c..a10e7c68ae9d 100644 --- a/include/asm-i386/percpu.h +++ b/include/asm-i386/percpu.h @@ -20,10 +20,10 @@ #ifdef CONFIG_SMP #define PER_CPU(var, cpu) \ movl __per_cpu_offset(,cpu,4), cpu; \ - addl $per_cpu__/**/var, cpu; + addl $per_cpu__##var, cpu; #else /* ! SMP */ #define PER_CPU(var, cpu) \ - movl $per_cpu__/**/var, cpu; + movl $per_cpu__##var, cpu; #endif /* SMP */ #endif /* !__ASSEMBLY__ */ -- cgit v1.2.3-59-g8ed1b From 9215da33209b861b01c51382254b178a3fe92a30 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 2 May 2007 19:27:05 +0200 Subject: [PATCH] i386: mtrr range check correction Whether a region is below 1Mb is determined by its start rather than its end. This hunk got erroneously dropped from a previous patch. Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/cpu/mtrr/generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c index f77fc53db654..68b383788882 100644 --- a/arch/i386/kernel/cpu/mtrr/generic.c +++ b/arch/i386/kernel/cpu/mtrr/generic.c @@ -428,7 +428,7 @@ int generic_validate_add_page(unsigned long base, unsigned long size, unsigned i } } - if (base + size < 0x100) { + if (base < 0x100) { printk(KERN_WARNING "mtrr: cannot set region below 1 MiB (0x%lx000,0x%lx000)\n", base, size); return -EINVAL; -- cgit v1.2.3-59-g8ed1b From f5e8861583a591020176c90c10c6a130fed4f3ec Mon Sep 17 00:00:00 2001 From: takada Date: Wed, 2 May 2007 19:27:05 +0200 Subject: [PATCH] i386: pit_latch_buggy has no effect Eliminated the arch/i386/kernel/timers in 2.6.18, use clocksoures instead. pit_latch_buggy was referred in timers/timer_tsc.c, and currently removed. Therefore nobody refer it. Until 2.6.17, MediaGX's TSC works correctly. after 2.6.18, warned "TSC appears to be running slowly. Marking it as unstable". So marked unstable TSC when CS55x0. Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/kernel/cpu/cyrix.c | 2 +- arch/i386/kernel/time.c | 2 -- include/asm-i386/timer.h | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c index de27bd07bc9c..f0badfdd4e45 100644 --- a/arch/i386/kernel/cpu/cyrix.c +++ b/arch/i386/kernel/cpu/cyrix.c @@ -279,7 +279,7 @@ static void __cpuinit init_cyrix(struct cpuinfo_x86 *c) */ if (vendor == PCI_VENDOR_ID_CYRIX && (device == PCI_DEVICE_ID_CYRIX_5510 || device == PCI_DEVICE_ID_CYRIX_5520)) - pit_latch_buggy = 1; + mark_tsc_unstable(); } #endif c->x86_cache_size=16; /* Yep 16K integrated cache thats it */ diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index 94e5cb091104..a665df61f08c 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -70,8 +70,6 @@ #include -int pit_latch_buggy; /* extern */ - #include "do_timer.h" unsigned int cpu_khz; /* Detected as we calibrate the TSC */ diff --git a/include/asm-i386/timer.h b/include/asm-i386/timer.h index 12dd67bf760f..153770e25faa 100644 --- a/include/asm-i386/timer.h +++ b/include/asm-i386/timer.h @@ -9,8 +9,6 @@ void setup_pit_timer(void); unsigned long long native_sched_clock(void); unsigned long native_calculate_cpu_khz(void); -/* Modifiers for buggy PIT handling */ -extern int pit_latch_buggy; extern int timer_ack; extern int no_timer_check; extern int no_sync_cmos_clock; -- cgit v1.2.3-59-g8ed1b From 0949be35095b53dbaa72db700cb5074c5c249629 Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Wed, 2 May 2007 19:27:05 +0200 Subject: [PATCH] i386: Add an option for the VIA C7 which sets appropriate L1 cache The VIA C7 is a 686 (with TSC) that supports MMX, SSE and SSE2, it also has a cache line length of 64 according to http://www.digit-life.com/articles2/cpu/rmma-via-c7.html. This patch sets gcc to -march=686 and select s the correct cache shift. Signed-off-by: Simon Arlott Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Dave Jones Cc: Alan Cox Signed-off-by: Andrew Morton --- arch/i386/Kconfig.cpu | 13 ++++++++++--- arch/i386/Makefile.cpu | 1 + arch/um/defconfig | 1 + include/asm-i386/module.h | 2 ++ 4 files changed, 14 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu index b99c0e2a4e63..b1af9f50a143 100644 --- a/arch/i386/Kconfig.cpu +++ b/arch/i386/Kconfig.cpu @@ -43,6 +43,7 @@ config M386 - "Geode GX/LX" For AMD Geode GX and LX processors. - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3. - "VIA C3-2" for VIA C3-2 "Nehemiah" (model 9 and above). + - "VIA C7" for VIA C7. If you don't know what to do, choose "386". @@ -203,6 +204,12 @@ config MVIAC3_2 of SSE and tells gcc to treat the CPU as a 686. Note, this kernel will not boot on older (pre model 9) C3s. +config MVIAC7 + bool "VIA C7" + help + Select this for a VIA C7. Selecting this uses the correct cache + shift and tells gcc to treat the CPU as a 686. + endchoice config X86_GENERIC @@ -231,7 +238,7 @@ config X86_L1_CACHE_SHIFT default "7" if MPENTIUM4 || X86_GENERIC default "4" if X86_ELAN || M486 || M386 || MGEODEGX1 default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX - default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 + default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 config RWSEM_GENERIC_SPINLOCK bool @@ -297,7 +304,7 @@ config X86_ALIGNMENT_16 config X86_GOOD_APIC bool - depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 + depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 || MVIAC7 default y config X86_INTEL_USERCOPY @@ -322,5 +329,5 @@ config X86_OOSTORE config X86_TSC bool - depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ + depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ default y diff --git a/arch/i386/Makefile.cpu b/arch/i386/Makefile.cpu index a32c031c90d7..e0ada4e9e137 100644 --- a/arch/i386/Makefile.cpu +++ b/arch/i386/Makefile.cpu @@ -32,6 +32,7 @@ cflags-$(CONFIG_MWINCHIP2) += $(call cc-option,-march=winchip2,-march=i586) cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586) cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) +cflags-$(CONFIG_MVIAC7) += -march=i686 cflags-$(CONFIG_MCORE2) += -march=i686 $(call cc-option,-mtune=core2,$(call cc-option,-mtune=generic,-mtune=i686)) # AMD Elan support diff --git a/arch/um/defconfig b/arch/um/defconfig index 780cc0a4a128..f938fa822146 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig @@ -41,6 +41,7 @@ CONFIG_M686=y # CONFIG_MGEODE_LX is not set # CONFIG_MCYRIXIII is not set # CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set # CONFIG_X86_GENERIC is not set CONFIG_X86_CMPXCHG=y CONFIG_X86_XADD=y diff --git a/include/asm-i386/module.h b/include/asm-i386/module.h index 02f8f541cbe0..7e5fda6c3976 100644 --- a/include/asm-i386/module.h +++ b/include/asm-i386/module.h @@ -54,6 +54,8 @@ struct mod_arch_specific #define MODULE_PROC_FAMILY "CYRIXIII " #elif defined CONFIG_MVIAC3_2 #define MODULE_PROC_FAMILY "VIAC3-2 " +#elif defined CONFIG_MVIAC7 +#define MODULE_PROC_FAMILY "VIAC7 " #elif defined CONFIG_MGEODEGX1 #define MODULE_PROC_FAMILY "GEODEGX1 " #elif defined CONFIG_MGEODE_LX -- cgit v1.2.3-59-g8ed1b From 0adad171c2334d43fc2fa208f6b45e88f0679427 Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Wed, 2 May 2007 19:27:05 +0200 Subject: [PATCH] i386: probe_roms() cleanup Remove the assumption that if the first page of a legacy ROM is mapped, it'll all be mapped. This'll also stop people reading this code from wondering if they're looking at a bug... Signed-off-by: Rene Herman Signed-off-by: Martin Murray Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Zachary Amsden Cc: Jeremy Fitzhardinge Signed-off-by: Andrew Morton --- arch/i386/kernel/e820.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c index 70f39560846a..31f4670ef740 100644 --- a/arch/i386/kernel/e820.c +++ b/arch/i386/kernel/e820.c @@ -161,26 +161,27 @@ static struct resource standard_io_resources[] = { { static int __init romsignature(const unsigned char *rom) { + const unsigned short * const ptr = (const unsigned short *)rom; unsigned short sig; - return probe_kernel_address((const unsigned short *)rom, sig) == 0 && - sig == ROMSIGNATURE; + return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE; } -static int __init romchecksum(unsigned char *rom, unsigned long length) +static int __init romchecksum(const unsigned char *rom, unsigned long length) { - unsigned char sum; + unsigned char sum, c; - for (sum = 0; length; length--) - sum += *rom++; - return sum == 0; + for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--) + sum += c; + return !length && !sum; } static void __init probe_roms(void) { + const unsigned char *rom; unsigned long start, length, upper; - unsigned char *rom; - int i; + unsigned char c; + int i; /* video rom */ upper = adapter_rom_resources[0].start; @@ -191,8 +192,11 @@ static void __init probe_roms(void) video_rom_resource.start = start; + if (probe_kernel_address(rom + 2, c) != 0) + continue; + /* 0 < length <= 0x7f * 512, historically */ - length = rom[2] * 512; + length = c * 512; /* if checksum okay, trust length byte */ if (length && romchecksum(rom, length)) @@ -226,8 +230,11 @@ static void __init probe_roms(void) if (!romsignature(rom)) continue; + if (probe_kernel_address(rom + 2, c) != 0) + continue; + /* 0 < length <= 0x7f * 512, historically */ - length = rom[2] * 512; + length = c * 512; /* but accept any length that fits if checksum okay */ if (!length || start + length > upper || !romchecksum(rom, length)) -- cgit v1.2.3-59-g8ed1b From 3755090722e5a9c44780e5461ed9e49ab542bc73 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 2 May 2007 19:27:05 +0200 Subject: [PATCH] x86-64: a few missing entry.S annotations Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/x86_64/kernel/entry.S | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index ed4350ced3d0..fa984b53e7e6 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S @@ -701,6 +701,7 @@ END(spurious_interrupt) CFI_ADJUST_CFA_OFFSET 8 pushq %rax /* push real oldrax to the rdi slot */ CFI_ADJUST_CFA_OFFSET 8 + CFI_REL_OFFSET rax,0 leaq \sym(%rip),%rax jmp error_entry CFI_ENDPROC @@ -710,6 +711,7 @@ END(spurious_interrupt) XCPT_FRAME pushq %rax CFI_ADJUST_CFA_OFFSET 8 + CFI_REL_OFFSET rax,0 leaq \sym(%rip),%rax jmp error_entry CFI_ENDPROC @@ -817,6 +819,7 @@ paranoid_schedule\trace: */ KPROBE_ENTRY(error_entry) _frame RDI + CFI_REL_OFFSET rax,0 /* rdi slot contains rax, oldrax contains error code */ cld subq $14*8,%rsp @@ -824,6 +827,7 @@ KPROBE_ENTRY(error_entry) movq %rsi,13*8(%rsp) CFI_REL_OFFSET rsi,RSI movq 14*8(%rsp),%rsi /* load rax from rdi slot */ + CFI_REGISTER rax,rsi movq %rdx,12*8(%rsp) CFI_REL_OFFSET rdx,RDX movq %rcx,11*8(%rsp) @@ -857,6 +861,7 @@ error_swapgs: swapgs error_sti: movq %rdi,RDI(%rsp) + CFI_REL_OFFSET rdi,RDI movq %rsp,%rdi movq ORIG_RAX(%rsp),%rsi /* get error code */ movq $-1,ORIG_RAX(%rsp) -- cgit v1.2.3-59-g8ed1b From 00e065ea587363e538d9624eea8cacad12cb7397 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 2 May 2007 19:27:05 +0200 Subject: [PATCH] i386: Add dwarf2 annotations to *_user and checksum functions Signed-off-by: Andi Kleen --- arch/i386/lib/checksum.S | 69 +++++++++++++++++++++++++++++++++++++++++------- arch/i386/lib/getuser.S | 26 +++++++++++------- arch/i386/lib/putuser.S | 39 +++++++++++++++++---------- 3 files changed, 102 insertions(+), 32 deletions(-) (limited to 'arch') diff --git a/arch/i386/lib/checksum.S b/arch/i386/lib/checksum.S index 75ffd02654fc..adbccd0bbb78 100644 --- a/arch/i386/lib/checksum.S +++ b/arch/i386/lib/checksum.S @@ -25,6 +25,8 @@ * 2 of the License, or (at your option) any later version. */ +#include +#include #include /* @@ -36,8 +38,6 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) */ .text -.align 4 -.globl csum_partial #ifndef CONFIG_X86_USE_PPRO_CHECKSUM @@ -48,9 +48,14 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) * Fortunately, it is easy to convert 2-byte alignment to 4-byte * alignment for the unrolled loop. */ -csum_partial: +ENTRY(csum_partial) + CFI_STARTPROC pushl %esi + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET esi, 0 pushl %ebx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ebx, 0 movl 20(%esp),%eax # Function arg: unsigned int sum movl 16(%esp),%ecx # Function arg: int len movl 12(%esp),%esi # Function arg: unsigned char *buff @@ -128,16 +133,27 @@ csum_partial: roll $8, %eax 8: popl %ebx + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE ebx popl %esi + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE esi ret + CFI_ENDPROC +ENDPROC(csum_partial) #else /* Version for PentiumII/PPro */ -csum_partial: +ENTRY(csum_partial) + CFI_STARTPROC pushl %esi + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET esi, 0 pushl %ebx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ebx, 0 movl 20(%esp),%eax # Function arg: unsigned int sum movl 16(%esp),%ecx # Function arg: int len movl 12(%esp),%esi # Function arg: const unsigned char *buf @@ -245,8 +261,14 @@ csum_partial: roll $8, %eax 90: popl %ebx + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE ebx popl %esi + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE esi ret + CFI_ENDPROC +ENDPROC(csum_partial) #endif @@ -278,19 +300,24 @@ unsigned int csum_partial_copy_generic (const char *src, char *dst, .long 9999b, 6002f ; \ .previous -.align 4 -.globl csum_partial_copy_generic - #ifndef CONFIG_X86_USE_PPRO_CHECKSUM #define ARGBASE 16 #define FP 12 -csum_partial_copy_generic: +ENTRY(csum_partial_copy_generic) + CFI_STARTPROC subl $4,%esp + CFI_ADJUST_CFA_OFFSET 4 pushl %edi + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET edi, 0 pushl %esi + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET esi, 0 pushl %ebx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ebx, 0 movl ARGBASE+16(%esp),%eax # sum movl ARGBASE+12(%esp),%ecx # len movl ARGBASE+4(%esp),%esi # src @@ -400,10 +427,19 @@ DST( movb %cl, (%edi) ) .previous popl %ebx + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE ebx popl %esi + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE esi popl %edi + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE edi popl %ecx # equivalent to addl $4,%esp + CFI_ADJUST_CFA_OFFSET -4 ret + CFI_ENDPROC +ENDPROC(csum_partial_copy_generic) #else @@ -421,10 +457,17 @@ DST( movb %cl, (%edi) ) #define ARGBASE 12 -csum_partial_copy_generic: +ENTRY(csum_partial_copy_generic) + CFI_STARTPROC pushl %ebx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ebx, 0 pushl %edi + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET edi, 0 pushl %esi + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET esi, 0 movl ARGBASE+4(%esp),%esi #src movl ARGBASE+8(%esp),%edi #dst movl ARGBASE+12(%esp),%ecx #len @@ -485,9 +528,17 @@ DST( movb %dl, (%edi) ) .previous popl %esi + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE esi popl %edi + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE edi popl %ebx + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE ebx ret + CFI_ENDPROC +ENDPROC(csum_partial_copy_generic) #undef ROUND #undef ROUND1 diff --git a/arch/i386/lib/getuser.S b/arch/i386/lib/getuser.S index 62d7f178a326..6d84b53f12a2 100644 --- a/arch/i386/lib/getuser.S +++ b/arch/i386/lib/getuser.S @@ -8,6 +8,8 @@ * return an error value in addition to the "real" * return value. */ +#include +#include #include @@ -24,19 +26,19 @@ */ .text -.align 4 -.globl __get_user_1 -__get_user_1: +ENTRY(__get_user_1) + CFI_STARTPROC GET_THREAD_INFO(%edx) cmpl TI_addr_limit(%edx),%eax jae bad_get_user 1: movzbl (%eax),%edx xorl %eax,%eax ret + CFI_ENDPROC +ENDPROC(__get_user_1) -.align 4 -.globl __get_user_2 -__get_user_2: +ENTRY(__get_user_2) + CFI_STARTPROC addl $1,%eax jc bad_get_user GET_THREAD_INFO(%edx) @@ -45,10 +47,11 @@ __get_user_2: 2: movzwl -1(%eax),%edx xorl %eax,%eax ret + CFI_ENDPROC +ENDPROC(__get_user_2) -.align 4 -.globl __get_user_4 -__get_user_4: +ENTRY(__get_user_4) + CFI_STARTPROC addl $3,%eax jc bad_get_user GET_THREAD_INFO(%edx) @@ -57,11 +60,16 @@ __get_user_4: 3: movl -3(%eax),%edx xorl %eax,%eax ret + CFI_ENDPROC +ENDPROC(__get_user_4) bad_get_user: + CFI_STARTPROC xorl %edx,%edx movl $-14,%eax ret + CFI_ENDPROC +END(bad_get_user) .section __ex_table,"a" .long 1b,bad_get_user diff --git a/arch/i386/lib/putuser.S b/arch/i386/lib/putuser.S index a32d9f570f48..f58fba109d18 100644 --- a/arch/i386/lib/putuser.S +++ b/arch/i386/lib/putuser.S @@ -8,6 +8,8 @@ * return an error value in addition to the "real" * return value. */ +#include +#include #include @@ -23,23 +25,28 @@ * as they get called from within inline assembly. */ -#define ENTER pushl %ebx ; GET_THREAD_INFO(%ebx) -#define EXIT popl %ebx ; ret +#define ENTER CFI_STARTPROC ; \ + pushl %ebx ; \ + CFI_ADJUST_CFA_OFFSET 4 ; \ + CFI_REL_OFFSET ebx, 0 ; \ + GET_THREAD_INFO(%ebx) +#define EXIT popl %ebx ; \ + CFI_ADJUST_CFA_OFFSET -4 ; \ + CFI_RESTORE ebx ; \ + ret ; \ + CFI_ENDPROC .text -.align 4 -.globl __put_user_1 -__put_user_1: +ENTRY(__put_user_1) ENTER cmpl TI_addr_limit(%ebx),%ecx jae bad_put_user 1: movb %al,(%ecx) xorl %eax,%eax EXIT +ENDPROC(__put_user_1) -.align 4 -.globl __put_user_2 -__put_user_2: +ENTRY(__put_user_2) ENTER movl TI_addr_limit(%ebx),%ebx subl $1,%ebx @@ -48,10 +55,9 @@ __put_user_2: 2: movw %ax,(%ecx) xorl %eax,%eax EXIT +ENDPROC(__put_user_2) -.align 4 -.globl __put_user_4 -__put_user_4: +ENTRY(__put_user_4) ENTER movl TI_addr_limit(%ebx),%ebx subl $3,%ebx @@ -60,10 +66,9 @@ __put_user_4: 3: movl %eax,(%ecx) xorl %eax,%eax EXIT +ENDPROC(__put_user_4) -.align 4 -.globl __put_user_8 -__put_user_8: +ENTRY(__put_user_8) ENTER movl TI_addr_limit(%ebx),%ebx subl $7,%ebx @@ -73,10 +78,16 @@ __put_user_8: 5: movl %edx,4(%ecx) xorl %eax,%eax EXIT +ENDPROC(__put_user_8) bad_put_user: + CFI_STARTPROC simple + CFI_DEF_CFA esp, 2*4 + CFI_OFFSET eip, -1*4 + CFI_OFFSET ebx, -2*4 movl $-14,%eax EXIT +END(bad_put_user) .section __ex_table,"a" .long 1b,bad_put_user -- cgit v1.2.3-59-g8ed1b From d18951834216eae82e2f9112416111b4f55f1849 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:05 +0200 Subject: [PATCH] x86: Fix i386 and x86_64 fault information pollution a userspace fault or a kernelspace fault which will result in the immediate death of the process. They should not be filled in as a result of a kernelspace fault which can be fixed up. Otherwise, if the process is handling SIGSEGV and examining the fault information, this can result in the kernel space fault trashing the previously stored fault information if it arrives between the userspace fault happening and the SIGSEGV being delivered to the process. Signed-off-by: Jeff Dike Signed-off-by: Andi Kleen Acked-by: Jan Beulich -- arch/i386/kernel/traps.c | 24 ++++++++++++++++++------ arch/x86_64/kernel/traps.c | 30 +++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 13 deletions(-) --- arch/i386/kernel/traps.c | 24 ++++++++++++++++++------ arch/x86_64/kernel/traps.c | 30 +++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index af0d3f70a817..58dfecc8e36c 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -476,8 +476,6 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86, siginfo_t *info) { struct task_struct *tsk = current; - tsk->thread.error_code = error_code; - tsk->thread.trap_no = trapnr; if (regs->eflags & VM_MASK) { if (vm86) @@ -489,6 +487,18 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86, goto kernel_trap; trap_signal: { + /* + * We want error_code and trap_no set for userspace faults and + * kernelspace faults which result in die(), but not + * kernelspace faults which are fixed up. die() gives the + * process no chance to handle the signal and notice the + * kernel fault information, so that won't result in polluting + * the information about previously queued, but not yet + * delivered, faults. See also do_general_protection below. + */ + tsk->thread.error_code = error_code; + tsk->thread.trap_no = trapnr; + if (info) force_sig_info(signr, info, tsk); else @@ -497,8 +507,11 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86, } kernel_trap: { - if (!fixup_exception(regs)) + if (!fixup_exception(regs)) { + tsk->thread.error_code = error_code; + tsk->thread.trap_no = trapnr; die(str, regs, error_code); + } return; } @@ -603,9 +616,6 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs, } put_cpu(); - current->thread.error_code = error_code; - current->thread.trap_no = 13; - if (regs->eflags & VM_MASK) goto gp_in_vm86; @@ -624,6 +634,8 @@ gp_in_vm86: gp_in_kernel: if (!fixup_exception(regs)) { + current->thread.error_code = error_code; + current->thread.trap_no = 13; if (notify_die(DIE_GPF, "general protection fault", regs, error_code, 13, SIGSEGV) == NOTIFY_STOP) return; diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 09d2e8a10a49..cceef5bd7302 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -581,10 +581,20 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, { struct task_struct *tsk = current; - tsk->thread.error_code = error_code; - tsk->thread.trap_no = trapnr; - if (user_mode(regs)) { + /* + * We want error_code and trap_no set for userspace + * faults and kernelspace faults which result in + * die(), but not kernelspace faults which are fixed + * up. die() gives the process no chance to handle + * the signal and notice the kernel fault information, + * so that won't result in polluting the information + * about previously queued, but not yet delivered, + * faults. See also do_general_protection below. + */ + tsk->thread.error_code = error_code; + tsk->thread.trap_no = trapnr; + if (exception_trace && unhandled_signal(tsk, signr)) printk(KERN_INFO "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n", @@ -605,8 +615,11 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, fixup = search_exception_tables(regs->rip); if (fixup) regs->rip = fixup->fixup; - else + else { + tsk->thread.error_code = error_code; + tsk->thread.trap_no = trapnr; die(str, regs, error_code); + } return; } } @@ -682,10 +695,10 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, conditional_sti(regs); - tsk->thread.error_code = error_code; - tsk->thread.trap_no = 13; - if (user_mode(regs)) { + tsk->thread.error_code = error_code; + tsk->thread.trap_no = 13; + if (exception_trace && unhandled_signal(tsk, SIGSEGV)) printk(KERN_INFO "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n", @@ -704,6 +717,9 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, regs->rip = fixup->fixup; return; } + + tsk->thread.error_code = error_code; + tsk->thread.trap_no = 13; if (notify_die(DIE_GPF, "general protection fault", regs, error_code, 13, SIGSEGV) == NOTIFY_STOP) return; -- cgit v1.2.3-59-g8ed1b From 803d80f65038f77c4681a0d7708e9d693e68aaa8 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:05 +0200 Subject: [PATCH] x86-64: Some cleanup in time.c Move prototypes into header files Remove unneeded includes. Signed-off-by: Andi Kleen --- arch/x86_64/kernel/time.c | 5 +---- include/asm-x86_64/proto.h | 2 ++ 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 75d73a9aa9ff..811b8f987b50 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -39,13 +39,10 @@ #include #include #include -#include #include #include #include - -extern void i8254_timer_resume(void); -extern int using_apic_timer; +#include static char *timename = NULL; diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index 6688cf9eb27b..f64949fae61a 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h @@ -122,6 +122,8 @@ extern void smp_local_timer_interrupt(void); long do_arch_prctl(struct task_struct *task, int code, unsigned long addr); +void i8254_timer_resume(void); + #define round_up(x,y) (((x) + (y) - 1) & ~((y)-1)) #define round_down(x,y) ((x) & ~((y)-1)) -- cgit v1.2.3-59-g8ed1b From bf8696ed6dfa561198b4736deaf11ab68dcc4845 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Wed, 2 May 2007 19:27:05 +0200 Subject: [PATCH] i386: i386 make NMI use PERFCTR1 for architectural perfmon (take 2) Hello, This patch against 2.6.20-git14 makes the NMI watchdog use PERFSEL1/PERFCTR1 instead of PERFSEL0/PERFCTR0 on processors supporting Intel architectural perfmon, such as Intel Core 2. Although all PMU events can work on both counters, the Precise Event-Based Sampling (PEBS) requires that the event be in PERFCTR0 to work correctly (see section 18.14.4.1 in the IA32 SDM Vol 3b). A similar patch for x86-64 is to follow. Changelog: - make the i386 NMI watchdog use PERFSEL1/PERFCTR1 instead of PERFSEL0/PERFCTR0 on processors supporting the Intel architectural perfmon (e.g. Core 2 Duo). This allows PEBS to work when the NMI watchdog is active. signed-off-by: stephane eranian Signed-off-by: Andi Kleen --- arch/i386/kernel/nmi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 84c3497efb60..aef22c881a0d 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -365,7 +365,7 @@ static int __init check_nmi_watchdog(void) nmi_hz = 1; if (wd->perfctr_msr == MSR_P6_PERFCTR0 || - wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { + wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR1) { nmi_hz = adjust_for_32bit_ctr(nmi_hz); } } @@ -799,8 +799,8 @@ static int setup_intel_arch_watchdog(void) (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) goto fail; - perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; - evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0; + perfctr_msr = MSR_ARCH_PERFMON_PERFCTR1; + evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL1; if (!__reserve_perfctr_nmi(-1, perfctr_msr)) goto fail; @@ -1080,7 +1080,7 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) write_watchdog_counter(wd->perfctr_msr, NULL); } else if (wd->perfctr_msr == MSR_P6_PERFCTR0 || - wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { + wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR1) { /* P6 based Pentium M need to re-unmask * the apic vector but it doesn't hurt * other P6 variant. -- cgit v1.2.3-59-g8ed1b From 405e494d91bac85cc992f55ad434b0f325e399a5 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Wed, 2 May 2007 19:27:05 +0200 Subject: [PATCH] x86-64: x86_64 make NMI use PERFCTR1 for architectural perfmon (take 2) Hello, This patch against 2.6.20-git14 makes the NMI watchdog use PERFSEL1/PERFCTR1 instead of PERFSEL0/PERFCTR0 on processors supporting Intel architectural perfmon, such as Intel Core 2. Although all PMU events can work on both counters, the Precise Event-Based Sampling (PEBS) requires that the event be in PERFCTR0 to work correctly (see section 18.14.4.1 in the IA32 SDM Vol 3b). This versions has 3 chunks compared to previous where we had missed on check. Changelog: - make the x86-64 NMI watchdog use PERFSEL1/PERFCTR1 instead of PERFSEL0/PERFCTR0 on processors supporting the Intel architectural perfmon (e.g. Core 2 Duo). This allows PEBS to work when the NMI watchdog is active. signed-off-by: stephane eranian Signed-off-by: Andi Kleen --- arch/x86_64/kernel/nmi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index dfab9f167366..010d3d9bd56a 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c @@ -348,7 +348,7 @@ int __init check_nmi_watchdog (void) struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); nmi_hz = 1; - if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) + if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR1) nmi_hz = adjust_for_32bit_ctr(nmi_hz); } @@ -713,8 +713,8 @@ static int setup_intel_arch_watchdog(void) (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) goto fail; - perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; - evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0; + perfctr_msr = MSR_ARCH_PERFMON_PERFCTR1; + evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL1; if (!__reserve_perfctr_nmi(-1, perfctr_msr)) goto fail; @@ -958,7 +958,7 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) /* start the cycle over again */ wrmsrl(wd->perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); - } else if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { + } else if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR1) { /* * ArchPerfom/Core Duo needs to re-unmask * the apic vector -- cgit v1.2.3-59-g8ed1b From e319af1d8722bc3fb61ed6968c88bb66fbb3f58e Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Wed, 2 May 2007 19:27:05 +0200 Subject: [PATCH] i386: Add __init to probe_bigsmp Add __init to probe_bigsmp. All callers are __init and data being examined is __initdata. Resolves MODPOST warning similar to: WARNING: vmlinux - Section mismatch: reference to .init.data: from .text between 'probe_bigsmp' (at offset 0xc0401e56) and 'init_apic_ldr' Signed-off-by: Prarit Bhargava Signed-off-by: Andi Kleen --- arch/i386/mach-generic/bigsmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/mach-generic/bigsmp.c b/arch/i386/mach-generic/bigsmp.c index 8a210fa915b5..e932d3485ae2 100644 --- a/arch/i386/mach-generic/bigsmp.c +++ b/arch/i386/mach-generic/bigsmp.c @@ -45,7 +45,7 @@ static struct dmi_system_id __initdata bigsmp_dmi_table[] = { }; -static int probe_bigsmp(void) +static int __init probe_bigsmp(void) { if (def_to_bigsmp) dmi_bigsmp = 1; -- cgit v1.2.3-59-g8ed1b From 86c0baf123e474b6eb404798926ecf62b426bf3a Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Wed, 2 May 2007 19:27:05 +0200 Subject: [PATCH] i386: Change sysenter_setup to __cpuinit & improve __INIT, __INITDATA Change sysenter_setup to __cpuinit. Change __INIT & __INITDATA to be cpu hotplug aware. Resolve MODPOST warnings similar to: WARNING: vmlinux - Section mismatch: reference to .init.text:sysenter_setup from .text between 'identify_cpu' (at offset 0xc040a380) and 'detect_ht' and WARNING: vmlinux - Section mismatch: reference to .init.data:vsyscall_int80_end from .text between 'sysenter_setup' (at offset 0xc041a269) and 'enable_sep_cpu' WARNING: vmlinux - Section mismatch: reference to .init.data:vsyscall_int80_start from .text between 'sysenter_setup' (at offset 0xc041a26e) and 'enable_sep_cpu' WARNING: vmlinux - Section mismatch: reference to .init.data:vsyscall_sysenter_end from .text between 'sysenter_setup' (at offset 0xc041a275) and 'enable_sep_cpu' WARNING: vmlinux - Section mismatch: reference to .init.data:vsyscall_sysenter_start from .text between 'sysenter_setup' (at offset 0xc041a27a) and 'enable_sep_cpu' Signed-off-by: Prarit Bhargava Signed-off-by: Andi Kleen --- arch/i386/kernel/sysenter.c | 2 +- include/linux/init.h | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c index 13ca54a85a1c..168f8147d3b4 100644 --- a/arch/i386/kernel/sysenter.c +++ b/arch/i386/kernel/sysenter.c @@ -72,7 +72,7 @@ extern const char vsyscall_int80_start, vsyscall_int80_end; extern const char vsyscall_sysenter_start, vsyscall_sysenter_end; static struct page *syscall_pages[1]; -int __init sysenter_setup(void) +int __cpuinit sysenter_setup(void) { void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); syscall_pages[0] = virt_to_page(syscall_page); diff --git a/include/linux/init.h b/include/linux/init.h index e290a010e3f2..9abf120ec9f8 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -52,9 +52,14 @@ #endif /* For assembly routines */ +#ifdef CONFIG_HOTPLUG_CPU +#define __INIT .section ".text","ax" +#define __INITDATA .section ".data","aw" +#else #define __INIT .section ".init.text","ax" -#define __FINIT .previous #define __INITDATA .section ".init.data","aw" +#endif +#define __FINIT .previous #ifndef __ASSEMBLY__ /* -- cgit v1.2.3-59-g8ed1b From d9c93813ac17b34ee6eb7a424578acae6f90d759 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:05 +0200 Subject: [PATCH] x86-64: Correct max number of CPUs in Kconfig Pointed out by Adrian Bunk Signed-off-by: Andi Kleen --- arch/x86_64/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 56eb14c98475..b3dbf11eb82c 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -415,13 +415,13 @@ config OUT_OF_LINE_PFN_TO_PAGE depends on DISCONTIGMEM config NR_CPUS - int "Maximum number of CPUs (2-256)" + int "Maximum number of CPUs (2-255)" range 2 255 depends on SMP default "8" help This allows you to specify the maximum number of CPUs which this - kernel will support. Current maximum is 256 CPUs due to + kernel will support. Current maximum is 255 CPUs due to APIC addressing limits. Less depending on the hardware. This is purely to save memory - each supported CPU requires -- cgit v1.2.3-59-g8ed1b From 2a12652c0335ec90747d3402a82b6699ae883b58 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:06 +0200 Subject: [PATCH] i386: Support Oprofile for AMD Family 10 CPUs Signed-off-by: Andi Kleen --- arch/i386/oprofile/nmi_int.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c index 8fda7be9dd4d..695f737516ae 100644 --- a/arch/i386/oprofile/nmi_int.c +++ b/arch/i386/oprofile/nmi_int.c @@ -414,6 +414,10 @@ int __init op_nmi_init(struct oprofile_operations *ops) user space an consistent name. */ cpu_type = "x86-64/hammer"; break; + case 0x10: + model = &op_athlon_spec; + cpu_type = "x86-64/family10"; + break; } break; -- cgit v1.2.3-59-g8ed1b From c8fdd247255a3a027cd9f66dcf93e6847d1d2f85 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:06 +0200 Subject: [PATCH] x86: Drop cc-options call for all options supported in gcc 3.2+ The kernel only supports gcc 3.2+ now so it doesn't make sense anymore to explicitely check for options this compiler version already has. This actually fixes a bug. The -mprefered-stack-boundary check never worked because gcc rightly complains CC arch/i386/kernel/asm-offsets.s cc1: -mpreferred-stack-boundary=2 is not between 4 and 12 We just never saw the error because of cc-options. I changed it to 4 to actually work. Tested by compiling i386 and x86-64 defconfig with gcc 3.2. Should speed up the build time a tiny bit and improve stack usage on i386 slightly. Signed-off-by: Andi Kleen --- Makefile | 2 +- arch/i386/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/Makefile b/Makefile index d970cb16545a..387526b69d4f 100644 --- a/Makefile +++ b/Makefile @@ -491,7 +491,7 @@ endif include $(srctree)/arch/$(ARCH)/Makefile ifdef CONFIG_FRAME_POINTER -CFLAGS += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,) +CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls else CFLAGS += -fomit-frame-pointer endif diff --git a/arch/i386/Makefile b/arch/i386/Makefile index bd28f9f9b4b7..6dc5e5d90fec 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile @@ -34,7 +34,7 @@ CHECKFLAGS += -D__i386__ CFLAGS += -pipe -msoft-float -mregparm=3 -freg-struct-return # prevent gcc from keeping the stack 16 byte aligned -CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2) +CFLAGS += -mpreferred-stack-boundary=4 # CPU-specific tuning. Anything which can be shared with UML should go here. include $(srctree)/arch/i386/Makefile.cpu -- cgit v1.2.3-59-g8ed1b From 973efae21beb2feda138f152ed06d4204774d93c Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:06 +0200 Subject: [PATCH] i386: clean up mach_reboot_fixups The reboot_fixups stuff seems to be a bit of a mess, specifically the header is in linux/ when its a purely i386-specific piece of code. I'm not sure why it has its config option; its only currently needed for "geode-gx1/cs5530a", so perhaps whatever config option controls that hardware should enable this? Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen --- arch/i386/kernel/reboot.c | 6 +++++- arch/i386/kernel/reboot_fixups.c | 2 +- include/asm-i386/reboot_fixups.h | 6 ++++++ include/linux/reboot_fixups.h | 10 ---------- 4 files changed, 12 insertions(+), 12 deletions(-) create mode 100644 include/asm-i386/reboot_fixups.h delete mode 100644 include/linux/reboot_fixups.h (limited to 'arch') diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c index 3514b4153f7f..8b5ff6e15412 100644 --- a/arch/i386/kernel/reboot.c +++ b/arch/i386/kernel/reboot.c @@ -17,7 +17,7 @@ #include #include #include "mach_reboot.h" -#include +#include /* * Power off function, if any @@ -316,6 +316,10 @@ void machine_shutdown(void) #endif } +void __attribute__((weak)) mach_reboot_fixups(void) +{ +} + void machine_emergency_restart(void) { if (!reboot_thru_bios) { diff --git a/arch/i386/kernel/reboot_fixups.c b/arch/i386/kernel/reboot_fixups.c index 99aab41a05b0..2d78d918340f 100644 --- a/arch/i386/kernel/reboot_fixups.c +++ b/arch/i386/kernel/reboot_fixups.c @@ -10,7 +10,7 @@ #include #include -#include +#include static void cs5530a_warm_reset(struct pci_dev *dev) { diff --git a/include/asm-i386/reboot_fixups.h b/include/asm-i386/reboot_fixups.h new file mode 100644 index 000000000000..0cb7d87c2b68 --- /dev/null +++ b/include/asm-i386/reboot_fixups.h @@ -0,0 +1,6 @@ +#ifndef _LINUX_REBOOT_FIXUPS_H +#define _LINUX_REBOOT_FIXUPS_H + +extern void mach_reboot_fixups(void); + +#endif /* _LINUX_REBOOT_FIXUPS_H */ diff --git a/include/linux/reboot_fixups.h b/include/linux/reboot_fixups.h deleted file mode 100644 index 480ea2d489d8..000000000000 --- a/include/linux/reboot_fixups.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _LINUX_REBOOT_FIXUPS_H -#define _LINUX_REBOOT_FIXUPS_H - -#ifdef CONFIG_X86_REBOOTFIXUPS -extern void mach_reboot_fixups(void); -#else -#define mach_reboot_fixups() ((void)(0)) -#endif - -#endif /* _LINUX_REBOOT_FIXUPS_H */ -- cgit v1.2.3-59-g8ed1b From b0b1ff653a0ce88dc9d5cec4e67c9c2be0ba03ef Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Wed, 2 May 2007 19:27:06 +0200 Subject: [PATCH] i386: Fix usage of -mtune when X86_GENERIC=y or CONFIG_MCORE2=y Hi! I sent this simple patch to lkml about two weeks ago and also cc'ed to Linus, but seems that the patch got ignored. I decided to write to you, because you have modified the relevant file most recently. Below is a copy of the mail that is also available at . Signed-off-by: Andi Kleen --- arch/i386/Makefile.cpu | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/i386/Makefile.cpu b/arch/i386/Makefile.cpu index e0ada4e9e137..e372b584e919 100644 --- a/arch/i386/Makefile.cpu +++ b/arch/i386/Makefile.cpu @@ -4,9 +4,9 @@ #-mtune exists since gcc 3.4 HAS_MTUNE := $(call cc-option-yn, -mtune=i386) ifeq ($(HAS_MTUNE),y) -tune = $(call cc-option,-mtune=$(1),) +tune = $(call cc-option,-mtune=$(1),$(2)) else -tune = $(call cc-option,-mcpu=$(1),) +tune = $(call cc-option,-mcpu=$(1),$(2)) endif align := $(cc-option-align) @@ -33,7 +33,7 @@ cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586) cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) cflags-$(CONFIG_MVIAC7) += -march=i686 -cflags-$(CONFIG_MCORE2) += -march=i686 $(call cc-option,-mtune=core2,$(call cc-option,-mtune=generic,-mtune=i686)) +cflags-$(CONFIG_MCORE2) += -march=i686 $(call tune,core2) # AMD Elan support cflags-$(CONFIG_X86_ELAN) += -march=i486 @@ -43,5 +43,5 @@ cflags-$(CONFIG_MGEODEGX1) += -march=pentium-mmx # add at the end to overwrite eventual tuning options from earlier # cpu entries -cflags-$(CONFIG_X86_GENERIC) += $(call tune,generic) +cflags-$(CONFIG_X86_GENERIC) += $(call tune,generic,$(call tune,i686)) -- cgit v1.2.3-59-g8ed1b From 6b37f5a20c0e5c334c010a587058354215433e92 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 2 May 2007 19:27:06 +0200 Subject: [PATCH] x86-64: fix cpu MHz reporting on constant_tsc cpus This patch fixes the reporting of cpu_mhz in /proc/cpuinfo on CPUs with a constant TSC rate and a kernel with disabled cpufreq. Signed-off-by: Mark Langsdorf Signed-off-by: Joerg Roedel Signed-off-by: Andi Kleen arch/x86_64/kernel/apic.c | 2 - arch/x86_64/kernel/time.c | 58 +++++++++++++++++++++++++++++++++++++++--- arch/x86_64/kernel/tsc.c | 12 +++++--- arch/x86_64/kernel/tsc_sync.c | 2 - include/asm-x86_64/proto.h | 1 5 files changed, 65 insertions(+), 10 deletions(-) --- arch/x86_64/kernel/apic.c | 2 +- arch/x86_64/kernel/time.c | 58 ++++++++++++++++++++++++++++++++++++++++--- arch/x86_64/kernel/tsc.c | 12 +++++---- arch/x86_64/kernel/tsc_sync.c | 2 +- include/asm-x86_64/proto.h | 1 + 5 files changed, 65 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index bd3e45d47c37..3421f21b6c70 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c @@ -843,7 +843,7 @@ static int __init calibrate_APIC_clock(void) } while ((tsc - tsc_start) < TICK_COUNT && (apic - apic_start) < TICK_COUNT); - result = (apic_start - apic) * 1000L * cpu_khz / + result = (apic_start - apic) * 1000L * tsc_khz / (tsc - tsc_start); } printk("result %d\n", result); diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 811b8f987b50..5f862e216a42 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -43,6 +43,7 @@ #include #include #include +#include static char *timename = NULL; @@ -249,6 +250,51 @@ static unsigned long get_cmos_time(void) return mktime(year, mon, day, hour, min, sec); } +/* calibrate_cpu is used on systems with fixed rate TSCs to determine + * processor frequency */ +#define TICK_COUNT 100000000 +static unsigned int __init tsc_calibrate_cpu_khz(void) +{ + int tsc_start, tsc_now; + int i, no_ctr_free; + unsigned long evntsel3 = 0, pmc3 = 0, pmc_now = 0; + unsigned long flags; + + for (i = 0; i < 4; i++) + if (avail_to_resrv_perfctr_nmi_bit(i)) + break; + no_ctr_free = (i == 4); + if (no_ctr_free) { + i = 3; + rdmsrl(MSR_K7_EVNTSEL3, evntsel3); + wrmsrl(MSR_K7_EVNTSEL3, 0); + rdmsrl(MSR_K7_PERFCTR3, pmc3); + } else { + reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i); + reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i); + } + local_irq_save(flags); + /* start meauring cycles, incrementing from 0 */ + wrmsrl(MSR_K7_PERFCTR0 + i, 0); + wrmsrl(MSR_K7_EVNTSEL0 + i, 1 << 22 | 3 << 16 | 0x76); + rdtscl(tsc_start); + do { + rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now); + tsc_now = get_cycles_sync(); + } while ((tsc_now - tsc_start) < TICK_COUNT); + + local_irq_restore(flags); + if (no_ctr_free) { + wrmsrl(MSR_K7_EVNTSEL3, 0); + wrmsrl(MSR_K7_PERFCTR3, pmc3); + wrmsrl(MSR_K7_EVNTSEL3, evntsel3); + } else { + release_perfctr_nmi(MSR_K7_PERFCTR0 + i); + release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); + } + + return pmc_now * tsc_khz / (tsc_now - tsc_start); +} /* * pit_calibrate_tsc() uses the speaker output (channel 2) of @@ -336,14 +382,20 @@ void __init time_init(void) if (hpet_use_timer) { /* set tick_nsec to use the proper rate for HPET */ tick_nsec = TICK_NSEC_HPET; - cpu_khz = hpet_calibrate_tsc(); + tsc_khz = hpet_calibrate_tsc(); timename = "HPET"; } else { pit_init(); - cpu_khz = pit_calibrate_tsc(); + tsc_khz = pit_calibrate_tsc(); timename = "PIT"; } + cpu_khz = tsc_khz; + if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) && + boot_cpu_data.x86_vendor == X86_VENDOR_AMD && + boot_cpu_data.x86 == 16) + cpu_khz = tsc_calibrate_cpu_khz(); + if (unsynchronized_tsc()) mark_tsc_unstable(); @@ -352,7 +404,7 @@ void __init time_init(void) else vgetcpu_mode = VGETCPU_LSL; - set_cyc2ns_scale(cpu_khz); + set_cyc2ns_scale(tsc_khz); printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000); init_tsc_clocksource(); diff --git a/arch/x86_64/kernel/tsc.c b/arch/x86_64/kernel/tsc.c index 1a0edbbffaa0..5c84992c676d 100644 --- a/arch/x86_64/kernel/tsc.c +++ b/arch/x86_64/kernel/tsc.c @@ -13,6 +13,8 @@ static int notsc __initdata = 0; unsigned int cpu_khz; /* TSC clocks / usec, not used here */ EXPORT_SYMBOL(cpu_khz); +unsigned int tsc_khz; +EXPORT_SYMBOL(tsc_khz); static unsigned int cyc2ns_scale __read_mostly; @@ -77,7 +79,7 @@ static void handle_cpufreq_delayed_get(struct work_struct *v) static unsigned int ref_freq = 0; static unsigned long loops_per_jiffy_ref = 0; -static unsigned long cpu_khz_ref = 0; +static unsigned long tsc_khz_ref = 0; static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) @@ -99,7 +101,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, if (!ref_freq) { ref_freq = freq->old; loops_per_jiffy_ref = *lpj; - cpu_khz_ref = cpu_khz; + tsc_khz_ref = tsc_khz; } if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) || @@ -107,12 +109,12 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, *lpj = cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new); - cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new); + tsc_khz = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new); if (!(freq->flags & CPUFREQ_CONST_LOOPS)) mark_tsc_unstable(); } - set_cyc2ns_scale(cpu_khz_ref); + set_cyc2ns_scale(tsc_khz_ref); return 0; } @@ -213,7 +215,7 @@ EXPORT_SYMBOL_GPL(mark_tsc_unstable); void __init init_tsc_clocksource(void) { if (!notsc) { - clocksource_tsc.mult = clocksource_khz2mult(cpu_khz, + clocksource_tsc.mult = clocksource_khz2mult(tsc_khz, clocksource_tsc.shift); if (check_tsc_unstable()) clocksource_tsc.rating = 0; diff --git a/arch/x86_64/kernel/tsc_sync.c b/arch/x86_64/kernel/tsc_sync.c index 014f0db45dfa..72d444dede9b 100644 --- a/arch/x86_64/kernel/tsc_sync.c +++ b/arch/x86_64/kernel/tsc_sync.c @@ -50,7 +50,7 @@ static __cpuinit void check_tsc_warp(void) /* * The measurement runs for 20 msecs: */ - end = start + cpu_khz * 20ULL; + end = start + tsc_khz * 20ULL; now = start; for (i = 0; ; i++) { diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index f64949fae61a..78427021d94a 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h @@ -92,6 +92,7 @@ extern unsigned long table_start, table_end; extern int exception_trace; extern unsigned cpu_khz; +extern unsigned tsc_khz; extern void no_iommu_init(void); extern int force_iommu, no_iommu; -- cgit v1.2.3-59-g8ed1b From 19d1743315099665db4ce02c9942507a5ee1deea Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:06 +0200 Subject: [PATCH] i386: Simplify smp_call_function*() by using common implementation smp_call_function and smp_call_function_single are almost complete duplicates of the same logic. This patch combines them by implementing them in terms of the more general smp_call_function_mask(). Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Stephane Eranian Cc: Andrew Morton Cc: Andi Kleen Cc: "Randy.Dunlap" Cc: Ingo Molnar --- arch/i386/kernel/smp.c | 173 +++++++++++++++++++++++++++---------------------- 1 file changed, 96 insertions(+), 77 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 0cd459baad68..b90bebeb1c79 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -546,34 +546,124 @@ static void __smp_call_function(void (*func) (void *info), void *info, cpu_relax(); } + /** - * smp_call_function(): Run a function on all other CPUs. + * smp_call_function_mask(): Run a function on a set of other CPUs. + * @mask: The set of cpus to run on. Must not include the current cpu. * @func: The function to run. This must be fast and non-blocking. * @info: An arbitrary pointer to pass to the function. - * @nonatomic: currently unused. * @wait: If true, wait (atomically) until function has completed on other CPUs. * * Returns 0 on success, else a negative status code. Does not return until - * remote CPUs are nearly ready to execute <> or are or have executed. + * remote CPUs are nearly ready to execute <> or are or have finished. * * You must not call this function with disabled interrupts or from a * hardware interrupt handler or from a bottom half handler. */ -int smp_call_function (void (*func) (void *info), void *info, int nonatomic, - int wait) +int smp_call_function_mask(cpumask_t mask, + void (*func)(void *), void *info, + int wait) { + struct call_data_struct data; + cpumask_t allbutself; + int cpus; + /* Can deadlock when called with interrupts disabled */ WARN_ON(irqs_disabled()); /* Holding any lock stops cpus from going down. */ spin_lock(&call_lock); - __smp_call_function(func, info, nonatomic, wait); + + allbutself = cpu_online_map; + cpu_clear(smp_processor_id(), allbutself); + + cpus_and(mask, mask, allbutself); + cpus = cpus_weight(mask); + + if (!cpus) { + spin_unlock(&call_lock); + return 0; + } + + data.func = func; + data.info = info; + atomic_set(&data.started, 0); + data.wait = wait; + if (wait) + atomic_set(&data.finished, 0); + + call_data = &data; + mb(); + + /* Send a message to other CPUs */ + if (cpus_equal(mask, allbutself)) + send_IPI_allbutself(CALL_FUNCTION_VECTOR); + else + send_IPI_mask(mask, CALL_FUNCTION_VECTOR); + + /* Wait for response */ + while (atomic_read(&data.started) != cpus) + cpu_relax(); + + if (wait) + while (atomic_read(&data.finished) != cpus) + cpu_relax(); spin_unlock(&call_lock); return 0; } + +/** + * smp_call_function(): Run a function on all other CPUs. + * @func: The function to run. This must be fast and non-blocking. + * @info: An arbitrary pointer to pass to the function. + * @nonatomic: currently unused. + * @wait: If true, wait (atomically) until function has completed on other CPUs. + * + * Returns 0 on success, else a negative status code. Does not return until + * remote CPUs are nearly ready to execute <> or are or have executed. + * + * You must not call this function with disabled interrupts or from a + * hardware interrupt handler or from a bottom half handler. + */ +int smp_call_function(void (*func) (void *info), void *info, int nonatomic, + int wait) +{ + return smp_call_function_mask(cpu_online_map, func, info, wait); +} EXPORT_SYMBOL(smp_call_function); +/* + * smp_call_function_single - Run a function on another CPU + * @func: The function to run. This must be fast and non-blocking. + * @info: An arbitrary pointer to pass to the function. + * @nonatomic: Currently unused. + * @wait: If true, wait until function has completed on other CPUs. + * + * Retrurns 0 on success, else a negative status code. + * + * Does not return until the remote CPU is nearly ready to execute + * or is or has executed. + */ +int smp_call_function_single(int cpu, void (*func) (void *info), void *info, + int nonatomic, int wait) +{ + /* prevent preemption and reschedule on another processor */ + int ret; + int me = get_cpu(); + if (cpu == me) { + WARN_ON(1); + put_cpu(); + return -EBUSY; + } + + ret = smp_call_function_mask(cpumask_of_cpu(cpu), func, info, wait); + + put_cpu(); + return ret; +} +EXPORT_SYMBOL(smp_call_function_single); + static void stop_this_cpu (void * dummy) { local_irq_disable(); @@ -641,77 +731,6 @@ fastcall void smp_call_function_interrupt(struct pt_regs *regs) } } -/* - * this function sends a 'generic call function' IPI to one other CPU - * in the system. - * - * cpu is a standard Linux logical CPU number. - */ -static void -__smp_call_function_single(int cpu, void (*func) (void *info), void *info, - int nonatomic, int wait) -{ - struct call_data_struct data; - int cpus = 1; - - data.func = func; - data.info = info; - atomic_set(&data.started, 0); - data.wait = wait; - if (wait) - atomic_set(&data.finished, 0); - - call_data = &data; - wmb(); - /* Send a message to all other CPUs and wait for them to respond */ - send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNCTION_VECTOR); - - /* Wait for response */ - while (atomic_read(&data.started) != cpus) - cpu_relax(); - - if (!wait) - return; - - while (atomic_read(&data.finished) != cpus) - cpu_relax(); -} - -/* - * smp_call_function_single - Run a function on another CPU - * @func: The function to run. This must be fast and non-blocking. - * @info: An arbitrary pointer to pass to the function. - * @nonatomic: Currently unused. - * @wait: If true, wait until function has completed on other CPUs. - * - * Retrurns 0 on success, else a negative status code. - * - * Does not return until the remote CPU is nearly ready to execute - * or is or has executed. - */ - -int smp_call_function_single(int cpu, void (*func) (void *info), void *info, - int nonatomic, int wait) -{ - /* prevent preemption and reschedule on another processor */ - int me = get_cpu(); - if (cpu == me) { - WARN_ON(1); - put_cpu(); - return -EBUSY; - } - - /* Can deadlock when called with interrupts disabled */ - WARN_ON(irqs_disabled()); - - spin_lock_bh(&call_lock); - __smp_call_function_single(cpu, func, info, nonatomic, wait); - spin_unlock_bh(&call_lock); - put_cpu(); - return 0; -} -EXPORT_SYMBOL(smp_call_function_single); - static int convert_apicid_to_cpu(int apic_id) { int i; -- cgit v1.2.3-59-g8ed1b From e65845045588806fa5c8df8a4f4253516515a5e3 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 2 May 2007 19:27:06 +0200 Subject: [PATCH] x86-64: dma_ops as const The dma_ops structure can be const since it never changes after boot. Signed-off-by: Stephen Hemminger Signed-off-by: Andi Kleen --- arch/x86_64/kernel/pci-calgary.c | 2 +- arch/x86_64/kernel/pci-gart.c | 2 +- arch/x86_64/kernel/pci-nommu.c | 2 +- arch/x86_64/kernel/pci-swiotlb.c | 2 +- arch/x86_64/mm/init.c | 2 +- include/asm-x86_64/dma-mapping.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index 04480c3b68f5..5bd20b542c1e 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c @@ -507,7 +507,7 @@ error: return ret; } -static struct dma_mapping_ops calgary_dma_ops = { +static const struct dma_mapping_ops calgary_dma_ops = { .alloc_coherent = calgary_alloc_coherent, .map_single = calgary_map_single, .unmap_single = calgary_unmap_single, diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c index 0bae862e9a55..0a762e10f2be 100644 --- a/arch/x86_64/kernel/pci-gart.c +++ b/arch/x86_64/kernel/pci-gart.c @@ -556,7 +556,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info) extern int agp_amd64_init(void); -static struct dma_mapping_ops gart_dma_ops = { +static const struct dma_mapping_ops gart_dma_ops = { .mapping_error = NULL, .map_single = gart_map_single, .map_simple = gart_map_simple, diff --git a/arch/x86_64/kernel/pci-nommu.c b/arch/x86_64/kernel/pci-nommu.c index df09ab05a1bd..6dade0c867cc 100644 --- a/arch/x86_64/kernel/pci-nommu.c +++ b/arch/x86_64/kernel/pci-nommu.c @@ -79,7 +79,7 @@ void nommu_unmap_sg(struct device *dev, struct scatterlist *sg, { } -struct dma_mapping_ops nommu_dma_ops = { +const struct dma_mapping_ops nommu_dma_ops = { .map_single = nommu_map_single, .unmap_single = nommu_unmap_single, .map_sg = nommu_map_sg, diff --git a/arch/x86_64/kernel/pci-swiotlb.c b/arch/x86_64/kernel/pci-swiotlb.c index eb18be5a6569..4b4569abc60c 100644 --- a/arch/x86_64/kernel/pci-swiotlb.c +++ b/arch/x86_64/kernel/pci-swiotlb.c @@ -12,7 +12,7 @@ int swiotlb __read_mostly; EXPORT_SYMBOL(swiotlb); -struct dma_mapping_ops swiotlb_dma_ops = { +const struct dma_mapping_ops swiotlb_dma_ops = { .mapping_error = swiotlb_dma_mapping_error, .alloc_coherent = swiotlb_alloc_coherent, .free_coherent = swiotlb_free_coherent, diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index ec31534eb104..5ca61731f550 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -46,7 +46,7 @@ #define Dprintk(x...) #endif -struct dma_mapping_ops* dma_ops; +const struct dma_mapping_ops* dma_ops; EXPORT_SYMBOL(dma_ops); static unsigned long dma_reserve __initdata; diff --git a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h index d2af227f06d0..6897e2a436e5 100644 --- a/include/asm-x86_64/dma-mapping.h +++ b/include/asm-x86_64/dma-mapping.h @@ -52,7 +52,7 @@ struct dma_mapping_ops { }; extern dma_addr_t bad_dma_address; -extern struct dma_mapping_ops* dma_ops; +extern const struct dma_mapping_ops* dma_ops; extern int iommu_merge; static inline int dma_mapping_error(dma_addr_t dma_addr) -- cgit v1.2.3-59-g8ed1b From dafe41ee3a9389c08c91cdfd8670295f20f89e04 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:06 +0200 Subject: [PATCH] x86-64: Kill temp boot pmds Early in the boot process we need the ability to set up temporary mappings, before our normal mechanisms are initialized. Currently this is used to map pages that are part of the page tables we are building and pages during the dmi scan. The core problem is that we are using the user portion of the page tables to implement this. Which means that while this mechanism is active we cannot catch NULL pointer dereferences and we deviate from the normal ways of handling things. In this patch I modify early_ioremap to map pages into the kernel portion of address space, roughly where we will later put modules, and I make the discovery of which addresses we can use dynamic which removes all kinds of static limits and remove the dependencies on implementation details between different parts of the code. Now alloc_low_page() and unmap_low_page() use early_iomap() and early_iounmap() to allocate/map and unmap a page. Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/kernel/head.S | 3 -- arch/x86_64/mm/init.c | 100 +++++++++++++++++++++------------------------- 2 files changed, 45 insertions(+), 58 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 598a4d0351fc..118c6088198a 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S @@ -288,9 +288,6 @@ NEXT_PAGE(level2_ident_pgt) .quad i << 21 | 0x083 i = i + 1 .endr - /* Temporary mappings for the super early allocator in arch/x86_64/mm/init.c */ - .globl temp_boot_pmds -temp_boot_pmds: .fill 492,8,0 NEXT_PAGE(level2_kernel_pgt) diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 5ca61731f550..4ab3d40aac90 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -167,23 +167,9 @@ __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t prot) unsigned long __initdata table_start, table_end; -extern pmd_t temp_boot_pmds[]; - -static struct temp_map { - pmd_t *pmd; - void *address; - int allocated; -} temp_mappings[] __initdata = { - { &temp_boot_pmds[0], (void *)(40UL * 1024 * 1024) }, - { &temp_boot_pmds[1], (void *)(42UL * 1024 * 1024) }, - {} -}; - -static __meminit void *alloc_low_page(int *index, unsigned long *phys) +static __meminit void *alloc_low_page(unsigned long *phys) { - struct temp_map *ti; - int i; - unsigned long pfn = table_end++, paddr; + unsigned long pfn = table_end++; void *adr; if (after_bootmem) { @@ -194,57 +180,63 @@ static __meminit void *alloc_low_page(int *index, unsigned long *phys) if (pfn >= end_pfn) panic("alloc_low_page: ran out of memory"); - for (i = 0; temp_mappings[i].allocated; i++) { - if (!temp_mappings[i].pmd) - panic("alloc_low_page: ran out of temp mappings"); - } - ti = &temp_mappings[i]; - paddr = (pfn << PAGE_SHIFT) & PMD_MASK; - set_pmd(ti->pmd, __pmd(paddr | _KERNPG_TABLE | _PAGE_PSE)); - ti->allocated = 1; - __flush_tlb(); - adr = ti->address + ((pfn << PAGE_SHIFT) & ~PMD_MASK); + + adr = early_ioremap(pfn * PAGE_SIZE, PAGE_SIZE); memset(adr, 0, PAGE_SIZE); - *index = i; - *phys = pfn * PAGE_SIZE; - return adr; -} + *phys = pfn * PAGE_SIZE; + return adr; +} -static __meminit void unmap_low_page(int i) +static __meminit void unmap_low_page(void *adr) { - struct temp_map *ti; if (after_bootmem) return; - ti = &temp_mappings[i]; - set_pmd(ti->pmd, __pmd(0)); - ti->allocated = 0; + early_iounmap(adr, PAGE_SIZE); } /* Must run before zap_low_mappings */ __init void *early_ioremap(unsigned long addr, unsigned long size) { - unsigned long map = round_down(addr, LARGE_PAGE_SIZE); - - /* actually usually some more */ - if (size >= LARGE_PAGE_SIZE) { - return NULL; + unsigned long vaddr; + pmd_t *pmd, *last_pmd; + int i, pmds; + + pmds = ((addr & ~PMD_MASK) + size + ~PMD_MASK) / PMD_SIZE; + vaddr = __START_KERNEL_map; + pmd = level2_kernel_pgt; + last_pmd = level2_kernel_pgt + PTRS_PER_PMD - 1; + for (; pmd <= last_pmd; pmd++, vaddr += PMD_SIZE) { + for (i = 0; i < pmds; i++) { + if (pmd_present(pmd[i])) + goto next; + } + vaddr += addr & ~PMD_MASK; + addr &= PMD_MASK; + for (i = 0; i < pmds; i++, addr += PMD_SIZE) + set_pmd(pmd + i,__pmd(addr | _KERNPG_TABLE | _PAGE_PSE)); + __flush_tlb(); + return (void *)vaddr; + next: + ; } - set_pmd(temp_mappings[0].pmd, __pmd(map | _KERNPG_TABLE | _PAGE_PSE)); - map += LARGE_PAGE_SIZE; - set_pmd(temp_mappings[1].pmd, __pmd(map | _KERNPG_TABLE | _PAGE_PSE)); - __flush_tlb(); - return temp_mappings[0].address + (addr & (LARGE_PAGE_SIZE-1)); + printk("early_ioremap(0x%lx, %lu) failed\n", addr, size); + return NULL; } /* To avoid virtual aliases later */ __init void early_iounmap(void *addr, unsigned long size) { - if ((void *)round_down((unsigned long)addr, LARGE_PAGE_SIZE) != temp_mappings[0].address) - printk("early_iounmap: bad address %p\n", addr); - set_pmd(temp_mappings[0].pmd, __pmd(0)); - set_pmd(temp_mappings[1].pmd, __pmd(0)); + unsigned long vaddr; + pmd_t *pmd; + int i, pmds; + + vaddr = (unsigned long)addr; + pmds = ((vaddr & ~PMD_MASK) + size + ~PMD_MASK) / PMD_SIZE; + pmd = level2_kernel_pgt + pmd_index(vaddr); + for (i = 0; i < pmds; i++) + pmd_clear(pmd + i); __flush_tlb(); } @@ -289,7 +281,6 @@ static void __meminit phys_pud_init(pud_t *pud_page, unsigned long addr, unsigne for (; i < PTRS_PER_PUD; i++, addr = (addr & PUD_MASK) + PUD_SIZE ) { - int map; unsigned long pmd_phys; pud_t *pud = pud_page + pud_index(addr); pmd_t *pmd; @@ -307,12 +298,12 @@ static void __meminit phys_pud_init(pud_t *pud_page, unsigned long addr, unsigne continue; } - pmd = alloc_low_page(&map, &pmd_phys); + pmd = alloc_low_page(&pmd_phys); spin_lock(&init_mm.page_table_lock); set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE)); phys_pmd_init(pmd, addr, end); spin_unlock(&init_mm.page_table_lock); - unmap_low_page(map); + unmap_low_page(pmd); } __flush_tlb(); } @@ -364,7 +355,6 @@ void __meminit init_memory_mapping(unsigned long start, unsigned long end) end = (unsigned long)__va(end); for (; start < end; start = next) { - int map; unsigned long pud_phys; pgd_t *pgd = pgd_offset_k(start); pud_t *pud; @@ -372,7 +362,7 @@ void __meminit init_memory_mapping(unsigned long start, unsigned long end) if (after_bootmem) pud = pud_offset(pgd, start & PGDIR_MASK); else - pud = alloc_low_page(&map, &pud_phys); + pud = alloc_low_page(&pud_phys); next = start + PGDIR_SIZE; if (next > end) @@ -380,7 +370,7 @@ void __meminit init_memory_mapping(unsigned long start, unsigned long end) phys_pud_init(pud, __pa(start), __pa(next)); if (!after_bootmem) set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys)); - unmap_low_page(map); + unmap_low_page(pud); } if (!after_bootmem) -- cgit v1.2.3-59-g8ed1b From 67dcbb6bc6537aea92a2466bfc75f015b00e465e Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:06 +0200 Subject: [PATCH] x86-64: Clean up the early boot page table - Merge physmem_pgt and ident_pgt, removing physmem_pgt. The merge is broken as soon as mm/init.c:init_memory_mapping is run. - As physmem_pgt is gone don't export it in pgtable.h. - Use defines from pgtable.h for page permissions. - Fix the physical memory identity mapping so it is at the correct address. - Remove the physical memory mapping from wakeup_level4_pgt it is at the wrong address so we can't possibly be usinging it. - Simply NEXT_PAGE the work to calculate the phys_ alias of the labels was very cool. Unfortuantely it was a brittle special purpose hack that makes maitenance more difficult. Instead just use label - __START_KERNEL_map like we do everywhere else in assembly. Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/kernel/head.S | 61 ++++++++++++++++++++------------------------ include/asm-x86_64/pgtable.h | 1 - 2 files changed, 28 insertions(+), 34 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 118c6088198a..23b45e79a27c 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -260,52 +261,48 @@ ljumpvector: ENTRY(stext) ENTRY(_stext) - $page = 0 #define NEXT_PAGE(name) \ - $page = $page + 1; \ - .org $page * 0x1000; \ - phys_/**/name = $page * 0x1000 + __PHYSICAL_START; \ + .balign PAGE_SIZE; \ ENTRY(name) +/* Automate the creation of 1 to 1 mapping pmd entries */ +#define PMDS(START, PERM, COUNT) \ + i = 0 ; \ + .rept (COUNT) ; \ + .quad (START) + (i << 21) + (PERM) ; \ + i = i + 1 ; \ + .endr + NEXT_PAGE(init_level4_pgt) /* This gets initialized in x86_64_start_kernel */ .fill 512,8,0 NEXT_PAGE(level3_ident_pgt) - .quad phys_level2_ident_pgt | 0x007 + .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE .fill 511,8,0 NEXT_PAGE(level3_kernel_pgt) .fill 510,8,0 /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */ - .quad phys_level2_kernel_pgt | 0x007 + .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE .fill 1,8,0 NEXT_PAGE(level2_ident_pgt) - /* 40MB for bootup. */ - i = 0 - .rept 20 - .quad i << 21 | 0x083 - i = i + 1 - .endr - .fill 492,8,0 + /* Since I easily can, map the first 1G. + * Don't set NX because code runs from these pages. + */ + PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC, PTRS_PER_PMD) NEXT_PAGE(level2_kernel_pgt) /* 40MB kernel mapping. The kernel code cannot be bigger than that. When you change this change KERNEL_TEXT_SIZE in page.h too. */ /* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */ - i = 0 - .rept 20 - .quad i << 21 | 0x183 - i = i + 1 - .endr + PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, + KERNEL_TEXT_SIZE/PMD_SIZE) /* Module mapping starts here */ - .fill 492,8,0 - -NEXT_PAGE(level3_physmem_pgt) - .quad phys_level2_kernel_pgt | 0x007 /* so that __va works even before pagetable_init */ - .fill 511,8,0 + .fill (PTRS_PER_PMD - (KERNEL_TEXT_SIZE/PMD_SIZE)),8,0 +#undef PMDS #undef NEXT_PAGE .data @@ -313,12 +310,10 @@ NEXT_PAGE(level3_physmem_pgt) #ifdef CONFIG_ACPI_SLEEP .align PAGE_SIZE ENTRY(wakeup_level4_pgt) - .quad phys_level3_ident_pgt | 0x007 - .fill 255,8,0 - .quad phys_level3_physmem_pgt | 0x007 - .fill 254,8,0 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .fill 510,8,0 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ - .quad phys_level3_kernel_pgt | 0x007 + .quad level3_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE #endif #ifndef CONFIG_HOTPLUG_CPU @@ -332,12 +327,12 @@ ENTRY(wakeup_level4_pgt) */ .align PAGE_SIZE ENTRY(boot_level4_pgt) - .quad phys_level3_ident_pgt | 0x007 - .fill 255,8,0 - .quad phys_level3_physmem_pgt | 0x007 - .fill 254,8,0 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .fill 257,8,0 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .fill 252,8,0 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ - .quad phys_level3_kernel_pgt | 0x007 + .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE .data diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h index c514deb658a3..5a5d43b3ef5d 100644 --- a/include/asm-x86_64/pgtable.h +++ b/include/asm-x86_64/pgtable.h @@ -14,7 +14,6 @@ #include extern pud_t level3_kernel_pgt[512]; -extern pud_t level3_physmem_pgt[512]; extern pud_t level3_ident_pgt[512]; extern pmd_t level2_kernel_pgt[512]; extern pgd_t init_level4_pgt[]; -- cgit v1.2.3-59-g8ed1b From 93fd755e47d7b00fa5470199cfb14cbd9ded0284 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:06 +0200 Subject: [PATCH] x86-64: Fix early printk to use standard ISA mapping Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/kernel/early_printk.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c index 47b6d90349da..b7aa9abe1c6a 100644 --- a/arch/x86_64/kernel/early_printk.c +++ b/arch/x86_64/kernel/early_printk.c @@ -11,11 +11,10 @@ #ifdef __i386__ #include -#define VGABASE (__ISA_IO_base + 0xb8000) #else #include -#define VGABASE ((void __iomem *)0xffffffff800b8000UL) #endif +#define VGABASE (__ISA_IO_base + 0xb8000) static int max_ypos = 25, max_xpos = 80; static int current_ypos = 25, current_xpos = 0; -- cgit v1.2.3-59-g8ed1b From 278c0eb7f96586c02b2bfaa8e250d951919a2e6a Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:07 +0200 Subject: [PATCH] x86-64: modify copy_bootdata to use virtual addresses Use virtual addresses instead of physical addresses in copy bootdata. In addition fix the implementation of the old bootloader convention. Everything is at real_mode_data always. It is just that sometimes real_mode_data was relocated by setup.S to not sit at 0x90000. Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/kernel/head64.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c index 5f197b0a330a..5c529c1e3d6c 100644 --- a/arch/x86_64/kernel/head64.c +++ b/arch/x86_64/kernel/head64.c @@ -29,25 +29,24 @@ static void __init clear_bss(void) } #define NEW_CL_POINTER 0x228 /* Relative to real mode data */ -#define OLD_CL_MAGIC_ADDR 0x90020 +#define OLD_CL_MAGIC_ADDR 0x20 #define OLD_CL_MAGIC 0xA33F -#define OLD_CL_BASE_ADDR 0x90000 -#define OLD_CL_OFFSET 0x90022 +#define OLD_CL_OFFSET 0x22 static void __init copy_bootdata(char *real_mode_data) { - int new_data; + unsigned long new_data; char * command_line; memcpy(x86_boot_params, real_mode_data, BOOT_PARAM_SIZE); - new_data = *(int *) (x86_boot_params + NEW_CL_POINTER); + new_data = *(u32 *) (x86_boot_params + NEW_CL_POINTER); if (!new_data) { - if (OLD_CL_MAGIC != * (u16 *) OLD_CL_MAGIC_ADDR) { + if (OLD_CL_MAGIC != *(u16 *)(real_mode_data + OLD_CL_MAGIC_ADDR)) { return; } - new_data = OLD_CL_BASE_ADDR + * (u16 *) OLD_CL_OFFSET; + new_data = __pa(real_mode_data) + *(u16 *)(real_mode_data + OLD_CL_OFFSET); } - command_line = (char *) ((u64)(new_data)); + command_line = __va(new_data); memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); } @@ -74,7 +73,7 @@ void __init x86_64_start_kernel(char * real_mode_data) cpu_pda(i) = &boot_cpu_pda[i]; pda_init(0); - copy_bootdata(real_mode_data); + copy_bootdata(__va(real_mode_data)); #ifdef CONFIG_SMP cpu_set(0, cpu_online_map); #endif -- cgit v1.2.3-59-g8ed1b From 30f472895401fbe8e64f861a2569bc9acb098741 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:07 +0200 Subject: [PATCH] x86-64: cleanup segments Move __KERNEL32_CS up into the unused gdt entry. __KERNEL32_CS is used when entering the kernel so putting it first is useful when trying to keep boot gdt sizes to a minimum. Set the accessed bit on all gdt entries. We don't care so there is no need for the cpu to burn the extra cycles, and it potentially allows the pages to be immutable. Plus it is confusing when debugging and your gdt entries mysteriously change. Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/kernel/head.S | 12 ++++++------ include/asm-x86_64/segment.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 23b45e79a27c..2b2e2c51e532 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S @@ -362,13 +362,13 @@ gdt: ENTRY(cpu_gdt_table) .quad 0x0000000000000000 /* NULL descriptor */ + .quad 0x00cf9b000000ffff /* __KERNEL32_CS */ + .quad 0x00af9b000000ffff /* __KERNEL_CS */ + .quad 0x00cf93000000ffff /* __KERNEL_DS */ + .quad 0x00cffb000000ffff /* __USER32_CS */ + .quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */ + .quad 0x00affb000000ffff /* __USER_CS */ .quad 0x0 /* unused */ - .quad 0x00af9a000000ffff /* __KERNEL_CS */ - .quad 0x00cf92000000ffff /* __KERNEL_DS */ - .quad 0x00cffa000000ffff /* __USER32_CS */ - .quad 0x00cff2000000ffff /* __USER_DS, __USER32_DS */ - .quad 0x00affa000000ffff /* __USER_CS */ - .quad 0x00cf9a000000ffff /* __KERNEL32_CS */ .quad 0,0 /* TSS */ .quad 0,0 /* LDT */ .quad 0,0,0 /* three TLS descriptors */ diff --git a/include/asm-x86_64/segment.h b/include/asm-x86_64/segment.h index 334ddcdd8f92..adf2bf1e187c 100644 --- a/include/asm-x86_64/segment.h +++ b/include/asm-x86_64/segment.h @@ -6,7 +6,7 @@ #define __KERNEL_CS 0x10 #define __KERNEL_DS 0x18 -#define __KERNEL32_CS 0x38 +#define __KERNEL32_CS 0x08 /* * we cannot use the same code segment descriptor for user and kernel -- cgit v1.2.3-59-g8ed1b From 3c321bceb4a626639ab43a5a24d884930e511826 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:07 +0200 Subject: [PATCH] x86-64: Add EFER to the register set saved by save_processor_state EFER varies like %cr4 depending on the cpu capabilities, and which cpu capabilities we want to make use of. So save/restore it make certain we have the same EFER value when we are done. Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/kernel/suspend.c | 3 ++- include/asm-x86_64/suspend.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c index 91f7e678bae7..fe865ea4df52 100644 --- a/arch/x86_64/kernel/suspend.c +++ b/arch/x86_64/kernel/suspend.c @@ -33,7 +33,6 @@ void __save_processor_state(struct saved_context *ctxt) asm volatile ("str %0" : "=m" (ctxt->tr)); /* XMM0..XMM15 should be handled by kernel_fpu_begin(). */ - /* EFER should be constant for kernel version, no need to handle it. */ /* * segment registers */ @@ -50,6 +49,7 @@ void __save_processor_state(struct saved_context *ctxt) /* * control registers */ + rdmsrl(MSR_EFER, ctxt->efer); asm volatile ("movq %%cr0, %0" : "=r" (ctxt->cr0)); asm volatile ("movq %%cr2, %0" : "=r" (ctxt->cr2)); asm volatile ("movq %%cr3, %0" : "=r" (ctxt->cr3)); @@ -75,6 +75,7 @@ void __restore_processor_state(struct saved_context *ctxt) /* * control registers */ + wrmsrl(MSR_EFER, ctxt->efer); asm volatile ("movq %0, %%cr8" :: "r" (ctxt->cr8)); asm volatile ("movq %0, %%cr4" :: "r" (ctxt->cr4)); asm volatile ("movq %0, %%cr3" :: "r" (ctxt->cr3)); diff --git a/include/asm-x86_64/suspend.h b/include/asm-x86_64/suspend.h index bc7f81715e5e..a42306c220d6 100644 --- a/include/asm-x86_64/suspend.h +++ b/include/asm-x86_64/suspend.h @@ -17,6 +17,7 @@ struct saved_context { u16 ds, es, fs, gs, ss; unsigned long gs_base, gs_kernel_base, fs_base; unsigned long cr0, cr2, cr3, cr4, cr8; + unsigned long efer; u16 gdt_pad; u16 gdt_limit; unsigned long gdt_base; -- cgit v1.2.3-59-g8ed1b From 90b1c2085ea1955641e60a4f0acd63fdc271cd0b Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:07 +0200 Subject: [PATCH] x86-64: 64bit PIC SMP trampoline This modifies the SMP trampoline and all of the associated code so it can jump to a 64bit kernel loaded at an arbitrary address. The dependencies on having an idenetity mapped page in the kernel page tables for SMP bootup have all been removed. In addition the trampoline has been modified to verify that long mode is supported. Asking if long mode is implemented is down right silly but we have traditionally had some of these checks, and they can't hurt anything. So when the totally ludicrous happens we just might handle it correctly. Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/kernel/head.S | 1 + arch/x86_64/kernel/setup.c | 9 +-- arch/x86_64/kernel/trampoline.S | 168 ++++++++++++++++++++++++++++++++++++---- 3 files changed, 156 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 2b2e2c51e532..562d62fbd69f 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S @@ -101,6 +101,7 @@ startup_32: .org 0x100 .globl startup_64 startup_64: +ENTRY(secondary_startup_64) /* We come here either from startup_32 * or directly from a 64bit bootloader. * Since we may have come directly from a bootloader we diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 3d98b696881d..4b114ee31ebc 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -329,15 +329,8 @@ void __init setup_arch(char **cmdline_p) #endif #ifdef CONFIG_SMP - /* - * But first pinch a few for the stack/trampoline stuff - * FIXME: Don't need the extra page at 4K, but need to fix - * trampoline before removing it. (see the GDT stuff) - */ - reserve_bootmem_generic(PAGE_SIZE, PAGE_SIZE); - /* Reserve SMP trampoline */ - reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, PAGE_SIZE); + reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, 2*PAGE_SIZE); #endif #ifdef CONFIG_ACPI_SLEEP diff --git a/arch/x86_64/kernel/trampoline.S b/arch/x86_64/kernel/trampoline.S index c79b99a9e2f6..13eee63c7bb5 100644 --- a/arch/x86_64/kernel/trampoline.S +++ b/arch/x86_64/kernel/trampoline.S @@ -3,6 +3,7 @@ * Trampoline.S Derived from Setup.S by Linus Torvalds * * 4 Jan 1997 Michael Chastain: changed to gnu as. + * 15 Sept 2005 Eric Biederman: 64bit PIC support * * Entry: CS:IP point to the start of our code, we are * in real mode with no stack, but the rest of the @@ -17,15 +18,20 @@ * and IP is zero. Thus, data addresses need to be absolute * (no relocation) and are taken with regard to r_base. * + * With the addition of trampoline_level4_pgt this code can + * now enter a 64bit kernel that lives at arbitrary 64bit + * physical addresses. + * * If you work on this file, check the object module with objdump * --full-contents --reloc to make sure there are no relocation - * entries. For the GDT entry we do hand relocation in smpboot.c - * because of 64bit linker limitations. + * entries. */ #include -#include +#include #include +#include +#include .data @@ -33,15 +39,31 @@ ENTRY(trampoline_data) r_base = . + cli # We should be safe anyway wbinvd mov %cs, %ax # Code and data in the same place mov %ax, %ds + mov %ax, %es + mov %ax, %ss - cli # We should be safe anyway movl $0xA5A5A5A5, trampoline_data - r_base # write marker for master knows we're running + # Setup stack + movw $(trampoline_stack_end - r_base), %sp + + call verify_cpu # Verify the cpu supports long mode + + mov %cs, %ax + movzx %ax, %esi # Find the 32bit trampoline location + shll $4, %esi + + # Fixup the vectors + addl %esi, startup_32_vector - r_base + addl %esi, startup_64_vector - r_base + addl %esi, tgdt + 2 - r_base # Fixup the gdt pointer + /* * GDT tables in non default location kernel can be beyond 16MB and * lgdt will not be able to load the address as in real mode default @@ -49,23 +71,141 @@ r_base = . * to 32 bit. */ - lidtl idt_48 - r_base # load idt with 0, 0 - lgdtl gdt_48 - r_base # load gdt with whatever is appropriate + lidtl tidt - r_base # load idt with 0, 0 + lgdtl tgdt - r_base # load gdt with whatever is appropriate xor %ax, %ax inc %ax # protected mode (PE) bit lmsw %ax # into protected mode - # flaush prefetch and jump to startup_32 in arch/x86_64/kernel/head.S - ljmpl $__KERNEL32_CS, $(startup_32-__START_KERNEL_map) + + # flush prefetch and jump to startup_32 + ljmpl *(startup_32_vector - r_base) + + .code32 + .balign 4 +startup_32: + movl $__KERNEL_DS, %eax # Initialize the %ds segment register + movl %eax, %ds + + xorl %eax, %eax + btsl $5, %eax # Enable PAE mode + movl %eax, %cr4 + + # Setup trampoline 4 level pagetables + leal (trampoline_level4_pgt - r_base)(%esi), %eax + movl %eax, %cr3 + + movl $MSR_EFER, %ecx + movl $(1 << _EFER_LME), %eax # Enable Long Mode + xorl %edx, %edx + wrmsr + + xorl %eax, %eax + btsl $31, %eax # Enable paging and in turn activate Long Mode + btsl $0, %eax # Enable protected mode + movl %eax, %cr0 + + /* + * At this point we're in long mode but in 32bit compatibility mode + * with EFER.LME = 1, CS.L = 0, CS.D = 1 (and in turn + * EFER.LMA = 1). Now we want to jump in 64bit mode, to do that we use + * the new gdt/idt that has __KERNEL_CS with CS.L = 1. + */ + ljmp *(startup_64_vector - r_base)(%esi) + + .code64 + .balign 4 +startup_64: + # Now jump into the kernel using virtual addresses + movq $secondary_startup_64, %rax + jmp *%rax + + .code16 +verify_cpu: + pushl $0 # Kill any dangerous flags + popfl + + /* minimum CPUID flags for x86-64 */ + /* see http://www.x86-64.org/lists/discuss/msg02971.html */ +#define REQUIRED_MASK1 ((1<<0)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<8)|\ + (1<<13)|(1<<15)|(1<<24)|(1<<25)|(1<<26)) +#define REQUIRED_MASK2 (1<<29) + + pushfl # check for cpuid + popl %eax + movl %eax, %ebx + xorl $0x200000,%eax + pushl %eax + popfl + pushfl + popl %eax + pushl %ebx + popfl + cmpl %eax, %ebx + jz no_longmode + + xorl %eax, %eax # See if cpuid 1 is implemented + cpuid + cmpl $0x1, %eax + jb no_longmode + + movl $0x01, %eax # Does the cpu have what it takes? + cpuid + andl $REQUIRED_MASK1, %edx + xorl $REQUIRED_MASK1, %edx + jnz no_longmode + + movl $0x80000000, %eax # See if extended cpuid is implemented + cpuid + cmpl $0x80000001, %eax + jb no_longmode + + movl $0x80000001, %eax # Does the cpu have what it takes? + cpuid + andl $REQUIRED_MASK2, %edx + xorl $REQUIRED_MASK2, %edx + jnz no_longmode + + ret # The cpu supports long mode + +no_longmode: + hlt + jmp no_longmode + # Careful these need to be in the same 64K segment as the above; -idt_48: +tidt: .word 0 # idt limit = 0 .word 0, 0 # idt base = 0L -gdt_48: - .short GDT_ENTRIES*8 - 1 # gdt limit - .long cpu_gdt_table-__START_KERNEL_map + # Duplicate the global descriptor table + # so the kernel can live anywhere + .balign 4 +tgdt: + .short tgdt_end - tgdt # gdt limit + .long tgdt - r_base + .short 0 + .quad 0x00cf9b000000ffff # __KERNEL32_CS + .quad 0x00af9b000000ffff # __KERNEL_CS + .quad 0x00cf93000000ffff # __KERNEL_DS +tgdt_end: + + .balign 4 +startup_32_vector: + .long startup_32 - r_base + .word __KERNEL32_CS, 0 + + .balign 4 +startup_64_vector: + .long startup_64 - r_base + .word __KERNEL_CS, 0 + +trampoline_stack: + .org 0x1000 +trampoline_stack_end: +ENTRY(trampoline_level4_pgt) + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .fill 510,8,0 + .quad level3_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE -.globl trampoline_end -trampoline_end: +ENTRY(trampoline_end) -- cgit v1.2.3-59-g8ed1b From 7c17e70613d2c70f9d5d0b5d37126fd5e8e9b728 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:07 +0200 Subject: [PATCH] x86-64: Get rid of dead code in suspend resume o Get rid of dead code in wakeup.S o We never restore from saved_gdt, saved_idt, saved_ltd, saved_tss, saved_cr3, saved_cr4, saved_cr0, real_save_gdt, saved_efer, saved_efer2. Get rid of of associated code. o Get rid of bogus_magic, bogus_31_magic and bogus_magic2. No longer being used. Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/kernel/acpi/wakeup.S | 57 +--------------------------------------- 1 file changed, 1 insertion(+), 56 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/acpi/wakeup.S b/arch/x86_64/kernel/acpi/wakeup.S index 185faa911db5..6ece70e91a32 100644 --- a/arch/x86_64/kernel/acpi/wakeup.S +++ b/arch/x86_64/kernel/acpi/wakeup.S @@ -258,8 +258,6 @@ gdt_48a: .word 0, 0 # gdt base (filled in later) -real_save_gdt: .word 0 - .quad 0 real_magic: .quad 0 video_mode: .quad 0 video_flags: .quad 0 @@ -272,10 +270,6 @@ bogus_32_magic: movb $0xb3,%al ; outb %al,$0x80 jmp bogus_32_magic -bogus_31_magic: - movb $0xb1,%al ; outb %al,$0x80 - jmp bogus_31_magic - bogus_cpu: movb $0xbc,%al ; outb %al,$0x80 jmp bogus_cpu @@ -346,16 +340,6 @@ check_vesaa: _setbada: jmp setbada - .code64 -bogus_magic: - movw $0x0e00 + 'B', %ds:(0xb8018) - jmp bogus_magic - -bogus_magic2: - movw $0x0e00 + '2', %ds:(0xb8018) - jmp bogus_magic2 - - wakeup_stack_begin: # Stack grows down .org 0xff0 @@ -373,28 +357,11 @@ ENTRY(wakeup_end) # # Returned address is location of code in low memory (past data and stack) # + .code64 ENTRY(acpi_copy_wakeup_routine) pushq %rax - pushq %rcx pushq %rdx - sgdt saved_gdt - sidt saved_idt - sldt saved_ldt - str saved_tss - - movq %cr3, %rdx - movq %rdx, saved_cr3 - movq %cr4, %rdx - movq %rdx, saved_cr4 - movq %cr0, %rdx - movq %rdx, saved_cr0 - sgdt real_save_gdt - wakeup_start (,%rdi) - movl $MSR_EFER, %ecx - rdmsr - movl %eax, saved_efer - movl %edx, saved_efer2 - movl saved_video_mode, %edx movl %edx, video_mode - wakeup_start (,%rdi) movl acpi_video_flags, %edx @@ -407,17 +374,8 @@ ENTRY(acpi_copy_wakeup_routine) cmpl $0x9abcdef0, %eax jne bogus_32_magic - # make sure %cr4 is set correctly (features, etc) - movl saved_cr4 - __START_KERNEL_map, %eax - movq %rax, %cr4 - - movl saved_cr0 - __START_KERNEL_map, %eax - movq %rax, %cr0 - jmp 1f # Flush pipelines -1: # restore the regs we used popq %rdx - popq %rcx popq %rax ENTRY(do_suspend_lowlevel_s4bios) ret @@ -512,16 +470,3 @@ ENTRY(saved_eip) .quad 0 ENTRY(saved_esp) .quad 0 ENTRY(saved_magic) .quad 0 - -ALIGN -# saved registers -saved_gdt: .quad 0,0 -saved_idt: .quad 0,0 -saved_ldt: .quad 0 -saved_tss: .quad 0 - -saved_cr0: .quad 0 -saved_cr3: .quad 0 -saved_cr4: .quad 0 -saved_efer: .quad 0 -saved_efer2: .quad 0 -- cgit v1.2.3-59-g8ed1b From 7db681d7e4038ad205b5face5cf7f7815633e1b5 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:07 +0200 Subject: [PATCH] x86-64: wakeup.S rename registers to reflect right names o Use appropriate names for 64bit regsiters. Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/kernel/acpi/wakeup.S | 36 ++++++++++++++++++------------------ include/asm-x86_64/suspend.h | 12 ++++++------ 2 files changed, 24 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/acpi/wakeup.S b/arch/x86_64/kernel/acpi/wakeup.S index 6ece70e91a32..17dbeff64eef 100644 --- a/arch/x86_64/kernel/acpi/wakeup.S +++ b/arch/x86_64/kernel/acpi/wakeup.S @@ -211,16 +211,16 @@ wakeup_long64: movw %ax, %es movw %ax, %fs movw %ax, %gs - movq saved_esp, %rsp + movq saved_rsp, %rsp movw $0x0e00 + 'x', %ds:(0xb8018) - movq saved_ebx, %rbx - movq saved_edi, %rdi - movq saved_esi, %rsi - movq saved_ebp, %rbp + movq saved_rbx, %rbx + movq saved_rdi, %rdi + movq saved_rsi, %rsi + movq saved_rbp, %rbp movw $0x0e00 + '!', %ds:(0xb801a) - movq saved_eip, %rax + movq saved_rip, %rax jmp *%rax .code32 @@ -408,13 +408,13 @@ do_suspend_lowlevel: movq %r15, saved_context_r15(%rip) pushfq ; popq saved_context_eflags(%rip) - movq $.L97, saved_eip(%rip) + movq $.L97, saved_rip(%rip) - movq %rsp,saved_esp - movq %rbp,saved_ebp - movq %rbx,saved_ebx - movq %rdi,saved_edi - movq %rsi,saved_esi + movq %rsp,saved_rsp + movq %rbp,saved_rbp + movq %rbx,saved_rbx + movq %rdi,saved_rdi + movq %rsi,saved_rsi addq $8, %rsp movl $3, %edi @@ -461,12 +461,12 @@ do_suspend_lowlevel: .data ALIGN -ENTRY(saved_ebp) .quad 0 -ENTRY(saved_esi) .quad 0 -ENTRY(saved_edi) .quad 0 -ENTRY(saved_ebx) .quad 0 +ENTRY(saved_rbp) .quad 0 +ENTRY(saved_rsi) .quad 0 +ENTRY(saved_rdi) .quad 0 +ENTRY(saved_rbx) .quad 0 -ENTRY(saved_eip) .quad 0 -ENTRY(saved_esp) .quad 0 +ENTRY(saved_rip) .quad 0 +ENTRY(saved_rsp) .quad 0 ENTRY(saved_magic) .quad 0 diff --git a/include/asm-x86_64/suspend.h b/include/asm-x86_64/suspend.h index a42306c220d6..9c3f8de90d2d 100644 --- a/include/asm-x86_64/suspend.h +++ b/include/asm-x86_64/suspend.h @@ -45,12 +45,12 @@ extern unsigned long saved_context_eflags; extern void fix_processor_context(void); #ifdef CONFIG_ACPI_SLEEP -extern unsigned long saved_eip; -extern unsigned long saved_esp; -extern unsigned long saved_ebp; -extern unsigned long saved_ebx; -extern unsigned long saved_esi; -extern unsigned long saved_edi; +extern unsigned long saved_rip; +extern unsigned long saved_rsp; +extern unsigned long saved_rbp; +extern unsigned long saved_rbx; +extern unsigned long saved_rsi; +extern unsigned long saved_rdi; /* routines for saving/restoring kernel state */ extern int acpi_save_state_mem(void); -- cgit v1.2.3-59-g8ed1b From 275f55170ec2b5d777b070cb8ab9e5d58e65a2a8 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:07 +0200 Subject: [PATCH] x86-64: wakeup.S misc cleanups o Various cleanups. One of the main purpose of cleanups is that make wakeup.S as close as possible to trampoline.S. o Following are the changes - Indentations for comments. - Changed the gdt table to compact form and to resemble the one in trampoline.S - Take the jump to 32bit from real mode using ljmpl. Makes code more readable. - After enabling long mode, directly take a long jump for 64bit mode. No need to take an extra jump to "reach_comaptibility_mode" - Stack is not used after real mode. So don't load stack in 32 bit mode. - No need to enable PGE here. - No need to do extra EFER read, anyway we trash the read contents. - No need to enable system call (EFER_SCE). Anyway it will be enabled when original EFER is restored. - No need to set MP, ET, NE, WP, AM bits in cr0. Very soon we will reload the original cr0 while restroing the processor state. Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/kernel/acpi/wakeup.S | 112 ++++++++++++++------------------------- 1 file changed, 40 insertions(+), 72 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/acpi/wakeup.S b/arch/x86_64/kernel/acpi/wakeup.S index 17dbeff64eef..bd4c6f1a6f32 100644 --- a/arch/x86_64/kernel/acpi/wakeup.S +++ b/arch/x86_64/kernel/acpi/wakeup.S @@ -30,11 +30,12 @@ wakeup_code: cld # setup data segment movw %cs, %ax - movw %ax, %ds # Make ds:0 point to wakeup_start + movw %ax, %ds # Make ds:0 point to wakeup_start movw %ax, %ss - mov $(wakeup_stack - wakeup_code), %sp # Private stack is needed for ASUS board + # Private stack is needed for ASUS board + mov $(wakeup_stack - wakeup_code), %sp - pushl $0 # Kill any dangerous flags + pushl $0 # Kill any dangerous flags popfl movl real_magic - wakeup_code, %eax @@ -45,7 +46,7 @@ wakeup_code: jz 1f lcall $0xc000,$3 movw %cs, %ax - movw %ax, %ds # Bios might have played with that + movw %ax, %ds # Bios might have played with that movw %ax, %ss 1: @@ -75,9 +76,12 @@ wakeup_code: jmp 1f 1: - .byte 0x66, 0xea # prefix + jmpi-opcode - .long wakeup_32 - __START_KERNEL_map - .word __KERNEL_CS + ljmpl *(wakeup_32_vector - wakeup_code) + + .balign 4 +wakeup_32_vector: + .long wakeup_32 - __START_KERNEL_map + .word __KERNEL32_CS, 0 .code32 wakeup_32: @@ -96,65 +100,50 @@ wakeup_32: jnc bogus_cpu movl %edx,%edi - movw $__KERNEL_DS, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs + movl $__KERNEL_DS, %eax + movl %eax, %ds - movw $__KERNEL_DS, %ax - movw %ax, %ss - - mov $(wakeup_stack - __START_KERNEL_map), %esp movl saved_magic - __START_KERNEL_map, %eax cmpl $0x9abcdef0, %eax jne bogus_32_magic + movw $0x0e00 + 'i', %ds:(0xb8012) + movb $0xa8, %al ; outb %al, $0x80; + /* * Prepare for entering 64bits mode */ - /* Enable PAE mode and PGE */ + /* Enable PAE */ xorl %eax, %eax btsl $5, %eax - btsl $7, %eax movl %eax, %cr4 /* Setup early boot stage 4 level pagetables */ movl $(wakeup_level4_pgt - __START_KERNEL_map), %eax movl %eax, %cr3 - /* Setup EFER (Extended Feature Enable Register) */ - movl $MSR_EFER, %ecx - rdmsr - /* Fool rdmsr and reset %eax to avoid dependences */ - xorl %eax, %eax /* Enable Long Mode */ + xorl %eax, %eax btsl $_EFER_LME, %eax - /* Enable System Call */ - btsl $_EFER_SCE, %eax - /* No Execute supported? */ + /* No Execute supported? */ btl $20,%edi jnc 1f btsl $_EFER_NX, %eax -1: /* Make changes effective */ +1: movl $MSR_EFER, %ecx + xorl %edx, %edx wrmsr - wbinvd xorl %eax, %eax btsl $31, %eax /* Enable paging and in turn activate Long Mode */ btsl $0, %eax /* Enable protected mode */ - btsl $1, %eax /* Enable MP */ - btsl $4, %eax /* Enable ET */ - btsl $5, %eax /* Enable NE */ - btsl $16, %eax /* Enable WP */ - btsl $18, %eax /* Enable AM */ /* Make changes effective */ movl %eax, %cr0 + /* At this point: CR4.PAE must be 1 CS.L must be 0 @@ -162,11 +151,6 @@ wakeup_32: Next instruction must be a branch This must be on identity-mapped page */ - jmp reach_compatibility_mode -reach_compatibility_mode: - movw $0x0e00 + 'i', %ds:(0xb8012) - movb $0xa8, %al ; outb %al, $0x80; - /* * At this point we're in long mode but in 32bit compatibility mode * with EFER.LME = 1, CS.L = 0, CS.D = 1 (and in turn @@ -174,24 +158,19 @@ reach_compatibility_mode: * the new gdt/idt that has __KERNEL_CS with CS.L = 1. */ - movw $0x0e00 + 'n', %ds:(0xb8014) - movb $0xa9, %al ; outb %al, $0x80 - - /* Load new GDT with the 64bit segment using 32bit descriptor */ - movl $(pGDT32 - __START_KERNEL_map), %eax - lgdt (%eax) - - movl $(wakeup_jumpvector - __START_KERNEL_map), %eax /* Finally jump in 64bit mode */ - ljmp *(%eax) + ljmp *(wakeup_long64_vector - __START_KERNEL_map) -wakeup_jumpvector: - .long wakeup_long64 - __START_KERNEL_map - .word __KERNEL_CS + .balign 4 +wakeup_long64_vector: + .long wakeup_long64 - __START_KERNEL_map + .word __KERNEL_CS, 0 .code64 - /* Hooray, we are in Long 64-bit mode (but still running in low memory) */ + /* Hooray, we are in Long 64-bit mode (but still running in + * low memory) + */ wakeup_long64: /* * We must switch to a new descriptor in kernel space for the GDT @@ -201,6 +180,9 @@ wakeup_long64: */ lgdt cpu_gdt_descr - __START_KERNEL_map + movw $0x0e00 + 'n', %ds:(0xb8014) + movb $0xa9, %al ; outb %al, $0x80 + movw $0x0e00 + 'u', %ds:(0xb8016) nop @@ -227,33 +209,19 @@ wakeup_long64: .align 64 gdta: + /* Its good to keep gdt in sync with one in trampoline.S */ .word 0, 0, 0, 0 # dummy - - .word 0, 0, 0, 0 # unused - - .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) - .word 0 # base address = 0 - .word 0x9B00 # code read/exec. ??? Why I need 0x9B00 (as opposed to 0x9A00 in order for this to work?) - .word 0x00CF # granularity = 4096, 386 - # (+5th nibble of limit) - - .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) - .word 0 # base address = 0 - .word 0x9200 # data read/write - .word 0x00CF # granularity = 4096, 386 - # (+5th nibble of limit) -# this is 64bit descriptor for code - .word 0xFFFF - .word 0 - .word 0x9A00 # code read/exec - .word 0x00AF # as above, but it is long mode and with D=0 + /* ??? Why I need the accessed bit set in order for this to work? */ + .quad 0x00cf9b000000ffff # __KERNEL32_CS + .quad 0x00af9b000000ffff # __KERNEL_CS + .quad 0x00cf93000000ffff # __KERNEL_DS idt_48a: .word 0 # idt limit = 0 .word 0, 0 # idt base = 0L gdt_48a: - .word 0x8000 # gdt limit=2048, + .word 0x800 # gdt limit=2048, # 256 GDT entries .word 0, 0 # gdt base (filled in later) @@ -263,7 +231,7 @@ video_mode: .quad 0 video_flags: .quad 0 bogus_real_magic: - movb $0xba,%al ; outb %al,$0x80 + movb $0xba,%al ; outb %al,$0x80 jmp bogus_real_magic bogus_32_magic: -- cgit v1.2.3-59-g8ed1b From d8e1baf10d62c06fc52e89137357e54da3d92672 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:07 +0200 Subject: [PATCH] x86-64: 64bit ACPI wakeup trampoline o Moved wakeup_level4_pgt into the wakeup routine so we can run the kernel above 4G. o Now we first go to 64bit mode and continue to run from trampoline and then then start accessing kernel symbols and restore processor context. This enables us to resume even in relocatable kernel context when kernel might not be loaded at physical addr it has been compiled for. o Removed the need for modifying any existing kernel page table. o Increased the size of the wakeup routine to 8K. This is required as wake page tables are on trampoline itself and they got to be at 4K boundary, hence one page is not sufficient. Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/kernel/acpi/sleep.c | 24 +++------------- arch/x86_64/kernel/acpi/wakeup.S | 59 +++++++++++++++++++++++++--------------- arch/x86_64/kernel/head.S | 9 ------ 3 files changed, 41 insertions(+), 51 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/acpi/sleep.c b/arch/x86_64/kernel/acpi/sleep.c index e1548fbe95ae..195b7034a148 100644 --- a/arch/x86_64/kernel/acpi/sleep.c +++ b/arch/x86_64/kernel/acpi/sleep.c @@ -60,19 +60,6 @@ extern char wakeup_start, wakeup_end; extern unsigned long acpi_copy_wakeup_routine(unsigned long); -static pgd_t low_ptr; - -static void init_low_mapping(void) -{ - pgd_t *slot0 = pgd_offset(current->mm, 0UL); - low_ptr = *slot0; - /* FIXME: We're playing with the current task's page tables here, which - * is potentially dangerous on SMP systems. - */ - set_pgd(slot0, *pgd_offset(current->mm, PAGE_OFFSET)); - local_flush_tlb(); -} - /** * acpi_save_state_mem - save kernel state * @@ -81,8 +68,6 @@ static void init_low_mapping(void) */ int acpi_save_state_mem(void) { - init_low_mapping(); - memcpy((void *)acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start); acpi_copy_wakeup_routine(acpi_wakeup_address); @@ -95,8 +80,6 @@ int acpi_save_state_mem(void) */ void acpi_restore_state_mem(void) { - set_pgd(pgd_offset(current->mm, 0UL), low_ptr); - local_flush_tlb(); } /** @@ -109,10 +92,11 @@ void acpi_restore_state_mem(void) */ void __init acpi_reserve_bootmem(void) { - acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE); - if ((&wakeup_end - &wakeup_start) > PAGE_SIZE) + acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE*2); + if ((&wakeup_end - &wakeup_start) > (PAGE_SIZE*2)) printk(KERN_CRIT - "ACPI: Wakeup code way too big, will crash on attempt to suspend\n"); + "ACPI: Wakeup code way too big, will crash on attempt" + " to suspend\n"); } static int __init acpi_sleep_setup(char *str) diff --git a/arch/x86_64/kernel/acpi/wakeup.S b/arch/x86_64/kernel/acpi/wakeup.S index bd4c6f1a6f32..766cfbcac1db 100644 --- a/arch/x86_64/kernel/acpi/wakeup.S +++ b/arch/x86_64/kernel/acpi/wakeup.S @@ -1,6 +1,7 @@ .text #include #include +#include #include #include @@ -62,12 +63,15 @@ wakeup_code: movb $0xa2, %al ; outb %al, $0x80 - lidt %ds:idt_48a - wakeup_code - xorl %eax, %eax - movw %ds, %ax # (Convert %ds:gdt to a linear ptr) - shll $4, %eax - addl $(gdta - wakeup_code), %eax - movl %eax, gdt_48a +2 - wakeup_code + mov %ds, %ax # Find 32bit wakeup_code addr + movzx %ax, %esi # (Convert %ds:gdt to a liner ptr) + shll $4, %esi + # Fix up the vectors + addl %esi, wakeup_32_vector - wakeup_code + addl %esi, wakeup_long64_vector - wakeup_code + addl %esi, gdt_48a + 2 - wakeup_code # Fixup the gdt pointer + + lidtl %ds:idt_48a - wakeup_code lgdtl %ds:gdt_48a - wakeup_code # load gdt with whatever is # appropriate @@ -80,7 +84,7 @@ wakeup_code: .balign 4 wakeup_32_vector: - .long wakeup_32 - __START_KERNEL_map + .long wakeup_32 - wakeup_code .word __KERNEL32_CS, 0 .code32 @@ -103,10 +107,6 @@ wakeup_32: movl $__KERNEL_DS, %eax movl %eax, %ds - movl saved_magic - __START_KERNEL_map, %eax - cmpl $0x9abcdef0, %eax - jne bogus_32_magic - movw $0x0e00 + 'i', %ds:(0xb8012) movb $0xa8, %al ; outb %al, $0x80; @@ -120,7 +120,7 @@ wakeup_32: movl %eax, %cr4 /* Setup early boot stage 4 level pagetables */ - movl $(wakeup_level4_pgt - __START_KERNEL_map), %eax + leal (wakeup_level4_pgt - wakeup_code)(%esi), %eax movl %eax, %cr3 /* Enable Long Mode */ @@ -159,11 +159,11 @@ wakeup_32: */ /* Finally jump in 64bit mode */ - ljmp *(wakeup_long64_vector - __START_KERNEL_map) + ljmp *(wakeup_long64_vector - wakeup_code)(%esi) .balign 4 wakeup_long64_vector: - .long wakeup_long64 - __START_KERNEL_map + .long wakeup_long64 - wakeup_code .word __KERNEL_CS, 0 .code64 @@ -178,11 +178,16 @@ wakeup_long64: * addresses where we're currently running on. We have to do that here * because in 32bit we couldn't load a 64bit linear address. */ - lgdt cpu_gdt_descr - __START_KERNEL_map + lgdt cpu_gdt_descr movw $0x0e00 + 'n', %ds:(0xb8014) movb $0xa9, %al ; outb %al, $0x80 + movq saved_magic, %rax + movq $0x123456789abcdef0, %rdx + cmpq %rdx, %rax + jne bogus_64_magic + movw $0x0e00 + 'u', %ds:(0xb8016) nop @@ -223,20 +228,21 @@ idt_48a: gdt_48a: .word 0x800 # gdt limit=2048, # 256 GDT entries - .word 0, 0 # gdt base (filled in later) - + .long gdta - wakeup_code # gdt base (relocated in later) real_magic: .quad 0 video_mode: .quad 0 video_flags: .quad 0 +.code16 bogus_real_magic: movb $0xba,%al ; outb %al,$0x80 jmp bogus_real_magic -bogus_32_magic: +.code64 +bogus_64_magic: movb $0xb3,%al ; outb %al,$0x80 - jmp bogus_32_magic + jmp bogus_64_magic bogus_cpu: movb $0xbc,%al ; outb %al,$0x80 @@ -263,6 +269,7 @@ bogus_cpu: #define VIDEO_FIRST_V7 0x0900 # Setting of user mode (AX=mode ID) => CF=success +.code16 mode_seta: movw %ax, %bx #if 0 @@ -313,6 +320,13 @@ wakeup_stack_begin: # Stack grows down .org 0xff0 wakeup_stack: # Just below end of page +.org 0x1000 +ENTRY(wakeup_level4_pgt) + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .fill 510,8,0 + /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ + .quad level3_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE + ENTRY(wakeup_end) ## @@ -338,9 +352,10 @@ ENTRY(acpi_copy_wakeup_routine) movq $0x123456789abcdef0, %rdx movq %rdx, saved_magic - movl saved_magic - __START_KERNEL_map, %eax - cmpl $0x9abcdef0, %eax - jne bogus_32_magic + movq saved_magic, %rax + movq $0x123456789abcdef0, %rdx + cmpq %rdx, %rax + jne bogus_64_magic # restore the regs we used popq %rdx diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 562d62fbd69f..926aa2197aaa 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S @@ -308,15 +308,6 @@ NEXT_PAGE(level2_kernel_pgt) .data -#ifdef CONFIG_ACPI_SLEEP - .align PAGE_SIZE -ENTRY(wakeup_level4_pgt) - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE - .fill 510,8,0 - /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ - .quad level3_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE -#endif - #ifndef CONFIG_HOTPLUG_CPU __INITDATA #endif -- cgit v1.2.3-59-g8ed1b From bdb96a6614cfaba24e23dd9de4040c068c3af19b Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:07 +0200 Subject: [PATCH] x86-64: Modify discover_ebda to use virtual addresses Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/kernel/setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 4b114ee31ebc..65e2bc551a2b 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -205,10 +205,10 @@ static void discover_ebda(void) * there is a real-mode segmented pointer pointing to the * 4K EBDA area at 0x40E */ - ebda_addr = *(unsigned short *)EBDA_ADDR_POINTER; + ebda_addr = *(unsigned short *)__va(EBDA_ADDR_POINTER); ebda_addr <<= 4; - ebda_size = *(unsigned short *)(unsigned long)ebda_addr; + ebda_size = *(unsigned short *)__va(ebda_addr); /* Round EBDA up to pages */ if (ebda_size == 0) -- cgit v1.2.3-59-g8ed1b From cfd243d4af7c7f8f52f5cb99d3932d9074b039ff Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:07 +0200 Subject: [PATCH] x86-64: Remove the identity mapping as early as possible With the rewrite of the SMP trampoline and the early page allocator there is nothing that needs identity mapped pages, once we start executing C code. So add zap_identity_mappings into head64.c and remove zap_low_mappings() from much later in the code. The functions are subtly different thus the name change. This also kills boot_level4_pgt which was from an earlier attempt to move the identity mappings as early as possible, and is now no longer needed. Essentially I have replaced boot_level4_pgt with trampoline_level4_pgt in trampoline.S Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/kernel/head.S | 39 ++++++++++++++------------------------- arch/x86_64/kernel/head64.c | 17 +++++++++++------ arch/x86_64/kernel/setup.c | 2 -- arch/x86_64/kernel/setup64.c | 1 - arch/x86_64/mm/init.c | 24 ------------------------ include/asm-x86_64/pgtable.h | 1 - include/asm-x86_64/proto.h | 2 -- 7 files changed, 25 insertions(+), 61 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 926aa2197aaa..c211e52f1333 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S @@ -71,7 +71,7 @@ startup_32: movl %eax, %cr4 /* Setup early boot stage 4 level pagetables */ - movl $(boot_level4_pgt - __START_KERNEL_map), %eax + movl $(init_level4_pgt - __START_KERNEL_map), %eax movl %eax, %cr3 /* Setup EFER (Extended Feature Enable Register) */ @@ -115,7 +115,7 @@ ENTRY(secondary_startup_64) movq %rax, %cr4 /* Setup early boot stage 4 level pagetables. */ - movq $(boot_level4_pgt - __START_KERNEL_map), %rax + movq $(init_level4_pgt - __START_KERNEL_map), %rax movq %rax, %cr3 /* Check if nx is implemented */ @@ -274,9 +274,19 @@ ENTRY(name) i = i + 1 ; \ .endr + /* + * This default setting generates an ident mapping at address 0x100000 + * and a mapping for the kernel that precisely maps virtual address + * 0xffffffff80000000 to physical address 0x000000. (always using + * 2Mbyte large pages provided by PAE mode) + */ NEXT_PAGE(init_level4_pgt) - /* This gets initialized in x86_64_start_kernel */ - .fill 512,8,0 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .fill 257,8,0 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .fill 252,8,0 + /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ + .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE NEXT_PAGE(level3_ident_pgt) .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE @@ -307,27 +317,6 @@ NEXT_PAGE(level2_kernel_pgt) #undef NEXT_PAGE .data - -#ifndef CONFIG_HOTPLUG_CPU - __INITDATA -#endif - /* - * This default setting generates an ident mapping at address 0x100000 - * and a mapping for the kernel that precisely maps virtual address - * 0xffffffff80000000 to physical address 0x000000. (always using - * 2Mbyte large pages provided by PAE mode) - */ - .align PAGE_SIZE -ENTRY(boot_level4_pgt) - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE - .fill 257,8,0 - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE - .fill 252,8,0 - /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ - .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE - - .data - .align 16 .globl cpu_gdt_descr cpu_gdt_descr: diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c index 5c529c1e3d6c..6c34bdd22e26 100644 --- a/arch/x86_64/kernel/head64.c +++ b/arch/x86_64/kernel/head64.c @@ -18,8 +18,16 @@ #include #include #include +#include #include +static void __init zap_identity_mappings(void) +{ + pgd_t *pgd = pgd_offset_k(0UL); + pgd_clear(pgd); + __flush_tlb(); +} + /* Don't add a printk in there. printk relies on the PDA which is not initialized yet. */ static void __init clear_bss(void) @@ -57,18 +65,15 @@ void __init x86_64_start_kernel(char * real_mode_data) /* clear bss before set_intr_gate with early_idt_handler */ clear_bss(); + /* Make NULL pointers segfault */ + zap_identity_mappings(); + for (i = 0; i < IDT_ENTRIES; i++) set_intr_gate(i, early_idt_handler); asm volatile("lidt %0" :: "m" (idt_descr)); early_printk("Kernel alive\n"); - /* - * switch to init_level4_pgt from boot_level4_pgt - */ - memcpy(init_level4_pgt, boot_level4_pgt, PTRS_PER_PGD*sizeof(pgd_t)); - asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt))); - for (i = 0; i < NR_CPUS; i++) cpu_pda(i) = &boot_cpu_pda[i]; diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 65e2bc551a2b..0e2b8df0ea64 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -274,8 +274,6 @@ void __init setup_arch(char **cmdline_p) dmi_scan_machine(); - zap_low_mappings(0); - #ifdef CONFIG_ACPI /* * Initialize the ACPI boot-time table parser (gets the RSDP and SDT). diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c index 6a70b55f719d..53064a9a365f 100644 --- a/arch/x86_64/kernel/setup64.c +++ b/arch/x86_64/kernel/setup64.c @@ -201,7 +201,6 @@ void __cpuinit cpu_init (void) /* CPU 0 is initialised in head64.c */ if (cpu != 0) { pda_init(cpu); - zap_low_mappings(cpu); } else estacks = boot_exception_stacks; diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 4ab3d40aac90..b0a607892183 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -378,21 +378,6 @@ void __meminit init_memory_mapping(unsigned long start, unsigned long end) __flush_tlb_all(); } -void __cpuinit zap_low_mappings(int cpu) -{ - if (cpu == 0) { - pgd_t *pgd = pgd_offset_k(0UL); - pgd_clear(pgd); - } else { - /* - * For AP's, zap the low identity mappings by changing the cr3 - * to init_level4_pgt and doing local flush tlb all - */ - asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt))); - } - __flush_tlb_all(); -} - #ifndef CONFIG_NUMA void __init paging_init(void) { @@ -569,15 +554,6 @@ void __init mem_init(void) reservedpages << (PAGE_SHIFT-10), datasize >> 10, initsize >> 10); - -#ifdef CONFIG_SMP - /* - * Sync boot_level4_pgt mappings with the init_level4_pgt - * except for the low identity mappings which are already zapped - * in init_level4_pgt. This sync-up is essential for AP's bringup - */ - memcpy(boot_level4_pgt+1, init_level4_pgt+1, (PTRS_PER_PGD-1)*sizeof(pgd_t)); -#endif } void free_init_pages(char *what, unsigned long begin, unsigned long end) diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h index 5a5d43b3ef5d..703f0243f27a 100644 --- a/include/asm-x86_64/pgtable.h +++ b/include/asm-x86_64/pgtable.h @@ -17,7 +17,6 @@ extern pud_t level3_kernel_pgt[512]; extern pud_t level3_ident_pgt[512]; extern pmd_t level2_kernel_pgt[512]; extern pgd_t init_level4_pgt[]; -extern pgd_t boot_level4_pgt[]; extern unsigned long __supported_pte_mask; #define swapper_pg_dir init_level4_pgt diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index 78427021d94a..3f8f285138d2 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h @@ -11,8 +11,6 @@ struct pt_regs; extern void start_kernel(void); extern void pda_init(int); -extern void zap_low_mappings(int cpu); - extern void early_idt_handler(void); extern void mcheck_init(struct cpuinfo_x86 *c); -- cgit v1.2.3-59-g8ed1b From 49c3df6aaa6a51071fc135273d1a2515d019099f Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:07 +0200 Subject: [PATCH] x86: Move swsusp __pa() dependent code to arch portion o __pa() should be used only on kernel linearly mapped virtual addresses and not on kernel text and data addresses. o Hibernation code needs to determine the physical address associated with kernel symbol to mark a section boundary which contains pages which don't have to be saved and restored during hibernate/resume operation. o Move this piece of code in arch dependent section. So that architectures which don't have kernel text/data mapped into kernel linearly mapped region can come up with their own ways of determining physical addresses associated with a kernel text. Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/i386/power/suspend.c | 14 ++++++++++++++ arch/powerpc/kernel/Makefile | 1 + arch/powerpc/kernel/suspend.c | 24 ++++++++++++++++++++++++ arch/x86_64/kernel/suspend.c | 14 ++++++++++++++ kernel/power/power.h | 5 ++--- kernel/power/snapshot.c | 11 ----------- 6 files changed, 55 insertions(+), 14 deletions(-) create mode 100644 arch/powerpc/kernel/suspend.c (limited to 'arch') diff --git a/arch/i386/power/suspend.c b/arch/i386/power/suspend.c index db5e98d2eb73..a0020b913f31 100644 --- a/arch/i386/power/suspend.c +++ b/arch/i386/power/suspend.c @@ -16,6 +16,9 @@ /* Defined in arch/i386/power/swsusp.S */ extern int restore_image(void); +/* References to section boundaries */ +extern const void __nosave_begin, __nosave_end; + /* Pointer to the temporary resume page tables */ pgd_t *resume_pg_dir; @@ -156,3 +159,14 @@ int swsusp_arch_resume(void) restore_image(); return 0; } + +/* + * pfn_is_nosave - check if given pfn is in the 'nosave' section + */ + +int pfn_is_nosave(unsigned long pfn) +{ + unsigned long nosave_begin_pfn = __pa_symbol(&__nosave_begin) >> PAGE_SHIFT; + unsigned long nosave_end_pfn = PAGE_ALIGN(__pa_symbol(&__nosave_end)) >> PAGE_SHIFT; + return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn); +} diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index e0fa80eca366..aa693d0f151a 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o obj-$(CONFIG_TAU) += tau_6xx.o obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o +obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o obj32-$(CONFIG_MODULES) += module_32.o ifeq ($(CONFIG_PPC_MERGE),y) diff --git a/arch/powerpc/kernel/suspend.c b/arch/powerpc/kernel/suspend.c new file mode 100644 index 000000000000..8cee57107541 --- /dev/null +++ b/arch/powerpc/kernel/suspend.c @@ -0,0 +1,24 @@ +/* + * Suspend support specific for power. + * + * Distribute under GPLv2 + * + * Copyright (c) 2002 Pavel Machek + * Copyright (c) 2001 Patrick Mochel + */ + +#include + +/* References to section boundaries */ +extern const void __nosave_begin, __nosave_end; + +/* + * pfn_is_nosave - check if given pfn is in the 'nosave' section + */ + +int pfn_is_nosave(unsigned long pfn) +{ + unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; + unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT; + return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn); +} diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c index fe865ea4df52..4ca523d58a5b 100644 --- a/arch/x86_64/kernel/suspend.c +++ b/arch/x86_64/kernel/suspend.c @@ -13,6 +13,9 @@ #include #include +/* References to section boundaries */ +extern const void __nosave_begin, __nosave_end; + struct saved_context saved_context; unsigned long saved_context_eax, saved_context_ebx, saved_context_ecx, saved_context_edx; @@ -220,4 +223,15 @@ int swsusp_arch_resume(void) restore_image(); return 0; } + +/* + * pfn_is_nosave - check if given pfn is in the 'nosave' section + */ + +int pfn_is_nosave(unsigned long pfn) +{ + unsigned long nosave_begin_pfn = __pa_symbol(&__nosave_begin) >> PAGE_SHIFT; + unsigned long nosave_end_pfn = PAGE_ALIGN(__pa_symbol(&__nosave_end)) >> PAGE_SHIFT; + return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn); +} #endif /* CONFIG_SOFTWARE_SUSPEND */ diff --git a/kernel/power/power.h b/kernel/power/power.h index eb461b816bf4..1c6eef8df4ad 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -23,6 +23,8 @@ static inline int pm_suspend_disk(void) } #endif +extern int pfn_is_nosave(unsigned long); + extern struct mutex pm_mutex; #define power_attr(_name) \ @@ -37,9 +39,6 @@ static struct subsys_attribute _name##_attr = { \ extern struct subsystem power_subsys; -/* References to section boundaries */ -extern const void __nosave_begin, __nosave_end; - /* Preferred image size in bytes (default 500 MB) */ extern unsigned long image_size; extern int in_suspend; diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index fc53ad068128..704c25a3ffec 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -650,17 +650,6 @@ static inline void *saveable_highmem_page(unsigned long pfn) { return NULL; } static inline unsigned int count_highmem_pages(void) { return 0; } #endif /* CONFIG_HIGHMEM */ -/** - * pfn_is_nosave - check if given pfn is in the 'nosave' section - */ - -static inline int pfn_is_nosave(unsigned long pfn) -{ - unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; - unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT; - return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn); -} - /** * saveable - Determine whether a non-highmem page should be included in * the suspend image. -- cgit v1.2.3-59-g8ed1b From 0dbf7028c0c1f266c9631139450a1502d3cd457e Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:07 +0200 Subject: [PATCH] x86: __pa and __pa_symbol address space separation Currently __pa_symbol is for use with symbols in the kernel address map and __pa is for use with pointers into the physical memory map. But the code is implemented so you can usually interchange the two. __pa which is much more common can be implemented much more cheaply if it is it doesn't have to worry about any other kernel address spaces. This is especially true with a relocatable kernel as __pa_symbol needs to peform an extra variable read to resolve the address. There is a third macro that is added for the vsyscall data __pa_vsymbol for finding the physical addesses of vsyscall pages. Most of this patch is simply sorting through the references to __pa or __pa_symbol and using the proper one. A little of it is continuing to use a physical address when we have it instead of recalculating it several times. swapper_pgd is now NULL. leave_mm now uses init_mm.pgd and init_mm.pgd is initialized at boot (instead of compile time) to the physmem virtual mapping of init_level4_pgd. The physical address changed. Except for the for EMPTY_ZERO page all of the remaining references to __pa_symbol appear to be during kernel initialization. So this should reduce the cost of __pa in the common case, even on a relocated kernel. As this is technically a semantic change we need to be on the lookout for anything I missed. But it works for me (tm). Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/i386/kernel/alternative.c | 4 ++-- arch/i386/mm/init.c | 15 ++++++++------- arch/x86_64/kernel/machine_kexec.c | 14 +++++++------- arch/x86_64/kernel/setup.c | 9 +++++---- arch/x86_64/kernel/smp.c | 2 +- arch/x86_64/kernel/vsyscall.c | 9 +++++++-- arch/x86_64/mm/init.c | 21 +++++++++++---------- arch/x86_64/mm/pageattr.c | 16 ++++++++-------- include/asm-x86_64/page.h | 6 ++---- include/asm-x86_64/pgtable.h | 4 ++-- 10 files changed, 53 insertions(+), 47 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index 426f59b0106b..a27c8d347364 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -402,8 +402,8 @@ void __init alternative_instructions(void) _text, _etext); } free_init_pages("SMP alternatives", - (unsigned long)__smp_alt_begin, - (unsigned long)__smp_alt_end); + __pa_symbol(&__smp_alt_begin), + __pa_symbol(&__smp_alt_end)); } else { alternatives_smp_save(__smp_alt_instructions, __smp_alt_instructions_end); diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index ae436882af7a..23be1b0aafa4 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -774,10 +774,11 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) unsigned long addr; for (addr = begin; addr < end; addr += PAGE_SIZE) { - ClearPageReserved(virt_to_page(addr)); - init_page_count(virt_to_page(addr)); - memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); - free_page(addr); + struct page *page = pfn_to_page(addr >> PAGE_SHIFT); + ClearPageReserved(page); + init_page_count(page); + memset(page_address(page), POISON_FREE_INITMEM, PAGE_SIZE); + __free_page(page); totalram_pages++; } printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); @@ -786,14 +787,14 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) void free_initmem(void) { free_init_pages("unused kernel memory", - (unsigned long)(&__init_begin), - (unsigned long)(&__init_end)); + __pa_symbol(&__init_begin), + __pa_symbol(&__init_end)); } #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { - free_init_pages("initrd memory", start, end); + free_init_pages("initrd memory", __pa(start), __pa(end)); } #endif diff --git a/arch/x86_64/kernel/machine_kexec.c b/arch/x86_64/kernel/machine_kexec.c index 0497e3bd5bff..a8bb33c1a8f2 100644 --- a/arch/x86_64/kernel/machine_kexec.c +++ b/arch/x86_64/kernel/machine_kexec.c @@ -191,19 +191,19 @@ NORET_TYPE void machine_kexec(struct kimage *image) page_list[PA_CONTROL_PAGE] = __pa(control_page); page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel; - page_list[PA_PGD] = __pa(kexec_pgd); + page_list[PA_PGD] = __pa_symbol(&kexec_pgd); page_list[VA_PGD] = (unsigned long)kexec_pgd; - page_list[PA_PUD_0] = __pa(kexec_pud0); + page_list[PA_PUD_0] = __pa_symbol(&kexec_pud0); page_list[VA_PUD_0] = (unsigned long)kexec_pud0; - page_list[PA_PMD_0] = __pa(kexec_pmd0); + page_list[PA_PMD_0] = __pa_symbol(&kexec_pmd0); page_list[VA_PMD_0] = (unsigned long)kexec_pmd0; - page_list[PA_PTE_0] = __pa(kexec_pte0); + page_list[PA_PTE_0] = __pa_symbol(&kexec_pte0); page_list[VA_PTE_0] = (unsigned long)kexec_pte0; - page_list[PA_PUD_1] = __pa(kexec_pud1); + page_list[PA_PUD_1] = __pa_symbol(&kexec_pud1); page_list[VA_PUD_1] = (unsigned long)kexec_pud1; - page_list[PA_PMD_1] = __pa(kexec_pmd1); + page_list[PA_PMD_1] = __pa_symbol(&kexec_pmd1); page_list[VA_PMD_1] = (unsigned long)kexec_pmd1; - page_list[PA_PTE_1] = __pa(kexec_pte1); + page_list[PA_PTE_1] = __pa_symbol(&kexec_pte1); page_list[VA_PTE_1] = (unsigned long)kexec_pte1; page_list[PA_TABLE_PAGE] = diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 0e2b8df0ea64..b9bdfc1b54f8 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -243,11 +243,12 @@ void __init setup_arch(char **cmdline_p) init_mm.end_code = (unsigned long) &_etext; init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) &_end; + init_mm.pgd = __va(__pa_symbol(&init_level4_pgt)); - code_resource.start = virt_to_phys(&_text); - code_resource.end = virt_to_phys(&_etext)-1; - data_resource.start = virt_to_phys(&_etext); - data_resource.end = virt_to_phys(&_edata)-1; + code_resource.start = __pa_symbol(&_text); + code_resource.end = __pa_symbol(&_etext)-1; + data_resource.start = __pa_symbol(&_etext); + data_resource.end = __pa_symbol(&_edata)-1; early_identify_cpu(&boot_cpu_data); diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c index bd1d123947ce..22abae4e9f39 100644 --- a/arch/x86_64/kernel/smp.c +++ b/arch/x86_64/kernel/smp.c @@ -76,7 +76,7 @@ static inline void leave_mm(int cpu) if (read_pda(mmu_state) == TLBSTATE_OK) BUG(); cpu_clear(cpu, read_pda(active_mm)->cpu_vm_mask); - load_cr3(swapper_pg_dir); + load_cr3(init_mm.pgd); } /* diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index b43c698cf7d3..d14cbb3e0ebe 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c @@ -45,6 +45,11 @@ #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) #define __syscall_clobber "r11","rcx","memory" +#define __pa_vsymbol(x) \ + ({unsigned long v; \ + extern char __vsyscall_0; \ + asm("" : "=r" (v) : "0" (x)); \ + ((v - VSYSCALL_FIRST_PAGE) + __pa_symbol(&__vsyscall_0)); }) struct vsyscall_gtod_data_t { seqlock_t lock; @@ -224,10 +229,10 @@ static int vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp, return ret; /* gcc has some trouble with __va(__pa()), so just do it this way. */ - map1 = ioremap(__pa_symbol(&vsysc1), 2); + map1 = ioremap(__pa_vsymbol(&vsysc1), 2); if (!map1) return -ENOMEM; - map2 = ioremap(__pa_symbol(&vsysc2), 2); + map2 = ioremap(__pa_vsymbol(&vsysc2), 2); if (!map2) { ret = -ENOMEM; goto out; diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index b0a607892183..69e22d3c9238 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -565,11 +565,11 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); for (addr = begin; addr < end; addr += PAGE_SIZE) { - ClearPageReserved(virt_to_page(addr)); - init_page_count(virt_to_page(addr)); - memset((void *)(addr & ~(PAGE_SIZE-1)), - POISON_FREE_INITMEM, PAGE_SIZE); - free_page(addr); + struct page *page = pfn_to_page(addr >> PAGE_SHIFT); + ClearPageReserved(page); + init_page_count(page); + memset(page_address(page), POISON_FREE_INITMEM, PAGE_SIZE); + __free_page(page); totalram_pages++; } } @@ -579,17 +579,18 @@ void free_initmem(void) memset(__initdata_begin, POISON_FREE_INITDATA, __initdata_end - __initdata_begin); free_init_pages("unused kernel memory", - (unsigned long)(&__init_begin), - (unsigned long)(&__init_end)); + __pa_symbol(&__init_begin), + __pa_symbol(&__init_end)); } #ifdef CONFIG_DEBUG_RODATA void mark_rodata_ro(void) { - unsigned long addr = (unsigned long)__start_rodata; + unsigned long addr = (unsigned long)__va(__pa_symbol(&__start_rodata)); + unsigned long end = (unsigned long)__va(__pa_symbol(&__end_rodata)); - for (; addr < (unsigned long)__end_rodata; addr += PAGE_SIZE) + for (; addr < end; addr += PAGE_SIZE) change_page_attr_addr(addr, 1, PAGE_KERNEL_RO); printk ("Write protecting the kernel read-only data: %luk\n", @@ -608,7 +609,7 @@ void mark_rodata_ro(void) #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { - free_init_pages("initrd memory", start, end); + free_init_pages("initrd memory", __pa(start), __pa(end)); } #endif diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c index 081409aa3452..76ee90a5abe0 100644 --- a/arch/x86_64/mm/pageattr.c +++ b/arch/x86_64/mm/pageattr.c @@ -51,7 +51,6 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot, SetPagePrivate(base); page_private(base) = 0; - address = __pa(address); addr = address & LARGE_PAGE_MASK; pbase = (pte_t *)page_address(base); for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) { @@ -101,13 +100,12 @@ static inline void save_page(struct page *fpage) * No more special protections in this 2/4MB area - revert to a * large page again. */ -static void revert_page(unsigned long address, pgprot_t ref_prot) +static void revert_page(unsigned long address, unsigned long pfn, pgprot_t ref_prot) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t large_pte; - unsigned long pfn; pgd = pgd_offset_k(address); BUG_ON(pgd_none(*pgd)); @@ -115,7 +113,6 @@ static void revert_page(unsigned long address, pgprot_t ref_prot) BUG_ON(pud_none(*pud)); pmd = pmd_offset(pud, address); BUG_ON(pmd_val(*pmd) & _PAGE_PSE); - pfn = (__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT; large_pte = pfn_pte(pfn, ref_prot); large_pte = pte_mkhuge(large_pte); set_pte((pte_t *)pmd, large_pte); @@ -141,7 +138,8 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot, */ struct page *split; ref_prot2 = pte_pgprot(pte_clrhuge(*kpte)); - split = split_large_page(address, prot, ref_prot2); + split = split_large_page(pfn << PAGE_SHIFT, prot, + ref_prot2); if (!split) return -ENOMEM; set_pte(kpte, mk_pte(split, ref_prot2)); @@ -160,7 +158,7 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot, if (page_private(kpte_page) == 0) { save_page(kpte_page); - revert_page(address, ref_prot); + revert_page(address, pfn, ref_prot); } return 0; } @@ -180,6 +178,7 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot, */ int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot) { + unsigned long phys_base_pfn = __pa_symbol(__START_KERNEL_map) >> PAGE_SHIFT; int err = 0; int i; @@ -192,10 +191,11 @@ int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot) break; /* Handle kernel mapping too which aliases part of the * lowmem */ - if (__pa(address) < KERNEL_TEXT_SIZE) { + if ((pfn >= phys_base_pfn) && + ((pfn - phys_base_pfn) < (KERNEL_TEXT_SIZE >> PAGE_SHIFT))) { unsigned long addr2; pgprot_t prot2; - addr2 = __START_KERNEL_map + __pa(address); + addr2 = __START_KERNEL_map + ((pfn - phys_base_pfn) << PAGE_SHIFT); /* Make sure the kernel mappings stay executable */ prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot))); err = __change_page_attr(addr2, pfn, prot2, diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h index d554b94485df..4974433bbf34 100644 --- a/include/asm-x86_64/page.h +++ b/include/asm-x86_64/page.h @@ -102,17 +102,15 @@ typedef struct { unsigned long pgprot; } pgprot_t; /* Note: __pa(&symbol_visible_to_c) should be always replaced with __pa_symbol. Otherwise you risk miscompilation. */ -#define __pa(x) (((unsigned long)(x)>=__START_KERNEL_map)?(unsigned long)(x) - (unsigned long)__START_KERNEL_map:(unsigned long)(x) - PAGE_OFFSET) +#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET) /* __pa_symbol should be used for C visible symbols. This seems to be the official gcc blessed way to do such arithmetic. */ #define __pa_symbol(x) \ ({unsigned long v; \ asm("" : "=r" (v) : "0" (x)); \ - __pa(v); }) + (v - __START_KERNEL_map); }) #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) -#define __boot_va(x) __va(x) -#define __boot_pa(x) __pa(x) #ifdef CONFIG_FLATMEM #define pfn_valid(pfn) ((pfn) < end_pfn) #endif diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h index 703f0243f27a..c1865e38c7b7 100644 --- a/include/asm-x86_64/pgtable.h +++ b/include/asm-x86_64/pgtable.h @@ -19,7 +19,7 @@ extern pmd_t level2_kernel_pgt[512]; extern pgd_t init_level4_pgt[]; extern unsigned long __supported_pte_mask; -#define swapper_pg_dir init_level4_pgt +#define swapper_pg_dir ((pgd_t *)NULL) extern void paging_init(void); extern void clear_kernel_mapping(unsigned long addr, unsigned long size); @@ -29,7 +29,7 @@ extern void clear_kernel_mapping(unsigned long addr, unsigned long size); * for zero-mapped memory areas etc.. */ extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)]; -#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) +#define ZERO_PAGE(vaddr) (pfn_to_page(__pa_symbol(&empty_zero_page) >> PAGE_SHIFT)) #endif /* !__ASSEMBLY__ */ -- cgit v1.2.3-59-g8ed1b From 1ab60e0f72f71ec54831e525a3e1154f1c092408 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:07 +0200 Subject: [PATCH] x86-64: Relocatable Kernel Support This patch modifies the x86_64 kernel so that it can be loaded and run at any 2M aligned address, below 512G. The technique used is to compile the decompressor with -fPIC and modify it so the decompressor is fully relocatable. For the main kernel the page tables are modified so the kernel remains at the same virtual address. In addition a variable phys_base is kept that holds the physical address the kernel is loaded at. __pa_symbol is modified to add that when we take the address of a kernel symbol. When loaded with a normal bootloader the decompressor will decompress the kernel to 2M and it will run there. This both ensures the relocation code is always working, and makes it easier to use 2M pages for the kernel and the cpu. AK: changed to not make RELOCATABLE default in Kconfig Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/Kconfig | 49 ++++- arch/x86_64/boot/compressed/Makefile | 12 +- arch/x86_64/boot/compressed/head.S | 322 +++++++++++++++++++++++--------- arch/x86_64/boot/compressed/misc.c | 247 ++++++++++++------------ arch/x86_64/boot/compressed/vmlinux.lds | 44 +++++ arch/x86_64/boot/compressed/vmlinux.scr | 9 +- arch/x86_64/kernel/head.S | 233 +++++++++++++---------- arch/x86_64/kernel/suspend_asm.S | 7 +- include/asm-x86_64/page.h | 6 +- 9 files changed, 597 insertions(+), 332 deletions(-) create mode 100644 arch/x86_64/boot/compressed/vmlinux.lds (limited to 'arch') diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index b3dbf11eb82c..715632026073 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -565,23 +565,56 @@ config CRASH_DUMP PHYSICAL_START. For more details see Documentation/kdump/kdump.txt +config RELOCATABLE + bool "Build a relocatable kernel(EXPERIMENTAL)" + depends on EXPERIMENTAL + help + Builds a relocatable kernel. This enables loading and running + a kernel binary from a different physical address than it has + been compiled for. + + One use is for the kexec on panic case where the recovery kernel + must live at a different physical address than the primary + kernel. + + Note: If CONFIG_RELOCATABLE=y, then kernel run from the address + it has been loaded at and compile time physical address + (CONFIG_PHYSICAL_START) is ignored. + config PHYSICAL_START hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) - default "0x1000000" if CRASH_DUMP default "0x200000" help - This gives the physical address where the kernel is loaded. Normally - for regular kernels this value is 0x200000 (2MB). But in the case - of kexec on panic the fail safe kernel needs to run at a different - address than the panic-ed kernel. This option is used to set the load - address for kernels used to capture crash dump on being kexec'ed - after panic. The default value for crash dump kernels is - 0x1000000 (16MB). This can also be set based on the "X" value as + This gives the physical address where the kernel is loaded. It + should be aligned to 2MB boundary. + + If kernel is a not relocatable (CONFIG_RELOCATABLE=n) then + bzImage will decompress itself to above physical address and + run from there. Otherwise, bzImage will run from the address where + it has been loaded by the boot loader and will ignore above physical + address. + + In normal kdump cases one does not have to set/change this option + as now bzImage can be compiled as a completely relocatable image + (CONFIG_RELOCATABLE=y) and be used to load and run from a different + address. This option is mainly useful for the folks who don't want + to use a bzImage for capturing the crash dump and want to use a + vmlinux instead. + + So if you are using bzImage for capturing the crash dump, leave + the value here unchanged to 0x200000 and set CONFIG_RELOCATABLE=y. + Otherwise if you plan to use vmlinux for capturing the crash dump + change this value to start of the reserved region (Typically 16MB + 0x1000000). In other words, it can be set based on the "X" value as specified in the "crashkernel=YM@XM" command line boot parameter passed to the panic-ed kernel. Typically this parameter is set as crashkernel=64M@16M. Please take a look at Documentation/kdump/kdump.txt for more details about crash dumps. + Usage of bzImage for capturing the crash dump is advantageous as + one does not have to build two kernels. Same kernel can be used + as production kernel and capture kernel. + Don't change this unless you know what you are doing. config SECCOMP diff --git a/arch/x86_64/boot/compressed/Makefile b/arch/x86_64/boot/compressed/Makefile index e70fa6e1da08..705a3e33d7e1 100644 --- a/arch/x86_64/boot/compressed/Makefile +++ b/arch/x86_64/boot/compressed/Makefile @@ -8,16 +8,14 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o EXTRA_AFLAGS := -traditional -AFLAGS := $(subst -m64,-m32,$(AFLAGS)) # cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with # -m32 -CFLAGS := -m32 -D__KERNEL__ -Iinclude -O2 -fno-strict-aliasing -LDFLAGS := -m elf_i386 +CFLAGS := -m64 -D__KERNEL__ -Iinclude -O2 -fno-strict-aliasing -fPIC -mcmodel=small -fno-builtin +LDFLAGS := -m elf_x86_64 -LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup_32 -m elf_i386 - -$(obj)/vmlinux: $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE +LDFLAGS_vmlinux := -T +$(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE $(call if_changed,ld) @: @@ -27,7 +25,7 @@ $(obj)/vmlinux.bin: vmlinux FORCE $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE $(call if_changed,gzip) -LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T +LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE $(call if_changed,ld) diff --git a/arch/x86_64/boot/compressed/head.S b/arch/x86_64/boot/compressed/head.S index 6f55565e4d42..c353a9266ea4 100644 --- a/arch/x86_64/boot/compressed/head.S +++ b/arch/x86_64/boot/compressed/head.S @@ -26,116 +26,262 @@ #include #include +#include #include +#include +.section ".text.head" .code32 .globl startup_32 - + startup_32: cld cli - movl $(__KERNEL_DS),%eax - movl %eax,%ds - movl %eax,%es - movl %eax,%fs - movl %eax,%gs - - lss stack_start,%esp - xorl %eax,%eax -1: incl %eax # check that A20 really IS enabled - movl %eax,0x000000 # loop forever if it isn't - cmpl %eax,0x100000 - je 1b + movl $(__KERNEL_DS), %eax + movl %eax, %ds + movl %eax, %es + movl %eax, %ss + +/* Calculate the delta between where we were compiled to run + * at and where we were actually loaded at. This can only be done + * with a short local call on x86. Nothing else will tell us what + * address we are running at. The reserved chunk of the real-mode + * data at 0x34-0x3f are used as the stack for this calculation. + * Only 4 bytes are needed. + */ + leal 0x40(%esi), %esp + call 1f +1: popl %ebp + subl $1b, %ebp + +/* Compute the delta between where we were compiled to run at + * and where the code will actually run at. + */ +/* %ebp contains the address we are loaded at by the boot loader and %ebx + * contains the address where we should move the kernel image temporarily + * for safe in-place decompression. + */ + +#ifdef CONFIG_RELOCATABLE + movl %ebp, %ebx + addl $(LARGE_PAGE_SIZE -1), %ebx + andl $LARGE_PAGE_MASK, %ebx +#else + movl $CONFIG_PHYSICAL_START, %ebx +#endif + + /* Replace the compressed data size with the uncompressed size */ + subl input_len(%ebp), %ebx + movl output_len(%ebp), %eax + addl %eax, %ebx + /* Add 8 bytes for every 32K input block */ + shrl $12, %eax + addl %eax, %ebx + /* Add 32K + 18 bytes of extra slack and align on a 4K boundary */ + addl $(32768 + 18 + 4095), %ebx + andl $~4095, %ebx /* - * Initialize eflags. Some BIOS's leave bits like NT set. This would - * confuse the debugger if this code is traced. - * XXX - best to initialize before switching to protected mode. + * Prepare for entering 64 bit mode */ - pushl $0 - popfl + + /* Load new GDT with the 64bit segments using 32bit descriptor */ + leal gdt(%ebp), %eax + movl %eax, gdt+2(%ebp) + lgdt gdt(%ebp) + + /* Enable PAE mode */ + xorl %eax, %eax + orl $(1 << 5), %eax + movl %eax, %cr4 + + /* + * Build early 4G boot pagetable + */ + /* Initialize Page tables to 0*/ + leal pgtable(%ebx), %edi + xorl %eax, %eax + movl $((4096*6)/4), %ecx + rep stosl + + /* Build Level 4 */ + leal pgtable + 0(%ebx), %edi + leal 0x1007 (%edi), %eax + movl %eax, 0(%edi) + + /* Build Level 3 */ + leal pgtable + 0x1000(%ebx), %edi + leal 0x1007(%edi), %eax + movl $4, %ecx +1: movl %eax, 0x00(%edi) + addl $0x00001000, %eax + addl $8, %edi + decl %ecx + jnz 1b + + /* Build Level 2 */ + leal pgtable + 0x2000(%ebx), %edi + movl $0x00000183, %eax + movl $2048, %ecx +1: movl %eax, 0(%edi) + addl $0x00200000, %eax + addl $8, %edi + decl %ecx + jnz 1b + + /* Enable the boot page tables */ + leal pgtable(%ebx), %eax + movl %eax, %cr3 + + /* Enable Long mode in EFER (Extended Feature Enable Register) */ + movl $MSR_EFER, %ecx + rdmsr + btsl $_EFER_LME, %eax + wrmsr + + /* Setup for the jump to 64bit mode + * + * When the jump is performend we will be in long mode but + * in 32bit compatibility mode with EFER.LME = 1, CS.L = 0, CS.D = 1 + * (and in turn EFER.LMA = 1). To jump into 64bit mode we use + * the new gdt/idt that has __KERNEL_CS with CS.L = 1. + * We place all of the values on our mini stack so lret can + * used to perform that far jump. + */ + pushl $__KERNEL_CS + leal startup_64(%ebp), %eax + pushl %eax + + /* Enter paged protected Mode, activating Long Mode */ + movl $0x80000001, %eax /* Enable Paging and Protected mode */ + movl %eax, %cr0 + + /* Jump from 32bit compatibility mode into 64bit mode. */ + lret + + /* Be careful here startup_64 needs to be at a predictable + * address so I can export it in an ELF header. Bootloaders + * should look at the ELF header to find this address, as + * it may change in the future. + */ + .code64 + .org 0x100 +ENTRY(startup_64) + /* We come here either from startup_32 or directly from a + * 64bit bootloader. If we come here from a bootloader we depend on + * an identity mapped page table being provied that maps our + * entire text+data+bss and hopefully all of memory. + */ + + /* Setup data segments. */ + xorl %eax, %eax + movl %eax, %ds + movl %eax, %es + movl %eax, %ss + + /* Compute the decompressed kernel start address. It is where + * we were loaded at aligned to a 2M boundary. %rbp contains the + * decompressed kernel start address. + * + * If it is a relocatable kernel then decompress and run the kernel + * from load address aligned to 2MB addr, otherwise decompress and + * run the kernel from CONFIG_PHYSICAL_START + */ + + /* Start with the delta to where the kernel will run at. */ +#ifdef CONFIG_RELOCATABLE + leaq startup_32(%rip) /* - $startup_32 */, %rbp + addq $(LARGE_PAGE_SIZE - 1), %rbp + andq $LARGE_PAGE_MASK, %rbp + movq %rbp, %rbx +#else + movq $CONFIG_PHYSICAL_START, %rbp + movq %rbp, %rbx +#endif + + /* Replace the compressed data size with the uncompressed size */ + movl input_len(%rip), %eax + subq %rax, %rbx + movl output_len(%rip), %eax + addq %rax, %rbx + /* Add 8 bytes for every 32K input block */ + shrq $12, %rax + addq %rax, %rbx + /* Add 32K + 18 bytes of extra slack and align on a 4K boundary */ + addq $(32768 + 18 + 4095), %rbx + andq $~4095, %rbx + +/* Copy the compressed kernel to the end of our buffer + * where decompression in place becomes safe. + */ + leaq _end(%rip), %r8 + leaq _end(%rbx), %r9 + movq $_end /* - $startup_32 */, %rcx +1: subq $8, %r8 + subq $8, %r9 + movq 0(%r8), %rax + movq %rax, 0(%r9) + subq $8, %rcx + jnz 1b + +/* + * Jump to the relocated address. + */ + leaq relocated(%rbx), %rax + jmp *%rax + +.section ".text" +relocated: + /* * Clear BSS */ - xorl %eax,%eax - movl $_edata,%edi - movl $_end,%ecx - subl %edi,%ecx + xorq %rax, %rax + leaq _edata(%rbx), %rdi + leaq _end(%rbx), %rcx + subq %rdi, %rcx cld rep stosb + + /* Setup the stack */ + leaq user_stack_end(%rip), %rsp + + /* zero EFLAGS after setting rsp */ + pushq $0 + popfq + /* * Do the decompression, and jump to the new kernel.. */ - subl $16,%esp # place for structure on the stack - movl %esp,%eax - pushl %esi # real mode pointer as second arg - pushl %eax # address of structure as first arg - call decompress_kernel - orl %eax,%eax - jnz 3f - addl $8,%esp - xorl %ebx,%ebx - ljmp $(__KERNEL_CS), $__PHYSICAL_START + pushq %rsi # Save the real mode argument + movq %rsi, %rdi # real mode address + leaq _heap(%rip), %rsi # _heap + leaq input_data(%rip), %rdx # input_data + movl input_len(%rip), %eax + movq %rax, %rcx # input_len + movq %rbp, %r8 # output + call decompress_kernel + popq %rsi -/* - * We come here, if we were loaded high. - * We need to move the move-in-place routine down to 0x1000 - * and then start it with the buffer addresses in registers, - * which we got from the stack. - */ -3: - movl %esi,%ebx - movl $move_routine_start,%esi - movl $0x1000,%edi - movl $move_routine_end,%ecx - subl %esi,%ecx - addl $3,%ecx - shrl $2,%ecx - cld - rep - movsl - - popl %esi # discard the address - addl $4,%esp # real mode pointer - popl %esi # low_buffer_start - popl %ecx # lcount - popl %edx # high_buffer_start - popl %eax # hcount - movl $__PHYSICAL_START,%edi - cli # make sure we don't get interrupted - ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine /* - * Routine (template) for moving the decompressed kernel in place, - * if we were high loaded. This _must_ PIC-code ! + * Jump to the decompressed kernel. */ -move_routine_start: - movl %ecx,%ebp - shrl $2,%ecx - rep - movsl - movl %ebp,%ecx - andl $3,%ecx - rep - movsb - movl %edx,%esi - movl %eax,%ecx # NOTE: rep movsb won't move if %ecx == 0 - addl $3,%ecx - shrl $2,%ecx - rep - movsl - movl %ebx,%esi # Restore setup pointer - xorl %ebx,%ebx - ljmp $(__KERNEL_CS), $__PHYSICAL_START -move_routine_end: + jmp *%rbp - -/* Stack for uncompression */ - .align 32 -user_stack: + .data +gdt: + .word gdt_end - gdt + .long gdt + .word 0 + .quad 0x0000000000000000 /* NULL descriptor */ + .quad 0x00af9a000000ffff /* __KERNEL_CS */ + .quad 0x00cf92000000ffff /* __KERNEL_DS */ +gdt_end: + .bss +/* Stack for uncompression */ + .balign 4 +user_stack: .fill 4096,4,0 -stack_start: - .long user_stack+4096 - .word __KERNEL_DS - +user_stack_end: diff --git a/arch/x86_64/boot/compressed/misc.c b/arch/x86_64/boot/compressed/misc.c index 3755b2e394d0..fee54dbf1749 100644 --- a/arch/x86_64/boot/compressed/misc.c +++ b/arch/x86_64/boot/compressed/misc.c @@ -9,10 +9,95 @@ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 */ +#define _LINUX_STRING_H_ 1 +#define __LINUX_BITMAP_H 1 + +#include #include #include #include +/* WARNING!! + * This code is compiled with -fPIC and it is relocated dynamically + * at run time, but no relocation processing is performed. + * This means that it is not safe to place pointers in static structures. + */ + +/* + * Getting to provable safe in place decompression is hard. + * Worst case behaviours need to be analized. + * Background information: + * + * The file layout is: + * magic[2] + * method[1] + * flags[1] + * timestamp[4] + * extraflags[1] + * os[1] + * compressed data blocks[N] + * crc[4] orig_len[4] + * + * resulting in 18 bytes of non compressed data overhead. + * + * Files divided into blocks + * 1 bit (last block flag) + * 2 bits (block type) + * + * 1 block occurs every 32K -1 bytes or when there 50% compression has been achieved. + * The smallest block type encoding is always used. + * + * stored: + * 32 bits length in bytes. + * + * fixed: + * magic fixed tree. + * symbols. + * + * dynamic: + * dynamic tree encoding. + * symbols. + * + * + * The buffer for decompression in place is the length of the + * uncompressed data, plus a small amount extra to keep the algorithm safe. + * The compressed data is placed at the end of the buffer. The output + * pointer is placed at the start of the buffer and the input pointer + * is placed where the compressed data starts. Problems will occur + * when the output pointer overruns the input pointer. + * + * The output pointer can only overrun the input pointer if the input + * pointer is moving faster than the output pointer. A condition only + * triggered by data whose compressed form is larger than the uncompressed + * form. + * + * The worst case at the block level is a growth of the compressed data + * of 5 bytes per 32767 bytes. + * + * The worst case internal to a compressed block is very hard to figure. + * The worst case can at least be boundined by having one bit that represents + * 32764 bytes and then all of the rest of the bytes representing the very + * very last byte. + * + * All of which is enough to compute an amount of extra data that is required + * to be safe. To avoid problems at the block level allocating 5 extra bytes + * per 32767 bytes of data is sufficient. To avoind problems internal to a block + * adding an extra 32767 bytes (the worst case uncompressed block size) is + * sufficient, to ensure that in the worst case the decompressed data for + * block will stop the byte before the compressed data for a block begins. + * To avoid problems with the compressed data's meta information an extra 18 + * bytes are needed. Leading to the formula: + * + * extra_bytes = (uncompressed_size >> 12) + 32768 + 18 + decompressor_size. + * + * Adding 8 bytes per 32K is a bit excessive but much easier to calculate. + * Adding 32768 instead of 32767 just makes for round numbers. + * Adding the decompressor_size is necessary as it musht live after all + * of the data as well. Last I measured the decompressor is about 14K. + * 10K of actuall data and 4K of bss. + * + */ + /* * gzip declarations */ @@ -28,15 +113,20 @@ typedef unsigned char uch; typedef unsigned short ush; typedef unsigned long ulg; -#define WSIZE 0x8000 /* Window size must be at least 32k, */ - /* and a power of two */ +#define WSIZE 0x80000000 /* Window size must be at least 32k, + * and a power of two + * We don't actually have a window just + * a huge output buffer so I report + * a 2G windows size, as that should + * always be larger than our output buffer. + */ -static uch *inbuf; /* input buffer */ -static uch window[WSIZE]; /* Sliding window buffer */ +static uch *inbuf; /* input buffer */ +static uch *window; /* Sliding window buffer, (and final output buffer) */ -static unsigned insize = 0; /* valid bytes in inbuf */ -static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ -static unsigned outcnt = 0; /* bytes in output buffer */ +static unsigned insize; /* valid bytes in inbuf */ +static unsigned inptr; /* index of next byte to be processed in inbuf */ +static unsigned outcnt; /* bytes in output buffer */ /* gzip flag byte */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ @@ -87,8 +177,6 @@ extern unsigned char input_data[]; extern int input_len; static long bytes_out = 0; -static uch *output_data; -static unsigned long output_ptr = 0; static void *malloc(int size); static void free(void *where); @@ -98,17 +186,10 @@ static void *memcpy(void *dest, const void *src, unsigned n); static void putstr(const char *); -extern int end; -static long free_mem_ptr = (long)&end; +static long free_mem_ptr; static long free_mem_end_ptr; -#define INPLACE_MOVE_ROUTINE 0x1000 -#define LOW_BUFFER_START 0x2000 -#define LOW_BUFFER_MAX 0x90000 -#define HEAP_SIZE 0x3000 -static unsigned int low_buffer_end, low_buffer_size; -static int high_loaded =0; -static uch *high_buffer_start /* = (uch *)(((ulg)&end) + HEAP_SIZE)*/; +#define HEAP_SIZE 0x6000 static char *vidmem = (char *)0xb8000; static int vidport; @@ -218,58 +299,31 @@ static void* memcpy(void* dest, const void* src, unsigned n) */ static int fill_inbuf(void) { - if (insize != 0) { - error("ran out of input data"); - } - - inbuf = input_data; - insize = input_len; - inptr = 1; - return inbuf[0]; + error("ran out of input data"); + return 0; } /* =========================================================================== * Write the output window window[0..outcnt-1] and update crc and bytes_out. * (Used for the decompressed data only.) */ -static void flush_window_low(void) -{ - ulg c = crc; /* temporary variable */ - unsigned n; - uch *in, *out, ch; - - in = window; - out = &output_data[output_ptr]; - for (n = 0; n < outcnt; n++) { - ch = *out++ = *in++; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - output_ptr += (ulg)outcnt; - outcnt = 0; -} - -static void flush_window_high(void) -{ - ulg c = crc; /* temporary variable */ - unsigned n; - uch *in, ch; - in = window; - for (n = 0; n < outcnt; n++) { - ch = *output_data++ = *in++; - if ((ulg)output_data == low_buffer_end) output_data=high_buffer_start; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - outcnt = 0; -} - static void flush_window(void) { - if (high_loaded) flush_window_high(); - else flush_window_low(); + /* With my window equal to my output buffer + * I only need to compute the crc here. + */ + ulg c = crc; /* temporary variable */ + unsigned n; + uch *in, ch; + + in = window; + for (n = 0; n < outcnt; n++) { + ch = *in++; + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + bytes_out += (ulg)outcnt; + outcnt = 0; } static void error(char *x) @@ -281,57 +335,8 @@ static void error(char *x) while(1); /* Halt */ } -static void setup_normal_output_buffer(void) -{ -#ifdef STANDARD_MEMORY_BIOS_CALL - if (RM_EXT_MEM_K < 1024) error("Less than 2MB of memory"); -#else - if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); -#endif - output_data = (unsigned char *)__PHYSICAL_START; /* Normally Points to 1M */ - free_mem_end_ptr = (long)real_mode; -} - -struct moveparams { - uch *low_buffer_start; int lcount; - uch *high_buffer_start; int hcount; -}; - -static void setup_output_buffer_if_we_run_high(struct moveparams *mv) -{ - high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE); -#ifdef STANDARD_MEMORY_BIOS_CALL - if (RM_EXT_MEM_K < (3*1024)) error("Less than 4MB of memory"); -#else - if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory"); -#endif - mv->low_buffer_start = output_data = (unsigned char *)LOW_BUFFER_START; - low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX - ? LOW_BUFFER_MAX : (unsigned int)real_mode) & ~0xfff; - low_buffer_size = low_buffer_end - LOW_BUFFER_START; - high_loaded = 1; - free_mem_end_ptr = (long)high_buffer_start; - if ( (__PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) { - high_buffer_start = (uch *)(__PHYSICAL_START + low_buffer_size); - mv->hcount = 0; /* say: we need not to move high_buffer */ - } - else mv->hcount = -1; - mv->high_buffer_start = high_buffer_start; -} - -static void close_output_buffer_if_we_run_high(struct moveparams *mv) -{ - if (bytes_out > low_buffer_size) { - mv->lcount = low_buffer_size; - if (mv->hcount) - mv->hcount = bytes_out - low_buffer_size; - } else { - mv->lcount = bytes_out; - mv->hcount = 0; - } -} - -int decompress_kernel(struct moveparams *mv, void *rmode) +asmlinkage void decompress_kernel(void *rmode, unsigned long heap, + uch *input_data, unsigned long input_len, uch *output) { real_mode = rmode; @@ -346,13 +351,21 @@ int decompress_kernel(struct moveparams *mv, void *rmode) lines = RM_SCREEN_INFO.orig_video_lines; cols = RM_SCREEN_INFO.orig_video_cols; - if (free_mem_ptr < 0x100000) setup_normal_output_buffer(); - else setup_output_buffer_if_we_run_high(mv); + window = output; /* Output buffer (Normally at 1M) */ + free_mem_ptr = heap; /* Heap */ + free_mem_end_ptr = heap + HEAP_SIZE; + inbuf = input_data; /* Input buffer */ + insize = input_len; + inptr = 0; + + if ((ulg)output & 0x1fffffUL) + error("Destination address not 2M aligned"); + if ((ulg)output >= 0xffffffffffUL) + error("Destination address too large"); makecrc(); putstr(".\nDecompressing Linux..."); gunzip(); putstr("done.\nBooting the kernel.\n"); - if (high_loaded) close_output_buffer_if_we_run_high(mv); - return high_loaded; + return; } diff --git a/arch/x86_64/boot/compressed/vmlinux.lds b/arch/x86_64/boot/compressed/vmlinux.lds new file mode 100644 index 000000000000..94c13e557fb4 --- /dev/null +++ b/arch/x86_64/boot/compressed/vmlinux.lds @@ -0,0 +1,44 @@ +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") +OUTPUT_ARCH(i386:x86-64) +ENTRY(startup_64) +SECTIONS +{ + /* Be careful parts of head.S assume startup_32 is at + * address 0. + */ + . = 0; + .text : { + _head = . ; + *(.text.head) + _ehead = . ; + *(.text.compressed) + _text = .; /* Text */ + *(.text) + *(.text.*) + _etext = . ; + } + .rodata : { + _rodata = . ; + *(.rodata) /* read-only data */ + *(.rodata.*) + _erodata = . ; + } + .data : { + _data = . ; + *(.data) + *(.data.*) + _edata = . ; + } + .bss : { + _bss = . ; + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(8); + _end = . ; + . = ALIGN(4096); + pgtable = . ; + . = . + 4096 * 6; + _heap = .; + } +} diff --git a/arch/x86_64/boot/compressed/vmlinux.scr b/arch/x86_64/boot/compressed/vmlinux.scr index 1ed9d791f863..bd1429ce193e 100644 --- a/arch/x86_64/boot/compressed/vmlinux.scr +++ b/arch/x86_64/boot/compressed/vmlinux.scr @@ -1,9 +1,10 @@ SECTIONS { - .data : { + .text.compressed : { input_len = .; - LONG(input_data_end - input_data) input_data = .; - *(.data) - input_data_end = .; + LONG(input_data_end - input_data) input_data = .; + *(.data) + output_len = . - 4; + input_data_end = .; } } diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index c211e52f1333..36aa98a6d15c 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S @@ -5,6 +5,7 @@ * Copyright (C) 2000 Pavel Machek * Copyright (C) 2000 Karsten Keil * Copyright (C) 2001,2002 Andi Kleen + * Copyright (C) 2005 Eric Biederman */ @@ -17,95 +18,127 @@ #include #include #include - + /* we are not able to switch in one step to the final KERNEL ADRESS SPACE - * because we need identity-mapped pages on setup so define __START_KERNEL to - * 0x100000 for this stage - * + * because we need identity-mapped pages. + * */ .text .section .bootstrap.text - .code32 - .globl startup_32 -/* %bx: 1 if coming from smp trampoline on secondary cpu */ -startup_32: - + .code64 + .globl startup_64 +startup_64: + /* - * At this point the CPU runs in 32bit protected mode (CS.D = 1) with - * paging disabled and the point of this file is to switch to 64bit - * long mode with a kernel mapping for kerneland to jump into the - * kernel virtual addresses. - * There is no stack until we set one up. + * At this point the CPU runs in 64bit mode CS.L = 1 CS.D = 1, + * and someone has loaded an identity mapped page table + * for us. These identity mapped page tables map all of the + * kernel pages and possibly all of memory. + * + * %esi holds a physical pointer to real_mode_data. + * + * We come here either directly from a 64bit bootloader, or from + * arch/x86_64/boot/compressed/head.S. + * + * We only come here initially at boot nothing else comes here. + * + * Since we may be loaded at an address different from what we were + * compiled to run at we first fixup the physical addresses in our page + * tables and then reload them. */ - /* Initialize the %ds segment register */ - movl $__KERNEL_DS,%eax - movl %eax,%ds - - /* Load new GDT with the 64bit segments using 32bit descriptor */ - lgdt pGDT32 - __START_KERNEL_map - - /* If the CPU doesn't support CPUID this will double fault. - * Unfortunately it is hard to check for CPUID without a stack. + /* Compute the delta between the address I am compiled to run at and the + * address I am actually running at. */ - - /* Check if extended functions are implemented */ - movl $0x80000000, %eax - cpuid - cmpl $0x80000000, %eax - jbe no_long_mode - /* Check if long mode is implemented */ - mov $0x80000001, %eax - cpuid - btl $29, %edx - jnc no_long_mode - - /* - * Prepare for entering 64bits mode + leaq _text(%rip), %rbp + subq $_text - __START_KERNEL_map, %rbp + + /* Is the address not 2M aligned? */ + movq %rbp, %rax + andl $~LARGE_PAGE_MASK, %eax + testl %eax, %eax + jnz bad_address + + /* Is the address too large? */ + leaq _text(%rip), %rdx + movq $PGDIR_SIZE, %rax + cmpq %rax, %rdx + jae bad_address + + /* Fixup the physical addresses in the page table */ + addq %rbp, init_level4_pgt + 0(%rip) + addq %rbp, init_level4_pgt + (258*8)(%rip) + addq %rbp, init_level4_pgt + (511*8)(%rip) + + addq %rbp, level3_ident_pgt + 0(%rip) + addq %rbp, level3_kernel_pgt + (510*8)(%rip) + + /* Add an Identity mapping if I am above 1G */ + leaq _text(%rip), %rdi + andq $LARGE_PAGE_MASK, %rdi + + movq %rdi, %rax + shrq $PUD_SHIFT, %rax + andq $(PTRS_PER_PUD - 1), %rax + jz ident_complete + + leaq (level2_spare_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx + leaq level3_ident_pgt(%rip), %rbx + movq %rdx, 0(%rbx, %rax, 8) + + movq %rdi, %rax + shrq $PMD_SHIFT, %rax + andq $(PTRS_PER_PMD - 1), %rax + leaq __PAGE_KERNEL_LARGE_EXEC(%rdi), %rdx + leaq level2_spare_pgt(%rip), %rbx + movq %rdx, 0(%rbx, %rax, 8) +ident_complete: + + /* Fixup the kernel text+data virtual addresses + */ + leaq level2_kernel_pgt(%rip), %rdi + leaq 4096(%rdi), %r8 + /* See if it is a valid page table entry */ +1: testq $1, 0(%rdi) + jz 2f + addq %rbp, 0(%rdi) + /* Go to the next page */ +2: addq $8, %rdi + cmp %r8, %rdi + jne 1b + + /* Fixup phys_base */ + addq %rbp, phys_base(%rip) - /* Enable PAE mode */ - xorl %eax, %eax - btsl $5, %eax - movl %eax, %cr4 - - /* Setup early boot stage 4 level pagetables */ - movl $(init_level4_pgt - __START_KERNEL_map), %eax - movl %eax, %cr3 - - /* Setup EFER (Extended Feature Enable Register) */ - movl $MSR_EFER, %ecx - rdmsr - - /* Enable Long Mode */ - btsl $_EFER_LME, %eax - - /* Make changes effective */ - wrmsr +#ifdef CONFIG_SMP + addq %rbp, trampoline_level4_pgt + 0(%rip) + addq %rbp, trampoline_level4_pgt + (511*8)(%rip) +#endif +#ifdef CONFIG_ACPI_SLEEP + addq %rbp, wakeup_level4_pgt + 0(%rip) + addq %rbp, wakeup_level4_pgt + (511*8)(%rip) +#endif - xorl %eax, %eax - btsl $31, %eax /* Enable paging and in turn activate Long Mode */ - btsl $0, %eax /* Enable protected mode */ - /* Make changes effective */ - movl %eax, %cr0 - /* - * At this point we're in long mode but in 32bit compatibility mode - * with EFER.LME = 1, CS.L = 0, CS.D = 1 (and in turn - * EFER.LMA = 1). Now we want to jump in 64bit mode, to do that we use - * the new gdt/idt that has __KERNEL_CS with CS.L = 1. + /* Due to ENTRY(), sometimes the empty space gets filled with + * zeros. Better take a jmp than relying on empty space being + * filled with 0x90 (nop) */ - ljmp $__KERNEL_CS, $(startup_64 - __START_KERNEL_map) - - .code64 - .org 0x100 - .globl startup_64 -startup_64: + jmp secondary_startup_64 ENTRY(secondary_startup_64) - /* We come here either from startup_32 - * or directly from a 64bit bootloader. - * Since we may have come directly from a bootloader we - * reload the page tables here. + /* + * At this point the CPU runs in 64bit mode CS.L = 1 CS.D = 1, + * and someone has loaded a mapped page table. + * + * %esi holds a physical pointer to real_mode_data. + * + * We come here either from startup_64 (using physical addresses) + * or from trampoline.S (using virtual addresses). + * + * Using virtual addresses from trampoline.S removes the need + * to have any identity mapped pages in the kernel page table + * after the boot processor executes this code. */ /* Enable PAE mode and PGE */ @@ -116,8 +149,14 @@ ENTRY(secondary_startup_64) /* Setup early boot stage 4 level pagetables. */ movq $(init_level4_pgt - __START_KERNEL_map), %rax + addq phys_base(%rip), %rax movq %rax, %cr3 + /* Ensure I am executing from virtual addresses */ + movq $1f, %rax + jmp *%rax +1: + /* Check if nx is implemented */ movl $0x80000001, %eax cpuid @@ -126,17 +165,11 @@ ENTRY(secondary_startup_64) /* Setup EFER (Extended Feature Enable Register) */ movl $MSR_EFER, %ecx rdmsr - - /* Enable System Call */ - btsl $_EFER_SCE, %eax - - /* No Execute supported? */ - btl $20,%edi + btsl $_EFER_SCE, %eax /* Enable System Call */ + btl $20,%edi /* No Execute supported? */ jnc 1f btsl $_EFER_NX, %eax -1: - /* Make changes effective */ - wrmsr +1: wrmsr /* Make changes effective */ /* Setup cr0 */ #define CR0_PM 1 /* protected mode */ @@ -163,7 +196,7 @@ ENTRY(secondary_startup_64) * addresses where we're currently running on. We have to do that here * because in 32bit we couldn't load a 64bit linear address. */ - lgdt cpu_gdt_descr + lgdt cpu_gdt_descr(%rip) /* set up data segments. actually 0 would do too */ movl $__KERNEL_DS,%eax @@ -214,6 +247,9 @@ initial_code: init_rsp: .quad init_thread_union+THREAD_SIZE-8 +bad_address: + jmp bad_address + ENTRY(early_idt_handler) cmpl $2,early_recursion_flag(%rip) jz 1f @@ -242,23 +278,7 @@ early_idt_msg: early_idt_ripmsg: .asciz "RIP %s\n" -.code32 -ENTRY(no_long_mode) - /* This isn't an x86-64 CPU so hang */ -1: - jmp 1b - -.org 0xf00 - .globl pGDT32 -pGDT32: - .word gdt_end-cpu_gdt_table-1 - .long cpu_gdt_table-__START_KERNEL_map - -.org 0xf10 -ljumpvector: - .long startup_64-__START_KERNEL_map - .word __KERNEL_CS - +.balign PAGE_SIZE ENTRY(stext) ENTRY(_stext) @@ -303,7 +323,7 @@ NEXT_PAGE(level2_ident_pgt) * Don't set NX because code runs from these pages. */ PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC, PTRS_PER_PMD) - + NEXT_PAGE(level2_kernel_pgt) /* 40MB kernel mapping. The kernel code cannot be bigger than that. When you change this change KERNEL_TEXT_SIZE in page.h too. */ @@ -313,6 +333,9 @@ NEXT_PAGE(level2_kernel_pgt) /* Module mapping starts here */ .fill (PTRS_PER_PMD - (KERNEL_TEXT_SIZE/PMD_SIZE)),8,0 +NEXT_PAGE(level2_spare_pgt) + .fill 512,8,0 + #undef PMDS #undef NEXT_PAGE @@ -330,6 +353,10 @@ gdt: .endr #endif +ENTRY(phys_base) + /* This must match the first entry in level2_kernel_pgt */ + .quad 0x0000000000000000 + /* We need valid kernel segments for data and code in long mode too * IRET will check the segment types kkeil 2000/10/28 * Also sysret mandates a special GDT layout diff --git a/arch/x86_64/kernel/suspend_asm.S b/arch/x86_64/kernel/suspend_asm.S index bfbe00763c68..16d183f67bc1 100644 --- a/arch/x86_64/kernel/suspend_asm.S +++ b/arch/x86_64/kernel/suspend_asm.S @@ -71,9 +71,10 @@ loop: jmp loop done: /* go back to the original page tables */ - leaq init_level4_pgt(%rip), %rax - subq $__START_KERNEL_map, %rax - movq %rax, %cr3 + movq $(init_level4_pgt - __START_KERNEL_map), %rax + addq phys_base(%rip), %rax + movq %rax, %cr3 + /* Flush TLB, including "global" things (vmalloc) */ movq mmu_cr4_features(%rip), %rax movq %rax, %rdx diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h index 4974433bbf34..40a24d0df090 100644 --- a/include/asm-x86_64/page.h +++ b/include/asm-x86_64/page.h @@ -61,6 +61,8 @@ typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; +extern unsigned long phys_base; + #define pte_val(x) ((x).pte) #define pmd_val(x) ((x).pmd) #define pud_val(x) ((x).pud) @@ -101,14 +103,14 @@ typedef struct { unsigned long pgprot; } pgprot_t; #define PAGE_OFFSET __PAGE_OFFSET /* Note: __pa(&symbol_visible_to_c) should be always replaced with __pa_symbol. - Otherwise you risk miscompilation. */ + Otherwise you risk miscompilation. */ #define __pa(x) ((unsigned long)(x) - PAGE_OFFSET) /* __pa_symbol should be used for C visible symbols. This seems to be the official gcc blessed way to do such arithmetic. */ #define __pa_symbol(x) \ ({unsigned long v; \ asm("" : "=r" (v) : "0" (x)); \ - (v - __START_KERNEL_map); }) + ((v - __START_KERNEL_map) + phys_base); }) #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) #ifdef CONFIG_FLATMEM -- cgit v1.2.3-59-g8ed1b From 6a50a664ca0cfd2a487525f10cec3ff4d570b5e8 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:08 +0200 Subject: [PATCH] x86-64: build-time checking o X86_64 kernel should run from 2MB aligned address for two reasons. - Performance. - For relocatable kernels, page tables are updated based on difference between compile time address and load time physical address. This difference should be multiple of 2MB as kernel text and data is mapped using 2MB pages and PMD should be pointing to a 2MB aligned address. Life is simpler if both compile time and load time kernel addresses are 2MB aligned. o Flag the error at compile time if one is trying to build a kernel which does not meet alignment restrictions. Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen Cc: "Eric W. Biederman" Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/x86_64/boot/compressed/misc.c | 2 +- arch/x86_64/kernel/head64.c | 7 +++++++ include/asm-x86_64/page.h | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/boot/compressed/misc.c b/arch/x86_64/boot/compressed/misc.c index fee54dbf1749..fed1167159c3 100644 --- a/arch/x86_64/boot/compressed/misc.c +++ b/arch/x86_64/boot/compressed/misc.c @@ -358,7 +358,7 @@ asmlinkage void decompress_kernel(void *rmode, unsigned long heap, insize = input_len; inptr = 0; - if ((ulg)output & 0x1fffffUL) + if ((ulg)output & (__KERNEL_ALIGN - 1)) error("Destination address not 2M aligned"); if ((ulg)output >= 0xffffffffffUL) error("Destination address too large"); diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c index 6c34bdd22e26..213d90e04755 100644 --- a/arch/x86_64/kernel/head64.c +++ b/arch/x86_64/kernel/head64.c @@ -62,6 +62,13 @@ void __init x86_64_start_kernel(char * real_mode_data) { int i; + /* + * Make sure kernel is aligned to 2MB address. Catching it at compile + * time is better. Change your config file and compile the kernel + * for a 2MB aligned address (CONFIG_PHYSICAL_START) + */ + BUILD_BUG_ON(CONFIG_PHYSICAL_START & (__KERNEL_ALIGN - 1)); + /* clear bss before set_intr_gate with early_idt_handler */ clear_bss(); diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h index 40a24d0df090..b17fc16ec2eb 100644 --- a/include/asm-x86_64/page.h +++ b/include/asm-x86_64/page.h @@ -78,6 +78,7 @@ extern unsigned long phys_base; #endif /* !__ASSEMBLY__ */ #define __PHYSICAL_START CONFIG_PHYSICAL_START +#define __KERNEL_ALIGN 0x200000 #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START) #define __START_KERNEL_map 0xffffffff80000000 #define __PAGE_OFFSET 0xffff810000000000 -- cgit v1.2.3-59-g8ed1b From 8035d3ea78c2a61a9738c7857742370e0aa74d5c Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:08 +0200 Subject: [PATCH] x86-64: Extend bzImage protocol for relocatable bzImage o Extend the bzImage protocol (same as i386) to allow bzImage loaders to load the protected mode kernel at non-1MB address. Now protected mode component is relocatable and can be loaded at non-1MB addresses. o As of today kdump uses it to run a second kernel from a reserved memory area. Signed-off-by: Vivek Goyal Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/boot/setup.S | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S index 770940cc0108..deb3573c7aec 100644 --- a/arch/x86_64/boot/setup.S +++ b/arch/x86_64/boot/setup.S @@ -80,7 +80,7 @@ start: # This is the setup header, and it must start at %cs:2 (old 0x9020:2) .ascii "HdrS" # header signature - .word 0x0204 # header version number (>= 0x0105) + .word 0x0205 # header version number (>= 0x0105) # or else old loadlin-1.5 will fail) realmode_swtch: .word 0, 0 # default_switch, SETUPSEG start_sys_seg: .word SYSSEG @@ -155,7 +155,16 @@ cmd_line_ptr: .long 0 # (Header version 0x0202 or later) # low memory 0x10000 or higher. ramdisk_max: .long 0xffffffff - +kernel_alignment: .long 0x200000 # physical addr alignment required for + # protected mode relocatable kernel +#ifdef CONFIG_RELOCATABLE +relocatable_kernel: .byte 1 +#else +relocatable_kernel: .byte 0 +#endif +pad2: .byte 0 +pad3: .word 0 + trampoline: call start_of_setup .align 16 # The offset at this point is 0x240 -- cgit v1.2.3-59-g8ed1b From a4831e08b7f3ed51623c9eb25e8c945b76b3eda3 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:08 +0200 Subject: [PATCH] x86-64: Move cpu verification code to common file o This patch moves the code to verify long mode and SSE to a common file. This code is now shared by trampoline.S, wakeup.S, boot/setup.S and boot/compressed/head.S o So far we used to do very limited check in trampoline.S, wakeup.S and in 32bit entry point. Now all the entry paths are forced to do the exhaustive check, including SSE because verify_cpu is shared. o I am keeping this patch as last in the x86 relocatable series because previous patches have got quite some amount of testing done and don't want to distrub that. So that if there is problem introduced by this patch, at least it can be easily isolated. Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/boot/compressed/head.S | 19 ++++++- arch/x86_64/boot/setup.S | 65 ++-------------------- arch/x86_64/kernel/acpi/wakeup.S | 30 +++++----- arch/x86_64/kernel/trampoline.S | 51 +---------------- arch/x86_64/kernel/verify_cpu.S | 110 +++++++++++++++++++++++++++++++++++++ 5 files changed, 152 insertions(+), 123 deletions(-) create mode 100644 arch/x86_64/kernel/verify_cpu.S (limited to 'arch') diff --git a/arch/x86_64/boot/compressed/head.S b/arch/x86_64/boot/compressed/head.S index c353a9266ea4..f9d5692a0106 100644 --- a/arch/x86_64/boot/compressed/head.S +++ b/arch/x86_64/boot/compressed/head.S @@ -54,6 +54,15 @@ startup_32: 1: popl %ebp subl $1b, %ebp +/* setup a stack and make sure cpu supports long mode. */ + movl $user_stack_end, %eax + addl %ebp, %eax + movl %eax, %esp + + call verify_cpu + testl %eax, %eax + jnz no_longmode + /* Compute the delta between where we were compiled to run at * and where the code will actually run at. */ @@ -159,13 +168,21 @@ startup_32: /* Jump from 32bit compatibility mode into 64bit mode. */ lret +no_longmode: + /* This isn't an x86-64 CPU so hang */ +1: + hlt + jmp 1b + +#include "../../kernel/verify_cpu.S" + /* Be careful here startup_64 needs to be at a predictable * address so I can export it in an ELF header. Bootloaders * should look at the ELF header to find this address, as * it may change in the future. */ .code64 - .org 0x100 + .org 0x200 ENTRY(startup_64) /* We come here either from startup_32 or directly from a * 64bit bootloader. If we come here from a bootloader we depend on diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S index deb3573c7aec..816d04faa2be 100644 --- a/arch/x86_64/boot/setup.S +++ b/arch/x86_64/boot/setup.S @@ -299,64 +299,10 @@ loader_ok: movw %cs,%ax movw %ax,%ds - /* minimum CPUID flags for x86-64 */ - /* see http://www.x86-64.org/lists/discuss/msg02971.html */ -#define SSE_MASK ((1<<25)|(1<<26)) -#define REQUIRED_MASK1 ((1<<0)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<8)|\ - (1<<13)|(1<<15)|(1<<24)) -#define REQUIRED_MASK2 (1<<29) - - pushfl /* standard way to check for cpuid */ - popl %eax - movl %eax,%ebx - xorl $0x200000,%eax - pushl %eax - popfl - pushfl - popl %eax - cmpl %eax,%ebx - jz no_longmode /* cpu has no cpuid */ - movl $0x0,%eax - cpuid - cmpl $0x1,%eax - jb no_longmode /* no cpuid 1 */ - xor %di,%di - cmpl $0x68747541,%ebx /* AuthenticAMD */ - jnz noamd - cmpl $0x69746e65,%edx - jnz noamd - cmpl $0x444d4163,%ecx - jnz noamd - mov $1,%di /* cpu is from AMD */ -noamd: - movl $0x1,%eax - cpuid - andl $REQUIRED_MASK1,%edx - xorl $REQUIRED_MASK1,%edx - jnz no_longmode - movl $0x80000000,%eax - cpuid - cmpl $0x80000001,%eax - jb no_longmode /* no extended cpuid */ - movl $0x80000001,%eax - cpuid - andl $REQUIRED_MASK2,%edx - xorl $REQUIRED_MASK2,%edx - jnz no_longmode -sse_test: - movl $1,%eax - cpuid - andl $SSE_MASK,%edx - cmpl $SSE_MASK,%edx - je sse_ok - test %di,%di - jz no_longmode /* only try to force SSE on AMD */ - movl $0xc0010015,%ecx /* HWCR */ - rdmsr - btr $15,%eax /* enable SSE */ - wrmsr - xor %di,%di /* don't loop */ - jmp sse_test /* try again */ + call verify_cpu + testl %eax,%eax + jz sse_ok + no_longmode: call beep lea long_mode_panic,%si @@ -366,7 +312,8 @@ no_longmode_loop: long_mode_panic: .string "Your CPU does not support long mode. Use a 32bit distribution." .byte 0 - + +#include "../kernel/verify_cpu.S" sse_ok: popw %ds diff --git a/arch/x86_64/kernel/acpi/wakeup.S b/arch/x86_64/kernel/acpi/wakeup.S index 766cfbcac1db..8550a6ffa275 100644 --- a/arch/x86_64/kernel/acpi/wakeup.S +++ b/arch/x86_64/kernel/acpi/wakeup.S @@ -43,6 +43,11 @@ wakeup_code: cmpl $0x12345678, %eax jne bogus_real_magic + call verify_cpu # Verify the cpu supports long + # mode + testl %eax, %eax + jnz no_longmode + testl $1, video_flags - wakeup_code jz 1f lcall $0xc000,$3 @@ -92,18 +97,6 @@ wakeup_32: # Running in this code, but at low address; paging is not yet turned on. movb $0xa5, %al ; outb %al, $0x80 - /* Check if extended functions are implemented */ - movl $0x80000000, %eax - cpuid - cmpl $0x80000000, %eax - jbe bogus_cpu - wbinvd - mov $0x80000001, %eax - cpuid - btl $29, %edx - jnc bogus_cpu - movl %edx,%edi - movl $__KERNEL_DS, %eax movl %eax, %ds @@ -123,6 +116,11 @@ wakeup_32: leal (wakeup_level4_pgt - wakeup_code)(%esi), %eax movl %eax, %cr3 + /* Check if nx is implemented */ + movl $0x80000001, %eax + cpuid + movl %edx,%edi + /* Enable Long Mode */ xorl %eax, %eax btsl $_EFER_LME, %eax @@ -244,10 +242,12 @@ bogus_64_magic: movb $0xb3,%al ; outb %al,$0x80 jmp bogus_64_magic -bogus_cpu: - movb $0xbc,%al ; outb %al,$0x80 - jmp bogus_cpu +.code16 +no_longmode: + movb $0xbc,%al ; outb %al,$0x80 + jmp no_longmode +#include "../verify_cpu.S" /* This code uses an extended set of video mode numbers. These include: * Aliases for standard modes diff --git a/arch/x86_64/kernel/trampoline.S b/arch/x86_64/kernel/trampoline.S index 13eee63c7bb5..e7e2764c461b 100644 --- a/arch/x86_64/kernel/trampoline.S +++ b/arch/x86_64/kernel/trampoline.S @@ -54,6 +54,8 @@ r_base = . movw $(trampoline_stack_end - r_base), %sp call verify_cpu # Verify the cpu supports long mode + testl %eax, %eax # Check for return code + jnz no_longmode mov %cs, %ax movzx %ax, %esi # Find the 32bit trampoline location @@ -121,57 +123,10 @@ startup_64: jmp *%rax .code16 -verify_cpu: - pushl $0 # Kill any dangerous flags - popfl - - /* minimum CPUID flags for x86-64 */ - /* see http://www.x86-64.org/lists/discuss/msg02971.html */ -#define REQUIRED_MASK1 ((1<<0)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<8)|\ - (1<<13)|(1<<15)|(1<<24)|(1<<25)|(1<<26)) -#define REQUIRED_MASK2 (1<<29) - - pushfl # check for cpuid - popl %eax - movl %eax, %ebx - xorl $0x200000,%eax - pushl %eax - popfl - pushfl - popl %eax - pushl %ebx - popfl - cmpl %eax, %ebx - jz no_longmode - - xorl %eax, %eax # See if cpuid 1 is implemented - cpuid - cmpl $0x1, %eax - jb no_longmode - - movl $0x01, %eax # Does the cpu have what it takes? - cpuid - andl $REQUIRED_MASK1, %edx - xorl $REQUIRED_MASK1, %edx - jnz no_longmode - - movl $0x80000000, %eax # See if extended cpuid is implemented - cpuid - cmpl $0x80000001, %eax - jb no_longmode - - movl $0x80000001, %eax # Does the cpu have what it takes? - cpuid - andl $REQUIRED_MASK2, %edx - xorl $REQUIRED_MASK2, %edx - jnz no_longmode - - ret # The cpu supports long mode - no_longmode: hlt jmp no_longmode - +#include "verify_cpu.S" # Careful these need to be in the same 64K segment as the above; tidt: diff --git a/arch/x86_64/kernel/verify_cpu.S b/arch/x86_64/kernel/verify_cpu.S new file mode 100644 index 000000000000..72edabd2ef9a --- /dev/null +++ b/arch/x86_64/kernel/verify_cpu.S @@ -0,0 +1,110 @@ +/* + * + * verify_cpu.S - Code for cpu long mode and SSE verification. This + * code has been borrowed from boot/setup.S and was introduced by + * Andi Kleen. + * + * Copyright (c) 2007 Andi Kleen (ak@suse.de) + * Copyright (c) 2007 Eric Biederman (ebiederm@xmission.com) + * Copyright (c) 2007 Vivek Goyal (vgoyal@in.ibm.com) + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + * + * This is a common code for verification whether CPU supports + * long mode and SSE or not. It is not called directly instead this + * file is included at various places and compiled in that context. + * Following are the current usage. + * + * This file is included by both 16bit and 32bit code. + * + * arch/x86_64/boot/setup.S : Boot cpu verification (16bit) + * arch/x86_64/boot/compressed/head.S: Boot cpu verification (32bit) + * arch/x86_64/kernel/trampoline.S: secondary processor verfication (16bit) + * arch/x86_64/kernel/acpi/wakeup.S:Verfication at resume (16bit) + * + * verify_cpu, returns the status of cpu check in register %eax. + * 0: Success 1: Failure + * + * The caller needs to check for the error code and take the action + * appropriately. Either display a message or halt. + */ + +verify_cpu: + + pushfl # Save caller passed flags + pushl $0 # Kill any dangerous flags + popfl + + /* minimum CPUID flags for x86-64 */ + /* see http://www.x86-64.org/lists/discuss/msg02971.html */ +#define SSE_MASK ((1<<25)|(1<<26)) +#define REQUIRED_MASK1 ((1<<0)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<8)|\ + (1<<13)|(1<<15)|(1<<24)) +#define REQUIRED_MASK2 (1<<29) + pushfl # standard way to check for cpuid + popl %eax + movl %eax,%ebx + xorl $0x200000,%eax + pushl %eax + popfl + pushfl + popl %eax + cmpl %eax,%ebx + jz verify_cpu_no_longmode # cpu has no cpuid + + movl $0x0,%eax # See if cpuid 1 is implemented + cpuid + cmpl $0x1,%eax + jb verify_cpu_no_longmode # no cpuid 1 + + xor %di,%di + cmpl $0x68747541,%ebx # AuthenticAMD + jnz verify_cpu_noamd + cmpl $0x69746e65,%edx + jnz verify_cpu_noamd + cmpl $0x444d4163,%ecx + jnz verify_cpu_noamd + mov $1,%di # cpu is from AMD + +verify_cpu_noamd: + movl $0x1,%eax # Does the cpu have what it takes + cpuid + andl $REQUIRED_MASK1,%edx + xorl $REQUIRED_MASK1,%edx + jnz verify_cpu_no_longmode + + movl $0x80000000,%eax # See if extended cpuid is implemented + cpuid + cmpl $0x80000001,%eax + jb verify_cpu_no_longmode # no extended cpuid + + movl $0x80000001,%eax # Does the cpu have what it takes + cpuid + andl $REQUIRED_MASK2,%edx + xorl $REQUIRED_MASK2,%edx + jnz verify_cpu_no_longmode + +verify_cpu_sse_test: + movl $1,%eax + cpuid + andl $SSE_MASK,%edx + cmpl $SSE_MASK,%edx + je verify_cpu_sse_ok + test %di,%di + jz verify_cpu_no_longmode # only try to force SSE on AMD + movl $0xc0010015,%ecx # HWCR + rdmsr + btr $15,%eax # enable SSE + wrmsr + xor %di,%di # don't loop + jmp verify_cpu_sse_test # try again + +verify_cpu_no_longmode: + popfl # Restore caller passed flags + movl $1,%eax + ret +verify_cpu_sse_ok: + popfl # Restore caller passed flags + xorl %eax, %eax + ret -- cgit v1.2.3-59-g8ed1b From 1652fcbf37abdbbebaf386b46b20e486769e7b45 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:08 +0200 Subject: [PATCH] x86-64: Don't disable basic block reordering When compiling with -Os (which is default) the compiler defaults to it anyways. And with -O2 it probably generates somewhat better (although also larger) code. Signed-off-by: Andi Kleen --- arch/x86_64/Makefile | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index 2941a915d4ef..803cfcc9b346 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile @@ -41,9 +41,6 @@ cflags-y += -mno-red-zone cflags-y += -mcmodel=kernel cflags-y += -pipe cflags-kernel-$(CONFIG_REORDER) += -ffunction-sections -# this makes reading assembly source easier, but produces worse code -# actually it makes the kernel smaller too. -cflags-y += -fno-reorder-blocks cflags-y += -Wno-sign-compare cflags-y += -fno-asynchronous-unwind-tables ifneq ($(CONFIG_DEBUG_INFO),y) -- cgit v1.2.3-59-g8ed1b From fb60b8392ce8ab185a7a0b4f7cefbe18b2afdab5 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:08 +0200 Subject: [PATCH] x86-64: Allow sys_uselib unconditionally Previously it wasn't enabled in the binfmt_aout is a module case. Signed-off-by: Andi Kleen --- arch/x86_64/ia32/ia32entry.S | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index 796df6992f62..c48087db6f75 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S @@ -481,11 +481,7 @@ ia32_sys_call_table: .quad sys_symlink .quad sys_lstat .quad sys_readlink /* 85 */ -#ifdef CONFIG_IA32_AOUT .quad sys_uselib -#else - .quad quiet_ni_syscall -#endif .quad sys_swapon .quad sys_reboot .quad compat_sys_old_readdir -- cgit v1.2.3-59-g8ed1b From d039c688c6b3e7217381d2804bc0ca3171913fec Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:08 +0200 Subject: [PATCH] x86-64: Minor white space cleanup in traps.c Signed-off-by: Andi Kleen --- arch/x86_64/kernel/traps.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index cceef5bd7302..d76fc32d4599 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -426,8 +426,7 @@ void show_registers(struct pt_regs *regs) const int cpu = smp_processor_id(); struct task_struct *cur = cpu_pda(cpu)->pcurrent; - rsp = regs->rsp; - + rsp = regs->rsp; printk("CPU %d ", cpu); __show_regs(regs); printk("Process %s (pid: %d, threadinfo %p, task %p)\n", @@ -438,7 +437,6 @@ void show_registers(struct pt_regs *regs) * time of the fault.. */ if (in_kernel) { - printk("Stack: "); _show_stack(NULL, regs, (unsigned long*)rsp); -- cgit v1.2.3-59-g8ed1b From 1833d6bc72893265f22addd79cf52e6987496e0f Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 2 May 2007 19:27:08 +0200 Subject: [PATCH] i386: modpost apic related warning fixes o Modpost generates warnings for i386 if compiled with CONFIG_RELOCATABLE=y WARNING: vmlinux - Section mismatch: reference to .init.text:find_unisys_acpi_oem_table from .text between 'acpi_madt_oem_check' (at offset 0xc0101eda) and 'enable_apic_mode' WARNING: vmlinux - Section mismatch: reference to .init.text:acpi_get_table_header_early from .text between 'acpi_madt_oem_check' (at offset 0xc0101ef0) and 'enable_apic_mode' WARNING: vmlinux - Section mismatch: reference to .init.text:parse_unisys_oem from .text between 'acpi_madt_oem_check' (at offset 0xc0101f2e) and 'enable_apic_mode' WARNING: vmlinux - Section mismatch: reference to .init.text:setup_unisys from .text between 'acpi_madt_oem_check' (at offset 0xc0101f37) and 'enable_apic_mode'WARNING: vmlinux - Section mismatch: reference to .init.text:parse_unisys_oem from .text between 'mps_oem_check' (at offset 0xc0101ec7) and 'acpi_madt_oem_check' WARNING: vmlinux - Section mismatch: reference to .init.text:es7000_sw_apic from .text between 'enable_apic_mode' (at offset 0xc0101f48) and 'check_apicid_present' o Some functions which are inline (acpi_madt_oem_check) are not inlined by compiler as these functions are accessed using function pointer. These functions are put in .text section and they in-turn access __init type functions hence modpost generates warnings. o Do not iniline acpi_madt_oem_check, instead make it __init. Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Len Brown Signed-off-by: Andrew Morton --- arch/i386/mach-generic/es7000.c | 41 +++++++++++++++++++++++++++++ include/asm-i386/mach-es7000/mach_apic.h | 7 ----- include/asm-i386/mach-es7000/mach_mpparse.h | 32 ---------------------- scripts/mod/modpost.c | 1 + 4 files changed, 42 insertions(+), 39 deletions(-) (limited to 'arch') diff --git a/arch/i386/mach-generic/es7000.c b/arch/i386/mach-generic/es7000.c index b8963a5a3b25..b47f951c0ec2 100644 --- a/arch/i386/mach-generic/es7000.c +++ b/arch/i386/mach-generic/es7000.c @@ -25,4 +25,45 @@ static int probe_es7000(void) return 0; } +extern void es7000_sw_apic(void); +static void __init enable_apic_mode(void) +{ + es7000_sw_apic(); + return; +} + +static __init int mps_oem_check(struct mp_config_table *mpc, char *oem, + char *productid) +{ + if (mpc->mpc_oemptr) { + struct mp_config_oemtable *oem_table = + (struct mp_config_oemtable *)mpc->mpc_oemptr; + if (!strncmp(oem, "UNISYS", 6)) + return parse_unisys_oem((char *)oem_table); + } + return 0; +} + +#ifdef CONFIG_ACPI +/* Hook from generic ACPI tables.c */ +static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + unsigned long oem_addr; + if (!find_unisys_acpi_oem_table(&oem_addr)) { + if (es7000_check_dsdt()) + return parse_unisys_oem((char *)oem_addr); + else { + setup_unisys(); + return 1; + } + } + return 0; +} +#else +static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + return 0; +} +#endif + struct genapic apic_es7000 = APIC_INIT("es7000", probe_es7000); diff --git a/include/asm-i386/mach-es7000/mach_apic.h b/include/asm-i386/mach-es7000/mach_apic.h index 8e8b3949173a..2d978928a395 100644 --- a/include/asm-i386/mach-es7000/mach_apic.h +++ b/include/asm-i386/mach-es7000/mach_apic.h @@ -73,13 +73,6 @@ static inline void init_apic_ldr(void) apic_write_around(APIC_LDR, val); } -extern void es7000_sw_apic(void); -static inline void enable_apic_mode(void) -{ - es7000_sw_apic(); - return; -} - extern int apic_version [MAX_APICS]; static inline void setup_apic_routing(void) { diff --git a/include/asm-i386/mach-es7000/mach_mpparse.h b/include/asm-i386/mach-es7000/mach_mpparse.h index 24990e546da3..b9fb784e1fd5 100644 --- a/include/asm-i386/mach-es7000/mach_mpparse.h +++ b/include/asm-i386/mach-es7000/mach_mpparse.h @@ -18,18 +18,6 @@ extern int parse_unisys_oem (char *oemptr); extern int find_unisys_acpi_oem_table(unsigned long *oem_addr); extern void setup_unisys(void); -static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, - char *productid) -{ - if (mpc->mpc_oemptr) { - struct mp_config_oemtable *oem_table = - (struct mp_config_oemtable *)mpc->mpc_oemptr; - if (!strncmp(oem, "UNISYS", 6)) - return parse_unisys_oem((char *)oem_table); - } - return 0; -} - #ifdef CONFIG_ACPI static inline int es7000_check_dsdt(void) @@ -41,26 +29,6 @@ static inline int es7000_check_dsdt(void) return 1; return 0; } - -/* Hook from generic ACPI tables.c */ -static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ - unsigned long oem_addr; - if (!find_unisys_acpi_oem_table(&oem_addr)) { - if (es7000_check_dsdt()) - return parse_unisys_oem((char *)oem_addr); - else { - setup_unisys(); - return 1; - } - } - return 0; -} -#else -static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ - return 0; -} #endif #endif /* __ASM_MACH_MPPARSE_H */ diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 65bdfdb56877..78d659cbb36a 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -606,6 +606,7 @@ static int secref_whitelist(const char *modname, const char *tosec, "_probe", "_probe_one", "_console", + "apic_es7000", NULL }; -- cgit v1.2.3-59-g8ed1b From 30a1528d3bf444eac7f2886ba284da22114b2f7c Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 2 May 2007 19:27:08 +0200 Subject: [PATCH] i386: make struct vmi_ops static Signed-off-by: Adrian Bunk Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Zachary Amsden Signed-off-by: Andrew Morton --- arch/i386/kernel/vmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index 697a70e8c0c9..440422482c6d 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c @@ -56,7 +56,7 @@ static int disable_noidle; static int disable_vmi_timer; /* Cached VMI operations */ -struct { +static struct { void (*cpuid)(void /* non-c */); void (*_set_ldt)(u32 selector); void (*set_tr)(u32 selector); -- cgit v1.2.3-59-g8ed1b From e48b30c189559e20e1f616faccae487972486320 Mon Sep 17 00:00:00 2001 From: Ken Chen Date: Wed, 2 May 2007 19:27:08 +0200 Subject: [PATCH] i386: type cast clean up for find_next_zero_bit clean up unneeded type cast by properly declare data type. Signed-off-by: Ken Chen Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/lib/bitops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/lib/bitops.c b/arch/i386/lib/bitops.c index 97db3853dc82..afd0045595d4 100644 --- a/arch/i386/lib/bitops.c +++ b/arch/i386/lib/bitops.c @@ -43,7 +43,7 @@ EXPORT_SYMBOL(find_next_bit); */ int find_next_zero_bit(const unsigned long *addr, int size, int offset) { - unsigned long * p = ((unsigned long *) addr) + (offset >> 5); + const unsigned long *p = addr + (offset >> 5); int set = 0, bit = offset & 31, res; if (bit) { @@ -64,7 +64,7 @@ int find_next_zero_bit(const unsigned long *addr, int size, int offset) /* * No zero yet, search remaining full bytes for a zero */ - res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); + res = find_first_zero_bit(p, size - 32 * (p - addr)); return (offset + set + res); } EXPORT_SYMBOL(find_next_zero_bit); -- cgit v1.2.3-59-g8ed1b From 2714221985ce6388ec2fa78d7d52e2a5bef78eec Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 2 May 2007 19:27:08 +0200 Subject: [PATCH] i386: workaround for a -Wmissing-prototypes warning Work around a warning with -Wmissing-prototypes in arch/i386/kernel/asm-offsets.c The warning isn't gcc's fault - asm-offsets.c is simply a special file. Signed-off-by: Adrian Bunk Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/asm-offsets.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c index c37535163bfc..d822792d8e3e 100644 --- a/arch/i386/kernel/asm-offsets.c +++ b/arch/i386/kernel/asm-offsets.c @@ -25,6 +25,9 @@ #define OFFSET(sym, str, mem) \ DEFINE(sym, offsetof(struct str, mem)); +/* workaround for a warning with -Wmissing-prototypes */ +void foo(void); + void foo(void) { OFFSET(SIGCONTEXT_eax, sigcontext, eax); -- cgit v1.2.3-59-g8ed1b From 5a90cf205c922707ffed2d8f87cefd942e96b0ba Mon Sep 17 00:00:00 2001 From: john stultz Date: Wed, 2 May 2007 19:27:08 +0200 Subject: [PATCH] x86: Log reason why TSC was marked unstable Change mark_tsc_unstable() so it takes a string argument, which holds the reason the TSC was marked unstable. This is then displayed the first time mark_tsc_unstable is called. This should help us better debug why the TSC was marked unstable on certain systems and allow us to make sure we're not being overly paranoid when throwing out this troublesome clocksource. Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/kernel/cpu/cyrix.c | 2 +- arch/i386/kernel/tsc.c | 5 +++-- arch/x86_64/kernel/time.c | 2 +- arch/x86_64/kernel/tsc.c | 5 +++-- arch/x86_64/kernel/tsc_sync.c | 2 +- drivers/acpi/processor_idle.c | 4 ++-- include/asm-i386/mach-summit/mach_mpparse.h | 4 ++-- include/asm-i386/tsc.h | 2 +- include/asm-x86_64/timex.h | 2 +- 9 files changed, 15 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c index f0badfdd4e45..e77f8e1cf7aa 100644 --- a/arch/i386/kernel/cpu/cyrix.c +++ b/arch/i386/kernel/cpu/cyrix.c @@ -279,7 +279,7 @@ static void __cpuinit init_cyrix(struct cpuinfo_x86 *c) */ if (vendor == PCI_VENDOR_ID_CYRIX && (device == PCI_DEVICE_ID_CYRIX_5510 || device == PCI_DEVICE_ID_CYRIX_5520)) - mark_tsc_unstable(); + mark_tsc_unstable("cyrix 5510/5520 detected"); } #endif c->x86_cache_size=16; /* Yep 16K integrated cache thats it */ diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c index 6cb8f5336732..755209dc93e1 100644 --- a/arch/i386/kernel/tsc.c +++ b/arch/i386/kernel/tsc.c @@ -233,7 +233,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) * TSC based sched_clock turns * to junk w/ cpufreq */ - mark_tsc_unstable(); + mark_tsc_unstable("cpufreq changes"); } } } @@ -281,11 +281,12 @@ static struct clocksource clocksource_tsc = { CLOCK_SOURCE_MUST_VERIFY, }; -void mark_tsc_unstable(void) +void mark_tsc_unstable(char *reason) { if (!tsc_unstable) { tsc_unstable = 1; tsc_enabled = 0; + printk("Marking TSC unstable due to: %s.\n", reason); /* Can be called before registration */ if (clocksource_tsc.mult) clocksource_change_rating(&clocksource_tsc, 0); diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 5f862e216a42..91c9066a380d 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -397,7 +397,7 @@ void __init time_init(void) cpu_khz = tsc_calibrate_cpu_khz(); if (unsynchronized_tsc()) - mark_tsc_unstable(); + mark_tsc_unstable("TSCs unsynchronized"); if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP)) vgetcpu_mode = VGETCPU_RDTSCP; diff --git a/arch/x86_64/kernel/tsc.c b/arch/x86_64/kernel/tsc.c index 5c84992c676d..48f9a8e6aa91 100644 --- a/arch/x86_64/kernel/tsc.c +++ b/arch/x86_64/kernel/tsc.c @@ -111,7 +111,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, tsc_khz = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new); if (!(freq->flags & CPUFREQ_CONST_LOOPS)) - mark_tsc_unstable(); + mark_tsc_unstable("cpufreq changes"); } set_cyc2ns_scale(tsc_khz_ref); @@ -199,10 +199,11 @@ static struct clocksource clocksource_tsc = { .vread = vread_tsc, }; -void mark_tsc_unstable(void) +void mark_tsc_unstable(char *reason) { if (!tsc_unstable) { tsc_unstable = 1; + printk("Marking TSC unstable due to %s\n", reason); /* Change only the rating, when not registered */ if (clocksource_tsc.mult) clocksource_change_rating(&clocksource_tsc, 0); diff --git a/arch/x86_64/kernel/tsc_sync.c b/arch/x86_64/kernel/tsc_sync.c index 72d444dede9b..355f5f506c81 100644 --- a/arch/x86_64/kernel/tsc_sync.c +++ b/arch/x86_64/kernel/tsc_sync.c @@ -138,7 +138,7 @@ void __cpuinit check_tsc_sync_source(int cpu) printk("\n"); printk(KERN_WARNING "Measured %Ld cycles TSC warp between CPUs," " turning off TSC clock.\n", max_warp); - mark_tsc_unstable(); + mark_tsc_unstable("check_tsc_sync_source failed"); nr_warps = 0; max_warp = 0; last_tsc = 0; diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index ae0654cd11ea..ee5759bef945 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -475,7 +475,7 @@ static void acpi_processor_idle(void) #ifdef CONFIG_GENERIC_TIME /* TSC halts in C2, so notify users */ - mark_tsc_unstable(); + mark_tsc_unstable("possible TSC halt in C2"); #endif /* Re-enable interrupts */ local_irq_enable(); @@ -517,7 +517,7 @@ static void acpi_processor_idle(void) #ifdef CONFIG_GENERIC_TIME /* TSC halts in C3, so notify users */ - mark_tsc_unstable(); + mark_tsc_unstable("TSC halts in C3"); #endif /* Re-enable interrupts */ local_irq_enable(); diff --git a/include/asm-i386/mach-summit/mach_mpparse.h b/include/asm-i386/mach-summit/mach_mpparse.h index 94268399170d..c2520539d934 100644 --- a/include/asm-i386/mach-summit/mach_mpparse.h +++ b/include/asm-i386/mach-summit/mach_mpparse.h @@ -30,7 +30,7 @@ static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, (!strncmp(productid, "VIGIL SMP", 9) || !strncmp(productid, "EXA", 3) || !strncmp(productid, "RUTHLESS SMP", 12))){ - mark_tsc_unstable(); + mark_tsc_unstable("Summit based system"); use_cyclone = 1; /*enable cyclone-timer*/ setup_summit(); return 1; @@ -44,7 +44,7 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) if (!strncmp(oem_id, "IBM", 3) && (!strncmp(oem_table_id, "SERVIGIL", 8) || !strncmp(oem_table_id, "EXA", 3))){ - mark_tsc_unstable(); + mark_tsc_unstable("Summit based system"); use_cyclone = 1; /*enable cyclone-timer*/ setup_summit(); return 1; diff --git a/include/asm-i386/tsc.h b/include/asm-i386/tsc.h index 84016ff481b9..346976632e15 100644 --- a/include/asm-i386/tsc.h +++ b/include/asm-i386/tsc.h @@ -53,7 +53,7 @@ static __always_inline cycles_t get_cycles_sync(void) } extern void tsc_init(void); -extern void mark_tsc_unstable(void); +extern void mark_tsc_unstable(char *reason); extern int unsynchronized_tsc(void); extern void init_tsc_clocksource(void); diff --git a/include/asm-x86_64/timex.h b/include/asm-x86_64/timex.h index 8c6808a3fba4..f6527e1b6c1c 100644 --- a/include/asm-x86_64/timex.h +++ b/include/asm-x86_64/timex.h @@ -27,6 +27,6 @@ extern int read_current_timer(unsigned long *timer_value); #define NS_SCALE 10 /* 2^10, carefully chosen */ #define US_SCALE 32 /* 2^32, arbitralrily chosen */ -extern void mark_tsc_unstable(void); +extern void mark_tsc_unstable(char *msg); extern void set_cyc2ns_scale(unsigned long khz); #endif -- cgit v1.2.3-59-g8ed1b From 9f7290ed23b1cedf7198ef7b67f2ed256bc8553e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 2 May 2007 19:27:08 +0200 Subject: [PATCH] x86-64: fix ia32_binfmt.c build error Reorder code to avoid multiple inclusion of elf.h. #undef several symbols to avoid build errors over redefinitions. Signed-off-by: Ralf Baechle Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/x86_64/ia32/ia32_binfmt.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c index 071100ea1251..185399baaf6d 100644 --- a/arch/x86_64/ia32/ia32_binfmt.c +++ b/arch/x86_64/ia32/ia32_binfmt.c @@ -5,6 +5,11 @@ * This tricks binfmt_elf.c into loading 32bit binaries using lots * of ugly preprocessor tricks. Talk about very very poor man's inheritance. */ +#define __ASM_X86_64_ELF_H 1 + +#undef ELF_CLASS +#define ELF_CLASS ELFCLASS32 + #include #include #include @@ -50,9 +55,6 @@ struct elf_phdr; #undef ELF_ARCH #define ELF_ARCH EM_386 -#undef ELF_CLASS -#define ELF_CLASS ELFCLASS32 - #define ELF_DATA ELFDATA2LSB #define USE_ELF_CORE_DUMP 1 @@ -136,7 +138,7 @@ struct elf_prpsinfo #define user user32 -#define __ASM_X86_64_ELF_H 1 +#undef elf_read_implies_exec #define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X) //#include #include -- cgit v1.2.3-59-g8ed1b From f0e13ae76a607eab9c387544ebca550f2196a876 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 2 May 2007 19:27:08 +0200 Subject: [PATCH] x86-64: remove extra smp_processor_id calling Cc: "Eric W. Biederman" Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/x86_64/kernel/io_apic.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index c6a5bc7e8118..318d9055cd97 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -1407,8 +1407,7 @@ static void irq_complete_move(unsigned int irq) vector = ~get_irq_regs()->orig_rax; me = smp_processor_id(); - if ((vector == cfg->vector) && - cpu_isset(smp_processor_id(), cfg->domain)) { + if ((vector == cfg->vector) && cpu_isset(me, cfg->domain)) { cpumask_t cleanup_mask; cpus_and(cleanup_mask, cfg->old_domain, cpu_online_map); -- cgit v1.2.3-59-g8ed1b From 786142fab86cfddd3e7797e9ccf8a8a3bcaf0456 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 2 May 2007 19:27:09 +0200 Subject: [PATCH] x86-64: make simnow_init() static Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/x86_64/kernel/early_printk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c index b7aa9abe1c6a..92213d2b7c11 100644 --- a/arch/x86_64/kernel/early_printk.c +++ b/arch/x86_64/kernel/early_printk.c @@ -175,7 +175,7 @@ static noinline long simnow(long cmd, long a, long b, long c) return ret; } -void __init simnow_init(char *str) +static void __init simnow_init(char *str) { char *fn = "klog"; if (*str == '=') -- cgit v1.2.3-59-g8ed1b From 8eb68faed9e077c45c2bab5fce7c4e371fe9c28f Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 2 May 2007 19:27:09 +0200 Subject: [PATCH] i386: vmi_pmd_clear() static This patch makes the needlessly global vmi_pmd_clear() static. Signed-off-by: Adrian Bunk Signed-off-by: Andi Kleen Acked-by: Zachary Amsden Signed-off-by: Andrew Morton --- arch/i386/kernel/vmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index 440422482c6d..626c82063d19 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c @@ -516,7 +516,7 @@ static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); } -void vmi_pmd_clear(pmd_t *pmd) +static void vmi_pmd_clear(pmd_t *pmd) { const pte_t pte = { 0 }; vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD); -- cgit v1.2.3-59-g8ed1b From 8280c0c58e9762a9fe29d550a9db81410de77691 Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Wed, 2 May 2007 19:27:09 +0200 Subject: [PATCH] i386: fix GDT's number of quadwords in comment Fix comments to represent the true number of quadwords in GDT. Signed-off-by: Ahmed S. Darwish Signed-off-by: Andi Kleen Acked-by: Randy Dunlap Signed-off-by: Andrew Morton --- arch/i386/kernel/head.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index 3fa7f9389afe..cb185f40c282 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -612,7 +612,7 @@ ENTRY(boot_gdt_table) .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */ /* - * The Global Descriptor Table contains 28 quadwords, per-CPU. + * The Global Descriptor Table contains 32 quadwords, per-CPU. */ .align L1_CACHE_BYTES ENTRY(cpu_gdt_table) @@ -639,7 +639,7 @@ ENTRY(cpu_gdt_table) /* * Segments used for calling PnP BIOS have byte granularity. - * They code segments and data segments have fixed 64k limits, + * The code segments and data segments have fixed 64k limits, * the transfer segment sizes are set at run time. */ .quad 0x00409a000000ffff /* 0x90 32-bit code */ -- cgit v1.2.3-59-g8ed1b From 8b8ca80e192b10eecc01fc44a2902510af86f73b Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Wed, 2 May 2007 19:27:09 +0200 Subject: [PATCH] x86-64: configurable fake numa node sizes Extends the numa=fake x86_64 command-line option to allow for configurable node sizes. These nodes can be used in conjunction with cpusets for coarse memory resource management. The old command-line option is still supported: numa=fake=32 gives 32 fake NUMA nodes, ignoring the NUMA setup of the actual machine. But now you may configure your system for the node sizes of your choice: numa=fake=2*512,1024,2*256 gives two 512M nodes, one 1024M node, two 256M nodes, and the rest of system memory to a sixth node. The existing hash function is maintained to support the various node sizes that are possible with this implementation. Each node of the same size receives roughly the same amount of available pages, regardless of any reserved memory with its address range. The total available pages on the system is calculated and divided by the number of equal nodes to allocate. These nodes are then dynamically allocated and their borders extended until such time as their number of available pages reaches the required size. Configurable node sizes are recommended when used in conjunction with cpusets for memory control because it eliminates the overhead associated with scanning the zonelists of many smaller full nodes on page_alloc(). Cc: Andi Kleen Signed-off-by: David Rientjes Signed-off-by: Andi Kleen Cc: Paul Jackson Cc: Christoph Lameter Signed-off-by: Andrew Morton --- Documentation/x86_64/boot-options.txt | 8 +- arch/x86_64/mm/numa.c | 261 ++++++++++++++++++++-------------- include/asm-x86_64/mmzone.h | 2 +- 3 files changed, 161 insertions(+), 110 deletions(-) (limited to 'arch') diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt index 85f51e5a749f..7500aad95f3c 100644 --- a/Documentation/x86_64/boot-options.txt +++ b/Documentation/x86_64/boot-options.txt @@ -149,7 +149,13 @@ NUMA numa=noacpi Don't parse the SRAT table for NUMA setup - numa=fake=X Fake X nodes and ignore NUMA setup of the actual machine. + numa=fake=CMDLINE + If a number, fakes CMDLINE nodes and ignores NUMA setup of the + actual machine. Otherwise, system memory is configured + depending on the sizes and coefficients listed. For example: + numa=fake=2*512,1024,4*256 + gives two 512M nodes, a 1024M node, and four 256M nodes. The + remaining system RAM is allocated to an additional node. numa=hotadd=percent Only allow hotadd memory to preallocate page structures upto diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index 41b8fb069924..c55936bc6be6 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c @@ -273,125 +273,172 @@ void __init numa_init_array(void) #ifdef CONFIG_NUMA_EMU /* Numa emulation */ -int numa_fake __initdata = 0; +#define E820_ADDR_HOLE_SIZE(start, end) \ + (e820_hole_size((start) >> PAGE_SHIFT, (end) >> PAGE_SHIFT) << \ + PAGE_SHIFT) +char *cmdline __initdata; /* - * This function is used to find out if the start and end correspond to - * different zones. + * Setups up nid to range from addr to addr + size. If the end boundary is + * greater than max_addr, then max_addr is used instead. The return value is 0 + * if there is additional memory left for allocation past addr and -1 otherwise. + * addr is adjusted to be at the end of the node. */ -int zone_cross_over(unsigned long start, unsigned long end) +static int __init setup_node_range(int nid, struct bootnode *nodes, u64 *addr, + u64 size, u64 max_addr) { - if ((start < (MAX_DMA32_PFN << PAGE_SHIFT)) && - (end >= (MAX_DMA32_PFN << PAGE_SHIFT))) - return 1; - return 0; + int ret = 0; + nodes[nid].start = *addr; + *addr += size; + if (*addr >= max_addr) { + *addr = max_addr; + ret = -1; + } + nodes[nid].end = *addr; + node_set_online(nid); + printk(KERN_INFO "Faking node %d at %016Lx-%016Lx (%LuMB)\n", nid, + nodes[nid].start, nodes[nid].end, + (nodes[nid].end - nodes[nid].start) >> 20); + return ret; } -static int __init numa_emulation(unsigned long start_pfn, unsigned long end_pfn) +/* + * Splits num_nodes nodes up equally starting at node_start. The return value + * is the number of nodes split up and addr is adjusted to be at the end of the + * last node allocated. + */ +static int __init split_nodes_equally(struct bootnode *nodes, u64 *addr, + u64 max_addr, int node_start, + int num_nodes) { - int i, big; - struct bootnode nodes[MAX_NUMNODES]; - unsigned long sz, old_sz; - unsigned long hole_size; - unsigned long start, end; - unsigned long max_addr = (end_pfn << PAGE_SHIFT); - - start = (start_pfn << PAGE_SHIFT); - hole_size = e820_hole_size(start, max_addr); - sz = (max_addr - start - hole_size) / numa_fake; - - /* Kludge needed for the hash function */ - - old_sz = sz; - /* - * Round down to the nearest FAKE_NODE_MIN_SIZE. - */ - sz &= FAKE_NODE_MIN_HASH_MASK; + unsigned int big; + u64 size; + int i; + if (num_nodes <= 0) + return -1; + if (num_nodes > MAX_NUMNODES) + num_nodes = MAX_NUMNODES; + size = (max_addr - *addr - E820_ADDR_HOLE_SIZE(*addr, max_addr)) / + num_nodes; /* - * We ensure that each node is at least 64MB big. Smaller than this - * size can cause VM hiccups. + * Calculate the number of big nodes that can be allocated as a result + * of consolidating the leftovers. */ - if (sz == 0) { - printk(KERN_INFO "Not enough memory for %d nodes. Reducing " - "the number of nodes\n", numa_fake); - numa_fake = (max_addr - start - hole_size) / FAKE_NODE_MIN_SIZE; - printk(KERN_INFO "Number of fake nodes will be = %d\n", - numa_fake); - sz = FAKE_NODE_MIN_SIZE; + big = ((size & ~FAKE_NODE_MIN_HASH_MASK) * num_nodes) / + FAKE_NODE_MIN_SIZE; + + /* Round down to nearest FAKE_NODE_MIN_SIZE. */ + size &= FAKE_NODE_MIN_HASH_MASK; + if (!size) { + printk(KERN_ERR "Not enough memory for each node. " + "NUMA emulation disabled.\n"); + return -1; } - /* - * Find out how many nodes can get an extra NODE_MIN_SIZE granule. - * This logic ensures the extra memory gets distributed among as many - * nodes as possible (as compared to one single node getting all that - * extra memory. - */ - big = ((old_sz - sz) * numa_fake) / FAKE_NODE_MIN_SIZE; - printk(KERN_INFO "Fake node Size: %luMB hole_size: %luMB big nodes: " - "%d\n", - (sz >> 20), (hole_size >> 20), big); - memset(&nodes,0,sizeof(nodes)); - end = start; - for (i = 0; i < numa_fake; i++) { - /* - * In case we are not able to allocate enough memory for all - * the nodes, we reduce the number of fake nodes. - */ - if (end >= max_addr) { - numa_fake = i - 1; - break; - } - start = nodes[i].start = end; - /* - * Final node can have all the remaining memory. - */ - if (i == numa_fake-1) - sz = max_addr - start; - end = nodes[i].start + sz; - /* - * Fir "big" number of nodes get extra granule. - */ + + for (i = node_start; i < num_nodes + node_start; i++) { + u64 end = *addr + size; if (i < big) end += FAKE_NODE_MIN_SIZE; /* - * Iterate over the range to ensure that this node gets at - * least sz amount of RAM (excluding holes) + * The final node can have the remaining system RAM. Other + * nodes receive roughly the same amount of available pages. */ - while ((end - start - e820_hole_size(start, end)) < sz) { - end += FAKE_NODE_MIN_SIZE; - if (end >= max_addr) - break; + if (i == num_nodes + node_start - 1) + end = max_addr; + else + while (end - *addr - E820_ADDR_HOLE_SIZE(*addr, end) < + size) { + end += FAKE_NODE_MIN_SIZE; + if (end > max_addr) { + end = max_addr; + break; + } + } + if (setup_node_range(i, nodes, addr, end - *addr, max_addr) < 0) + break; + } + return i - node_start + 1; +} + +/* + * Sets up the system RAM area from start_pfn to end_pfn according to the + * numa=fake command-line option. + */ +static int __init numa_emulation(unsigned long start_pfn, unsigned long end_pfn) +{ + struct bootnode nodes[MAX_NUMNODES]; + u64 addr = start_pfn << PAGE_SHIFT; + u64 max_addr = end_pfn << PAGE_SHIFT; + unsigned int coeff; + unsigned int num = 0; + int num_nodes = 0; + u64 size; + int i; + + memset(&nodes, 0, sizeof(nodes)); + /* + * If the numa=fake command-line is just a single number N, split the + * system RAM into N fake nodes. + */ + if (!strchr(cmdline, '*') && !strchr(cmdline, ',')) { + num_nodes = split_nodes_equally(nodes, &addr, max_addr, 0, + simple_strtol(cmdline, NULL, 0)); + if (num_nodes < 0) + return num_nodes; + goto out; + } + + /* Parse the command line. */ + for (coeff = 1; ; cmdline++) { + if (*cmdline && isdigit(*cmdline)) { + num = num * 10 + *cmdline - '0'; + continue; } - /* - * Look at the next node to make sure there is some real memory - * to map. Bad things happen when the only memory present - * in a zone on a fake node is IO hole. - */ - while (e820_hole_size(end, end + FAKE_NODE_MIN_SIZE) > 0) { - if (zone_cross_over(start, end + sz)) { - end = (MAX_DMA32_PFN << PAGE_SHIFT); - break; + if (*cmdline == '*') + coeff = num; + if (!*cmdline || *cmdline == ',') { + /* + * Round down to the nearest FAKE_NODE_MIN_SIZE. + * Command-line coefficients are in megabytes. + */ + size = ((u64)num << 20) & FAKE_NODE_MIN_HASH_MASK; + if (size) { + for (i = 0; i < coeff; i++, num_nodes++) + if (setup_node_range(num_nodes, nodes, + &addr, size, max_addr) < 0) + goto done; + coeff = 1; } - if (end >= max_addr) - break; - end += FAKE_NODE_MIN_SIZE; } - if (end > max_addr) - end = max_addr; - nodes[i].end = end; - printk(KERN_INFO "Faking node %d at %016Lx-%016Lx (%LuMB)\n", - i, - nodes[i].start, nodes[i].end, - (nodes[i].end - nodes[i].start) >> 20); - node_set_online(i); - } - memnode_shift = compute_hash_shift(nodes, numa_fake); - if (memnode_shift < 0) { - memnode_shift = 0; - printk(KERN_ERR "No NUMA hash function found. Emulation disabled.\n"); - return -1; - } - for_each_online_node(i) { + if (!*cmdline) + break; + num = 0; + } +done: + if (!num_nodes) + return -1; + /* Fill remainder of system RAM with a final node, if appropriate. */ + if (addr < max_addr) { + setup_node_range(num_nodes, nodes, &addr, max_addr - addr, + max_addr); + num_nodes++; + } +out: + memnode_shift = compute_hash_shift(nodes, num_nodes); + if (memnode_shift < 0) { + memnode_shift = 0; + printk(KERN_ERR "No NUMA hash function found. NUMA emulation " + "disabled.\n"); + return -1; + } + + /* + * We need to vacate all active ranges that may have been registered by + * SRAT. + */ + remove_all_active_ranges(); + for_each_online_node(i) { e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT, nodes[i].end >> PAGE_SHIFT); setup_node_bootmem(i, nodes[i].start, nodes[i].end); @@ -399,14 +446,15 @@ static int __init numa_emulation(unsigned long start_pfn, unsigned long end_pfn) numa_init_array(); return 0; } -#endif +#undef E820_ADDR_HOLE_SIZE +#endif /* CONFIG_NUMA_EMU */ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn) { int i; #ifdef CONFIG_NUMA_EMU - if (numa_fake && !numa_emulation(start_pfn, end_pfn)) + if (cmdline && !numa_emulation(start_pfn, end_pfn)) return; #endif @@ -486,11 +534,8 @@ static __init int numa_setup(char *opt) if (!strncmp(opt,"off",3)) numa_off = 1; #ifdef CONFIG_NUMA_EMU - if(!strncmp(opt, "fake=", 5)) { - numa_fake = simple_strtoul(opt+5,NULL,0); ; - if (numa_fake >= MAX_NUMNODES) - numa_fake = MAX_NUMNODES; - } + if (!strncmp(opt, "fake=", 5)) + cmdline = opt + 5; #endif #ifdef CONFIG_ACPI_NUMA if (!strncmp(opt,"noacpi",6)) diff --git a/include/asm-x86_64/mmzone.h b/include/asm-x86_64/mmzone.h index fb558fb1d211..19a89377b123 100644 --- a/include/asm-x86_64/mmzone.h +++ b/include/asm-x86_64/mmzone.h @@ -49,7 +49,7 @@ extern int pfn_valid(unsigned long pfn); #ifdef CONFIG_NUMA_EMU #define FAKE_NODE_MIN_SIZE (64*1024*1024) -#define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1ul)) +#define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1uL)) #endif #endif -- cgit v1.2.3-59-g8ed1b From 14694d736bb66d0ec250d05c81c6e98a19c229c6 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Wed, 2 May 2007 19:27:09 +0200 Subject: [PATCH] x86-64: split remaining fake nodes equally Extends the numa=fake x86_64 command-line option to split the remaining system memory into equal-sized nodes. For example: numa=fake=2*512,4* gives two 512M nodes and the remaining system memory is split into four approximately equal chunks. This is beneficial for systems where the exact size of RAM is unknown or not necessarily relevant, but the granularity with which nodes shall be allocated is known. Cc: Andi Kleen Signed-off-by: David Rientjes Signed-off-by: Andi Kleen Cc: Paul Jackson Cc: Christoph Lameter Signed-off-by: Andrew Morton --- Documentation/x86_64/boot-options.txt | 4 +++- arch/x86_64/mm/numa.c | 22 ++++++++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt index 7500aad95f3c..12a9aacecaae 100644 --- a/Documentation/x86_64/boot-options.txt +++ b/Documentation/x86_64/boot-options.txt @@ -155,7 +155,9 @@ NUMA depending on the sizes and coefficients listed. For example: numa=fake=2*512,1024,4*256 gives two 512M nodes, a 1024M node, and four 256M nodes. The - remaining system RAM is allocated to an additional node. + remaining system RAM is allocated to an additional node. If + the last character of CMDLINE is a *, the remaining system RAM + is instead divided up equally among its coefficient. numa=hotadd=percent Only allow hotadd memory to preallocate page structures upto diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index c55936bc6be6..0ae2d9d5d7ea 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c @@ -418,11 +418,25 @@ static int __init numa_emulation(unsigned long start_pfn, unsigned long end_pfn) done: if (!num_nodes) return -1; - /* Fill remainder of system RAM with a final node, if appropriate. */ + /* Fill remainder of system RAM, if appropriate. */ if (addr < max_addr) { - setup_node_range(num_nodes, nodes, &addr, max_addr - addr, - max_addr); - num_nodes++; + switch (*(cmdline - 1)) { + case '*': + /* Split remaining nodes into coeff chunks */ + if (coeff <= 0) + break; + num_nodes += split_nodes_equally(nodes, &addr, max_addr, + num_nodes, coeff); + break; + case ',': + /* Do not allocate remaining system RAM */ + break; + default: + /* Give one final node */ + setup_node_range(num_nodes, nodes, &addr, + max_addr - addr, max_addr); + num_nodes++; + } } out: memnode_shift = compute_hash_shift(nodes, num_nodes); -- cgit v1.2.3-59-g8ed1b From 382591d500bbcd20a44416c5e0e292708468587c Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Wed, 2 May 2007 19:27:09 +0200 Subject: [PATCH] x86-64: fixed size remaining fake nodes Extends the numa=fake x86_64 command-line option to split the remaining system memory into nodes of fixed size. Any leftover memory is allocated to a final node unless the command-line ends with a comma. For example: numa=fake=2*512,*128 gives two 512M nodes and the remaining system memory is split into nodes of 128M each. This is beneficial for systems where the exact size of RAM is unknown or not necessarily relevant, but the size of the remaining nodes to be allocated is known based on their capacity for resource management. Cc: Andi Kleen Signed-off-by: David Rientjes Signed-off-by: Andi Kleen Cc: Paul Jackson Cc: Christoph Lameter Signed-off-by: Andrew Morton --- Documentation/x86_64/boot-options.txt | 14 +++++++---- arch/x86_64/mm/numa.c | 47 +++++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt index 12a9aacecaae..6177d881983f 100644 --- a/Documentation/x86_64/boot-options.txt +++ b/Documentation/x86_64/boot-options.txt @@ -153,11 +153,15 @@ NUMA If a number, fakes CMDLINE nodes and ignores NUMA setup of the actual machine. Otherwise, system memory is configured depending on the sizes and coefficients listed. For example: - numa=fake=2*512,1024,4*256 - gives two 512M nodes, a 1024M node, and four 256M nodes. The - remaining system RAM is allocated to an additional node. If - the last character of CMDLINE is a *, the remaining system RAM - is instead divided up equally among its coefficient. + numa=fake=2*512,1024,4*256,*128 + gives two 512M nodes, a 1024M node, four 256M nodes, and the + rest split into 128M chunks. If the last character of CMDLINE + is a *, the remaining memory is divided up equally among its + coefficient: + numa=fake=2*512,2* + gives two 512M nodes and the rest split into two nodes. + Otherwise, the remaining system RAM is allocated to an + additional node. numa=hotadd=percent Only allow hotadd memory to preallocate page structures upto diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index 0ae2d9d5d7ea..5ee07bc41eb5 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c @@ -361,6 +361,21 @@ static int __init split_nodes_equally(struct bootnode *nodes, u64 *addr, return i - node_start + 1; } +/* + * Splits the remaining system RAM into chunks of size. The remaining memory is + * always assigned to a final node and can be asymmetric. Returns the number of + * nodes split. + */ +static int __init split_nodes_by_size(struct bootnode *nodes, u64 *addr, + u64 max_addr, int node_start, u64 size) +{ + int i = node_start; + size = (size << 20) & FAKE_NODE_MIN_HASH_MASK; + while (!setup_node_range(i++, nodes, addr, size, max_addr)) + ; + return i - node_start; +} + /* * Sets up the system RAM area from start_pfn to end_pfn according to the * numa=fake command-line option. @@ -370,9 +385,10 @@ static int __init numa_emulation(unsigned long start_pfn, unsigned long end_pfn) struct bootnode nodes[MAX_NUMNODES]; u64 addr = start_pfn << PAGE_SHIFT; u64 max_addr = end_pfn << PAGE_SHIFT; - unsigned int coeff; - unsigned int num = 0; int num_nodes = 0; + int coeff_flag; + int coeff = -1; + int num = 0; u64 size; int i; @@ -390,29 +406,34 @@ static int __init numa_emulation(unsigned long start_pfn, unsigned long end_pfn) } /* Parse the command line. */ - for (coeff = 1; ; cmdline++) { + for (coeff_flag = 0; ; cmdline++) { if (*cmdline && isdigit(*cmdline)) { num = num * 10 + *cmdline - '0'; continue; } - if (*cmdline == '*') - coeff = num; + if (*cmdline == '*') { + if (num > 0) + coeff = num; + coeff_flag = 1; + } if (!*cmdline || *cmdline == ',') { + if (!coeff_flag) + coeff = 1; /* * Round down to the nearest FAKE_NODE_MIN_SIZE. * Command-line coefficients are in megabytes. */ size = ((u64)num << 20) & FAKE_NODE_MIN_HASH_MASK; - if (size) { + if (size) for (i = 0; i < coeff; i++, num_nodes++) if (setup_node_range(num_nodes, nodes, &addr, size, max_addr) < 0) goto done; - coeff = 1; - } + if (!*cmdline) + break; + coeff_flag = 0; + coeff = -1; } - if (!*cmdline) - break; num = 0; } done: @@ -420,6 +441,12 @@ done: return -1; /* Fill remainder of system RAM, if appropriate. */ if (addr < max_addr) { + if (coeff_flag && coeff < 0) { + /* Split remaining nodes into num-sized chunks */ + num_nodes += split_nodes_by_size(nodes, &addr, max_addr, + num_nodes, num); + goto out; + } switch (*(cmdline - 1)) { case '*': /* Split remaining nodes into coeff chunks */ -- cgit v1.2.3-59-g8ed1b From d824395c5994adbf7efe377cc67f732133270554 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 2 May 2007 19:27:09 +0200 Subject: [PATCH] x86: remove constant_tsc reporting from /proc/cpuinfo' power flags remove the reporting of the constant_tsc flag from the "power management" field in /proc/cpuinfo. The NULL value there was replaced by "" because the former would result in a printout of [8] if the flag is set. Signed-off-by: Joerg Roedel Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/kernel/cpu/proc.c | 3 +-- arch/x86_64/kernel/setup.c | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c index 47e3ebbfb28d..89d91e6cc972 100644 --- a/arch/i386/kernel/cpu/proc.c +++ b/arch/i386/kernel/cpu/proc.c @@ -72,8 +72,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) "stc", "100mhzsteps", "hwpstate", - NULL, - NULL, /* constant_tsc - moved to flags */ + "", /* constant_tsc - moved to flags */ /* nothing */ }; struct cpuinfo_x86 *c = v; diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index b9bdfc1b54f8..0a1d539149df 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -979,9 +979,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) "stc", "100mhzsteps", "hwpstate", - NULL, /* tsc invariant mapped to constant_tsc */ - NULL, - /* nothing */ /* constant_tsc - moved to flags */ + "", /* tsc invariant mapped to constant_tsc */ + /* nothing */ }; -- cgit v1.2.3-59-g8ed1b From 1b523fb54977c9bb81b16c4badce581a2b455994 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 2 May 2007 19:27:09 +0200 Subject: [PATCH] i386: VDSO_PRELINK warning fix The lguest patches somehow managed to trigger this: In file included from arch/i386/lguest/lguest.c:38: include/asm/asm-offsets.h:67:1: warning: "VDSO_PRELINK" redefined In file included from include/linux/elf.h:7, from include/linux/module.h:15, from include/linux/device.h:21, from include/linux/interrupt.h:15, from arch/i386/lguest/lguest.c:27: include/asm/elf.h:140:1: warning: this is the location of the previous definition I assume that using the same identifier twice was a bad idea.. Cc: Rusty Russell Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/kernel/asm-offsets.c | 2 +- arch/i386/kernel/vsyscall.lds.S | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c index d822792d8e3e..655cc8d4c745 100644 --- a/arch/i386/kernel/asm-offsets.c +++ b/arch/i386/kernel/asm-offsets.c @@ -97,7 +97,7 @@ void foo(void) sizeof(struct tss_struct)); DEFINE(PAGE_SIZE_asm, PAGE_SIZE); - DEFINE(VDSO_PRELINK, VDSO_PRELINK); + DEFINE(VDSO_PRELINK_asm, VDSO_PRELINK); OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx); diff --git a/arch/i386/kernel/vsyscall.lds.S b/arch/i386/kernel/vsyscall.lds.S index f66cd11adb72..4a8b0ed9b8fb 100644 --- a/arch/i386/kernel/vsyscall.lds.S +++ b/arch/i386/kernel/vsyscall.lds.S @@ -7,7 +7,7 @@ SECTIONS { - . = VDSO_PRELINK + SIZEOF_HEADERS; + . = VDSO_PRELINK_asm + SIZEOF_HEADERS; .hash : { *(.hash) } :text .gnu.hash : { *(.gnu.hash) } @@ -21,7 +21,7 @@ SECTIONS For the layouts to match, we need to skip more than enough space for the dynamic symbol table et al. If this amount is insufficient, ld -shared will barf. Just increase it here. */ - . = VDSO_PRELINK + 0x400; + . = VDSO_PRELINK_asm + 0x400; .text : { *(.text) } :text =0x90909090 .note : { *(.note.*) } :text :note -- cgit v1.2.3-59-g8ed1b From 8f9aeca7a081d81c4c9862be1e04f15b5ab5461f Mon Sep 17 00:00:00 2001 From: Bernhard Walle Date: Wed, 2 May 2007 19:27:10 +0200 Subject: [PATCH] x86: add command line length to boot protocol Because the command line is increased to 2048 characters after 2.6.21, it's not possible for boot loaders and userspace tools to determine the length of the command line the kernel can understand. The benefit of knowing the length is that users can be warned if the command line size is too long which prevents surprise if things don't work after bootup. This patch updates the boot protocol to contain a field called "cmdline_size" that contain the length of the command line (excluding the terminating zero). The patch also adds missing fields (of protocol version 2.05) to the x86_64 setup code. Signed-off-by: Bernhard Walle Signed-off-by: Andi Kleen Cc: Alon Bar-Lev Acked-by: H. Peter Anvin Cc: Andi Kleen Signed-off-by: Andrew Morton --- Documentation/i386/boot.txt | 23 +++++++++++++++++------ arch/i386/boot/setup.S | 7 ++++++- arch/x86_64/boot/setup.S | 7 ++++++- 3 files changed, 29 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/Documentation/i386/boot.txt b/Documentation/i386/boot.txt index 38fe1f03fb14..6498666ea330 100644 --- a/Documentation/i386/boot.txt +++ b/Documentation/i386/boot.txt @@ -2,7 +2,7 @@ ---------------------------- H. Peter Anvin - Last update 2007-01-26 + Last update 2007-03-06 On the i386 platform, the Linux kernel uses a rather complicated boot convention. This has evolved partially due to historical aspects, as @@ -35,9 +35,13 @@ Protocol 2.03: (Kernel 2.4.18-pre1) Explicitly makes the highest possible initrd address available to the bootloader. Protocol 2.04: (Kernel 2.6.14) Extend the syssize field to four bytes. + Protocol 2.05: (Kernel 2.6.20) Make protected mode kernel relocatable. Introduce relocatable_kernel and kernel_alignment fields. +Protocol 2.06: (Kernel 2.6.22) Added a field that contains the size of + the boot command line + **** MEMORY LAYOUT @@ -133,6 +137,8 @@ Offset Proto Name Meaning 022C/4 2.03+ initrd_addr_max Highest legal initrd address 0230/4 2.05+ kernel_alignment Physical addr alignment required for kernel 0234/1 2.05+ relocatable_kernel Whether kernel is relocatable or not +0235/3 N/A pad2 Unused +0238/4 2.06+ cmdline_size Maximum size of the kernel command line (1) For backwards compatibility, if the setup_sects field contains 0, the real value is 4. @@ -233,6 +239,12 @@ filled out, however: if your ramdisk is exactly 131072 bytes long and this field is 0x37FFFFFF, you can start your ramdisk at 0x37FE0000.) + cmdline_size: + The maximum size of the command line without the terminating + zero. This means that the command line can contain at most + cmdline_size characters. With protocol version 2.05 and + earlier, the maximum size was 255. + **** THE KERNEL COMMAND LINE @@ -241,11 +253,10 @@ loader to communicate with the kernel. Some of its options are also relevant to the boot loader itself, see "special command line options" below. -The kernel command line is a null-terminated string currently up to -255 characters long, plus the final null. A string that is too long -will be automatically truncated by the kernel, a boot loader may allow -a longer command line to be passed to permit future kernels to extend -this limit. +The kernel command line is a null-terminated string. The maximum +length can be retrieved from the field cmdline_size. Before protocol +version 2.06, the maximum was 255 characters. A string that is too +long will be automatically truncated by the kernel. If the boot protocol version is 2.02 or later, the address of the kernel command line is given by the header field cmd_line_ptr (see diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S index 06edf1c66242..b74b7f40b79c 100644 --- a/arch/i386/boot/setup.S +++ b/arch/i386/boot/setup.S @@ -52,6 +52,7 @@ #include #include #include +#include /* Signature words to ensure LILO loaded us right */ #define SIG1 0xAA55 @@ -81,7 +82,7 @@ start: # This is the setup header, and it must start at %cs:2 (old 0x9020:2) .ascii "HdrS" # header signature - .word 0x0205 # header version number (>= 0x0105) + .word 0x0206 # header version number (>= 0x0105) # or else old loadlin-1.5 will fail) realmode_swtch: .word 0, 0 # default_switch, SETUPSEG start_sys_seg: .word SYSSEG @@ -171,6 +172,10 @@ relocatable_kernel: .byte 0 pad2: .byte 0 pad3: .word 0 +cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line, + #added with boot protocol + #version 2.06 + trampoline: call start_of_setup .align 16 # The offset at this point is 0x240 diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S index 816d04faa2be..4f8851000d7e 100644 --- a/arch/x86_64/boot/setup.S +++ b/arch/x86_64/boot/setup.S @@ -51,6 +51,7 @@ #include #include #include +#include /* Signature words to ensure LILO loaded us right */ #define SIG1 0xAA55 @@ -80,7 +81,7 @@ start: # This is the setup header, and it must start at %cs:2 (old 0x9020:2) .ascii "HdrS" # header signature - .word 0x0205 # header version number (>= 0x0105) + .word 0x0206 # header version number (>= 0x0105) # or else old loadlin-1.5 will fail) realmode_swtch: .word 0, 0 # default_switch, SETUPSEG start_sys_seg: .word SYSSEG @@ -165,6 +166,10 @@ relocatable_kernel: .byte 0 pad2: .byte 0 pad3: .word 0 +cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line, + #added with boot protocol + #version 2.06 + trampoline: call start_of_setup .align 16 # The offset at this point is 0x240 -- cgit v1.2.3-59-g8ed1b From ae1ee11be77f51cedb6c569887dddc70c163ab6d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 2 May 2007 19:27:10 +0200 Subject: [PATCH] i386: Use per-cpu variables for GDT, PDA Allocating PDA and GDT at boot is a pain. Using simple per-cpu variables adds happiness (although we need the GDT page-aligned for Xen, which we do in a followup patch). [akpm@linux-foundation.org: build fix] Signed-off-by: Rusty Russell Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/cpu/common.c | 94 +++++------------------------------- arch/i386/kernel/smpboot.c | 21 +------- arch/i386/mach-voyager/voyager_smp.c | 10 +--- include/asm-generic/percpu.h | 1 + include/asm-i386/desc.h | 1 + include/asm-i386/pda.h | 7 ++- include/asm-i386/processor.h | 2 +- 7 files changed, 21 insertions(+), 115 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index dcbbd0a8bfc2..2335f4464ead 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -25,8 +25,10 @@ DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr); -struct i386_pda *_cpu_pda[NR_CPUS] __read_mostly; -EXPORT_SYMBOL(_cpu_pda); +DEFINE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]); + +DEFINE_PER_CPU(struct i386_pda, _cpu_pda); +EXPORT_PER_CPU_SYMBOL(_cpu_pda); static int cachesize_override __cpuinitdata = -1; static int disable_x86_fxsr __cpuinitdata; @@ -609,52 +611,6 @@ struct pt_regs * __devinit idle_regs(struct pt_regs *regs) return regs; } -static __cpuinit int alloc_gdt(int cpu) -{ - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); - struct desc_struct *gdt; - struct i386_pda *pda; - - gdt = (struct desc_struct *)cpu_gdt_descr->address; - pda = cpu_pda(cpu); - - /* - * This is a horrible hack to allocate the GDT. The problem - * is that cpu_init() is called really early for the boot CPU - * (and hence needs bootmem) but much later for the secondary - * CPUs, when bootmem will have gone away - */ - if (NODE_DATA(0)->bdata->node_bootmem_map) { - BUG_ON(gdt != NULL || pda != NULL); - - gdt = alloc_bootmem_pages(PAGE_SIZE); - pda = alloc_bootmem(sizeof(*pda)); - /* alloc_bootmem(_pages) panics on failure, so no check */ - - memset(gdt, 0, PAGE_SIZE); - memset(pda, 0, sizeof(*pda)); - } else { - /* GDT and PDA might already have been allocated if - this is a CPU hotplug re-insertion. */ - if (gdt == NULL) - gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL); - - if (pda == NULL) - pda = kmalloc_node(sizeof(*pda), GFP_KERNEL, cpu_to_node(cpu)); - - if (unlikely(!gdt || !pda)) { - free_pages((unsigned long)gdt, 0); - kfree(pda); - return 0; - } - } - - cpu_gdt_descr->address = (unsigned long)gdt; - cpu_pda(cpu) = pda; - - return 1; -} - /* Initial PDA used by boot CPU */ struct i386_pda boot_pda = { ._pda = &boot_pda, @@ -670,31 +626,17 @@ static inline void set_kernel_fs(void) asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_PDA) : "memory"); } -/* Initialize the CPU's GDT and PDA. The boot CPU does this for - itself, but secondaries find this done for them. */ -__cpuinit int init_gdt(int cpu, struct task_struct *idle) +/* Initialize the CPU's GDT and PDA. This is either the boot CPU doing itself + (still using cpu_gdt_table), or a CPU doing it for a secondary which + will soon come up. */ +__cpuinit void init_gdt(int cpu, struct task_struct *idle) { struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); - struct desc_struct *gdt; - struct i386_pda *pda; - - /* For non-boot CPUs, the GDT and PDA should already have been - allocated. */ - if (!alloc_gdt(cpu)) { - printk(KERN_CRIT "CPU%d failed to allocate GDT or PDA\n", cpu); - return 0; - } + struct desc_struct *gdt = per_cpu(cpu_gdt, cpu); + struct i386_pda *pda = &per_cpu(_cpu_pda, cpu); - gdt = (struct desc_struct *)cpu_gdt_descr->address; - pda = cpu_pda(cpu); - - BUG_ON(gdt == NULL || pda == NULL); - - /* - * Initialize the per-CPU GDT with the boot GDT, - * and set up the GDT descriptor: - */ memcpy(gdt, cpu_gdt_table, GDT_SIZE); + cpu_gdt_descr->address = (unsigned long)gdt; cpu_gdt_descr->size = GDT_SIZE - 1; pack_descriptor((u32 *)&gdt[GDT_ENTRY_PDA].a, @@ -706,17 +648,12 @@ __cpuinit int init_gdt(int cpu, struct task_struct *idle) pda->_pda = pda; pda->cpu_number = cpu; pda->pcurrent = idle; - - return 1; } void __cpuinit cpu_set_gdt(int cpu) { struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); - /* Reinit these anyway, even if they've already been done (on - the boot CPU, this will transition from the boot gdt+pda to - the real ones). */ load_gdt(cpu_gdt_descr); set_kernel_fs(); } @@ -804,13 +741,8 @@ void __cpuinit cpu_init(void) struct task_struct *curr = current; /* Set up the real GDT and PDA, so we can transition from the - boot versions. */ - if (!init_gdt(cpu, curr)) { - /* failed to allocate something; not much we can do... */ - for (;;) - local_irq_enable(); - } - + boot_gdt_table & boot_pda. */ + init_gdt(cpu, curr); cpu_set_gdt(cpu); _cpu_init(cpu, curr); } diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 7b14e88b555f..b36a5f174cc9 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -808,13 +808,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) if (IS_ERR(idle)) panic("failed fork for CPU %d", cpu); - /* Pre-allocate and initialize the CPU's GDT and PDA so it - doesn't have to do any memory allocation during the - delicate CPU-bringup phase. */ - if (!init_gdt(cpu, idle)) { - printk(KERN_INFO "Couldn't allocate GDT/PDA for CPU %d\n", cpu); - return -1; /* ? */ - } + init_gdt(cpu, idle); idle->thread.eip = (unsigned long) start_secondary; /* start_eip had better be page-aligned! */ @@ -940,7 +934,6 @@ static int __cpuinit __smp_prepare_cpu(int cpu) DECLARE_COMPLETION_ONSTACK(done); struct warm_boot_cpu_info info; int apicid, ret; - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); apicid = x86_cpu_to_apicid[cpu]; if (apicid == BAD_APICID) { @@ -948,18 +941,6 @@ static int __cpuinit __smp_prepare_cpu(int cpu) goto exit; } - /* - * the CPU isn't initialized at boot time, allocate gdt table here. - * cpu_init will initialize it - */ - if (!cpu_gdt_descr->address) { - cpu_gdt_descr->address = get_zeroed_page(GFP_KERNEL); - if (!cpu_gdt_descr->address) - printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu); - ret = -ENOMEM; - goto exit; - } - info.complete = &done; info.apicid = apicid; info.cpu = cpu; diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index 74aeedf277f4..15d8132d4f5e 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c @@ -580,15 +580,7 @@ do_boot_cpu(__u8 cpu) /* init_tasks (in sched.c) is indexed logically */ stack_start.esp = (void *) idle->thread.esp; - /* Pre-allocate and initialize the CPU's GDT and PDA so it - doesn't have to do any memory allocation during the - delicate CPU-bringup phase. */ - if (!init_gdt(cpu, idle)) { - printk(KERN_INFO "Couldn't allocate GDT/PDA for CPU %d\n", cpu); - cpucount--; - return; - } - + init_gdt(cpu, idle); irq_ctx_init(cpu); /* Note: Don't modify initial ss override */ diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h index 196376262240..d984a9041436 100644 --- a/include/asm-generic/percpu.h +++ b/include/asm-generic/percpu.h @@ -1,6 +1,7 @@ #ifndef _ASM_GENERIC_PERCPU_H_ #define _ASM_GENERIC_PERCPU_H_ #include +#include #define __GENERIC_PER_CPU #ifdef CONFIG_SMP diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h index 050831f34f71..53c5916687b6 100644 --- a/include/asm-i386/desc.h +++ b/include/asm-i386/desc.h @@ -22,6 +22,7 @@ struct Xgt_desc_struct { extern struct Xgt_desc_struct idt_descr; DECLARE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); +DECLARE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]); extern struct Xgt_desc_struct early_gdt_descr; static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) diff --git a/include/asm-i386/pda.h b/include/asm-i386/pda.h index b12d59a318b7..aef7f732f77e 100644 --- a/include/asm-i386/pda.h +++ b/include/asm-i386/pda.h @@ -8,6 +8,7 @@ #include #include +#include struct i386_pda { @@ -18,10 +19,8 @@ struct i386_pda struct pt_regs *irq_regs; }; -extern struct i386_pda *_cpu_pda[]; - -#define cpu_pda(i) (_cpu_pda[i]) - +DECLARE_PER_CPU(struct i386_pda, _cpu_pda); +#define cpu_pda(i) (&per_cpu(_cpu_pda, (i))) #define pda_offset(field) offsetof(struct i386_pda, field) extern void __bad_pda_field(void); diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 01ae0ffcf236..cd940befef53 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -743,7 +743,7 @@ extern unsigned long boot_option_idle_override; extern void enable_sep_cpu(void); extern int sysenter_setup(void); -extern int init_gdt(int cpu, struct task_struct *idle); +extern void init_gdt(int cpu, struct task_struct *idle); extern void cpu_set_gdt(int); extern void secondary_cpu_init(void); -- cgit v1.2.3-59-g8ed1b From bf50467204b435421d8de33ad080fa46c6f3d50b Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 2 May 2007 19:27:10 +0200 Subject: [PATCH] i386: Use per-cpu GDT immediately upon boot Now we are no longer dynamically allocating the GDT, we don't need the "cpu_gdt_table" at all: we can switch straight from "boot_gdt_table" to the per-cpu GDT. This means initializing the cpu_gdt array in C. The boot CPU uses the per-cpu var directly, then in smp_prepare_cpus() it switches to the per-cpu copy just allocated. For secondary CPUs, the early_gdt_descr is set to point directly to their per-cpu copy. For UP the code is very simple: it keeps using the "per-cpu" GDT as per SMP, but we never have to move. Signed-off-by: Rusty Russell Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/cpu/common.c | 72 ++++++++++++++---------------------- arch/i386/kernel/head.S | 55 +-------------------------- arch/i386/kernel/smpboot.c | 59 +++++++++++++++++++++++------ arch/i386/mach-voyager/voyager_smp.c | 6 --- include/asm-i386/desc.h | 2 - include/asm-i386/processor.h | 1 - 6 files changed, 75 insertions(+), 120 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 2335f4464ead..fd6b079f7609 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -25,7 +25,33 @@ DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr); -DEFINE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]); +DEFINE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]) = { + [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 }, + [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 }, + [GDT_ENTRY_DEFAULT_USER_CS] = { 0x0000ffff, 0x00cffa00 }, + [GDT_ENTRY_DEFAULT_USER_DS] = { 0x0000ffff, 0x00cff200 }, + /* + * Segments used for calling PnP BIOS have byte granularity. + * They code segments and data segments have fixed 64k limits, + * the transfer segment sizes are set at run time. + */ + [GDT_ENTRY_PNPBIOS_CS32] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */ + [GDT_ENTRY_PNPBIOS_CS16] = { 0x0000ffff, 0x00009a00 },/* 16-bit code */ + [GDT_ENTRY_PNPBIOS_DS] = { 0x0000ffff, 0x00009200 }, /* 16-bit data */ + [GDT_ENTRY_PNPBIOS_TS1] = { 0x00000000, 0x00009200 },/* 16-bit data */ + [GDT_ENTRY_PNPBIOS_TS2] = { 0x00000000, 0x00009200 },/* 16-bit data */ + /* + * The APM segments have byte granularity and their bases + * are set at run time. All have 64k limits. + */ + [GDT_ENTRY_APMBIOS_BASE] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */ + /* 16-bit code */ + [GDT_ENTRY_APMBIOS_BASE+1] = { 0x0000ffff, 0x00009a00 }, + [GDT_ENTRY_APMBIOS_BASE+2] = { 0x0000ffff, 0x00409200 }, /* data */ + + [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 }, + [GDT_ENTRY_PDA] = { 0x00000000, 0x00c09200 }, /* set in setup_pda */ +}; DEFINE_PER_CPU(struct i386_pda, _cpu_pda); EXPORT_PER_CPU_SYMBOL(_cpu_pda); @@ -618,46 +644,6 @@ struct i386_pda boot_pda = { .pcurrent = &init_task, }; -static inline void set_kernel_fs(void) -{ - /* Set %fs for this CPU's PDA. Memory clobber is to create a - barrier with respect to any PDA operations, so the compiler - doesn't move any before here. */ - asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_PDA) : "memory"); -} - -/* Initialize the CPU's GDT and PDA. This is either the boot CPU doing itself - (still using cpu_gdt_table), or a CPU doing it for a secondary which - will soon come up. */ -__cpuinit void init_gdt(int cpu, struct task_struct *idle) -{ - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); - struct desc_struct *gdt = per_cpu(cpu_gdt, cpu); - struct i386_pda *pda = &per_cpu(_cpu_pda, cpu); - - memcpy(gdt, cpu_gdt_table, GDT_SIZE); - cpu_gdt_descr->address = (unsigned long)gdt; - cpu_gdt_descr->size = GDT_SIZE - 1; - - pack_descriptor((u32 *)&gdt[GDT_ENTRY_PDA].a, - (u32 *)&gdt[GDT_ENTRY_PDA].b, - (unsigned long)pda, sizeof(*pda) - 1, - 0x80 | DESCTYPE_S | 0x2, 0); /* present read-write data segment */ - - memset(pda, 0, sizeof(*pda)); - pda->_pda = pda; - pda->cpu_number = cpu; - pda->pcurrent = idle; -} - -void __cpuinit cpu_set_gdt(int cpu) -{ - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); - - load_gdt(cpu_gdt_descr); - set_kernel_fs(); -} - /* Common CPU init for both boot and secondary CPUs */ static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) { @@ -740,10 +726,6 @@ void __cpuinit cpu_init(void) int cpu = smp_processor_id(); struct task_struct *curr = current; - /* Set up the real GDT and PDA, so we can transition from the - boot_gdt_table & boot_pda. */ - init_gdt(cpu, curr); - cpu_set_gdt(cpu); _cpu_init(cpu, curr); } diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index cb185f40c282..633fd2f47429 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -599,7 +599,7 @@ idt_descr: .word 0 # 32 bit align gdt_desc.address ENTRY(early_gdt_descr) .word GDT_ENTRIES*8-1 - .long cpu_gdt_table + .long per_cpu__cpu_gdt /* Overwritten for secondary CPUs */ /* * The boot_gdt_table must mirror the equivalent in setup.S and is @@ -610,56 +610,3 @@ ENTRY(boot_gdt_table) .fill GDT_ENTRY_BOOT_CS,8,0 .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */ .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */ - -/* - * The Global Descriptor Table contains 32 quadwords, per-CPU. - */ - .align L1_CACHE_BYTES -ENTRY(cpu_gdt_table) - .quad 0x0000000000000000 /* NULL descriptor */ - .quad 0x0000000000000000 /* 0x0b reserved */ - .quad 0x0000000000000000 /* 0x13 reserved */ - .quad 0x0000000000000000 /* 0x1b reserved */ - .quad 0x0000000000000000 /* 0x20 unused */ - .quad 0x0000000000000000 /* 0x28 unused */ - .quad 0x0000000000000000 /* 0x33 TLS entry 1 */ - .quad 0x0000000000000000 /* 0x3b TLS entry 2 */ - .quad 0x0000000000000000 /* 0x43 TLS entry 3 */ - .quad 0x0000000000000000 /* 0x4b reserved */ - .quad 0x0000000000000000 /* 0x53 reserved */ - .quad 0x0000000000000000 /* 0x5b reserved */ - - .quad 0x00cf9a000000ffff /* 0x60 kernel 4GB code at 0x00000000 */ - .quad 0x00cf92000000ffff /* 0x68 kernel 4GB data at 0x00000000 */ - .quad 0x00cffa000000ffff /* 0x73 user 4GB code at 0x00000000 */ - .quad 0x00cff2000000ffff /* 0x7b user 4GB data at 0x00000000 */ - - .quad 0x0000000000000000 /* 0x80 TSS descriptor */ - .quad 0x0000000000000000 /* 0x88 LDT descriptor */ - - /* - * Segments used for calling PnP BIOS have byte granularity. - * The code segments and data segments have fixed 64k limits, - * the transfer segment sizes are set at run time. - */ - .quad 0x00409a000000ffff /* 0x90 32-bit code */ - .quad 0x00009a000000ffff /* 0x98 16-bit code */ - .quad 0x000092000000ffff /* 0xa0 16-bit data */ - .quad 0x0000920000000000 /* 0xa8 16-bit data */ - .quad 0x0000920000000000 /* 0xb0 16-bit data */ - - /* - * The APM segments have byte granularity and their bases - * are set at run time. All have 64k limits. - */ - .quad 0x00409a000000ffff /* 0xb8 APM CS code */ - .quad 0x00009a000000ffff /* 0xc0 APM CS 16 code (16 bit) */ - .quad 0x004092000000ffff /* 0xc8 APM DS data */ - - .quad 0x00c0920000000000 /* 0xd0 - ESPFIX SS */ - .quad 0x00cf92000000ffff /* 0xd8 - PDA */ - .quad 0x0000000000000000 /* 0xe0 - unused */ - .quad 0x0000000000000000 /* 0xe8 - unused */ - .quad 0x0000000000000000 /* 0xf0 - unused */ - .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */ - diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index b36a5f174cc9..a9447c3e86dd 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -439,12 +439,6 @@ static void __cpuinit start_secondary(void *unused) */ void __devinit initialize_secondary(void) { - /* - * switch to the per CPU GDT we already set up - * in do_boot_cpu() - */ - cpu_set_gdt(current_thread_info()->cpu); - /* * We don't actually need to load the full TSS, * basically just the stack pointer and the eip. @@ -787,6 +781,32 @@ static inline struct task_struct * alloc_idle_task(int cpu) #define alloc_idle_task(cpu) fork_idle(cpu) #endif +/* Initialize the CPU's GDT. This is either the boot CPU doing itself + (still using the master per-cpu area), or a CPU doing it for a + secondary which will soon come up. */ +static __cpuinit void init_gdt(int cpu, struct task_struct *idle) +{ + struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); + struct desc_struct *gdt = per_cpu(cpu_gdt, cpu); + struct i386_pda *pda = &per_cpu(_cpu_pda, cpu); + + cpu_gdt_descr->address = (unsigned long)gdt; + cpu_gdt_descr->size = GDT_SIZE - 1; + + pack_descriptor((u32 *)&gdt[GDT_ENTRY_PDA].a, + (u32 *)&gdt[GDT_ENTRY_PDA].b, + (unsigned long)pda, sizeof(*pda) - 1, + 0x80 | DESCTYPE_S | 0x2, 0); /* present read-write data segment */ + + memset(pda, 0, sizeof(*pda)); + pda->_pda = pda; + pda->cpu_number = cpu; + pda->pcurrent = idle; +} + +/* Defined in head.S */ +extern struct Xgt_desc_struct early_gdt_descr; + static int __cpuinit do_boot_cpu(int apicid, int cpu) /* * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad @@ -809,6 +829,8 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) panic("failed fork for CPU %d", cpu); init_gdt(cpu, idle); + early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); + start_pda = cpu_pda(cpu); idle->thread.eip = (unsigned long) start_secondary; /* start_eip had better be page-aligned! */ @@ -1161,13 +1183,26 @@ void __init smp_prepare_cpus(unsigned int max_cpus) smp_boot_cpus(max_cpus); } -void __devinit smp_prepare_boot_cpu(void) +/* Current gdt points %fs at the "master" per-cpu area: after this, + * it's on the real one. */ +static inline void switch_to_new_gdt(void) { - cpu_set(smp_processor_id(), cpu_online_map); - cpu_set(smp_processor_id(), cpu_callout_map); - cpu_set(smp_processor_id(), cpu_present_map); - cpu_set(smp_processor_id(), cpu_possible_map); - per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; + load_gdt(&per_cpu(cpu_gdt_descr, smp_processor_id())); + asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_PDA) : "memory"); +} + +void __init smp_prepare_boot_cpu(void) +{ + unsigned int cpu = smp_processor_id(); + + init_gdt(cpu, current); + switch_to_new_gdt(); + + cpu_set(cpu, cpu_online_map); + cpu_set(cpu, cpu_callout_map); + cpu_set(cpu, cpu_present_map); + cpu_set(cpu, cpu_possible_map); + __get_cpu_var(cpu_state) = CPU_ONLINE; } #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index 15d8132d4f5e..b9ce33c0c202 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c @@ -764,12 +764,6 @@ initialize_secondary(void) set_current(hard_get_current()); #endif - /* - * switch to the per CPU GDT we already set up - * in do_boot_cpu() - */ - cpu_set_gdt(current_thread_info()->cpu); - /* * We don't actually need to load the full TSS, * basically just the stack pointer and the eip. diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h index 53c5916687b6..a75ae6b97860 100644 --- a/include/asm-i386/desc.h +++ b/include/asm-i386/desc.h @@ -12,8 +12,6 @@ #include -extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; - struct Xgt_desc_struct { unsigned short size; unsigned long address __attribute__((packed)); diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index cd940befef53..b25a2f5b5375 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -743,7 +743,6 @@ extern unsigned long boot_option_idle_override; extern void enable_sep_cpu(void); extern int sysenter_setup(void); -extern void init_gdt(int cpu, struct task_struct *idle); extern void cpu_set_gdt(int); extern void secondary_cpu_init(void); -- cgit v1.2.3-59-g8ed1b From d2cbcc49e2bfd6eaa44d7e4e5e5f171aaa5ec80d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 2 May 2007 19:27:10 +0200 Subject: [PATCH] i386: clean up cpu_init() We now have cpu_init() and secondary_cpu_init() doing nothing but calling _cpu_init() with the same arguments. Rename _cpu_init() to cpu_init() and use it as a replcement for secondary_cpu_init(). Signed-off-by: Rusty Russell Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/cpu/common.c | 34 +++++++++------------------------- arch/i386/kernel/smpboot.c | 8 ++++---- include/asm-i386/processor.h | 2 +- 3 files changed, 14 insertions(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index fd6b079f7609..2a26956fce42 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -644,9 +644,16 @@ struct i386_pda boot_pda = { .pcurrent = &init_task, }; -/* Common CPU init for both boot and secondary CPUs */ -static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) +/* + * cpu_init() initializes state that is per-CPU. Some data is already + * initialized (naturally) in the bootstrap process, such as the GDT + * and IDT. We reload them nevertheless, this function acts as a + * 'CPU state barrier', nothing should get across. + */ +void __cpuinit cpu_init(void) { + int cpu = smp_processor_id(); + struct task_struct *curr = current; struct tss_struct * t = &per_cpu(init_tss, cpu); struct thread_struct *thread = &curr->thread; @@ -706,29 +713,6 @@ static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) mxcsr_feature_mask_init(); } -/* Entrypoint to initialize secondary CPU */ -void __cpuinit secondary_cpu_init(void) -{ - int cpu = smp_processor_id(); - struct task_struct *curr = current; - - _cpu_init(cpu, curr); -} - -/* - * cpu_init() initializes state that is per-CPU. Some data is already - * initialized (naturally) in the bootstrap process, such as the GDT - * and IDT. We reload them nevertheless, this function acts as a - * 'CPU state barrier', nothing should get across. - */ -void __cpuinit cpu_init(void) -{ - int cpu = smp_processor_id(); - struct task_struct *curr = current; - - _cpu_init(cpu, curr); -} - #ifdef CONFIG_HOTPLUG_CPU void __cpuinit cpu_uninit(void) { diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index a9447c3e86dd..954245f6d307 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -378,14 +378,14 @@ set_cpu_sibling_map(int cpu) static void __cpuinit start_secondary(void *unused) { /* - * Don't put *anything* before secondary_cpu_init(), SMP - * booting is too fragile that we want to limit the - * things done here to the most necessary things. + * Don't put *anything* before cpu_init(), SMP booting is too + * fragile that we want to limit the things done here to the + * most necessary things. */ #ifdef CONFIG_VMI vmi_bringup(); #endif - secondary_cpu_init(); + cpu_init(); preempt_disable(); smp_callin(); while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index b25a2f5b5375..80f7e8a1e878 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -744,6 +744,6 @@ extern void enable_sep_cpu(void); extern int sysenter_setup(void); extern void cpu_set_gdt(int); -extern void secondary_cpu_init(void); +extern void cpu_init(void); #endif /* __ASM_I386_PROCESSOR_H */ -- cgit v1.2.3-59-g8ed1b From 52de74dd3994e165ef1b35c33d54655a6400e30c Mon Sep 17 00:00:00 2001 From: Sebastien Dugue Date: Wed, 2 May 2007 19:27:10 +0200 Subject: [PATCH] i386: Rename boot_gdt_table to boot_gdt Rename boot_gdt_table to boot_gdt to avoid the duplicate T(able). Signed-off-by: Sebastien Dugue Signed-off-by: Andi Kleen Acked-by: Rusty Russell Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/head.S | 9 ++++----- arch/i386/kernel/trampoline.S | 12 ++++++------ 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index 633fd2f47429..cc46494787e8 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -147,8 +147,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20); /* * Non-boot CPU entry point; entered from trampoline.S * We can't lgdt here, because lgdt itself uses a data segment, but - * we know the trampoline has already loaded the boot_gdt_table GDT - * for us. + * we know the trampoline has already loaded the boot_gdt for us. * * If cpu hotplug is not supported then this code can go in init section * which will be freed later @@ -588,7 +587,7 @@ fault_msg: .word 0 # 32 bit align gdt_desc.address boot_gdt_descr: .word __BOOT_DS+7 - .long boot_gdt_table - __PAGE_OFFSET + .long boot_gdt - __PAGE_OFFSET .word 0 # 32-bit align idt_desc.address idt_descr: @@ -602,11 +601,11 @@ ENTRY(early_gdt_descr) .long per_cpu__cpu_gdt /* Overwritten for secondary CPUs */ /* - * The boot_gdt_table must mirror the equivalent in setup.S and is + * The boot_gdt must mirror the equivalent in setup.S and is * used only for booting. */ .align L1_CACHE_BYTES -ENTRY(boot_gdt_table) +ENTRY(boot_gdt) .fill GDT_ENTRY_BOOT_CS,8,0 .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */ .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */ diff --git a/arch/i386/kernel/trampoline.S b/arch/i386/kernel/trampoline.S index 2f1814c5cfd7..f62815f8d06a 100644 --- a/arch/i386/kernel/trampoline.S +++ b/arch/i386/kernel/trampoline.S @@ -29,7 +29,7 @@ * * TYPE VALUE * R_386_32 startup_32_smp - * R_386_32 boot_gdt_table + * R_386_32 boot_gdt */ #include @@ -62,8 +62,8 @@ r_base = . * to 32 bit. */ - lidtl boot_idt - r_base # load idt with 0, 0 - lgdtl boot_gdt - r_base # load gdt with whatever is appropriate + lidtl boot_idt_descr - r_base # load idt with 0, 0 + lgdtl boot_gdt_descr - r_base # load gdt with whatever is appropriate xor %ax, %ax inc %ax # protected mode (PE) bit @@ -73,11 +73,11 @@ r_base = . # These need to be in the same 64K segment as the above; # hence we don't use the boot_gdt_descr defined in head.S -boot_gdt: +boot_gdt_descr: .word __BOOT_DS + 7 # gdt limit - .long boot_gdt_table-__PAGE_OFFSET # gdt base + .long boot_gdt - __PAGE_OFFSET # gdt base -boot_idt: +boot_idt_descr: .word 0 # idt limit = 0 .long 0 # idt base = 0L -- cgit v1.2.3-59-g8ed1b From 90a0a06aa81692028864c21f981905fda46b1208 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 2 May 2007 19:27:10 +0200 Subject: [PATCH] i386: rationalize paravirt wrappers paravirt.c used to implement native versions of all low-level functions. Far cleaner is to have the native versions exposed in the headers and as inline native_XXX, and if !CONFIG_PARAVIRT, then simply #define XXX native_XXX. There are several nice side effects: 1) write_dt_entry() now takes the correct "struct Xgt_desc_struct *" not "void *". 2) load_TLS is reintroduced to the for loop, not manually unrolled with a #error in case the bounds ever change. 3) Macros become inlines, with type checking. 4) Access to the native versions is trivial for KVM, lguest, Xen and others who might want it. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Rusty Russell Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Avi Kivity Signed-off-by: Andrew Morton --- arch/i386/kernel/paravirt.c | 293 +------------------------------------------ include/asm-i386/desc.h | 82 ++++++++---- include/asm-i386/io.h | 15 ++- include/asm-i386/irqflags.h | 61 ++++++--- include/asm-i386/msr.h | 163 ++++++++++++++++-------- include/asm-i386/paravirt.h | 17 +-- include/asm-i386/processor.h | 94 ++++++++++---- include/asm-i386/system.h | 139 ++++++++++++-------- 8 files changed, 389 insertions(+), 475 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index 2ec331e03fa9..47698756aec5 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -93,294 +93,11 @@ static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) return insn_len; } -static unsigned long native_get_debugreg(int regno) -{ - unsigned long val = 0; /* Damn you, gcc! */ - - switch (regno) { - case 0: - asm("movl %%db0, %0" :"=r" (val)); break; - case 1: - asm("movl %%db1, %0" :"=r" (val)); break; - case 2: - asm("movl %%db2, %0" :"=r" (val)); break; - case 3: - asm("movl %%db3, %0" :"=r" (val)); break; - case 6: - asm("movl %%db6, %0" :"=r" (val)); break; - case 7: - asm("movl %%db7, %0" :"=r" (val)); break; - default: - BUG(); - } - return val; -} - -static void native_set_debugreg(int regno, unsigned long value) -{ - switch (regno) { - case 0: - asm("movl %0,%%db0" : /* no output */ :"r" (value)); - break; - case 1: - asm("movl %0,%%db1" : /* no output */ :"r" (value)); - break; - case 2: - asm("movl %0,%%db2" : /* no output */ :"r" (value)); - break; - case 3: - asm("movl %0,%%db3" : /* no output */ :"r" (value)); - break; - case 6: - asm("movl %0,%%db6" : /* no output */ :"r" (value)); - break; - case 7: - asm("movl %0,%%db7" : /* no output */ :"r" (value)); - break; - default: - BUG(); - } -} - void init_IRQ(void) { paravirt_ops.init_IRQ(); } -static void native_clts(void) -{ - asm volatile ("clts"); -} - -static unsigned long native_read_cr0(void) -{ - unsigned long val; - asm volatile("movl %%cr0,%0\n\t" :"=r" (val)); - return val; -} - -static void native_write_cr0(unsigned long val) -{ - asm volatile("movl %0,%%cr0": :"r" (val)); -} - -static unsigned long native_read_cr2(void) -{ - unsigned long val; - asm volatile("movl %%cr2,%0\n\t" :"=r" (val)); - return val; -} - -static void native_write_cr2(unsigned long val) -{ - asm volatile("movl %0,%%cr2": :"r" (val)); -} - -static unsigned long native_read_cr3(void) -{ - unsigned long val; - asm volatile("movl %%cr3,%0\n\t" :"=r" (val)); - return val; -} - -static void native_write_cr3(unsigned long val) -{ - asm volatile("movl %0,%%cr3": :"r" (val)); -} - -static unsigned long native_read_cr4(void) -{ - unsigned long val; - asm volatile("movl %%cr4,%0\n\t" :"=r" (val)); - return val; -} - -static unsigned long native_read_cr4_safe(void) -{ - unsigned long val; - /* This could fault if %cr4 does not exist */ - asm("1: movl %%cr4, %0 \n" - "2: \n" - ".section __ex_table,\"a\" \n" - ".long 1b,2b \n" - ".previous \n" - : "=r" (val): "0" (0)); - return val; -} - -static void native_write_cr4(unsigned long val) -{ - asm volatile("movl %0,%%cr4": :"r" (val)); -} - -static unsigned long native_save_fl(void) -{ - unsigned long f; - asm volatile("pushfl ; popl %0":"=g" (f): /* no input */); - return f; -} - -static void native_restore_fl(unsigned long f) -{ - asm volatile("pushl %0 ; popfl": /* no output */ - :"g" (f) - :"memory", "cc"); -} - -static void native_irq_disable(void) -{ - asm volatile("cli": : :"memory"); -} - -static void native_irq_enable(void) -{ - asm volatile("sti": : :"memory"); -} - -static void native_safe_halt(void) -{ - asm volatile("sti; hlt": : :"memory"); -} - -static void native_halt(void) -{ - asm volatile("hlt": : :"memory"); -} - -static void native_wbinvd(void) -{ - asm volatile("wbinvd": : :"memory"); -} - -static unsigned long long native_read_msr(unsigned int msr, int *err) -{ - unsigned long long val; - - asm volatile("2: rdmsr ; xorl %0,%0\n" - "1:\n\t" - ".section .fixup,\"ax\"\n\t" - "3: movl %3,%0 ; jmp 1b\n\t" - ".previous\n\t" - ".section __ex_table,\"a\"\n" - " .align 4\n\t" - " .long 2b,3b\n\t" - ".previous" - : "=r" (*err), "=A" (val) - : "c" (msr), "i" (-EFAULT)); - - return val; -} - -static int native_write_msr(unsigned int msr, unsigned long long val) -{ - int err; - asm volatile("2: wrmsr ; xorl %0,%0\n" - "1:\n\t" - ".section .fixup,\"ax\"\n\t" - "3: movl %4,%0 ; jmp 1b\n\t" - ".previous\n\t" - ".section __ex_table,\"a\"\n" - " .align 4\n\t" - " .long 2b,3b\n\t" - ".previous" - : "=a" (err) - : "c" (msr), "0" ((u32)val), "d" ((u32)(val>>32)), - "i" (-EFAULT)); - return err; -} - -static unsigned long long native_read_tsc(void) -{ - unsigned long long val; - asm volatile("rdtsc" : "=A" (val)); - return val; -} - -static unsigned long long native_read_pmc(void) -{ - unsigned long long val; - asm volatile("rdpmc" : "=A" (val)); - return val; -} - -static void native_load_tr_desc(void) -{ - asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8)); -} - -static void native_load_gdt(const struct Xgt_desc_struct *dtr) -{ - asm volatile("lgdt %0"::"m" (*dtr)); -} - -static void native_load_idt(const struct Xgt_desc_struct *dtr) -{ - asm volatile("lidt %0"::"m" (*dtr)); -} - -static void native_store_gdt(struct Xgt_desc_struct *dtr) -{ - asm ("sgdt %0":"=m" (*dtr)); -} - -static void native_store_idt(struct Xgt_desc_struct *dtr) -{ - asm ("sidt %0":"=m" (*dtr)); -} - -static unsigned long native_store_tr(void) -{ - unsigned long tr; - asm ("str %0":"=r" (tr)); - return tr; -} - -static void native_load_tls(struct thread_struct *t, unsigned int cpu) -{ -#define C(i) get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i] - C(0); C(1); C(2); -#undef C -} - -static inline void native_write_dt_entry(void *dt, int entry, u32 entry_low, u32 entry_high) -{ - u32 *lp = (u32 *)((char *)dt + entry*8); - lp[0] = entry_low; - lp[1] = entry_high; -} - -static void native_write_ldt_entry(void *dt, int entrynum, u32 low, u32 high) -{ - native_write_dt_entry(dt, entrynum, low, high); -} - -static void native_write_gdt_entry(void *dt, int entrynum, u32 low, u32 high) -{ - native_write_dt_entry(dt, entrynum, low, high); -} - -static void native_write_idt_entry(void *dt, int entrynum, u32 low, u32 high) -{ - native_write_dt_entry(dt, entrynum, low, high); -} - -static void native_load_esp0(struct tss_struct *tss, - struct thread_struct *thread) -{ - tss->esp0 = thread->esp0; - - /* This can only happen when SEP is enabled, no need to test "SEP"arately */ - if (unlikely(tss->ss1 != thread->sysenter_cs)) { - tss->ss1 = thread->sysenter_cs; - wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); - } -} - -static void native_io_delay(void) -{ - asm volatile("outb %al,$0x80"); -} - static void native_flush_tlb(void) { __native_flush_tlb(); @@ -517,8 +234,8 @@ struct paravirt_ops paravirt_ops = { .safe_halt = native_safe_halt, .halt = native_halt, .wbinvd = native_wbinvd, - .read_msr = native_read_msr, - .write_msr = native_write_msr, + .read_msr = native_read_msr_safe, + .write_msr = native_write_msr_safe, .read_tsc = native_read_tsc, .read_pmc = native_read_pmc, .get_scheduled_cycles = native_read_tsc, @@ -531,9 +248,9 @@ struct paravirt_ops paravirt_ops = { .store_idt = native_store_idt, .store_tr = native_store_tr, .load_tls = native_load_tls, - .write_ldt_entry = native_write_ldt_entry, - .write_gdt_entry = native_write_gdt_entry, - .write_idt_entry = native_write_idt_entry, + .write_ldt_entry = write_dt_entry, + .write_gdt_entry = write_dt_entry, + .write_idt_entry = write_dt_entry, .load_esp0 = native_load_esp0, .set_iopl_mask = native_set_iopl_mask, diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h index a75ae6b97860..13f701ea9a8f 100644 --- a/include/asm-i386/desc.h +++ b/include/asm-i386/desc.h @@ -57,45 +57,33 @@ static inline void pack_gate(__u32 *a, __u32 *b, #ifdef CONFIG_PARAVIRT #include #else -#define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8)) - -#define load_gdt(dtr) __asm__ __volatile("lgdt %0"::"m" (*dtr)) -#define load_idt(dtr) __asm__ __volatile("lidt %0"::"m" (*dtr)) +#define load_TR_desc() native_load_tr_desc() +#define load_gdt(dtr) native_load_gdt(dtr) +#define load_idt(dtr) native_load_idt(dtr) #define load_tr(tr) __asm__ __volatile("ltr %0"::"m" (tr)) #define load_ldt(ldt) __asm__ __volatile("lldt %0"::"m" (ldt)) -#define store_gdt(dtr) __asm__ ("sgdt %0":"=m" (*dtr)) -#define store_idt(dtr) __asm__ ("sidt %0":"=m" (*dtr)) -#define store_tr(tr) __asm__ ("str %0":"=m" (tr)) +#define store_gdt(dtr) native_store_gdt(dtr) +#define store_idt(dtr) native_store_idt(dtr) +#define store_tr(tr) (tr = native_store_tr()) #define store_ldt(ldt) __asm__ ("sldt %0":"=m" (ldt)) -#if TLS_SIZE != 24 -# error update this code. -#endif - -static inline void load_TLS(struct thread_struct *t, unsigned int cpu) -{ -#define C(i) get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i] - C(0); C(1); C(2); -#undef C -} +#define load_TLS(t, cpu) native_load_tls(t, cpu) +#define set_ldt native_set_ldt #define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) #define write_gdt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) #define write_idt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#endif -static inline void write_dt_entry(void *dt, int entry, __u32 entry_a, __u32 entry_b) +static inline void write_dt_entry(struct desc_struct *dt, + int entry, u32 entry_low, u32 entry_high) { - __u32 *lp = (__u32 *)((char *)dt + entry*8); - *lp = entry_a; - *(lp+1) = entry_b; + dt[entry].a = entry_low; + dt[entry].b = entry_high; } -#define set_ldt native_set_ldt -#endif /* CONFIG_PARAVIRT */ - -static inline fastcall void native_set_ldt(const void *addr, - unsigned int entries) +static inline void native_set_ldt(const void *addr, unsigned int entries) { if (likely(entries == 0)) __asm__ __volatile__("lldt %w0"::"q" (0)); @@ -111,6 +99,48 @@ static inline fastcall void native_set_ldt(const void *addr, } } + +static inline void native_load_tr_desc(void) +{ + asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8)); +} + +static inline void native_load_gdt(const struct Xgt_desc_struct *dtr) +{ + asm volatile("lgdt %0"::"m" (*dtr)); +} + +static inline void native_load_idt(const struct Xgt_desc_struct *dtr) +{ + asm volatile("lidt %0"::"m" (*dtr)); +} + +static inline void native_store_gdt(struct Xgt_desc_struct *dtr) +{ + asm ("sgdt %0":"=m" (*dtr)); +} + +static inline void native_store_idt(struct Xgt_desc_struct *dtr) +{ + asm ("sidt %0":"=m" (*dtr)); +} + +static inline unsigned long native_store_tr(void) +{ + unsigned long tr; + asm ("str %0":"=r" (tr)); + return tr; +} + +static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) +{ + unsigned int i; + struct desc_struct *gdt = get_cpu_gdt_table(cpu); + + for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) + gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; +} + static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg) { __u32 a, b; diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h index 59fe616933c4..e797586a5bfc 100644 --- a/include/asm-i386/io.h +++ b/include/asm-i386/io.h @@ -250,19 +250,22 @@ static inline void flush_write_buffers(void) #endif /* __KERNEL__ */ +static inline void native_io_delay(void) +{ + asm volatile("outb %%al,$0x80" : : : "memory"); +} + #if defined(CONFIG_PARAVIRT) #include #else -#define __SLOW_DOWN_IO "outb %%al,$0x80;" - static inline void slow_down_io(void) { - __asm__ __volatile__( - __SLOW_DOWN_IO + native_io_delay(); #ifdef REALLY_SLOW_IO - __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO + native_io_delay(); + native_io_delay(); + native_io_delay(); #endif - : : ); } #endif diff --git a/include/asm-i386/irqflags.h b/include/asm-i386/irqflags.h index 17b18cf4fe9d..c1cdd094938e 100644 --- a/include/asm-i386/irqflags.h +++ b/include/asm-i386/irqflags.h @@ -10,6 +10,42 @@ #ifndef _ASM_IRQFLAGS_H #define _ASM_IRQFLAGS_H +#ifndef __ASSEMBLY__ +static inline unsigned long native_save_fl(void) +{ + unsigned long f; + asm volatile("pushfl ; popl %0":"=g" (f): /* no input */); + return f; +} + +static inline void native_restore_fl(unsigned long f) +{ + asm volatile("pushl %0 ; popfl": /* no output */ + :"g" (f) + :"memory", "cc"); +} + +static inline void native_irq_disable(void) +{ + asm volatile("cli": : :"memory"); +} + +static inline void native_irq_enable(void) +{ + asm volatile("sti": : :"memory"); +} + +static inline void native_safe_halt(void) +{ + asm volatile("sti; hlt": : :"memory"); +} + +static inline void native_halt(void) +{ + asm volatile("hlt": : :"memory"); +} +#endif /* __ASSEMBLY__ */ + #ifdef CONFIG_PARAVIRT #include #else @@ -17,35 +53,22 @@ static inline unsigned long __raw_local_save_flags(void) { - unsigned long flags; - - __asm__ __volatile__( - "pushfl ; popl %0" - : "=g" (flags) - : /* no input */ - ); - - return flags; + return native_save_fl(); } static inline void raw_local_irq_restore(unsigned long flags) { - __asm__ __volatile__( - "pushl %0 ; popfl" - : /* no output */ - :"g" (flags) - :"memory", "cc" - ); + native_restore_fl(flags); } static inline void raw_local_irq_disable(void) { - __asm__ __volatile__("cli" : : : "memory"); + native_irq_disable(); } static inline void raw_local_irq_enable(void) { - __asm__ __volatile__("sti" : : : "memory"); + native_irq_enable(); } /* @@ -54,7 +77,7 @@ static inline void raw_local_irq_enable(void) */ static inline void raw_safe_halt(void) { - __asm__ __volatile__("sti; hlt" : : : "memory"); + native_safe_halt(); } /* @@ -63,7 +86,7 @@ static inline void raw_safe_halt(void) */ static inline void halt(void) { - __asm__ __volatile__("hlt": : :"memory"); + native_halt(); } /* diff --git a/include/asm-i386/msr.h b/include/asm-i386/msr.h index 2ad3f30b1a68..00acaa8b36bb 100644 --- a/include/asm-i386/msr.h +++ b/include/asm-i386/msr.h @@ -1,6 +1,74 @@ #ifndef __ASM_MSR_H #define __ASM_MSR_H +#include + +static inline unsigned long long native_read_msr(unsigned int msr) +{ + unsigned long long val; + + asm volatile("rdmsr" : "=A" (val) : "c" (msr)); + return val; +} + +static inline unsigned long long native_read_msr_safe(unsigned int msr, + int *err) +{ + unsigned long long val; + + asm volatile("2: rdmsr ; xorl %0,%0\n" + "1:\n\t" + ".section .fixup,\"ax\"\n\t" + "3: movl %3,%0 ; jmp 1b\n\t" + ".previous\n\t" + ".section __ex_table,\"a\"\n" + " .align 4\n\t" + " .long 2b,3b\n\t" + ".previous" + : "=r" (*err), "=A" (val) + : "c" (msr), "i" (-EFAULT)); + + return val; +} + +static inline void native_write_msr(unsigned int msr, unsigned long long val) +{ + asm volatile("wrmsr" : : "c" (msr), "A"(val)); +} + +static inline int native_write_msr_safe(unsigned int msr, + unsigned long long val) +{ + int err; + asm volatile("2: wrmsr ; xorl %0,%0\n" + "1:\n\t" + ".section .fixup,\"ax\"\n\t" + "3: movl %4,%0 ; jmp 1b\n\t" + ".previous\n\t" + ".section __ex_table,\"a\"\n" + " .align 4\n\t" + " .long 2b,3b\n\t" + ".previous" + : "=a" (err) + : "c" (msr), "0" ((u32)val), "d" ((u32)(val>>32)), + "i" (-EFAULT)); + return err; +} + +static inline unsigned long long native_read_tsc(void) +{ + unsigned long long val; + asm volatile("rdtsc" : "=A" (val)); + return val; +} + +static inline unsigned long long native_read_pmc(void) +{ + unsigned long long val; + asm volatile("rdpmc" : "=A" (val)); + return val; +} + #ifdef CONFIG_PARAVIRT #include #else @@ -11,22 +79,20 @@ * pointer indirection), this allows gcc to optimize better */ -#define rdmsr(msr,val1,val2) \ - __asm__ __volatile__("rdmsr" \ - : "=a" (val1), "=d" (val2) \ - : "c" (msr)) +#define rdmsr(msr,val1,val2) \ + do { \ + unsigned long long __val = native_read_msr(msr); \ + val1 = __val; \ + val2 = __val >> 32; \ + } while(0) -#define wrmsr(msr,val1,val2) \ - __asm__ __volatile__("wrmsr" \ - : /* no outputs */ \ - : "c" (msr), "a" (val1), "d" (val2)) +#define wrmsr(msr,val1,val2) \ + native_write_msr(msr, ((unsigned long long)val2 << 32) | val1) -#define rdmsrl(msr,val) do { \ - unsigned long l__,h__; \ - rdmsr (msr, l__, h__); \ - val = l__; \ - val |= ((u64)h__<<32); \ -} while(0) +#define rdmsrl(msr,val) \ + do { \ + (val) = native_read_msr(msr); \ + } while(0) static inline void wrmsrl (unsigned long msr, unsigned long long val) { @@ -37,50 +103,41 @@ static inline void wrmsrl (unsigned long msr, unsigned long long val) } /* wrmsr with exception handling */ -#define wrmsr_safe(msr,a,b) ({ int ret__; \ - asm volatile("2: wrmsr ; xorl %0,%0\n" \ - "1:\n\t" \ - ".section .fixup,\"ax\"\n\t" \ - "3: movl %4,%0 ; jmp 1b\n\t" \ - ".previous\n\t" \ - ".section __ex_table,\"a\"\n" \ - " .align 4\n\t" \ - " .long 2b,3b\n\t" \ - ".previous" \ - : "=a" (ret__) \ - : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT));\ - ret__; }) +#define wrmsr_safe(msr,val1,val2) \ + (native_write_msr_safe(msr, ((unsigned long long)val2 << 32) | val1)) /* rdmsr with exception handling */ -#define rdmsr_safe(msr,a,b) ({ int ret__; \ - asm volatile("2: rdmsr ; xorl %0,%0\n" \ - "1:\n\t" \ - ".section .fixup,\"ax\"\n\t" \ - "3: movl %4,%0 ; jmp 1b\n\t" \ - ".previous\n\t" \ - ".section __ex_table,\"a\"\n" \ - " .align 4\n\t" \ - " .long 2b,3b\n\t" \ - ".previous" \ - : "=r" (ret__), "=a" (*(a)), "=d" (*(b)) \ - : "c" (msr), "i" (-EFAULT));\ - ret__; }) - -#define rdtsc(low,high) \ - __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) - -#define rdtscl(low) \ - __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx") - -#define rdtscll(val) \ - __asm__ __volatile__("rdtsc" : "=A" (val)) +#define rdmsr_safe(msr,p1,p2) \ + ({ \ + int __err; \ + unsigned long long __val = native_read_msr_safe(msr, &__err);\ + (*p1) = __val; \ + (*p2) = __val >> 32; \ + __err; \ + }) + +#define rdtsc(low,high) \ + do { \ + u64 _l = native_read_tsc(); \ + (low) = (u32)_l; \ + (high) = _l >> 32; \ + } while(0) + +#define rdtscl(low) \ + do { \ + (low) = native_read_tsc(); \ + } while(0) + +#define rdtscll(val) ((val) = native_read_tsc()) #define write_tsc(val1,val2) wrmsr(0x10, val1, val2) -#define rdpmc(counter,low,high) \ - __asm__ __volatile__("rdpmc" \ - : "=a" (low), "=d" (high) \ - : "c" (counter)) +#define rdpmc(counter,low,high) \ + do { \ + u64 _l = native_read_pmc(); \ + low = (u32)_l; \ + high = _l >> 32; \ + } while(0) #endif /* !CONFIG_PARAVIRT */ #ifdef CONFIG_SMP diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index e63f1e444fcf..32acebce9ae2 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -29,6 +29,7 @@ struct thread_struct; struct Xgt_desc_struct; struct tss_struct; struct mm_struct; +struct desc_struct; struct paravirt_ops { unsigned int kernel_rpl; @@ -105,14 +106,13 @@ struct paravirt_ops void (*set_ldt)(const void *desc, unsigned entries); unsigned long (*store_tr)(void); void (*load_tls)(struct thread_struct *t, unsigned int cpu); - void (*write_ldt_entry)(void *dt, int entrynum, - u32 low, u32 high); - void (*write_gdt_entry)(void *dt, int entrynum, - u32 low, u32 high); - void (*write_idt_entry)(void *dt, int entrynum, - u32 low, u32 high); - void (*load_esp0)(struct tss_struct *tss, - struct thread_struct *thread); + void (*write_ldt_entry)(struct desc_struct *, + int entrynum, u32 low, u32 high); + void (*write_gdt_entry)(struct desc_struct *, + int entrynum, u32 low, u32 high); + void (*write_idt_entry)(struct desc_struct *, + int entrynum, u32 low, u32 high); + void (*load_esp0)(struct tss_struct *tss, struct thread_struct *t); void (*set_iopl_mask)(unsigned mask); @@ -232,6 +232,7 @@ static inline void halt(void) #define get_kernel_rpl() (paravirt_ops.kernel_rpl) +/* These should all do BUG_ON(_err), but our headers are too tangled. */ #define rdmsr(msr,val1,val2) do { \ int _err; \ u64 _l = paravirt_ops.read_msr(msr,&_err); \ diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 80f7e8a1e878..96edfdfe32d1 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -147,7 +147,7 @@ static inline void detect_ht(struct cpuinfo_x86 *c) {} #define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */ #define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */ -static inline fastcall void native_cpuid(unsigned int *eax, unsigned int *ebx, +static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { /* ecx is often an input as well as an output. */ @@ -545,13 +545,7 @@ static inline void rep_nop(void) #define cpu_relax() rep_nop() -#ifdef CONFIG_PARAVIRT -#include -#else -#define paravirt_enabled() 0 -#define __cpuid native_cpuid - -static inline void load_esp0(struct tss_struct *tss, struct thread_struct *thread) +static inline void native_load_esp0(struct tss_struct *tss, struct thread_struct *thread) { tss->esp0 = thread->esp0; /* This can only happen when SEP is enabled, no need to test "SEP"arately */ @@ -561,24 +555,60 @@ static inline void load_esp0(struct tss_struct *tss, struct thread_struct *threa } } -/* - * These special macros can be used to get or set a debugging register - */ -#define get_debugreg(var, register) \ - __asm__("movl %%db" #register ", %0" \ - :"=r" (var)) -#define set_debugreg(value, register) \ - __asm__("movl %0,%%db" #register \ - : /* no output */ \ - :"r" (value)) -#define set_iopl_mask native_set_iopl_mask -#endif /* CONFIG_PARAVIRT */ +static inline unsigned long native_get_debugreg(int regno) +{ + unsigned long val = 0; /* Damn you, gcc! */ + + switch (regno) { + case 0: + asm("movl %%db0, %0" :"=r" (val)); break; + case 1: + asm("movl %%db1, %0" :"=r" (val)); break; + case 2: + asm("movl %%db2, %0" :"=r" (val)); break; + case 3: + asm("movl %%db3, %0" :"=r" (val)); break; + case 6: + asm("movl %%db6, %0" :"=r" (val)); break; + case 7: + asm("movl %%db7, %0" :"=r" (val)); break; + default: + BUG(); + } + return val; +} + +static inline void native_set_debugreg(int regno, unsigned long value) +{ + switch (regno) { + case 0: + asm("movl %0,%%db0" : /* no output */ :"r" (value)); + break; + case 1: + asm("movl %0,%%db1" : /* no output */ :"r" (value)); + break; + case 2: + asm("movl %0,%%db2" : /* no output */ :"r" (value)); + break; + case 3: + asm("movl %0,%%db3" : /* no output */ :"r" (value)); + break; + case 6: + asm("movl %0,%%db6" : /* no output */ :"r" (value)); + break; + case 7: + asm("movl %0,%%db7" : /* no output */ :"r" (value)); + break; + default: + BUG(); + } +} /* * Set IOPL bits in EFLAGS from given mask */ -static fastcall inline void native_set_iopl_mask(unsigned mask) +static inline void native_set_iopl_mask(unsigned mask) { unsigned int reg; __asm__ __volatile__ ("pushfl;" @@ -591,6 +621,28 @@ static fastcall inline void native_set_iopl_mask(unsigned mask) : "i" (~X86_EFLAGS_IOPL), "r" (mask)); } +#ifdef CONFIG_PARAVIRT +#include +#else +#define paravirt_enabled() 0 +#define __cpuid native_cpuid + +static inline void load_esp0(struct tss_struct *tss, struct thread_struct *thread) +{ + native_load_esp0(tss, thread); +} + +/* + * These special macros can be used to get or set a debugging register + */ +#define get_debugreg(var, register) \ + (var) = native_get_debugreg(register) +#define set_debugreg(value, register) \ + native_set_debugreg(register, value) + +#define set_iopl_mask native_set_iopl_mask +#endif /* CONFIG_PARAVIRT */ + /* * Generic CPUID function * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h index a6d20d9a1a30..c3a58c08c495 100644 --- a/include/asm-i386/system.h +++ b/include/asm-i386/system.h @@ -88,65 +88,96 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t" \ #define savesegment(seg, value) \ asm volatile("mov %%" #seg ",%0":"=rm" (value)) + +static inline void native_clts(void) +{ + asm volatile ("clts"); +} + +static inline unsigned long native_read_cr0(void) +{ + unsigned long val; + asm volatile("movl %%cr0,%0\n\t" :"=r" (val)); + return val; +} + +static inline void native_write_cr0(unsigned long val) +{ + asm volatile("movl %0,%%cr0": :"r" (val)); +} + +static inline unsigned long native_read_cr2(void) +{ + unsigned long val; + asm volatile("movl %%cr2,%0\n\t" :"=r" (val)); + return val; +} + +static inline void native_write_cr2(unsigned long val) +{ + asm volatile("movl %0,%%cr2": :"r" (val)); +} + +static inline unsigned long native_read_cr3(void) +{ + unsigned long val; + asm volatile("movl %%cr3,%0\n\t" :"=r" (val)); + return val; +} + +static inline void native_write_cr3(unsigned long val) +{ + asm volatile("movl %0,%%cr3": :"r" (val)); +} + +static inline unsigned long native_read_cr4(void) +{ + unsigned long val; + asm volatile("movl %%cr4,%0\n\t" :"=r" (val)); + return val; +} + +static inline unsigned long native_read_cr4_safe(void) +{ + unsigned long val; + /* This could fault if %cr4 does not exist */ + asm("1: movl %%cr4, %0 \n" + "2: \n" + ".section __ex_table,\"a\" \n" + ".long 1b,2b \n" + ".previous \n" + : "=r" (val): "0" (0)); + return val; +} + +static inline void native_write_cr4(unsigned long val) +{ + asm volatile("movl %0,%%cr4": :"r" (val)); +} + +static inline void native_wbinvd(void) +{ + asm volatile("wbinvd": : :"memory"); +} + + #ifdef CONFIG_PARAVIRT #include #else -#define read_cr0() ({ \ - unsigned int __dummy; \ - __asm__ __volatile__( \ - "movl %%cr0,%0\n\t" \ - :"=r" (__dummy)); \ - __dummy; \ -}) -#define write_cr0(x) \ - __asm__ __volatile__("movl %0,%%cr0": :"r" (x)) - -#define read_cr2() ({ \ - unsigned int __dummy; \ - __asm__ __volatile__( \ - "movl %%cr2,%0\n\t" \ - :"=r" (__dummy)); \ - __dummy; \ -}) -#define write_cr2(x) \ - __asm__ __volatile__("movl %0,%%cr2": :"r" (x)) - -#define read_cr3() ({ \ - unsigned int __dummy; \ - __asm__ ( \ - "movl %%cr3,%0\n\t" \ - :"=r" (__dummy)); \ - __dummy; \ -}) -#define write_cr3(x) \ - __asm__ __volatile__("movl %0,%%cr3": :"r" (x)) - -#define read_cr4() ({ \ - unsigned int __dummy; \ - __asm__( \ - "movl %%cr4,%0\n\t" \ - :"=r" (__dummy)); \ - __dummy; \ -}) -#define read_cr4_safe() ({ \ - unsigned int __dummy; \ - /* This could fault if %cr4 does not exist */ \ - __asm__("1: movl %%cr4, %0 \n" \ - "2: \n" \ - ".section __ex_table,\"a\" \n" \ - ".long 1b,2b \n" \ - ".previous \n" \ - : "=r" (__dummy): "0" (0)); \ - __dummy; \ -}) -#define write_cr4(x) \ - __asm__ __volatile__("movl %0,%%cr4": :"r" (x)) - -#define wbinvd() \ - __asm__ __volatile__ ("wbinvd": : :"memory") +#define read_cr0() (native_read_cr0()) +#define write_cr0(x) (native_write_cr0(x)) +#define read_cr2() (native_read_cr2()) +#define write_cr2(x) (native_write_cr2(x)) +#define read_cr3() (native_read_cr3()) +#define write_cr3(x) (native_write_cr3(x)) +#define read_cr4() (native_read_cr4()) +#define read_cr4_safe() (native_read_cr4_safe()) +#define write_cr4(x) (native_write_cr4(x)) +#define wbinvd() (native_wbinvd()) /* Clear the 'TS' bit */ -#define clts() __asm__ __volatile__ ("clts") +#define clts() (native_clts()) + #endif/* CONFIG_PARAVIRT */ /* Set the 'TS' bit */ -- cgit v1.2.3-59-g8ed1b From d01ad8dd56527be72947b4b9997bb2c05783c3ed Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 2 May 2007 19:27:10 +0200 Subject: [PATCH] x86: Improve handling of kernel mappings in change_page_attr Fix various broken corner cases in i386 and x86-64 change_page_attr. AK: split off from tighten kernel image access rights Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/i386/mm/pageattr.c | 4 ++-- arch/x86_64/mm/pageattr.c | 16 ++++++++++++---- include/asm-i386/pgtable.h | 2 ++ 3 files changed, 16 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c index 412ebbd8adb0..ea6b6d4a0a2a 100644 --- a/arch/i386/mm/pageattr.c +++ b/arch/i386/mm/pageattr.c @@ -142,7 +142,7 @@ __change_page_attr(struct page *page, pgprot_t prot) return -EINVAL; kpte_page = virt_to_page(kpte); if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) { - if ((pte_val(*kpte) & _PAGE_PSE) == 0) { + if (!pte_huge(*kpte)) { set_pte_atomic(kpte, mk_pte(page, prot)); } else { pgprot_t ref_prot; @@ -158,7 +158,7 @@ __change_page_attr(struct page *page, pgprot_t prot) kpte_page = split; } page_private(kpte_page)++; - } else if ((pte_val(*kpte) & _PAGE_PSE) == 0) { + } else if (!pte_huge(*kpte)) { set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL)); BUG_ON(page_private(kpte_page) == 0); page_private(kpte_page)--; diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c index 76ee90a5abe0..bf4aa8dd4254 100644 --- a/arch/x86_64/mm/pageattr.c +++ b/arch/x86_64/mm/pageattr.c @@ -179,16 +179,24 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot, int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot) { unsigned long phys_base_pfn = __pa_symbol(__START_KERNEL_map) >> PAGE_SHIFT; - int err = 0; + int err = 0, kernel_map = 0; int i; + if (address >= __START_KERNEL_map + && address < __START_KERNEL_map + KERNEL_TEXT_SIZE) { + address = (unsigned long)__va(__pa(address)); + kernel_map = 1; + } + down_write(&init_mm.mmap_sem); for (i = 0; i < numpages; i++, address += PAGE_SIZE) { unsigned long pfn = __pa(address) >> PAGE_SHIFT; - err = __change_page_attr(address, pfn, prot, PAGE_KERNEL); - if (err) - break; + if (!kernel_map || pte_present(pfn_pte(0, prot))) { + err = __change_page_attr(address, pfn, prot, PAGE_KERNEL); + if (err) + break; + } /* Handle kernel mapping too which aliases part of the * lowmem */ if ((pfn >= phys_base_pfn) && diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index c3b58d473a55..143ddc42b86f 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -159,6 +159,7 @@ void paging_init(void); extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; #define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW) +#define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW) #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD) #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) @@ -166,6 +167,7 @@ extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; #define PAGE_KERNEL __pgprot(__PAGE_KERNEL) #define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) #define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) +#define PAGE_KERNEL_RX __pgprot(__PAGE_KERNEL_RX) #define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE) #define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE) #define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC) -- cgit v1.2.3-59-g8ed1b From 6fb14755a676282a4e6caa05a08c92db8e45cfff Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 2 May 2007 19:27:10 +0200 Subject: [PATCH] x86: tighten kernel image page access rights On x86-64, kernel memory freed after init can be entirely unmapped instead of just getting 'poisoned' by overwriting with a debug pattern. On i386 and x86-64 (under CONFIG_DEBUG_RODATA), kernel text and bug table can also be write-protected. Compared to the first version, this one prevents re-creating deleted mappings in the kernel image range on x86-64, if those got removed previously. This, together with the original changes, prevents temporarily having inconsistent mappings when cacheability attributes are being changed on such pages (e.g. from AGP code). While on i386 such duplicate mappings don't exist, the same change is done there, too, both for consistency and because checking pte_present() before using various other pte_XXX functions is a requirement anyway. At once, i386 code gets adjusted to use pte_huge() instead of open coding this. AK: split out cpa() changes Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/i386/kernel/vmlinux.lds.S | 4 ++-- arch/i386/mm/init.c | 25 +++++++++++++++++++------ arch/x86_64/kernel/head.S | 1 - arch/x86_64/kernel/vmlinux.lds.S | 5 +++-- arch/x86_64/mm/init.c | 25 ++++++++++++++++--------- include/linux/poison.h | 3 --- 6 files changed, 40 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 6f38f818380b..f4ec72231835 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -61,8 +61,6 @@ SECTIONS __stop___ex_table = .; } - RODATA - BUG_TABLE . = ALIGN(4); @@ -72,6 +70,8 @@ SECTIONS __tracedata_end = .; } + RODATA + /* writeable */ . = ALIGN(4096); .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 23be1b0aafa4..bd5ef3718504 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -751,13 +752,25 @@ static int noinline do_test_wp_bit(void) void mark_rodata_ro(void) { - unsigned long addr = (unsigned long)__start_rodata; + unsigned long start = PFN_ALIGN(_text); + unsigned long size = PFN_ALIGN(_etext) - start; - for (; addr < (unsigned long)__end_rodata; addr += PAGE_SIZE) - change_page_attr(virt_to_page(addr), 1, PAGE_KERNEL_RO); +#ifdef CONFIG_HOTPLUG_CPU + /* It must still be possible to apply SMP alternatives. */ + if (num_possible_cpus() <= 1) +#endif + { + change_page_attr(virt_to_page(start), + size >> PAGE_SHIFT, PAGE_KERNEL_RX); + printk("Write protecting the kernel text: %luk\n", size >> 10); + } - printk("Write protecting the kernel read-only data: %uk\n", - (__end_rodata - __start_rodata) >> 10); + start += size; + size = (unsigned long)__end_rodata - start; + change_page_attr(virt_to_page(start), + size >> PAGE_SHIFT, PAGE_KERNEL_RO); + printk("Write protecting the kernel read-only data: %luk\n", + size >> 10); /* * change_page_attr() requires a global_flush_tlb() call after it. @@ -781,7 +794,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) __free_page(page); totalram_pages++; } - printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); + printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10); } void free_initmem(void) diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 36aa98a6d15c..fd9fdfdd143e 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S @@ -280,7 +280,6 @@ early_idt_ripmsg: .balign PAGE_SIZE ENTRY(stext) -ENTRY(_stext) #define NEXT_PAGE(name) \ .balign PAGE_SIZE; \ diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 5176ecf006ee..3bdeb88d28f4 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -29,6 +29,7 @@ SECTIONS .text : AT(ADDR(.text) - LOAD_OFFSET) { /* First the code that has to be first for bootstrapping */ *(.bootstrap.text) + _stext = .; /* Then all the functions that are "hot" in profiles, to group them onto the same hugetlb entry */ #include "functionlist" @@ -50,10 +51,10 @@ SECTIONS __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) } __stop___ex_table = .; - RODATA - BUG_TABLE + RODATA + . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */ /* Data */ .data : AT(ADDR(.data) - LOAD_OFFSET) { diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 69e22d3c9238..e3134bc9a4fc 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -563,21 +564,23 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) if (begin >= end) return; - printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); + printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10); for (addr = begin; addr < end; addr += PAGE_SIZE) { struct page *page = pfn_to_page(addr >> PAGE_SHIFT); ClearPageReserved(page); init_page_count(page); memset(page_address(page), POISON_FREE_INITMEM, PAGE_SIZE); + if (addr >= __START_KERNEL_map) + change_page_attr_addr(addr, 1, __pgprot(0)); __free_page(page); totalram_pages++; } + if (addr > __START_KERNEL_map) + global_flush_tlb(); } void free_initmem(void) { - memset(__initdata_begin, POISON_FREE_INITDATA, - __initdata_end - __initdata_begin); free_init_pages("unused kernel memory", __pa_symbol(&__init_begin), __pa_symbol(&__init_end)); @@ -587,14 +590,18 @@ void free_initmem(void) void mark_rodata_ro(void) { - unsigned long addr = (unsigned long)__va(__pa_symbol(&__start_rodata)); - unsigned long end = (unsigned long)__va(__pa_symbol(&__end_rodata)); + unsigned long start = PFN_ALIGN(__va(__pa_symbol(&_stext))), size; - for (; addr < end; addr += PAGE_SIZE) - change_page_attr_addr(addr, 1, PAGE_KERNEL_RO); +#ifdef CONFIG_HOTPLUG_CPU + /* It must still be possible to apply SMP alternatives. */ + if (num_possible_cpus() > 1) + start = PFN_ALIGN(__va(__pa_symbol(&_etext))); +#endif + size = (unsigned long)__va(__pa_symbol(&__end_rodata)) - start; + change_page_attr_addr(start, size >> PAGE_SHIFT, PAGE_KERNEL_RO); - printk ("Write protecting the kernel read-only data: %luk\n", - (__end_rodata - __start_rodata) >> 10); + printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", + size >> 10); /* * change_page_attr_addr() requires a global_flush_tlb() call after it. diff --git a/include/linux/poison.h b/include/linux/poison.h index 3e628f990fdf..89580b764959 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h @@ -26,9 +26,6 @@ /********** arch/$ARCH/mm/init.c **********/ #define POISON_FREE_INITMEM 0xcc -/********** arch/x86_64/mm/init.c **********/ -#define POISON_FREE_INITDATA 0xba - /********** arch/ia64/hp/common/sba_iommu.c **********/ /* * arch/ia64/hp/common/sba_iommu.c uses a 16-byte poison string with a -- cgit v1.2.3-59-g8ed1b From 78eea47ac3e256559d97f0c2434928be39cba524 Mon Sep 17 00:00:00 2001 From: Parag Warudkar Date: Wed, 2 May 2007 19:27:10 +0200 Subject: [PATCH] i386: get rid of unused variables Signed-off-by: Parag Warudkar Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/kernel/apm.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 064bbf2861f4..4d073d390715 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -384,13 +384,6 @@ static int ignore_sys_suspend; static int ignore_normal_resume; static int bounce_interval __read_mostly = DEFAULT_BOUNCE_INTERVAL; -#ifdef CONFIG_APM_RTC_IS_GMT -# define clock_cmos_diff 0 -# define got_clock_diff 1 -#else -static long clock_cmos_diff; -static int got_clock_diff; -#endif static int debug __read_mostly; static int smp __read_mostly; static int apm_disabled = -1; -- cgit v1.2.3-59-g8ed1b From b8716890f35dd567a3f8e4dd69c428a8b3f47814 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:10 +0200 Subject: [PATCH] x86-64: Remove unused stext symbol suggested by Jan Beulich Signed-off-by: Andi Kleen --- arch/x86_64/kernel/head.S | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index fd9fdfdd143e..1fab487dee86 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S @@ -279,7 +279,6 @@ early_idt_ripmsg: .asciz "RIP %s\n" .balign PAGE_SIZE -ENTRY(stext) #define NEXT_PAGE(name) \ .balign PAGE_SIZE; \ -- cgit v1.2.3-59-g8ed1b From 05f36927eddd83e2840a981ef4d9af754dcb86e9 Mon Sep 17 00:00:00 2001 From: Parag Warudkar Date: Wed, 2 May 2007 19:27:10 +0200 Subject: [PATCH] i386: remove the APM_RTC_IS_GMT config option. Signed-off-by: Parag Warudkar Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/Kconfig | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'arch') diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 53d62373a524..c0a3e233fa3f 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -1029,19 +1029,6 @@ config APM_DISPLAY_BLANK backlight at all, or it might print a lot of errors to the console, especially if you are using gpm. -config APM_RTC_IS_GMT - bool "RTC stores time in GMT" - depends on APM - help - Say Y here if your RTC (Real Time Clock a.k.a. hardware clock) - stores the time in GMT (Greenwich Mean Time). Say N if your RTC - stores localtime. - - It is in fact recommended to store GMT in your RTC, because then you - don't have to worry about daylight savings time changes. The only - reason not to use GMT in your RTC is if you also run a broken OS - that doesn't understand GMT. - config APM_ALLOW_INTS bool "Allow interrupts during APM BIOS calls" depends on APM -- cgit v1.2.3-59-g8ed1b From 2bff73830c3df5f575d3bc21bf19df1a10bf7091 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 2 May 2007 19:27:10 +0200 Subject: [PATCH] x86-64: use lru instead of page->index and page->private for pgd lists management. x86_64 currently simulates a list using the index and private fields of the page struct. Seems that the code was inherited from i386. But x86_64 does not use the slab to allocate pgds and pmds etc. So the lru field is not used by the slab and therefore available. This patch uses standard list operations on page->lru to realize pgd tracking. Signed-off-by: Christoph Lameter Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/x86_64/mm/fault.c | 5 ++--- include/asm-x86_64/pgalloc.h | 14 +++----------- include/asm-x86_64/pgtable.h | 2 +- 3 files changed, 6 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index 6ada7231f3ab..de99dba2c515 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c @@ -585,7 +585,7 @@ do_sigbus: } DEFINE_SPINLOCK(pgd_lock); -struct page *pgd_list; +LIST_HEAD(pgd_list); void vmalloc_sync_all(void) { @@ -605,8 +605,7 @@ void vmalloc_sync_all(void) if (pgd_none(*pgd_ref)) continue; spin_lock(&pgd_lock); - for (page = pgd_list; page; - page = (struct page *)page->index) { + list_for_each_entry(page, &pgd_list, lru) { pgd_t *pgd; pgd = (pgd_t *)page_address(page) + pgd_index(address); if (pgd_none(*pgd)) diff --git a/include/asm-x86_64/pgalloc.h b/include/asm-x86_64/pgalloc.h index 31d497171969..8bb564687860 100644 --- a/include/asm-x86_64/pgalloc.h +++ b/include/asm-x86_64/pgalloc.h @@ -44,24 +44,16 @@ static inline void pgd_list_add(pgd_t *pgd) struct page *page = virt_to_page(pgd); spin_lock(&pgd_lock); - page->index = (pgoff_t)pgd_list; - if (pgd_list) - pgd_list->private = (unsigned long)&page->index; - pgd_list = page; - page->private = (unsigned long)&pgd_list; + list_add(&page->lru, &pgd_list); spin_unlock(&pgd_lock); } static inline void pgd_list_del(pgd_t *pgd) { - struct page *next, **pprev, *page = virt_to_page(pgd); + struct page *page = virt_to_page(pgd); spin_lock(&pgd_lock); - next = (struct page *)page->index; - pprev = (struct page **)page->private; - *pprev = next; - if (next) - next->private = (unsigned long)pprev; + list_del(&page->lru); spin_unlock(&pgd_lock); } diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h index c1865e38c7b7..599993f6ba84 100644 --- a/include/asm-x86_64/pgtable.h +++ b/include/asm-x86_64/pgtable.h @@ -410,7 +410,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) extern spinlock_t pgd_lock; -extern struct page *pgd_list; +extern struct list_head pgd_list; void vmalloc_sync_all(void); extern int kern_addr_valid(unsigned long addr); -- cgit v1.2.3-59-g8ed1b From ca906e42312781c38b7a9625109fc65b937ca56c Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 2 May 2007 19:27:10 +0200 Subject: [PATCH] x86: sys_ioperm() prototype cleanup - there's no reason for duplicating the prototype from include/linux/syscalls.h in include/asm-x86_64/unistd.h - every file should #include the headers containing the prototypes for it's global functions Signed-off-by: Adrian Bunk Signed-off-by: Andi Kleen --- arch/i386/kernel/ioport.c | 1 + arch/x86_64/kernel/ioport.c | 1 + include/asm-x86_64/unistd.h | 1 - 3 files changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/ioport.c b/arch/i386/kernel/ioport.c index 498e8bc197d5..1b4530e6cd82 100644 --- a/arch/i386/kernel/ioport.c +++ b/arch/i386/kernel/ioport.c @@ -16,6 +16,7 @@ #include #include #include +#include /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value) diff --git a/arch/x86_64/kernel/ioport.c b/arch/x86_64/kernel/ioport.c index 745b1f0f494e..387d347b0e07 100644 --- a/arch/x86_64/kernel/ioport.c +++ b/arch/x86_64/kernel/ioport.c @@ -16,6 +16,7 @@ #include #include #include +#include /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value) diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h index c5f596e71faa..576b29732d3c 100644 --- a/include/asm-x86_64/unistd.h +++ b/include/asm-x86_64/unistd.h @@ -655,7 +655,6 @@ __SYSCALL(__NR_move_pages, sys_move_pages) #include asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs); -asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on); struct sigaction; asmlinkage long sys_rt_sigaction(int sig, const struct sigaction __user *act, -- cgit v1.2.3-59-g8ed1b From bd8559c38ee5be40ce2c57a80fd3c3e978cca267 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 2 May 2007 19:27:11 +0200 Subject: [PATCH] x86: remove UNEXPECTED_IO_APIC() Many years ago, UNEXPECTED_IO_APIC() contained printk()'s (but nothing more). Now that it's completely empty for years, we can as well remove it. Signed-off-by: Adrian Bunk Signed-off-by: Andi Kleen --- arch/i386/kernel/io_apic.c | 30 ------------------------------ arch/x86_64/kernel/io_apic.c | 28 ---------------------------- 2 files changed, 58 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index b3ab8ffebd27..8191583032d0 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -1403,10 +1403,6 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in enable_8259A_irq(0); } -static inline void UNEXPECTED_IO_APIC(void) -{ -} - void __init print_IO_APIC(void) { int apic, i; @@ -1446,34 +1442,12 @@ void __init print_IO_APIC(void) printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type); printk(KERN_DEBUG "....... : LTS : %X\n", reg_00.bits.LTS); - if (reg_00.bits.ID >= get_physical_broadcast()) - UNEXPECTED_IO_APIC(); - if (reg_00.bits.__reserved_1 || reg_00.bits.__reserved_2) - UNEXPECTED_IO_APIC(); printk(KERN_DEBUG ".... register #01: %08X\n", reg_01.raw); printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.bits.entries); - if ( (reg_01.bits.entries != 0x0f) && /* older (Neptune) boards */ - (reg_01.bits.entries != 0x17) && /* typical ISA+PCI boards */ - (reg_01.bits.entries != 0x1b) && /* Compaq Proliant boards */ - (reg_01.bits.entries != 0x1f) && /* dual Xeon boards */ - (reg_01.bits.entries != 0x22) && /* bigger Xeon boards */ - (reg_01.bits.entries != 0x2E) && - (reg_01.bits.entries != 0x3F) - ) - UNEXPECTED_IO_APIC(); printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.bits.PRQ); printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.bits.version); - if ( (reg_01.bits.version != 0x01) && /* 82489DX IO-APICs */ - (reg_01.bits.version != 0x10) && /* oldest IO-APICs */ - (reg_01.bits.version != 0x11) && /* Pentium/Pro IO-APICs */ - (reg_01.bits.version != 0x13) && /* Xeon IO-APICs */ - (reg_01.bits.version != 0x20) /* Intel P64H (82806 AA) */ - ) - UNEXPECTED_IO_APIC(); - if (reg_01.bits.__reserved_1 || reg_01.bits.__reserved_2) - UNEXPECTED_IO_APIC(); /* * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02, @@ -1483,8 +1457,6 @@ void __init print_IO_APIC(void) if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) { printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw); printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.bits.arbitration); - if (reg_02.bits.__reserved_1 || reg_02.bits.__reserved_2) - UNEXPECTED_IO_APIC(); } /* @@ -1496,8 +1468,6 @@ void __init print_IO_APIC(void) reg_03.raw != reg_01.raw) { printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw); printk(KERN_DEBUG "....... : Boot DT : %X\n", reg_03.bits.boot_DT); - if (reg_03.bits.__reserved_1) - UNEXPECTED_IO_APIC(); } printk(KERN_DEBUG ".... IRQ redirection table:\n"); diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 318d9055cd97..dd14ffa565b1 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -907,10 +907,6 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in enable_8259A_irq(0); } -void __init UNEXPECTED_IO_APIC(void) -{ -} - void __apicdebuginit print_IO_APIC(void) { int apic, i; @@ -946,40 +942,16 @@ void __apicdebuginit print_IO_APIC(void) printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid); printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); - if (reg_00.bits.__reserved_1 || reg_00.bits.__reserved_2) - UNEXPECTED_IO_APIC(); printk(KERN_DEBUG ".... register #01: %08X\n", *(int *)®_01); printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.bits.entries); - if ( (reg_01.bits.entries != 0x0f) && /* older (Neptune) boards */ - (reg_01.bits.entries != 0x17) && /* typical ISA+PCI boards */ - (reg_01.bits.entries != 0x1b) && /* Compaq Proliant boards */ - (reg_01.bits.entries != 0x1f) && /* dual Xeon boards */ - (reg_01.bits.entries != 0x22) && /* bigger Xeon boards */ - (reg_01.bits.entries != 0x2E) && - (reg_01.bits.entries != 0x3F) && - (reg_01.bits.entries != 0x03) - ) - UNEXPECTED_IO_APIC(); printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.bits.PRQ); printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.bits.version); - if ( (reg_01.bits.version != 0x01) && /* 82489DX IO-APICs */ - (reg_01.bits.version != 0x02) && /* 82801BA IO-APICs (ICH2) */ - (reg_01.bits.version != 0x10) && /* oldest IO-APICs */ - (reg_01.bits.version != 0x11) && /* Pentium/Pro IO-APICs */ - (reg_01.bits.version != 0x13) && /* Xeon IO-APICs */ - (reg_01.bits.version != 0x20) /* Intel P64H (82806 AA) */ - ) - UNEXPECTED_IO_APIC(); - if (reg_01.bits.__reserved_1 || reg_01.bits.__reserved_2) - UNEXPECTED_IO_APIC(); if (reg_01.bits.version >= 0x10) { printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw); printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.bits.arbitration); - if (reg_02.bits.__reserved_1 || reg_02.bits.__reserved_2) - UNEXPECTED_IO_APIC(); } printk(KERN_DEBUG ".... IRQ redirection table:\n"); -- cgit v1.2.3-59-g8ed1b From 272a3713bb9e302e0455c894c41180a482d2c8a3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 2 May 2007 19:27:11 +0200 Subject: [PATCH] x86-64: fix vtime() vsyscall There is a tiny probability that the return value from vtime(time_t *t) is Signed-off-by: Andi Kleen different than the value stored in *t Using a temporary variable solves the problem and gives a faster code. 17: 48 85 ff test %rdi,%rdi 1a: 48 8b 05 00 00 00 00 mov 0(%rip),%rax # __vsyscall_gtod_data.wall_time_tv.tv_sec 21: 74 03 je 26 23: 48 89 07 mov %rax,(%rdi) 26: c9 leaveq 27: c3 retq Signed-off-by: Eric Dumazet --- arch/x86_64/kernel/vsyscall.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index d14cbb3e0ebe..ba330f870679 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c @@ -156,11 +156,13 @@ int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz) * unlikely */ time_t __vsyscall(1) vtime(time_t *t) { + time_t result; if (unlikely(!__vsyscall_gtod_data.sysctl_enabled)) return time_syscall(t); - else if (t) - *t = __vsyscall_gtod_data.wall_time_tv.tv_sec; - return __vsyscall_gtod_data.wall_time_tv.tv_sec; + result = __vsyscall_gtod_data.wall_time_tv.tv_sec; + if (t) + *t = result; + return result; } /* Fast way to get current CPU and node. -- cgit v1.2.3-59-g8ed1b From c8118c6c07f2edfd697aaa0b93e08c3b65a5a675 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 2 May 2007 19:27:11 +0200 Subject: [PATCH] x86-64: vsyscall_gtod_data diet and vgettimeofday() fix Current vsyscall_gtod_data is large (3 or 4 cache lines dirtied at timer interrupt). We can shrink it to exactly 64 bytes (1 cache line on AMD64) Instead of copying a whole struct clocksource, we copy only needed fields. I deleted an unused field : offset_base This patch fixes one oddity in vgettimeofday(): It can returns a timeval with tv_usec = 1000000. Maybe not a bug, but why not doing the right thing ? Signed-off-by: Eric Dumazet Signed-off-by: Andi Kleen --- arch/x86_64/kernel/vsyscall.c | 53 +++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index ba330f870679..dc32cef96195 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c @@ -51,13 +51,28 @@ asm("" : "=r" (v) : "0" (x)); \ ((v - VSYSCALL_FIRST_PAGE) + __pa_symbol(&__vsyscall_0)); }) +/* + * vsyscall_gtod_data contains data that is : + * - readonly from vsyscalls + * - writen by timer interrupt or systcl (/proc/sys/kernel/vsyscall64) + * Try to keep this structure as small as possible to avoid cache line ping pongs + */ struct vsyscall_gtod_data_t { - seqlock_t lock; - int sysctl_enabled; - struct timeval wall_time_tv; + seqlock_t lock; + + /* open coded 'struct timespec' */ + time_t wall_time_sec; + u32 wall_time_nsec; + + int sysctl_enabled; struct timezone sys_tz; - cycle_t offset_base; - struct clocksource clock; + struct { /* extract of a clocksource struct */ + cycle_t (*vread)(void); + cycle_t cycle_last; + cycle_t mask; + u32 mult; + u32 shift; + } clock; }; int __vgetcpu_mode __section_vgetcpu_mode; @@ -73,9 +88,13 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) write_seqlock_irqsave(&vsyscall_gtod_data.lock, flags); /* copy vsyscall data */ - vsyscall_gtod_data.clock = *clock; - vsyscall_gtod_data.wall_time_tv.tv_sec = wall_time->tv_sec; - vsyscall_gtod_data.wall_time_tv.tv_usec = wall_time->tv_nsec/1000; + vsyscall_gtod_data.clock.vread = clock->vread; + vsyscall_gtod_data.clock.cycle_last = clock->cycle_last; + vsyscall_gtod_data.clock.mask = clock->mask; + vsyscall_gtod_data.clock.mult = clock->mult; + vsyscall_gtod_data.clock.shift = clock->shift; + vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec; + vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec; vsyscall_gtod_data.sys_tz = sys_tz; write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); } @@ -110,7 +129,8 @@ static __always_inline long time_syscall(long *t) static __always_inline void do_vgettimeofday(struct timeval * tv) { cycle_t now, base, mask, cycle_delta; - unsigned long seq, mult, shift, nsec_delta; + unsigned seq; + unsigned long mult, shift, nsec; cycle_t (*vread)(void); do { seq = read_seqbegin(&__vsyscall_gtod_data.lock); @@ -126,21 +146,20 @@ static __always_inline void do_vgettimeofday(struct timeval * tv) mult = __vsyscall_gtod_data.clock.mult; shift = __vsyscall_gtod_data.clock.shift; - *tv = __vsyscall_gtod_data.wall_time_tv; - + tv->tv_sec = __vsyscall_gtod_data.wall_time_sec; + nsec = __vsyscall_gtod_data.wall_time_nsec; } while (read_seqretry(&__vsyscall_gtod_data.lock, seq)); /* calculate interval: */ cycle_delta = (now - base) & mask; /* convert to nsecs: */ - nsec_delta = (cycle_delta * mult) >> shift; + nsec += (cycle_delta * mult) >> shift; - /* convert to usecs and add to timespec: */ - tv->tv_usec += nsec_delta / NSEC_PER_USEC; - while (tv->tv_usec > USEC_PER_SEC) { + while (nsec >= NSEC_PER_SEC) { tv->tv_sec += 1; - tv->tv_usec -= USEC_PER_SEC; + nsec -= NSEC_PER_SEC; } + tv->tv_usec = nsec / NSEC_PER_USEC; } int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz) @@ -159,7 +178,7 @@ time_t __vsyscall(1) vtime(time_t *t) time_t result; if (unlikely(!__vsyscall_gtod_data.sysctl_enabled)) return time_syscall(t); - result = __vsyscall_gtod_data.wall_time_tv.tv_sec; + result = __vsyscall_gtod_data.wall_time_sec; if (t) *t = result; return result; -- cgit v1.2.3-59-g8ed1b From ae32b1297a77c23fd0badd642bb685062f7a37f8 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Date: Wed, 2 May 2007 19:27:11 +0200 Subject: [PATCH] x86-64: Inhibit machine from asserting an NMI when doing Alt-SysRq-M operation. This patch touches the NMI watchdog every MAX_ORDER_NR_PAGES to inhibit the machine from triggering an NMI while the CPUs are locked. This situation is happening on boxes with more than 64CPUs and 128GB of RAM when Alt-SysRq-m is performed. It has been succesfully tested for regression on uni, 2, 4, 8 32, and 64 CPU boxes with various memory configuration. Signed-off-by: Andi Kleen --- arch/x86_64/mm/init.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index e3134bc9a4fc..282b0a8f00ad 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -73,6 +74,11 @@ void show_mem(void) for_each_online_pgdat(pgdat) { for (i = 0; i < pgdat->node_spanned_pages; ++i) { + /* this loop can take a while with 256 GB and 4k pages + so update the NMI watchdog */ + if (unlikely(i % MAX_ORDER_NR_PAGES == 0)) { + touch_nmi_watchdog(); + } page = pfn_to_page(pgdat->node_start_pfn + i); total++; if (PageReserved(page)) -- cgit v1.2.3-59-g8ed1b From dd4ecfc2b10d962d70ff59f8994a29aa048700ec Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 2 May 2007 19:27:11 +0200 Subject: [PATCH] x86-64: adjust EDID retrieval commit 5e518d7672dea4cd7c60871e40d0490c52f01d13 did the same change to i386's variant. With this change, i386's and x86-64's versions are identical, raising the question whether the x86-64 one should go (just like there's only one instance of edd.S). Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/x86_64/boot/video.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/boot/video.S b/arch/x86_64/boot/video.S index 6090516c9c7f..8143c9516cb4 100644 --- a/arch/x86_64/boot/video.S +++ b/arch/x86_64/boot/video.S @@ -1977,7 +1977,7 @@ store_edid: movw $0x4f15, %ax # do VBE/DDC movw $0x01, %bx movw $0x00, %cx - movw $0x01, %dx + movw $0x00, %dx movw $0x140, %di int $0x10 -- cgit v1.2.3-59-g8ed1b From 141f9cfe0a948c8fe26e5669364ee62c03ea42e8 Mon Sep 17 00:00:00 2001 From: Bernhard Walle Date: Wed, 2 May 2007 19:27:11 +0200 Subject: [PATCH] x86-64: Fix "Section mismatch" compile warning Fix "Section mismatch" warnings in arch/x86_64/kernel/time.c Signed-off-by: Bernhard Walle Signed-off-by: Andi Kleen --- arch/x86_64/kernel/time.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 91c9066a380d..0652e173813b 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -328,7 +328,7 @@ static unsigned int __init pit_calibrate_tsc(void) #define PIT_MODE 0x43 #define PIT_CH0 0x40 -static void __init __pit_init(int val, u8 mode) +static void __pit_init(int val, u8 mode) { unsigned long flags; @@ -344,12 +344,12 @@ void __init pit_init(void) __pit_init(LATCH, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */ } -void __init pit_stop_interrupt(void) +void pit_stop_interrupt(void) { __pit_init(0, 0x30); /* mode 0 */ } -void __init stop_timer_interrupt(void) +void stop_timer_interrupt(void) { char *name; if (hpet_address) { -- cgit v1.2.3-59-g8ed1b From 4fbb5968810b237e81977f131986b9efd5245368 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 2 May 2007 19:27:11 +0200 Subject: [PATCH] i386: cleanup GDT Access Now we have an explicit per-cpu GDT variable, we don't need to keep the descriptors around to use them to find the GDT: expose cpu_gdt directly. We could go further and make load_gdt() pack the descriptor for us, or even assume it means "load the current cpu's GDT" which is what it always does. Signed-off-by: Rusty Russell Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/cpu/common.c | 4 +--- arch/i386/kernel/efi.c | 16 ++++++++-------- arch/i386/kernel/entry.S | 3 +-- arch/i386/kernel/smpboot.c | 12 ++++++------ arch/i386/kernel/traps.c | 4 +--- include/asm-i386/desc.h | 7 ++----- 6 files changed, 19 insertions(+), 27 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 2a26956fce42..5faf675aab4b 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -22,9 +22,6 @@ #include "cpu.h" -DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); -EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr); - DEFINE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]) = { [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 }, [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 }, @@ -52,6 +49,7 @@ DEFINE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]) = { [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 }, [GDT_ENTRY_PDA] = { 0x00000000, 0x00c09200 }, /* set in setup_pda */ }; +EXPORT_PER_CPU_SYMBOL_GPL(cpu_gdt); DEFINE_PER_CPU(struct i386_pda, _cpu_pda); EXPORT_PER_CPU_SYMBOL(_cpu_pda); diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c index 8f9c624ace6f..dd9e7faafa7c 100644 --- a/arch/i386/kernel/efi.c +++ b/arch/i386/kernel/efi.c @@ -69,13 +69,11 @@ static void efi_call_phys_prelog(void) __acquires(efi_rt_lock) { unsigned long cr4; unsigned long temp; - struct Xgt_desc_struct *cpu_gdt_descr; + struct Xgt_desc_struct gdt_descr; spin_lock(&efi_rt_lock); local_irq_save(efi_rt_eflags); - cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0); - /* * If I don't have PSE, I should just duplicate two entries in page * directory. If I have PSE, I just need to duplicate one entry in @@ -105,17 +103,19 @@ static void efi_call_phys_prelog(void) __acquires(efi_rt_lock) */ local_flush_tlb(); - cpu_gdt_descr->address = __pa(cpu_gdt_descr->address); - load_gdt(cpu_gdt_descr); + gdt_descr.address = __pa(get_cpu_gdt_table(0)); + gdt_descr.size = GDT_SIZE - 1; + load_gdt(&gdt_descr); } static void efi_call_phys_epilog(void) __releases(efi_rt_lock) { unsigned long cr4; - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0); + struct Xgt_desc_struct gdt_descr; - cpu_gdt_descr->address = (unsigned long)__va(cpu_gdt_descr->address); - load_gdt(cpu_gdt_descr); + gdt_descr.address = (unsigned long)get_cpu_gdt_table(0); + gdt_descr.size = GDT_SIZE - 1; + load_gdt(&gdt_descr); cr4 = read_cr4(); diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 922cc38dc405..c61c6b67e856 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -561,8 +561,7 @@ END(syscall_badsys) #define FIXUP_ESPFIX_STACK \ /* since we are on a wrong stack, we cant make it a C code :( */ \ movl %fs:PDA_cpu, %ebx; \ - PER_CPU(cpu_gdt_descr, %ebx); \ - movl GDS_address(%ebx), %ebx; \ + PER_CPU(cpu_gdt, %ebx); \ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \ addl %esp, %eax; \ pushl $__KERNEL_DS; \ diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 954245f6d307..b0ad04d9ef21 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -786,13 +786,9 @@ static inline struct task_struct * alloc_idle_task(int cpu) secondary which will soon come up. */ static __cpuinit void init_gdt(int cpu, struct task_struct *idle) { - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); - struct desc_struct *gdt = per_cpu(cpu_gdt, cpu); + struct desc_struct *gdt = get_cpu_gdt_table(cpu); struct i386_pda *pda = &per_cpu(_cpu_pda, cpu); - cpu_gdt_descr->address = (unsigned long)gdt; - cpu_gdt_descr->size = GDT_SIZE - 1; - pack_descriptor((u32 *)&gdt[GDT_ENTRY_PDA].a, (u32 *)&gdt[GDT_ENTRY_PDA].b, (unsigned long)pda, sizeof(*pda) - 1, @@ -1187,7 +1183,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus) * it's on the real one. */ static inline void switch_to_new_gdt(void) { - load_gdt(&per_cpu(cpu_gdt_descr, smp_processor_id())); + struct Xgt_desc_struct gdt_descr; + + gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id()); + gdt_descr.size = GDT_SIZE - 1; + load_gdt(&gdt_descr); asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_PDA) : "memory"); } diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 58dfecc8e36c..8722444cacaa 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -1030,9 +1030,7 @@ fastcall void do_spurious_interrupt_bug(struct pt_regs * regs, fastcall unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp) { - int cpu = smp_processor_id(); - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); - struct desc_struct *gdt = (struct desc_struct *)cpu_gdt_descr->address; + struct desc_struct *gdt = __get_cpu_var(cpu_gdt); unsigned long base = (kesp - uesp) & -THREAD_SIZE; unsigned long new_kesp = kesp - base; unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT; diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h index 13f701ea9a8f..4a974064e928 100644 --- a/include/asm-i386/desc.h +++ b/include/asm-i386/desc.h @@ -18,16 +18,13 @@ struct Xgt_desc_struct { unsigned short pad; } __attribute__ ((packed)); -extern struct Xgt_desc_struct idt_descr; -DECLARE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); DECLARE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]); -extern struct Xgt_desc_struct early_gdt_descr; - static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) { - return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address; + return per_cpu(cpu_gdt, cpu); } +extern struct Xgt_desc_struct idt_descr; extern struct desc_struct idt_table[]; extern void set_intr_gate(unsigned int irq, void * addr); -- cgit v1.2.3-59-g8ed1b From 01a2f435564b4baab61328b4018d36464468f57b Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:11 +0200 Subject: [PATCH] i386: Add smp_ops interface Add a smp_ops interface. This abstracts the API defined by for use within arch/i386. The primary intent is that it be used by a paravirtualizing hypervisor to implement SMP, but it could also be used by non-APIC-using sub-architectures. This is related to CONFIG_PARAVIRT, but is implemented unconditionally since it is simpler that way and not a highly performance-sensitive interface. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Ingo Molnar Cc: James Bottomley --- arch/i386/kernel/smp.c | 21 +++++++++++++----- arch/i386/kernel/smpboot.c | 8 +++---- include/asm-i386/smp.h | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index b90bebeb1c79..fe38b49a1223 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -483,7 +483,7 @@ void flush_tlb_all(void) * it goes straight through and wastes no time serializing * anything. Worst case is that we lose a reschedule ... */ -void smp_send_reschedule(int cpu) +void native_smp_send_reschedule(int cpu) { WARN_ON(cpu_is_offline(cpu)); send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR); @@ -560,9 +560,9 @@ static void __smp_call_function(void (*func) (void *info), void *info, * You must not call this function with disabled interrupts or from a * hardware interrupt handler or from a bottom half handler. */ -int smp_call_function_mask(cpumask_t mask, - void (*func)(void *), void *info, - int wait) +int native_smp_call_function_mask(cpumask_t mask, + void (*func)(void *), void *info, + int wait) { struct call_data_struct data; cpumask_t allbutself; @@ -681,7 +681,7 @@ static void stop_this_cpu (void * dummy) * this function calls the 'stop' function on all other CPUs in the system. */ -void smp_send_stop(void) +void native_smp_send_stop(void) { /* Don't deadlock on the call lock in panic */ int nolock = !spin_trylock(&call_lock); @@ -757,3 +757,14 @@ int safe_smp_processor_id(void) return cpuid >= 0 ? cpuid : 0; } + +struct smp_ops smp_ops = { + .smp_prepare_boot_cpu = native_smp_prepare_boot_cpu, + .smp_prepare_cpus = native_smp_prepare_cpus, + .cpu_up = native_cpu_up, + .smp_cpus_done = native_smp_cpus_done, + + .smp_send_stop = native_smp_send_stop, + .smp_send_reschedule = native_smp_send_reschedule, + .smp_call_function_mask = native_smp_call_function_mask, +}; diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index b0ad04d9ef21..1c3ad9b406ca 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -1171,7 +1171,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) /* These are wrappers to interface to the new boot process. Someone who understands all this stuff should rewrite it properly. --RR 15/Jul/02 */ -void __init smp_prepare_cpus(unsigned int max_cpus) +void __init native_smp_prepare_cpus(unsigned int max_cpus) { smp_commenced_mask = cpumask_of_cpu(0); cpu_callin_map = cpumask_of_cpu(0); @@ -1191,7 +1191,7 @@ static inline void switch_to_new_gdt(void) asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_PDA) : "memory"); } -void __init smp_prepare_boot_cpu(void) +void __init native_smp_prepare_boot_cpu(void) { unsigned int cpu = smp_processor_id(); @@ -1292,7 +1292,7 @@ void __cpu_die(unsigned int cpu) } #endif /* CONFIG_HOTPLUG_CPU */ -int __cpuinit __cpu_up(unsigned int cpu) +int __cpuinit native_cpu_up(unsigned int cpu) { unsigned long flags; #ifdef CONFIG_HOTPLUG_CPU @@ -1337,7 +1337,7 @@ int __cpuinit __cpu_up(unsigned int cpu) return 0; } -void __init smp_cpus_done(unsigned int max_cpus) +void __init native_smp_cpus_done(unsigned int max_cpus) { #ifdef CONFIG_X86_IO_APIC setup_ioapic_dest(); diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h index 9cab1531c613..2d083cb4ca93 100644 --- a/include/asm-i386/smp.h +++ b/include/asm-i386/smp.h @@ -49,6 +49,59 @@ extern void cpu_exit_clear(void); extern void cpu_uninit(void); #endif +struct smp_ops +{ + void (*smp_prepare_boot_cpu)(void); + void (*smp_prepare_cpus)(unsigned max_cpus); + int (*cpu_up)(unsigned cpu); + void (*smp_cpus_done)(unsigned max_cpus); + + void (*smp_send_stop)(void); + void (*smp_send_reschedule)(int cpu); + int (*smp_call_function_mask)(cpumask_t mask, + void (*func)(void *info), void *info, + int wait); +}; + +extern struct smp_ops smp_ops; + +static inline void smp_prepare_boot_cpu(void) +{ + smp_ops.smp_prepare_boot_cpu(); +} +static inline void smp_prepare_cpus(unsigned int max_cpus) +{ + smp_ops.smp_prepare_cpus(max_cpus); +} +static inline int __cpu_up(unsigned int cpu) +{ + return smp_ops.cpu_up(cpu); +} +static inline void smp_cpus_done(unsigned int max_cpus) +{ + smp_ops.smp_cpus_done(max_cpus); +} + +static inline void smp_send_stop(void) +{ + smp_ops.smp_send_stop(); +} +static inline void smp_send_reschedule(int cpu) +{ + smp_ops.smp_send_reschedule(cpu); +} +static inline int smp_call_function_mask(cpumask_t mask, + void (*func) (void *info), void *info, + int wait) +{ + return smp_ops.smp_call_function_mask(mask, func, info, wait); +} + +void native_smp_prepare_boot_cpu(void); +void native_smp_prepare_cpus(unsigned int max_cpus); +int native_cpu_up(unsigned int cpunum); +void native_smp_cpus_done(unsigned int max_cpus); + #ifndef CONFIG_PARAVIRT #define startup_ipi_hook(phys_apicid, start_eip, start_esp) \ do { } while (0) -- cgit v1.2.3-59-g8ed1b From 07f3331c6bfd27a06dfb0ca9fa4f06dec6606876 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:11 +0200 Subject: [PATCH] i386: Add machine_ops interface to abstract halting and rebooting machine_ops is an interface for the machine_* functions defined in . This is intended to allow hypervisors to intercept the reboot process, but it could be used to implement other x86 subarchtecture reboots. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen --- arch/i386/kernel/apm.c | 3 +-- arch/i386/kernel/reboot.c | 43 ++++++++++++++++++++++++++++++++++++++----- include/asm-i386/reboot.h | 20 ++++++++++++++++++++ 3 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 include/asm-i386/reboot.h (limited to 'arch') diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 4d073d390715..367ff1d930cb 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -233,11 +233,10 @@ #include #include #include +#include #include "io_ports.h" -extern void machine_real_restart(unsigned char *, int); - #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT) extern int (*console_blank_hook)(int); #endif diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c index 8b5ff6e15412..14b4de2882be 100644 --- a/arch/i386/kernel/reboot.c +++ b/arch/i386/kernel/reboot.c @@ -18,6 +18,7 @@ #include #include "mach_reboot.h" #include +#include /* * Power off function, if any @@ -280,7 +281,7 @@ void machine_real_restart(unsigned char *code, int length) EXPORT_SYMBOL(machine_real_restart); #endif -void machine_shutdown(void) +static void native_machine_shutdown(void) { #ifdef CONFIG_SMP int reboot_cpu_id; @@ -320,7 +321,7 @@ void __attribute__((weak)) mach_reboot_fixups(void) { } -void machine_emergency_restart(void) +static void native_machine_emergency_restart(void) { if (!reboot_thru_bios) { if (efi_enabled) { @@ -344,17 +345,17 @@ void machine_emergency_restart(void) machine_real_restart(jump_to_bios, sizeof(jump_to_bios)); } -void machine_restart(char * __unused) +static void native_machine_restart(char * __unused) { machine_shutdown(); machine_emergency_restart(); } -void machine_halt(void) +static void native_machine_halt(void) { } -void machine_power_off(void) +static void native_machine_power_off(void) { if (pm_power_off) { machine_shutdown(); @@ -363,3 +364,35 @@ void machine_power_off(void) } +struct machine_ops machine_ops = { + .power_off = native_machine_power_off, + .shutdown = native_machine_shutdown, + .emergency_restart = native_machine_emergency_restart, + .restart = native_machine_restart, + .halt = native_machine_halt, +}; + +void machine_power_off(void) +{ + machine_ops.power_off(); +} + +void machine_shutdown(void) +{ + machine_ops.shutdown(); +} + +void machine_emergency_restart(void) +{ + machine_ops.emergency_restart(); +} + +void machine_restart(char *cmd) +{ + machine_ops.restart(cmd); +} + +void machine_halt(void) +{ + machine_ops.halt(); +} diff --git a/include/asm-i386/reboot.h b/include/asm-i386/reboot.h new file mode 100644 index 000000000000..e9e3ffc22c07 --- /dev/null +++ b/include/asm-i386/reboot.h @@ -0,0 +1,20 @@ +#ifndef _ASM_REBOOT_H +#define _ASM_REBOOT_H + +struct pt_regs; + +struct machine_ops +{ + void (*restart)(char *cmd); + void (*halt)(void); + void (*power_off)(void); + void (*shutdown)(void); + void (*crash_shutdown)(struct pt_regs *); + void (*emergency_restart)(void); +}; + +extern struct machine_ops machine_ops; + +void machine_real_restart(unsigned char *code, int length); + +#endif /* _ASM_REBOOT_H */ -- cgit v1.2.3-59-g8ed1b From bbba11c35baaad3f70f32e185a2c1d40d7901fe9 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:11 +0200 Subject: [PATCH] i386: Remove unneeded externs in nmi.c All were already in some header Signed-off-by: Andi Kleen --- arch/i386/kernel/nmi.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index aef22c881a0d..2dec1b105737 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -75,9 +75,6 @@ static DEFINE_PER_CPU(struct nmi_watchdog_ctlblk, nmi_watchdog_ctlblk); /* local prototypes */ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu); -extern void show_registers(struct pt_regs *regs); -extern int unknown_nmi_panic; - /* converts an msr to an appropriate reservation bit */ static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr) { -- cgit v1.2.3-59-g8ed1b From b92e9fac400d4ae5bc7a75c568e9844ec53ea329 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 2 May 2007 19:27:11 +0200 Subject: [PATCH] x86: fix amd64-agp aperture validation Under CONFIG_DISCONTIGMEM, assuming that a !pfn_valid() implies all subsequent pfn-s are also invalid is wrong. Thus replace this by explicitly checking against the E820 map. AK: make e820 on x86-64 not initdata Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen Acked-by: Mark Langsdorf --- arch/i386/kernel/e820.c | 20 ++++++++++++++++++++ arch/x86_64/kernel/e820.c | 5 +++-- drivers/char/agp/amd64-agp.c | 13 ++++--------- include/asm-i386/e820.h | 1 + 4 files changed, 28 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c index 31f4670ef740..829beec9247e 100644 --- a/arch/i386/kernel/e820.c +++ b/arch/i386/kernel/e820.c @@ -825,6 +825,26 @@ void __init limit_regions(unsigned long long size) print_memory_map("limit_regions endfunc"); } +/* + * This function checks if any part of the range is mapped + * with type. + */ +int +e820_any_mapped(u64 start, u64 end, unsigned type) +{ + int i; + for (i = 0; i < e820.nr_map; i++) { + const struct e820entry *ei = &e820.map[i]; + if (type && ei->type != type) + continue; + if (ei->addr >= end || ei->addr + ei->size <= start) + continue; + return 1; + } + return 0; +} +EXPORT_SYMBOL_GPL(e820_any_mapped); + /* * This function checks if the entire range is mapped with type. * diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index a490fabfcf47..be8965427a93 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c @@ -25,7 +25,7 @@ #include #include -struct e820map e820 __initdata; +struct e820map e820; /* * PFN of last memory page. @@ -98,7 +98,7 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size) * This function checks if any part of the range is mapped * with type. */ -int __meminit +int e820_any_mapped(unsigned long start, unsigned long end, unsigned type) { int i; @@ -112,6 +112,7 @@ e820_any_mapped(unsigned long start, unsigned long end, unsigned type) } return 0; } +EXPORT_SYMBOL_GPL(e820_any_mapped); /* * This function checks if the entire range is mapped with type. diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 485720486d60..c9f0f250d78f 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -14,6 +14,7 @@ #include #include #include /* PAGE_SIZE */ +#include #include #include "agp.h" @@ -259,7 +260,6 @@ static const struct agp_bridge_driver amd_8151_driver = { /* Some basic sanity checks for the aperture. */ static int __devinit aperture_valid(u64 aper, u32 size) { - u32 pfn, c; if (aper == 0) { printk(KERN_ERR PFX "No aperture\n"); return 0; @@ -272,14 +272,9 @@ static int __devinit aperture_valid(u64 aper, u32 size) printk(KERN_ERR PFX "Aperture out of bounds\n"); return 0; } - pfn = aper >> PAGE_SHIFT; - for (c = 0; c < size/PAGE_SIZE; c++) { - if (!pfn_valid(pfn + c)) - break; - if (!PageReserved(pfn_to_page(pfn + c))) { - printk(KERN_ERR PFX "Aperture pointing to RAM\n"); - return 0; - } + if (e820_any_mapped(aper, aper + size, E820_RAM)) { + printk(KERN_ERR PFX "Aperture pointing to RAM\n"); + return 0; } /* Request the Aperture. This catches cases when someone else diff --git a/include/asm-i386/e820.h b/include/asm-i386/e820.h index c5b8fc6109d6..096a2a8eb1da 100644 --- a/include/asm-i386/e820.h +++ b/include/asm-i386/e820.h @@ -38,6 +38,7 @@ extern struct e820map e820; extern int e820_all_mapped(unsigned long start, unsigned long end, unsigned type); +extern int e820_any_mapped(u64 start, u64 end, unsigned type); extern void find_max_pfn(void); extern void register_bootmem_low_pages(unsigned long max_low_pfn); extern void e820_register_memory(void); -- cgit v1.2.3-59-g8ed1b From 1353ebb4b48151e3810d9a60449edd43a90ea3c3 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:12 +0200 Subject: [PATCH] i386: Clean up asm-i386/bugs.h Most of asm-i386/bugs.h is code which should be in a C file, so put it there. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Linus Torvalds --- arch/i386/kernel/cpu/Makefile | 2 +- arch/i386/kernel/cpu/bugs.c | 191 ++++++++++++++++++++++++++++++++++++++++ include/asm-i386/alternative.h | 1 + include/asm-i386/bugs.h | 194 +---------------------------------------- 4 files changed, 197 insertions(+), 191 deletions(-) create mode 100644 arch/i386/kernel/cpu/bugs.c (limited to 'arch') diff --git a/arch/i386/kernel/cpu/Makefile b/arch/i386/kernel/cpu/Makefile index 010aecfffbc1..5fb1a7560438 100644 --- a/arch/i386/kernel/cpu/Makefile +++ b/arch/i386/kernel/cpu/Makefile @@ -2,7 +2,7 @@ # Makefile for x86-compatible CPU details and quirks # -obj-y := common.o proc.o +obj-y := common.o proc.o bugs.o obj-y += amd.o obj-y += cyrix.o diff --git a/arch/i386/kernel/cpu/bugs.c b/arch/i386/kernel/cpu/bugs.c new file mode 100644 index 000000000000..54428a2500f3 --- /dev/null +++ b/arch/i386/kernel/cpu/bugs.c @@ -0,0 +1,191 @@ +/* + * arch/i386/cpu/bugs.c + * + * Copyright (C) 1994 Linus Torvalds + * + * Cyrix stuff, June 1998 by: + * - Rafael R. Reilova (moved everything from head.S), + * + * - Channing Corn (tests & fixes), + * - Andrew D. Balsa (code cleanup). + */ +#include +#include +#include +#include +#include +#include +#include + +static int __init no_halt(char *s) +{ + boot_cpu_data.hlt_works_ok = 0; + return 1; +} + +__setup("no-hlt", no_halt); + +static int __init mca_pentium(char *s) +{ + mca_pentium_flag = 1; + return 1; +} + +__setup("mca-pentium", mca_pentium); + +static int __init no_387(char *s) +{ + boot_cpu_data.hard_math = 0; + write_cr0(0xE | read_cr0()); + return 1; +} + +__setup("no387", no_387); + +static double __initdata x = 4195835.0; +static double __initdata y = 3145727.0; + +/* + * This used to check for exceptions.. + * However, it turns out that to support that, + * the XMM trap handlers basically had to + * be buggy. So let's have a correct XMM trap + * handler, and forget about printing out + * some status at boot. + * + * We should really only care about bugs here + * anyway. Not features. + */ +static void __init check_fpu(void) +{ + if (!boot_cpu_data.hard_math) { +#ifndef CONFIG_MATH_EMULATION + printk(KERN_EMERG "No coprocessor found and no math emulation present.\n"); + printk(KERN_EMERG "Giving up.\n"); + for (;;) ; +#endif + return; + } + +/* trap_init() enabled FXSR and company _before_ testing for FP problems here. */ + /* Test for the divl bug.. */ + __asm__("fninit\n\t" + "fldl %1\n\t" + "fdivl %2\n\t" + "fmull %2\n\t" + "fldl %1\n\t" + "fsubp %%st,%%st(1)\n\t" + "fistpl %0\n\t" + "fwait\n\t" + "fninit" + : "=m" (*&boot_cpu_data.fdiv_bug) + : "m" (*&x), "m" (*&y)); + if (boot_cpu_data.fdiv_bug) + printk("Hmm, FPU with FDIV bug.\n"); +} + +static void __init check_hlt(void) +{ + if (paravirt_enabled()) + return; + + printk(KERN_INFO "Checking 'hlt' instruction... "); + if (!boot_cpu_data.hlt_works_ok) { + printk("disabled\n"); + return; + } + halt(); + halt(); + halt(); + halt(); + printk("OK.\n"); +} + +/* + * Most 386 processors have a bug where a POPAD can lock the + * machine even from user space. + */ + +static void __init check_popad(void) +{ +#ifndef CONFIG_X86_POPAD_OK + int res, inp = (int) &res; + + printk(KERN_INFO "Checking for popad bug... "); + __asm__ __volatile__( + "movl $12345678,%%eax; movl $0,%%edi; pusha; popa; movl (%%edx,%%edi),%%ecx " + : "=&a" (res) + : "d" (inp) + : "ecx", "edi" ); + /* If this fails, it means that any user program may lock the CPU hard. Too bad. */ + if (res != 12345678) printk( "Buggy.\n" ); + else printk( "OK.\n" ); +#endif +} + +/* + * Check whether we are able to run this kernel safely on SMP. + * + * - In order to run on a i386, we need to be compiled for i386 + * (for due to lack of "invlpg" and working WP on a i386) + * - In order to run on anything without a TSC, we need to be + * compiled for a i486. + * - In order to support the local APIC on a buggy Pentium machine, + * we need to be compiled with CONFIG_X86_GOOD_APIC disabled, + * which happens implicitly if compiled for a Pentium or lower + * (unless an advanced selection of CPU features is used) as an + * otherwise config implies a properly working local APIC without + * the need to do extra reads from the APIC. +*/ + +static void __init check_config(void) +{ +/* + * We'd better not be a i386 if we're configured to use some + * i486+ only features! (WP works in supervisor mode and the + * new "invlpg" and "bswap" instructions) + */ +#if defined(CONFIG_X86_WP_WORKS_OK) || defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_BSWAP) + if (boot_cpu_data.x86 == 3) + panic("Kernel requires i486+ for 'invlpg' and other features"); +#endif + +/* + * If we configured ourselves for a TSC, we'd better have one! + */ +#ifdef CONFIG_X86_TSC + if (!cpu_has_tsc && !tsc_disable) + panic("Kernel compiled for Pentium+, requires TSC feature!"); +#endif + +/* + * If we were told we had a good local APIC, check for buggy Pentia, + * i.e. all B steppings and the C2 stepping of P54C when using their + * integrated APIC (see 11AP erratum in "Pentium Processor + * Specification Update"). + */ +#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_GOOD_APIC) + if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL + && cpu_has_apic + && boot_cpu_data.x86 == 5 + && boot_cpu_data.x86_model == 2 + && (boot_cpu_data.x86_mask < 6 || boot_cpu_data.x86_mask == 11)) + panic("Kernel compiled for PMMX+, assumes a local APIC without the read-before-write bug!"); +#endif +} + + +void __init check_bugs(void) +{ + identify_boot_cpu(); +#ifndef CONFIG_SMP + printk("CPU: "); + print_cpu_info(&boot_cpu_data); +#endif + check_config(); + check_fpu(); + check_hlt(); + check_popad(); + init_utsname()->machine[1] = '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); + alternative_instructions(); +} diff --git a/include/asm-i386/alternative.h b/include/asm-i386/alternative.h index b8fa9557c532..dbc1a29284f3 100644 --- a/include/asm-i386/alternative.h +++ b/include/asm-i386/alternative.h @@ -16,6 +16,7 @@ struct alt_instr { u8 pad; }; +extern void alternative_instructions(void); extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end); struct module; diff --git a/include/asm-i386/bugs.h b/include/asm-i386/bugs.h index c90c7c499302..df539b390448 100644 --- a/include/asm-i386/bugs.h +++ b/include/asm-i386/bugs.h @@ -1,198 +1,12 @@ -/* - * include/asm-i386/bugs.h - * - * Copyright (C) 1994 Linus Torvalds - * - * Cyrix stuff, June 1998 by: - * - Rafael R. Reilova (moved everything from head.S), - * - * - Channing Corn (tests & fixes), - * - Andrew D. Balsa (code cleanup). - */ - /* * This is included by init/main.c to check for architecture-dependent bugs. * * Needs: * void check_bugs(void); */ +#ifndef _ASM_I386_BUG_H +#define _ASM_I386_BUG_H -#include -#include -#include -#include -#include - -static int __init no_halt(char *s) -{ - boot_cpu_data.hlt_works_ok = 0; - return 1; -} - -__setup("no-hlt", no_halt); - -static int __init mca_pentium(char *s) -{ - mca_pentium_flag = 1; - return 1; -} - -__setup("mca-pentium", mca_pentium); - -static int __init no_387(char *s) -{ - boot_cpu_data.hard_math = 0; - write_cr0(0xE | read_cr0()); - return 1; -} - -__setup("no387", no_387); - -static double __initdata x = 4195835.0; -static double __initdata y = 3145727.0; - -/* - * This used to check for exceptions.. - * However, it turns out that to support that, - * the XMM trap handlers basically had to - * be buggy. So let's have a correct XMM trap - * handler, and forget about printing out - * some status at boot. - * - * We should really only care about bugs here - * anyway. Not features. - */ -static void __init check_fpu(void) -{ - if (!boot_cpu_data.hard_math) { -#ifndef CONFIG_MATH_EMULATION - printk(KERN_EMERG "No coprocessor found and no math emulation present.\n"); - printk(KERN_EMERG "Giving up.\n"); - for (;;) ; -#endif - return; - } - -/* trap_init() enabled FXSR and company _before_ testing for FP problems here. */ - /* Test for the divl bug.. */ - __asm__("fninit\n\t" - "fldl %1\n\t" - "fdivl %2\n\t" - "fmull %2\n\t" - "fldl %1\n\t" - "fsubp %%st,%%st(1)\n\t" - "fistpl %0\n\t" - "fwait\n\t" - "fninit" - : "=m" (*&boot_cpu_data.fdiv_bug) - : "m" (*&x), "m" (*&y)); - if (boot_cpu_data.fdiv_bug) - printk("Hmm, FPU with FDIV bug.\n"); -} - -static void __init check_hlt(void) -{ - if (paravirt_enabled()) - return; - - printk(KERN_INFO "Checking 'hlt' instruction... "); - if (!boot_cpu_data.hlt_works_ok) { - printk("disabled\n"); - return; - } - halt(); - halt(); - halt(); - halt(); - printk("OK.\n"); -} - -/* - * Most 386 processors have a bug where a POPAD can lock the - * machine even from user space. - */ - -static void __init check_popad(void) -{ -#ifndef CONFIG_X86_POPAD_OK - int res, inp = (int) &res; - - printk(KERN_INFO "Checking for popad bug... "); - __asm__ __volatile__( - "movl $12345678,%%eax; movl $0,%%edi; pusha; popa; movl (%%edx,%%edi),%%ecx " - : "=&a" (res) - : "d" (inp) - : "ecx", "edi" ); - /* If this fails, it means that any user program may lock the CPU hard. Too bad. */ - if (res != 12345678) printk( "Buggy.\n" ); - else printk( "OK.\n" ); -#endif -} - -/* - * Check whether we are able to run this kernel safely on SMP. - * - * - In order to run on a i386, we need to be compiled for i386 - * (for due to lack of "invlpg" and working WP on a i386) - * - In order to run on anything without a TSC, we need to be - * compiled for a i486. - * - In order to support the local APIC on a buggy Pentium machine, - * we need to be compiled with CONFIG_X86_GOOD_APIC disabled, - * which happens implicitly if compiled for a Pentium or lower - * (unless an advanced selection of CPU features is used) as an - * otherwise config implies a properly working local APIC without - * the need to do extra reads from the APIC. -*/ - -static void __init check_config(void) -{ -/* - * We'd better not be a i386 if we're configured to use some - * i486+ only features! (WP works in supervisor mode and the - * new "invlpg" and "bswap" instructions) - */ -#if defined(CONFIG_X86_WP_WORKS_OK) || defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_BSWAP) - if (boot_cpu_data.x86 == 3) - panic("Kernel requires i486+ for 'invlpg' and other features"); -#endif - -/* - * If we configured ourselves for a TSC, we'd better have one! - */ -#ifdef CONFIG_X86_TSC - if (!cpu_has_tsc && !tsc_disable) - panic("Kernel compiled for Pentium+, requires TSC feature!"); -#endif - -/* - * If we were told we had a good local APIC, check for buggy Pentia, - * i.e. all B steppings and the C2 stepping of P54C when using their - * integrated APIC (see 11AP erratum in "Pentium Processor - * Specification Update"). - */ -#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_GOOD_APIC) - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL - && cpu_has_apic - && boot_cpu_data.x86 == 5 - && boot_cpu_data.x86_model == 2 - && (boot_cpu_data.x86_mask < 6 || boot_cpu_data.x86_mask == 11)) - panic("Kernel compiled for PMMX+, assumes a local APIC without the read-before-write bug!"); -#endif -} - -extern void alternative_instructions(void); +extern void __init check_bugs(void); -static void __init check_bugs(void) -{ - identify_cpu(&boot_cpu_data); -#ifndef CONFIG_SMP - printk("CPU: "); - print_cpu_info(&boot_cpu_data); -#endif - check_config(); - check_fpu(); - check_hlt(); - check_popad(); - init_utsname()->machine[1] = '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); - alternative_instructions(); -} +#endif /* _ASM_I386_BUG_H */ -- cgit v1.2.3-59-g8ed1b From a6c4e076ee4c1ea670e4faa55814e63dd08e3f29 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:12 +0200 Subject: [PATCH] i386: clean up identify_cpu identify_cpu() is used to identify both the boot CPU and secondary CPUs, but it performs some actions which only apply to the boot CPU. Those functions are therefore really __init functions, but because they're called by identify_cpu(), they must be marked __cpuinit. This patch splits identify_cpu() into identify_boot_cpu() and identify_secondary_cpu(), and calls the appropriate init functions from each. Also, identify_boot_cpu() and all the functions it dominates are marked __init. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen --- arch/i386/kernel/cpu/common.c | 21 ++++++++++++++------- arch/i386/kernel/smpboot.c | 2 +- arch/i386/kernel/sysenter.c | 2 +- include/asm-i386/processor.h | 3 ++- 4 files changed, 18 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 5faf675aab4b..58128585ae60 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -394,7 +394,7 @@ __setup("serialnumber", x86_serial_nr_setup); /* * This does the hard work of actually picking apart the CPU stuff... */ -void __cpuinit identify_cpu(struct cpuinfo_x86 *c) +static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) { int i; @@ -505,15 +505,22 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) /* Init Machine Check Exception if available. */ mcheck_init(c); +} - if (c == &boot_cpu_data) - sysenter_setup(); +void __init identify_boot_cpu(void) +{ + identify_cpu(&boot_cpu_data); + sysenter_setup(); enable_sep_cpu(); + mtrr_bp_init(); +} - if (c == &boot_cpu_data) - mtrr_bp_init(); - else - mtrr_ap_init(); +void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) +{ + BUG_ON(c == &boot_cpu_data); + identify_cpu(c); + enable_sep_cpu(); + mtrr_ap_init(); } #ifdef CONFIG_X86_HT diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 1c3ad9b406ca..61e2842add36 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -155,7 +155,7 @@ static void __cpuinit smp_store_cpu_info(int id) *c = boot_cpu_data; if (id!=0) - identify_cpu(c); + identify_secondary_cpu(c); /* * Mask B, Pentium, but not Pentium MMX */ diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c index 168f8147d3b4..13ca54a85a1c 100644 --- a/arch/i386/kernel/sysenter.c +++ b/arch/i386/kernel/sysenter.c @@ -72,7 +72,7 @@ extern const char vsyscall_int80_start, vsyscall_int80_end; extern const char vsyscall_sysenter_start, vsyscall_sysenter_end; static struct page *syscall_pages[1]; -int __cpuinit sysenter_setup(void) +int __init sysenter_setup(void) { void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); syscall_pages[0] = virt_to_page(syscall_page); diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 11838df88603..9d895cc2f312 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -116,7 +116,8 @@ extern char ignore_fpu_irq; void __init cpu_detect(struct cpuinfo_x86 *c); -extern void identify_cpu(struct cpuinfo_x86 *); +extern void identify_boot_cpu(void); +extern void identify_secondary_cpu(struct cpuinfo_x86 *); extern void print_cpu_info(struct cpuinfo_x86 *); extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); extern unsigned short num_cache_leaves; -- cgit v1.2.3-59-g8ed1b From d4f7a2c18e59e0304a1c733589ce14fc02fec1bd Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:12 +0200 Subject: [PATCH] i386: Relocate VDSO ELF headers to match mapped location with COMPAT_VDSO Some versions of libc can't deal with a VDSO which doesn't have its ELF headers matching its mapped address. COMPAT_VDSO maps the VDSO at a specific system-wide fixed address. Previously this was all done at build time, on the grounds that the fixed VDSO address is always at the top of the address space. However, a hypervisor may reserve some of that address space, pushing the fixmap address down. This patch does the adjustment dynamically at runtime, depending on the runtime location of the VDSO fixmap. [ Patch has been through several hands: Jan Beulich wrote the orignal version; Zach reworked it, and Jeremy converted it to relocate phdrs as well as sections. ] Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Zachary Amsden Cc: "Jan Beulich" Cc: Eric W. Biederman Cc: Andi Kleen Cc: Ingo Molnar Cc: Roland McGrath --- arch/i386/kernel/entry.S | 4 -- arch/i386/kernel/sysenter.c | 158 +++++++++++++++++++++++++++++++++++++++++--- arch/i386/mm/pgtable.c | 6 -- include/asm-i386/elf.h | 28 +++----- include/asm-i386/fixmap.h | 8 +-- include/linux/elf.h | 17 +++++ 6 files changed, 178 insertions(+), 43 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index c61c6b67e856..e901952dff37 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -305,16 +305,12 @@ sysenter_past_esp: pushl $(__USER_CS) CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET cs, 0*/ -#ifndef CONFIG_COMPAT_VDSO /* * Push current_thread_info()->sysenter_return to the stack. * A tiny bit of offset fixup is necessary - 4*4 means the 4 words * pushed above; +8 corresponds to copy_thread's esp0 setting. */ pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) -#else - pushl $SYSENTER_RETURN -#endif CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET eip, 0 diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c index 13ca54a85a1c..e5a958379ac9 100644 --- a/arch/i386/kernel/sysenter.c +++ b/arch/i386/kernel/sysenter.c @@ -22,6 +22,7 @@ #include #include #include +#include /* * Should the kernel map a VDSO page into processes and pass its @@ -46,6 +47,129 @@ __setup("vdso=", vdso_setup); extern asmlinkage void sysenter_entry(void); +#ifdef CONFIG_COMPAT_VDSO +static __init void reloc_symtab(Elf32_Ehdr *ehdr, + unsigned offset, unsigned size) +{ + Elf32_Sym *sym = (void *)ehdr + offset; + unsigned nsym = size / sizeof(*sym); + unsigned i; + + for(i = 0; i < nsym; i++, sym++) { + if (sym->st_shndx == SHN_UNDEF || + sym->st_shndx == SHN_ABS) + continue; /* skip */ + + if (sym->st_shndx > SHN_LORESERVE) { + printk(KERN_INFO "VDSO: unexpected st_shndx %x\n", + sym->st_shndx); + continue; + } + + switch(ELF_ST_TYPE(sym->st_info)) { + case STT_OBJECT: + case STT_FUNC: + case STT_SECTION: + case STT_FILE: + sym->st_value += VDSO_HIGH_BASE; + } + } +} + +static __init void reloc_dyn(Elf32_Ehdr *ehdr, unsigned offset) +{ + Elf32_Dyn *dyn = (void *)ehdr + offset; + + for(; dyn->d_tag != DT_NULL; dyn++) + switch(dyn->d_tag) { + case DT_PLTGOT: + case DT_HASH: + case DT_STRTAB: + case DT_SYMTAB: + case DT_RELA: + case DT_INIT: + case DT_FINI: + case DT_REL: + case DT_DEBUG: + case DT_JMPREL: + case DT_VERSYM: + case DT_VERDEF: + case DT_VERNEED: + case DT_ADDRRNGLO ... DT_ADDRRNGHI: + /* definitely pointers needing relocation */ + dyn->d_un.d_ptr += VDSO_HIGH_BASE; + break; + + case DT_ENCODING ... OLD_DT_LOOS-1: + case DT_LOOS ... DT_HIOS-1: + /* Tags above DT_ENCODING are pointers if + they're even */ + if (dyn->d_tag >= DT_ENCODING && + (dyn->d_tag & 1) == 0) + dyn->d_un.d_ptr += VDSO_HIGH_BASE; + break; + + case DT_VERDEFNUM: + case DT_VERNEEDNUM: + case DT_FLAGS_1: + case DT_RELACOUNT: + case DT_RELCOUNT: + case DT_VALRNGLO ... DT_VALRNGHI: + /* definitely not pointers */ + break; + + case OLD_DT_LOOS ... DT_LOOS-1: + case DT_HIOS ... DT_VALRNGLO-1: + default: + if (dyn->d_tag > DT_ENCODING) + printk(KERN_INFO "VDSO: unexpected DT_tag %x\n", + dyn->d_tag); + break; + } +} + +static __init void relocate_vdso(Elf32_Ehdr *ehdr) +{ + Elf32_Phdr *phdr; + Elf32_Shdr *shdr; + int i; + + BUG_ON(memcmp(ehdr->e_ident, ELFMAG, 4) != 0 || + !elf_check_arch(ehdr) || + ehdr->e_type != ET_DYN); + + ehdr->e_entry += VDSO_HIGH_BASE; + + /* rebase phdrs */ + phdr = (void *)ehdr + ehdr->e_phoff; + for (i = 0; i < ehdr->e_phnum; i++) { + phdr[i].p_vaddr += VDSO_HIGH_BASE; + + /* relocate dynamic stuff */ + if (phdr[i].p_type == PT_DYNAMIC) + reloc_dyn(ehdr, phdr[i].p_offset); + } + + /* rebase sections */ + shdr = (void *)ehdr + ehdr->e_shoff; + for(i = 0; i < ehdr->e_shnum; i++) { + if (!(shdr[i].sh_flags & SHF_ALLOC)) + continue; + + shdr[i].sh_addr += VDSO_HIGH_BASE; + + if (shdr[i].sh_type == SHT_SYMTAB || + shdr[i].sh_type == SHT_DYNSYM) + reloc_symtab(ehdr, shdr[i].sh_offset, + shdr[i].sh_size); + } +} +#else +static inline void relocate_vdso(Elf32_Ehdr *ehdr) +{ +} +#endif /* COMPAT_VDSO */ + void enable_sep_cpu(void) { int cpu = get_cpu(); @@ -75,6 +199,9 @@ static struct page *syscall_pages[1]; int __init sysenter_setup(void) { void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); + const void *vsyscall; + size_t vsyscall_len; + syscall_pages[0] = virt_to_page(syscall_page); #ifdef CONFIG_COMPAT_VDSO @@ -83,23 +210,23 @@ int __init sysenter_setup(void) #endif if (!boot_cpu_has(X86_FEATURE_SEP)) { - memcpy(syscall_page, - &vsyscall_int80_start, - &vsyscall_int80_end - &vsyscall_int80_start); - return 0; + vsyscall = &vsyscall_int80_start; + vsyscall_len = &vsyscall_int80_end - &vsyscall_int80_start; + } else { + vsyscall = &vsyscall_sysenter_start; + vsyscall_len = &vsyscall_sysenter_end - &vsyscall_sysenter_start; } - memcpy(syscall_page, - &vsyscall_sysenter_start, - &vsyscall_sysenter_end - &vsyscall_sysenter_start); + memcpy(syscall_page, vsyscall, vsyscall_len); + relocate_vdso(syscall_page); return 0; } -#ifndef CONFIG_COMPAT_VDSO /* Defined in vsyscall-sysenter.S */ extern void SYSENTER_RETURN; +#ifdef __HAVE_ARCH_GATE_AREA /* Setup a VMA at program startup for the vsyscall page */ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) { @@ -159,4 +286,17 @@ int in_gate_area_no_task(unsigned long addr) { return 0; } -#endif +#else /* !__HAVE_ARCH_GATE_AREA */ +int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) +{ + /* + * If not creating userspace VMA, simply set vdso to point to + * fixmap page. + */ + current->mm->context.vdso = (void *)VDSO_HIGH_BASE; + current_thread_info()->sysenter_return = + (void *)VDSO_SYM(&SYSENTER_RETURN); + + return 0; +} +#endif /* __HAVE_ARCH_GATE_AREA */ diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c index fa0cfbd551e1..99c09edc3dbb 100644 --- a/arch/i386/mm/pgtable.c +++ b/arch/i386/mm/pgtable.c @@ -144,10 +144,8 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) } static int fixmaps; -#ifndef CONFIG_COMPAT_VDSO unsigned long __FIXADDR_TOP = 0xfffff000; EXPORT_SYMBOL(__FIXADDR_TOP); -#endif void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) { @@ -173,12 +171,8 @@ void reserve_top_address(unsigned long reserve) BUG_ON(fixmaps > 0); printk(KERN_INFO "Reserving virtual address space above 0x%08x\n", (int)-reserve); -#ifdef CONFIG_COMPAT_VDSO - BUG_ON(reserve != 0); -#else __FIXADDR_TOP = -reserve - PAGE_SIZE; __VMALLOC_RESERVE += reserve; -#endif } pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h index 952b3ee3c9bb..d304ab4161ff 100644 --- a/include/asm-i386/elf.h +++ b/include/asm-i386/elf.h @@ -133,39 +133,31 @@ extern int dump_task_extended_fpu (struct task_struct *, struct user_fxsr_struct #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs) #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO)) -#define VDSO_BASE ((unsigned long)current->mm->context.vdso) - -#ifdef CONFIG_COMPAT_VDSO -# define VDSO_COMPAT_BASE VDSO_HIGH_BASE -# define VDSO_PRELINK VDSO_HIGH_BASE -#else -# define VDSO_COMPAT_BASE VDSO_BASE -# define VDSO_PRELINK 0 -#endif +#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso) +#define VDSO_PRELINK 0 #define VDSO_SYM(x) \ - (VDSO_COMPAT_BASE + (unsigned long)(x) - VDSO_PRELINK) + (VDSO_CURRENT_BASE + (unsigned long)(x) - VDSO_PRELINK) #define VDSO_HIGH_EHDR ((const struct elfhdr *) VDSO_HIGH_BASE) -#define VDSO_EHDR ((const struct elfhdr *) VDSO_COMPAT_BASE) +#define VDSO_EHDR ((const struct elfhdr *) VDSO_CURRENT_BASE) extern void __kernel_vsyscall; #define VDSO_ENTRY VDSO_SYM(&__kernel_vsyscall) -#ifndef CONFIG_COMPAT_VDSO -#define ARCH_HAS_SETUP_ADDITIONAL_PAGES struct linux_binprm; + +#define ARCH_HAS_SETUP_ADDITIONAL_PAGES extern int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack); -#endif extern unsigned int vdso_enabled; -#define ARCH_DLINFO \ -do if (vdso_enabled) { \ - NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ - NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_COMPAT_BASE); \ +#define ARCH_DLINFO \ +do if (vdso_enabled) { \ + NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ + NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \ } while (0) #endif diff --git a/include/asm-i386/fixmap.h b/include/asm-i386/fixmap.h index 3e9f610c35df..e5651b2a585a 100644 --- a/include/asm-i386/fixmap.h +++ b/include/asm-i386/fixmap.h @@ -19,13 +19,9 @@ * Leave one empty page between vmalloc'ed areas and * the start of the fixmap. */ -#ifndef CONFIG_COMPAT_VDSO extern unsigned long __FIXADDR_TOP; -#else -#define __FIXADDR_TOP 0xfffff000 -#define FIXADDR_USER_START __fix_to_virt(FIX_VDSO) -#define FIXADDR_USER_END __fix_to_virt(FIX_VDSO - 1) -#endif +#define FIXADDR_USER_START __fix_to_virt(FIX_VDSO) +#define FIXADDR_USER_END __fix_to_virt(FIX_VDSO - 1) #ifndef __ASSEMBLY__ #include diff --git a/include/linux/elf.h b/include/linux/elf.h index 60713e6ea297..8b17ffe222c4 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -83,6 +83,23 @@ typedef __s64 Elf64_Sxword; #define DT_DEBUG 21 #define DT_TEXTREL 22 #define DT_JMPREL 23 +#define DT_ENCODING 32 +#define OLD_DT_LOOS 0x60000000 +#define DT_LOOS 0x6000000d +#define DT_HIOS 0x6ffff000 +#define DT_VALRNGLO 0x6ffffd00 +#define DT_VALRNGHI 0x6ffffdff +#define DT_ADDRRNGLO 0x6ffffe00 +#define DT_ADDRRNGHI 0x6ffffeff +#define DT_VERSYM 0x6ffffff0 +#define DT_RELACOUNT 0x6ffffff9 +#define DT_RELCOUNT 0x6ffffffa +#define DT_FLAGS_1 0x6ffffffb +#define DT_VERDEF 0x6ffffffc +#define DT_VERDEFNUM 0x6ffffffd +#define DT_VERNEED 0x6ffffffe +#define DT_VERNEEDNUM 0x6fffffff +#define OLD_DT_HIOS 0x6fffffff #define DT_LOPROC 0x70000000 #define DT_HIPROC 0x7fffffff -- cgit v1.2.3-59-g8ed1b From 1dbf527c51c6c20c19869c8125cb5b87c3d09506 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:12 +0200 Subject: [PATCH] i386: Make COMPAT_VDSO runtime selectable. Now that relocation of the VDSO for COMPAT_VDSO users is done at runtime rather than compile time, it is possible to enable/disable compat mode at runtime. This patch allows you to enable COMPAT_VDSO mode with "vdso=2" on the kernel command line, or via sysctl. (Switching on a running system shouldn't be done lightly; any process which was relying on the compat VDSO will be upset if it goes away.) The COMPAT_VDSO config option still exists, but if enabled it just makes vdso_enabled default to VDSO_COMPAT. +From: Hugh Dickins Fix oops from i386-make-compat_vdso-runtime-selectable.patch. Even mingetty at system startup finds it easy to trigger an oops while reading /proc/PID/maps: though it has a good hold on the mm itself, that cannot stop exit_mm() from resetting tsk->mm to NULL. (It is usually show_map()'s call to get_gate_vma() which oopses, and I expect we could change that to check priv->tail_vma instead; but no matter, even m_start()'s call just after get_task_mm() is racy.) Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Zachary Amsden Cc: "Jan Beulich" Cc: Eric W. Biederman Cc: Andi Kleen Cc: Ingo Molnar Cc: Roland McGrath --- Documentation/kernel-parameters.txt | 1 + arch/i386/kernel/sysenter.c | 145 +++++++++++++++++++++++------------- include/asm-i386/page.h | 2 - 3 files changed, 95 insertions(+), 53 deletions(-) (limited to 'arch') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 84c3bd05c639..4287696f18dd 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1820,6 +1820,7 @@ and is between 256 and 4096 characters. It is defined in the file [USBHID] The interval which mice are to be polled at. vdso= [IA-32,SH] + vdso=2: enable compat VDSO (default with COMPAT_VDSO) vdso=1: enable VDSO (default) vdso=0: disable VDSO mapping diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c index e5a958379ac9..0b9768ee1e8d 100644 --- a/arch/i386/kernel/sysenter.c +++ b/arch/i386/kernel/sysenter.c @@ -23,16 +23,25 @@ #include #include #include +#include + +enum { + VDSO_DISABLED = 0, + VDSO_ENABLED = 1, + VDSO_COMPAT = 2, +}; + +#ifdef CONFIG_COMPAT_VDSO +#define VDSO_DEFAULT VDSO_COMPAT +#else +#define VDSO_DEFAULT VDSO_ENABLED +#endif /* * Should the kernel map a VDSO page into processes and pass its * address down to glibc upon exec()? */ -#ifdef CONFIG_PARAVIRT -unsigned int __read_mostly vdso_enabled = 0; -#else -unsigned int __read_mostly vdso_enabled = 1; -#endif +unsigned int __read_mostly vdso_enabled = VDSO_DEFAULT; EXPORT_SYMBOL_GPL(vdso_enabled); @@ -47,7 +56,6 @@ __setup("vdso=", vdso_setup); extern asmlinkage void sysenter_entry(void); -#ifdef CONFIG_COMPAT_VDSO static __init void reloc_symtab(Elf32_Ehdr *ehdr, unsigned offset, unsigned size) { @@ -164,11 +172,6 @@ static __init void relocate_vdso(Elf32_Ehdr *ehdr) shdr[i].sh_size); } } -#else -static inline void relocate_vdso(Elf32_Ehdr *ehdr) -{ -} -#endif /* COMPAT_VDSO */ void enable_sep_cpu(void) { @@ -188,6 +191,25 @@ void enable_sep_cpu(void) put_cpu(); } +static struct vm_area_struct gate_vma; + +static int __init gate_vma_init(void) +{ + gate_vma.vm_mm = NULL; + gate_vma.vm_start = FIXADDR_USER_START; + gate_vma.vm_end = FIXADDR_USER_END; + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC; + gate_vma.vm_page_prot = __P101; + /* + * Make sure the vDSO gets into every core dump. + * Dumping its contents makes post-mortem fully interpretable later + * without matching up the same kernel and hardware config to see + * what PC values meant. + */ + gate_vma.vm_flags |= VM_ALWAYSDUMP; + return 0; +} + /* * These symbols are defined by vsyscall.o to mark the bounds * of the ELF DSO images included therein. @@ -196,6 +218,22 @@ extern const char vsyscall_int80_start, vsyscall_int80_end; extern const char vsyscall_sysenter_start, vsyscall_sysenter_end; static struct page *syscall_pages[1]; +static void map_compat_vdso(int map) +{ + static int vdso_mapped; + + if (map == vdso_mapped) + return; + + vdso_mapped = map; + + __set_fixmap(FIX_VDSO, page_to_pfn(syscall_pages[0]) << PAGE_SHIFT, + map ? PAGE_READONLY_EXEC : PAGE_NONE); + + /* flush stray tlbs */ + flush_tlb_all(); +} + int __init sysenter_setup(void) { void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); @@ -204,10 +242,9 @@ int __init sysenter_setup(void) syscall_pages[0] = virt_to_page(syscall_page); -#ifdef CONFIG_COMPAT_VDSO - __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY_EXEC); + gate_vma_init(); + printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO)); -#endif if (!boot_cpu_has(X86_FEATURE_SEP)) { vsyscall = &vsyscall_int80_start; @@ -226,42 +263,57 @@ int __init sysenter_setup(void) /* Defined in vsyscall-sysenter.S */ extern void SYSENTER_RETURN; -#ifdef __HAVE_ARCH_GATE_AREA /* Setup a VMA at program startup for the vsyscall page */ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) { struct mm_struct *mm = current->mm; unsigned long addr; int ret; + bool compat; down_write(&mm->mmap_sem); - addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); - if (IS_ERR_VALUE(addr)) { - ret = addr; - goto up_fail; - } - /* - * MAYWRITE to allow gdb to COW and set breakpoints - * - * Make sure the vDSO gets into every core dump. - * Dumping its contents makes post-mortem fully interpretable later - * without matching up the same kernel and hardware config to see - * what PC values meant. - */ - ret = install_special_mapping(mm, addr, PAGE_SIZE, - VM_READ|VM_EXEC| - VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| - VM_ALWAYSDUMP, - syscall_pages); - if (ret) - goto up_fail; + /* Test compat mode once here, in case someone + changes it via sysctl */ + compat = (vdso_enabled == VDSO_COMPAT); + + map_compat_vdso(compat); + + if (compat) + addr = VDSO_HIGH_BASE; + else { + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); + if (IS_ERR_VALUE(addr)) { + ret = addr; + goto up_fail; + } + + /* + * MAYWRITE to allow gdb to COW and set breakpoints + * + * Make sure the vDSO gets into every core dump. + * Dumping its contents makes post-mortem fully + * interpretable later without matching up the same + * kernel and hardware config to see what PC values + * meant. + */ + ret = install_special_mapping(mm, addr, PAGE_SIZE, + VM_READ|VM_EXEC| + VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| + VM_ALWAYSDUMP, + syscall_pages); + + if (ret) + goto up_fail; + } current->mm->context.vdso = (void *)addr; current_thread_info()->sysenter_return = - (void *)VDSO_SYM(&SYSENTER_RETURN); -up_fail: + (void *)VDSO_SYM(&SYSENTER_RETURN); + + up_fail: up_write(&mm->mmap_sem); + return ret; } @@ -274,6 +326,11 @@ const char *arch_vma_name(struct vm_area_struct *vma) struct vm_area_struct *get_gate_vma(struct task_struct *tsk) { + struct mm_struct *mm = tsk->mm; + + /* Check to see if this task was created in compat vdso mode */ + if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE) + return &gate_vma; return NULL; } @@ -286,17 +343,3 @@ int in_gate_area_no_task(unsigned long addr) { return 0; } -#else /* !__HAVE_ARCH_GATE_AREA */ -int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) -{ - /* - * If not creating userspace VMA, simply set vdso to point to - * fixmap page. - */ - current->mm->context.vdso = (void *)VDSO_HIGH_BASE; - current_thread_info()->sysenter_return = - (void *)VDSO_SYM(&SYSENTER_RETURN); - - return 0; -} -#endif /* __HAVE_ARCH_GATE_AREA */ diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h index 7b19f454761d..fd3f64ace248 100644 --- a/include/asm-i386/page.h +++ b/include/asm-i386/page.h @@ -143,9 +143,7 @@ extern int page_is_ram(unsigned long pagenr); #include #include -#ifndef CONFIG_COMPAT_VDSO #define __HAVE_ARCH_GATE_AREA 1 -#endif #endif /* __KERNEL__ */ #endif /* _I386_PAGE_H */ -- cgit v1.2.3-59-g8ed1b From c169859d6dfc7471ef9f2dbd720936e17906a084 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:12 +0200 Subject: [PATCH] x86-64: Clean up asm-x86_64/bugs.h Most of asm-x86_64/bugs.h is code which should be in a C file, so put it there. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Linus Torvalds --- arch/x86_64/kernel/Makefile | 2 +- arch/x86_64/kernel/bugs.c | 28 ++++++++++++++++++++++++++++ include/asm-x86_64/alternative.h | 1 + include/asm-x86_64/bugs.h | 30 ++++-------------------------- 4 files changed, 34 insertions(+), 27 deletions(-) create mode 100644 arch/x86_64/kernel/bugs.c (limited to 'arch') diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index 6879b4f01e88..a613e13d0e75 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile @@ -8,7 +8,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \ x8664_ksyms.o i387.o syscall.o vsyscall.o \ setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \ - pci-dma.o pci-nommu.o alternative.o hpet.o tsc.o + pci-dma.o pci-nommu.o alternative.o hpet.o tsc.o bugs.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_X86_MCE) += mce.o therm_throt.o diff --git a/arch/x86_64/kernel/bugs.c b/arch/x86_64/kernel/bugs.c new file mode 100644 index 000000000000..131e541e3f7b --- /dev/null +++ b/arch/x86_64/kernel/bugs.c @@ -0,0 +1,28 @@ +/* + * arch/x86_64/kernel/bugs.c + * + * Copyright (C) 1994 Linus Torvalds + * Copyright (C) 2000 SuSE + * + * This is included by init/main.c to check for architecture-dependent bugs. + * + * Needs: + * void check_bugs(void); + */ + +#include +#include +#include +#include +#include +#include + +void __init check_bugs(void) +{ + identify_cpu(&boot_cpu_data); +#if !defined(CONFIG_SMP) + printk("CPU: "); + print_cpu_info(&boot_cpu_data); +#endif + alternative_instructions(); +} diff --git a/include/asm-x86_64/alternative.h b/include/asm-x86_64/alternative.h index a6657b4f3e0e..67ebea3cc481 100644 --- a/include/asm-x86_64/alternative.h +++ b/include/asm-x86_64/alternative.h @@ -16,6 +16,7 @@ struct alt_instr { u8 pad[5]; }; +extern void alternative_instructions(void); extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end); struct module; diff --git a/include/asm-x86_64/bugs.h b/include/asm-x86_64/bugs.h index d86c5dd689fa..b33dc04d8f42 100644 --- a/include/asm-x86_64/bugs.h +++ b/include/asm-x86_64/bugs.h @@ -1,28 +1,6 @@ -/* - * include/asm-x86_64/bugs.h - * - * Copyright (C) 1994 Linus Torvalds - * Copyright (C) 2000 SuSE - * - * This is included by init/main.c to check for architecture-dependent bugs. - * - * Needs: - * void check_bugs(void); - */ +#ifndef _ASM_X86_64_BUGS_H +#define _ASM_X86_64_BUGS_H -#include -#include -#include -#include +void check_bugs(void); -extern void alternative_instructions(void); - -static void __init check_bugs(void) -{ - identify_cpu(&boot_cpu_data); -#if !defined(CONFIG_SMP) - printk("CPU: "); - print_cpu_info(&boot_cpu_data); -#endif - alternative_instructions(); -} +#endif /* _ASM_X86_64_BUGS_H */ -- cgit v1.2.3-59-g8ed1b From f039b754714a422959027cb18bb33760eb8153f0 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:12 +0200 Subject: [PATCH] x86: Don't use MWAIT on AMD Family 10 It doesn't put the CPU into deeper sleep states, so it's better to use the standard idle loop to save power. But allow to reenable it anyways for benchmarking. I also removed the obsolete idle=halt on i386 Cc: andreas.herrmann@amd.com Signed-off-by: Andi Kleen --- Documentation/kernel-parameters.txt | 11 +++++++++-- arch/i386/kernel/cpu/amd.c | 5 +++++ arch/i386/kernel/process.c | 17 ++++++++--------- arch/x86_64/kernel/process.c | 12 +++++++----- arch/x86_64/kernel/setup.c | 6 ++++++ include/asm-i386/processor.h | 2 ++ include/asm-x86_64/proto.h | 2 ++ 7 files changed, 39 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 4287696f18dd..94ce0d20253d 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -695,8 +695,15 @@ and is between 256 and 4096 characters. It is defined in the file idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed See Documentation/ide.txt. - idle= [HW] - Format: idle=poll or idle=halt + idle= [X86] + Format: idle=poll or idle=mwait + Poll forces a polling idle loop that can slightly improves the performance + of waking up a idle CPU, but will use a lot of power and make the system + run hot. Not recommended. + idle=mwait. On systems which support MONITOR/MWAIT but the kernel chose + to not use it because it doesn't save as much power as a normal idle + loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same + as idle=poll. ignore_loglevel [KNL] Ignore loglevel setting - this will print /all/ diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index 2d47db482972..197cda62caa3 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c @@ -53,6 +53,8 @@ static __cpuinit int amd_apic_timer_broken(void) return 0; } +int force_mwait __cpuinitdata; + static void __cpuinit init_amd(struct cpuinfo_x86 *c) { u32 l, h; @@ -275,6 +277,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) if (amd_apic_timer_broken()) set_bit(X86_FEATURE_LAPIC_TIMER_BROKEN, c->x86_capability); + + if (c->x86 == 0x10 && !force_mwait) + clear_bit(X86_FEATURE_MWAIT, c->x86_capability); } static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 393a67d5d943..7e8e129b3d7d 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -272,25 +272,24 @@ void __devinit select_idle_routine(const struct cpuinfo_x86 *c) } } -static int __init idle_setup (char *str) +static int __init idle_setup(char *str) { - if (!strncmp(str, "poll", 4)) { + if (!strcmp(str, "poll")) { printk("using polling idle threads.\n"); pm_idle = poll_idle; #ifdef CONFIG_X86_SMP if (smp_num_siblings > 1) printk("WARNING: polling idle and HT enabled, performance may degrade.\n"); #endif - } else if (!strncmp(str, "halt", 4)) { - printk("using halt in idle threads.\n"); - pm_idle = default_idle; - } + } else if (!strcmp(str, "mwait")) + force_mwait = 1; + else + return -1; boot_option_idle_override = 1; - return 1; + return 0; } - -__setup("idle=", idle_setup); +early_param("idle", idle_setup); void show_regs(struct pt_regs * regs) { diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index d8d5ccc245c8..4f21765078b7 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -288,16 +288,18 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) static int __init idle_setup (char *str) { - if (!strncmp(str, "poll", 4)) { + if (!strcmp(str, "poll")) { printk("using polling idle threads.\n"); pm_idle = poll_idle; - } + } else if (!strcmp(str, "mwait")) + force_mwait = 1; + else + return -1; boot_option_idle_override = 1; - return 1; + return 0; } - -__setup("idle=", idle_setup); +early_param("idle", idle_setup); /* Prints also some state that isn't saved in the pt_regs */ void __show_regs(struct pt_regs * regs) diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 0a1d539149df..db30b5bcef61 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -79,6 +79,8 @@ int bootloader_type; unsigned long saved_video_mode; +int force_mwait __cpuinitdata; + /* * Early DMI memory */ @@ -604,6 +606,10 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) /* RDTSC can be speculated around */ clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); + + /* Family 10 doesn't support C states in MWAIT so don't use it */ + if (c->x86 == 0x10 && !force_mwait) + clear_bit(X86_FEATURE_MWAIT, &c->x86_capability); } static void __cpuinit detect_ht(struct cpuinfo_x86 *c) diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 9d895cc2f312..882d3f8fbbac 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -779,4 +779,6 @@ extern int sysenter_setup(void); extern void cpu_set_gdt(int); extern void cpu_init(void); +extern int force_mwait; + #endif /* __ASM_I386_PROCESSOR_H */ diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index 3f8f285138d2..98063bcb3b33 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h @@ -119,6 +119,8 @@ extern int gsi_irq_sharing(int gsi); extern void smp_local_timer_interrupt(void); +extern int force_mwait; + long do_arch_prctl(struct task_struct *task, int code, unsigned long addr); void i8254_timer_resume(void); -- cgit v1.2.3-59-g8ed1b From 7946331856f99bdb00b0a0a53e97d9b621546622 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 2 May 2007 19:27:12 +0200 Subject: [PATCH] i386: Use menuconfig objects - APM (I hope Andi is the right one to Cc, otherwise please add, thanks!) Use menuconfigs instead of menus, so the whole menu can be disabled at once instead of going through all options. Signed-off-by: Jan Engelhardt Signed-off-by: Andi Kleen --- arch/i386/Kconfig | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index c0a3e233fa3f..6964e247f473 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -915,12 +915,9 @@ source kernel/power/Kconfig source "drivers/acpi/Kconfig" -menu "APM (Advanced Power Management) BIOS Support" -depends on PM && !X86_VISWS - -config APM +menuconfig APM tristate "APM (Advanced Power Management) BIOS support" - depends on PM + depends on PM && !X86_VISWS ---help--- APM is a BIOS specification for saving power using several different techniques. This is mostly useful for battery powered laptops with @@ -977,9 +974,10 @@ config APM To compile this driver as a module, choose M here: the module will be called apm. +if APM + config APM_IGNORE_USER_SUSPEND bool "Ignore USER SUSPEND" - depends on APM help This option will ignore USER SUSPEND requests. On machines with a compliant APM BIOS, you want to say N. However, on the NEC Versa M @@ -987,7 +985,6 @@ config APM_IGNORE_USER_SUSPEND config APM_DO_ENABLE bool "Enable PM at boot time" - depends on APM ---help--- Enable APM features at boot time. From page 36 of the APM BIOS specification: "When disabled, the APM BIOS does not automatically @@ -1005,7 +1002,6 @@ config APM_DO_ENABLE config APM_CPU_IDLE bool "Make CPU Idle calls when idle" - depends on APM help Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop. On some machines, this can activate improved power savings, such as @@ -1017,7 +1013,6 @@ config APM_CPU_IDLE config APM_DISPLAY_BLANK bool "Enable console blanking using APM" - depends on APM help Enable console blanking using the APM. Some laptops can use this to turn off the LCD backlight when the screen blanker of the Linux @@ -1031,7 +1026,6 @@ config APM_DISPLAY_BLANK config APM_ALLOW_INTS bool "Allow interrupts during APM BIOS calls" - depends on APM help Normally we disable external interrupts while we are making calls to the APM BIOS as a measure to lessen the effects of a badly behaving @@ -1042,13 +1036,12 @@ config APM_ALLOW_INTS config APM_REAL_MODE_POWER_OFF bool "Use real mode APM BIOS call to power off" - depends on APM help Use real mode APM BIOS calls to switch off the computer. This is a work-around for a number of buggy BIOSes. Switch this option on if your computer crashes instead of powering off properly. -endmenu +endif # APM source "arch/i386/kernel/cpu/cpufreq/Kconfig" -- cgit v1.2.3-59-g8ed1b From d479d2cc0802d5c8546a6a7492646e08228effd5 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:12 +0200 Subject: [PATCH] i386: Update smp_call_function* comments Update documentation for i386 smp_call_function* functions. As reported by Randy Dunlap [ I've posted this before but it seems to have been lost along the way. ] Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Randy Dunlap --- arch/i386/kernel/smp.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index fe38b49a1223..9d84f6f001bf 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -554,8 +554,10 @@ static void __smp_call_function(void (*func) (void *info), void *info, * @info: An arbitrary pointer to pass to the function. * @wait: If true, wait (atomically) until function has completed on other CPUs. * - * Returns 0 on success, else a negative status code. Does not return until - * remote CPUs are nearly ready to execute <> or are or have finished. + * Returns 0 on success, else a negative status code. + * + * If @wait is true, then returns once @func has returned; otherwise + * it returns just before the target cpu calls @func. * * You must not call this function with disabled interrupts or from a * hardware interrupt handler or from a bottom half handler. @@ -617,11 +619,13 @@ int native_smp_call_function_mask(cpumask_t mask, * smp_call_function(): Run a function on all other CPUs. * @func: The function to run. This must be fast and non-blocking. * @info: An arbitrary pointer to pass to the function. - * @nonatomic: currently unused. + * @nonatomic: Unused. * @wait: If true, wait (atomically) until function has completed on other CPUs. * - * Returns 0 on success, else a negative status code. Does not return until - * remote CPUs are nearly ready to execute <> or are or have executed. + * Returns 0 on success, else a negative status code. + * + * If @wait is true, then returns once @func has returned; otherwise + * it returns just before the target cpu calls @func. * * You must not call this function with disabled interrupts or from a * hardware interrupt handler or from a bottom half handler. @@ -633,17 +637,18 @@ int smp_call_function(void (*func) (void *info), void *info, int nonatomic, } EXPORT_SYMBOL(smp_call_function); -/* +/** * smp_call_function_single - Run a function on another CPU + * @cpu: The target CPU. Cannot be the calling CPU. * @func: The function to run. This must be fast and non-blocking. * @info: An arbitrary pointer to pass to the function. - * @nonatomic: Currently unused. + * @nonatomic: Unused. * @wait: If true, wait until function has completed on other CPUs. * - * Retrurns 0 on success, else a negative status code. + * Returns 0 on success, else a negative status code. * - * Does not return until the remote CPU is nearly ready to execute - * or is or has executed. + * If @wait is true, then returns once @func has returned; otherwise + * it returns just before the target cpu calls @func. */ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int nonatomic, int wait) -- cgit v1.2.3-59-g8ed1b From de90c5ce832b1218042316260ff9268b00fdcba3 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:12 +0200 Subject: [PATCH] i386: Enable bank 0 on non K7 Athlon As a bug workaround bank 0 on K7s is normally disabled, but no need to do that on other AMD CPUs. Cc: davej@redhat.com Signed-off-by: Andi Kleen --- arch/i386/kernel/cpu/mcheck/k7.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/mcheck/k7.c b/arch/i386/kernel/cpu/mcheck/k7.c index b0862af595aa..7a2472557bbb 100644 --- a/arch/i386/kernel/cpu/mcheck/k7.c +++ b/arch/i386/kernel/cpu/mcheck/k7.c @@ -82,9 +82,13 @@ void amd_mcheck_init(struct cpuinfo_x86 *c) nr_mce_banks = l & 0xff; /* Clear status for MC index 0 separately, we don't touch CTL, - * as some Athlons cause spurious MCEs when its enabled. */ - wrmsr (MSR_IA32_MC0_STATUS, 0x0, 0x0); - for (i=1; i Date: Wed, 2 May 2007 19:27:12 +0200 Subject: [PATCH] x86: Allow percpu variables to be page-aligned Let's allow page-alignment in general for per-cpu data (wanted by Xen, and Ingo suggested KVM as well). Because larger alignments can use more room, we increase the max per-cpu memory to 64k rather than 32k: it's getting a little tight. Signed-off-by: Rusty Russell Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Acked-by: Ingo Molnar Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/alpha/kernel/vmlinux.lds.S | 2 +- arch/arm/kernel/vmlinux.lds.S | 2 +- arch/cris/arch-v32/vmlinux.lds.S | 1 + arch/frv/kernel/vmlinux.lds.S | 1 + arch/i386/kernel/vmlinux.lds.S | 2 +- arch/m32r/kernel/vmlinux.lds.S | 2 +- arch/mips/kernel/vmlinux.lds.S | 2 +- arch/parisc/kernel/vmlinux.lds.S | 2 +- arch/powerpc/kernel/setup_64.c | 4 ++-- arch/powerpc/kernel/vmlinux.lds.S | 6 +----- arch/ppc/kernel/vmlinux.lds.S | 2 +- arch/s390/kernel/vmlinux.lds.S | 2 +- arch/sh/kernel/vmlinux.lds.S | 2 +- arch/sh64/kernel/vmlinux.lds.S | 2 +- arch/sparc/kernel/vmlinux.lds.S | 2 +- arch/sparc64/kernel/smp.c | 6 +++--- arch/x86_64/kernel/setup64.c | 4 ++-- arch/x86_64/kernel/vmlinux.lds.S | 2 +- arch/xtensa/kernel/vmlinux.lds.S | 2 +- init/main.c | 8 ++------ kernel/module.c | 8 ++++---- 21 files changed, 29 insertions(+), 35 deletions(-) (limited to 'arch') diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S index 4cc44bd33d33..cf1e6fc6c686 100644 --- a/arch/alpha/kernel/vmlinux.lds.S +++ b/arch/alpha/kernel/vmlinux.lds.S @@ -69,7 +69,7 @@ SECTIONS . = ALIGN(8); SECURITY_INIT - . = ALIGN(64); + . = ALIGN(8192); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index ddbdad48f5b2..d1a6a597ed9a 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -59,7 +59,7 @@ SECTIONS usr/built-in.o(.init.ramfs) __initramfs_end = .; #endif - . = ALIGN(64); + . = ALIGN(4096); __per_cpu_start = .; *(.data.percpu) __per_cpu_end = .; diff --git a/arch/cris/arch-v32/vmlinux.lds.S b/arch/cris/arch-v32/vmlinux.lds.S index e124fcd766d5..dfa25e1542b9 100644 --- a/arch/cris/arch-v32/vmlinux.lds.S +++ b/arch/cris/arch-v32/vmlinux.lds.S @@ -91,6 +91,7 @@ SECTIONS } SECURITY_INIT + . = ALIGN (8192); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S index 97910e016825..28eae9735ad6 100644 --- a/arch/frv/kernel/vmlinux.lds.S +++ b/arch/frv/kernel/vmlinux.lds.S @@ -57,6 +57,7 @@ SECTIONS __alt_instructions_end = .; .altinstr_replacement : { *(.altinstr_replacement) } + . = ALIGN(4096); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index f4ec72231835..97fe6eac47c9 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -194,7 +194,7 @@ SECTIONS __initramfs_end = .; } #endif - . = ALIGN(L1_CACHE_BYTES); + . = ALIGN(4096); .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { __per_cpu_start = .; *(.data.percpu) diff --git a/arch/m32r/kernel/vmlinux.lds.S b/arch/m32r/kernel/vmlinux.lds.S index 439cc257cd1d..6c73bca3f478 100644 --- a/arch/m32r/kernel/vmlinux.lds.S +++ b/arch/m32r/kernel/vmlinux.lds.S @@ -110,7 +110,7 @@ SECTIONS __initramfs_end = .; #endif - . = ALIGN(32); + . = ALIGN(4096); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index c76b793310c2..043f637e3d10 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -119,7 +119,7 @@ SECTIONS .init.ramfs : { *(.init.ramfs) } __initramfs_end = .; #endif - . = ALIGN(32); + . = ALIGN(_PAGE_SIZE); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index 2a8253358c6c..c74585990598 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -181,7 +181,7 @@ SECTIONS .init.ramfs : { *(.init.ramfs) } __initramfs_end = .; #endif - . = ALIGN(32); + . = ALIGN(ASM_PAGE_SIZE); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 22083ce3cc30..6018178708a5 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -582,14 +582,14 @@ void __init setup_per_cpu_areas(void) char *ptr; /* Copy section for each CPU (we discard the original) */ - size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES); + size = ALIGN(__per_cpu_end - __per_cpu_start, PAGE_SIZE); #ifdef CONFIG_MODULES if (size < PERCPU_ENOUGH_ROOM) size = PERCPU_ENOUGH_ROOM; #endif for_each_possible_cpu(i) { - ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size); + ptr = alloc_bootmem_pages_node(NODE_DATA(cpu_to_node(i)), size); if (!ptr) panic("Cannot allocate cpu data for CPU %d\n", i); diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 7eefeb4a30e7..132067313147 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -139,11 +139,7 @@ SECTIONS __initramfs_end = .; } #endif -#ifdef CONFIG_PPC32 - . = ALIGN(32); -#else - . = ALIGN(128); -#endif + . = ALIGN(PAGE_SIZE); .data.percpu : { __per_cpu_start = .; *(.data.percpu) diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S index a0625562a44b..44cd128fb719 100644 --- a/arch/ppc/kernel/vmlinux.lds.S +++ b/arch/ppc/kernel/vmlinux.lds.S @@ -130,7 +130,7 @@ SECTIONS __ftr_fixup : { *(__ftr_fixup) } __stop___ftr_fixup = .; - . = ALIGN(32); + . = ALIGN(4096); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 418f6426a949..e9d3432aba60 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -107,7 +107,7 @@ SECTIONS . = ALIGN(2); __initramfs_end = .; #endif - . = ALIGN(256); + . = ALIGN(4096); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 78a6c09875b2..2f606d0ce1f6 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -54,7 +54,7 @@ SECTIONS . = ALIGN(PAGE_SIZE); .data.page_aligned : { *(.data.page_aligned) } - . = ALIGN(L1_CACHE_BYTES); + . = ALIGN(PAGE_SIZE); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/arch/sh64/kernel/vmlinux.lds.S b/arch/sh64/kernel/vmlinux.lds.S index a59c5e998131..4f9616f39830 100644 --- a/arch/sh64/kernel/vmlinux.lds.S +++ b/arch/sh64/kernel/vmlinux.lds.S @@ -85,7 +85,7 @@ SECTIONS . = ALIGN(PAGE_SIZE); .data.page_aligned : C_PHYS(.data.page_aligned) { *(.data.page_aligned) } - . = ALIGN(L1_CACHE_BYTES); + . = ALIGN(PAGE_SIZE); __per_cpu_start = .; .data.percpu : C_PHYS(.data.percpu) { *(.data.percpu) } __per_cpu_end = . ; diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index e5c24e0521de..f0bb6e60e620 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -65,7 +65,7 @@ SECTIONS __initramfs_end = .; #endif - . = ALIGN(32); + . = ALIGN(4096); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index d4f0a70f4845..1fac215252e4 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -1343,11 +1343,11 @@ void __init setup_per_cpu_areas(void) /* Copy section for each CPU (we discard the original) */ goal = PERCPU_ENOUGH_ROOM; - __per_cpu_shift = 0; - for (size = 1UL; size < goal; size <<= 1UL) + __per_cpu_shift = PAGE_SHIFT; + for (size = PAGE_SIZE; size < goal; size <<= 1UL) __per_cpu_shift++; - ptr = alloc_bootmem(size * NR_CPUS); + ptr = alloc_bootmem_pages(size * NR_CPUS); __per_cpu_base = ptr - __per_cpu_start; diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c index 53064a9a365f..64379a80d763 100644 --- a/arch/x86_64/kernel/setup64.c +++ b/arch/x86_64/kernel/setup64.c @@ -103,9 +103,9 @@ void __init setup_per_cpu_areas(void) if (!NODE_DATA(cpu_to_node(i))) { printk("cpu with no node %d, num_online_nodes %d\n", i, num_online_nodes()); - ptr = alloc_bootmem(size); + ptr = alloc_bootmem_pages(size); } else { - ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size); + ptr = alloc_bootmem_pages_node(NODE_DATA(cpu_to_node(i)), size); } if (!ptr) panic("Cannot allocate cpu data for CPU %d\n", i); diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 3bdeb88d28f4..7ef0b8820cd2 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -195,7 +195,7 @@ SECTIONS __initramfs_end = .; #endif - . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); + . = ALIGN(4096); __per_cpu_start = .; .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } __per_cpu_end = .; diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index ab6370054cee..4fbd66a52a88 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -198,7 +198,7 @@ SECTIONS __ftr_fixup : { *(__ftr_fixup) } __stop___ftr_fixup = .; - . = ALIGN(32); + . = ALIGN(4096); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/init/main.c b/init/main.c index a92989e7836a..80f09f31bfab 100644 --- a/init/main.c +++ b/init/main.c @@ -369,12 +369,8 @@ static void __init setup_per_cpu_areas(void) unsigned long nr_possible_cpus = num_possible_cpus(); /* Copy section for each CPU (we discard the original) */ - size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES); -#ifdef CONFIG_MODULES - if (size < PERCPU_ENOUGH_ROOM) - size = PERCPU_ENOUGH_ROOM; -#endif - ptr = alloc_bootmem(size * nr_possible_cpus); + size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE); + ptr = alloc_bootmem_pages(size * nr_possible_cpus); for_each_possible_cpu(i) { __per_cpu_offset[i] = ptr - __per_cpu_start; diff --git a/kernel/module.c b/kernel/module.c index cf49ca25fcce..4dc4a257545c 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -346,10 +346,10 @@ static void *percpu_modalloc(unsigned long size, unsigned long align, unsigned int i; void *ptr; - if (align > SMP_CACHE_BYTES) { - printk(KERN_WARNING "%s: per-cpu alignment %li > %i\n", - name, align, SMP_CACHE_BYTES); - align = SMP_CACHE_BYTES; + if (align > PAGE_SIZE) { + printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n", + name, align, PAGE_SIZE); + align = PAGE_SIZE; } ptr = __per_cpu_start; -- cgit v1.2.3-59-g8ed1b From d0175ab64412aabc93da8682aaa99124d6815056 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:13 +0200 Subject: [PATCH] i386: Remove smp_alt_instructions The .smp_altinstructions section and its corresponding symbols are completely unused, so remove them. Also, remove stray #ifdef __KENREL__ in asm-i386/alternative.h Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Andi Kleen --- arch/i386/kernel/alternative.c | 38 ++------------------------------------ arch/i386/kernel/vmlinux.lds.S | 11 ----------- include/asm-i386/alternative.h | 6 +----- 3 files changed, 3 insertions(+), 52 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index a27c8d347364..f09635408049 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -132,11 +132,8 @@ static void nop_out(void *insns, unsigned int len) } extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; -extern struct alt_instr __smp_alt_instructions[], __smp_alt_instructions_end[]; extern u8 *__smp_locks[], *__smp_locks_end[]; -extern u8 __smp_alt_begin[], __smp_alt_end[]; - /* Replace instructions with better alternatives for this CPU type. This runs before SMP is initialized to avoid SMP problems with self modifying code. This implies that assymetric systems where @@ -171,29 +168,6 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end) #ifdef CONFIG_SMP -static void alternatives_smp_save(struct alt_instr *start, struct alt_instr *end) -{ - struct alt_instr *a; - - DPRINTK("%s: alt table %p-%p\n", __FUNCTION__, start, end); - for (a = start; a < end; a++) { - memcpy(a->replacement + a->replacementlen, - a->instr, - a->instrlen); - } -} - -static void alternatives_smp_apply(struct alt_instr *start, struct alt_instr *end) -{ - struct alt_instr *a; - - for (a = start; a < end; a++) { - memcpy(a->instr, - a->replacement + a->replacementlen, - a->instrlen); - } -} - static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) { u8 **ptr; @@ -319,8 +293,6 @@ void alternatives_smp_switch(int smp) printk(KERN_INFO "SMP alternatives: switching to SMP code\n"); clear_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); clear_bit(X86_FEATURE_UP, cpu_data[0].x86_capability); - alternatives_smp_apply(__smp_alt_instructions, - __smp_alt_instructions_end); list_for_each_entry(mod, &smp_alt_modules, next) alternatives_smp_lock(mod->locks, mod->locks_end, mod->text, mod->text_end); @@ -328,8 +300,6 @@ void alternatives_smp_switch(int smp) printk(KERN_INFO "SMP alternatives: switching to UP code\n"); set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability); - apply_alternatives(__smp_alt_instructions, - __smp_alt_instructions_end); list_for_each_entry(mod, &smp_alt_modules, next) alternatives_smp_unlock(mod->locks, mod->locks_end, mod->text, mod->text_end); @@ -396,17 +366,13 @@ void __init alternative_instructions(void) printk(KERN_INFO "SMP alternatives: switching to UP code\n"); set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability); - apply_alternatives(__smp_alt_instructions, - __smp_alt_instructions_end); alternatives_smp_unlock(__smp_locks, __smp_locks_end, _text, _etext); } free_init_pages("SMP alternatives", - __pa_symbol(&__smp_alt_begin), - __pa_symbol(&__smp_alt_end)); + __pa_symbol(&__smp_locks), + __pa_symbol(&__smp_locks_end)); } else { - alternatives_smp_save(__smp_alt_instructions, - __smp_alt_instructions_end); alternatives_smp_module_add(NULL, "core kernel", __smp_locks, __smp_locks_end, _text, _etext); diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 97fe6eac47c9..2ce4aa185fc8 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -117,22 +117,11 @@ SECTIONS /* might get freed after init */ . = ALIGN(4096); - .smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) { - __smp_alt_begin = .; - __smp_alt_instructions = .; - *(.smp_altinstructions) - __smp_alt_instructions_end = .; - } - . = ALIGN(4); .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { __smp_locks = .; *(.smp_locks) __smp_locks_end = .; } - .smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) { - *(.smp_altinstr_replacement) - __smp_alt_end = .; - } /* will be freed after init * Following ALIGN() is required to make sure no other data falls on the * same page where __smp_alt_end is pointing as that page might be freed diff --git a/include/asm-i386/alternative.h b/include/asm-i386/alternative.h index dbc1a29284f3..4d518eebe461 100644 --- a/include/asm-i386/alternative.h +++ b/include/asm-i386/alternative.h @@ -1,8 +1,6 @@ #ifndef _I386_ALTERNATIVE_H #define _I386_ALTERNATIVE_H -#ifdef __KERNEL__ - #include #include #include @@ -32,9 +30,7 @@ static inline void alternatives_smp_module_add(struct module *mod, char *name, void *text, void *text_end) {} static inline void alternatives_smp_module_del(struct module *mod) {} static inline void alternatives_smp_switch(int smp) {} -#endif - -#endif +#endif /* CONFIG_SMP */ /* * Alternative instructions for different CPU types or capabilities. -- cgit v1.2.3-59-g8ed1b From b7fb4af06c18496950a45b365f7a09c47ea64c17 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:13 +0200 Subject: [PATCH] i386: Allow boot-time disable of SMP altinstructions Add "noreplace-smp" to disable SMP instruction replacement. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen --- Documentation/kernel-parameters.txt | 6 ++++++ arch/i386/kernel/alternative.c | 23 +++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 94ce0d20253d..242b3a09b6ce 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1164,6 +1164,9 @@ and is between 256 and 4096 characters. It is defined in the file nomce [IA-32] Machine Check Exception + noreplace-smp [IA-32,SMP] Don't replace SMP instructions + with UP alternatives + noresidual [PPC] Don't use residual data on PReP machines. noresume [SWSUSP] Disables resume and restores original swap @@ -1569,6 +1572,9 @@ and is between 256 and 4096 characters. It is defined in the file smart2= [HW] Format: [,[,...,]] + smp-alt-once [IA-32,SMP] On a hotplug CPU system, only + attempt to substitute SMP alternatives once at boot. + snd-ad1816a= [HW,ALSA] snd-ad1848= [HW,ALSA] diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index f09635408049..9b8e85a8edec 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -5,6 +5,7 @@ #include #include +static int noreplace_smp = 0; static int smp_alt_once = 0; static int debug_alternative = 0; @@ -13,15 +14,23 @@ static int __init bootonly(char *str) smp_alt_once = 1; return 1; } +__setup("smp-alt-boot", bootonly); + static int __init debug_alt(char *str) { debug_alternative = 1; return 1; } - -__setup("smp-alt-boot", bootonly); __setup("debug-alternative", debug_alt); +static int __init setup_noreplace_smp(char *str) +{ + noreplace_smp = 1; + return 1; +} +__setup("noreplace-smp", setup_noreplace_smp); + + #define DPRINTK(fmt, args...) if (debug_alternative) \ printk(KERN_DEBUG fmt, args) @@ -185,6 +194,9 @@ static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end { u8 **ptr; + if (noreplace_smp) + return; + for (ptr = start; ptr < end; ptr++) { if (*ptr < text) continue; @@ -219,6 +231,9 @@ void alternatives_smp_module_add(struct module *mod, char *name, struct smp_alt_module *smp; unsigned long flags; + if (noreplace_smp) + return; + if (smp_alt_once) { if (boot_cpu_has(X86_FEATURE_UP)) alternatives_smp_unlock(locks, locks_end, @@ -253,7 +268,7 @@ void alternatives_smp_module_del(struct module *mod) struct smp_alt_module *item; unsigned long flags; - if (smp_alt_once) + if (smp_alt_once || noreplace_smp) return; spin_lock_irqsave(&smp_alt, flags); @@ -284,7 +299,7 @@ void alternatives_smp_switch(int smp) return; #endif - if (smp_alt_once) + if (noreplace_smp || smp_alt_once) return; BUG_ON(!smp && (num_online_cpus() > 1)); -- cgit v1.2.3-59-g8ed1b From 1c3d99c11c47c8a1a9ed6a46555dbf6520683c52 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 2 May 2007 19:27:13 +0200 Subject: [PATCH] x86-64: Fix x86_64 compilation with DEBUG_SIG on Setting the DEBUG_SIG flag breaks compilation due to a wrong struct access. Aditionally, it raises two warnings. This is one patch to fix them all. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Andi Kleen --- arch/x86_64/kernel/signal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c index 49ec324cd141..c819625f3316 100644 --- a/arch/x86_64/kernel/signal.c +++ b/arch/x86_64/kernel/signal.c @@ -141,7 +141,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) goto badframe; #ifdef DEBUG_SIG - printk("%d sigreturn rip:%lx rsp:%lx frame:%p rax:%lx\n",current->pid,regs.rip,regs.rsp,frame,eax); + printk("%d sigreturn rip:%lx rsp:%lx frame:%p rax:%lx\n",current->pid,regs->rip,regs->rsp,frame,eax); #endif if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->rsp) == -EFAULT) @@ -301,7 +301,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); #ifdef DEBUG_SIG - printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", + printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%p\n", current->comm, current->pid, frame, regs->rip, frame->pretcode); #endif @@ -463,7 +463,7 @@ void do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) { #ifdef DEBUG_SIG - printk("do_notify_resume flags:%x rip:%lx rsp:%lx caller:%lx pending:%lx\n", + printk("do_notify_resume flags:%x rip:%lx rsp:%lx caller:%p pending:%x\n", thread_info_flags, regs->rip, regs->rsp, __builtin_return_address(0),signal_pending(current)); #endif -- cgit v1.2.3-59-g8ed1b From 82d1bb725e128c97b362a4b33fcbfff08fdaaa5a Mon Sep 17 00:00:00 2001 From: James Puthukattukaran Date: Wed, 2 May 2007 19:27:13 +0200 Subject: [PATCH] x86-64: x86-64 system crashes when no memory populating Node 0 I have a 4 socket AMD Operton system. The 2.6.18 kernel I have crashes when there is no memory in node0. AK: changed call to _nopanic Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/x86_64/kernel/aperture.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c index b487396c4c5b..a52af5820592 100644 --- a/arch/x86_64/kernel/aperture.c +++ b/arch/x86_64/kernel/aperture.c @@ -51,7 +51,6 @@ static void __init insert_aperture_resource(u32 aper_base, u32 aper_size) static u32 __init allocate_aperture(void) { - pg_data_t *nd0 = NODE_DATA(0); u32 aper_size; void *p; @@ -65,12 +64,12 @@ static u32 __init allocate_aperture(void) * Unfortunately we cannot move it up because that would make the * IOMMU useless. */ - p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); + p = __alloc_bootmem_nopanic(aper_size, aper_size, 0); if (!p || __pa(p)+aper_size > 0xffffffff) { printk("Cannot allocate aperture memory hole (%p,%uK)\n", p, aper_size>>10); if (p) - free_bootmem_node(nd0, __pa(p), aper_size); + free_bootmem(__pa(p), aper_size); return 0; } printk("Mapping aperture over %d KB of RAM @ %lx\n", -- cgit v1.2.3-59-g8ed1b From a75c54f933bd8db9f4a609bd128663c179b3e6a1 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 2 May 2007 19:27:13 +0200 Subject: [PATCH] i386: i386 separate hardware-defined TSS from Linux additions On Thu, 2007-03-29 at 13:16 +0200, Andi Kleen wrote: > Please clean it up properly with two structs. Not sure about this, now I've done it. Running it here. If you like it, I can do x86-64 as well. == lguest defines its own TSS struct because the "struct tss_struct" contains linux-specific additions. Andi asked me to split the struct in processor.h. Unfortunately it makes usage a little awkward. Signed-off-by: Rusty Russell Signed-off-by: Andi Kleen --- arch/i386/kernel/asm-offsets.c | 2 +- arch/i386/kernel/doublefault.c | 29 ++++++++++++++++------------- arch/i386/kernel/ioport.c | 2 +- arch/i386/kernel/process.c | 8 ++++---- arch/i386/kernel/sysenter.c | 6 +++--- arch/i386/kernel/traps.c | 4 ++-- arch/i386/kernel/vmi.c | 8 ++++---- include/asm-i386/processor.h | 24 ++++++++++++++++-------- 8 files changed, 47 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c index 655cc8d4c745..d558adfc293c 100644 --- a/arch/i386/kernel/asm-offsets.c +++ b/arch/i386/kernel/asm-offsets.c @@ -93,7 +93,7 @@ void foo(void) OFFSET(pbe_next, pbe, next); /* Offset from the sysenter stack to tss.esp0 */ - DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, esp0) - + DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, x86_tss.esp0) - sizeof(struct tss_struct)); DEFINE(PAGE_SIZE_asm, PAGE_SIZE); diff --git a/arch/i386/kernel/doublefault.c b/arch/i386/kernel/doublefault.c index b4d14c2eb345..265c5597efb0 100644 --- a/arch/i386/kernel/doublefault.c +++ b/arch/i386/kernel/doublefault.c @@ -33,7 +33,7 @@ static void doublefault_fn(void) printk("double fault, tss at %08lx\n", tss); if (ptr_ok(tss)) { - struct tss_struct *t = (struct tss_struct *)tss; + struct i386_hw_tss *t = (struct i386_hw_tss *)tss; printk("eip = %08lx, esp = %08lx\n", t->eip, t->esp); @@ -49,18 +49,21 @@ static void doublefault_fn(void) } struct tss_struct doublefault_tss __cacheline_aligned = { - .esp0 = STACK_START, - .ss0 = __KERNEL_DS, - .ldt = 0, - .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, + .x86_tss = { + .esp0 = STACK_START, + .ss0 = __KERNEL_DS, + .ldt = 0, + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, - .eip = (unsigned long) doublefault_fn, - .eflags = X86_EFLAGS_SF | 0x2, /* 0x2 bit is always set */ - .esp = STACK_START, - .es = __USER_DS, - .cs = __KERNEL_CS, - .ss = __KERNEL_DS, - .ds = __USER_DS, + .eip = (unsigned long) doublefault_fn, + /* 0x2 bit is always set */ + .eflags = X86_EFLAGS_SF | 0x2, + .esp = STACK_START, + .es = __USER_DS, + .cs = __KERNEL_CS, + .ss = __KERNEL_DS, + .ds = __USER_DS, - .__cr3 = __pa(swapper_pg_dir) + .__cr3 = __pa(swapper_pg_dir) + } }; diff --git a/arch/i386/kernel/ioport.c b/arch/i386/kernel/ioport.c index 1b4530e6cd82..d1e42e0dbe67 100644 --- a/arch/i386/kernel/ioport.c +++ b/arch/i386/kernel/ioport.c @@ -114,7 +114,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) * Reset the owner so that a process switch will not set * tss->io_bitmap_base to IO_BITMAP_OFFSET. */ - tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY; + tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY; tss->io_bitmap_owner = NULL; put_cpu(); diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 7e8e129b3d7d..5fb9524c6f4b 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -375,7 +375,7 @@ void exit_thread(void) t->io_bitmap_max = 0; tss->io_bitmap_owner = NULL; tss->io_bitmap_max = 0; - tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET; + tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; put_cpu(); } } @@ -554,7 +554,7 @@ static noinline void __switch_to_xtra(struct task_struct *next_p, * Disable the bitmap via an invalid offset. We still cache * the previous bitmap owner and the IO bitmap contents: */ - tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET; + tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; return; } @@ -564,7 +564,7 @@ static noinline void __switch_to_xtra(struct task_struct *next_p, * matches the next task, we dont have to do anything but * to set a valid offset in the TSS: */ - tss->io_bitmap_base = IO_BITMAP_OFFSET; + tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET; return; } /* @@ -576,7 +576,7 @@ static noinline void __switch_to_xtra(struct task_struct *next_p, * redundant copies when the currently switched task does not * perform any I/O during its timeslice. */ - tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY; + tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY; } /* diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c index 0b9768ee1e8d..94defac6fc3d 100644 --- a/arch/i386/kernel/sysenter.c +++ b/arch/i386/kernel/sysenter.c @@ -183,10 +183,10 @@ void enable_sep_cpu(void) return; } - tss->ss1 = __KERNEL_CS; - tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss; + tss->x86_tss.ss1 = __KERNEL_CS; + tss->x86_tss.esp1 = sizeof(struct tss_struct) + (unsigned long) tss; wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); - wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0); + wrmsr(MSR_IA32_SYSENTER_ESP, tss->x86_tss.esp1, 0); wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0); put_cpu(); } diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 8722444cacaa..e0a23bee6967 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -596,7 +596,7 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs, * and we set the offset field correctly. Then we let the CPU to * restart the faulting instruction. */ - if (tss->io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY && + if (tss->x86_tss.io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY && thread->io_bitmap_ptr) { memcpy(tss->io_bitmap, thread->io_bitmap_ptr, thread->io_bitmap_max); @@ -609,7 +609,7 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs, thread->io_bitmap_max, 0xff, tss->io_bitmap_max - thread->io_bitmap_max); tss->io_bitmap_max = thread->io_bitmap_max; - tss->io_bitmap_base = IO_BITMAP_OFFSET; + tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET; tss->io_bitmap_owner = thread; put_cpu(); return; diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index 626c82063d19..8f3bac473450 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c @@ -230,14 +230,14 @@ static void vmi_set_tr(void) static void vmi_load_esp0(struct tss_struct *tss, struct thread_struct *thread) { - tss->esp0 = thread->esp0; + tss->x86_tss.esp0 = thread->esp0; /* This can only happen when SEP is enabled, no need to test "SEP"arately */ - if (unlikely(tss->ss1 != thread->sysenter_cs)) { - tss->ss1 = thread->sysenter_cs; + if (unlikely(tss->x86_tss.ss1 != thread->sysenter_cs)) { + tss->x86_tss.ss1 = thread->sysenter_cs; wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); } - vmi_ops.set_kernel_stack(__KERNEL_DS, tss->esp0); + vmi_ops.set_kernel_stack(__KERNEL_DS, tss->x86_tss.esp0); } static void vmi_flush_tlb_user(void) diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 77e263267aa6..922260474646 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -291,7 +291,8 @@ typedef struct { struct thread_struct; -struct tss_struct { +/* This is the TSS defined by the hardware. */ +struct i386_hw_tss { unsigned short back_link,__blh; unsigned long esp0; unsigned short ss0,__ss0h; @@ -315,6 +316,11 @@ struct tss_struct { unsigned short gs, __gsh; unsigned short ldt, __ldth; unsigned short trace, io_bitmap_base; +} __attribute__((packed)); + +struct tss_struct { + struct i386_hw_tss x86_tss; + /* * The extra 1 is there because the CPU will access an * additional byte beyond the end of the IO permission @@ -381,10 +387,12 @@ struct thread_struct { * be within the limit. */ #define INIT_TSS { \ - .esp0 = sizeof(init_stack) + (long)&init_stack, \ - .ss0 = __KERNEL_DS, \ - .ss1 = __KERNEL_CS, \ - .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \ + .x86_tss = { \ + .esp0 = sizeof(init_stack) + (long)&init_stack, \ + .ss0 = __KERNEL_DS, \ + .ss1 = __KERNEL_CS, \ + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \ + }, \ .io_bitmap = { [ 0 ... IO_BITMAP_LONGS] = ~0 }, \ } @@ -493,10 +501,10 @@ static inline void rep_nop(void) static inline void native_load_esp0(struct tss_struct *tss, struct thread_struct *thread) { - tss->esp0 = thread->esp0; + tss->x86_tss.esp0 = thread->esp0; /* This can only happen when SEP is enabled, no need to test "SEP"arately */ - if (unlikely(tss->ss1 != thread->sysenter_cs)) { - tss->ss1 = thread->sysenter_cs; + if (unlikely(tss->x86_tss.ss1 != thread->sysenter_cs)) { + tss->x86_tss.ss1 = thread->sysenter_cs; wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); } } -- cgit v1.2.3-59-g8ed1b From 7f63c41c6c57371a0931da3940c6620c2301442c Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:13 +0200 Subject: [PATCH] i386: PARAVIRT: Remove CONFIG_DEBUG_PARAVIRT Remove CONFIG_DEBUG_PARAVIRT. When inlining code, this option attempts to trash registers in the patch-site's "clobber" field, on the grounds that this should find bugs with incorrect clobbers. Unfortunately, the clobber field really means "registers modified by this patch site", which includes return values. Because of this, this option has outlived its usefulness, so remove it. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Rusty Russell --- arch/i386/Kconfig.debug | 10 ---------- arch/i386/kernel/alternative.c | 14 +------------- 2 files changed, 1 insertion(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/i386/Kconfig.debug b/arch/i386/Kconfig.debug index 458bc1611933..b31c0802e1cc 100644 --- a/arch/i386/Kconfig.debug +++ b/arch/i386/Kconfig.debug @@ -85,14 +85,4 @@ config DOUBLEFAULT option saves about 4k and might cause you much additional grey hair. -config DEBUG_PARAVIRT - bool "Enable some paravirtualization debugging" - default n - depends on PARAVIRT && DEBUG_KERNEL - help - Currently deliberately clobbers regs which are allowed to be - clobbered in inlined paravirt hooks, even in native mode. - If turning this off solves a problem, then DISABLE_INTERRUPTS() or - ENABLE_INTERRUPTS() is lying about what registers can be clobbered. - endmenu diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index 9b8e85a8edec..915b6c4d9baf 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -334,19 +334,7 @@ void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end) used = paravirt_ops.patch(p->instrtype, p->clobbers, p->instr, p->len); -#ifdef CONFIG_DEBUG_PARAVIRT - { - int i; - /* Deliberately clobber regs using "not %reg" to find bugs. */ - for (i = 0; i < 3; i++) { - if (p->len - used >= 2 && (p->clobbers & (1 << i))) { - memcpy(p->instr + used, "\xf7\xd0", 2); - p->instr[used+1] |= i; - used += 2; - } - } - } -#endif + /* Pad the rest with nops */ nop_out(p->instr + used, p->len - used); } -- cgit v1.2.3-59-g8ed1b From 45876233605c268e929a7875081e129debe34bdc Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:13 +0200 Subject: [PATCH] i386: PARAVIRT: use paravirt_nop to consistently mark no-op operations Add a _paravirt_nop function for use as a stub for no-op operations, and paravirt_nop #defined void * version to make using it easier (since all its uses are as a void *). This is useful to allow the patcher to automatically identify noop operations so it can simply nop out the callsite. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Acked-by: Ingo Molnar [mingo] but only as a cleanup of the current open-coded (void *) casts. My problem with this is that it loses the types. Not that there is much to check for, but still, this adds some assumptions about how function calls look like --- arch/i386/kernel/paravirt.c | 24 ++++++++++++------------ include/asm-i386/paravirt.h | 3 +++ 2 files changed, 15 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index 47698756aec5..3fdbd1f62379 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -35,7 +35,7 @@ #include /* nop stub */ -static void native_nop(void) +void _paravirt_nop(void) { } @@ -207,7 +207,7 @@ struct paravirt_ops paravirt_ops = { .patch = native_patch, .banner = default_banner, - .arch_setup = native_nop, + .arch_setup = paravirt_nop, .memory_setup = machine_specific_memory_setup, .get_wallclock = native_get_wallclock, .set_wallclock = native_set_wallclock, @@ -263,25 +263,25 @@ struct paravirt_ops paravirt_ops = { .setup_boot_clock = setup_boot_APIC_clock, .setup_secondary_clock = setup_secondary_APIC_clock, #endif - .set_lazy_mode = (void *)native_nop, + .set_lazy_mode = paravirt_nop, .flush_tlb_user = native_flush_tlb, .flush_tlb_kernel = native_flush_tlb_global, .flush_tlb_single = native_flush_tlb_single, - .map_pt_hook = (void *)native_nop, + .map_pt_hook = paravirt_nop, - .alloc_pt = (void *)native_nop, - .alloc_pd = (void *)native_nop, - .alloc_pd_clone = (void *)native_nop, - .release_pt = (void *)native_nop, - .release_pd = (void *)native_nop, + .alloc_pt = paravirt_nop, + .alloc_pd = paravirt_nop, + .alloc_pd_clone = paravirt_nop, + .release_pt = paravirt_nop, + .release_pd = paravirt_nop, .set_pte = native_set_pte, .set_pte_at = native_set_pte_at, .set_pmd = native_set_pmd, - .pte_update = (void *)native_nop, - .pte_update_defer = (void *)native_nop, + .pte_update = paravirt_nop, + .pte_update_defer = paravirt_nop, #ifdef CONFIG_X86_PAE .set_pte_atomic = native_set_pte_atomic, .set_pte_present = native_set_pte_present, @@ -293,7 +293,7 @@ struct paravirt_ops paravirt_ops = { .irq_enable_sysexit = native_irq_enable_sysexit, .iret = native_iret, - .startup_ipi_hook = (void *)native_nop, + .startup_ipi_hook = paravirt_nop, }; /* diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index 32acebce9ae2..f0bdaea6235d 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -434,6 +434,9 @@ static inline void pmd_clear(pmd_t *pmdp) #define arch_leave_lazy_mmu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_NONE) #define arch_flush_lazy_mmu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_FLUSH) +void _paravirt_nop(void); +#define paravirt_nop ((void *)_paravirt_nop) + /* These all sit in the .parainstructions section to tell us what to patch. */ struct paravirt_patch { u8 *instr; /* original instructions */ -- cgit v1.2.3-59-g8ed1b From 3dc494e86d1c93afd4c66385f270899dbfae483d Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:13 +0200 Subject: [PATCH] i386: PARAVIRT: Add pagetable accessors to pack and unpack pagetable entries Add a set of accessors to pack, unpack and modify page table entries (at all levels). This allows a paravirt implementation to control the contents of pgd/pmd/pte entries. For example, Xen uses this to convert the (pseudo-)physical address into a machine address when populating a pagetable entry, and converting back to pphys address when an entry is read. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Acked-by: Ingo Molnar --- arch/i386/kernel/paravirt.c | 84 ++++++--------------------------------- arch/i386/kernel/vmi.c | 6 +-- include/asm-i386/page.h | 79 +++++++++++++++++++++++++++++++----- include/asm-i386/paravirt.h | 52 ++++++++++++++++++------ include/asm-i386/pgtable-2level.h | 26 +++++++++--- include/asm-i386/pgtable-3level.h | 63 +++++++++++++++++------------ include/asm-i386/pgtable.h | 2 + 7 files changed, 184 insertions(+), 128 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index 3fdbd1f62379..cba7a15ce1b0 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -117,78 +117,6 @@ static void native_flush_tlb_single(u32 addr) __native_flush_tlb_single(addr); } -#ifndef CONFIG_X86_PAE -static void native_set_pte(pte_t *ptep, pte_t pteval) -{ - *ptep = pteval; -} - -static void native_set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pteval) -{ - *ptep = pteval; -} - -static void native_set_pmd(pmd_t *pmdp, pmd_t pmdval) -{ - *pmdp = pmdval; -} - -#else /* CONFIG_X86_PAE */ - -static void native_set_pte(pte_t *ptep, pte_t pte) -{ - ptep->pte_high = pte.pte_high; - smp_wmb(); - ptep->pte_low = pte.pte_low; -} - -static void native_set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pte) -{ - ptep->pte_high = pte.pte_high; - smp_wmb(); - ptep->pte_low = pte.pte_low; -} - -static void native_set_pte_present(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) -{ - ptep->pte_low = 0; - smp_wmb(); - ptep->pte_high = pte.pte_high; - smp_wmb(); - ptep->pte_low = pte.pte_low; -} - -static void native_set_pte_atomic(pte_t *ptep, pte_t pteval) -{ - set_64bit((unsigned long long *)ptep,pte_val(pteval)); -} - -static void native_set_pmd(pmd_t *pmdp, pmd_t pmdval) -{ - set_64bit((unsigned long long *)pmdp,pmd_val(pmdval)); -} - -static void native_set_pud(pud_t *pudp, pud_t pudval) -{ - *pudp = pudval; -} - -static void native_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) -{ - ptep->pte_low = 0; - smp_wmb(); - ptep->pte_high = 0; -} - -static void native_pmd_clear(pmd_t *pmd) -{ - u32 *tmp = (u32 *)pmd; - *tmp = 0; - smp_wmb(); - *(tmp + 1) = 0; -} -#endif /* CONFIG_X86_PAE */ - /* These are in entry.S */ extern void native_iret(void); extern void native_irq_enable_sysexit(void); @@ -282,14 +210,26 @@ struct paravirt_ops paravirt_ops = { .set_pmd = native_set_pmd, .pte_update = paravirt_nop, .pte_update_defer = paravirt_nop, + + .ptep_get_and_clear = native_ptep_get_and_clear, + #ifdef CONFIG_X86_PAE .set_pte_atomic = native_set_pte_atomic, .set_pte_present = native_set_pte_present, .set_pud = native_set_pud, .pte_clear = native_pte_clear, .pmd_clear = native_pmd_clear, + + .pmd_val = native_pmd_val, + .make_pmd = native_make_pmd, #endif + .pte_val = native_pte_val, + .pgd_val = native_pgd_val, + + .make_pte = native_make_pte, + .make_pgd = native_make_pgd, + .irq_enable_sysexit = native_irq_enable_sysexit, .iret = native_iret, diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index 8f3bac473450..ea77d93f59dd 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c @@ -443,13 +443,13 @@ static void vmi_release_pd(u32 pfn) ((level) | (is_current_as(mm, user) ? \ (VMI_PAGE_DEFER | VMI_PAGE_CURRENT_AS | ((addr) & VMI_PAGE_VA_MASK)) : 0)) -static void vmi_update_pte(struct mm_struct *mm, u32 addr, pte_t *ptep) +static void vmi_update_pte(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); vmi_ops.update_pte(ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); } -static void vmi_update_pte_defer(struct mm_struct *mm, u32 addr, pte_t *ptep) +static void vmi_update_pte_defer(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); vmi_ops.update_pte(ptep, vmi_flags_addr_defer(mm, addr, VMI_PAGE_PT, 0)); @@ -462,7 +462,7 @@ static void vmi_set_pte(pte_t *ptep, pte_t pte) vmi_ops.set_pte(pte, ptep, VMI_PAGE_PT); } -static void vmi_set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pte) +static void vmi_set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) { vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h index fd3f64ace248..818ac8bf01e2 100644 --- a/include/asm-i386/page.h +++ b/include/asm-i386/page.h @@ -12,7 +12,6 @@ #ifdef __KERNEL__ #ifndef __ASSEMBLY__ - #ifdef CONFIG_X86_USE_3DNOW #include @@ -42,26 +41,81 @@ * These are used to make use of C type-checking.. */ extern int nx_enabled; + #ifdef CONFIG_X86_PAE extern unsigned long long __supported_pte_mask; typedef struct { unsigned long pte_low, pte_high; } pte_t; typedef struct { unsigned long long pmd; } pmd_t; typedef struct { unsigned long long pgd; } pgd_t; typedef struct { unsigned long long pgprot; } pgprot_t; -#define pmd_val(x) ((x).pmd) -#define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) -#define __pmd(x) ((pmd_t) { (x) } ) + +static inline unsigned long long native_pgd_val(pgd_t pgd) +{ + return pgd.pgd; +} + +static inline unsigned long long native_pmd_val(pmd_t pmd) +{ + return pmd.pmd; +} + +static inline unsigned long long native_pte_val(pte_t pte) +{ + return pte.pte_low | ((unsigned long long)pte.pte_high << 32); +} + +static inline pgd_t native_make_pgd(unsigned long long val) +{ + return (pgd_t) { val }; +} + +static inline pmd_t native_make_pmd(unsigned long long val) +{ + return (pmd_t) { val }; +} + +static inline pte_t native_make_pte(unsigned long long val) +{ + return (pte_t) { .pte_low = val, .pte_high = (val >> 32) } ; +} + +#ifndef CONFIG_PARAVIRT +#define pmd_val(x) native_pmd_val(x) +#define __pmd(x) native_make_pmd(x) +#endif + #define HPAGE_SHIFT 21 #include -#else +#else /* !CONFIG_X86_PAE */ typedef struct { unsigned long pte_low; } pte_t; typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; #define boot_pte_t pte_t /* or would you rather have a typedef */ -#define pte_val(x) ((x).pte_low) + +static inline unsigned long native_pgd_val(pgd_t pgd) +{ + return pgd.pgd; +} + +static inline unsigned long native_pte_val(pte_t pte) +{ + return pte.pte_low; +} + +static inline pgd_t native_make_pgd(unsigned long val) +{ + return (pgd_t) { val }; +} + +static inline pte_t native_make_pte(unsigned long val) +{ + return (pte_t) { .pte_low = val }; +} + #define HPAGE_SHIFT 22 #include -#endif +#endif /* CONFIG_X86_PAE */ + #define PTE_MASK PAGE_MASK #ifdef CONFIG_HUGETLB_PAGE @@ -71,13 +125,16 @@ typedef struct { unsigned long pgprot; } pgprot_t; #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA #endif -#define pgd_val(x) ((x).pgd) #define pgprot_val(x) ((x).pgprot) - -#define __pte(x) ((pte_t) { (x) } ) -#define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) +#ifndef CONFIG_PARAVIRT +#define pgd_val(x) native_pgd_val(x) +#define __pgd(x) native_make_pgd(x) +#define pte_val(x) native_pte_val(x) +#define __pte(x) native_make_pte(x) +#endif + #endif /* !__ASSEMBLY__ */ /* to align the pointer to the (next) page boundary */ diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index f0bdaea6235d..0aacb13bb929 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -2,7 +2,6 @@ #define __ASM_PARAVIRT_H /* Various instructions on x86 need to be replaced for * para-virtualization: those hooks are defined here. */ -#include #include #include @@ -25,6 +24,8 @@ #define CLBR_ANY 0x7 #ifndef __ASSEMBLY__ +#include + struct thread_struct; struct Xgt_desc_struct; struct tss_struct; @@ -55,11 +56,6 @@ struct paravirt_ops int (*set_wallclock)(unsigned long); void (*time_init)(void); - /* All the function pointers here are declared as "fastcall" - so that we get a specific register-based calling - convention. This makes it easier to implement inline - assembler replacements. */ - void (*cpuid)(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx); @@ -139,16 +135,33 @@ struct paravirt_ops void (*release_pd)(u32 pfn); void (*set_pte)(pte_t *ptep, pte_t pteval); - void (*set_pte_at)(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pteval); + void (*set_pte_at)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval); void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval); - void (*pte_update)(struct mm_struct *mm, u32 addr, pte_t *ptep); - void (*pte_update_defer)(struct mm_struct *mm, u32 addr, pte_t *ptep); + void (*pte_update)(struct mm_struct *mm, unsigned long addr, pte_t *ptep); + void (*pte_update_defer)(struct mm_struct *mm, unsigned long addr, pte_t *ptep); + + pte_t (*ptep_get_and_clear)(pte_t *ptep); + #ifdef CONFIG_X86_PAE void (*set_pte_atomic)(pte_t *ptep, pte_t pteval); - void (*set_pte_present)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte); + void (*set_pte_present)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte); void (*set_pud)(pud_t *pudp, pud_t pudval); - void (*pte_clear)(struct mm_struct *mm, unsigned long addr, pte_t *ptep); + void (*pte_clear)(struct mm_struct *mm, unsigned long addr, pte_t *ptep); void (*pmd_clear)(pmd_t *pmdp); + + unsigned long long (*pte_val)(pte_t); + unsigned long long (*pmd_val)(pmd_t); + unsigned long long (*pgd_val)(pgd_t); + + pte_t (*make_pte)(unsigned long long pte); + pmd_t (*make_pmd)(unsigned long long pmd); + pgd_t (*make_pgd)(unsigned long long pgd); +#else + unsigned long (*pte_val)(pte_t); + unsigned long (*pgd_val)(pgd_t); + + pte_t (*make_pte)(unsigned long pte); + pgd_t (*make_pgd)(unsigned long pgd); #endif void (*set_lazy_mode)(int mode); @@ -219,6 +232,8 @@ static inline void __cpuid(unsigned int *eax, unsigned int *ebx, #define read_cr4_safe(x) paravirt_ops.read_cr4_safe() #define write_cr4(x) paravirt_ops.write_cr4(x) +#define raw_ptep_get_and_clear(xp) (paravirt_ops.ptep_get_and_clear(xp)) + static inline void raw_safe_halt(void) { paravirt_ops.safe_halt(); @@ -304,6 +319,17 @@ static inline void halt(void) (paravirt_ops.write_idt_entry((dt), (entry), (low), (high))) #define set_iopl_mask(mask) (paravirt_ops.set_iopl_mask(mask)) +#define __pte(x) paravirt_ops.make_pte(x) +#define __pgd(x) paravirt_ops.make_pgd(x) + +#define pte_val(x) paravirt_ops.pte_val(x) +#define pgd_val(x) paravirt_ops.pgd_val(x) + +#ifdef CONFIG_X86_PAE +#define __pmd(x) paravirt_ops.make_pmd(x) +#define pmd_val(x) paravirt_ops.pmd_val(x) +#endif + /* The paravirtualized I/O functions */ static inline void slow_down_io(void) { paravirt_ops.io_delay(); @@ -344,6 +370,7 @@ static inline void setup_secondary_clock(void) } #endif + #ifdef CONFIG_SMP static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip, unsigned long start_esp) @@ -371,7 +398,8 @@ static inline void set_pte(pte_t *ptep, pte_t pteval) paravirt_ops.set_pte(ptep, pteval); } -static inline void set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pteval) +static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pteval) { paravirt_ops.set_pte_at(mm, addr, ptep, pteval); } diff --git a/include/asm-i386/pgtable-2level.h b/include/asm-i386/pgtable-2level.h index 38c3fcc0676d..043a2bcfa86a 100644 --- a/include/asm-i386/pgtable-2level.h +++ b/include/asm-i386/pgtable-2level.h @@ -11,10 +11,23 @@ * within a page table are directly modified. Thus, the following * hook is made available. */ +static inline void native_set_pte(pte_t *ptep , pte_t pte) +{ + *ptep = pte; +} +static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep , pte_t pte) +{ + native_set_pte(ptep, pte); +} +static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) +{ + *pmdp = pmd; +} #ifndef CONFIG_PARAVIRT -#define set_pte(pteptr, pteval) (*(pteptr) = pteval) -#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) -#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval)) +#define set_pte(pteptr, pteval) native_set_pte(pteptr, pteval) +#define set_pte_at(mm,addr,ptep,pteval) native_set_pte_at(mm, addr, ptep, pteval) +#define set_pmd(pmdptr, pmdval) native_set_pmd(pmdptr, pmdval) #endif #define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval) @@ -23,11 +36,14 @@ #define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) #define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) -#define raw_ptep_get_and_clear(xp) __pte(xchg(&(xp)->pte_low, 0)) +static inline pte_t native_ptep_get_and_clear(pte_t *xp) +{ + return __pte(xchg(&xp->pte_low, 0)); +} #define pte_page(x) pfn_to_page(pte_pfn(x)) #define pte_none(x) (!(x).pte_low) -#define pte_pfn(x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT))) +#define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT) #define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) #define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) diff --git a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h index 7a2318f38303..be6017f37a91 100644 --- a/include/asm-i386/pgtable-3level.h +++ b/include/asm-i386/pgtable-3level.h @@ -42,20 +42,23 @@ static inline int pte_exec_kernel(pte_t pte) return pte_x(pte); } -#ifndef CONFIG_PARAVIRT /* Rules for using set_pte: the pte being assigned *must* be * either not present or in a state where the hardware will * not attempt to update the pte. In places where this is * not possible, use pte_get_and_clear to obtain the old pte * value and then use set_pte to update it. -ben */ -static inline void set_pte(pte_t *ptep, pte_t pte) +static inline void native_set_pte(pte_t *ptep, pte_t pte) { ptep->pte_high = pte.pte_high; smp_wmb(); ptep->pte_low = pte.pte_low; } -#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) +static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep , pte_t pte) +{ + native_set_pte(ptep, pte); +} /* * Since this is only called on user PTEs, and the page fault handler @@ -63,7 +66,8 @@ static inline void set_pte(pte_t *ptep, pte_t pte) * we are justified in merely clearing the PTE present bit, followed * by a set. The ordering here is important. */ -static inline void set_pte_present(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) +static inline void native_set_pte_present(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) { ptep->pte_low = 0; smp_wmb(); @@ -72,32 +76,48 @@ static inline void set_pte_present(struct mm_struct *mm, unsigned long addr, pte ptep->pte_low = pte.pte_low; } -#define set_pte_atomic(pteptr,pteval) \ - set_64bit((unsigned long long *)(pteptr),pte_val(pteval)) -#define set_pmd(pmdptr,pmdval) \ - set_64bit((unsigned long long *)(pmdptr),pmd_val(pmdval)) -#define set_pud(pudptr,pudval) \ - (*(pudptr) = (pudval)) +static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) +{ + set_64bit((unsigned long long *)(ptep),native_pte_val(pte)); +} +static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) +{ + set_64bit((unsigned long long *)(pmdp),native_pmd_val(pmd)); +} +static inline void native_set_pud(pud_t *pudp, pud_t pud) +{ + *pudp = pud; +} /* * For PTEs and PDEs, we must clear the P-bit first when clearing a page table * entry, so clear the bottom half first and enforce ordering with a compiler * barrier. */ -static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { ptep->pte_low = 0; smp_wmb(); ptep->pte_high = 0; } -static inline void pmd_clear(pmd_t *pmd) +static inline void native_pmd_clear(pmd_t *pmd) { u32 *tmp = (u32 *)pmd; *tmp = 0; smp_wmb(); *(tmp + 1) = 0; } + +#ifndef CONFIG_PARAVIRT +#define set_pte(ptep, pte) native_set_pte(ptep, pte) +#define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte) +#define set_pte_present(mm, addr, ptep, pte) native_set_pte_present(mm, addr, ptep, pte) +#define set_pte_atomic(ptep, pte) native_set_pte_atomic(ptep, pte) +#define set_pmd(pmdp, pmd) native_set_pmd(pmdp, pmd) +#define set_pud(pudp, pud) native_set_pud(pudp, pud) +#define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep) +#define pmd_clear(pmd) native_pmd_clear(pmd) #endif /* @@ -119,7 +139,7 @@ static inline void pud_clear (pud_t * pud) { } #define pmd_offset(pud, address) ((pmd_t *) pud_page(*(pud)) + \ pmd_index(address)) -static inline pte_t raw_ptep_get_and_clear(pte_t *ptep) +static inline pte_t native_ptep_get_and_clear(pte_t *ptep) { pte_t res; @@ -146,28 +166,21 @@ static inline int pte_none(pte_t pte) static inline unsigned long pte_pfn(pte_t pte) { - return (pte.pte_low >> PAGE_SHIFT) | - (pte.pte_high << (32 - PAGE_SHIFT)); + return pte_val(pte) >> PAGE_SHIFT; } extern unsigned long long __supported_pte_mask; static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) { - pte_t pte; - - pte.pte_high = (page_nr >> (32 - PAGE_SHIFT)) | \ - (pgprot_val(pgprot) >> 32); - pte.pte_high &= (__supported_pte_mask >> 32); - pte.pte_low = ((page_nr << PAGE_SHIFT) | pgprot_val(pgprot)) & \ - __supported_pte_mask; - return pte; + return __pte((((unsigned long long)page_nr << PAGE_SHIFT) | + pgprot_val(pgprot)) & __supported_pte_mask); } static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) { - return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) | \ - pgprot_val(pgprot)) & __supported_pte_mask); + return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) | + pgprot_val(pgprot)) & __supported_pte_mask); } /* diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index 143ddc42b86f..147f2553784d 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -266,6 +266,8 @@ static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return p #define pte_update(mm, addr, ptep) do { } while (0) #define pte_update_defer(mm, addr, ptep) do { } while (0) #define paravirt_map_pt_hook(slot, va, pfn) do { } while (0) + +#define raw_ptep_get_and_clear(xp) native_ptep_get_and_clear(xp) #endif /* -- cgit v1.2.3-59-g8ed1b From b239fb2501117bf3aeb4dd6926edd855be92333d Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:13 +0200 Subject: [PATCH] i386: PARAVIRT: Hooks to set up initial pagetable This patch introduces paravirt_ops hooks to control how the kernel's initial pagetable is set up. In the case of a native boot, the very early bootstrap code creates a simple non-PAE pagetable to map the kernel and physical memory. When the VM subsystem is initialized, it creates a proper pagetable which respects the PAE mode, large pages, etc. When booting under a hypervisor, there are many possibilities for what paging environment the hypervisor establishes for the guest kernel, so the constructon of the kernel's pagetable depends on the hypervisor. In the case of Xen, the hypervisor boots the kernel with a fully constructed pagetable, which is already using PAE if necessary. Also, Xen requires particular care when constructing pagetables to make sure all pagetables are always mapped read-only. In order to make this easier, kernel's initial pagetable construction has been changed to only allocate and initialize a pagetable page if there's no page already present in the pagetable. This allows the Xen paravirt backend to make a copy of the hypervisor-provided pagetable, allowing the kernel to establish any more mappings it needs while keeping the existing ones. A slightly subtle point which is worth highlighting here is that Xen requires all kernel mappings to share the same pte_t pages between all pagetables, so that updating a kernel page's mapping in one pagetable is reflected in all other pagetables. This makes it possible to allocate a page and attach it to a pagetable without having to explicitly enumerate that page's mapping in all pagetables. And: +From: "Eric W. Biederman" If we don't set the leaf page table entries it is quite possible that will inherit and incorrect page table entry from the initial boot page table setup in head.S. So we need to redo the effort here, so we pick up PSE, PGE and the like. Hypervisors like Xen require that their page tables be read-only, which is slightly incompatible with our low identity mappings, however I discussed this with Jeremy he has modified the Xen early set_pte function to avoid problems in this area. Signed-off-by: Eric W. Biederman Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Acked-by: William Irwin Cc: Ingo Molnar --- arch/i386/kernel/paravirt.c | 3 + arch/i386/mm/init.c | 138 +++++++++++++++++++++++++++++--------------- include/asm-i386/paravirt.h | 17 +++++- include/asm-i386/pgtable.h | 16 +++++ 4 files changed, 126 insertions(+), 48 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index cba7a15ce1b0..47d075bdfb95 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -193,6 +193,9 @@ struct paravirt_ops paravirt_ops = { #endif .set_lazy_mode = paravirt_nop, + .pagetable_setup_start = native_pagetable_setup_start, + .pagetable_setup_done = native_pagetable_setup_done, + .flush_tlb_user = native_flush_tlb, .flush_tlb_kernel = native_flush_tlb_global, .flush_tlb_single = native_flush_tlb_single, diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index bd5ef3718504..e8545dcf06c5 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -43,6 +43,7 @@ #include #include #include +#include unsigned int __VMALLOC_RESERVE = 128 << 20; @@ -62,17 +63,18 @@ static pmd_t * __init one_md_table_init(pgd_t *pgd) pmd_t *pmd_table; #ifdef CONFIG_X86_PAE - pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); - paravirt_alloc_pd(__pa(pmd_table) >> PAGE_SHIFT); - set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT)); - pud = pud_offset(pgd, 0); - if (pmd_table != pmd_offset(pud, 0)) - BUG(); -#else + if (!(pgd_val(*pgd) & _PAGE_PRESENT)) { + pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); + + paravirt_alloc_pd(__pa(pmd_table) >> PAGE_SHIFT); + set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT)); + pud = pud_offset(pgd, 0); + if (pmd_table != pmd_offset(pud, 0)) + BUG(); + } +#endif pud = pud_offset(pgd, 0); pmd_table = pmd_offset(pud, 0); -#endif - return pmd_table; } @@ -82,14 +84,12 @@ static pmd_t * __init one_md_table_init(pgd_t *pgd) */ static pte_t * __init one_page_table_init(pmd_t *pmd) { - if (pmd_none(*pmd)) { + if (!(pmd_val(*pmd) & _PAGE_PRESENT)) { pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); + paravirt_alloc_pt(__pa(page_table) >> PAGE_SHIFT); set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE)); - if (page_table != pte_offset_kernel(pmd, 0)) - BUG(); - - return page_table; + BUG_ON(page_table != pte_offset_kernel(pmd, 0)); } return pte_offset_kernel(pmd, 0); @@ -109,7 +109,6 @@ static pte_t * __init one_page_table_init(pmd_t *pmd) static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base) { pgd_t *pgd; - pud_t *pud; pmd_t *pmd; int pgd_idx, pmd_idx; unsigned long vaddr; @@ -120,13 +119,10 @@ static void __init page_table_range_init (unsigned long start, unsigned long end pgd = pgd_base + pgd_idx; for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) { - if (pgd_none(*pgd)) - one_md_table_init(pgd); - pud = pud_offset(pgd, vaddr); - pmd = pmd_offset(pud, vaddr); + pmd = one_md_table_init(pgd); + pmd = pmd + pmd_index(vaddr); for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) { - if (pmd_none(*pmd)) - one_page_table_init(pmd); + one_page_table_init(pmd); vaddr += PMD_SIZE; } @@ -168,20 +164,22 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base) /* Map with big pages if possible, otherwise create normal page tables. */ if (cpu_has_pse) { unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1; - if (is_kernel_text(address) || is_kernel_text(address2)) set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC)); else set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE)); + pfn += PTRS_PER_PTE; } else { pte = one_page_table_init(pmd); - for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) { - if (is_kernel_text(address)) - set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC)); - else - set_pte(pte, pfn_pte(pfn, PAGE_KERNEL)); + for (pte_ofs = 0; + pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; + pte++, pfn++, pte_ofs++, address += PAGE_SIZE) { + if (is_kernel_text(address)) + set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC)); + else + set_pte(pte, pfn_pte(pfn, PAGE_KERNEL)); } } } @@ -338,24 +336,78 @@ extern void __init remap_numa_kva(void); #define remap_numa_kva() do {} while (0) #endif -static void __init pagetable_init (void) +void __init native_pagetable_setup_start(pgd_t *base) { - unsigned long vaddr; - pgd_t *pgd_base = swapper_pg_dir; - #ifdef CONFIG_X86_PAE int i; - /* Init entries of the first-level page table to the zero page */ - for (i = 0; i < PTRS_PER_PGD; i++) - set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT)); + + /* + * Init entries of the first-level page table to the + * zero page, if they haven't already been set up. + * + * In a normal native boot, we'll be running on a + * pagetable rooted in swapper_pg_dir, but not in PAE + * mode, so this will end up clobbering the mappings + * for the lower 24Mbytes of the address space, + * without affecting the kernel address space. + */ + for (i = 0; i < USER_PTRS_PER_PGD; i++) + set_pgd(&base[i], + __pgd(__pa(empty_zero_page) | _PAGE_PRESENT)); + + /* Make sure kernel address space is empty so that a pagetable + will be allocated for it. */ + memset(&base[USER_PTRS_PER_PGD], 0, + KERNEL_PGD_PTRS * sizeof(pgd_t)); #else paravirt_alloc_pd(__pa(swapper_pg_dir) >> PAGE_SHIFT); #endif +} + +void __init native_pagetable_setup_done(pgd_t *base) +{ +#ifdef CONFIG_X86_PAE + /* + * Add low memory identity-mappings - SMP needs it when + * starting up on an AP from real-mode. In the non-PAE + * case we already have these mappings through head.S. + * All user-space mappings are explicitly cleared after + * SMP startup. + */ + set_pgd(&base[0], base[USER_PTRS_PER_PGD]); +#endif +} + +/* + * Build a proper pagetable for the kernel mappings. Up until this + * point, we've been running on some set of pagetables constructed by + * the boot process. + * + * If we're booting on native hardware, this will be a pagetable + * constructed in arch/i386/kernel/head.S, and not running in PAE mode + * (even if we'll end up running in PAE). The root of the pagetable + * will be swapper_pg_dir. + * + * If we're booting paravirtualized under a hypervisor, then there are + * more options: we may already be running PAE, and the pagetable may + * or may not be based in swapper_pg_dir. In any case, + * paravirt_pagetable_setup_start() will set up swapper_pg_dir + * appropriately for the rest of the initialization to work. + * + * In general, pagetable_init() assumes that the pagetable may already + * be partially populated, and so it avoids stomping on any existing + * mappings. + */ +static void __init pagetable_init (void) +{ + unsigned long vaddr, end; + pgd_t *pgd_base = swapper_pg_dir; + + paravirt_pagetable_setup_start(pgd_base); /* Enable PSE if available */ - if (cpu_has_pse) { + if (cpu_has_pse) set_in_cr4(X86_CR4_PSE); - } /* Enable PGE if available */ if (cpu_has_pge) { @@ -372,20 +424,12 @@ static void __init pagetable_init (void) * created - mappings will be set by set_fixmap(): */ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; - page_table_range_init(vaddr, 0, pgd_base); + end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK; + page_table_range_init(vaddr, end, pgd_base); permanent_kmaps_init(pgd_base); -#ifdef CONFIG_X86_PAE - /* - * Add low memory identity-mappings - SMP needs it when - * starting up on an AP from real-mode. In the non-PAE - * case we already have these mappings through head.S. - * All user-space mappings are explicitly cleared after - * SMP startup. - */ - set_pgd(&pgd_base[0], pgd_base[USER_PTRS_PER_PGD]); -#endif + paravirt_pagetable_setup_done(pgd_base); } #if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_ACPI_SLEEP) diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index 0aacb13bb929..c49b44cdd8ee 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -2,10 +2,11 @@ #define __ASM_PARAVIRT_H /* Various instructions on x86 need to be replaced for * para-virtualization: those hooks are defined here. */ + +#ifdef CONFIG_PARAVIRT #include #include -#ifdef CONFIG_PARAVIRT /* These are the most performance critical ops, so we want to be able to patch * callers */ #define PARAVIRT_IRQ_DISABLE 0 @@ -50,6 +51,9 @@ struct paravirt_ops char *(*memory_setup)(void); void (*init_IRQ)(void); + void (*pagetable_setup_start)(pgd_t *pgd_base); + void (*pagetable_setup_done)(pgd_t *pgd_base); + void (*banner)(void); unsigned long (*get_wallclock)(void); @@ -370,6 +374,17 @@ static inline void setup_secondary_clock(void) } #endif +static inline void paravirt_pagetable_setup_start(pgd_t *base) +{ + if (paravirt_ops.pagetable_setup_start) + (*paravirt_ops.pagetable_setup_start)(base); +} + +static inline void paravirt_pagetable_setup_done(pgd_t *base) +{ + if (paravirt_ops.pagetable_setup_done) + (*paravirt_ops.pagetable_setup_done)(base); +} #ifdef CONFIG_SMP static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip, diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index 147f2553784d..0790ad6ed440 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -514,6 +514,22 @@ do { \ * tables contain all the necessary information. */ #define update_mmu_cache(vma,address,pte) do { } while (0) + +void native_pagetable_setup_start(pgd_t *base); +void native_pagetable_setup_done(pgd_t *base); + +#ifndef CONFIG_PARAVIRT +static inline void paravirt_pagetable_setup_start(pgd_t *base) +{ + native_pagetable_setup_start(base); +} + +static inline void paravirt_pagetable_setup_done(pgd_t *base) +{ + native_pagetable_setup_done(base); +} +#endif /* !CONFIG_PARAVIRT */ + #endif /* !__ASSEMBLY__ */ #ifdef CONFIG_FLATMEM -- cgit v1.2.3-59-g8ed1b From 5311ab62cdc7788784971ed816ce85e926f3e994 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:13 +0200 Subject: [PATCH] i386: PARAVIRT: Allow paravirt backend to choose kernel PMD sharing Normally when running in PAE mode, the 4th PMD maps the kernel address space, which can be shared among all processes (since they all need the same kernel mappings). Xen, however, does not allow guests to have the kernel pmd shared between page tables, so parameterize pgtable.c to allow both modes of operation. There are several side-effects of this. One is that vmalloc will update the kernel address space mappings, and those updates need to be propagated into all processes if the kernel mappings are not intrinsically shared. In the non-PAE case, this is done by maintaining a pgd_list of all processes; this list is used when all process pagetables must be updated. pgd_list is threaded via otherwise unused entries in the page structure for the pgd, which means that the pgd must be page-sized for this to work. Normally the PAE pgd is only 4x64 byte entries large, but Xen requires the PAE pgd to page aligned anyway, so this patch forces the pgd to be page aligned+sized when the kernel pmd is unshared, to accomodate both these requirements. Also, since there may be several distinct kernel pmds (if the user/kernel split is below 3G), there's no point in allocating them from a slab cache; they're just allocated with get_free_page and initialized appropriately. (Of course the could be cached if there is just a single kernel pmd - which is the default with a 3G user/kernel split - but it doesn't seem worthwhile to add yet another case into this code). [ Many thanks to wli for review comments. ] Signed-off-by: Jeremy Fitzhardinge Signed-off-by: William Lee Irwin III Signed-off-by: Andi Kleen Cc: Zachary Amsden Cc: Christoph Lameter Acked-by: Ingo Molnar Signed-off-by: Andrew Morton --- arch/i386/kernel/paravirt.c | 1 + arch/i386/mm/fault.c | 5 +- arch/i386/mm/init.c | 18 +++++-- arch/i386/mm/pageattr.c | 2 +- arch/i386/mm/pgtable.c | 88 +++++++++++++++++++++++++++------- include/asm-i386/paravirt.h | 1 + include/asm-i386/pgtable-2level-defs.h | 2 + include/asm-i386/pgtable-2level.h | 2 - include/asm-i386/pgtable-3level-defs.h | 6 +++ include/asm-i386/pgtable-3level.h | 2 - include/asm-i386/pgtable.h | 2 + 11 files changed, 101 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index 47d075bdfb95..2040a831d5b3 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -132,6 +132,7 @@ struct paravirt_ops paravirt_ops = { .name = "bare hardware", .paravirt_enabled = 0, .kernel_rpl = 0, + .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */ .patch = native_patch, .banner = default_banner, diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index c6a0a06258e6..f534c29e80b2 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c @@ -603,7 +603,6 @@ do_sigbus: force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk); } -#ifndef CONFIG_X86_PAE void vmalloc_sync_all(void) { /* @@ -616,6 +615,9 @@ void vmalloc_sync_all(void) static unsigned long start = TASK_SIZE; unsigned long address; + if (SHARED_KERNEL_PMD) + return; + BUILD_BUG_ON(TASK_SIZE & ~PGDIR_MASK); for (address = start; address >= TASK_SIZE; address += PGDIR_SIZE) { if (!test_bit(pgd_index(address), insync)) { @@ -638,4 +640,3 @@ void vmalloc_sync_all(void) start = address + PGDIR_SIZE; } } -#endif diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index e8545dcf06c5..dbe16f63a566 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -745,6 +745,8 @@ struct kmem_cache *pmd_cache; void __init pgtable_cache_init(void) { + size_t pgd_size = PTRS_PER_PGD*sizeof(pgd_t); + if (PTRS_PER_PMD > 1) { pmd_cache = kmem_cache_create("pmd", PTRS_PER_PMD*sizeof(pmd_t), @@ -754,13 +756,23 @@ void __init pgtable_cache_init(void) NULL); if (!pmd_cache) panic("pgtable_cache_init(): cannot create pmd cache"); + + if (!SHARED_KERNEL_PMD) { + /* If we're in PAE mode and have a non-shared + kernel pmd, then the pgd size must be a + page size. This is because the pgd_list + links through the page structure, so there + can only be one pgd per page for this to + work. */ + pgd_size = PAGE_SIZE; + } } pgd_cache = kmem_cache_create("pgd", - PTRS_PER_PGD*sizeof(pgd_t), - PTRS_PER_PGD*sizeof(pgd_t), + pgd_size, + pgd_size, 0, pgd_ctor, - PTRS_PER_PMD == 1 ? pgd_dtor : NULL); + (!SHARED_KERNEL_PMD) ? pgd_dtor : NULL); if (!pgd_cache) panic("pgtable_cache_init(): Cannot create pgd cache"); } diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c index ea6b6d4a0a2a..47bd477c8ecc 100644 --- a/arch/i386/mm/pageattr.c +++ b/arch/i386/mm/pageattr.c @@ -91,7 +91,7 @@ static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) unsigned long flags; set_pte_atomic(kpte, pte); /* change init_mm */ - if (PTRS_PER_PMD > 1) + if (SHARED_KERNEL_PMD) return; spin_lock_irqsave(&pgd_lock, flags); diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c index 99c09edc3dbb..9a96c1647428 100644 --- a/arch/i386/mm/pgtable.c +++ b/arch/i386/mm/pgtable.c @@ -232,42 +232,92 @@ static inline void pgd_list_del(pgd_t *pgd) set_page_private(next, (unsigned long)pprev); } +#if (PTRS_PER_PMD == 1) +/* Non-PAE pgd constructor */ void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused) { unsigned long flags; - if (PTRS_PER_PMD == 1) { - memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t)); - spin_lock_irqsave(&pgd_lock, flags); - } + /* !PAE, no pagetable sharing */ + memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t)); + + spin_lock_irqsave(&pgd_lock, flags); + /* must happen under lock */ clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD, swapper_pg_dir + USER_PTRS_PER_PGD, KERNEL_PGD_PTRS); - - if (PTRS_PER_PMD > 1) - return; - - /* must happen under lock */ paravirt_alloc_pd_clone(__pa(pgd) >> PAGE_SHIFT, - __pa(swapper_pg_dir) >> PAGE_SHIFT, - USER_PTRS_PER_PGD, PTRS_PER_PGD - USER_PTRS_PER_PGD); - + __pa(swapper_pg_dir) >> PAGE_SHIFT, + USER_PTRS_PER_PGD, + KERNEL_PGD_PTRS); pgd_list_add(pgd); spin_unlock_irqrestore(&pgd_lock, flags); } +#else /* PTRS_PER_PMD > 1 */ +/* PAE pgd constructor */ +void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused) +{ + /* PAE, kernel PMD may be shared */ + + if (SHARED_KERNEL_PMD) { + clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD, + swapper_pg_dir + USER_PTRS_PER_PGD, + KERNEL_PGD_PTRS); + } else { + unsigned long flags; + + memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t)); + spin_lock_irqsave(&pgd_lock, flags); + pgd_list_add(pgd); + spin_unlock_irqrestore(&pgd_lock, flags); + } +} +#endif /* PTRS_PER_PMD */ -/* never called when PTRS_PER_PMD > 1 */ void pgd_dtor(void *pgd, struct kmem_cache *cache, unsigned long unused) { unsigned long flags; /* can be called from interrupt context */ + BUG_ON(SHARED_KERNEL_PMD); + paravirt_release_pd(__pa(pgd) >> PAGE_SHIFT); spin_lock_irqsave(&pgd_lock, flags); pgd_list_del(pgd); spin_unlock_irqrestore(&pgd_lock, flags); } +#define UNSHARED_PTRS_PER_PGD \ + (SHARED_KERNEL_PMD ? USER_PTRS_PER_PGD : PTRS_PER_PGD) + +/* If we allocate a pmd for part of the kernel address space, then + make sure its initialized with the appropriate kernel mappings. + Otherwise use a cached zeroed pmd. */ +static pmd_t *pmd_cache_alloc(int idx) +{ + pmd_t *pmd; + + if (idx >= USER_PTRS_PER_PGD) { + pmd = (pmd_t *)__get_free_page(GFP_KERNEL); + + if (pmd) + memcpy(pmd, + (void *)pgd_page_vaddr(swapper_pg_dir[idx]), + sizeof(pmd_t) * PTRS_PER_PMD); + } else + pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL); + + return pmd; +} + +static void pmd_cache_free(pmd_t *pmd, int idx) +{ + if (idx >= USER_PTRS_PER_PGD) + free_page((unsigned long)pmd); + else + kmem_cache_free(pmd_cache, pmd); +} + pgd_t *pgd_alloc(struct mm_struct *mm) { int i; @@ -276,10 +326,12 @@ pgd_t *pgd_alloc(struct mm_struct *mm) if (PTRS_PER_PMD == 1 || !pgd) return pgd; - for (i = 0; i < USER_PTRS_PER_PGD; ++i) { - pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL); + for (i = 0; i < UNSHARED_PTRS_PER_PGD; ++i) { + pmd_t *pmd = pmd_cache_alloc(i); + if (!pmd) goto out_oom; + paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT); set_pgd(&pgd[i], __pgd(1 + __pa(pmd))); } @@ -290,7 +342,7 @@ out_oom: pgd_t pgdent = pgd[i]; void* pmd = (void *)__va(pgd_val(pgdent)-1); paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT); - kmem_cache_free(pmd_cache, pmd); + pmd_cache_free(pmd, i); } kmem_cache_free(pgd_cache, pgd); return NULL; @@ -302,11 +354,11 @@ void pgd_free(pgd_t *pgd) /* in the PAE case user pgd entries are overwritten before usage */ if (PTRS_PER_PMD > 1) - for (i = 0; i < USER_PTRS_PER_PGD; ++i) { + for (i = 0; i < UNSHARED_PTRS_PER_PGD; ++i) { pgd_t pgdent = pgd[i]; void* pmd = (void *)__va(pgd_val(pgdent)-1); paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT); - kmem_cache_free(pmd_cache, pmd); + pmd_cache_free(pmd, i); } /* in the non-PAE case, free_pgtables() clears user pgd entries */ kmem_cache_free(pgd_cache, pgd); diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index c49b44cdd8ee..f93599dc7756 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -35,6 +35,7 @@ struct desc_struct; struct paravirt_ops { unsigned int kernel_rpl; + int shared_kernel_pmd; int paravirt_enabled; const char *name; diff --git a/include/asm-i386/pgtable-2level-defs.h b/include/asm-i386/pgtable-2level-defs.h index 02518079f816..0f71c9f13da4 100644 --- a/include/asm-i386/pgtable-2level-defs.h +++ b/include/asm-i386/pgtable-2level-defs.h @@ -1,6 +1,8 @@ #ifndef _I386_PGTABLE_2LEVEL_DEFS_H #define _I386_PGTABLE_2LEVEL_DEFS_H +#define SHARED_KERNEL_PMD 0 + /* * traditional i386 two-level paging structure: */ diff --git a/include/asm-i386/pgtable-2level.h b/include/asm-i386/pgtable-2level.h index 043a2bcfa86a..781fe4bcc962 100644 --- a/include/asm-i386/pgtable-2level.h +++ b/include/asm-i386/pgtable-2level.h @@ -82,6 +82,4 @@ static inline int pte_exec_kernel(pte_t pte) #define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_low }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) -void vmalloc_sync_all(void); - #endif /* _I386_PGTABLE_2LEVEL_H */ diff --git a/include/asm-i386/pgtable-3level-defs.h b/include/asm-i386/pgtable-3level-defs.h index eb3a1ea88671..c0df89f66e8b 100644 --- a/include/asm-i386/pgtable-3level-defs.h +++ b/include/asm-i386/pgtable-3level-defs.h @@ -1,6 +1,12 @@ #ifndef _I386_PGTABLE_3LEVEL_DEFS_H #define _I386_PGTABLE_3LEVEL_DEFS_H +#ifdef CONFIG_PARAVIRT +#define SHARED_KERNEL_PMD (paravirt_ops.shared_kernel_pmd) +#else +#define SHARED_KERNEL_PMD 1 +#endif + /* * PGDIR_SHIFT determines what a top-level page table entry can map */ diff --git a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h index be6017f37a91..664bfee5a2f2 100644 --- a/include/asm-i386/pgtable-3level.h +++ b/include/asm-i386/pgtable-3level.h @@ -200,6 +200,4 @@ static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) #define __pmd_free_tlb(tlb, x) do { } while (0) -#define vmalloc_sync_all() ((void)0) - #endif /* _I386_PGTABLE_3LEVEL_H */ diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index 0790ad6ed440..5b88a6a1278e 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -243,6 +243,8 @@ static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; re static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; } static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return pte; } +extern void vmalloc_sync_all(void); + #ifdef CONFIG_X86_PAE # include #else -- cgit v1.2.3-59-g8ed1b From d6dd61c831226f9cd7750885da04d360d6455101 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:14 +0200 Subject: [PATCH] x86: PARAVIRT: add hooks to intercept mm creation and destruction Add hooks to allow a paravirt implementation to track the lifetime of an mm. Paravirtualization requires three hooks, but only two are needed in common code. They are: arch_dup_mmap, which is called when a new mmap is created at fork arch_exit_mmap, which is called when the last process reference to an mm is dropped, which typically happens on exit and exec. The third hook is activate_mm, which is called from the arch-specific activate_mm() macro/function, and so doesn't need stub versions for other architectures. It's called when an mm is first used. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: linux-arch@vger.kernel.org Cc: James Bottomley Acked-by: Ingo Molnar --- arch/i386/kernel/paravirt.c | 4 ++++ include/asm-alpha/mmu_context.h | 1 + include/asm-arm/mmu_context.h | 1 + include/asm-arm26/mmu_context.h | 2 ++ include/asm-avr32/mmu_context.h | 1 + include/asm-cris/mmu_context.h | 2 ++ include/asm-frv/mmu_context.h | 1 + include/asm-generic/mm_hooks.h | 18 ++++++++++++++++++ include/asm-h8300/mmu_context.h | 1 + include/asm-i386/mmu_context.h | 17 +++++++++++++++-- include/asm-i386/paravirt.h | 23 +++++++++++++++++++++++ include/asm-ia64/mmu_context.h | 1 + include/asm-m32r/mmu_context.h | 1 + include/asm-m68k/mmu_context.h | 1 + include/asm-m68knommu/mmu_context.h | 1 + include/asm-mips/mmu_context.h | 1 + include/asm-parisc/mmu_context.h | 1 + include/asm-powerpc/mmu_context.h | 1 + include/asm-ppc/mmu_context.h | 1 + include/asm-s390/mmu_context.h | 2 ++ include/asm-sh/mmu_context.h | 1 + include/asm-sh64/mmu_context.h | 2 +- include/asm-sparc/mmu_context.h | 2 ++ include/asm-sparc64/mmu_context.h | 1 + include/asm-um/mmu_context.h | 2 ++ include/asm-v850/mmu_context.h | 2 ++ include/asm-x86_64/mmu_context.h | 1 + include/asm-xtensa/mmu_context.h | 1 + kernel/fork.c | 2 ++ mm/mmap.c | 4 ++++ 30 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 include/asm-generic/mm_hooks.h (limited to 'arch') diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index 2040a831d5b3..54cc14d99740 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -237,6 +237,10 @@ struct paravirt_ops paravirt_ops = { .irq_enable_sysexit = native_irq_enable_sysexit, .iret = native_iret, + .dup_mmap = paravirt_nop, + .exit_mmap = paravirt_nop, + .activate_mm = paravirt_nop, + .startup_ipi_hook = paravirt_nop, }; diff --git a/include/asm-alpha/mmu_context.h b/include/asm-alpha/mmu_context.h index fe249e9d3360..0bd7bd2ccb90 100644 --- a/include/asm-alpha/mmu_context.h +++ b/include/asm-alpha/mmu_context.h @@ -10,6 +10,7 @@ #include #include #include +#include /* * Force a context reload. This is needed when we change the page diff --git a/include/asm-arm/mmu_context.h b/include/asm-arm/mmu_context.h index d1a65b1edcaa..f8755c818b54 100644 --- a/include/asm-arm/mmu_context.h +++ b/include/asm-arm/mmu_context.h @@ -16,6 +16,7 @@ #include #include #include +#include void __check_kvm_seq(struct mm_struct *mm); diff --git a/include/asm-arm26/mmu_context.h b/include/asm-arm26/mmu_context.h index 1a929bfe5c3a..16c821f81b8d 100644 --- a/include/asm-arm26/mmu_context.h +++ b/include/asm-arm26/mmu_context.h @@ -13,6 +13,8 @@ #ifndef __ASM_ARM_MMU_CONTEXT_H #define __ASM_ARM_MMU_CONTEXT_H +#include + #define init_new_context(tsk,mm) 0 #define destroy_context(mm) do { } while(0) diff --git a/include/asm-avr32/mmu_context.h b/include/asm-avr32/mmu_context.h index 31add1ae8089..c37c391faef6 100644 --- a/include/asm-avr32/mmu_context.h +++ b/include/asm-avr32/mmu_context.h @@ -15,6 +15,7 @@ #include #include #include +#include /* * The MMU "context" consists of two things: diff --git a/include/asm-cris/mmu_context.h b/include/asm-cris/mmu_context.h index e6e659dc757b..72ba08dcfd18 100644 --- a/include/asm-cris/mmu_context.h +++ b/include/asm-cris/mmu_context.h @@ -1,6 +1,8 @@ #ifndef __CRIS_MMU_CONTEXT_H #define __CRIS_MMU_CONTEXT_H +#include + extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm); extern void get_mmu_context(struct mm_struct *mm); extern void destroy_context(struct mm_struct *mm); diff --git a/include/asm-frv/mmu_context.h b/include/asm-frv/mmu_context.h index 72edcaaccd5d..c7daa395156a 100644 --- a/include/asm-frv/mmu_context.h +++ b/include/asm-frv/mmu_context.h @@ -15,6 +15,7 @@ #include #include #include +#include static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { diff --git a/include/asm-generic/mm_hooks.h b/include/asm-generic/mm_hooks.h new file mode 100644 index 000000000000..67dea8123683 --- /dev/null +++ b/include/asm-generic/mm_hooks.h @@ -0,0 +1,18 @@ +/* + * Define generic no-op hooks for arch_dup_mmap and arch_exit_mmap, to + * be included in asm-FOO/mmu_context.h for any arch FOO which doesn't + * need to hook these. + */ +#ifndef _ASM_GENERIC_MM_HOOKS_H +#define _ASM_GENERIC_MM_HOOKS_H + +static inline void arch_dup_mmap(struct mm_struct *oldmm, + struct mm_struct *mm) +{ +} + +static inline void arch_exit_mmap(struct mm_struct *mm) +{ +} + +#endif /* _ASM_GENERIC_MM_HOOKS_H */ diff --git a/include/asm-h8300/mmu_context.h b/include/asm-h8300/mmu_context.h index 5c165f7bee0e..f44b730da54d 100644 --- a/include/asm-h8300/mmu_context.h +++ b/include/asm-h8300/mmu_context.h @@ -4,6 +4,7 @@ #include #include #include +#include static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { diff --git a/include/asm-i386/mmu_context.h b/include/asm-i386/mmu_context.h index e6aa30f8de5b..8198d1cca1f3 100644 --- a/include/asm-i386/mmu_context.h +++ b/include/asm-i386/mmu_context.h @@ -5,6 +5,16 @@ #include #include #include +#include +#ifndef CONFIG_PARAVIRT +#include + +static inline void paravirt_activate_mm(struct mm_struct *prev, + struct mm_struct *next) +{ +} +#endif /* !CONFIG_PARAVIRT */ + /* * Used for LDT copy/destruction. @@ -65,7 +75,10 @@ static inline void switch_mm(struct mm_struct *prev, #define deactivate_mm(tsk, mm) \ asm("movl %0,%%gs": :"r" (0)); -#define activate_mm(prev, next) \ - switch_mm((prev),(next),NULL) +#define activate_mm(prev, next) \ + do { \ + paravirt_activate_mm(prev, next); \ + switch_mm((prev),(next),NULL); \ + } while(0); #endif diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index f93599dc7756..61c03f1e0c29 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -119,6 +119,12 @@ struct paravirt_ops void (*io_delay)(void); + void (*activate_mm)(struct mm_struct *prev, + struct mm_struct *next); + void (*dup_mmap)(struct mm_struct *oldmm, + struct mm_struct *mm); + void (*exit_mmap)(struct mm_struct *mm); + #ifdef CONFIG_X86_LOCAL_APIC void (*apic_write)(unsigned long reg, unsigned long v); void (*apic_write_atomic)(unsigned long reg, unsigned long v); @@ -395,6 +401,23 @@ static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip, } #endif +static inline void paravirt_activate_mm(struct mm_struct *prev, + struct mm_struct *next) +{ + paravirt_ops.activate_mm(prev, next); +} + +static inline void arch_dup_mmap(struct mm_struct *oldmm, + struct mm_struct *mm) +{ + paravirt_ops.dup_mmap(oldmm, mm); +} + +static inline void arch_exit_mmap(struct mm_struct *mm) +{ + paravirt_ops.exit_mmap(mm); +} + #define __flush_tlb() paravirt_ops.flush_tlb_user() #define __flush_tlb_global() paravirt_ops.flush_tlb_kernel() #define __flush_tlb_single(addr) paravirt_ops.flush_tlb_single(addr) diff --git a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h index b5c65081a3aa..cef2400983fa 100644 --- a/include/asm-ia64/mmu_context.h +++ b/include/asm-ia64/mmu_context.h @@ -29,6 +29,7 @@ #include #include +#include struct ia64_ctx { spinlock_t lock; diff --git a/include/asm-m32r/mmu_context.h b/include/asm-m32r/mmu_context.h index 1f40d4a0acf1..91909e5dd9d0 100644 --- a/include/asm-m32r/mmu_context.h +++ b/include/asm-m32r/mmu_context.h @@ -15,6 +15,7 @@ #include #include #include +#include /* * Cache of MMU context last used. diff --git a/include/asm-m68k/mmu_context.h b/include/asm-m68k/mmu_context.h index 231d11bd8e32..894dacbcee14 100644 --- a/include/asm-m68k/mmu_context.h +++ b/include/asm-m68k/mmu_context.h @@ -1,6 +1,7 @@ #ifndef __M68K_MMU_CONTEXT_H #define __M68K_MMU_CONTEXT_H +#include static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { diff --git a/include/asm-m68knommu/mmu_context.h b/include/asm-m68knommu/mmu_context.h index 6c077d3a2572..9ccee4278c97 100644 --- a/include/asm-m68knommu/mmu_context.h +++ b/include/asm-m68knommu/mmu_context.h @@ -4,6 +4,7 @@ #include #include #include +#include static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { diff --git a/include/asm-mips/mmu_context.h b/include/asm-mips/mmu_context.h index fe065d6070ca..65024ffd7879 100644 --- a/include/asm-mips/mmu_context.h +++ b/include/asm-mips/mmu_context.h @@ -20,6 +20,7 @@ #include #include #endif /* SMTC */ +#include /* * For the fast tlb miss handlers, we keep a per cpu array of pointers diff --git a/include/asm-parisc/mmu_context.h b/include/asm-parisc/mmu_context.h index 9c05836239a2..bad690298f0c 100644 --- a/include/asm-parisc/mmu_context.h +++ b/include/asm-parisc/mmu_context.h @@ -5,6 +5,7 @@ #include #include #include +#include static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { diff --git a/include/asm-powerpc/mmu_context.h b/include/asm-powerpc/mmu_context.h index 083ac917bd29..c0d7795e3d25 100644 --- a/include/asm-powerpc/mmu_context.h +++ b/include/asm-powerpc/mmu_context.h @@ -10,6 +10,7 @@ #include #include #include +#include /* * Copyright (C) 2001 PPC 64 Team, IBM Corp diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h index 2bc8589cc451..a6441a063e5d 100644 --- a/include/asm-ppc/mmu_context.h +++ b/include/asm-ppc/mmu_context.h @@ -6,6 +6,7 @@ #include #include #include +#include /* * On 32-bit PowerPC 6xx/7xx/7xxx CPUs, we use a set of 16 VSIDs diff --git a/include/asm-s390/mmu_context.h b/include/asm-s390/mmu_context.h index 1d21da220d49..501cb9b06314 100644 --- a/include/asm-s390/mmu_context.h +++ b/include/asm-s390/mmu_context.h @@ -10,6 +10,8 @@ #define __S390_MMU_CONTEXT_H #include +#include + /* * get a new mmu context.. S390 don't know about contexts. */ diff --git a/include/asm-sh/mmu_context.h b/include/asm-sh/mmu_context.h index 342024425b7d..01acaaae9751 100644 --- a/include/asm-sh/mmu_context.h +++ b/include/asm-sh/mmu_context.h @@ -12,6 +12,7 @@ #include #include #include +#include /* * The MMU "context" consists of two things: diff --git a/include/asm-sh64/mmu_context.h b/include/asm-sh64/mmu_context.h index 8c860dab2d0e..507bf72bb8e1 100644 --- a/include/asm-sh64/mmu_context.h +++ b/include/asm-sh64/mmu_context.h @@ -27,7 +27,7 @@ extern unsigned long mmu_context_cache; #include - +#include /* Current mm's pgd */ extern pgd_t *mmu_pdtp_cache; diff --git a/include/asm-sparc/mmu_context.h b/include/asm-sparc/mmu_context.h index ed1e01d04d21..671a997b9e69 100644 --- a/include/asm-sparc/mmu_context.h +++ b/include/asm-sparc/mmu_context.h @@ -5,6 +5,8 @@ #ifndef __ASSEMBLY__ +#include + static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { } diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h index 2337eb487719..8d129032013e 100644 --- a/include/asm-sparc64/mmu_context.h +++ b/include/asm-sparc64/mmu_context.h @@ -9,6 +9,7 @@ #include #include #include +#include static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { diff --git a/include/asm-um/mmu_context.h b/include/asm-um/mmu_context.h index f709c784bf12..9aa4b44e8cc1 100644 --- a/include/asm-um/mmu_context.h +++ b/include/asm-um/mmu_context.h @@ -6,6 +6,8 @@ #ifndef __UM_MMU_CONTEXT_H #define __UM_MMU_CONTEXT_H +#include + #include "linux/sched.h" #include "choose-mode.h" #include "um_mmu.h" diff --git a/include/asm-v850/mmu_context.h b/include/asm-v850/mmu_context.h index f521c8050d3c..01daacd5474e 100644 --- a/include/asm-v850/mmu_context.h +++ b/include/asm-v850/mmu_context.h @@ -1,6 +1,8 @@ #ifndef __V850_MMU_CONTEXT_H__ #define __V850_MMU_CONTEXT_H__ +#include + #define destroy_context(mm) ((void)0) #define init_new_context(tsk,mm) 0 #define switch_mm(prev,next,tsk) ((void)0) diff --git a/include/asm-x86_64/mmu_context.h b/include/asm-x86_64/mmu_context.h index af03b9f852d6..0cce83a78378 100644 --- a/include/asm-x86_64/mmu_context.h +++ b/include/asm-x86_64/mmu_context.h @@ -7,6 +7,7 @@ #include #include #include +#include /* * possibly do the LDT unload here? diff --git a/include/asm-xtensa/mmu_context.h b/include/asm-xtensa/mmu_context.h index f14851f086c3..92f948392ebc 100644 --- a/include/asm-xtensa/mmu_context.h +++ b/include/asm-xtensa/mmu_context.h @@ -18,6 +18,7 @@ #include #include #include +#include #define XCHAL_MMU_ASID_BITS 8 diff --git a/kernel/fork.c b/kernel/fork.c index 6af959c034d8..ffccefb28b6a 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -286,6 +286,8 @@ static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) if (retval) goto out; } + /* a new mm has just been created */ + arch_dup_mmap(oldmm, mm); retval = 0; out: up_write(&mm->mmap_sem); diff --git a/mm/mmap.c b/mm/mmap.c index 84f997da78d7..88da687bde89 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -29,6 +29,7 @@ #include #include #include +#include #ifndef arch_mmap_check #define arch_mmap_check(addr, len, flags) (0) @@ -1979,6 +1980,9 @@ void exit_mmap(struct mm_struct *mm) unsigned long nr_accounted = 0; unsigned long end; + /* mm's last user has gone, and its about to be pulled down */ + arch_exit_mmap(mm); + lru_add_drain(); flush_cache_mm(mm); tlb = tlb_gather_mmu(mm, 1); -- cgit v1.2.3-59-g8ed1b From 98de032b681d8a7532d44dfc66aa5c0c1c755a9d Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:14 +0200 Subject: [PATCH] i386: PARAVIRT: rename struct paravirt_patch to paravirt_patch_site for clarity Rename struct paravirt_patch to paravirt_patch_site, so that it clearly refers to a callsite, and not the patch which may be applied to that callsite. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Rusty Russell Cc: Zachary Amsden --- arch/i386/kernel/alternative.c | 7 ++++--- include/asm-i386/alternative.h | 8 +++++--- include/asm-i386/paravirt.h | 5 ++++- 3 files changed, 13 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index 915b6c4d9baf..dae3ded9041c 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -325,9 +325,10 @@ void alternatives_smp_switch(int smp) #endif #ifdef CONFIG_PARAVIRT -void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end) +void apply_paravirt(struct paravirt_patch_site *start, + struct paravirt_patch_site *end) { - struct paravirt_patch *p; + struct paravirt_patch_site *p; for (p = start; p < end; p++) { unsigned int used; @@ -342,7 +343,7 @@ void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end) /* Sync to be conservative, in case we patched following instructions */ sync_core(); } -extern struct paravirt_patch __start_parainstructions[], +extern struct paravirt_patch_site __start_parainstructions[], __stop_parainstructions[]; #endif /* CONFIG_PARAVIRT */ diff --git a/include/asm-i386/alternative.h b/include/asm-i386/alternative.h index 4d518eebe461..5b59d07e9d29 100644 --- a/include/asm-i386/alternative.h +++ b/include/asm-i386/alternative.h @@ -115,12 +115,14 @@ static inline void alternatives_smp_switch(int smp) {} #define LOCK_PREFIX "" #endif -struct paravirt_patch; +struct paravirt_patch_site; #ifdef CONFIG_PARAVIRT -void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end); +void apply_paravirt(struct paravirt_patch_site *start, + struct paravirt_patch_site *end); #else static inline void -apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end) +apply_paravirt(struct paravirt_patch_site *start, + struct paravirt_patch_site *end) {} #define __start_parainstructions NULL #define __stop_parainstructions NULL diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index 61c03f1e0c29..b4cc2fc4031e 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -505,13 +505,16 @@ void _paravirt_nop(void); #define paravirt_nop ((void *)_paravirt_nop) /* These all sit in the .parainstructions section to tell us what to patch. */ -struct paravirt_patch { +struct paravirt_patch_site { u8 *instr; /* original instructions */ u8 instrtype; /* type of this instruction */ u8 len; /* length of original instruction */ u16 clobbers; /* what registers you may clobber */ }; +extern struct paravirt_patch_site __parainstructions[], + __parainstructions_end[]; + #define paravirt_alt(insn_string, typenum, clobber) \ "771:\n\t" insn_string "\n" "772:\n" \ ".pushsection .parainstructions,\"a\"\n" \ -- cgit v1.2.3-59-g8ed1b From d582203578a1f3d408e27bb9042e8635954cd320 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:14 +0200 Subject: [PATCH] i386: PARAVIRT: Use patch site IDs computed from offset in paravirt_ops structure Use patch type identifiers derived from the offset of the operation in the paravirt_ops structure. This avoids having to maintain a separate enum for patch site types. Also, since the identifier is derived from the offset into paravirt_ops, the offset can be derived from the identifier. This is used to remove replicated information in the various callsite macros, which has been a source of bugs in the past. This patch also drops the fused save_fl+cli operation, which doesn't really add much and makes things more complex - specifically because it breaks the 1:1 relationship between identifiers and offsets. If this operation turns out to be particularly beneficial, then the right answer is to define a new entrypoint for it. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Rusty Russell Cc: Zachary Amsden --- arch/i386/kernel/paravirt.c | 14 ++-- arch/i386/kernel/vmi.c | 39 ++-------- include/asm-i386/paravirt.h | 177 +++++++++++++++++++++++--------------------- 3 files changed, 104 insertions(+), 126 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index 54cc14d99740..f2982832d3b9 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -58,7 +58,6 @@ DEF_NATIVE(cli, "cli"); DEF_NATIVE(sti, "sti"); DEF_NATIVE(popf, "push %eax; popf"); DEF_NATIVE(pushf, "pushf; pop %eax"); -DEF_NATIVE(pushf_cli, "pushf; pop %eax; cli"); DEF_NATIVE(iret, "iret"); DEF_NATIVE(sti_sysexit, "sti; sysexit"); @@ -66,13 +65,12 @@ static const struct native_insns { const char *start, *end; } native_insns[] = { - [PARAVIRT_IRQ_DISABLE] = { start_cli, end_cli }, - [PARAVIRT_IRQ_ENABLE] = { start_sti, end_sti }, - [PARAVIRT_RESTORE_FLAGS] = { start_popf, end_popf }, - [PARAVIRT_SAVE_FLAGS] = { start_pushf, end_pushf }, - [PARAVIRT_SAVE_FLAGS_IRQ_DISABLE] = { start_pushf_cli, end_pushf_cli }, - [PARAVIRT_INTERRUPT_RETURN] = { start_iret, end_iret }, - [PARAVIRT_STI_SYSEXIT] = { start_sti_sysexit, end_sti_sysexit }, + [PARAVIRT_PATCH(irq_disable)] = { start_cli, end_cli }, + [PARAVIRT_PATCH(irq_enable)] = { start_sti, end_sti }, + [PARAVIRT_PATCH(restore_fl)] = { start_popf, end_popf }, + [PARAVIRT_PATCH(save_fl)] = { start_pushf, end_pushf }, + [PARAVIRT_PATCH(iret)] = { start_iret, end_iret }, + [PARAVIRT_PATCH(irq_enable_sysexit)] = { start_sti_sysexit, end_sti_sysexit }, }; static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index ea77d93f59dd..b8d01c3cbff4 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c @@ -83,11 +83,6 @@ extern struct paravirt_patch __start_parainstructions[], #define MNEM_JMP 0xe9 #define MNEM_RET 0xc3 -static char irq_save_disable_callout[] = { - MNEM_CALL, 0, 0, 0, 0, - MNEM_CALL, 0, 0, 0, 0, - MNEM_RET -}; #define IRQ_PATCH_INT_MASK 0 #define IRQ_PATCH_DISABLE 5 @@ -135,33 +130,17 @@ static unsigned patch_internal(int call, unsigned len, void *insns) static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, unsigned len) { switch (type) { - case PARAVIRT_IRQ_DISABLE: + case PARAVIRT_PATCH(irq_disable): return patch_internal(VMI_CALL_DisableInterrupts, len, insns); - case PARAVIRT_IRQ_ENABLE: + case PARAVIRT_PATCH(irq_enable): return patch_internal(VMI_CALL_EnableInterrupts, len, insns); - case PARAVIRT_RESTORE_FLAGS: + case PARAVIRT_PATCH(restore_fl): return patch_internal(VMI_CALL_SetInterruptMask, len, insns); - case PARAVIRT_SAVE_FLAGS: + case PARAVIRT_PATCH(save_fl): return patch_internal(VMI_CALL_GetInterruptMask, len, insns); - case PARAVIRT_SAVE_FLAGS_IRQ_DISABLE: - if (len >= 10) { - patch_internal(VMI_CALL_GetInterruptMask, len, insns); - patch_internal(VMI_CALL_DisableInterrupts, len-5, insns+5); - return 10; - } else { - /* - * You bastards didn't leave enough room to - * patch save_flags_irq_disable inline. Patch - * to a helper - */ - BUG_ON(len < 5); - *(char *)insns = MNEM_CALL; - patch_offset(insns, irq_save_disable_callout); - return 5; - } - case PARAVIRT_INTERRUPT_RETURN: + case PARAVIRT_PATCH(iret): return patch_internal(VMI_CALL_IRET, len, insns); - case PARAVIRT_STI_SYSEXIT: + case PARAVIRT_PATCH(irq_enable_sysexit): return patch_internal(VMI_CALL_SYSEXIT, len, insns); default: break; @@ -796,12 +775,6 @@ static inline int __init activate_vmi(void) para_fill(irq_disable, DisableInterrupts); para_fill(irq_enable, EnableInterrupts); - /* irq_save_disable !!! sheer pain */ - patch_offset(&irq_save_disable_callout[IRQ_PATCH_INT_MASK], - (char *)paravirt_ops.save_fl); - patch_offset(&irq_save_disable_callout[IRQ_PATCH_DISABLE], - (char *)paravirt_ops.irq_disable); - para_fill(wbinvd, WBINVD); para_fill(read_tsc, RDTSC); diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index b4cc2fc4031e..1dbc01f4ed4d 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -4,19 +4,8 @@ * para-virtualization: those hooks are defined here. */ #ifdef CONFIG_PARAVIRT -#include #include -/* These are the most performance critical ops, so we want to be able to patch - * callers */ -#define PARAVIRT_IRQ_DISABLE 0 -#define PARAVIRT_IRQ_ENABLE 1 -#define PARAVIRT_RESTORE_FLAGS 2 -#define PARAVIRT_SAVE_FLAGS 3 -#define PARAVIRT_SAVE_FLAGS_IRQ_DISABLE 4 -#define PARAVIRT_INTERRUPT_RETURN 5 -#define PARAVIRT_STI_SYSEXIT 6 - /* Bitmask of what can be clobbered: usually at least eax. */ #define CLBR_NONE 0x0 #define CLBR_EAX 0x1 @@ -191,6 +180,28 @@ struct paravirt_ops extern struct paravirt_ops paravirt_ops; +#define PARAVIRT_PATCH(x) \ + (offsetof(struct paravirt_ops, x) / sizeof(void *)) + +#define paravirt_type(type) \ + [paravirt_typenum] "i" (PARAVIRT_PATCH(type)) +#define paravirt_clobber(clobber) \ + [paravirt_clobber] "i" (clobber) + +#define PARAVIRT_CALL "call *paravirt_ops+%c[paravirt_typenum]*4;" + +#define _paravirt_alt(insn_string, type, clobber) \ + "771:\n\t" insn_string "\n" "772:\n" \ + ".pushsection .parainstructions,\"a\"\n" \ + " .long 771b\n" \ + " .byte " type "\n" \ + " .byte 772b-771b\n" \ + " .short " clobber "\n" \ + ".popsection\n" + +#define paravirt_alt(insn_string) \ + _paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]") + #define paravirt_enabled() (paravirt_ops.paravirt_enabled) static inline void load_esp0(struct tss_struct *tss, @@ -515,93 +526,89 @@ struct paravirt_patch_site { extern struct paravirt_patch_site __parainstructions[], __parainstructions_end[]; -#define paravirt_alt(insn_string, typenum, clobber) \ - "771:\n\t" insn_string "\n" "772:\n" \ - ".pushsection .parainstructions,\"a\"\n" \ - " .long 771b\n" \ - " .byte " __stringify(typenum) "\n" \ - " .byte 772b-771b\n" \ - " .short " __stringify(clobber) "\n" \ - ".popsection" - static inline unsigned long __raw_local_save_flags(void) { unsigned long f; - __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;" - "call *%1;" - "popl %%edx; popl %%ecx", - PARAVIRT_SAVE_FLAGS, CLBR_NONE) - : "=a"(f): "m"(paravirt_ops.save_fl) - : "memory", "cc"); + asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;" + PARAVIRT_CALL + "popl %%edx; popl %%ecx") + : "=a"(f) + : paravirt_type(save_fl), + paravirt_clobber(CLBR_NONE) + : "memory", "cc"); return f; } static inline void raw_local_irq_restore(unsigned long f) { - __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;" - "call *%1;" - "popl %%edx; popl %%ecx", - PARAVIRT_RESTORE_FLAGS, CLBR_EAX) - : "=a"(f) : "m" (paravirt_ops.restore_fl), "0"(f) - : "memory", "cc"); + asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;" + PARAVIRT_CALL + "popl %%edx; popl %%ecx") + : "=a"(f) + : "0"(f), + paravirt_type(restore_fl), + paravirt_clobber(CLBR_EAX) + : "memory", "cc"); } static inline void raw_local_irq_disable(void) { - __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;" - "call *%0;" - "popl %%edx; popl %%ecx", - PARAVIRT_IRQ_DISABLE, CLBR_EAX) - : : "m" (paravirt_ops.irq_disable) - : "memory", "eax", "cc"); + asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;" + PARAVIRT_CALL + "popl %%edx; popl %%ecx") + : + : paravirt_type(irq_disable), + paravirt_clobber(CLBR_EAX) + : "memory", "eax", "cc"); } static inline void raw_local_irq_enable(void) { - __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;" - "call *%0;" - "popl %%edx; popl %%ecx", - PARAVIRT_IRQ_ENABLE, CLBR_EAX) - : : "m" (paravirt_ops.irq_enable) - : "memory", "eax", "cc"); + asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;" + PARAVIRT_CALL + "popl %%edx; popl %%ecx") + : + : paravirt_type(irq_enable), + paravirt_clobber(CLBR_EAX) + : "memory", "eax", "cc"); } static inline unsigned long __raw_local_irq_save(void) { unsigned long f; - __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;" - "call *%1; pushl %%eax;" - "call *%2; popl %%eax;" - "popl %%edx; popl %%ecx", - PARAVIRT_SAVE_FLAGS_IRQ_DISABLE, - CLBR_NONE) - : "=a"(f) - : "m" (paravirt_ops.save_fl), - "m" (paravirt_ops.irq_disable) - : "memory", "cc"); + f = __raw_local_save_flags(); + raw_local_irq_disable(); return f; } -#define CLI_STRING paravirt_alt("pushl %%ecx; pushl %%edx;" \ - "call *paravirt_ops+%c[irq_disable];" \ - "popl %%edx; popl %%ecx", \ - PARAVIRT_IRQ_DISABLE, CLBR_EAX) +#define CLI_STRING \ + _paravirt_alt("pushl %%ecx; pushl %%edx;" \ + "call *paravirt_ops+%c[paravirt_cli_type]*4;" \ + "popl %%edx; popl %%ecx", \ + "%c[paravirt_cli_type]", "%c[paravirt_clobber]") + +#define STI_STRING \ + _paravirt_alt("pushl %%ecx; pushl %%edx;" \ + "call *paravirt_ops+%c[paravirt_sti_type]*4;" \ + "popl %%edx; popl %%ecx", \ + "%c[paravirt_sti_type]", "%c[paravirt_clobber]") -#define STI_STRING paravirt_alt("pushl %%ecx; pushl %%edx;" \ - "call *paravirt_ops+%c[irq_enable];" \ - "popl %%edx; popl %%ecx", \ - PARAVIRT_IRQ_ENABLE, CLBR_EAX) #define CLI_STI_CLOBBERS , "%eax" -#define CLI_STI_INPUT_ARGS \ +#define CLI_STI_INPUT_ARGS \ , \ - [irq_disable] "i" (offsetof(struct paravirt_ops, irq_disable)), \ - [irq_enable] "i" (offsetof(struct paravirt_ops, irq_enable)) + [paravirt_cli_type] "i" (PARAVIRT_PATCH(irq_disable)), \ + [paravirt_sti_type] "i" (PARAVIRT_PATCH(irq_enable)), \ + paravirt_clobber(CLBR_EAX) + +#undef PARAVIRT_CALL #else /* __ASSEMBLY__ */ -#define PARA_PATCH(ptype, clobbers, ops) \ +#define PARA_PATCH(off) ((off) / 4) + +#define PARA_SITE(ptype, clobbers, ops) \ 771:; \ ops; \ 772:; \ @@ -612,25 +619,25 @@ static inline unsigned long __raw_local_irq_save(void) .short clobbers; \ .popsection -#define INTERRUPT_RETURN \ - PARA_PATCH(PARAVIRT_INTERRUPT_RETURN, CLBR_ANY, \ - jmp *%cs:paravirt_ops+PARAVIRT_iret) - -#define DISABLE_INTERRUPTS(clobbers) \ - PARA_PATCH(PARAVIRT_IRQ_DISABLE, clobbers, \ - pushl %ecx; pushl %edx; \ - call *paravirt_ops+PARAVIRT_irq_disable; \ - popl %edx; popl %ecx) \ - -#define ENABLE_INTERRUPTS(clobbers) \ - PARA_PATCH(PARAVIRT_IRQ_ENABLE, clobbers, \ - pushl %ecx; pushl %edx; \ - call *%cs:paravirt_ops+PARAVIRT_irq_enable; \ - popl %edx; popl %ecx) - -#define ENABLE_INTERRUPTS_SYSEXIT \ - PARA_PATCH(PARAVIRT_STI_SYSEXIT, CLBR_ANY, \ - jmp *%cs:paravirt_ops+PARAVIRT_irq_enable_sysexit) +#define INTERRUPT_RETURN \ + PARA_SITE(PARA_PATCH(PARAVIRT_iret), CLBR_ANY, \ + jmp *%cs:paravirt_ops+PARAVIRT_iret) + +#define DISABLE_INTERRUPTS(clobbers) \ + PARA_SITE(PARA_PATCH(PARAVIRT_irq_disable), clobbers, \ + pushl %ecx; pushl %edx; \ + call *%cs:paravirt_ops+PARAVIRT_irq_disable; \ + popl %edx; popl %ecx) \ + +#define ENABLE_INTERRUPTS(clobbers) \ + PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable), clobbers, \ + pushl %ecx; pushl %edx; \ + call *%cs:paravirt_ops+PARAVIRT_irq_enable; \ + popl %edx; popl %ecx) + +#define ENABLE_INTERRUPTS_SYSEXIT \ + PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable_sysexit), CLBR_ANY, \ + jmp *%cs:paravirt_ops+PARAVIRT_irq_enable_sysexit) #define GET_CR0_INTO_EAX \ call *paravirt_ops+PARAVIRT_read_cr0 -- cgit v1.2.3-59-g8ed1b From 42c24fa22e86365055fc931d833f26165e687c19 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:14 +0200 Subject: [PATCH] i386: PARAVIRT: Fix patch site clobbers to include return register Fix a few clobbers to include the return register. The clobbers set is the set of all registers modified (or may be modified) by the code snippet, regardless of whether it was deliberate or accidental. Also, make sure that callsites which are used in contexts which don't allow clobbers actually save and restore all clobberable registers. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Rusty Russell Cc: Zachary Amsden --- arch/i386/kernel/entry.S | 2 +- include/asm-i386/paravirt.h | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index e901952dff37..e07473c0d3e7 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -338,7 +338,7 @@ sysenter_past_esp: jae syscall_badsys call *sys_call_table(,%eax,4) movl %eax,PT_EAX(%esp) - DISABLE_INTERRUPTS(CLBR_ECX|CLBR_EDX) + DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF movl TI_flags(%ebp), %ecx testw $_TIF_ALLWORK_MASK, %cx diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index 1dbc01f4ed4d..87fd4317bee9 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -535,7 +535,7 @@ static inline unsigned long __raw_local_save_flags(void) "popl %%edx; popl %%ecx") : "=a"(f) : paravirt_type(save_fl), - paravirt_clobber(CLBR_NONE) + paravirt_clobber(CLBR_EAX) : "memory", "cc"); return f; } @@ -620,27 +620,29 @@ static inline unsigned long __raw_local_irq_save(void) .popsection #define INTERRUPT_RETURN \ - PARA_SITE(PARA_PATCH(PARAVIRT_iret), CLBR_ANY, \ + PARA_SITE(PARA_PATCH(PARAVIRT_iret), CLBR_NONE, \ jmp *%cs:paravirt_ops+PARAVIRT_iret) #define DISABLE_INTERRUPTS(clobbers) \ PARA_SITE(PARA_PATCH(PARAVIRT_irq_disable), clobbers, \ - pushl %ecx; pushl %edx; \ + pushl %eax; pushl %ecx; pushl %edx; \ call *%cs:paravirt_ops+PARAVIRT_irq_disable; \ - popl %edx; popl %ecx) \ + popl %edx; popl %ecx; popl %eax) \ #define ENABLE_INTERRUPTS(clobbers) \ PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable), clobbers, \ - pushl %ecx; pushl %edx; \ + pushl %eax; pushl %ecx; pushl %edx; \ call *%cs:paravirt_ops+PARAVIRT_irq_enable; \ - popl %edx; popl %ecx) + popl %edx; popl %ecx; popl %eax) #define ENABLE_INTERRUPTS_SYSEXIT \ - PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable_sysexit), CLBR_ANY, \ + PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable_sysexit), CLBR_NONE, \ jmp *%cs:paravirt_ops+PARAVIRT_irq_enable_sysexit) #define GET_CR0_INTO_EAX \ - call *paravirt_ops+PARAVIRT_read_cr0 + push %ecx; push %edx; \ + call *paravirt_ops+PARAVIRT_read_cr0; \ + pop %edx; pop %ecx #endif /* __ASSEMBLY__ */ #endif /* CONFIG_PARAVIRT */ -- cgit v1.2.3-59-g8ed1b From 63f70270ccd981ce40a8ff58c03a8c2e97e368be Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:14 +0200 Subject: [PATCH] i386: PARAVIRT: add common patching machinery Implement the actual patching machinery. paravirt_patch_default() contains the logic to automatically patch a callsite based on a few simple rules: - if the paravirt_op function is paravirt_nop, then patch nops - if the paravirt_op function is a jmp target, then jmp to it - if the paravirt_op function is callable and doesn't clobber too much for the callsite, call it directly paravirt_patch_default is suitable as a default implementation of paravirt_ops.patch, will remove most of the expensive indirect calls in favour of either a direct call or a pile of nops. Backends may implement their own patcher, however. There are several helper functions to help with this: paravirt_patch_nop nop out a callsite paravirt_patch_ignore leave the callsite as-is paravirt_patch_call patch a call if the caller and callee have compatible clobbers paravirt_patch_jmp patch in a jmp paravirt_patch_insns patch some literal instructions over the callsite, if they fit This patch also implements more direct patches for the native case, so that when running on native hardware many common operations are implemented inline. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Rusty Russell Cc: Zachary Amsden Cc: Anthony Liguori Acked-by: Ingo Molnar --- arch/i386/kernel/alternative.c | 5 +- arch/i386/kernel/paravirt.c | 154 ++++++++++++++++++++++++++++++++++------- include/asm-i386/paravirt.h | 12 ++++ 3 files changed, 144 insertions(+), 27 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index dae3ded9041c..c5d037c60950 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -336,11 +336,14 @@ void apply_paravirt(struct paravirt_patch_site *start, used = paravirt_ops.patch(p->instrtype, p->clobbers, p->instr, p->len); + BUG_ON(used > p->len); + /* Pad the rest with nops */ nop_out(p->instr + used, p->len - used); } - /* Sync to be conservative, in case we patched following instructions */ + /* Sync to be conservative, in case we patched following + * instructions */ sync_core(); } extern struct paravirt_patch_site __start_parainstructions[], diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index f2982832d3b9..b0ed163e6f70 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -54,40 +54,142 @@ char *memory_setup(void) #define DEF_NATIVE(name, code) \ extern const char start_##name[], end_##name[]; \ asm("start_" #name ": " code "; end_" #name ":") -DEF_NATIVE(cli, "cli"); -DEF_NATIVE(sti, "sti"); -DEF_NATIVE(popf, "push %eax; popf"); -DEF_NATIVE(pushf, "pushf; pop %eax"); + +DEF_NATIVE(irq_disable, "cli"); +DEF_NATIVE(irq_enable, "sti"); +DEF_NATIVE(restore_fl, "push %eax; popf"); +DEF_NATIVE(save_fl, "pushf; pop %eax"); DEF_NATIVE(iret, "iret"); -DEF_NATIVE(sti_sysexit, "sti; sysexit"); +DEF_NATIVE(irq_enable_sysexit, "sti; sysexit"); +DEF_NATIVE(read_cr2, "mov %cr2, %eax"); +DEF_NATIVE(write_cr3, "mov %eax, %cr3"); +DEF_NATIVE(read_cr3, "mov %cr3, %eax"); +DEF_NATIVE(clts, "clts"); +DEF_NATIVE(read_tsc, "rdtsc"); -static const struct native_insns -{ - const char *start, *end; -} native_insns[] = { - [PARAVIRT_PATCH(irq_disable)] = { start_cli, end_cli }, - [PARAVIRT_PATCH(irq_enable)] = { start_sti, end_sti }, - [PARAVIRT_PATCH(restore_fl)] = { start_popf, end_popf }, - [PARAVIRT_PATCH(save_fl)] = { start_pushf, end_pushf }, - [PARAVIRT_PATCH(iret)] = { start_iret, end_iret }, - [PARAVIRT_PATCH(irq_enable_sysexit)] = { start_sti_sysexit, end_sti_sysexit }, -}; +DEF_NATIVE(ud2a, "ud2a"); static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) { - unsigned int insn_len; + const unsigned char *start, *end; + unsigned ret; + + switch(type) { +#define SITE(x) case PARAVIRT_PATCH(x): start = start_##x; end = end_##x; goto patch_site + SITE(irq_disable); + SITE(irq_enable); + SITE(restore_fl); + SITE(save_fl); + SITE(iret); + SITE(irq_enable_sysexit); + SITE(read_cr2); + SITE(read_cr3); + SITE(write_cr3); + SITE(clts); + SITE(read_tsc); +#undef SITE + + patch_site: + ret = paravirt_patch_insns(insns, len, start, end); + break; + + case PARAVIRT_PATCH(make_pgd): + case PARAVIRT_PATCH(make_pte): + case PARAVIRT_PATCH(pgd_val): + case PARAVIRT_PATCH(pte_val): +#ifdef CONFIG_X86_PAE + case PARAVIRT_PATCH(make_pmd): + case PARAVIRT_PATCH(pmd_val): +#endif + /* These functions end up returning exactly what + they're passed, in the same registers. */ + ret = paravirt_patch_nop(); + break; + + default: + ret = paravirt_patch_default(type, clobbers, insns, len); + break; + } + + return ret; +} + +unsigned paravirt_patch_nop(void) +{ + return 0; +} + +unsigned paravirt_patch_ignore(unsigned len) +{ + return len; +} + +unsigned paravirt_patch_call(void *target, u16 tgt_clobbers, + void *site, u16 site_clobbers, + unsigned len) +{ + unsigned char *call = site; + unsigned long delta = (unsigned long)target - (unsigned long)(call+5); + + if (tgt_clobbers & ~site_clobbers) + return len; /* target would clobber too much for this site */ + if (len < 5) + return len; /* call too long for patch site */ + + *call++ = 0xe8; /* call */ + *(unsigned long *)call = delta; + + return 5; +} + +unsigned paravirt_patch_jmp(void *target, void *site, unsigned len) +{ + unsigned char *jmp = site; + unsigned long delta = (unsigned long)target - (unsigned long)(jmp+5); - /* Don't touch it if we don't have a replacement */ - if (type >= ARRAY_SIZE(native_insns) || !native_insns[type].start) - return len; + if (len < 5) + return len; /* call too long for patch site */ - insn_len = native_insns[type].end - native_insns[type].start; + *jmp++ = 0xe9; /* jmp */ + *(unsigned long *)jmp = delta; + + return 5; +} + +unsigned paravirt_patch_default(u8 type, u16 clobbers, void *site, unsigned len) +{ + void *opfunc = *((void **)¶virt_ops + type); + unsigned ret; + + if (opfunc == NULL) + /* If there's no function, patch it with a ud2a (BUG) */ + ret = paravirt_patch_insns(site, len, start_ud2a, end_ud2a); + else if (opfunc == paravirt_nop) + /* If the operation is a nop, then nop the callsite */ + ret = paravirt_patch_nop(); + else if (type == PARAVIRT_PATCH(iret) || + type == PARAVIRT_PATCH(irq_enable_sysexit)) + /* If operation requires a jmp, then jmp */ + ret = paravirt_patch_jmp(opfunc, site, len); + else + /* Otherwise call the function; assume target could + clobber any caller-save reg */ + ret = paravirt_patch_call(opfunc, CLBR_ANY, + site, clobbers, len); + + return ret; +} + +unsigned paravirt_patch_insns(void *site, unsigned len, + const char *start, const char *end) +{ + unsigned insn_len = end - start; - /* Similarly if we can't fit replacement. */ - if (len < insn_len) - return len; + if (insn_len > len || start == NULL) + insn_len = len; + else + memcpy(site, start, insn_len); - memcpy(insns, native_insns[type].start, insn_len); return insn_len; } @@ -110,7 +212,7 @@ static void native_flush_tlb_global(void) __native_flush_tlb_global(); } -static void native_flush_tlb_single(u32 addr) +static void native_flush_tlb_single(unsigned long addr) { __native_flush_tlb_single(addr); } diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index 8bfaf10d9961..4b3d50858670 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -248,6 +248,18 @@ extern struct paravirt_ops paravirt_ops; #define paravirt_alt(insn_string) \ _paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]") +unsigned paravirt_patch_nop(void); +unsigned paravirt_patch_ignore(unsigned len); +unsigned paravirt_patch_call(void *target, u16 tgt_clobbers, + void *site, u16 site_clobbers, + unsigned len); +unsigned paravirt_patch_jmp(void *target, void *site, unsigned len); +unsigned paravirt_patch_default(u8 type, u16 clobbers, void *site, unsigned len); + +unsigned paravirt_patch_insns(void *site, unsigned len, + const char *start, const char *end); + + /* * This generates an indirect call based on the operation type number. * The type number, computed in PARAVIRT_PATCH, is derived from the -- cgit v1.2.3-59-g8ed1b From d4c104771a1c58e3de2a888b73b0ba1b54c0ae76 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:15 +0200 Subject: [PATCH] i386: PARAVIRT: add flush_tlb_others paravirt_op This patch adds a pv_op for flush_tlb_others. Linux running on native hardware uses cross-CPU IPIs to flush the TLB on any CPU which may have a particular mm's pagetable entries cached in its TLB. This is inefficient in a paravirtualized environment, since the hypervisor knows which real CPUs actually contain cached mappings, which may be a small subset of a guest's VCPUs. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen --- arch/i386/kernel/paravirt.c | 1 + arch/i386/kernel/smp.c | 13 +++++++------ include/asm-i386/paravirt.h | 9 +++++++++ include/asm-i386/tlbflush.h | 19 +++++++++++++++++-- 4 files changed, 34 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index b0ed163e6f70..c7f0cf92925f 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -300,6 +300,7 @@ struct paravirt_ops paravirt_ops = { .flush_tlb_user = native_flush_tlb, .flush_tlb_kernel = native_flush_tlb_global, .flush_tlb_single = native_flush_tlb_single, + .flush_tlb_others = native_flush_tlb_others, .map_pt_hook = paravirt_nop, diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 9d84f6f001bf..892cd64130bc 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -256,7 +256,6 @@ static cpumask_t flush_cpumask; static struct mm_struct * flush_mm; static unsigned long flush_va; static DEFINE_SPINLOCK(tlbstate_lock); -#define FLUSH_ALL 0xffffffff /* * We cannot call mmdrop() because we are in interrupt context, @@ -338,7 +337,7 @@ fastcall void smp_invalidate_interrupt(struct pt_regs *regs) if (flush_mm == per_cpu(cpu_tlbstate, cpu).active_mm) { if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) { - if (flush_va == FLUSH_ALL) + if (flush_va == TLB_FLUSH_ALL) local_flush_tlb(); else __flush_tlb_one(flush_va); @@ -353,9 +352,11 @@ out: put_cpu_no_resched(); } -static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, - unsigned long va) +void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm, + unsigned long va) { + cpumask_t cpumask = *cpumaskp; + /* * A couple of (to be removed) sanity checks: * @@ -417,7 +418,7 @@ void flush_tlb_current_task(void) local_flush_tlb(); if (!cpus_empty(cpu_mask)) - flush_tlb_others(cpu_mask, mm, FLUSH_ALL); + flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL); preempt_enable(); } @@ -436,7 +437,7 @@ void flush_tlb_mm (struct mm_struct * mm) leave_mm(smp_processor_id()); } if (!cpus_empty(cpu_mask)) - flush_tlb_others(cpu_mask, mm, FLUSH_ALL); + flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL); preempt_enable(); } diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index 4b3d50858670..f880b06d6d56 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -15,6 +15,7 @@ #ifndef __ASSEMBLY__ #include +#include struct thread_struct; struct Xgt_desc_struct; @@ -165,6 +166,8 @@ struct paravirt_ops void (*flush_tlb_user)(void); void (*flush_tlb_kernel)(void); void (*flush_tlb_single)(unsigned long addr); + void (*flush_tlb_others)(const cpumask_t *cpus, struct mm_struct *mm, + unsigned long va); void (*map_pt_hook)(int type, pte_t *va, u32 pfn); @@ -853,6 +856,12 @@ static inline void __flush_tlb_single(unsigned long addr) PVOP_VCALL1(flush_tlb_single, addr); } +static inline void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, + unsigned long va) +{ + PVOP_VCALL3(flush_tlb_others, &cpumask, mm, va); +} + static inline void paravirt_map_pt_hook(int type, pte_t *va, u32 pfn) { PVOP_VCALL3(map_pt_hook, type, va, pfn); diff --git a/include/asm-i386/tlbflush.h b/include/asm-i386/tlbflush.h index 4dd82840d53b..db7f77eacfa0 100644 --- a/include/asm-i386/tlbflush.h +++ b/include/asm-i386/tlbflush.h @@ -79,11 +79,15 @@ * - flush_tlb_range(vma, start, end) flushes a range of pages * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables + * - flush_tlb_others(cpumask, mm, va) flushes a TLBs on other cpus * * ..but the i386 has somewhat limited tlb flushing capabilities, * and page-granular flushes are available only on i486 and up. */ +#define TLB_FLUSH_ALL 0xffffffff + + #ifndef CONFIG_SMP #define flush_tlb() __flush_tlb() @@ -110,7 +114,12 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, __flush_tlb(); } -#else +static inline void native_flush_tlb_others(const cpumask_t *cpumask, + struct mm_struct *mm, unsigned long va) +{ +} + +#else /* SMP */ #include @@ -129,6 +138,9 @@ static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long st flush_tlb_mm(vma->vm_mm); } +void native_flush_tlb_others(const cpumask_t *cpumask, struct mm_struct *mm, + unsigned long va); + #define TLBSTATE_OK 1 #define TLBSTATE_LAZY 2 @@ -139,8 +151,11 @@ struct tlb_state char __cacheline_padding[L1_CACHE_BYTES-8]; }; DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate); +#endif /* SMP */ - +#ifndef CONFIG_PARAVIRT +#define flush_tlb_others(mask, mm, va) \ + native_flush_tlb_others(&mask, mm, va) #endif #define flush_tlb_kernel_range(start, end) flush_tlb_all() -- cgit v1.2.3-59-g8ed1b From a27fe809b82c5e18932fcceded28d0d1481ce7bb Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:15 +0200 Subject: [PATCH] i386: PARAVIRT: revert map_pt_hook. Back out the map_pt_hook to clear the way for kmap_atomic_pte. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Zachary Amsden --- arch/i386/kernel/paravirt.c | 2 -- arch/i386/kernel/vmi.c | 2 ++ include/asm-i386/paravirt.h | 7 ------- include/asm-i386/pgtable.h | 23 ++++------------------- 4 files changed, 6 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index c7f0cf92925f..13f41b5c887a 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -302,8 +302,6 @@ struct paravirt_ops paravirt_ops = { .flush_tlb_single = native_flush_tlb_single, .flush_tlb_others = native_flush_tlb_others, - .map_pt_hook = paravirt_nop, - .alloc_pt = paravirt_nop, .alloc_pd = paravirt_nop, .alloc_pd_clone = paravirt_nop, diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index b8d01c3cbff4..ccad7ee960aa 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c @@ -851,8 +851,10 @@ static inline int __init activate_vmi(void) paravirt_ops.release_pt = vmi_release_pt; paravirt_ops.release_pd = vmi_release_pd; } +#if 0 para_wrap(map_pt_hook, vmi_map_pt_hook, set_linear_mapping, SetLinearMapping); +#endif /* * These MUST always be patched. Don't support indirect jumps diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index f880b06d6d56..10f44af76b49 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -169,8 +169,6 @@ struct paravirt_ops void (*flush_tlb_others)(const cpumask_t *cpus, struct mm_struct *mm, unsigned long va); - void (*map_pt_hook)(int type, pte_t *va, u32 pfn); - /* Hooks for allocating/releasing pagetable pages */ void (*alloc_pt)(u32 pfn); void (*alloc_pd)(u32 pfn); @@ -862,11 +860,6 @@ static inline void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, PVOP_VCALL3(flush_tlb_others, &cpumask, mm, va); } -static inline void paravirt_map_pt_hook(int type, pte_t *va, u32 pfn) -{ - PVOP_VCALL3(map_pt_hook, type, va, pfn); -} - static inline void paravirt_alloc_pt(unsigned pfn) { PVOP_VCALL1(alloc_pt, pfn); diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index 5b88a6a1278e..6599f2aa91b7 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -267,7 +267,6 @@ extern void vmalloc_sync_all(void); */ #define pte_update(mm, addr, ptep) do { } while (0) #define pte_update_defer(mm, addr, ptep) do { } while (0) -#define paravirt_map_pt_hook(slot, va, pfn) do { } while (0) #define raw_ptep_get_and_clear(xp) native_ptep_get_and_clear(xp) #endif @@ -476,24 +475,10 @@ extern pte_t *lookup_address(unsigned long address); #endif #if defined(CONFIG_HIGHPTE) -#define pte_offset_map(dir, address) \ -({ \ - pte_t *__ptep; \ - unsigned pfn = pmd_val(*(dir)) >> PAGE_SHIFT; \ - __ptep = (pte_t *)kmap_atomic(pfn_to_page(pfn),KM_PTE0);\ - paravirt_map_pt_hook(KM_PTE0,__ptep, pfn); \ - __ptep = __ptep + pte_index(address); \ - __ptep; \ -}) -#define pte_offset_map_nested(dir, address) \ -({ \ - pte_t *__ptep; \ - unsigned pfn = pmd_val(*(dir)) >> PAGE_SHIFT; \ - __ptep = (pte_t *)kmap_atomic(pfn_to_page(pfn),KM_PTE1);\ - paravirt_map_pt_hook(KM_PTE1,__ptep, pfn); \ - __ptep = __ptep + pte_index(address); \ - __ptep; \ -}) +#define pte_offset_map(dir, address) \ + ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + pte_index(address)) +#define pte_offset_map_nested(dir, address) \ + ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE1) + pte_index(address)) #define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) #define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1) #else -- cgit v1.2.3-59-g8ed1b From ce6234b5298902aaec831a67d5f8d9bd2ef5a488 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:15 +0200 Subject: [PATCH] i386: PARAVIRT: add kmap_atomic_pte for mapping highpte pages Xen and VMI both have special requirements when mapping a highmem pte page into the kernel address space. These can be dealt with by adding a new kmap_atomic_pte() function for mapping highptes, and hooking it into the paravirt_ops infrastructure. Xen specifically wants to map the pte page RO, so this patch exposes a helper function, kmap_atomic_prot, which maps the page with the specified page protections. This also adds a kmap_flush_unused() function to clear out the cached kmap mappings. Xen needs this to clear out any potential stray RW mappings of pages which will become part of a pagetable. [ Zach - vmi.c will need some attention after this patch. It wasn't immediately obvious to me what needs to be done. ] Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Zachary Amsden --- arch/i386/kernel/paravirt.c | 5 +++++ arch/i386/mm/highmem.c | 9 +++++++-- include/asm-i386/highmem.h | 6 ++++++ include/asm-i386/paravirt.h | 15 +++++++++++++++ include/asm-i386/pgtable.h | 4 ++-- include/linux/highmem.h | 6 ++++++ mm/highmem.c | 9 +++++++++ 7 files changed, 50 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index 13f41b5c887a..596f382c641c 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -316,6 +317,10 @@ struct paravirt_ops paravirt_ops = { .ptep_get_and_clear = native_ptep_get_and_clear, +#ifdef CONFIG_HIGHPTE + .kmap_atomic_pte = kmap_atomic, +#endif + #ifdef CONFIG_X86_PAE .set_pte_atomic = native_set_pte_atomic, .set_pte_present = native_set_pte_present, diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c index ac70d09df7ee..a1a21abf742e 100644 --- a/arch/i386/mm/highmem.c +++ b/arch/i386/mm/highmem.c @@ -26,7 +26,7 @@ void kunmap(struct page *page) * However when holding an atomic kmap is is not legal to sleep, so atomic * kmaps are appropriate for short, tight code paths only. */ -void *kmap_atomic(struct page *page, enum km_type type) +void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) { enum fixed_addresses idx; unsigned long vaddr; @@ -41,12 +41,17 @@ void *kmap_atomic(struct page *page, enum km_type type) return page_address(page); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); - set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); + set_pte(kmap_pte-idx, mk_pte(page, prot)); arch_flush_lazy_mmu_mode(); return (void*) vaddr; } +void *kmap_atomic(struct page *page, enum km_type type) +{ + return kmap_atomic_prot(page, type, kmap_prot); +} + void kunmap_atomic(void *kvaddr, enum km_type type) { unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; diff --git a/include/asm-i386/highmem.h b/include/asm-i386/highmem.h index e9a34ebc25d5..13cdcd66fff2 100644 --- a/include/asm-i386/highmem.h +++ b/include/asm-i386/highmem.h @@ -24,6 +24,7 @@ #include #include #include +#include /* declarations for highmem.c */ extern unsigned long highstart_pfn, highend_pfn; @@ -67,11 +68,16 @@ extern void FASTCALL(kunmap_high(struct page *page)); void *kmap(struct page *page); void kunmap(struct page *page); +void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot); void *kmap_atomic(struct page *page, enum km_type type); void kunmap_atomic(void *kvaddr, enum km_type type); void *kmap_atomic_pfn(unsigned long pfn, enum km_type type); struct page *kmap_atomic_to_page(void *ptr); +#ifndef CONFIG_PARAVIRT +#define kmap_atomic_pte(page, type) kmap_atomic(page, type) +#endif + #define flush_cache_kmaps() do { } while (0) #endif /* __KERNEL__ */ diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index 10f44af76b49..5048b41428fa 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -16,7 +16,9 @@ #ifndef __ASSEMBLY__ #include #include +#include +struct page; struct thread_struct; struct Xgt_desc_struct; struct tss_struct; @@ -187,6 +189,10 @@ struct paravirt_ops pte_t (*ptep_get_and_clear)(pte_t *ptep); +#ifdef CONFIG_HIGHPTE + void *(*kmap_atomic_pte)(struct page *page, enum km_type type); +#endif + #ifdef CONFIG_X86_PAE void (*set_pte_atomic)(pte_t *ptep, pte_t pteval); void (*set_pte_present)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte); @@ -884,6 +890,15 @@ static inline void paravirt_release_pd(unsigned pfn) PVOP_VCALL1(release_pd, pfn); } +#ifdef CONFIG_HIGHPTE +static inline void *kmap_atomic_pte(struct page *page, enum km_type type) +{ + unsigned long ret; + ret = PVOP_CALL2(unsigned long, kmap_atomic_pte, page, type); + return (void *)ret; +} +#endif + static inline void pte_update(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index 6599f2aa91b7..befc697821e5 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -476,9 +476,9 @@ extern pte_t *lookup_address(unsigned long address); #if defined(CONFIG_HIGHPTE) #define pte_offset_map(dir, address) \ - ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + pte_index(address)) + ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)),KM_PTE0) + pte_index(address)) #define pte_offset_map_nested(dir, address) \ - ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE1) + pte_index(address)) + ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)),KM_PTE1) + pte_index(address)) #define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) #define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1) #else diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 645d440807c2..bca8e2dfa355 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -27,6 +27,8 @@ static inline void flush_kernel_dcache_page(struct page *page) unsigned int nr_free_highpages(void); extern unsigned long totalhigh_pages; +void kmap_flush_unused(void); + #else /* CONFIG_HIGHMEM */ static inline unsigned int nr_free_highpages(void) { return 0; } @@ -44,9 +46,13 @@ static inline void *kmap(struct page *page) #define kmap_atomic(page, idx) \ ({ pagefault_disable(); page_address(page); }) +#define kmap_atomic_prot(page, idx, prot) kmap_atomic(page, idx) + #define kunmap_atomic(addr, idx) do { pagefault_enable(); } while (0) #define kmap_atomic_pfn(pfn, idx) kmap_atomic(pfn_to_page(pfn), (idx)) #define kmap_atomic_to_page(ptr) virt_to_page(ptr) + +#define kmap_flush_unused() do {} while(0) #endif #endif /* CONFIG_HIGHMEM */ diff --git a/mm/highmem.c b/mm/highmem.c index 51e1c1995fec..be8f8d36a8b9 100644 --- a/mm/highmem.c +++ b/mm/highmem.c @@ -99,6 +99,15 @@ static void flush_all_zero_pkmaps(void) flush_tlb_kernel_range(PKMAP_ADDR(0), PKMAP_ADDR(LAST_PKMAP)); } +/* Flush all unused kmap mappings in order to remove stray + mappings. */ +void kmap_flush_unused(void) +{ + spin_lock(&kmap_lock); + flush_all_zero_pkmaps(); + spin_unlock(&kmap_lock); +} + static inline unsigned long map_new_virtual(struct page *page) { unsigned long vaddr; -- cgit v1.2.3-59-g8ed1b From 7b2f27f4e1818fad980da7bea688dca2b9e9c3f3 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:15 +0200 Subject: [PATCH] i386: PARAVIRT: flush lazy mmu updates on kunmap_atomic kunmap_atomic should flush any pending lazy mmu updates, mainly to be consistent with kmap_atomic, and to preserve its normal behaviour. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen --- arch/i386/mm/highmem.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c index a1a21abf742e..ad8d86cc683e 100644 --- a/arch/i386/mm/highmem.c +++ b/arch/i386/mm/highmem.c @@ -72,6 +72,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type) #endif } + arch_flush_lazy_mmu_mode(); pagefault_enable(); } -- cgit v1.2.3-59-g8ed1b From 4cdd9c8931767e1c56a51a1078d33a8c340f4405 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:15 +0200 Subject: [PATCH] i386: PARAVIRT: drop unused ptep_get_and_clear In shadow mode hypervisors, ptep_get_and_clear achieves the desired purpose of keeping the shadows in sync by issuing a native_get_and_clear, followed by a call to pte_update, which indicates the PTE has been modified. Direct mode hypervisors (Xen) have no need for this anyway, and will trap the update using writable pagetables. This means no hypervisor makes use of ptep_get_and_clear; there is no reason to have it in the paravirt-ops structure. Change confusing terminology about raw vs. native functions into consistent use of native_pte_xxx for operations which do not invoke paravirt-ops. Signed-off-by: Zachary Amsden Signed-off-by: Andi Kleen --- arch/i386/kernel/paravirt.c | 2 -- include/asm-i386/paravirt.h | 13 +------------ include/asm-i386/pgtable.h | 4 +--- 3 files changed, 2 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index 596f382c641c..c4850ddd6a9d 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -315,8 +315,6 @@ struct paravirt_ops paravirt_ops = { .pte_update = paravirt_nop, .pte_update_defer = paravirt_nop, - .ptep_get_and_clear = native_ptep_get_and_clear, - #ifdef CONFIG_HIGHPTE .kmap_atomic_pte = kmap_atomic, #endif diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index 2ba18963e114..e2e7f98723c5 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -188,8 +188,6 @@ struct paravirt_ops void (*pte_update_defer)(struct mm_struct *mm, unsigned long addr, pte_t *ptep); - pte_t (*ptep_get_and_clear)(pte_t *ptep); - #ifdef CONFIG_HIGHPTE void *(*kmap_atomic_pte)(struct page *page, enum km_type type); #endif @@ -859,12 +857,8 @@ static inline void pmd_clear(pmd_t *pmdp) PVOP_VCALL1(pmd_clear, pmdp); } -static inline pte_t raw_ptep_get_and_clear(pte_t *p) -{ - unsigned long long val = PVOP_CALL1(unsigned long long, ptep_get_and_clear, p); - return (pte_t) { val, val >> 32 }; -} #else /* !CONFIG_X86_PAE */ + static inline pte_t __pte(unsigned long val) { return (pte_t) { PVOP_CALL1(unsigned long, make_pte, val) }; @@ -900,11 +894,6 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval) { PVOP_VCALL2(set_pmd, pmdp, pmdval.pud.pgd.pgd); } - -static inline pte_t raw_ptep_get_and_clear(pte_t *p) -{ - return (pte_t) { PVOP_CALL1(unsigned long, ptep_get_and_clear, p) }; -} #endif /* CONFIG_X86_PAE */ #define __HAVE_ARCH_ENTER_LAZY_CPU_MODE diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index befc697821e5..e7ddd2341309 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -267,8 +267,6 @@ extern void vmalloc_sync_all(void); */ #define pte_update(mm, addr, ptep) do { } while (0) #define pte_update_defer(mm, addr, ptep) do { } while (0) - -#define raw_ptep_get_and_clear(xp) native_ptep_get_and_clear(xp) #endif /* @@ -335,7 +333,7 @@ do { \ #define __HAVE_ARCH_PTEP_GET_AND_CLEAR static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - pte_t pte = raw_ptep_get_and_clear(ptep); + pte_t pte = native_ptep_get_and_clear(ptep); pte_update(mm, addr, ptep); return pte; } -- cgit v1.2.3-59-g8ed1b From 35c7422649ee7a3d0eb4ebd32c997eeb45f81046 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:15 +0200 Subject: [PATCH] x86: deflate stack usage in lib/inflate.c inflate_fixed and huft_build together use around 2.7k of stack. When using 4k stacks, I saw stack overflows from interrupts arriving while unpacking the root initrd: do_IRQ: stack overflow: 384 [] show_trace_log_lvl+0x1a/0x30 [] show_trace+0x12/0x14 [] dump_stack+0x16/0x18 [] do_IRQ+0x6d/0xd9 [] xen_evtchn_do_upcall+0x6e/0xa2 [] xen_hypervisor_callback+0x25/0x2c [] xen_restore_fl+0x27/0x29 [] _spin_unlock_irqrestore+0x4a/0x50 [] change_page_attr+0x577/0x584 [] kernel_map_pages+0x8d/0xb4 [] cache_alloc_refill+0x53f/0x632 [] __kmalloc+0xc1/0x10d [] malloc+0x10/0x12 [] huft_build+0x2a7/0x5fa [] inflate_fixed+0x91/0x136 [] unpack_to_rootfs+0x5f2/0x8c1 [] populate_rootfs+0x1e/0xe4 (This was under Xen, but there's no reason it couldn't happen on bare hardware.) This patch mallocs the local variables, thereby reducing the stack usage to sane levels. Also, up the heap size for the kernel decompressor to deal with the extra allocation. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Tim Yamin Cc: Andi Kleen Cc: Matt Mackall Cc: Ivan Kokshaysky Cc: Richard Henderson Cc: Russell King Cc: Ian Molton --- arch/alpha/boot/misc.c | 2 +- arch/arm/boot/compressed/misc.c | 2 +- arch/arm26/boot/compressed/misc.c | 2 +- arch/i386/boot/compressed/misc.c | 2 +- arch/x86_64/boot/compressed/misc.c | 2 +- lib/inflate.c | 66 ++++++++++++++++++++++++++++---------- 6 files changed, 54 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/alpha/boot/misc.c b/arch/alpha/boot/misc.c index 1d65adf5691e..c00646b25f6e 100644 --- a/arch/alpha/boot/misc.c +++ b/arch/alpha/boot/misc.c @@ -98,7 +98,7 @@ extern int end; static ulg free_mem_ptr; static ulg free_mem_ptr_end; -#define HEAP_SIZE 0x2000 +#define HEAP_SIZE 0x3000 #include "../../../lib/inflate.c" diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 283891c736c4..9b444022cb9b 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -239,7 +239,7 @@ extern int end; static ulg free_mem_ptr; static ulg free_mem_ptr_end; -#define HEAP_SIZE 0x2000 +#define HEAP_SIZE 0x3000 #include "../../../../lib/inflate.c" diff --git a/arch/arm26/boot/compressed/misc.c b/arch/arm26/boot/compressed/misc.c index f17f50e5516f..0714d19c5776 100644 --- a/arch/arm26/boot/compressed/misc.c +++ b/arch/arm26/boot/compressed/misc.c @@ -182,7 +182,7 @@ extern int end; static ulg free_mem_ptr; static ulg free_mem_ptr_end; -#define HEAP_SIZE 0x2000 +#define HEAP_SIZE 0x3000 #include "../../../../lib/inflate.c" diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c index 1ce7017fd627..b28505c544c9 100644 --- a/arch/i386/boot/compressed/misc.c +++ b/arch/i386/boot/compressed/misc.c @@ -189,7 +189,7 @@ static void putstr(const char *); static unsigned long free_mem_ptr; static unsigned long free_mem_end_ptr; -#define HEAP_SIZE 0x3000 +#define HEAP_SIZE 0x4000 static char *vidmem = (char *)0xb8000; static int vidport; diff --git a/arch/x86_64/boot/compressed/misc.c b/arch/x86_64/boot/compressed/misc.c index fed1167159c3..f932b0e89096 100644 --- a/arch/x86_64/boot/compressed/misc.c +++ b/arch/x86_64/boot/compressed/misc.c @@ -189,7 +189,7 @@ static void putstr(const char *); static long free_mem_ptr; static long free_mem_end_ptr; -#define HEAP_SIZE 0x6000 +#define HEAP_SIZE 0x7000 static char *vidmem = (char *)0xb8000; static int vidport; diff --git a/lib/inflate.c b/lib/inflate.c index 6db6e98d1637..88a22f4a49df 100644 --- a/lib/inflate.c +++ b/lib/inflate.c @@ -292,7 +292,6 @@ STATIC int INIT huft_build( oversubscribed set of lengths), and three if not enough memory. */ { unsigned a; /* counter for codes of length k */ - unsigned c[BMAX+1]; /* bit length count table */ unsigned f; /* i repeats in table every f entries */ int g; /* maximum code length */ int h; /* table level */ @@ -303,18 +302,33 @@ STATIC int INIT huft_build( register unsigned *p; /* pointer into c[], b[], or v[] */ register struct huft *q; /* points to current table */ struct huft r; /* table entry for structure assignment */ - struct huft *u[BMAX]; /* table stack */ - unsigned v[N_MAX]; /* values in order of bit length */ register int w; /* bits before this table == (l * h) */ - unsigned x[BMAX+1]; /* bit offsets, then code stack */ unsigned *xp; /* pointer into x */ int y; /* number of dummy codes added */ unsigned z; /* number of entries in current table */ + struct { + unsigned c[BMAX+1]; /* bit length count table */ + struct huft *u[BMAX]; /* table stack */ + unsigned v[N_MAX]; /* values in order of bit length */ + unsigned x[BMAX+1]; /* bit offsets, then code stack */ + } *stk; + unsigned *c, *v, *x; + struct huft **u; + int ret; DEBG("huft1 "); + stk = malloc(sizeof(*stk)); + if (stk == NULL) + return 3; /* out of memory */ + + c = stk->c; + v = stk->v; + x = stk->x; + u = stk->u; + /* Generate counts for each bit length */ - memzero(c, sizeof(c)); + memzero(stk->c, sizeof(stk->c)); p = b; i = n; do { Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"), @@ -326,7 +340,8 @@ DEBG("huft1 "); { *t = (struct huft *)NULL; *m = 0; - return 2; + ret = 2; + goto out; } DEBG("huft2 "); @@ -351,10 +366,14 @@ DEBG("huft3 "); /* Adjust last length count to fill out codes, if needed */ for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= c[j]) < 0) - return 2; /* bad input: more codes than bits */ - if ((y -= c[i]) < 0) - return 2; + if ((y -= c[j]) < 0) { + ret = 2; /* bad input: more codes than bits */ + goto out; + } + if ((y -= c[i]) < 0) { + ret = 2; + goto out; + } c[i] += y; DEBG("huft4 "); @@ -428,7 +447,8 @@ DEBG1("3 "); { if (h) huft_free(u[0]); - return 3; /* not enough memory */ + ret = 3; /* not enough memory */ + goto out; } DEBG1("4 "); hufts += z + 1; /* track memory usage */ @@ -492,7 +512,11 @@ DEBG("h6f "); DEBG("huft7 "); /* Return true (1) if we were given an incomplete table */ - return y != 0 && g != 1; + ret = y != 0 && g != 1; + + out: + free(stk); + return ret; } @@ -705,10 +729,14 @@ STATIC int noinline INIT inflate_fixed(void) struct huft *td; /* distance code table */ int bl; /* lookup bits for tl */ int bd; /* lookup bits for td */ - unsigned l[288]; /* length list for huft_build */ + unsigned *l; /* length list for huft_build */ DEBG(" 1) { huft_free(tl); + free(l); DEBG(">"); return i; @@ -737,11 +767,13 @@ DEBG(" Date: Wed, 2 May 2007 19:27:15 +0200 Subject: [PATCH] i386: Page-align the GDT Xen wants a dedicated page for the GDT. I believe VMI likes it too. lguest, KVM and native don't care. Simple transformation to page-aligned "struct gdt_page". Signed-off-by: Rusty Russell Signed-off-by: Andi Kleen Acked-by: Jeremy Fitzhardinge --- arch/i386/kernel/cpu/common.c | 6 +++--- arch/i386/kernel/entry.S | 2 +- arch/i386/kernel/head.S | 2 +- arch/i386/kernel/traps.c | 2 +- include/asm-i386/desc.h | 9 +++++++-- 5 files changed, 13 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 58128585ae60..7a4c036d93c8 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -22,7 +22,7 @@ #include "cpu.h" -DEFINE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]) = { +DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = { [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 }, [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 }, [GDT_ENTRY_DEFAULT_USER_CS] = { 0x0000ffff, 0x00cffa00 }, @@ -48,8 +48,8 @@ DEFINE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]) = { [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 }, [GDT_ENTRY_PDA] = { 0x00000000, 0x00c09200 }, /* set in setup_pda */ -}; -EXPORT_PER_CPU_SYMBOL_GPL(cpu_gdt); +} }; +EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); DEFINE_PER_CPU(struct i386_pda, _cpu_pda); EXPORT_PER_CPU_SYMBOL(_cpu_pda); diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index e07473c0d3e7..3e4aa1fd33e2 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -557,7 +557,7 @@ END(syscall_badsys) #define FIXUP_ESPFIX_STACK \ /* since we are on a wrong stack, we cant make it a C code :( */ \ movl %fs:PDA_cpu, %ebx; \ - PER_CPU(cpu_gdt, %ebx); \ + PER_CPU(gdt_page, %ebx); \ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \ addl %esp, %eax; \ pushl $__KERNEL_DS; \ diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index cc46494787e8..bb36c24311b4 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -598,7 +598,7 @@ idt_descr: .word 0 # 32 bit align gdt_desc.address ENTRY(early_gdt_descr) .word GDT_ENTRIES*8-1 - .long per_cpu__cpu_gdt /* Overwritten for secondary CPUs */ + .long per_cpu__gdt_page /* Overwritten for secondary CPUs */ /* * The boot_gdt must mirror the equivalent in setup.S and is diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index e0a23bee6967..f21b41e7770c 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -1030,7 +1030,7 @@ fastcall void do_spurious_interrupt_bug(struct pt_regs * regs, fastcall unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp) { - struct desc_struct *gdt = __get_cpu_var(cpu_gdt); + struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt; unsigned long base = (kesp - uesp) & -THREAD_SIZE; unsigned long new_kesp = kesp - base; unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT; diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h index 4a974064e928..c547403f341d 100644 --- a/include/asm-i386/desc.h +++ b/include/asm-i386/desc.h @@ -18,10 +18,15 @@ struct Xgt_desc_struct { unsigned short pad; } __attribute__ ((packed)); -DECLARE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]); +struct gdt_page +{ + struct desc_struct gdt[GDT_ENTRIES]; +} __attribute__((aligned(PAGE_SIZE))); +DECLARE_PER_CPU(struct gdt_page, gdt_page); + static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) { - return per_cpu(cpu_gdt, cpu); + return per_cpu(gdt_page, cpu).gdt; } extern struct Xgt_desc_struct idt_descr; -- cgit v1.2.3-59-g8ed1b From 7c3576d261ce046789a7db14f43303f8120910c7 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:16 +0200 Subject: [PATCH] i386: Convert PDA into the percpu section Currently x86 (similar to x84-64) has a special per-cpu structure called "i386_pda" which can be easily and efficiently referenced via the %fs register. An ELF section is more flexible than a structure, allowing any piece of code to use this area. Indeed, such a section already exists: the per-cpu area. So this patch: (1) Removes the PDA and uses per-cpu variables for each current member. (2) Replaces the __KERNEL_PDA segment with __KERNEL_PERCPU. (3) Creates a per-cpu mirror of __per_cpu_offset called this_cpu_off, which can be used to calculate addresses for this CPU's variables. (4) Simplifies startup, because %fs doesn't need to be loaded with a special segment at early boot; it can be deferred until the first percpu area is allocated (or never for UP). The result is less code and one less x86-specific concept. Signed-off-by: Rusty Russell Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Andi Kleen --- arch/i386/kernel/asm-offsets.c | 5 -- arch/i386/kernel/cpu/common.c | 17 +----- arch/i386/kernel/entry.S | 5 +- arch/i386/kernel/head.S | 31 ++-------- arch/i386/kernel/i386_ksyms.c | 2 - arch/i386/kernel/irq.c | 3 + arch/i386/kernel/process.c | 12 +++- arch/i386/kernel/smpboot.c | 30 +++++----- arch/i386/kernel/vmi.c | 6 +- arch/i386/kernel/vmlinux.lds.S | 1 - include/asm-i386/current.h | 5 +- include/asm-i386/irq_regs.h | 12 ++-- include/asm-i386/pda.h | 99 ------------------------------- include/asm-i386/percpu.h | 132 ++++++++++++++++++++++++++++++++++++++--- include/asm-i386/processor.h | 2 +- include/asm-i386/segment.h | 6 +- include/asm-i386/smp.h | 4 +- 17 files changed, 177 insertions(+), 195 deletions(-) delete mode 100644 include/asm-i386/pda.h (limited to 'arch') diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c index d558adfc293c..b05e85fd1c1e 100644 --- a/arch/i386/kernel/asm-offsets.c +++ b/arch/i386/kernel/asm-offsets.c @@ -15,7 +15,6 @@ #include #include #include -#include #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -101,10 +100,6 @@ void foo(void) OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx); - BLANK(); - OFFSET(PDA_cpu, i386_pda, cpu_number); - OFFSET(PDA_pcurrent, i386_pda, pcurrent); - #ifdef CONFIG_PARAVIRT BLANK(); OFFSET(PARAVIRT_enabled, paravirt_ops, paravirt_enabled); diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 7a4c036d93c8..27e00565f5e4 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -18,7 +18,6 @@ #include #include #endif -#include #include "cpu.h" @@ -47,13 +46,10 @@ DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = { [GDT_ENTRY_APMBIOS_BASE+2] = { 0x0000ffff, 0x00409200 }, /* data */ [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 }, - [GDT_ENTRY_PDA] = { 0x00000000, 0x00c09200 }, /* set in setup_pda */ + [GDT_ENTRY_PERCPU] = { 0x00000000, 0x00000000 }, } }; EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); -DEFINE_PER_CPU(struct i386_pda, _cpu_pda); -EXPORT_PER_CPU_SYMBOL(_cpu_pda); - static int cachesize_override __cpuinitdata = -1; static int disable_x86_fxsr __cpuinitdata; static int disable_x86_serial_nr __cpuinitdata = 1; @@ -634,21 +630,14 @@ void __init early_cpu_init(void) #endif } -/* Make sure %gs is initialized properly in idle threads */ +/* Make sure %fs is initialized properly in idle threads */ struct pt_regs * __devinit idle_regs(struct pt_regs *regs) { memset(regs, 0, sizeof(struct pt_regs)); - regs->xfs = __KERNEL_PDA; + regs->xfs = __KERNEL_PERCPU; return regs; } -/* Initial PDA used by boot CPU */ -struct i386_pda boot_pda = { - ._pda = &boot_pda, - .cpu_number = 0, - .pcurrent = &init_task, -}; - /* * cpu_init() initializes state that is per-CPU. Some data is already * initialized (naturally) in the bootstrap process, such as the GDT diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 3e4aa1fd33e2..7f92ceb428ad 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -132,7 +132,7 @@ VM_MASK = 0x00020000 movl $(__USER_DS), %edx; \ movl %edx, %ds; \ movl %edx, %es; \ - movl $(__KERNEL_PDA), %edx; \ + movl $(__KERNEL_PERCPU), %edx; \ movl %edx, %fs #define RESTORE_INT_REGS \ @@ -556,7 +556,6 @@ END(syscall_badsys) #define FIXUP_ESPFIX_STACK \ /* since we are on a wrong stack, we cant make it a C code :( */ \ - movl %fs:PDA_cpu, %ebx; \ PER_CPU(gdt_page, %ebx); \ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \ addl %esp, %eax; \ @@ -681,7 +680,7 @@ error_code: pushl %fs CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET fs, 0*/ - movl $(__KERNEL_PDA), %ecx + movl $(__KERNEL_PERCPU), %ecx movl %ecx, %fs UNWIND_ESPFIX_STACK popl %ecx diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index bb36c24311b4..12277d8938df 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -317,12 +317,12 @@ is386: movl $2,%ecx # set MP movl %eax,%cr0 call check_x87 - call setup_pda lgdt early_gdt_descr lidt idt_descr ljmp $(__KERNEL_CS),$1f 1: movl $(__KERNEL_DS),%eax # reload all the segment registers movl %eax,%ss # after changing gdt. + movl %eax,%fs # gets reset once there's real percpu movl $(__USER_DS),%eax # DS/ES contains default USER segment movl %eax,%ds @@ -332,16 +332,17 @@ is386: movl $2,%ecx # set MP movl %eax,%gs lldt %ax - movl $(__KERNEL_PDA),%eax - mov %eax,%fs - cld # gcc2 wants the direction flag cleared at all times pushl $0 # fake return address for unwinder #ifdef CONFIG_SMP movb ready, %cl movb $1, ready cmpb $0,%cl # the first CPU calls start_kernel - jne initialize_secondary # all other CPUs call initialize_secondary + je 1f + movl $(__KERNEL_PERCPU), %eax + movl %eax,%fs # set this cpu's percpu + jmp initialize_secondary # all other CPUs call initialize_secondary +1: #endif /* CONFIG_SMP */ jmp start_kernel @@ -364,23 +365,6 @@ check_x87: .byte 0xDB,0xE4 /* fsetpm for 287, ignored by 387 */ ret -/* - * Point the GDT at this CPU's PDA. On boot this will be - * cpu_gdt_table and boot_pda; for secondary CPUs, these will be - * that CPU's GDT and PDA. - */ -ENTRY(setup_pda) - /* get the PDA pointer */ - movl start_pda, %eax - - /* slot the PDA address into the GDT */ - mov early_gdt_descr+2, %ecx - mov %ax, (__KERNEL_PDA+0+2)(%ecx) /* base & 0x0000ffff */ - shr $16, %eax - mov %al, (__KERNEL_PDA+4+0)(%ecx) /* base & 0x00ff0000 */ - mov %ah, (__KERNEL_PDA+4+3)(%ecx) /* base & 0xff000000 */ - ret - /* * setup_idt * @@ -553,9 +537,6 @@ ENTRY(empty_zero_page) * This starts the data section. */ .data -ENTRY(start_pda) - .long boot_pda - ENTRY(stack_start) .long init_thread_union+THREAD_SIZE .long __BOOT_DS diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index 4afe26e86260..e3d4b73bfdb0 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c @@ -28,5 +28,3 @@ EXPORT_SYMBOL(__read_lock_failed); #endif EXPORT_SYMBOL(csum_partial); - -EXPORT_SYMBOL(_proxy_pda); diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index 8db8d514c9c0..d2daf672f4a2 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -24,6 +24,9 @@ DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_internodealigned_in_smp; EXPORT_PER_CPU_SYMBOL(irq_stat); +DEFINE_PER_CPU(struct pt_regs *, irq_regs); +EXPORT_PER_CPU_SYMBOL(irq_regs); + /* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves. diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 5fb9524c6f4b..61999479b7a4 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -57,7 +58,6 @@ #include #include -#include asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); @@ -66,6 +66,12 @@ static int hlt_counter; unsigned long boot_option_idle_override = 0; EXPORT_SYMBOL(boot_option_idle_override); +DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; +EXPORT_PER_CPU_SYMBOL(current_task); + +DEFINE_PER_CPU(int, cpu_number); +EXPORT_PER_CPU_SYMBOL(cpu_number); + /* * Return saved PC of a blocked thread. */ @@ -342,7 +348,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) regs.xds = __USER_DS; regs.xes = __USER_DS; - regs.xfs = __KERNEL_PDA; + regs.xfs = __KERNEL_PERCPU; regs.orig_eax = -1; regs.eip = (unsigned long) kernel_thread_helper; regs.xcs = __KERNEL_CS | get_kernel_rpl(); @@ -711,7 +717,7 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas if (prev->gs | next->gs) loadsegment(gs, next->gs); - write_pda(pcurrent, next_p); + x86_write_percpu(current_task, next_p); return prev_p; } diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 61e2842add36..f79b6233db78 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -53,7 +53,6 @@ #include #include #include -#include #include #include @@ -99,6 +98,9 @@ EXPORT_SYMBOL(x86_cpu_to_apicid); u8 apicid_2_node[MAX_APICID]; +DEFINE_PER_CPU(unsigned long, this_cpu_off); +EXPORT_PER_CPU_SYMBOL(this_cpu_off); + /* * Trampoline 80x86 program as an array. */ @@ -456,7 +458,6 @@ extern struct { void * esp; unsigned short ss; } stack_start; -extern struct i386_pda *start_pda; #ifdef CONFIG_NUMA @@ -784,20 +785,17 @@ static inline struct task_struct * alloc_idle_task(int cpu) /* Initialize the CPU's GDT. This is either the boot CPU doing itself (still using the master per-cpu area), or a CPU doing it for a secondary which will soon come up. */ -static __cpuinit void init_gdt(int cpu, struct task_struct *idle) +static __cpuinit void init_gdt(int cpu) { struct desc_struct *gdt = get_cpu_gdt_table(cpu); - struct i386_pda *pda = &per_cpu(_cpu_pda, cpu); - pack_descriptor((u32 *)&gdt[GDT_ENTRY_PDA].a, - (u32 *)&gdt[GDT_ENTRY_PDA].b, - (unsigned long)pda, sizeof(*pda) - 1, - 0x80 | DESCTYPE_S | 0x2, 0); /* present read-write data segment */ + pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a, + (u32 *)&gdt[GDT_ENTRY_PERCPU].b, + __per_cpu_offset[cpu], 0xFFFFF, + 0x80 | DESCTYPE_S | 0x2, 0x8); - memset(pda, 0, sizeof(*pda)); - pda->_pda = pda; - pda->cpu_number = cpu; - pda->pcurrent = idle; + per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; + per_cpu(cpu_number, cpu) = cpu; } /* Defined in head.S */ @@ -824,9 +822,9 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) if (IS_ERR(idle)) panic("failed fork for CPU %d", cpu); - init_gdt(cpu, idle); + init_gdt(cpu); + per_cpu(current_task, cpu) = idle; early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); - start_pda = cpu_pda(cpu); idle->thread.eip = (unsigned long) start_secondary; /* start_eip had better be page-aligned! */ @@ -1188,14 +1186,14 @@ static inline void switch_to_new_gdt(void) gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id()); gdt_descr.size = GDT_SIZE - 1; load_gdt(&gdt_descr); - asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_PDA) : "memory"); + asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory"); } void __init native_smp_prepare_boot_cpu(void) { unsigned int cpu = smp_processor_id(); - init_gdt(cpu, current); + init_gdt(cpu); switch_to_new_gdt(); cpu_set(cpu, cpu_online_map); diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index ccad7ee960aa..12312988c626 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c @@ -504,8 +504,6 @@ static void vmi_pmd_clear(pmd_t *pmd) #endif #ifdef CONFIG_SMP -extern void setup_pda(void); - static void __devinit vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip, unsigned long start_esp) @@ -530,13 +528,11 @@ vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip, ap.ds = __USER_DS; ap.es = __USER_DS; - ap.fs = __KERNEL_PDA; + ap.fs = __KERNEL_PERCPU; ap.gs = 0; ap.eflags = 0; - setup_pda(); - #ifdef CONFIG_X86_PAE /* efer should match BSP efer. */ if (cpu_has_nx) { diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 2ce4aa185fc8..d125784ddf5e 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -26,7 +26,6 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) ENTRY(phys_startup_32) jiffies = jiffies_64; -_proxy_pda = 1; PHDRS { text PT_LOAD FLAGS(5); /* R_E */ diff --git a/include/asm-i386/current.h b/include/asm-i386/current.h index 5252ee0f6d7a..d35248539912 100644 --- a/include/asm-i386/current.h +++ b/include/asm-i386/current.h @@ -1,14 +1,15 @@ #ifndef _I386_CURRENT_H #define _I386_CURRENT_H -#include #include +#include struct task_struct; +DECLARE_PER_CPU(struct task_struct *, current_task); static __always_inline struct task_struct *get_current(void) { - return read_pda(pcurrent); + return x86_read_percpu(current_task); } #define current get_current() diff --git a/include/asm-i386/irq_regs.h b/include/asm-i386/irq_regs.h index a1b3f7f594a2..3368b20c0b48 100644 --- a/include/asm-i386/irq_regs.h +++ b/include/asm-i386/irq_regs.h @@ -1,25 +1,27 @@ /* * Per-cpu current frame pointer - the location of the last exception frame on - * the stack, stored in the PDA. + * the stack, stored in the per-cpu area. * * Jeremy Fitzhardinge */ #ifndef _ASM_I386_IRQ_REGS_H #define _ASM_I386_IRQ_REGS_H -#include +#include + +DECLARE_PER_CPU(struct pt_regs *, irq_regs); static inline struct pt_regs *get_irq_regs(void) { - return read_pda(irq_regs); + return x86_read_percpu(irq_regs); } static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs) { struct pt_regs *old_regs; - old_regs = read_pda(irq_regs); - write_pda(irq_regs, new_regs); + old_regs = get_irq_regs(); + x86_write_percpu(irq_regs, new_regs); return old_regs; } diff --git a/include/asm-i386/pda.h b/include/asm-i386/pda.h deleted file mode 100644 index aef7f732f77e..000000000000 --- a/include/asm-i386/pda.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - Per-processor Data Areas - Jeremy Fitzhardinge 2006 - Based on asm-x86_64/pda.h by Andi Kleen. - */ -#ifndef _I386_PDA_H -#define _I386_PDA_H - -#include -#include -#include - -struct i386_pda -{ - struct i386_pda *_pda; /* pointer to self */ - - int cpu_number; - struct task_struct *pcurrent; /* current process */ - struct pt_regs *irq_regs; -}; - -DECLARE_PER_CPU(struct i386_pda, _cpu_pda); -#define cpu_pda(i) (&per_cpu(_cpu_pda, (i))) -#define pda_offset(field) offsetof(struct i386_pda, field) - -extern void __bad_pda_field(void); - -/* This variable is never instantiated. It is only used as a stand-in - for the real per-cpu PDA memory, so that gcc can understand what - memory operations the inline asms() below are performing. This - eliminates the need to make the asms volatile or have memory - clobbers, so gcc can readily analyse them. */ -extern struct i386_pda _proxy_pda; - -#define pda_to_op(op,field,val) \ - do { \ - typedef typeof(_proxy_pda.field) T__; \ - if (0) { T__ tmp__; tmp__ = (val); } \ - switch (sizeof(_proxy_pda.field)) { \ - case 1: \ - asm(op "b %1,%%fs:%c2" \ - : "+m" (_proxy_pda.field) \ - :"ri" ((T__)val), \ - "i"(pda_offset(field))); \ - break; \ - case 2: \ - asm(op "w %1,%%fs:%c2" \ - : "+m" (_proxy_pda.field) \ - :"ri" ((T__)val), \ - "i"(pda_offset(field))); \ - break; \ - case 4: \ - asm(op "l %1,%%fs:%c2" \ - : "+m" (_proxy_pda.field) \ - :"ri" ((T__)val), \ - "i"(pda_offset(field))); \ - break; \ - default: __bad_pda_field(); \ - } \ - } while (0) - -#define pda_from_op(op,field) \ - ({ \ - typeof(_proxy_pda.field) ret__; \ - switch (sizeof(_proxy_pda.field)) { \ - case 1: \ - asm(op "b %%fs:%c1,%0" \ - : "=r" (ret__) \ - : "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ - break; \ - case 2: \ - asm(op "w %%fs:%c1,%0" \ - : "=r" (ret__) \ - : "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ - break; \ - case 4: \ - asm(op "l %%fs:%c1,%0" \ - : "=r" (ret__) \ - : "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ - break; \ - default: __bad_pda_field(); \ - } \ - ret__; }) - -/* Return a pointer to a pda field */ -#define pda_addr(field) \ - ((typeof(_proxy_pda.field) *)((unsigned char *)read_pda(_pda) + \ - pda_offset(field))) - -#define read_pda(field) pda_from_op("mov",field) -#define write_pda(field,val) pda_to_op("mov",field,val) -#define add_pda(field,val) pda_to_op("add",field,val) -#define sub_pda(field,val) pda_to_op("sub",field,val) -#define or_pda(field,val) pda_to_op("or",field,val) - -#endif /* _I386_PDA_H */ diff --git a/include/asm-i386/percpu.h b/include/asm-i386/percpu.h index a10e7c68ae9d..c5f12f0d9c23 100644 --- a/include/asm-i386/percpu.h +++ b/include/asm-i386/percpu.h @@ -1,9 +1,30 @@ #ifndef __ARCH_I386_PERCPU__ #define __ARCH_I386_PERCPU__ -#ifndef __ASSEMBLY__ -#include -#else +#ifdef __ASSEMBLY__ + +/* + * PER_CPU finds an address of a per-cpu variable. + * + * Args: + * var - variable name + * reg - 32bit register + * + * The resulting address is stored in the "reg" argument. + * + * Example: + * PER_CPU(cpu_gdt_descr, %ebx) + */ +#ifdef CONFIG_SMP +#define PER_CPU(var, reg) \ + movl %fs:per_cpu__this_cpu_off, reg; \ + addl $per_cpu__##var, reg +#else /* ! SMP */ +#define PER_CPU(var, reg) \ + movl $per_cpu__##var, reg; +#endif /* SMP */ + +#else /* ...!ASSEMBLY */ /* * PER_CPU finds an address of a per-cpu variable. @@ -18,14 +39,107 @@ * PER_CPU(cpu_gdt_descr, %ebx) */ #ifdef CONFIG_SMP -#define PER_CPU(var, cpu) \ - movl __per_cpu_offset(,cpu,4), cpu; \ - addl $per_cpu__##var, cpu; -#else /* ! SMP */ -#define PER_CPU(var, cpu) \ - movl $per_cpu__##var, cpu; +/* Same as generic implementation except for optimized local access. */ +#define __GENERIC_PER_CPU + +/* This is used for other cpus to find our section. */ +extern unsigned long __per_cpu_offset[]; + +/* Separate out the type, so (int[3], foo) works. */ +#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name +#define DEFINE_PER_CPU(type, name) \ + __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name + +/* We can use this directly for local CPU (faster). */ +DECLARE_PER_CPU(unsigned long, this_cpu_off); + +/* var is in discarded region: offset to particular copy we want */ +#define per_cpu(var, cpu) (*({ \ + extern int simple_indentifier_##var(void); \ + RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); })) + +#define __raw_get_cpu_var(var) (*({ \ + extern int simple_indentifier_##var(void); \ + RELOC_HIDE(&per_cpu__##var, x86_read_percpu(this_cpu_off)); \ +})) + +#define __get_cpu_var(var) __raw_get_cpu_var(var) + +/* A macro to avoid #include hell... */ +#define percpu_modcopy(pcpudst, src, size) \ +do { \ + unsigned int __i; \ + for_each_possible_cpu(__i) \ + memcpy((pcpudst)+__per_cpu_offset[__i], \ + (src), (size)); \ +} while (0) + +#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) +#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) + +/* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */ +#define __percpu_seg "%%fs:" +#else /* !SMP */ +#include +#define __percpu_seg "" #endif /* SMP */ +/* For arch-specific code, we can use direct single-insn ops (they + * don't give an lvalue though). */ +extern void __bad_percpu_size(void); + +#define percpu_to_op(op,var,val) \ + do { \ + typedef typeof(var) T__; \ + if (0) { T__ tmp__; tmp__ = (val); } \ + switch (sizeof(var)) { \ + case 1: \ + asm(op "b %1,"__percpu_seg"%0" \ + : "+m" (var) \ + :"ri" ((T__)val)); \ + break; \ + case 2: \ + asm(op "w %1,"__percpu_seg"%0" \ + : "+m" (var) \ + :"ri" ((T__)val)); \ + break; \ + case 4: \ + asm(op "l %1,"__percpu_seg"%0" \ + : "+m" (var) \ + :"ri" ((T__)val)); \ + break; \ + default: __bad_percpu_size(); \ + } \ + } while (0) + +#define percpu_from_op(op,var) \ + ({ \ + typeof(var) ret__; \ + switch (sizeof(var)) { \ + case 1: \ + asm(op "b "__percpu_seg"%1,%0" \ + : "=r" (ret__) \ + : "m" (var)); \ + break; \ + case 2: \ + asm(op "w "__percpu_seg"%1,%0" \ + : "=r" (ret__) \ + : "m" (var)); \ + break; \ + case 4: \ + asm(op "l "__percpu_seg"%1,%0" \ + : "=r" (ret__) \ + : "m" (var)); \ + break; \ + default: __bad_percpu_size(); \ + } \ + ret__; }) + +#define x86_read_percpu(var) percpu_from_op("mov", per_cpu__##var) +#define x86_write_percpu(var,val) percpu_to_op("mov", per_cpu__##var, val) +#define x86_add_percpu(var,val) percpu_to_op("add", per_cpu__##var, val) +#define x86_sub_percpu(var,val) percpu_to_op("sub", per_cpu__##var, val) +#define x86_or_percpu(var,val) percpu_to_op("or", per_cpu__##var, val) #endif /* !__ASSEMBLY__ */ #endif /* __ARCH_I386_PERCPU__ */ diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 922260474646..ced2da8a0d65 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -377,7 +377,7 @@ struct thread_struct { .vm86_info = NULL, \ .sysenter_cs = __KERNEL_CS, \ .io_bitmap_ptr = NULL, \ - .fs = __KERNEL_PDA, \ + .fs = __KERNEL_PERCPU, \ } /* diff --git a/include/asm-i386/segment.h b/include/asm-i386/segment.h index 065f10bfa487..07e70624d87c 100644 --- a/include/asm-i386/segment.h +++ b/include/asm-i386/segment.h @@ -39,7 +39,7 @@ * 25 - APM BIOS support * * 26 - ESPFIX small SS - * 27 - PDA [ per-cpu private data area ] + * 27 - per-cpu [ offset to per-cpu data area ] * 28 - unused * 29 - unused * 30 - unused @@ -74,8 +74,8 @@ #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14) #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8) -#define GDT_ENTRY_PDA (GDT_ENTRY_KERNEL_BASE + 15) -#define __KERNEL_PDA (GDT_ENTRY_PDA * 8) +#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15) +#define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8) #define GDT_ENTRY_DOUBLEFAULT_TSS 31 diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h index 2d083cb4ca93..090abc1da32a 100644 --- a/include/asm-i386/smp.h +++ b/include/asm-i386/smp.h @@ -8,7 +8,6 @@ #include #include #include -#include #endif #if defined(CONFIG_X86_LOCAL_APIC) && !defined(__ASSEMBLY__) @@ -112,7 +111,8 @@ do { } while (0) * from the initial startup. We map APIC_BASE very early in page_setup(), * so this is correct in the x86 case. */ -#define raw_smp_processor_id() (read_pda(cpu_number)) +DECLARE_PER_CPU(int, cpu_number); +#define raw_smp_processor_id() (x86_read_percpu(cpu_number)) extern cpumask_t cpu_callout_map; extern cpumask_t cpu_callin_map; -- cgit v1.2.3-59-g8ed1b From c5413fbe894924ddb8aa474a4d4da52e7a6c7e0b Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:16 +0200 Subject: [PATCH] i386: Fix UP gdt bugs Fixes two problems with the GDT when compiling for uniprocessor: - There's no percpu segment, so trying to load its selector into %fs fails. Use a null selector instead. - The real gdt needs to be loaded at some point. Do it in cpu_init(). Signed-off-by: Chris Wright Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Rusty Russell --- arch/i386/kernel/cpu/common.c | 13 +++++++++++++ arch/i386/kernel/smpboot.c | 12 ------------ include/asm-i386/processor.h | 1 + include/asm-i386/segment.h | 4 ++++ 4 files changed, 18 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 27e00565f5e4..794d593c47eb 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -638,6 +638,18 @@ struct pt_regs * __devinit idle_regs(struct pt_regs *regs) return regs; } +/* Current gdt points %fs at the "master" per-cpu area: after this, + * it's on the real one. */ +void switch_to_new_gdt(void) +{ + struct Xgt_desc_struct gdt_descr; + + gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id()); + gdt_descr.size = GDT_SIZE - 1; + load_gdt(&gdt_descr); + asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory"); +} + /* * cpu_init() initializes state that is per-CPU. Some data is already * initialized (naturally) in the bootstrap process, such as the GDT @@ -668,6 +680,7 @@ void __cpuinit cpu_init(void) } load_idt(&idt_descr); + switch_to_new_gdt(); /* * Set up and load the per-CPU TSS and LDT diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index f79b6233db78..7c1dbef399cd 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -1177,18 +1177,6 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) smp_boot_cpus(max_cpus); } -/* Current gdt points %fs at the "master" per-cpu area: after this, - * it's on the real one. */ -static inline void switch_to_new_gdt(void) -{ - struct Xgt_desc_struct gdt_descr; - - gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id()); - gdt_descr.size = GDT_SIZE - 1; - load_gdt(&gdt_descr); - asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory"); -} - void __init native_smp_prepare_boot_cpu(void) { unsigned int cpu = smp_processor_id(); diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index ced2da8a0d65..70f3515c3db0 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -750,6 +750,7 @@ extern void enable_sep_cpu(void); extern int sysenter_setup(void); extern void cpu_set_gdt(int); +extern void switch_to_new_gdt(void); extern void cpu_init(void); extern int force_mwait; diff --git a/include/asm-i386/segment.h b/include/asm-i386/segment.h index 07e70624d87c..597a47c2515f 100644 --- a/include/asm-i386/segment.h +++ b/include/asm-i386/segment.h @@ -75,7 +75,11 @@ #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8) #define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15) +#ifdef CONFIG_SMP #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8) +#else +#define __KERNEL_PERCPU 0 +#endif #define GDT_ENTRY_DOUBLEFAULT_TSS 31 -- cgit v1.2.3-59-g8ed1b From 9ce8c2ed12550f90fd6e902990652b13df647793 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:16 +0200 Subject: [PATCH] i386: map enough initial memory to create lowmem mappings head.S creates the very initial pagetable for the kernel. This just maps enough space for the kernel itself, and an allocation bitmap. The amount of mapped memory is rounded up to 4Mbytes, and so this typically ends up mapping 8Mbytes of memory. When booting, pagetable_init() needs to create mappings for all lowmem, and the pagetables for these mappings are allocated from the free pages around the kernel in low memory. If the number of pagetable pages + kernel size exceeds head.S's initial mapping, it will end up faulting on an unmapped page. This will only happen with specific combinations of kernel size and memory size. This patch makes sure that head.S also maps enough space to fit the kernel pagetables as well as the kernel itself. It ends up using an additional two pages of unreclaimable memory. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Acked-by: "H. Peter Anvin" Cc: Andi Kleen Cc: Zachary Amsden Cc: Chris Wright Cc: "Eric W. Biederman" Cc: Linus Torvalds , --- arch/i386/kernel/asm-offsets.c | 6 ++++++ arch/i386/kernel/head.S | 23 +++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c index b05e85fd1c1e..27a776c9044d 100644 --- a/arch/i386/kernel/asm-offsets.c +++ b/arch/i386/kernel/asm-offsets.c @@ -11,6 +11,7 @@ #include #include #include "sigframe.h" +#include #include #include #include @@ -96,6 +97,11 @@ void foo(void) sizeof(struct tss_struct)); DEFINE(PAGE_SIZE_asm, PAGE_SIZE); + DEFINE(PAGE_SHIFT_asm, PAGE_SHIFT); + DEFINE(PTRS_PER_PTE, PTRS_PER_PTE); + DEFINE(PTRS_PER_PMD, PTRS_PER_PMD); + DEFINE(PTRS_PER_PGD, PTRS_PER_PGD); + DEFINE(VDSO_PRELINK_asm, VDSO_PRELINK); OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx); diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index 12277d8938df..9b10af65faaa 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -34,17 +34,32 @@ /* * This is how much memory *in addition to the memory covered up to - * and including _end* we need mapped initially. We need one bit for - * each possible page, but only in low memory, which means - * 2^32/4096/8 = 128K worst case (4G/4G split.) + * and including _end* we need mapped initially. + * We need: + * - one bit for each possible page, but only in low memory, which means + * 2^32/4096/8 = 128K worst case (4G/4G split.) + * - enough space to map all low memory, which means + * (2^32/4096) / 1024 pages (worst case, non PAE) + * (2^32/4096) / 512 + 4 pages (worst case for PAE) + * - a few pages for allocator use before the kernel pagetable has + * been set up * * Modulo rounding, each megabyte assigned here requires a kilobyte of * memory, which is currently unreclaimed. * * This should be a multiple of a page. */ -#define INIT_MAP_BEYOND_END (128*1024) +LOW_PAGES = 1<<(32-PAGE_SHIFT_asm) +#if PTRS_PER_PMD > 1 +PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD +#else +PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD) +#endif +BOOTBITMAP_SIZE = LOW_PAGES / 8 +ALLOCATOR_SLOP = 4 + +INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm /* * 32-bit kernel entrypoint; only used by the boot CPU. On entry, -- cgit v1.2.3-59-g8ed1b From 57decbda6a2a7c400b2a3b3b12e52ccbdc977118 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:16 +0200 Subject: [PATCH] x86: update for i386 and x86-64 check_bugs Remove spurious comments, headers and keywords from x86-64 bugs.[ch]. Use identify_boot_cpu() AK: merged with other patch Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen --- arch/x86_64/kernel/bugs.c | 9 +-------- include/asm-i386/bugs.h | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/bugs.c b/arch/x86_64/kernel/bugs.c index 131e541e3f7b..12b585b5345d 100644 --- a/arch/x86_64/kernel/bugs.c +++ b/arch/x86_64/kernel/bugs.c @@ -3,19 +3,12 @@ * * Copyright (C) 1994 Linus Torvalds * Copyright (C) 2000 SuSE - * - * This is included by init/main.c to check for architecture-dependent bugs. - * - * Needs: - * void check_bugs(void); */ #include +#include #include #include -#include -#include -#include void __init check_bugs(void) { diff --git a/include/asm-i386/bugs.h b/include/asm-i386/bugs.h index df539b390448..d28979ff73be 100644 --- a/include/asm-i386/bugs.h +++ b/include/asm-i386/bugs.h @@ -7,6 +7,6 @@ #ifndef _ASM_I386_BUG_H #define _ASM_I386_BUG_H -extern void __init check_bugs(void); +void check_bugs(void); #endif /* _ASM_I386_BUG_H */ -- cgit v1.2.3-59-g8ed1b From 752783c050f1729452a89b2baea45b0124ac91c7 Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Wed, 2 May 2007 19:27:16 +0200 Subject: [PATCH] i386: In compat mode, the return value here was uninitialized. Signed-off-by: Zachary Amsden Signed-off-by: Andi Kleen --- arch/i386/kernel/sysenter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c index 94defac6fc3d..ff4ee6f3326b 100644 --- a/arch/i386/kernel/sysenter.c +++ b/arch/i386/kernel/sysenter.c @@ -268,7 +268,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) { struct mm_struct *mm = current->mm; unsigned long addr; - int ret; + int ret = 0; bool compat; down_write(&mm->mmap_sem); -- cgit v1.2.3-59-g8ed1b From 959b4fdfe7e27bcf101e2381e500e4076f2bb9ce Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:16 +0200 Subject: [PATCH] i386: PARAVIRT: Allow boot-time disable of paravirt_ops patching Add "noreplace-paravirt" to disable paravirt_ops patching. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Rusty Russell Cc: Andi Kleen Signed-off-by: Andrew Morton --- Documentation/kernel-parameters.txt | 3 +++ arch/i386/kernel/alternative.c | 13 +++++++++++++ 2 files changed, 16 insertions(+) (limited to 'arch') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 242b3a09b6ce..38d7db3262c7 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -64,6 +64,7 @@ parameter is applicable: GENERIC_TIME The generic timeofday code is enabled. NFS Appropriate NFS support is enabled. OSS OSS sound support is enabled. + PV_OPS A paravirtualized kernel PARIDE The ParIDE subsystem is enabled. PARISC The PA-RISC architecture is enabled. PCI PCI bus support is enabled. @@ -1164,6 +1165,8 @@ and is between 256 and 4096 characters. It is defined in the file nomce [IA-32] Machine Check Exception + noreplace-paravirt [IA-32,PV_OPS] Don't patch paravirt_ops + noreplace-smp [IA-32,SMP] Don't replace SMP instructions with UP alternatives diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index c5d037c60950..080a59d56ea6 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -30,6 +30,16 @@ static int __init setup_noreplace_smp(char *str) } __setup("noreplace-smp", setup_noreplace_smp); +#ifdef CONFIG_PARAVIRT +static int noreplace_paravirt = 0; + +static int __init setup_noreplace_paravirt(char *str) +{ + noreplace_paravirt = 1; + return 1; +} +__setup("noreplace-paravirt", setup_noreplace_paravirt); +#endif #define DPRINTK(fmt, args...) if (debug_alternative) \ printk(KERN_DEBUG fmt, args) @@ -330,6 +340,9 @@ void apply_paravirt(struct paravirt_patch_site *start, { struct paravirt_patch_site *p; + if (noreplace_paravirt) + return; + for (p = start; p < end; p++) { unsigned int used; -- cgit v1.2.3-59-g8ed1b From 18420001d6ceafbe094a6f911126c6eee34d25c4 Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Wed, 2 May 2007 19:27:16 +0200 Subject: [PATCH] i386: Clean up arch/i386/kernel/cpu/mcheck/p4.c No, just no. You do not use goto to skip a code block. You do not return an obvious variable from a singly-inlined function and give the function a return value. You don't put unexplained comments about kmalloc in code which doesn't do dynamic allocation. And you don't leave stray warnings around for no good reason. Also, when possible, it is better to use block scoped variables because gcc can sometime generate better code. Signed-off-by: Zachary Amsden Signed-off-by: Andi Kleen --- arch/i386/kernel/cpu/mcheck/p4.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/mcheck/p4.c b/arch/i386/kernel/cpu/mcheck/p4.c index 504434a46011..1509edfb2313 100644 --- a/arch/i386/kernel/cpu/mcheck/p4.c +++ b/arch/i386/kernel/cpu/mcheck/p4.c @@ -124,13 +124,10 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) /* P4/Xeon Extended MCE MSR retrieval, return 0 if unsupported */ -static inline int intel_get_extended_msrs(struct intel_mce_extended_msrs *r) +static inline void intel_get_extended_msrs(struct intel_mce_extended_msrs *r) { u32 h; - if (mce_num_extended_msrs == 0) - goto done; - rdmsr (MSR_IA32_MCG_EAX, r->eax, h); rdmsr (MSR_IA32_MCG_EBX, r->ebx, h); rdmsr (MSR_IA32_MCG_ECX, r->ecx, h); @@ -141,12 +138,6 @@ static inline int intel_get_extended_msrs(struct intel_mce_extended_msrs *r) rdmsr (MSR_IA32_MCG_ESP, r->esp, h); rdmsr (MSR_IA32_MCG_EFLAGS, r->eflags, h); rdmsr (MSR_IA32_MCG_EIP, r->eip, h); - - /* can we rely on kmalloc to do a dynamic - * allocation for the reserved registers? - */ -done: - return mce_num_extended_msrs; } static fastcall void intel_machine_check(struct pt_regs * regs, long error_code) @@ -155,7 +146,6 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code) u32 alow, ahigh, high, low; u32 mcgstl, mcgsth; int i; - struct intel_mce_extended_msrs dbg; rdmsr (MSR_IA32_MCG_STATUS, mcgstl, mcgsth); if (mcgstl & (1<<0)) /* Recoverable ? */ @@ -164,7 +154,9 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code) printk (KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", smp_processor_id(), mcgsth, mcgstl); - if (intel_get_extended_msrs(&dbg)) { + if (mce_num_extended_msrs > 0) { + struct intel_mce_extended_msrs dbg; + intel_get_extended_msrs(&dbg); printk (KERN_DEBUG "CPU %d: EIP: %08x EFLAGS: %08x\n", smp_processor_id(), dbg.eip, dbg.eflags); printk (KERN_DEBUG "\teax: %08x ebx: %08x ecx: %08x edx: %08x\n", -- cgit v1.2.3-59-g8ed1b From 9f53a729dbf0ba8abdc464f6eb828f485d3417f7 Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Wed, 2 May 2007 19:27:16 +0200 Subject: [PATCH] i386: Now that the VDSO can be relocated, we can support it in VMI configurations. Signed-off-by: Zachary Amsden Signed-off-by: Andi Kleen --- arch/i386/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 6964e247f473..1a94a73fe801 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -220,7 +220,7 @@ config PARAVIRT config VMI bool "VMI Paravirt-ops support" - depends on PARAVIRT && !COMPAT_VDSO + depends on PARAVIRT help VMI provides a paravirtualized interface to the VMware ESX server (it could be used by other hypervisors in theory too, but is not -- cgit v1.2.3-59-g8ed1b From eeef9c68aae2f4f21ab810d0339e0f22d30b0cd8 Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Wed, 2 May 2007 19:27:16 +0200 Subject: [PATCH] i386: Implement vmi_kmap_atomic_pte Implement vmi_kmap_atomic_pte in terms of the backend set_linear_mapping operation. The conversion is rather straighforward; call kmap_atomic and then inform the hypervisor of the page mapping. The _flush_tlb damage is due to macros being pulled in from highmem.h. Signed-off-by: Zachary Amsden Signed-off-by: Andi Kleen --- arch/i386/kernel/vmi.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index 12312988c626..0df0b2cd3617 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -65,8 +66,8 @@ static struct { void (*release_page)(u32, u32); void (*set_pte)(pte_t, pte_t *, unsigned); void (*update_pte)(pte_t *, unsigned); - void (*set_linear_mapping)(int, u32, u32, u32); - void (*flush_tlb)(int); + void (*set_linear_mapping)(int, void *, u32, u32); + void (*_flush_tlb)(int); void (*set_initial_ap_state)(int, int); void (*halt)(void); void (*set_lazy_mode)(int mode); @@ -221,12 +222,12 @@ static void vmi_load_esp0(struct tss_struct *tss, static void vmi_flush_tlb_user(void) { - vmi_ops.flush_tlb(VMI_FLUSH_TLB); + vmi_ops._flush_tlb(VMI_FLUSH_TLB); } static void vmi_flush_tlb_kernel(void) { - vmi_ops.flush_tlb(VMI_FLUSH_TLB | VMI_FLUSH_GLOBAL); + vmi_ops._flush_tlb(VMI_FLUSH_TLB | VMI_FLUSH_GLOBAL); } /* Stub to do nothing at all; used for delays and unimplemented calls */ @@ -349,8 +350,11 @@ static void vmi_check_page_type(u32 pfn, int type) #define vmi_check_page_type(p,t) do { } while (0) #endif -static void vmi_map_pt_hook(int type, pte_t *va, u32 pfn) +#ifdef CONFIG_HIGHPTE +static void *vmi_kmap_atomic_pte(struct page *page, enum km_type type) { + void *va = kmap_atomic(page, type); + /* * Internally, the VMI ROM must map virtual addresses to physical * addresses for processing MMU updates. By the time MMU updates @@ -364,8 +368,11 @@ static void vmi_map_pt_hook(int type, pte_t *va, u32 pfn) * args: SLOT VA COUNT PFN */ BUG_ON(type != KM_PTE0 && type != KM_PTE1); - vmi_ops.set_linear_mapping((type - KM_PTE0)+1, (u32)va, 1, pfn); + vmi_ops.set_linear_mapping((type - KM_PTE0)+1, va, 1, page_to_pfn(page)); + + return va; } +#endif static void vmi_allocate_pt(u32 pfn) { @@ -660,7 +667,7 @@ void vmi_bringup(void) { /* We must establish the lowmem mapping for MMU ops to work */ if (vmi_ops.set_linear_mapping) - vmi_ops.set_linear_mapping(0, __PAGE_OFFSET, max_low_pfn, 0); + vmi_ops.set_linear_mapping(0, (void *)__PAGE_OFFSET, max_low_pfn, 0); } /* @@ -800,8 +807,8 @@ static inline int __init activate_vmi(void) para_wrap(set_lazy_mode, vmi_set_lazy_mode, set_lazy_mode, SetLazyMode); /* user and kernel flush are just handled with different flags to FlushTLB */ - para_wrap(flush_tlb_user, vmi_flush_tlb_user, flush_tlb, FlushTLB); - para_wrap(flush_tlb_kernel, vmi_flush_tlb_kernel, flush_tlb, FlushTLB); + para_wrap(flush_tlb_user, vmi_flush_tlb_user, _flush_tlb, FlushTLB); + para_wrap(flush_tlb_kernel, vmi_flush_tlb_kernel, _flush_tlb, FlushTLB); para_fill(flush_tlb_single, InvalPage); /* @@ -847,9 +854,12 @@ static inline int __init activate_vmi(void) paravirt_ops.release_pt = vmi_release_pt; paravirt_ops.release_pd = vmi_release_pd; } -#if 0 - para_wrap(map_pt_hook, vmi_map_pt_hook, set_linear_mapping, - SetLinearMapping); + + /* Set linear is needed in all cases */ + vmi_ops.set_linear_mapping = vmi_get_function(VMI_CALL_SetLinearMapping); +#ifdef CONFIG_HIGHPTE + if (vmi_ops.set_linear_mapping) + paravirt_ops.kmap_atomic_pte = vmi_kmap_atomic_pte; #endif /* -- cgit v1.2.3-59-g8ed1b From e0bb8643974397a8d36670e06e6a54bb84f3289f Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Wed, 2 May 2007 19:27:16 +0200 Subject: [PATCH] i386: Convert VMI timer to use clock events Convert VMI timer to use clock events, making it properly able to use the NO_HZ infrastructure. On UP systems, with no local APIC, we just continue to route these events through the PIT. On systems with a local APIC, or SMP, we provide a single source interrupt chip which creates the local timer IRQ. It actually gets delivered by the APIC hardware, but we don't want to use the same local APIC clocksource processing, so we create our own handler here. Signed-off-by: Zachary Amsden Signed-off-by: Andi Kleen CC: Dan Hecht CC: Ingo Molnar CC: Thomas Gleixner --- arch/i386/kernel/Makefile | 2 +- arch/i386/kernel/entry.S | 5 - arch/i386/kernel/vmi.c | 26 +-- arch/i386/kernel/vmiclock.c | 318 +++++++++++++++++++++++++++++ arch/i386/kernel/vmitime.c | 482 -------------------------------------------- include/asm-i386/vmi_time.h | 18 +- 6 files changed, 327 insertions(+), 524 deletions(-) create mode 100644 arch/i386/kernel/vmiclock.c delete mode 100644 arch/i386/kernel/vmitime.c (limited to 'arch') diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index bd7753cb9e69..4f98516b9f94 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile @@ -39,7 +39,7 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_HPET_TIMER) += hpet.o obj-$(CONFIG_K8_NB) += k8.o -obj-$(CONFIG_VMI) += vmi.o vmitime.o +obj-$(CONFIG_VMI) += vmi.o vmiclock.o obj-$(CONFIG_PARAVIRT) += paravirt.o obj-y += pcspeaker.o diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 7f92ceb428ad..90ffcdb69838 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -637,11 +637,6 @@ ENDPROC(name) /* The include is where all of the SMP etc. interrupts come from */ #include "entry_arch.h" -/* This alternate entry is needed because we hijack the apic LVTT */ -#if defined(CONFIG_VMI) && defined(CONFIG_X86_LOCAL_APIC) -BUILD_INTERRUPT(apic_vmi_timer_interrupt,LOCAL_TIMER_VECTOR) -#endif - KPROBE_ENTRY(page_fault) RING0_EC_FRAME pushl $do_page_fault diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index 0df0b2cd3617..0fae15dee765 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c @@ -77,6 +77,9 @@ static struct { extern struct paravirt_patch __start_parainstructions[], __stop_parainstructions[]; +/* Cached VMI operations */ +struct vmi_timer_ops vmi_timer_ops; + /* * VMI patching routines. */ @@ -235,18 +238,6 @@ static void vmi_nop(void) { } -/* For NO_IDLE_HZ, we stop the clock when halting the kernel */ -static fastcall void vmi_safe_halt(void) -{ - int idle = vmi_stop_hz_timer(); - vmi_ops.halt(); - if (idle) { - local_irq_disable(); - vmi_account_time_restart_hz_timer(); - local_irq_enable(); - } -} - #ifdef CONFIG_DEBUG_PAGE_TYPE #ifdef CONFIG_X86_PAE @@ -722,7 +713,6 @@ do { \ } \ } while (0) - /* * Activate the VMI interface and switch into paravirtualized mode */ @@ -901,8 +891,8 @@ static inline int __init activate_vmi(void) paravirt_ops.get_wallclock = vmi_get_wallclock; paravirt_ops.set_wallclock = vmi_set_wallclock; #ifdef CONFIG_X86_LOCAL_APIC - paravirt_ops.setup_boot_clock = vmi_timer_setup_boot_alarm; - paravirt_ops.setup_secondary_clock = vmi_timer_setup_secondary_alarm; + paravirt_ops.setup_boot_clock = vmi_time_bsp_init; + paravirt_ops.setup_secondary_clock = vmi_time_ap_init; #endif paravirt_ops.get_scheduled_cycles = vmi_get_sched_cycles; paravirt_ops.get_cpu_khz = vmi_cpu_khz; @@ -914,11 +904,7 @@ static inline int __init activate_vmi(void) disable_vmi_timer = 1; } - /* No idle HZ mode only works if VMI timer and no idle is enabled */ - if (disable_noidle || disable_vmi_timer) - para_fill(safe_halt, Halt); - else - para_wrap(safe_halt, vmi_safe_halt, halt, Halt); + para_fill(safe_halt, Halt); /* * Alternative instruction rewriting doesn't happen soon enough diff --git a/arch/i386/kernel/vmiclock.c b/arch/i386/kernel/vmiclock.c new file mode 100644 index 000000000000..26a37f8a8762 --- /dev/null +++ b/arch/i386/kernel/vmiclock.c @@ -0,0 +1,318 @@ +/* + * VMI paravirtual timer support routines. + * + * Copyright (C) 2007, VMware, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include "io_ports.h" + +#define VMI_ONESHOT (VMI_ALARM_IS_ONESHOT | VMI_CYCLES_REAL | vmi_get_alarm_wiring()) +#define VMI_PERIODIC (VMI_ALARM_IS_PERIODIC | VMI_CYCLES_REAL | vmi_get_alarm_wiring()) + +static DEFINE_PER_CPU(struct clock_event_device, local_events); + +static inline u32 vmi_counter(u32 flags) +{ + /* Given VMI_ONESHOT or VMI_PERIODIC, return the corresponding + * cycle counter. */ + return flags & VMI_ALARM_COUNTER_MASK; +} + +/* paravirt_ops.get_wallclock = vmi_get_wallclock */ +unsigned long vmi_get_wallclock(void) +{ + unsigned long long wallclock; + wallclock = vmi_timer_ops.get_wallclock(); // nsec + (void)do_div(wallclock, 1000000000); // sec + + return wallclock; +} + +/* paravirt_ops.set_wallclock = vmi_set_wallclock */ +int vmi_set_wallclock(unsigned long now) +{ + return 0; +} + +/* paravirt_ops.get_scheduled_cycles = vmi_get_sched_cycles */ +unsigned long long vmi_get_sched_cycles(void) +{ + return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_AVAILABLE); +} + +/* paravirt_ops.get_cpu_khz = vmi_cpu_khz */ +unsigned long vmi_cpu_khz(void) +{ + unsigned long long khz; + khz = vmi_timer_ops.get_cycle_frequency(); + (void)do_div(khz, 1000); + return khz; +} + +static inline unsigned int vmi_get_timer_vector(void) +{ +#ifdef CONFIG_X86_IO_APIC + return FIRST_DEVICE_VECTOR; +#else + return FIRST_EXTERNAL_VECTOR; +#endif +} + +/** vmi clockchip */ +#ifdef CONFIG_X86_LOCAL_APIC +static unsigned int startup_timer_irq(unsigned int irq) +{ + unsigned long val = apic_read(APIC_LVTT); + apic_write(APIC_LVTT, vmi_get_timer_vector()); + + return (val & APIC_SEND_PENDING); +} + +static void mask_timer_irq(unsigned int irq) +{ + unsigned long val = apic_read(APIC_LVTT); + apic_write(APIC_LVTT, val | APIC_LVT_MASKED); +} + +static void unmask_timer_irq(unsigned int irq) +{ + unsigned long val = apic_read(APIC_LVTT); + apic_write(APIC_LVTT, val & ~APIC_LVT_MASKED); +} + +static void ack_timer_irq(unsigned int irq) +{ + ack_APIC_irq(); +} + +static struct irq_chip vmi_chip __read_mostly = { + .name = "VMI-LOCAL", + .startup = startup_timer_irq, + .mask = mask_timer_irq, + .unmask = unmask_timer_irq, + .ack = ack_timer_irq +}; +#endif + +/** vmi clockevent */ +#define VMI_ALARM_WIRED_IRQ0 0x00000000 +#define VMI_ALARM_WIRED_LVTT 0x00010000 +static int vmi_wiring = VMI_ALARM_WIRED_IRQ0; + +static inline int vmi_get_alarm_wiring(void) +{ + return vmi_wiring; +} + +static void vmi_timer_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + cycle_t now, cycles_per_hz; + BUG_ON(!irqs_disabled()); + + switch (mode) { + case CLOCK_EVT_MODE_ONESHOT: + break; + case CLOCK_EVT_MODE_PERIODIC: + cycles_per_hz = vmi_timer_ops.get_cycle_frequency(); + (void)do_div(cycles_per_hz, HZ); + now = vmi_timer_ops.get_cycle_counter(vmi_counter(VMI_PERIODIC)); + vmi_timer_ops.set_alarm(VMI_PERIODIC, now, cycles_per_hz); + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + switch (evt->mode) { + case CLOCK_EVT_MODE_ONESHOT: + vmi_timer_ops.cancel_alarm(VMI_ONESHOT); + break; + case CLOCK_EVT_MODE_PERIODIC: + vmi_timer_ops.cancel_alarm(VMI_PERIODIC); + break; + default: + break; + } + break; + default: + break; + } +} + +static int vmi_timer_next_event(unsigned long delta, + struct clock_event_device *evt) +{ + /* Unfortunately, set_next_event interface only passes relative + * expiry, but we want absolute expiry. It'd be better if were + * were passed an aboslute expiry, since a bunch of time may + * have been stolen between the time the delta is computed and + * when we set the alarm below. */ + cycle_t now = vmi_timer_ops.get_cycle_counter(vmi_counter(VMI_ONESHOT)); + + BUG_ON(evt->mode != CLOCK_EVT_MODE_ONESHOT); + vmi_timer_ops.set_alarm(VMI_ONESHOT, now + delta, 0); + return 0; +} + +static struct clock_event_device vmi_clockevent = { + .name = "vmi-timer", + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .shift = 22, + .set_mode = vmi_timer_set_mode, + .set_next_event = vmi_timer_next_event, + .rating = 1000, + .irq = 0, +}; + +static irqreturn_t vmi_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = &__get_cpu_var(local_events); + evt->event_handler(evt); + return IRQ_HANDLED; +} + +static struct irqaction vmi_clock_action = { + .name = "vmi-timer", + .handler = vmi_timer_interrupt, + .flags = IRQF_DISABLED | IRQF_NOBALANCING, + .mask = CPU_MASK_ALL, +}; + +static void __devinit vmi_time_init_clockevent(void) +{ + cycle_t cycles_per_msec; + struct clock_event_device *evt; + + int cpu = smp_processor_id(); + evt = &__get_cpu_var(local_events); + + /* Use cycles_per_msec since div_sc params are 32-bits. */ + cycles_per_msec = vmi_timer_ops.get_cycle_frequency(); + (void)do_div(cycles_per_msec, 1000); + + memcpy(evt, &vmi_clockevent, sizeof(*evt)); + /* Must pick .shift such that .mult fits in 32-bits. Choosing + * .shift to be 22 allows 2^(32-22) cycles per nano-seconds + * before overflow. */ + evt->mult = div_sc(cycles_per_msec, NSEC_PER_MSEC, evt->shift); + /* Upper bound is clockevent's use of ulong for cycle deltas. */ + evt->max_delta_ns = clockevent_delta2ns(ULONG_MAX, evt); + evt->min_delta_ns = clockevent_delta2ns(1, evt); + evt->cpumask = cpumask_of_cpu(cpu); + + printk(KERN_WARNING "vmi: registering clock event %s. mult=%lu shift=%u\n", + evt->name, evt->mult, evt->shift); + clockevents_register_device(evt); +} + +void __init vmi_time_init(void) +{ + /* Disable PIT: BIOSes start PIT CH0 with 18.2hz peridic. */ + outb_p(0x3a, PIT_MODE); /* binary, mode 5, LSB/MSB, ch 0 */ + + vmi_time_init_clockevent(); + setup_irq(0, &vmi_clock_action); +} + +#ifdef CONFIG_X86_LOCAL_APIC +void __devinit vmi_time_bsp_init(void) +{ + /* + * On APIC systems, we want local timers to fire on each cpu. We do + * this by programming LVTT to deliver timer events to the IRQ handler + * for IRQ-0, since we can't re-use the APIC local timer handler + * without interfering with that code. + */ + clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL); + local_irq_disable(); +#ifdef CONFIG_X86_SMP + /* + * XXX handle_percpu_irq only defined for SMP; we need to switch over + * to using it, since this is a local interrupt, which each CPU must + * handle individually without locking out or dropping simultaneous + * local timers on other CPUs. We also don't want to trigger the + * quirk workaround code for interrupts which gets invoked from + * handle_percpu_irq via eoi, so we use our own IRQ chip. + */ + set_irq_chip_and_handler_name(0, &vmi_chip, handle_percpu_irq, "lvtt"); +#else + set_irq_chip_and_handler_name(0, &vmi_chip, handle_edge_irq, "lvtt"); +#endif + vmi_wiring = VMI_ALARM_WIRED_LVTT; + apic_write(APIC_LVTT, vmi_get_timer_vector()); + local_irq_enable(); + clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL); +} + +void __devinit vmi_time_ap_init(void) +{ + vmi_time_init_clockevent(); + apic_write(APIC_LVTT, vmi_get_timer_vector()); +} +#endif + +/** vmi clocksource */ + +static cycle_t read_real_cycles(void) +{ + return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); +} + +static struct clocksource clocksource_vmi = { + .name = "vmi-timer", + .rating = 450, + .read = read_real_cycles, + .mask = CLOCKSOURCE_MASK(64), + .mult = 0, /* to be set */ + .shift = 22, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static int __init init_vmi_clocksource(void) +{ + cycle_t cycles_per_msec; + + if (!vmi_timer_ops.get_cycle_frequency) + return 0; + /* Use khz2mult rather than hz2mult since hz arg is only 32-bits. */ + cycles_per_msec = vmi_timer_ops.get_cycle_frequency(); + (void)do_div(cycles_per_msec, 1000); + + /* Note that clocksource.{mult, shift} converts in the opposite direction + * as clockevents. */ + clocksource_vmi.mult = clocksource_khz2mult(cycles_per_msec, + clocksource_vmi.shift); + + printk(KERN_WARNING "vmi: registering clock source khz=%lld\n", cycles_per_msec); + return clocksource_register(&clocksource_vmi); + +} +module_init(init_vmi_clocksource); diff --git a/arch/i386/kernel/vmitime.c b/arch/i386/kernel/vmitime.c deleted file mode 100644 index 9dfb17739b67..000000000000 --- a/arch/i386/kernel/vmitime.c +++ /dev/null @@ -1,482 +0,0 @@ -/* - * VMI paravirtual timer support routines. - * - * Copyright (C) 2005, VMware, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Send feedback to dhecht@vmware.com - * - */ - -/* - * Portions of this code from arch/i386/kernel/timers/timer_tsc.c. - * Portions of the CONFIG_NO_IDLE_HZ code from arch/s390/kernel/time.c. - * See comments there for proper credits. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#ifdef CONFIG_X86_LOCAL_APIC -#define VMI_ALARM_WIRING VMI_ALARM_WIRED_LVTT -#else -#define VMI_ALARM_WIRING VMI_ALARM_WIRED_IRQ0 -#endif - -/* Cached VMI operations */ -struct vmi_timer_ops vmi_timer_ops; - -#ifdef CONFIG_NO_IDLE_HZ - -/* /proc/sys/kernel/hz_timer state. */ -int sysctl_hz_timer; - -/* Some stats */ -static DEFINE_PER_CPU(unsigned long, vmi_idle_no_hz_irqs); -static DEFINE_PER_CPU(unsigned long, vmi_idle_no_hz_jiffies); -static DEFINE_PER_CPU(unsigned long, idle_start_jiffies); - -#endif /* CONFIG_NO_IDLE_HZ */ - -/* Number of alarms per second. By default this is CONFIG_VMI_ALARM_HZ. */ -static int alarm_hz = CONFIG_VMI_ALARM_HZ; - -/* Cache of the value get_cycle_frequency / HZ. */ -static signed long long cycles_per_jiffy; - -/* Cache of the value get_cycle_frequency / alarm_hz. */ -static signed long long cycles_per_alarm; - -/* The number of cycles accounted for by the 'jiffies'/'xtime' count. - * Protected by xtime_lock. */ -static unsigned long long real_cycles_accounted_system; - -/* The number of cycles accounted for by update_process_times(), per cpu. */ -static DEFINE_PER_CPU(unsigned long long, process_times_cycles_accounted_cpu); - -/* The number of stolen cycles accounted, per cpu. */ -static DEFINE_PER_CPU(unsigned long long, stolen_cycles_accounted_cpu); - -/* Clock source. */ -static cycle_t read_real_cycles(void) -{ - return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); -} - -static cycle_t read_available_cycles(void) -{ - return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_AVAILABLE); -} - -#if 0 -static cycle_t read_stolen_cycles(void) -{ - return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_STOLEN); -} -#endif /* 0 */ - -static struct clocksource clocksource_vmi = { - .name = "vmi-timer", - .rating = 450, - .read = read_real_cycles, - .mask = CLOCKSOURCE_MASK(64), - .mult = 0, /* to be set */ - .shift = 22, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - - -/* Timer interrupt handler. */ -static irqreturn_t vmi_timer_interrupt(int irq, void *dev_id); - -static struct irqaction vmi_timer_irq = { - .handler = vmi_timer_interrupt, - .flags = IRQF_DISABLED, - .mask = CPU_MASK_NONE, - .name = "VMI-alarm", -}; - -/* Alarm rate */ -static int __init vmi_timer_alarm_rate_setup(char* str) -{ - int alarm_rate; - if (get_option(&str, &alarm_rate) == 1 && alarm_rate > 0) { - alarm_hz = alarm_rate; - printk(KERN_WARNING "VMI timer alarm HZ set to %d\n", alarm_hz); - } - return 1; -} -__setup("vmi_timer_alarm_hz=", vmi_timer_alarm_rate_setup); - - -/* Initialization */ -static void vmi_get_wallclock_ts(struct timespec *ts) -{ - unsigned long long wallclock; - wallclock = vmi_timer_ops.get_wallclock(); // nsec units - ts->tv_nsec = do_div(wallclock, 1000000000); - ts->tv_sec = wallclock; -} - -unsigned long vmi_get_wallclock(void) -{ - struct timespec ts; - vmi_get_wallclock_ts(&ts); - return ts.tv_sec; -} - -int vmi_set_wallclock(unsigned long now) -{ - return -1; -} - -unsigned long long vmi_get_sched_cycles(void) -{ - return read_available_cycles(); -} - -unsigned long vmi_cpu_khz(void) -{ - unsigned long long khz; - - khz = vmi_timer_ops.get_cycle_frequency(); - (void)do_div(khz, 1000); - return khz; -} - -void __init vmi_time_init(void) -{ - unsigned long long cycles_per_sec, cycles_per_msec; - unsigned long flags; - - local_irq_save(flags); - setup_irq(0, &vmi_timer_irq); -#ifdef CONFIG_X86_LOCAL_APIC - set_intr_gate(LOCAL_TIMER_VECTOR, apic_vmi_timer_interrupt); -#endif - - real_cycles_accounted_system = read_real_cycles(); - per_cpu(process_times_cycles_accounted_cpu, 0) = read_available_cycles(); - - cycles_per_sec = vmi_timer_ops.get_cycle_frequency(); - cycles_per_jiffy = cycles_per_sec; - (void)do_div(cycles_per_jiffy, HZ); - cycles_per_alarm = cycles_per_sec; - (void)do_div(cycles_per_alarm, alarm_hz); - cycles_per_msec = cycles_per_sec; - (void)do_div(cycles_per_msec, 1000); - - printk(KERN_WARNING "VMI timer cycles/sec = %llu ; cycles/jiffy = %llu ;" - "cycles/alarm = %llu\n", cycles_per_sec, cycles_per_jiffy, - cycles_per_alarm); - - clocksource_vmi.mult = clocksource_khz2mult(cycles_per_msec, - clocksource_vmi.shift); - if (clocksource_register(&clocksource_vmi)) - printk(KERN_WARNING "Error registering VMITIME clocksource."); - - /* Disable PIT. */ - outb_p(0x3a, PIT_MODE); /* binary, mode 5, LSB/MSB, ch 0 */ - - /* schedule the alarm. do this in phase with process_times_cycles_accounted_cpu - * reduce the latency calling update_process_times. */ - vmi_timer_ops.set_alarm( - VMI_ALARM_WIRED_IRQ0 | VMI_ALARM_IS_PERIODIC | VMI_CYCLES_AVAILABLE, - per_cpu(process_times_cycles_accounted_cpu, 0) + cycles_per_alarm, - cycles_per_alarm); - - local_irq_restore(flags); -} - -#ifdef CONFIG_X86_LOCAL_APIC - -void __init vmi_timer_setup_boot_alarm(void) -{ - local_irq_disable(); - - /* Route the interrupt to the correct vector. */ - apic_write_around(APIC_LVTT, LOCAL_TIMER_VECTOR); - - /* Cancel the IRQ0 wired alarm, and setup the LVTT alarm. */ - vmi_timer_ops.cancel_alarm(VMI_CYCLES_AVAILABLE); - vmi_timer_ops.set_alarm( - VMI_ALARM_WIRED_LVTT | VMI_ALARM_IS_PERIODIC | VMI_CYCLES_AVAILABLE, - per_cpu(process_times_cycles_accounted_cpu, 0) + cycles_per_alarm, - cycles_per_alarm); - local_irq_enable(); -} - -/* Initialize the time accounting variables for an AP on an SMP system. - * Also, set the local alarm for the AP. */ -void __devinit vmi_timer_setup_secondary_alarm(void) -{ - int cpu = smp_processor_id(); - - /* Route the interrupt to the correct vector. */ - apic_write_around(APIC_LVTT, LOCAL_TIMER_VECTOR); - - per_cpu(process_times_cycles_accounted_cpu, cpu) = read_available_cycles(); - - vmi_timer_ops.set_alarm( - VMI_ALARM_WIRED_LVTT | VMI_ALARM_IS_PERIODIC | VMI_CYCLES_AVAILABLE, - per_cpu(process_times_cycles_accounted_cpu, cpu) + cycles_per_alarm, - cycles_per_alarm); -} - -#endif - -/* Update system wide (real) time accounting (e.g. jiffies, xtime). */ -static void vmi_account_real_cycles(unsigned long long cur_real_cycles) -{ - long long cycles_not_accounted; - - write_seqlock(&xtime_lock); - - cycles_not_accounted = cur_real_cycles - real_cycles_accounted_system; - while (cycles_not_accounted >= cycles_per_jiffy) { - /* systems wide jiffies. */ - do_timer(1); - - cycles_not_accounted -= cycles_per_jiffy; - real_cycles_accounted_system += cycles_per_jiffy; - } - - write_sequnlock(&xtime_lock); -} - -/* Update per-cpu process times. */ -static void vmi_account_process_times_cycles(struct pt_regs *regs, int cpu, - unsigned long long cur_process_times_cycles) -{ - long long cycles_not_accounted; - cycles_not_accounted = cur_process_times_cycles - - per_cpu(process_times_cycles_accounted_cpu, cpu); - - while (cycles_not_accounted >= cycles_per_jiffy) { - /* Account time to the current process. This includes - * calling into the scheduler to decrement the timeslice - * and possibly reschedule.*/ - update_process_times(user_mode(regs)); - /* XXX handle /proc/profile multiplier. */ - profile_tick(CPU_PROFILING); - - cycles_not_accounted -= cycles_per_jiffy; - per_cpu(process_times_cycles_accounted_cpu, cpu) += cycles_per_jiffy; - } -} - -#ifdef CONFIG_NO_IDLE_HZ -/* Update per-cpu idle times. Used when a no-hz halt is ended. */ -static void vmi_account_no_hz_idle_cycles(int cpu, - unsigned long long cur_process_times_cycles) -{ - long long cycles_not_accounted; - unsigned long no_idle_hz_jiffies = 0; - - cycles_not_accounted = cur_process_times_cycles - - per_cpu(process_times_cycles_accounted_cpu, cpu); - - while (cycles_not_accounted >= cycles_per_jiffy) { - no_idle_hz_jiffies++; - cycles_not_accounted -= cycles_per_jiffy; - per_cpu(process_times_cycles_accounted_cpu, cpu) += cycles_per_jiffy; - } - /* Account time to the idle process. */ - account_steal_time(idle_task(cpu), jiffies_to_cputime(no_idle_hz_jiffies)); -} -#endif - -/* Update per-cpu stolen time. */ -static void vmi_account_stolen_cycles(int cpu, - unsigned long long cur_real_cycles, - unsigned long long cur_avail_cycles) -{ - long long stolen_cycles_not_accounted; - unsigned long stolen_jiffies = 0; - - if (cur_real_cycles < cur_avail_cycles) - return; - - stolen_cycles_not_accounted = cur_real_cycles - cur_avail_cycles - - per_cpu(stolen_cycles_accounted_cpu, cpu); - - while (stolen_cycles_not_accounted >= cycles_per_jiffy) { - stolen_jiffies++; - stolen_cycles_not_accounted -= cycles_per_jiffy; - per_cpu(stolen_cycles_accounted_cpu, cpu) += cycles_per_jiffy; - } - /* HACK: pass NULL to force time onto cpustat->steal. */ - account_steal_time(NULL, jiffies_to_cputime(stolen_jiffies)); -} - -/* Body of either IRQ0 interrupt handler (UP no local-APIC) or - * local-APIC LVTT interrupt handler (UP & local-APIC or SMP). */ -static void vmi_local_timer_interrupt(int cpu) -{ - unsigned long long cur_real_cycles, cur_process_times_cycles; - - cur_real_cycles = read_real_cycles(); - cur_process_times_cycles = read_available_cycles(); - /* Update system wide (real) time state (xtime, jiffies). */ - vmi_account_real_cycles(cur_real_cycles); - /* Update per-cpu process times. */ - vmi_account_process_times_cycles(get_irq_regs(), cpu, cur_process_times_cycles); - /* Update time stolen from this cpu by the hypervisor. */ - vmi_account_stolen_cycles(cpu, cur_real_cycles, cur_process_times_cycles); -} - -#ifdef CONFIG_NO_IDLE_HZ - -/* Must be called only from idle loop, with interrupts disabled. */ -int vmi_stop_hz_timer(void) -{ - /* Note that cpu_set, cpu_clear are (SMP safe) atomic on x86. */ - - unsigned long seq, next; - unsigned long long real_cycles_expiry; - int cpu = smp_processor_id(); - - BUG_ON(!irqs_disabled()); - if (sysctl_hz_timer != 0) - return 0; - - cpu_set(cpu, nohz_cpu_mask); - smp_mb(); - - if (rcu_needs_cpu(cpu) || local_softirq_pending() || - (next = next_timer_interrupt(), - time_before_eq(next, jiffies + HZ/CONFIG_VMI_ALARM_HZ))) { - cpu_clear(cpu, nohz_cpu_mask); - return 0; - } - - /* Convert jiffies to the real cycle counter. */ - do { - seq = read_seqbegin(&xtime_lock); - real_cycles_expiry = real_cycles_accounted_system + - (long)(next - jiffies) * cycles_per_jiffy; - } while (read_seqretry(&xtime_lock, seq)); - - /* This cpu is going idle. Disable the periodic alarm. */ - vmi_timer_ops.cancel_alarm(VMI_CYCLES_AVAILABLE); - per_cpu(idle_start_jiffies, cpu) = jiffies; - /* Set the real time alarm to expire at the next event. */ - vmi_timer_ops.set_alarm( - VMI_ALARM_WIRING | VMI_ALARM_IS_ONESHOT | VMI_CYCLES_REAL, - real_cycles_expiry, 0); - return 1; -} - -static void vmi_reenable_hz_timer(int cpu) -{ - /* For /proc/vmi/info idle_hz stat. */ - per_cpu(vmi_idle_no_hz_jiffies, cpu) += jiffies - per_cpu(idle_start_jiffies, cpu); - per_cpu(vmi_idle_no_hz_irqs, cpu)++; - - /* Don't bother explicitly cancelling the one-shot alarm -- at - * worse we will receive a spurious timer interrupt. */ - vmi_timer_ops.set_alarm( - VMI_ALARM_WIRING | VMI_ALARM_IS_PERIODIC | VMI_CYCLES_AVAILABLE, - per_cpu(process_times_cycles_accounted_cpu, cpu) + cycles_per_alarm, - cycles_per_alarm); - /* Indicate this cpu is no longer nohz idle. */ - cpu_clear(cpu, nohz_cpu_mask); -} - -/* Called from interrupt handlers when (local) HZ timer is disabled. */ -void vmi_account_time_restart_hz_timer(void) -{ - unsigned long long cur_real_cycles, cur_process_times_cycles; - int cpu = smp_processor_id(); - - BUG_ON(!irqs_disabled()); - /* Account the time during which the HZ timer was disabled. */ - cur_real_cycles = read_real_cycles(); - cur_process_times_cycles = read_available_cycles(); - /* Update system wide (real) time state (xtime, jiffies). */ - vmi_account_real_cycles(cur_real_cycles); - /* Update per-cpu idle times. */ - vmi_account_no_hz_idle_cycles(cpu, cur_process_times_cycles); - /* Update time stolen from this cpu by the hypervisor. */ - vmi_account_stolen_cycles(cpu, cur_real_cycles, cur_process_times_cycles); - /* Reenable the hz timer. */ - vmi_reenable_hz_timer(cpu); -} - -#endif /* CONFIG_NO_IDLE_HZ */ - -/* UP (and no local-APIC) VMI-timer alarm interrupt handler. - * Handler for IRQ0. Not used when SMP or X86_LOCAL_APIC after - * APIC setup and setup_boot_vmi_alarm() is called. */ -static irqreturn_t vmi_timer_interrupt(int irq, void *dev_id) -{ - vmi_local_timer_interrupt(smp_processor_id()); - return IRQ_HANDLED; -} - -#ifdef CONFIG_X86_LOCAL_APIC - -/* SMP VMI-timer alarm interrupt handler. Handler for LVTT vector. - * Also used in UP when CONFIG_X86_LOCAL_APIC. - * The wrapper code is from arch/i386/kernel/apic.c#smp_apic_timer_interrupt. */ -void smp_apic_vmi_timer_interrupt(struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - int cpu = smp_processor_id(); - - /* - * the NMI deadlock-detector uses this. - */ - per_cpu(irq_stat,cpu).apic_timer_irqs++; - - /* - * NOTE! We'd better ACK the irq immediately, - * because timer handling can be slow. - */ - ack_APIC_irq(); - - /* - * update_process_times() expects us to have done irq_enter(). - * Besides, if we don't timer interrupts ignore the global - * interrupt lock, which is the WrongThing (tm) to do. - */ - irq_enter(); - vmi_local_timer_interrupt(cpu); - irq_exit(); - set_irq_regs(old_regs); -} - -#endif /* CONFIG_X86_LOCAL_APIC */ diff --git a/include/asm-i386/vmi_time.h b/include/asm-i386/vmi_time.h index c3a1fcf66c96..213930b995cb 100644 --- a/include/asm-i386/vmi_time.h +++ b/include/asm-i386/vmi_time.h @@ -53,22 +53,8 @@ extern unsigned long long vmi_get_sched_cycles(void); extern unsigned long vmi_cpu_khz(void); #ifdef CONFIG_X86_LOCAL_APIC -extern void __init vmi_timer_setup_boot_alarm(void); -extern void __devinit vmi_timer_setup_secondary_alarm(void); -extern void apic_vmi_timer_interrupt(void); -#endif - -#ifdef CONFIG_NO_IDLE_HZ -extern int vmi_stop_hz_timer(void); -extern void vmi_account_time_restart_hz_timer(void); -#else -static inline int vmi_stop_hz_timer(void) -{ - return 0; -} -static inline void vmi_account_time_restart_hz_timer(void) -{ -} +extern void __devinit vmi_time_bsp_init(void); +extern void __devinit vmi_time_ap_init(void); #endif /* -- cgit v1.2.3-59-g8ed1b From 441d40dca024deb305a5e3d5003e8cd9d364d10f Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:16 +0200 Subject: [PATCH] x86: PARAVIRT: Jeremy Fitzhardinge The other symbols used to delineate the alt-instructions sections have the form __foo/__foo_end. Rename parainstructions to match. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Rusty Russell Signed-off-by: Andrew Morton --- arch/i386/kernel/alternative.c | 2 +- arch/i386/kernel/vmi.c | 10 +++------- arch/i386/kernel/vmlinux.lds.S | 4 ++-- include/asm-i386/alternative.h | 4 ++-- include/asm-x86_64/alternative.h | 4 ++-- 5 files changed, 10 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index 080a59d56ea6..e5cec6685cc5 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -399,6 +399,6 @@ void __init alternative_instructions(void) alternatives_smp_switch(0); } #endif - apply_paravirt(__start_parainstructions, __stop_parainstructions); + apply_paravirt(__parainstructions, __parainstructions_end); local_irq_restore(flags); } diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index 0fae15dee765..c8726c424b35 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c @@ -73,10 +73,6 @@ static struct { void (*set_lazy_mode)(int mode); } vmi_ops; -/* XXX move this to alternative.h */ -extern struct paravirt_patch __start_parainstructions[], - __stop_parainstructions[]; - /* Cached VMI operations */ struct vmi_timer_ops vmi_timer_ops; @@ -548,9 +544,9 @@ vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip, } #endif -static void vmi_set_lazy_mode(int mode) +static void vmi_set_lazy_mode(enum paravirt_lazy_mode mode) { - static DEFINE_PER_CPU(int, lazy_mode); + static DEFINE_PER_CPU(enum paravirt_lazy_mode, lazy_mode); if (!vmi_ops.set_lazy_mode) return; @@ -912,7 +908,7 @@ static inline int __init activate_vmi(void) * to do this before IRQs get reenabled. Fortunately, it is * idempotent. */ - apply_paravirt(__start_parainstructions, __stop_parainstructions); + apply_paravirt(__parainstructions, __parainstructions_end); vmi_bringup(); diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index d125784ddf5e..568caca87715 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -166,9 +166,9 @@ SECTIONS } . = ALIGN(4); .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { - __start_parainstructions = .; + __parainstructions = .; *(.parainstructions) - __stop_parainstructions = .; + __parainstructions_end = .; } /* .exit.text is discard at runtime, not link time, to deal with references from .altinstructions and .eh_frame */ diff --git a/include/asm-i386/alternative.h b/include/asm-i386/alternative.h index 5b59d07e9d29..277467329583 100644 --- a/include/asm-i386/alternative.h +++ b/include/asm-i386/alternative.h @@ -124,8 +124,8 @@ static inline void apply_paravirt(struct paravirt_patch_site *start, struct paravirt_patch_site *end) {} -#define __start_parainstructions NULL -#define __stop_parainstructions NULL +#define __parainstructions NULL +#define __parainstructions_end NULL #endif #endif /* _I386_ALTERNATIVE_H */ diff --git a/include/asm-x86_64/alternative.h b/include/asm-x86_64/alternative.h index 67ebea3cc481..a09fe85c268e 100644 --- a/include/asm-x86_64/alternative.h +++ b/include/asm-x86_64/alternative.h @@ -142,8 +142,8 @@ void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end); static inline void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end) {} -#define __start_parainstructions NULL -#define __stop_parainstructions NULL +#define __parainstructions NULL +#define __parainstructions_end NULL #endif #endif /* _X86_64_ALTERNATIVE_H */ -- cgit v1.2.3-59-g8ed1b From 21564fd2a3deb48200b595332f9ed4c9f311f2a7 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:17 +0200 Subject: [PATCH] i386: PARAVIRT: Export paravirt_ops for non GPL modules too Otherwise non GPL modules cannot even do basic operations like disabling interrupts anymore, which would be excessive. Longer term should split the single structure up into internal and external symbols and not export the internal ones at all. Signed-off-by: Andi Kleen --- arch/i386/kernel/paravirt.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index c4850ddd6a9d..f99d3d78c53f 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -346,10 +346,4 @@ struct paravirt_ops paravirt_ops = { .startup_ipi_hook = paravirt_nop, }; -/* - * NOTE: CONFIG_PARAVIRT is experimental and the paravirt_ops - * semantics are subject to change. Hence we only do this - * internal-only export of this, until it gets sorted out and - * all lowlevel CPU ops used by modules are separately exported. - */ -EXPORT_SYMBOL_GPL(paravirt_ops); +EXPORT_SYMBOL(paravirt_ops); -- cgit v1.2.3-59-g8ed1b From 03df4f6ee997589a84d5f9492c6419183724c710 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:17 +0200 Subject: [PATCH] i386: Clean up ELF note generation Three cleanups: 1: ELF notes are never mapped, so there's no need to have any access flags in their phdr. 2: When generating them from asm, tell the assembler to use a SHT_NOTE section type. There doesn't seem to be a way to do this from C. 3: Use ANSI rather than traditional cpp behaviour to stringify the macro argument. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Eric W. Biederman --- arch/i386/kernel/vmlinux.lds.S | 2 +- include/asm-generic/vmlinux.lds.h | 2 +- include/linux/elfnote.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 568caca87715..23e8614edeee 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -30,7 +30,7 @@ jiffies = jiffies_64; PHDRS { text PT_LOAD FLAGS(5); /* R_E */ data PT_LOAD FLAGS(7); /* RWE */ - note PT_NOTE FLAGS(4); /* R__ */ + note PT_NOTE FLAGS(0); /* ___ */ } SECTIONS { diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 9fcc8d9fbb14..f3806a74c478 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -208,7 +208,7 @@ } #define NOTES \ - .notes : { *(.note.*) } :note + .notes : { *(.note.*) } :note #define INITCALLS \ *(.initcall0.init) \ diff --git a/include/linux/elfnote.h b/include/linux/elfnote.h index 67396db141e8..9a1e0674e56c 100644 --- a/include/linux/elfnote.h +++ b/include/linux/elfnote.h @@ -39,12 +39,12 @@ * ELFNOTE(XYZCo, 12, .long, 0xdeadbeef) */ #define ELFNOTE(name, type, desctype, descdata) \ -.pushsection .note.name ; \ +.pushsection .note.name, "",@note ; \ .align 4 ; \ .long 2f - 1f /* namesz */ ; \ .long 4f - 3f /* descsz */ ; \ .long type ; \ -1:.asciz "name" ; \ +1:.asciz #name ; \ 2:.align 4 ; \ 3:desctype descdata ; \ 4:.align 4 ; \ -- cgit v1.2.3-59-g8ed1b From 2b3b4835c94226681c496de9446d456dcf42ed08 Mon Sep 17 00:00:00 2001 From: Bernhard Kaindl Date: Wed, 2 May 2007 19:27:17 +0200 Subject: [PATCH] x86: Adds mtrr_save_fixed_ranges() for use in two later patches. In this current implementation which is used in other patches, mtrr_save_fixed_ranges() accepts a dummy void pointer because in the current implementation of one of these patches, this function may be called from smp_call_function_single() which requires that this function takes a void pointer argument. This function calls get_fixed_ranges(), passing mtrr_state.fixed_ranges which is the element of the static struct which stores our current backup of the fixed-range MTRR values which all CPUs shall be using. Because mtrr_save_fixed_ranges calls get_fixed_ranges after kernel initialisation time, __init needs to be removed from the declaration of get_fixed_ranges(). If CONFIG_MTRR is not set, we define mtrr_save_fixed_ranges as an empty statement because there is nothing to do. AK: Moved prototypes for x86-64 around to fix warnings Signed-off-by: Bernhard Kaindl Signed-off-by: Andi Kleen Cc: Andrew Morton Cc: Andi Kleen Cc: Dave Jones --- arch/i386/kernel/cpu/mtrr/generic.c | 7 ++++++- include/asm-i386/mtrr.h | 2 ++ include/asm-x86_64/mtrr.h | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c index 68b383788882..150cf5055a3c 100644 --- a/arch/i386/kernel/cpu/mtrr/generic.c +++ b/arch/i386/kernel/cpu/mtrr/generic.c @@ -37,7 +37,7 @@ get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr) rdmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi); } -static void __init +static void get_fixed_ranges(mtrr_type * frs) { unsigned int *p = (unsigned int *) frs; @@ -51,6 +51,11 @@ get_fixed_ranges(mtrr_type * frs) rdmsr(MTRRfix4K_C0000_MSR + i, p[6 + i * 2], p[7 + i * 2]); } +void mtrr_save_fixed_ranges(void *info) +{ + get_fixed_ranges(mtrr_state.fixed_ranges); +} + static void __init print_fixed(unsigned base, unsigned step, const mtrr_type*types) { unsigned i; diff --git a/include/asm-i386/mtrr.h b/include/asm-i386/mtrr.h index 07f063ae26ea..02a41b99bd7e 100644 --- a/include/asm-i386/mtrr.h +++ b/include/asm-i386/mtrr.h @@ -69,6 +69,7 @@ struct mtrr_gentry /* The following functions are for use by other drivers */ # ifdef CONFIG_MTRR +extern void mtrr_save_fixed_ranges(void *); extern int mtrr_add (unsigned long base, unsigned long size, unsigned int type, char increment); extern int mtrr_add_page (unsigned long base, unsigned long size, @@ -79,6 +80,7 @@ extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi); extern void mtrr_ap_init(void); extern void mtrr_bp_init(void); # else +#define mtrr_save_fixed_ranges(arg) do {} while (0) static __inline__ int mtrr_add (unsigned long base, unsigned long size, unsigned int type, char increment) { diff --git a/include/asm-x86_64/mtrr.h b/include/asm-x86_64/mtrr.h index 66809eca98cf..1b326cbb9305 100644 --- a/include/asm-x86_64/mtrr.h +++ b/include/asm-x86_64/mtrr.h @@ -138,9 +138,11 @@ struct mtrr_gentry32 #ifdef CONFIG_MTRR extern void mtrr_ap_init(void); extern void mtrr_bp_init(void); +extern void mtrr_save_fixed_ranges(void *); #else #define mtrr_ap_init() do {} while (0) #define mtrr_bp_init() do {} while (0) +#define mtrr_save_fixed_ranges(arg) do {} while (0) #endif #endif /* __KERNEL__ */ -- cgit v1.2.3-59-g8ed1b From 2b1f6278d77c1f2f669346fc2bb48012b5e9495a Mon Sep 17 00:00:00 2001 From: Bernhard Kaindl Date: Wed, 2 May 2007 19:27:17 +0200 Subject: [PATCH] x86: Save the MTRRs of the BSP before booting an AP Applied fix by Andew Morton: http://lkml.org/lkml/2007/4/8/88 - Fix `make headers_check'. AMD and Intel x86 CPU manuals state that it is the responsibility of system software to initialize and maintain MTRR consistency across all processors in Multi-Processing Environments. Quote from page 188 of the AMD64 System Programming manual (Volume 2): 7.6.5 MTRRs in Multi-Processing Environments "In multi-processing environments, the MTRRs located in all processors must characterize memory in the same way. Generally, this means that identical values are written to the MTRRs used by the processors." (short omission here) "Failure to do so may result in coherency violations or loss of atomicity. Processor implementations do not check the MTRR settings in other processors to ensure consistency. It is the responsibility of system software to initialize and maintain MTRR consistency across all processors." Current Linux MTRR code already implements the above in the case that the BIOS does not properly initialize MTRRs on the secondary processors, but the case where the fixed-range MTRRs of the boot processor are changed after Linux started to boot, before the initialsation of a secondary processor, is not handled yet. In this case, secondary processors are currently initialized by Linux with MTRRs which the boot processor had very early, when mtrr_bp_init() did run, but not with the MTRRs which the boot processor uses at the time when that secondary processors is actually booted, causing differing MTRR contents on the secondary processors. Such situation happens on Acer Ferrari 1000 and 5000 notebooks where the BIOS enables and sets AMD-specific IORR bits in the fixed-range MTRRs of the boot processor when it transitions the system into ACPI mode. The SMI handler of the BIOS does this in SMM, entered while Linux ACPI code runs acpi_enable(). Other occasions where the SMI handler of the BIOS may change bits in the MTRRs could occur as well. To initialize newly booted secodary processors with the fixed-range MTRRs which the boot processor uses at that time, this patch saves the fixed-range MTRRs of the boot processor before new secondary processors are started. When the secondary processors run their Linux initialisation code, their fixed-range MTRRs will be updated with the saved fixed-range MTRRs. If CONFIG_MTRR is not set, we define mtrr_save_state as an empty statement because there is nothing to do. Possible TODOs: *) CPU-hotplugging outside of SMP suspend/resume is not yet tested with this patch. *) If, even in this case, an AP never runs i386/do_boot_cpu or x86_64/cpu_up, then the calls to mtrr_save_state() could be replaced by calls to mtrr_save_fixed_ranges(NULL) and mtrr_save_state() would not be needed. That would need either verification of the CPU-hotplug code or at least a test on a >2 CPU machine. *) The MTRRs of other running processors are not yet checked at this time but it might be interesting to syncronize the MTTRs of all processors before booting. That would be an incremental patch, but of rather low priority since there is no machine known so far which would require this. AK: moved prototypes on x86-64 around to fix warnings Signed-off-by: Bernhard Kaindl Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Dave Jones --- arch/i386/kernel/cpu/mtrr/main.c | 11 +++++++++++ arch/i386/kernel/smpboot.c | 7 +++++++ arch/x86_64/kernel/smpboot.c | 6 ++++++ include/asm-i386/mtrr.h | 2 ++ include/asm-x86_64/mtrr.h | 2 ++ 5 files changed, 28 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index 0acfb6a5a220..02a2f39e5e0a 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c @@ -729,6 +729,17 @@ void mtrr_ap_init(void) local_irq_restore(flags); } +/** + * Save current fixed-range MTRR state of the BSP + */ +void mtrr_save_state(void) +{ + if (smp_processor_id() == 0) + mtrr_save_fixed_ranges(NULL); + else + smp_call_function_single(0, mtrr_save_fixed_ranges, NULL, 1, 1); +} + static int __init mtrr_init_finialize(void) { if (!mtrr_if) diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 7c1dbef399cd..f14d93351a82 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -58,6 +58,7 @@ #include #include #include +#include /* Set if we find a B stepping CPU */ static int __devinitdata smp_b_stepping; @@ -814,6 +815,12 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) unsigned long start_eip; unsigned short nmi_high = 0, nmi_low = 0; + /* + * Save current MTRR state in case it was changed since early boot + * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync: + */ + mtrr_save_state(); + /* * We can't use kernel_thread since we must avoid to * reschedule the child. diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index 14724be48bec..ddc392bee243 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -944,6 +944,12 @@ int __cpuinit __cpu_up(unsigned int cpu) return -ENOSYS; } + /* + * Save current MTRR state in case it was changed since early boot + * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync: + */ + mtrr_save_state(); + per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; /* Boot it! */ err = do_boot_cpu(cpu, apicid); diff --git a/include/asm-i386/mtrr.h b/include/asm-i386/mtrr.h index 02a41b99bd7e..7e9c7ccbdcfe 100644 --- a/include/asm-i386/mtrr.h +++ b/include/asm-i386/mtrr.h @@ -70,6 +70,7 @@ struct mtrr_gentry /* The following functions are for use by other drivers */ # ifdef CONFIG_MTRR extern void mtrr_save_fixed_ranges(void *); +extern void mtrr_save_state(void); extern int mtrr_add (unsigned long base, unsigned long size, unsigned int type, char increment); extern int mtrr_add_page (unsigned long base, unsigned long size, @@ -81,6 +82,7 @@ extern void mtrr_ap_init(void); extern void mtrr_bp_init(void); # else #define mtrr_save_fixed_ranges(arg) do {} while (0) +#define mtrr_save_state() do {} while (0) static __inline__ int mtrr_add (unsigned long base, unsigned long size, unsigned int type, char increment) { diff --git a/include/asm-x86_64/mtrr.h b/include/asm-x86_64/mtrr.h index 1b326cbb9305..b557c486bef8 100644 --- a/include/asm-x86_64/mtrr.h +++ b/include/asm-x86_64/mtrr.h @@ -139,10 +139,12 @@ struct mtrr_gentry32 extern void mtrr_ap_init(void); extern void mtrr_bp_init(void); extern void mtrr_save_fixed_ranges(void *); +extern void mtrr_save_state(void); #else #define mtrr_ap_init() do {} while (0) #define mtrr_bp_init() do {} while (0) #define mtrr_save_fixed_ranges(arg) do {} while (0) +#define mtrr_save_state() do {} while (0) #endif #endif /* __KERNEL__ */ -- cgit v1.2.3-59-g8ed1b From 3ebad5905609476a4ff1151a66b21d9794009961 Mon Sep 17 00:00:00 2001 From: Bernhard Kaindl Date: Wed, 2 May 2007 19:27:17 +0200 Subject: [PATCH] x86: Save and restore the fixed-range MTRRs of the BSP when suspending Note: This patch didn'nt need an update since it's initial post. Some BIOSes may modify fixed-range MTRRs in SMM, e.g. when they transition the system into ACPI mode, which is entered thru an SMI, triggered by Linux in acpi_enable(). SMIs which cause that Linux is interrupted and BIOS code is executed (which may change e.g. fixed-range MTRRs) in SMM may be raised by an embedded system controller which is often found in notebooks also at other occasions. If we would not update our copy of the fixed-range MTRRs before suspending to RAM or to disk, restore_processor_state() would set the fixed-range MTRRs of the BSP using old backup values which may be outdated and this could cause the system to fail later during resume. This patch ensures that our copy of the fixed-range MTRRs is updated when saving the boot processor state on suspend to disk and suspend to RAM. In combination with other patches this allows to fix s2ram and s2disk on the Acer Ferrari 1000 notebook and at least s2disk on the Acer Ferrari 5000 notebook. Signed-off-by: Bernhard Kaindl Signed-off-by: Andi Kleen Cc: Andrew Morton Cc: Andi Kleen Cc: Dave Jones --- arch/i386/power/cpu.c | 1 + arch/x86_64/kernel/suspend.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c index 2c15500f8713..998fd3ec0d68 100644 --- a/arch/i386/power/cpu.c +++ b/arch/i386/power/cpu.c @@ -21,6 +21,7 @@ unsigned long saved_context_eflags; void __save_processor_state(struct saved_context *ctxt) { + mtrr_save_fixed_ranges(NULL); kernel_fpu_begin(); /* diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c index 4ca523d58a5b..6a5a98f2a75c 100644 --- a/arch/x86_64/kernel/suspend.c +++ b/arch/x86_64/kernel/suspend.c @@ -12,6 +12,7 @@ #include #include #include +#include /* References to section boundaries */ extern const void __nosave_begin, __nosave_end; @@ -48,6 +49,7 @@ void __save_processor_state(struct saved_context *ctxt) rdmsrl(MSR_FS_BASE, ctxt->fs_base); rdmsrl(MSR_GS_BASE, ctxt->gs_base); rdmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base); + mtrr_save_fixed_ranges(NULL); /* * control registers -- cgit v1.2.3-59-g8ed1b From de938c51d5fec4ae03af64b06beb15d4423ec611 Mon Sep 17 00:00:00 2001 From: Bernhard Kaindl Date: Wed, 2 May 2007 19:27:17 +0200 Subject: [PATCH] i386: Enable support for fixed-range IORRs to keep RdMem & WrMem in sync If our copy of the MTRRs of the BSP has RdMem or WrMem set, and we are running on an AMD64/K8 system, the boot CPU must have had MtrrFixDramEn and MtrrFixDramModEn set (otherwise our RDMSR would have copied these bits cleared), so we set them on this CPU as well. This allows us to keep the AMD64/K8 RdMem and WrMem bits in sync across the CPUs of SMP systems in order to fullfill the duty of system software to "initialize and maintain MTRR consistency across all processors." as written in the AMD and Intel manuals. If an WRMSR instruction fails because MtrrFixDramModEn is not set, I expect that also the Intel-style MTRR bits are not updated. AK: minor cleanup, moved MSR defines around Signed-off-by: Bernhard Kaindl Signed-off-by: Andi Kleen Cc: Andrew Morton Cc: Andi Kleen Cc: Dave Jones --- arch/i386/kernel/cpu/mtrr/generic.c | 85 ++++++++++++++++++++++++++----------- include/asm-i386/msr-index.h | 5 +++ 2 files changed, 65 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c index 150cf5055a3c..000c07e86433 100644 --- a/arch/i386/kernel/cpu/mtrr/generic.c +++ b/arch/i386/kernel/cpu/mtrr/generic.c @@ -20,6 +20,18 @@ struct mtrr_state { mtrr_type def_type; }; +struct fixed_range_block { + int base_msr; /* start address of an MTRR block */ + int ranges; /* number of MTRRs in this block */ +}; + +static struct fixed_range_block fixed_range_blocks[] = { + { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */ + { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */ + { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */ + {} +}; + static unsigned long smp_changes_mask; static struct mtrr_state mtrr_state = {}; @@ -152,6 +164,44 @@ void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b) smp_processor_id(), msr, a, b); } +/** + * Enable and allow read/write of extended fixed-range MTRR bits on K8 CPUs + * see AMD publication no. 24593, chapter 3.2.1 for more information + */ +static inline void k8_enable_fixed_iorrs(void) +{ + unsigned lo, hi; + + rdmsr(MSR_K8_SYSCFG, lo, hi); + mtrr_wrmsr(MSR_K8_SYSCFG, lo + | K8_MTRRFIXRANGE_DRAM_ENABLE + | K8_MTRRFIXRANGE_DRAM_MODIFY, hi); +} + +/** + * Checks and updates an fixed-range MTRR if it differs from the value it + * should have. If K8 extenstions are wanted, update the K8 SYSCFG MSR also. + * see AMD publication no. 24593, chapter 7.8.1, page 233 for more information + * \param msr MSR address of the MTTR which should be checked and updated + * \param changed pointer which indicates whether the MTRR needed to be changed + * \param msrwords pointer to the MSR values which the MSR should have + */ +static void set_fixed_range(int msr, int * changed, unsigned int * msrwords) +{ + unsigned lo, hi; + + rdmsr(msr, lo, hi); + + if (lo != msrwords[0] || hi != msrwords[1]) { + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && + boot_cpu_data.x86 == 15 && + ((msrwords[0] | msrwords[1]) & K8_MTRR_RDMEM_WRMEM_MASK)) + k8_enable_fixed_iorrs(); + mtrr_wrmsr(msr, msrwords[0], msrwords[1]); + *changed = TRUE; + } +} + int generic_get_free_region(unsigned long base, unsigned long size, int replace_reg) /* [SUMMARY] Get a free MTRR. The starting (base) address of the region. @@ -201,36 +251,21 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, *type = base_lo & 0xff; } +/** + * Checks and updates the fixed-range MTRRs if they differ from the saved set + * \param frs pointer to fixed-range MTRR values, saved by get_fixed_ranges() + */ static int set_fixed_ranges(mtrr_type * frs) { - unsigned int *p = (unsigned int *) frs; + unsigned long long *saved = (unsigned long long *) frs; int changed = FALSE; - int i; - unsigned int lo, hi; + int block=-1, range; - rdmsr(MTRRfix64K_00000_MSR, lo, hi); - if (p[0] != lo || p[1] != hi) { - mtrr_wrmsr(MTRRfix64K_00000_MSR, p[0], p[1]); - changed = TRUE; - } - - for (i = 0; i < 2; i++) { - rdmsr(MTRRfix16K_80000_MSR + i, lo, hi); - if (p[2 + i * 2] != lo || p[3 + i * 2] != hi) { - mtrr_wrmsr(MTRRfix16K_80000_MSR + i, p[2 + i * 2], - p[3 + i * 2]); - changed = TRUE; - } - } + while (fixed_range_blocks[++block].ranges) + for (range=0; range < fixed_range_blocks[block].ranges; range++) + set_fixed_range(fixed_range_blocks[block].base_msr + range, + &changed, (unsigned int *) saved++); - for (i = 0; i < 8; i++) { - rdmsr(MTRRfix4K_C0000_MSR + i, lo, hi); - if (p[6 + i * 2] != lo || p[7 + i * 2] != hi) { - mtrr_wrmsr(MTRRfix4K_C0000_MSR + i, p[6 + i * 2], - p[7 + i * 2]); - changed = TRUE; - } - } return changed; } diff --git a/include/asm-i386/msr-index.h b/include/asm-i386/msr-index.h index f1190802283d..a02eb2991349 100644 --- a/include/asm-i386/msr-index.h +++ b/include/asm-i386/msr-index.h @@ -87,6 +87,11 @@ #define MSR_K7_CLK_CTL 0xc001001b #define MSR_K8_TOP_MEM2 0xc001001d #define MSR_K8_SYSCFG 0xc0010010 + +#define K8_MTRRFIXRANGE_DRAM_ENABLE 0x00040000 /* MtrrFixDramEn bit */ +#define K8_MTRRFIXRANGE_DRAM_MODIFY 0x00080000 /* MtrrFixDramModEn bit */ +#define K8_MTRR_RDMEM_WRMEM_MASK 0x18181818 /* Mask: RdMem|WrMem */ + #define MSR_K7_HWCR 0xc0010015 #define MSR_K8_HWCR 0xc0010015 #define MSR_K7_FID_VID_CTL 0xc0010041 -- cgit v1.2.3-59-g8ed1b From f2b218dd6199983b120a96bc6531c1b81f4090d8 Mon Sep 17 00:00:00 2001 From: Fernando Luis VazquezCao Date: Wed, 2 May 2007 19:27:17 +0200 Subject: [PATCH] i386: safe_apic_wait_icr_idle - i386 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit apic_wait_icr_idle looks like this: static __inline__ void apic_wait_icr_idle(void) { while (apic_read(APIC_ICR) & APIC_ICR_BUSY) cpu_relax(); } The busy loop in this function would not be problematic if the corresponding status bit in the ICR were always updated, but that does not seem to be the case under certain crash scenarios. Kdump uses an IPI to stop the other CPUs in the event of a crash, but when any of the other CPUs are locked-up inside the NMI handler the CPU that sends the IPI will end up looping forever in the ICR check, effectively hard-locking the whole system. Quoting from Intel's "MultiProcessor Specification" (Version 1.4), B-3: "A local APIC unit indicates successful dispatch of an IPI by resetting the Delivery Status bit in the Interrupt Command Register (ICR). The operating system polls the delivery status bit after sending an INIT or STARTUP IPI until the command has been dispatched. A period of 20 microseconds should be sufficient for IPI dispatch to complete under normal operating conditions. If the IPI is not successfully dispatched, the operating system can abort the command. Alternatively, the operating system can retry the IPI by writing the lower 32-bit double word of the ICR. This “time-out†mechanism can be implemented through an external interrupt, if interrupts are enabled on the processor, or through execution of an instruction or time-stamp counter spin loop." Intel's documentation suggests the implementation of a time-out mechanism, which, by the way, is already being open-coded in some parts of the kernel that tinker with ICR. Create a apic_wait_icr_idle replacement that implements the time-out mechanism and that can be used to solve the aforementioned problem. AK: moved both functions out of line AK: added improved loop from Keith Owens Signed-off-by: Fernando Luis Vazquez Cao Signed-off-by: Andi Kleen --- arch/i386/kernel/apic.c | 22 ++++++++++++++++++++++ include/asm-i386/apic.h | 9 +++------ 2 files changed, 25 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 93aa911646ad..aca054cc0552 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -129,6 +129,28 @@ static int modern_apic(void) return lapic_get_version() >= 0x14; } +void apic_wait_icr_idle(void) +{ + while (apic_read(APIC_ICR) & APIC_ICR_BUSY) + cpu_relax(); +} + +unsigned long safe_apic_wait_icr_idle(void) +{ + unsigned long send_status; + int timeout; + + timeout = 0; + do { + send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; + if (!send_status) + break; + udelay(100); + } while (timeout++ < 1000); + + return send_status; +} + /** * enable_NMI_through_LVT0 - enable NMI through local vector table 0 */ diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h index a19810a08ae9..1e8f6f252dd3 100644 --- a/include/asm-i386/apic.h +++ b/include/asm-i386/apic.h @@ -2,6 +2,7 @@ #define __ASM_APIC_H #include +#include #include #include #include @@ -64,12 +65,8 @@ static __inline fastcall unsigned long native_apic_read(unsigned long reg) return *((volatile unsigned long *)(APIC_BASE+reg)); } -static __inline__ void apic_wait_icr_idle(void) -{ - while ( apic_read( APIC_ICR ) & APIC_ICR_BUSY ) - cpu_relax(); -} - +void apic_wait_icr_idle(void); +unsigned long safe_apic_wait_icr_idle(void); int get_physical_broadcast(void); #ifdef CONFIG_X86_GOOD_APIC -- cgit v1.2.3-59-g8ed1b From 8339e9fba33aa3205f541478c413982c0ac5a37f Mon Sep 17 00:00:00 2001 From: Fernando Luis VazquezCao Date: Wed, 2 May 2007 19:27:17 +0200 Subject: [PATCH] x86-64: safe_apic_wait_icr_idle - x86_64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit apic_wait_icr_idle looks like this: static __inline__ void apic_wait_icr_idle(void) { while (apic_read(APIC_ICR) & APIC_ICR_BUSY) cpu_relax(); } The busy loop in this function would not be problematic if the corresponding status bit in the ICR were always updated, but that does not seem to be the case under certain crash scenarios. Kdump uses an IPI to stop the other CPUs in the event of a crash, but when any of the other CPUs are locked-up inside the NMI handler the CPU that sends the IPI will end up looping forever in the ICR check, effectively hard-locking the whole system. Quoting from Intel's "MultiProcessor Specification" (Version 1.4), B-3: "A local APIC unit indicates successful dispatch of an IPI by resetting the Delivery Status bit in the Interrupt Command Register (ICR). The operating system polls the delivery status bit after sending an INIT or STARTUP IPI until the command has been dispatched. A period of 20 microseconds should be sufficient for IPI dispatch to complete under normal operating conditions. If the IPI is not successfully dispatched, the operating system can abort the command. Alternatively, the operating system can retry the IPI by writing the lower 32-bit double word of the ICR. This “time-out†mechanism can be implemented through an external interrupt, if interrupts are enabled on the processor, or through execution of an instruction or time-stamp counter spin loop." Intel's documentation suggests the implementation of a time-out mechanism, which, by the way, is already being open-coded in some parts of the kernel that tinker with ICR. Create a apic_wait_icr_idle replacement that implements the time-out mechanism and that can be used to solve the aforementioned problem. AK: moved both functions out of line AK: Added improved loop from Keith Owens Signed-off-by: Fernando Luis Vazquez Cao Signed-off-by: Andi Kleen --- arch/x86_64/kernel/apic.c | 22 ++++++++++++++++++++++ include/asm-x86_64/apic.h | 8 +++----- 2 files changed, 25 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index 3421f21b6c70..943ec4d1bd8e 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c @@ -68,6 +68,28 @@ int using_apic_timer __read_mostly = 0; static void apic_pm_activate(void); +void apic_wait_icr_idle(void) +{ + while (apic_read(APIC_ICR) & APIC_ICR_BUSY) + cpu_relax(); +} + +unsigned int safe_apic_wait_icr_idle(void) +{ + unsigned int send_status; + int timeout; + + timeout = 0; + do { + send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; + if (!send_status) + break; + udelay(100); + } while (timeout++ < 1000); + + return send_status; +} + void enable_NMI_through_LVT0 (void * dummy) { unsigned int v; diff --git a/include/asm-x86_64/apic.h b/include/asm-x86_64/apic.h index 2f3b013595ab..45e9fca1febc 100644 --- a/include/asm-x86_64/apic.h +++ b/include/asm-x86_64/apic.h @@ -2,6 +2,7 @@ #define __ASM_APIC_H #include +#include #include #include #include @@ -47,11 +48,8 @@ static __inline unsigned int apic_read(unsigned long reg) return *((volatile unsigned int *)(APIC_BASE+reg)); } -static __inline__ void apic_wait_icr_idle(void) -{ - while (apic_read( APIC_ICR ) & APIC_ICR_BUSY) - cpu_relax(); -} +extern void apic_wait_icr_idle(void); +extern unsigned int safe_apic_wait_icr_idle(void); static inline void ack_APIC_irq(void) { -- cgit v1.2.3-59-g8ed1b From ae08e43eecd250e50ffa40c4bd62a65e005b875b Mon Sep 17 00:00:00 2001 From: Fernando Luis VazquezCao Date: Wed, 2 May 2007 19:27:17 +0200 Subject: [PATCH] i386: use safe_apic_wait_icr_idle - i386 The functionality provided by the new safe_apic_wait_icr_idle is being open-coded all over "kernel/smpboot.c". Use safe_apic_wait_icr_idle instead to consolidate code and ease maintenance. Signed-off-by: Fernando Luis Vazquez Cao Signed-off-by: Andi Kleen --- arch/i386/kernel/smpboot.c | 36 ++++++++---------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index f14d93351a82..94dce14a1b37 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -563,8 +563,8 @@ static inline void __inquire_remote_apic(int apicid) static int __devinit wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) { - unsigned long send_status = 0, accept_status = 0; - int timeout, maxlvt; + unsigned long send_status, accept_status = 0; + int maxlvt; /* Target chip */ apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(logical_apicid)); @@ -574,12 +574,7 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) apic_write_around(APIC_ICR, APIC_DM_NMI | APIC_DEST_LOGICAL); Dprintk("Waiting for send to finish...\n"); - timeout = 0; - do { - Dprintk("+"); - udelay(100); - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - } while (send_status && (timeout++ < 1000)); + send_status = safe_apic_wait_icr_idle(); /* * Give the other CPU some time to accept the IPI. @@ -609,8 +604,8 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) static int __devinit wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) { - unsigned long send_status = 0, accept_status = 0; - int maxlvt, timeout, num_starts, j; + unsigned long send_status, accept_status = 0; + int maxlvt, num_starts, j; /* * Be paranoid about clearing APIC errors. @@ -635,12 +630,7 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) | APIC_DM_INIT); Dprintk("Waiting for send to finish...\n"); - timeout = 0; - do { - Dprintk("+"); - udelay(100); - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - } while (send_status && (timeout++ < 1000)); + send_status = safe_apic_wait_icr_idle(); mdelay(10); @@ -653,12 +643,7 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT); Dprintk("Waiting for send to finish...\n"); - timeout = 0; - do { - Dprintk("+"); - udelay(100); - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - } while (send_status && (timeout++ < 1000)); + send_status = safe_apic_wait_icr_idle(); atomic_set(&init_deasserted, 1); @@ -714,12 +699,7 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) Dprintk("Startup point 1.\n"); Dprintk("Waiting for send to finish...\n"); - timeout = 0; - do { - Dprintk("+"); - udelay(100); - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - } while (send_status && (timeout++ < 1000)); + send_status = safe_apic_wait_icr_idle(); /* * Give the other CPU some time to accept the IPI. -- cgit v1.2.3-59-g8ed1b From ea8c733b98b73289421ed8f8fc15cfbce3adc3bc Mon Sep 17 00:00:00 2001 From: Fernando Luis VazquezCao Date: Wed, 2 May 2007 19:27:17 +0200 Subject: [PATCH] x86-64: use safe_apic_wait_icr_idle in smpboot.c - x86_64 The functionality provided by the new safe_apic_wait_icr_idle is being open-coded all over "kernel/smpboot.c". Use safe_apic_wait_icr_idle instead to consolidate code and ease maintenance. Signed-off-by: Fernando Luis Vazquez Cao Signed-off-by: Andi Kleen --- arch/x86_64/kernel/smpboot.c | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index ddc392bee243..f2a234b390e8 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -429,8 +429,8 @@ static void inquire_remote_apic(int apicid) */ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int start_rip) { - unsigned long send_status = 0, accept_status = 0; - int maxlvt, timeout, num_starts, j; + unsigned long send_status, accept_status = 0; + int maxlvt, num_starts, j; Dprintk("Asserting INIT.\n"); @@ -446,12 +446,7 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta | APIC_DM_INIT); Dprintk("Waiting for send to finish...\n"); - timeout = 0; - do { - Dprintk("+"); - udelay(100); - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - } while (send_status && (timeout++ < 1000)); + send_status = safe_apic_wait_icr_idle(); mdelay(10); @@ -464,12 +459,7 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT); Dprintk("Waiting for send to finish...\n"); - timeout = 0; - do { - Dprintk("+"); - udelay(100); - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - } while (send_status && (timeout++ < 1000)); + send_status = safe_apic_wait_icr_idle(); mb(); atomic_set(&init_deasserted, 1); @@ -508,12 +498,7 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta Dprintk("Startup point 1.\n"); Dprintk("Waiting for send to finish...\n"); - timeout = 0; - do { - Dprintk("+"); - udelay(100); - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - } while (send_status && (timeout++ < 1000)); + send_status = safe_apic_wait_icr_idle(); /* * Give the other CPU some time to accept the IPI. -- cgit v1.2.3-59-g8ed1b From 4312fa8157f5ebdaf36e615cf40f9d7a6137a22c Mon Sep 17 00:00:00 2001 From: Fernando Luis VazquezCao Date: Wed, 2 May 2007 19:27:17 +0200 Subject: [PATCH] i386: use safe_apic_wait_icr_idle in smpboot.c __inquire_remote_apic is used for APIC debugging, so use safe_apic_wait_icr_idle instead of apic_wait_icr_idle to avoid possible lockups when APIC delivery fails. Signed-off-by: Fernando Luis Vazquez Cao Signed-off-by: Andi Kleen --- arch/i386/kernel/smpboot.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 94dce14a1b37..a768eceeac37 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -521,7 +521,8 @@ static inline void __inquire_remote_apic(int apicid) { int i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 }; char *names[] = { "ID", "VERSION", "SPIV" }; - int timeout, status; + int timeout; + unsigned long status; printk("Inquiring remote APIC #%d...\n", apicid); @@ -531,7 +532,9 @@ static inline void __inquire_remote_apic(int apicid) /* * Wait for idle. */ - apic_wait_icr_idle(); + status = safe_apic_wait_icr_idle(); + if (status) + printk("a previous APIC delivery may have failed\n"); apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid)); apic_write_around(APIC_ICR, APIC_DM_REMRD | regs[i]); -- cgit v1.2.3-59-g8ed1b From 3144c332fa2ee4c4b9804aae5fe31098f04bffd9 Mon Sep 17 00:00:00 2001 From: Fernando Luis VazquezCao Date: Wed, 2 May 2007 19:27:17 +0200 Subject: [PATCH] x86-64: use safe_apic_wait_icr_idle in smpboot.c - x86_64 inquire_remote_apic is used for APIC debugging, so use safe_apic_wait_icr_idle instead of apic_wait_icr_idle to avoid possible lockups when APIC delivery fails. Signed-off-by: Fernando Luis Vazquez Cao Signed-off-by: Andi Kleen --- arch/x86_64/kernel/smpboot.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index f2a234b390e8..082f478fb777 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -391,7 +391,8 @@ static void inquire_remote_apic(int apicid) { unsigned i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 }; char *names[] = { "ID", "VERSION", "SPIV" }; - int timeout, status; + int timeout; + unsigned int status; printk(KERN_INFO "Inquiring remote APIC #%d...\n", apicid); @@ -401,7 +402,9 @@ static void inquire_remote_apic(int apicid) /* * Wait for idle. */ - apic_wait_icr_idle(); + status = safe_apic_wait_icr_idle(); + if (status) + printk("a previous APIC delivery may have failed\n"); apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid)); apic_write(APIC_ICR, APIC_DM_REMRD | regs[i]); -- cgit v1.2.3-59-g8ed1b From 45ae5e968ea01d8326833ca2863cec5183ce1930 Mon Sep 17 00:00:00 2001 From: "Fernando Luis [** ISO-8859-1 charset **] VázquezCao" Date: Wed, 2 May 2007 19:27:18 +0200 Subject: [PATCH] i386: __send_IPI_dest_field - i386 Implement __send_IPI_dest_field which can be used to send IPIs when the "destination shorthand" field of the ICR is set to 00 (destination field). Use it whenever possible. Signed-off-by: Fernando Luis Vazquez Cao Signed-off-by: Andi Kleen --- arch/i386/kernel/smp.c | 47 ++++++++++++++++++----------------------------- 1 file changed, 18 insertions(+), 29 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 892cd64130bc..d14ffe2109b8 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -165,16 +165,13 @@ void fastcall send_IPI_self(int vector) } /* - * This is only used on smaller machines. + * This is used to send an IPI with no shorthand notation (the destination is + * specified in bits 56 to 63 of the ICR). */ -void send_IPI_mask_bitmask(cpumask_t cpumask, int vector) +static inline void __send_IPI_dest_field(unsigned long mask, int vector) { - unsigned long mask = cpus_addr(cpumask)[0]; unsigned long cfg; - unsigned long flags; - local_irq_save(flags); - WARN_ON(mask & ~cpus_addr(cpu_online_map)[0]); /* * Wait for idle. */ @@ -195,13 +192,25 @@ void send_IPI_mask_bitmask(cpumask_t cpumask, int vector) * Send the IPI. The write to APIC_ICR fires this off. */ apic_write_around(APIC_ICR, cfg); +} +/* + * This is only used on smaller machines. + */ +void send_IPI_mask_bitmask(cpumask_t cpumask, int vector) +{ + unsigned long mask = cpus_addr(cpumask)[0]; + unsigned long flags; + + local_irq_save(flags); + WARN_ON(mask & ~cpus_addr(cpu_online_map)[0]); + __send_IPI_dest_field(mask, vector); local_irq_restore(flags); } void send_IPI_mask_sequence(cpumask_t mask, int vector) { - unsigned long cfg, flags; + unsigned long flags; unsigned int query_cpu; /* @@ -211,30 +220,10 @@ void send_IPI_mask_sequence(cpumask_t mask, int vector) */ local_irq_save(flags); - for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) { if (cpu_isset(query_cpu, mask)) { - - /* - * Wait for idle. - */ - apic_wait_icr_idle(); - - /* - * prepare target chip field - */ - cfg = __prepare_ICR2(cpu_to_logical_apicid(query_cpu)); - apic_write_around(APIC_ICR2, cfg); - - /* - * program the ICR - */ - cfg = __prepare_ICR(0, vector); - - /* - * Send the IPI. The write to APIC_ICR fires this off. - */ - apic_write_around(APIC_ICR, cfg); + __send_IPI_dest_field(cpu_to_logical_apicid(query_cpu), + vector); } } local_irq_restore(flags); -- cgit v1.2.3-59-g8ed1b From 9062d888aa448318e38792b6879a795dd10adda4 Mon Sep 17 00:00:00 2001 From: "Fernando Luis [** ISO-8859-1 charset **] VázquezCao" Date: Wed, 2 May 2007 19:27:18 +0200 Subject: [PATCH] x86-64: __send_IPI_dest_field - x86_64 Implement __send_IPI_dest_field which can be used to send IPIs when the "destination shorthand" field of the ICR is set to 00 (destination field). Use it whenever possible. Signed-off-by: Fernando Luis Vazquez Cao Signed-off-by: Andi Kleen --- arch/x86_64/kernel/genapic_flat.c | 23 +---------------- include/asm-x86_64/ipi.h | 54 +++++++++++++++++++++++---------------- 2 files changed, 33 insertions(+), 44 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c index 9e0a552f0e4a..01d3939e3a9c 100644 --- a/arch/x86_64/kernel/genapic_flat.c +++ b/arch/x86_64/kernel/genapic_flat.c @@ -61,31 +61,10 @@ static void flat_init_apic_ldr(void) static void flat_send_IPI_mask(cpumask_t cpumask, int vector) { unsigned long mask = cpus_addr(cpumask)[0]; - unsigned long cfg; unsigned long flags; local_irq_save(flags); - - /* - * Wait for idle. - */ - apic_wait_icr_idle(); - - /* - * prepare target chip field - */ - cfg = __prepare_ICR2(mask); - apic_write(APIC_ICR2, cfg); - - /* - * program the ICR - */ - cfg = __prepare_ICR(0, vector, APIC_DEST_LOGICAL); - - /* - * Send the IPI. The write to APIC_ICR fires this off. - */ - apic_write(APIC_ICR, cfg); + __send_IPI_dest_field(mask, vector, APIC_DEST_LOGICAL); local_irq_restore(flags); } diff --git a/include/asm-x86_64/ipi.h b/include/asm-x86_64/ipi.h index ffa6f1517f1a..26961e671948 100644 --- a/include/asm-x86_64/ipi.h +++ b/include/asm-x86_64/ipi.h @@ -74,10 +74,39 @@ static inline void __send_IPI_shortcut(unsigned int shortcut, int vector, unsign apic_write(APIC_ICR, cfg); } +/* + * This is used to send an IPI with no shorthand notation (the destination is + * specified in bits 56 to 63 of the ICR). + */ +static inline void __send_IPI_dest_field(unsigned int mask, int vector, unsigned int dest) +{ + unsigned long cfg; + + /* + * Wait for idle. + */ + apic_wait_icr_idle(); + + /* + * prepare target chip field + */ + cfg = __prepare_ICR2(mask); + apic_write(APIC_ICR2, cfg); + + /* + * program the ICR + */ + cfg = __prepare_ICR(0, vector, dest); + + /* + * Send the IPI. The write to APIC_ICR fires this off. + */ + apic_write(APIC_ICR, cfg); +} static inline void send_IPI_mask_sequence(cpumask_t mask, int vector) { - unsigned long cfg, flags; + unsigned long flags; unsigned long query_cpu; /* @@ -86,28 +115,9 @@ static inline void send_IPI_mask_sequence(cpumask_t mask, int vector) * - mbligh */ local_irq_save(flags); - for_each_cpu_mask(query_cpu, mask) { - /* - * Wait for idle. - */ - apic_wait_icr_idle(); - - /* - * prepare target chip field - */ - cfg = __prepare_ICR2(x86_cpu_to_apicid[query_cpu]); - apic_write(APIC_ICR2, cfg); - - /* - * program the ICR - */ - cfg = __prepare_ICR(0, vector, APIC_DEST_PHYSICAL); - - /* - * Send the IPI. The write to APIC_ICR fires this off. - */ - apic_write(APIC_ICR, cfg); + __send_IPI_dest_field(x86_cpu_to_apicid[query_cpu], + vector, APIC_DEST_PHYSICAL); } local_irq_restore(flags); } -- cgit v1.2.3-59-g8ed1b From f5efb41e793ce587836b89b7191083b9a6185ed5 Mon Sep 17 00:00:00 2001 From: "Fernando Luis [** ISO-8859-1 charset **] VázquezCao" Date: Wed, 2 May 2007 19:27:18 +0200 Subject: [PATCH] i386: Use safe_apic_wait_icr_idle in safe_apic_wait_icr_idle - i386 Use safe_apic_wait_icr_idle to check ICR idle bit if the vector is NMI_VECTOR to avoid potential hangups in the event of crash when kdump tries to stop the other CPUs. Signed-off-by: Fernando Luis Vazquez Cao Signed-off-by: Andi Kleen --- arch/i386/kernel/smp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index d14ffe2109b8..f8667109db1c 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -175,7 +175,10 @@ static inline void __send_IPI_dest_field(unsigned long mask, int vector) /* * Wait for idle. */ - apic_wait_icr_idle(); + if (unlikely(vector == NMI_VECTOR)) + safe_apic_wait_icr_idle(); + else + apic_wait_icr_idle(); /* * prepare target chip field -- cgit v1.2.3-59-g8ed1b From 25c16b992c32db4bc7e085b763abd866a505ca72 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 2 May 2007 19:27:18 +0200 Subject: [PATCH] i386: fix mtrr sections Fix section mismatch warnings in mtrr code. Fix line length on one source line. WARNING: arch/x86_64/kernel/built-in.o - Section mismatch: reference to .init.data: from .text.get_mtrr_state after 'get_mtrr_state' (at offset 0x103) WARNING: arch/x86_64/kernel/built-in.o - Section mismatch: reference to .init.text: from .text.get_mtrr_state after 'get_mtrr_state' (at offset 0x180) WARNING: arch/x86_64/kernel/built-in.o - Section mismatch: reference to .init.text: from .text.get_mtrr_state after 'get_mtrr_state' (at offset 0x199) WARNING: arch/x86_64/kernel/built-in.o - Section mismatch: reference to .init.text: from .text.get_mtrr_state after 'get_mtrr_state' (at offset 0x1c1) Signed-off-by: Randy Dunlap Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/cpu/mtrr/generic.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c index 000c07e86433..5367e32e0403 100644 --- a/arch/i386/kernel/cpu/mtrr/generic.c +++ b/arch/i386/kernel/cpu/mtrr/generic.c @@ -38,7 +38,7 @@ static struct mtrr_state mtrr_state = {}; #undef MODULE_PARAM_PREFIX #define MODULE_PARAM_PREFIX "mtrr." -static __initdata int mtrr_show; +static int mtrr_show; module_param_named(show, mtrr_show, bool, 0); /* Get the MSR pair relating to a var range */ @@ -68,12 +68,13 @@ void mtrr_save_fixed_ranges(void *info) get_fixed_ranges(mtrr_state.fixed_ranges); } -static void __init print_fixed(unsigned base, unsigned step, const mtrr_type*types) +static void __cpuinit print_fixed(unsigned base, unsigned step, const mtrr_type*types) { unsigned i; for (i = 0; i < 8; ++i, ++types, base += step) - printk(KERN_INFO "MTRR %05X-%05X %s\n", base, base + step - 1, mtrr_attrib_to_str(*types)); + printk(KERN_INFO "MTRR %05X-%05X %s\n", + base, base + step - 1, mtrr_attrib_to_str(*types)); } /* Grab all of the MTRR state for this CPU into *state */ -- cgit v1.2.3-59-g8ed1b From 0260c196c97e48e4b821031ae55912c22113ed87 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 May 2007 19:27:18 +0200 Subject: [PATCH] i386: PARAVIRT: fix startup_ipi_hook config dependency startup_ipi_hook depends on CONFIG_X86_LOCAL_APIC, so move it to the right part of the paravirt_ops initialization. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen --- arch/i386/kernel/paravirt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index f99d3d78c53f..5c10f376bce1 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -292,6 +292,7 @@ struct paravirt_ops paravirt_ops = { .apic_read = native_apic_read, .setup_boot_clock = setup_boot_APIC_clock, .setup_secondary_clock = setup_secondary_APIC_clock, + .startup_ipi_hook = paravirt_nop, #endif .set_lazy_mode = paravirt_nop, @@ -342,8 +343,6 @@ struct paravirt_ops paravirt_ops = { .dup_mmap = paravirt_nop, .exit_mmap = paravirt_nop, .activate_mm = paravirt_nop, - - .startup_ipi_hook = paravirt_nop, }; EXPORT_SYMBOL(paravirt_ops); -- cgit v1.2.3-59-g8ed1b From 141a892f57972b01891df7036f567a70459c19ac Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 2 May 2007 19:27:18 +0200 Subject: [PATCH] x86-64: move __vgetcpu_mode & __jiffies to the vsyscall_2 zone We apparently hit the 1024 limit of vsyscall_0 zone when some debugging options are set, or if __vsyscall_gtod_data is 64 bytes larger. In order to save 128 bytes from the vsyscall_0 zone, we move __vgetcpu_mode & __jiffies to vsyscall_2 zone where they really belong, since they are used only from vgetcpu() (which is in this vsyscall_2 area). After patch is applied, new layout is : ffffffffff600000 T vgettimeofday ffffffffff60004e t vsysc2 ffffffffff600140 t vread_hpet ffffffffff600150 t vread_tsc ffffffffff600180 D __vsyscall_gtod_data ffffffffff600400 T vtime ffffffffff600413 t vsysc1 ffffffffff600800 T vgetcpu ffffffffff600870 D __vgetcpu_mode ffffffffff600880 D __jiffies ffffffffff600c00 T venosys_1 Signed-off-by: Eric Dumazet Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/x86_64/kernel/vmlinux.lds.S | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 7ef0b8820cd2..32e427a95ffd 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -95,6 +95,12 @@ SECTIONS { *(.vsyscall_gtod_data) } vsyscall_gtod_data = VVIRT(.vsyscall_gtod_data); + + .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1)) + { *(.vsyscall_1) } + .vsyscall_2 ADDR(.vsyscall_0) + 2048: AT(VLOAD(.vsyscall_2)) + { *(.vsyscall_2) } + .vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) { *(.vgetcpu_mode) } vgetcpu_mode = VVIRT(.vgetcpu_mode); @@ -102,10 +108,6 @@ SECTIONS .jiffies : AT(VLOAD(.jiffies)) { *(.jiffies) } jiffies = VVIRT(.jiffies); - .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1)) - { *(.vsyscall_1) } - .vsyscall_2 ADDR(.vsyscall_0) + 2048: AT(VLOAD(.vsyscall_2)) - { *(.vsyscall_2) } .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) { *(.vsyscall_3) } -- cgit v1.2.3-59-g8ed1b From e8a72ffa3aa618fb25b5727c0e0ae939d30d66c0 Mon Sep 17 00:00:00 2001 From: "Keshavamurthy, Anil S" Date: Wed, 2 May 2007 19:27:18 +0200 Subject: [PATCH] i386: avoid checking for cpu gone when CONFIG_HOTPLUG_CPU not defined Avoid checking for cpu gone in mm hot path when CONFIG_HOTPLUG_CPU is not defined. Signed-off-by: Anil S Keshavamurthy Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Gautham R Shenoy Signed-off-by: Andrew Morton --- arch/i386/kernel/smp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index f8667109db1c..f98c3ffd6fc3 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -359,10 +359,12 @@ void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm, BUG_ON(cpu_isset(smp_processor_id(), cpumask)); BUG_ON(!mm); +#ifdef CONFIG_HOTPLUG_CPU /* If a CPU which we ran on has gone down, OK. */ cpus_and(cpumask, cpumask, cpu_online_map); - if (cpus_empty(cpumask)) + if (unlikely(cpus_empty(cpumask))) return; +#endif /* * i'm not happy about this global shared spinlock in the -- cgit v1.2.3-59-g8ed1b From 62dbc210e2532dec061ca65eeb8bc31b6c898b01 Mon Sep 17 00:00:00 2001 From: Hisashi Hifumi Date: Wed, 2 May 2007 19:27:18 +0200 Subject: [PATCH] i386: replace spin_lock_irqsave with spin_lock IRQ is already disabled through local_irq_disable(). So spin_lock_irqsave() can be replaced with spin_lock(). Signed-off-by: Hisashi Hifumi Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/reboot.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c index 14b4de2882be..50dfc65319cd 100644 --- a/arch/i386/kernel/reboot.c +++ b/arch/i386/kernel/reboot.c @@ -198,8 +198,6 @@ static unsigned char jump_to_bios [] = */ void machine_real_restart(unsigned char *code, int length) { - unsigned long flags; - local_irq_disable(); /* Write zero to CMOS register number 0x0f, which the BIOS POST @@ -212,9 +210,9 @@ void machine_real_restart(unsigned char *code, int length) safe side. (Yes, CMOS_WRITE does outb_p's. - Paul G.) */ - spin_lock_irqsave(&rtc_lock, flags); + spin_lock(&rtc_lock); CMOS_WRITE(0x00, 0x8f); - spin_unlock_irqrestore(&rtc_lock, flags); + spin_unlock(&rtc_lock); /* Remap the kernel at virtual address zero, as well as offset zero from the kernel segment. This assumes the kernel segment starts at -- cgit v1.2.3-59-g8ed1b From 1bdae4583e7abd2c1daedfc9f46ac6420a26c1b0 Mon Sep 17 00:00:00 2001 From: "Keshavamurthy, Anil S" Date: Wed, 2 May 2007 19:27:18 +0200 Subject: [PATCH] i386: clean up flush_tlb_others fn Cleanup flush_tlb_others(), no functional change. Signed-off-by: Anil S Keshavamurthy Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/smp.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index f98c3ffd6fc3..89a45a9ddcd4 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -375,17 +375,7 @@ void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm, flush_mm = mm; flush_va = va; -#if NR_CPUS <= BITS_PER_LONG - atomic_set_mask(cpumask, &flush_cpumask); -#else - { - int k; - unsigned long *flush_mask = (unsigned long *)&flush_cpumask; - unsigned long *cpu_mask = (unsigned long *)&cpumask; - for (k = 0; k < BITS_TO_LONGS(NR_CPUS); ++k) - atomic_set_mask(cpu_mask[k], &flush_mask[k]); - } -#endif + cpus_or(flush_cpumask, cpumask, flush_cpumask); /* * We have to send the IPI only to * CPUs affected. -- cgit v1.2.3-59-g8ed1b From 2f3c30e6a886ddaf65cb74df82c03245050ff0aa Mon Sep 17 00:00:00 2001 From: Joachim Deguara Date: Wed, 2 May 2007 19:27:18 +0200 Subject: [PATCH] i386: check capability Currently the i386 architecture checks the family for mce capability and this removes that and uses the CPUID information. Tested on a K8 revE and a family10h processor. This eliminates checking of a set AMD procesor family if mce is allowed and relies on the information being in CPUID. Signed-off-by: Joachim Deguara Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/cpu/mcheck/k7.c | 3 +++ arch/i386/kernel/cpu/mcheck/mce.c | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/mcheck/k7.c b/arch/i386/kernel/cpu/mcheck/k7.c index 7a2472557bbb..f9fa4142551e 100644 --- a/arch/i386/kernel/cpu/mcheck/k7.c +++ b/arch/i386/kernel/cpu/mcheck/k7.c @@ -75,6 +75,9 @@ void amd_mcheck_init(struct cpuinfo_x86 *c) machine_check_vector = k7_machine_check; wmb(); + if (!cpu_has(c, X86_FEATURE_MCE)) + return; + printk (KERN_INFO "Intel machine check architecture supported.\n"); rdmsr (MSR_IA32_MCG_CAP, l, h); if (l & (1<<8)) /* Control register present ? */ diff --git a/arch/i386/kernel/cpu/mcheck/mce.c b/arch/i386/kernel/cpu/mcheck/mce.c index 4f10c62d180c..56cd485b127c 100644 --- a/arch/i386/kernel/cpu/mcheck/mce.c +++ b/arch/i386/kernel/cpu/mcheck/mce.c @@ -38,8 +38,7 @@ void mcheck_init(struct cpuinfo_x86 *c) switch (c->x86_vendor) { case X86_VENDOR_AMD: - if (c->x86==6 || c->x86==15) - amd_mcheck_init(c); + amd_mcheck_init(c); break; case X86_VENDOR_INTEL: -- cgit v1.2.3-59-g8ed1b From 57a4f91ae5571edd7c0428285d8df16bb8bf5f40 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:18 +0200 Subject: [PATCH] x86-64: Auto compute __NR_syscall_max at compile time No need to maintain it anymore Signed-off-by: Andi Kleen --- arch/x86_64/kernel/asm-offsets.c | 10 ++++++++++ arch/x86_64/kernel/syscall.c | 1 + include/asm-x86_64/unistd.h | 2 -- 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/asm-offsets.c b/arch/x86_64/kernel/asm-offsets.c index 96687e2beb2c..778953bc636c 100644 --- a/arch/x86_64/kernel/asm-offsets.c +++ b/arch/x86_64/kernel/asm-offsets.c @@ -21,6 +21,14 @@ #define BLANK() asm volatile("\n->" : : ) +#define __NO_STUBS 1 +#undef __SYSCALL +#undef _ASM_X86_64_UNISTD_H_ +#define __SYSCALL(nr, sym) [nr] = 1, +static char syscalls[] = { +#include +}; + int main(void) { #define ENTRY(entry) DEFINE(tsk_ ## entry, offsetof(struct task_struct, entry)) @@ -71,5 +79,7 @@ int main(void) DEFINE(TSS_ist, offsetof(struct tss_struct, ist)); BLANK(); DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); + BLANK(); + DEFINE(__NR_syscall_max, sizeof(syscalls) - 1); return 0; } diff --git a/arch/x86_64/kernel/syscall.c b/arch/x86_64/kernel/syscall.c index 213fd6ab789d..63d592c276cc 100644 --- a/arch/x86_64/kernel/syscall.c +++ b/arch/x86_64/kernel/syscall.c @@ -3,6 +3,7 @@ #include #include #include +#include #define __NO_STUBS diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h index 576b29732d3c..26e23e01c54a 100644 --- a/include/asm-x86_64/unistd.h +++ b/include/asm-x86_64/unistd.h @@ -620,8 +620,6 @@ __SYSCALL(__NR_vmsplice, sys_vmsplice) #define __NR_move_pages 279 __SYSCALL(__NR_move_pages, sys_move_pages) -#define __NR_syscall_max __NR_move_pages - #ifndef __NO_STUBS #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT -- cgit v1.2.3-59-g8ed1b From df3624aa293dfa2d46089747d919711089a702eb Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 2 May 2007 19:27:18 +0200 Subject: [PATCH] i386: remove xtime_lock'ing around cpufreq notifier The locking of the xtime_lock around the cpu notifier is unessesary now. At one time the tsc was used after a frequency change for timekeeping, but the re-write of timekeeping no longer uses the TSC unless the frequency is constant. The variables that are changed in this section of code had also once been used for timekeeping, but not any longer .. Signed-off-by: Daniel Walker Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Ingo Molnar Cc: Thomas Gleixner Cc: john stultz Signed-off-by: Andrew Morton --- arch/i386/kernel/tsc.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c index 755209dc93e1..f64b81f3033b 100644 --- a/arch/i386/kernel/tsc.c +++ b/arch/i386/kernel/tsc.c @@ -200,13 +200,10 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) { struct cpufreq_freqs *freq = data; - if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE) - write_seqlock_irq(&xtime_lock); - if (!ref_freq) { if (!freq->old){ ref_freq = freq->new; - goto end; + return 0; } ref_freq = freq->old; loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy; @@ -237,9 +234,6 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) } } } -end: - if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE) - write_sequnlock_irq(&xtime_lock); return 0; } -- cgit v1.2.3-59-g8ed1b From f26d6a2bbcf381230df771123578380584004631 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 2 May 2007 19:27:19 +0200 Subject: [PATCH] i386: convert to the kthread API This patch just trivial converts from calling kernel_thread and daemonize to just calling kthread_run. Signed-off-by: Eric W. Biederman Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/io_apic.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 8191583032d0..f23a17b3b8cf 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -661,8 +662,6 @@ static int balanced_irq(void *unused) unsigned long prev_balance_time = jiffies; long time_remaining = balanced_irq_interval; - daemonize("kirqd"); - /* push everything to CPU 0 to give us a starting point. */ for (i = 0 ; i < NR_IRQS ; i++) { irq_desc[i].pending_mask = cpumask_of_cpu(0); @@ -722,10 +721,9 @@ static int __init balanced_irq_init(void) } printk(KERN_INFO "Starting balanced_irq\n"); - if (kernel_thread(balanced_irq, NULL, CLONE_KERNEL) >= 0) + if (!IS_ERR(kthread_run(balanced_irq, NULL, "kirqd"))) return 0; - else - printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); + printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); failed: for_each_possible_cpu(i) { kfree(irq_cpu_data[i].irq_delta); -- cgit v1.2.3-59-g8ed1b From 425001fea782dd072cfec5694b93778eb59a1fd3 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 2 May 2007 19:27:19 +0200 Subject: [PATCH] x86-64: unexport cpu_llc_id WARNING: arch/x86_64/kernel/built-in.o - Section mismatch: reference to .init.data:cpu_llc_id from __ksymtab between '__ksymtab_cpu_llc_id' (at offset 0x4a0) and '__ksymtab_smp_num_siblings' It is strange to export a __cpuinitdata symbols to modules, and no module appears to use it anyway. Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/x86_64/kernel/smpboot.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index 082f478fb777..4d9dacfae575 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -67,7 +67,6 @@ EXPORT_SYMBOL(smp_num_siblings); /* Last level cache ID of each logical CPU */ u8 cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID}; -EXPORT_SYMBOL(cpu_llc_id); /* Bitmask of currently online CPUs */ cpumask_t cpu_online_map __read_mostly; -- cgit v1.2.3-59-g8ed1b From 889f21ce272e38db19c8114a7e0a5793d4590077 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:19 +0200 Subject: [PATCH] i386: fix wrong comment for syscall stack layout `ret_from_sys_call' label no longer exist and `syscall_exit' label was introduced instead. Signed-off-by: Satoru Takeuchi Signed-off-by: Andi Kleen --- arch/i386/kernel/entry.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 90ffcdb69838..b1f16ee65e4d 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -15,7 +15,7 @@ * I changed all the .align's to 4 (16 byte alignment), as that's faster * on a 486. * - * Stack layout in 'ret_from_system_call': + * Stack layout in 'syscall_exit': * ptrace needs to have all regs on the stack. * if the order here is changed, it needs to be * updated in fork.c:copy_process, signal.c:do_signal, -- cgit v1.2.3-59-g8ed1b From 8a336b0a4b6dfacc8cc5fd617ba1e1904077de2d Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Wed, 2 May 2007 19:27:19 +0200 Subject: [PATCH] x86-64: Dynamically adjust machine check interval Background: We've found that MCEs (specifically DRAM SBEs) tend to come in bunches, especially when we are trying really hard to stress the system out. The current MCE poller uses a static interval which does not care whether it has or has not found MCEs recently. Description: This patch makes the MCE poller adjust the polling interval dynamically. If we find an MCE, poll 2x faster (down to 10 ms). When we stop finding MCEs, poll 2x slower (up to check_interval seconds). The check_interval tunable becomes the max polling interval. The "Machine check events logged" printk() is rate limited to the check_interval, which should be identical behavior to the old functionality. Result: If you start to take a lot of correctable errors (not exceptions), you log them faster and more accurately (less chance of overflowing the MCA registers). If you don't take a lot of errors, you will see no change. Alternatives: I considered simply reducing the polling interval to 10 ms immediately and keeping it there as long as we continue to find errors. This felt a bit heavy handed, but does perform significantly better for the default check_interval of 5 minutes (we're using a few seconds when testing for DRAM errors). I could be convinced to go with this, if anyone felt it was not too aggressive. Testing: I used an error-injecting DIMM to create lots of correctable DRAM errors and verified that the polling interval accelerates. The printk() only happens once per check_interval seconds. Patch: This patch is against 2.6.21-rc7. Signed-Off-By: Tim Hockin Signed-off-by: Andi Kleen --- Documentation/x86_64/machinecheck | 7 ++++++- arch/x86_64/kernel/mce.c | 32 ++++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/Documentation/x86_64/machinecheck b/Documentation/x86_64/machinecheck index 068a6d9904b9..feaeaf6f6e4d 100644 --- a/Documentation/x86_64/machinecheck +++ b/Documentation/x86_64/machinecheck @@ -36,7 +36,12 @@ between all CPUs. check_interval How often to poll for corrected machine check errors, in seconds - (Note output is hexademical). Default 5 minutes. + (Note output is hexademical). Default 5 minutes. When the poller + finds MCEs it triggers an exponential speedup (poll more often) on + the polling interval. When the poller stops finding MCEs, it + triggers an exponential backoff (poll less often) on the polling + interval. The check_interval variable is both the initial and + maximum polling interval. tolerant Tolerance level. When a machine check exception occurs for a non diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index 8011a8e1c7d4..fa2672682477 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c @@ -323,10 +323,13 @@ void mce_log_therm_throt_event(unsigned int cpu, __u64 status) #endif /* CONFIG_X86_MCE_INTEL */ /* - * Periodic polling timer for "silent" machine check errors. + * Periodic polling timer for "silent" machine check errors. If the + * poller finds an MCE, poll 2x faster. When the poller finds no more + * errors, poll 2x slower (up to check_interval seconds). */ static int check_interval = 5 * 60; /* 5 minutes */ +static int next_interval; /* in jiffies */ static void mcheck_timer(struct work_struct *work); static DECLARE_DELAYED_WORK(mcheck_work, mcheck_timer); @@ -339,7 +342,6 @@ static void mcheck_check_cpu(void *info) static void mcheck_timer(struct work_struct *work) { on_each_cpu(mcheck_check_cpu, NULL, 1, 1); - schedule_delayed_work(&mcheck_work, check_interval * HZ); /* * It's ok to read stale data here for notify_user and @@ -349,17 +351,30 @@ static void mcheck_timer(struct work_struct *work) * writes. */ if (notify_user && console_logged) { + static unsigned long last_print; + unsigned long now = jiffies; + + /* if we logged an MCE, reduce the polling interval */ + next_interval = max(next_interval/2, HZ/100); notify_user = 0; clear_bit(0, &console_logged); - printk(KERN_INFO "Machine check events logged\n"); + if (time_after_eq(now, last_print + (check_interval*HZ))) { + last_print = now; + printk(KERN_INFO "Machine check events logged\n"); + } + } else { + next_interval = min(next_interval*2, check_interval*HZ); } + + schedule_delayed_work(&mcheck_work, next_interval); } static __init int periodic_mcheck_init(void) { - if (check_interval) - schedule_delayed_work(&mcheck_work, check_interval*HZ); + next_interval = check_interval * HZ; + if (next_interval) + schedule_delayed_work(&mcheck_work, next_interval); return 0; } __initcall(periodic_mcheck_init); @@ -597,12 +612,13 @@ static int mce_resume(struct sys_device *dev) /* Reinit MCEs after user configuration changes */ static void mce_restart(void) { - if (check_interval) + if (next_interval) cancel_delayed_work(&mcheck_work); /* Timer race is harmless here */ on_each_cpu(mce_init, NULL, 1, 1); - if (check_interval) - schedule_delayed_work(&mcheck_work, check_interval*HZ); + next_interval = check_interval * HZ; + if (next_interval) + schedule_delayed_work(&mcheck_work, next_interval); } static struct sysdev_class mce_sysclass = { -- cgit v1.2.3-59-g8ed1b From e3f1caeef9a70b0699518092d653c15274b025ab Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Wed, 2 May 2007 19:27:20 +0200 Subject: [PATCH] x86-64: set node_possible_map at runtime - try 2 Set the node_possible_map at runtime on x86_64. On a non NUMA system, num_possible_nodes() will now say '1'. Signed-off-by: Suresh Siddha Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Eric Dumazet Cc: David Rientjes Cc: Christoph Lameter --- arch/x86_64/mm/k8topology.c | 7 ++----- arch/x86_64/mm/numa.c | 10 ++++++++-- arch/x86_64/mm/srat.c | 8 +++++--- 3 files changed, 15 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/mm/k8topology.c b/arch/x86_64/mm/k8topology.c index b5b8dba28b4e..60e860e5ef4c 100644 --- a/arch/x86_64/mm/k8topology.c +++ b/arch/x86_64/mm/k8topology.c @@ -49,11 +49,8 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end) int found = 0; u32 reg; unsigned numnodes; - nodemask_t nodes_parsed; unsigned dualcore = 0; - nodes_clear(nodes_parsed); - if (!early_pci_allowed()) return -1; @@ -102,7 +99,7 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end) nodeid, (base>>8)&3, (limit>>8) & 3); return -1; } - if (node_isset(nodeid, nodes_parsed)) { + if (node_isset(nodeid, node_possible_map)) { printk(KERN_INFO "Node %d already present. Skipping\n", nodeid); continue; @@ -155,7 +152,7 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end) prevbase = base; - node_set(nodeid, nodes_parsed); + node_set(nodeid, node_possible_map); } if (!found) diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index 5ee07bc41eb5..51548947ad3b 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c @@ -295,7 +295,7 @@ static int __init setup_node_range(int nid, struct bootnode *nodes, u64 *addr, ret = -1; } nodes[nid].end = *addr; - node_set_online(nid); + node_set(nid, node_possible_map); printk(KERN_INFO "Faking node %d at %016Lx-%016Lx (%LuMB)\n", nid, nodes[nid].start, nodes[nid].end, (nodes[nid].end - nodes[nid].start) >> 20); @@ -479,7 +479,7 @@ out: * SRAT. */ remove_all_active_ranges(); - for_each_online_node(i) { + for_each_node_mask(i, node_possible_map) { e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT, nodes[i].end >> PAGE_SHIFT); setup_node_bootmem(i, nodes[i].start, nodes[i].end); @@ -494,20 +494,25 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn) { int i; + nodes_clear(node_possible_map); + #ifdef CONFIG_NUMA_EMU if (cmdline && !numa_emulation(start_pfn, end_pfn)) return; + nodes_clear(node_possible_map); #endif #ifdef CONFIG_ACPI_NUMA if (!numa_off && !acpi_scan_nodes(start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT)) return; + nodes_clear(node_possible_map); #endif #ifdef CONFIG_K8_NUMA if (!numa_off && !k8_scan_nodes(start_pfn< Date: Wed, 2 May 2007 19:27:20 +0200 Subject: [PATCH] i386: Clean up NMI watchdog code - Introduce a wd_ops structure - Convert the various nmi watchdogs over to it - This allows to split the perfctr reservation from the watchdog setup cleanly. - Do perfctr reservation globally as it should have always been - Remove dead code referenced only by unused EXPORT_SYMBOLs Signed-off-by: Andi Kleen --- arch/i386/kernel/cpu/Makefile | 2 + arch/i386/kernel/cpu/perfctr-watchdog.c | 658 +++++++++++++++++++++++++ arch/i386/kernel/nmi.c | 829 ++------------------------------ include/asm-i386/nmi.h | 8 + 4 files changed, 721 insertions(+), 776 deletions(-) create mode 100644 arch/i386/kernel/cpu/perfctr-watchdog.c (limited to 'arch') diff --git a/arch/i386/kernel/cpu/Makefile b/arch/i386/kernel/cpu/Makefile index 5fb1a7560438..74f27a463db0 100644 --- a/arch/i386/kernel/cpu/Makefile +++ b/arch/i386/kernel/cpu/Makefile @@ -17,3 +17,5 @@ obj-$(CONFIG_X86_MCE) += mcheck/ obj-$(CONFIG_MTRR) += mtrr/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ + +obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o diff --git a/arch/i386/kernel/cpu/perfctr-watchdog.c b/arch/i386/kernel/cpu/perfctr-watchdog.c new file mode 100644 index 000000000000..2b04c8f1db62 --- /dev/null +++ b/arch/i386/kernel/cpu/perfctr-watchdog.c @@ -0,0 +1,658 @@ +/* local apic based NMI watchdog for various CPUs. + This file also handles reservation of performance counters for coordination + with other users (like oprofile). + + Note that these events normally don't tick when the CPU idles. This means + the frequency varies with CPU load. + + Original code for K7/P6 written by Keith Owens */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct nmi_watchdog_ctlblk { + unsigned int cccr_msr; + unsigned int perfctr_msr; /* the MSR to reset in NMI handler */ + unsigned int evntsel_msr; /* the MSR to select the events to handle */ +}; + +/* Interface defining a CPU specific perfctr watchdog */ +struct wd_ops { + int (*reserve)(void); + void (*unreserve)(void); + int (*setup)(unsigned nmi_hz); + void (*rearm)(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz); + void (*stop)(void *); + unsigned perfctr; + unsigned evntsel; + u64 checkbit; +}; + +static struct wd_ops *wd_ops; + +/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's + * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) + */ +#define NMI_MAX_COUNTER_BITS 66 + +/* perfctr_nmi_owner tracks the ownership of the perfctr registers: + * evtsel_nmi_owner tracks the ownership of the event selection + * - different performance counters/ event selection may be reserved for + * different subsystems this reservation system just tries to coordinate + * things a little + */ +static DECLARE_BITMAP(perfctr_nmi_owner, NMI_MAX_COUNTER_BITS); +static DECLARE_BITMAP(evntsel_nmi_owner, NMI_MAX_COUNTER_BITS); + +static DEFINE_PER_CPU(struct nmi_watchdog_ctlblk, nmi_watchdog_ctlblk); + +/* converts an msr to an appropriate reservation bit */ +static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr) +{ + return wd_ops ? msr - wd_ops->perfctr : 0; +} + +/* converts an msr to an appropriate reservation bit */ +/* returns the bit offset of the event selection register */ +static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr) +{ + return wd_ops ? msr - wd_ops->evntsel : 0; +} + +/* checks for a bit availability (hack for oprofile) */ +int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) +{ + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + + return (!test_bit(counter, perfctr_nmi_owner)); +} + +/* checks the an msr for availability */ +int avail_to_resrv_perfctr_nmi(unsigned int msr) +{ + unsigned int counter; + + counter = nmi_perfctr_msr_to_bit(msr); + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + + return (!test_bit(counter, perfctr_nmi_owner)); +} + +int reserve_perfctr_nmi(unsigned int msr) +{ + unsigned int counter; + + counter = nmi_perfctr_msr_to_bit(msr); + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + + if (!test_and_set_bit(counter, perfctr_nmi_owner)) + return 1; + return 0; +} + +void release_perfctr_nmi(unsigned int msr) +{ + unsigned int counter; + + counter = nmi_perfctr_msr_to_bit(msr); + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + + clear_bit(counter, perfctr_nmi_owner); +} + +int reserve_evntsel_nmi(unsigned int msr) +{ + unsigned int counter; + + counter = nmi_evntsel_msr_to_bit(msr); + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + + if (!test_and_set_bit(counter, evntsel_nmi_owner)) + return 1; + return 0; +} + +void release_evntsel_nmi(unsigned int msr) +{ + unsigned int counter; + + counter = nmi_evntsel_msr_to_bit(msr); + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + + clear_bit(counter, evntsel_nmi_owner); +} + +EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi); +EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit); +EXPORT_SYMBOL(reserve_perfctr_nmi); +EXPORT_SYMBOL(release_perfctr_nmi); +EXPORT_SYMBOL(reserve_evntsel_nmi); +EXPORT_SYMBOL(release_evntsel_nmi); + +void disable_lapic_nmi_watchdog(void) +{ + BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); + + if (atomic_read(&nmi_active) <= 0) + return; + + on_each_cpu(wd_ops->stop, NULL, 0, 1); + wd_ops->unreserve(); + + BUG_ON(atomic_read(&nmi_active) != 0); +} + +void enable_lapic_nmi_watchdog(void) +{ + BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); + + /* are we already enabled */ + if (atomic_read(&nmi_active) != 0) + return; + + /* are we lapic aware */ + if (!wd_ops) + return; + if (!wd_ops->reserve()) { + printk(KERN_ERR "NMI watchdog: cannot reserve perfctrs\n"); + return; + } + + on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); + touch_nmi_watchdog(); +} + +/* + * Activate the NMI watchdog via the local APIC. + */ + +static unsigned int adjust_for_32bit_ctr(unsigned int hz) +{ + u64 counter_val; + unsigned int retval = hz; + + /* + * On Intel CPUs with P6/ARCH_PERFMON only 32 bits in the counter + * are writable, with higher bits sign extending from bit 31. + * So, we can only program the counter with 31 bit values and + * 32nd bit should be 1, for 33.. to be 1. + * Find the appropriate nmi_hz + */ + counter_val = (u64)cpu_khz * 1000; + do_div(counter_val, retval); + if (counter_val > 0x7fffffffULL) { + u64 count = (u64)cpu_khz * 1000; + do_div(count, 0x7fffffffUL); + retval = count + 1; + } + return retval; +} + +static void +write_watchdog_counter(unsigned int perfctr_msr, const char *descr, unsigned nmi_hz) +{ + u64 count = (u64)cpu_khz * 1000; + + do_div(count, nmi_hz); + if(descr) + Dprintk("setting %s to -0x%08Lx\n", descr, count); + wrmsrl(perfctr_msr, 0 - count); +} + +static void write_watchdog_counter32(unsigned int perfctr_msr, + const char *descr, unsigned nmi_hz) +{ + u64 count = (u64)cpu_khz * 1000; + + do_div(count, nmi_hz); + if(descr) + Dprintk("setting %s to -0x%08Lx\n", descr, count); + wrmsr(perfctr_msr, (u32)(-count), 0); +} + +/* AMD K7/K8/Family10h/Family11h support. AMD keeps this interface + nicely stable so there is not much variety */ + +#define K7_EVNTSEL_ENABLE (1 << 22) +#define K7_EVNTSEL_INT (1 << 20) +#define K7_EVNTSEL_OS (1 << 17) +#define K7_EVNTSEL_USR (1 << 16) +#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 +#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING + +static int setup_k7_watchdog(unsigned nmi_hz) +{ + unsigned int perfctr_msr, evntsel_msr; + unsigned int evntsel; + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + perfctr_msr = MSR_K7_PERFCTR0; + evntsel_msr = MSR_K7_EVNTSEL0; + + wrmsrl(perfctr_msr, 0UL); + + evntsel = K7_EVNTSEL_INT + | K7_EVNTSEL_OS + | K7_EVNTSEL_USR + | K7_NMI_EVENT; + + /* setup the timer */ + wrmsr(evntsel_msr, evntsel, 0); + write_watchdog_counter(perfctr_msr, "K7_PERFCTR0",nmi_hz); + apic_write(APIC_LVTPC, APIC_DM_NMI); + evntsel |= K7_EVNTSEL_ENABLE; + wrmsr(evntsel_msr, evntsel, 0); + + wd->perfctr_msr = perfctr_msr; + wd->evntsel_msr = evntsel_msr; + wd->cccr_msr = 0; //unused + return 1; +} + +static void single_msr_stop_watchdog(void *arg) +{ + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + wrmsr(wd->evntsel_msr, 0, 0); +} + +static int single_msr_reserve(void) +{ + if (!reserve_perfctr_nmi(wd_ops->perfctr)) + return 0; + + if (!reserve_evntsel_nmi(wd_ops->evntsel)) { + release_perfctr_nmi(wd_ops->perfctr); + return 0; + } + return 1; +} + +static void single_msr_unreserve(void) +{ + release_evntsel_nmi(wd_ops->perfctr); + release_perfctr_nmi(wd_ops->evntsel); +} + +static void single_msr_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz) +{ + /* start the cycle over again */ + write_watchdog_counter(wd->perfctr_msr, NULL, nmi_hz); +} + +static struct wd_ops k7_wd_ops = { + .reserve = single_msr_reserve, + .unreserve = single_msr_unreserve, + .setup = setup_k7_watchdog, + .rearm = single_msr_rearm, + .stop = single_msr_stop_watchdog, + .perfctr = MSR_K7_PERFCTR0, + .evntsel = MSR_K7_EVNTSEL0, + .checkbit = 1ULL<<63, +}; + +/* Intel Model 6 (PPro+,P2,P3,P-M,Core1) */ + +#define P6_EVNTSEL0_ENABLE (1 << 22) +#define P6_EVNTSEL_INT (1 << 20) +#define P6_EVNTSEL_OS (1 << 17) +#define P6_EVNTSEL_USR (1 << 16) +#define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79 +#define P6_NMI_EVENT P6_EVENT_CPU_CLOCKS_NOT_HALTED + +static int setup_p6_watchdog(unsigned nmi_hz) +{ + unsigned int perfctr_msr, evntsel_msr; + unsigned int evntsel; + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + perfctr_msr = MSR_P6_PERFCTR0; + evntsel_msr = MSR_P6_EVNTSEL0; + + wrmsrl(perfctr_msr, 0UL); + + evntsel = P6_EVNTSEL_INT + | P6_EVNTSEL_OS + | P6_EVNTSEL_USR + | P6_NMI_EVENT; + + /* setup the timer */ + wrmsr(evntsel_msr, evntsel, 0); + nmi_hz = adjust_for_32bit_ctr(nmi_hz); + write_watchdog_counter32(perfctr_msr, "P6_PERFCTR0",nmi_hz); + apic_write(APIC_LVTPC, APIC_DM_NMI); + evntsel |= P6_EVNTSEL0_ENABLE; + wrmsr(evntsel_msr, evntsel, 0); + + wd->perfctr_msr = perfctr_msr; + wd->evntsel_msr = evntsel_msr; + wd->cccr_msr = 0; //unused + return 1; +} + +static void p6_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz) +{ + /* P6 based Pentium M need to re-unmask + * the apic vector but it doesn't hurt + * other P6 variant. + * ArchPerfom/Core Duo also needs this */ + apic_write(APIC_LVTPC, APIC_DM_NMI); + /* P6/ARCH_PERFMON has 32 bit counter write */ + write_watchdog_counter32(wd->perfctr_msr, NULL,nmi_hz); +} + +static struct wd_ops p6_wd_ops = { + .reserve = single_msr_reserve, + .unreserve = single_msr_unreserve, + .setup = setup_p6_watchdog, + .rearm = p6_rearm, + .stop = single_msr_stop_watchdog, + .perfctr = MSR_P6_PERFCTR0, + .evntsel = MSR_P6_EVNTSEL0, + .checkbit = 1ULL<<39, +}; + +/* Intel P4 performance counters. By far the most complicated of all. */ + +#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) +#define P4_ESCR_EVENT_SELECT(N) ((N)<<25) +#define P4_ESCR_OS (1<<3) +#define P4_ESCR_USR (1<<2) +#define P4_CCCR_OVF_PMI0 (1<<26) +#define P4_CCCR_OVF_PMI1 (1<<27) +#define P4_CCCR_THRESHOLD(N) ((N)<<20) +#define P4_CCCR_COMPLEMENT (1<<19) +#define P4_CCCR_COMPARE (1<<18) +#define P4_CCCR_REQUIRED (3<<16) +#define P4_CCCR_ESCR_SELECT(N) ((N)<<13) +#define P4_CCCR_ENABLE (1<<12) +#define P4_CCCR_OVF (1<<31) + +/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter + CRU_ESCR0 (with any non-null event selector) through a complemented + max threshold. [IA32-Vol3, Section 14.9.9] */ + +static int setup_p4_watchdog(unsigned nmi_hz) +{ + unsigned int perfctr_msr, evntsel_msr, cccr_msr; + unsigned int evntsel, cccr_val; + unsigned int misc_enable, dummy; + unsigned int ht_num; + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + rdmsr(MSR_IA32_MISC_ENABLE, misc_enable, dummy); + if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL)) + return 0; + +#ifdef CONFIG_SMP + /* detect which hyperthread we are on */ + if (smp_num_siblings == 2) { + unsigned int ebx, apicid; + + ebx = cpuid_ebx(1); + apicid = (ebx >> 24) & 0xff; + ht_num = apicid & 1; + } else +#endif + ht_num = 0; + + /* performance counters are shared resources + * assign each hyperthread its own set + * (re-use the ESCR0 register, seems safe + * and keeps the cccr_val the same) + */ + if (!ht_num) { + /* logical cpu 0 */ + perfctr_msr = MSR_P4_IQ_PERFCTR0; + evntsel_msr = MSR_P4_CRU_ESCR0; + cccr_msr = MSR_P4_IQ_CCCR0; + cccr_val = P4_CCCR_OVF_PMI0 | P4_CCCR_ESCR_SELECT(4); + } else { + /* logical cpu 1 */ + perfctr_msr = MSR_P4_IQ_PERFCTR1; + evntsel_msr = MSR_P4_CRU_ESCR0; + cccr_msr = MSR_P4_IQ_CCCR1; + cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4); + } + + evntsel = P4_ESCR_EVENT_SELECT(0x3F) + | P4_ESCR_OS + | P4_ESCR_USR; + + cccr_val |= P4_CCCR_THRESHOLD(15) + | P4_CCCR_COMPLEMENT + | P4_CCCR_COMPARE + | P4_CCCR_REQUIRED; + + wrmsr(evntsel_msr, evntsel, 0); + wrmsr(cccr_msr, cccr_val, 0); + write_watchdog_counter(perfctr_msr, "P4_IQ_COUNTER0", nmi_hz); + apic_write(APIC_LVTPC, APIC_DM_NMI); + cccr_val |= P4_CCCR_ENABLE; + wrmsr(cccr_msr, cccr_val, 0); + wd->perfctr_msr = perfctr_msr; + wd->evntsel_msr = evntsel_msr; + wd->cccr_msr = cccr_msr; + return 1; +} + +static void stop_p4_watchdog(void *arg) +{ + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + wrmsr(wd->cccr_msr, 0, 0); + wrmsr(wd->evntsel_msr, 0, 0); +} + +static int p4_reserve(void) +{ + if (!reserve_perfctr_nmi(MSR_P4_IQ_PERFCTR0)) + return 0; +#ifdef CONFIG_SMP + if (smp_num_siblings > 1 && !reserve_perfctr_nmi(MSR_P4_IQ_PERFCTR1)) + goto fail1; +#endif + if (!reserve_evntsel_nmi(MSR_P4_CRU_ESCR0)) + goto fail2; + /* RED-PEN why is ESCR1 not reserved here? */ + return 1; + fail2: +#ifdef CONFIG_SMP + if (smp_num_siblings > 1) + release_perfctr_nmi(MSR_P4_IQ_PERFCTR1); + fail1: +#endif + release_perfctr_nmi(MSR_P4_IQ_PERFCTR0); + return 0; +} + +static void p4_unreserve(void) +{ +#ifdef CONFIG_SMP + if (smp_num_siblings > 1) + release_evntsel_nmi(MSR_P4_IQ_PERFCTR1); +#endif + release_evntsel_nmi(MSR_P4_IQ_PERFCTR0); + release_perfctr_nmi(MSR_P4_CRU_ESCR0); +} + +static void p4_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz) +{ + unsigned dummy; + /* + * P4 quirks: + * - An overflown perfctr will assert its interrupt + * until the OVF flag in its CCCR is cleared. + * - LVTPC is masked on interrupt and must be + * unmasked by the LVTPC handler. + */ + rdmsrl(wd->cccr_msr, dummy); + dummy &= ~P4_CCCR_OVF; + wrmsrl(wd->cccr_msr, dummy); + apic_write(APIC_LVTPC, APIC_DM_NMI); + /* start the cycle over again */ + write_watchdog_counter(wd->perfctr_msr, NULL, nmi_hz); +} + +static struct wd_ops p4_wd_ops = { + .reserve = p4_reserve, + .unreserve = p4_unreserve, + .setup = setup_p4_watchdog, + .rearm = p4_rearm, + .stop = stop_p4_watchdog, + /* RED-PEN this is wrong for the other sibling */ + .perfctr = MSR_P4_BPU_PERFCTR0, + .evntsel = MSR_P4_BSU_ESCR0, + .checkbit = 1ULL<<39, +}; + +/* Watchdog using the Intel architected PerfMon. Used for Core2 and hopefully + all future Intel CPUs. */ + +#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL +#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK + +static int setup_intel_arch_watchdog(unsigned nmi_hz) +{ + unsigned int ebx; + union cpuid10_eax eax; + unsigned int unused; + unsigned int perfctr_msr, evntsel_msr; + unsigned int evntsel; + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + /* + * Check whether the Architectural PerfMon supports + * Unhalted Core Cycles Event or not. + * NOTE: Corresponding bit = 0 in ebx indicates event present. + */ + cpuid(10, &(eax.full), &ebx, &unused, &unused); + if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || + (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + return 0; + + perfctr_msr = MSR_ARCH_PERFMON_PERFCTR1; + evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL1; + + wrmsrl(perfctr_msr, 0UL); + + evntsel = ARCH_PERFMON_EVENTSEL_INT + | ARCH_PERFMON_EVENTSEL_OS + | ARCH_PERFMON_EVENTSEL_USR + | ARCH_PERFMON_NMI_EVENT_SEL + | ARCH_PERFMON_NMI_EVENT_UMASK; + + /* setup the timer */ + wrmsr(evntsel_msr, evntsel, 0); + nmi_hz = adjust_for_32bit_ctr(nmi_hz); + write_watchdog_counter32(perfctr_msr, "INTEL_ARCH_PERFCTR0", nmi_hz); + apic_write(APIC_LVTPC, APIC_DM_NMI); + evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; + wrmsr(evntsel_msr, evntsel, 0); + + wd->perfctr_msr = perfctr_msr; + wd->evntsel_msr = evntsel_msr; + wd->cccr_msr = 0; //unused + wd_ops->checkbit = 1ULL << (eax.split.bit_width - 1); + return 1; +} + +static struct wd_ops intel_arch_wd_ops = { + .reserve = single_msr_reserve, + .unreserve = single_msr_unreserve, + .setup = setup_intel_arch_watchdog, + .rearm = p6_rearm, + .stop = single_msr_stop_watchdog, + .perfctr = MSR_ARCH_PERFMON_PERFCTR0, + .evntsel = MSR_ARCH_PERFMON_EVENTSEL0, +}; + +static void probe_nmi_watchdog(void) +{ + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15 && + boot_cpu_data.x86 != 16) + return; + wd_ops = &k7_wd_ops; + break; + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + wd_ops = &intel_arch_wd_ops; + break; + } + switch (boot_cpu_data.x86) { + case 6: + if (boot_cpu_data.x86_model > 0xd) + return; + + wd_ops = &p6_wd_ops; + break; + case 15: + if (boot_cpu_data.x86_model > 0x4) + return; + + wd_ops = &p4_wd_ops; + break; + default: + return; + } + break; + } +} + +/* Interface to nmi.c */ + +int lapic_watchdog_init(unsigned nmi_hz) +{ + if (!wd_ops) { + probe_nmi_watchdog(); + if (!wd_ops) + return -1; + } + + if (!(wd_ops->setup(nmi_hz))) { + printk(KERN_ERR "Cannot setup NMI watchdog on CPU %d\n", + raw_smp_processor_id()); + return -1; + } + + return 0; +} + +void lapic_watchdog_stop(void) +{ + if (wd_ops) + wd_ops->stop(NULL); +} + +unsigned lapic_adjust_nmi_hz(unsigned hz) +{ + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + if (wd->perfctr_msr == MSR_P6_PERFCTR0 || + wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR1) + hz = adjust_for_32bit_ctr(hz); + return hz; +} + +int lapic_wd_event(unsigned nmi_hz) +{ + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + u64 ctr; + rdmsrl(wd->perfctr_msr, ctr); + if (ctr & wd_ops->checkbit) { /* perfctr still running? */ + return 0; + } + wd_ops->rearm(wd, nmi_hz); + return 1; +} + +int lapic_watchdog_ok(void) +{ + return wd_ops != NULL; +} diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 2dec1b105737..33cf2f3c444f 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -28,30 +27,14 @@ #include #include #include -#include #include "mach_traps.h" int unknown_nmi_panic; int nmi_watchdog_enabled; -/* perfctr_nmi_owner tracks the ownership of the perfctr registers: - * evtsel_nmi_owner tracks the ownership of the event selection - * - different performance counters/ event selection may be reserved for - * different subsystems this reservation system just tries to coordinate - * things a little - */ - -/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's - * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) - */ -#define NMI_MAX_COUNTER_BITS 66 -#define NMI_MAX_COUNTER_LONGS BITS_TO_LONGS(NMI_MAX_COUNTER_BITS) - -static DEFINE_PER_CPU(unsigned long, perfctr_nmi_owner[NMI_MAX_COUNTER_LONGS]); -static DEFINE_PER_CPU(unsigned long, evntsel_nmi_owner[NMI_MAX_COUNTER_LONGS]); - static cpumask_t backtrace_mask = CPU_MASK_NONE; + /* nmi_active: * >0: the lapic NMI watchdog is active, but can be disabled * <0: the lapic NMI watchdog has not been set up, and cannot @@ -63,203 +46,11 @@ atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */ unsigned int nmi_watchdog = NMI_DEFAULT; static unsigned int nmi_hz = HZ; -struct nmi_watchdog_ctlblk { - int enabled; - u64 check_bit; - unsigned int cccr_msr; - unsigned int perfctr_msr; /* the MSR to reset in NMI handler */ - unsigned int evntsel_msr; /* the MSR to select the events to handle */ -}; -static DEFINE_PER_CPU(struct nmi_watchdog_ctlblk, nmi_watchdog_ctlblk); +static DEFINE_PER_CPU(short, wd_enabled); /* local prototypes */ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu); -/* converts an msr to an appropriate reservation bit */ -static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr) -{ - /* returns the bit offset of the performance counter register */ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - return (msr - MSR_K7_PERFCTR0); - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return (msr - MSR_ARCH_PERFMON_PERFCTR0); - - switch (boot_cpu_data.x86) { - case 6: - return (msr - MSR_P6_PERFCTR0); - case 15: - return (msr - MSR_P4_BPU_PERFCTR0); - } - } - return 0; -} - -/* converts an msr to an appropriate reservation bit */ -static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr) -{ - /* returns the bit offset of the event selection register */ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - return (msr - MSR_K7_EVNTSEL0); - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return (msr - MSR_ARCH_PERFMON_EVENTSEL0); - - switch (boot_cpu_data.x86) { - case 6: - return (msr - MSR_P6_EVNTSEL0); - case 15: - return (msr - MSR_P4_BSU_ESCR0); - } - } - return 0; -} - -/* checks for a bit availability (hack for oprofile) */ -int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) -{ - int cpu; - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - for_each_possible_cpu (cpu) { - if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0])) - return 0; - } - return 1; -} - -/* checks the an msr for availability */ -int avail_to_resrv_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - int cpu; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - for_each_possible_cpu (cpu) { - if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0])) - return 0; - } - return 1; -} - -static int __reserve_perfctr_nmi(int cpu, unsigned int msr) -{ - unsigned int counter; - if (cpu < 0) - cpu = smp_processor_id(); - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - if (!test_and_set_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0])) - return 1; - return 0; -} - -static void __release_perfctr_nmi(int cpu, unsigned int msr) -{ - unsigned int counter; - if (cpu < 0) - cpu = smp_processor_id(); - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - clear_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0]); -} - -int reserve_perfctr_nmi(unsigned int msr) -{ - int cpu, i; - for_each_possible_cpu (cpu) { - if (!__reserve_perfctr_nmi(cpu, msr)) { - for_each_possible_cpu (i) { - if (i >= cpu) - break; - __release_perfctr_nmi(i, msr); - } - return 0; - } - } - return 1; -} - -void release_perfctr_nmi(unsigned int msr) -{ - int cpu; - for_each_possible_cpu (cpu) { - __release_perfctr_nmi(cpu, msr); - } -} - -int __reserve_evntsel_nmi(int cpu, unsigned int msr) -{ - unsigned int counter; - if (cpu < 0) - cpu = smp_processor_id(); - - counter = nmi_evntsel_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - if (!test_and_set_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0])) - return 1; - return 0; -} - -static void __release_evntsel_nmi(int cpu, unsigned int msr) -{ - unsigned int counter; - if (cpu < 0) - cpu = smp_processor_id(); - - counter = nmi_evntsel_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - clear_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0]); -} - -int reserve_evntsel_nmi(unsigned int msr) -{ - int cpu, i; - for_each_possible_cpu (cpu) { - if (!__reserve_evntsel_nmi(cpu, msr)) { - for_each_possible_cpu (i) { - if (i >= cpu) - break; - __release_evntsel_nmi(i, msr); - } - return 0; - } - } - return 1; -} - -void release_evntsel_nmi(unsigned int msr) -{ - int cpu; - for_each_possible_cpu (cpu) { - __release_evntsel_nmi(cpu, msr); - } -} - -static __cpuinit inline int nmi_known_cpu(void) -{ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - return ((boot_cpu_data.x86 == 15) || (boot_cpu_data.x86 == 6) - || (boot_cpu_data.x86 == 16)); - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return 1; - else - return ((boot_cpu_data.x86 == 15) || (boot_cpu_data.x86 == 6)); - } - return 0; -} - static int endflag __initdata = 0; #ifdef CONFIG_SMP @@ -281,28 +72,6 @@ static __init void nmi_cpu_busy(void *data) } #endif -static unsigned int adjust_for_32bit_ctr(unsigned int hz) -{ - u64 counter_val; - unsigned int retval = hz; - - /* - * On Intel CPUs with P6/ARCH_PERFMON only 32 bits in the counter - * are writable, with higher bits sign extending from bit 31. - * So, we can only program the counter with 31 bit values and - * 32nd bit should be 1, for 33.. to be 1. - * Find the appropriate nmi_hz - */ - counter_val = (u64)cpu_khz * 1000; - do_div(counter_val, retval); - if (counter_val > 0x7fffffffULL) { - u64 count = (u64)cpu_khz * 1000; - do_div(count, 0x7fffffffUL); - retval = count + 1; - } - return retval; -} - static int __init check_nmi_watchdog(void) { unsigned int *prev_nmi_count; @@ -335,14 +104,14 @@ static int __init check_nmi_watchdog(void) if (!cpu_isset(cpu, cpu_callin_map)) continue; #endif - if (!per_cpu(nmi_watchdog_ctlblk, cpu).enabled) + if (!per_cpu(wd_enabled, cpu)) continue; if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) { printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n", cpu, prev_nmi_count[cpu], nmi_count(cpu)); - per_cpu(nmi_watchdog_ctlblk, cpu).enabled = 0; + per_cpu(wd_enabled, cpu) = 0; atomic_dec(&nmi_active); } } @@ -356,16 +125,8 @@ static int __init check_nmi_watchdog(void) /* now that we know it works we can reduce NMI frequency to something more reasonable; makes a difference in some configs */ - if (nmi_watchdog == NMI_LOCAL_APIC) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - nmi_hz = 1; - - if (wd->perfctr_msr == MSR_P6_PERFCTR0 || - wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR1) { - nmi_hz = adjust_for_32bit_ctr(nmi_hz); - } - } + if (nmi_watchdog == NMI_LOCAL_APIC) + nmi_hz = lapic_adjust_nmi_hz(1); kfree(prev_nmi_count); return 0; @@ -388,85 +149,8 @@ static int __init setup_nmi_watchdog(char *str) __setup("nmi_watchdog=", setup_nmi_watchdog); -static void disable_lapic_nmi_watchdog(void) -{ - BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); - - if (atomic_read(&nmi_active) <= 0) - return; - - on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1); - - BUG_ON(atomic_read(&nmi_active) != 0); -} - -static void enable_lapic_nmi_watchdog(void) -{ - BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); - - /* are we already enabled */ - if (atomic_read(&nmi_active) != 0) - return; - - /* are we lapic aware */ - if (nmi_known_cpu() <= 0) - return; - - on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); - touch_nmi_watchdog(); -} - -void disable_timer_nmi_watchdog(void) -{ - BUG_ON(nmi_watchdog != NMI_IO_APIC); - - if (atomic_read(&nmi_active) <= 0) - return; - - disable_irq(0); - on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1); - - BUG_ON(atomic_read(&nmi_active) != 0); -} - -void enable_timer_nmi_watchdog(void) -{ - BUG_ON(nmi_watchdog != NMI_IO_APIC); - - if (atomic_read(&nmi_active) == 0) { - touch_nmi_watchdog(); - on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); - enable_irq(0); - } -} - -static void __acpi_nmi_disable(void *__unused) -{ - apic_write_around(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED); -} -/* - * Disable timer based NMIs on all CPUs: - */ -void acpi_nmi_disable(void) -{ - if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC) - on_each_cpu(__acpi_nmi_disable, NULL, 0, 1); -} - -static void __acpi_nmi_enable(void *__unused) -{ - apic_write_around(APIC_LVT0, APIC_DM_NMI); -} - -/* - * Enable timer based NMIs on all CPUs: - */ -void acpi_nmi_enable(void) -{ - if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC) - on_each_cpu(__acpi_nmi_enable, NULL, 0, 1); -} +/* Suspend/resume support */ #ifdef CONFIG_PM @@ -513,7 +197,7 @@ static int __init init_lapic_nmi_sysfs(void) if (nmi_watchdog != NMI_LOCAL_APIC) return 0; - if ( atomic_read(&nmi_active) < 0 ) + if (atomic_read(&nmi_active) < 0) return 0; error = sysdev_class_register(&nmi_sysclass); @@ -526,433 +210,69 @@ late_initcall(init_lapic_nmi_sysfs); #endif /* CONFIG_PM */ -/* - * Activate the NMI watchdog via the local APIC. - * Original code written by Keith Owens. - */ - -static void write_watchdog_counter(unsigned int perfctr_msr, const char *descr) -{ - u64 count = (u64)cpu_khz * 1000; - - do_div(count, nmi_hz); - if(descr) - Dprintk("setting %s to -0x%08Lx\n", descr, count); - wrmsrl(perfctr_msr, 0 - count); -} - -static void write_watchdog_counter32(unsigned int perfctr_msr, - const char *descr) -{ - u64 count = (u64)cpu_khz * 1000; - - do_div(count, nmi_hz); - if(descr) - Dprintk("setting %s to -0x%08Lx\n", descr, count); - wrmsr(perfctr_msr, (u32)(-count), 0); -} - -/* Note that these events don't tick when the CPU idles. This means - the frequency varies with CPU load. */ - -#define K7_EVNTSEL_ENABLE (1 << 22) -#define K7_EVNTSEL_INT (1 << 20) -#define K7_EVNTSEL_OS (1 << 17) -#define K7_EVNTSEL_USR (1 << 16) -#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 -#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING - -static int setup_k7_watchdog(void) -{ - unsigned int perfctr_msr, evntsel_msr; - unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - perfctr_msr = MSR_K7_PERFCTR0; - evntsel_msr = MSR_K7_EVNTSEL0; - if (!__reserve_perfctr_nmi(-1, perfctr_msr)) - goto fail; - - if (!__reserve_evntsel_nmi(-1, evntsel_msr)) - goto fail1; - - wrmsrl(perfctr_msr, 0UL); - - evntsel = K7_EVNTSEL_INT - | K7_EVNTSEL_OS - | K7_EVNTSEL_USR - | K7_NMI_EVENT; - - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - write_watchdog_counter(perfctr_msr, "K7_PERFCTR0"); - apic_write(APIC_LVTPC, APIC_DM_NMI); - evntsel |= K7_EVNTSEL_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - wd->check_bit = 1ULL<<63; - return 1; -fail1: - __release_perfctr_nmi(-1, perfctr_msr); -fail: - return 0; -} - -static void stop_k7_watchdog(void) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - wrmsr(wd->evntsel_msr, 0, 0); - - __release_evntsel_nmi(-1, wd->evntsel_msr); - __release_perfctr_nmi(-1, wd->perfctr_msr); -} - -#define P6_EVNTSEL0_ENABLE (1 << 22) -#define P6_EVNTSEL_INT (1 << 20) -#define P6_EVNTSEL_OS (1 << 17) -#define P6_EVNTSEL_USR (1 << 16) -#define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79 -#define P6_NMI_EVENT P6_EVENT_CPU_CLOCKS_NOT_HALTED - -static int setup_p6_watchdog(void) -{ - unsigned int perfctr_msr, evntsel_msr; - unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - perfctr_msr = MSR_P6_PERFCTR0; - evntsel_msr = MSR_P6_EVNTSEL0; - if (!__reserve_perfctr_nmi(-1, perfctr_msr)) - goto fail; - - if (!__reserve_evntsel_nmi(-1, evntsel_msr)) - goto fail1; - - wrmsrl(perfctr_msr, 0UL); - - evntsel = P6_EVNTSEL_INT - | P6_EVNTSEL_OS - | P6_EVNTSEL_USR - | P6_NMI_EVENT; - - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - nmi_hz = adjust_for_32bit_ctr(nmi_hz); - write_watchdog_counter32(perfctr_msr, "P6_PERFCTR0"); - apic_write(APIC_LVTPC, APIC_DM_NMI); - evntsel |= P6_EVNTSEL0_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - wd->check_bit = 1ULL<<39; - return 1; -fail1: - __release_perfctr_nmi(-1, perfctr_msr); -fail: - return 0; -} - -static void stop_p6_watchdog(void) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - wrmsr(wd->evntsel_msr, 0, 0); - - __release_evntsel_nmi(-1, wd->evntsel_msr); - __release_perfctr_nmi(-1, wd->perfctr_msr); -} - -/* Note that these events don't tick when the CPU idles. This means - the frequency varies with CPU load. */ - -#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) -#define P4_ESCR_EVENT_SELECT(N) ((N)<<25) -#define P4_ESCR_OS (1<<3) -#define P4_ESCR_USR (1<<2) -#define P4_CCCR_OVF_PMI0 (1<<26) -#define P4_CCCR_OVF_PMI1 (1<<27) -#define P4_CCCR_THRESHOLD(N) ((N)<<20) -#define P4_CCCR_COMPLEMENT (1<<19) -#define P4_CCCR_COMPARE (1<<18) -#define P4_CCCR_REQUIRED (3<<16) -#define P4_CCCR_ESCR_SELECT(N) ((N)<<13) -#define P4_CCCR_ENABLE (1<<12) -#define P4_CCCR_OVF (1<<31) -/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter - CRU_ESCR0 (with any non-null event selector) through a complemented - max threshold. [IA32-Vol3, Section 14.9.9] */ - -static int setup_p4_watchdog(void) +static void __acpi_nmi_enable(void *__unused) { - unsigned int perfctr_msr, evntsel_msr, cccr_msr; - unsigned int evntsel, cccr_val; - unsigned int misc_enable, dummy; - unsigned int ht_num; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - rdmsr(MSR_IA32_MISC_ENABLE, misc_enable, dummy); - if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL)) - return 0; - -#ifdef CONFIG_SMP - /* detect which hyperthread we are on */ - if (smp_num_siblings == 2) { - unsigned int ebx, apicid; - - ebx = cpuid_ebx(1); - apicid = (ebx >> 24) & 0xff; - ht_num = apicid & 1; - } else -#endif - ht_num = 0; - - /* performance counters are shared resources - * assign each hyperthread its own set - * (re-use the ESCR0 register, seems safe - * and keeps the cccr_val the same) - */ - if (!ht_num) { - /* logical cpu 0 */ - perfctr_msr = MSR_P4_IQ_PERFCTR0; - evntsel_msr = MSR_P4_CRU_ESCR0; - cccr_msr = MSR_P4_IQ_CCCR0; - cccr_val = P4_CCCR_OVF_PMI0 | P4_CCCR_ESCR_SELECT(4); - } else { - /* logical cpu 1 */ - perfctr_msr = MSR_P4_IQ_PERFCTR1; - evntsel_msr = MSR_P4_CRU_ESCR0; - cccr_msr = MSR_P4_IQ_CCCR1; - cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4); - } - - if (!__reserve_perfctr_nmi(-1, perfctr_msr)) - goto fail; - - if (!__reserve_evntsel_nmi(-1, evntsel_msr)) - goto fail1; - - evntsel = P4_ESCR_EVENT_SELECT(0x3F) - | P4_ESCR_OS - | P4_ESCR_USR; - - cccr_val |= P4_CCCR_THRESHOLD(15) - | P4_CCCR_COMPLEMENT - | P4_CCCR_COMPARE - | P4_CCCR_REQUIRED; - - wrmsr(evntsel_msr, evntsel, 0); - wrmsr(cccr_msr, cccr_val, 0); - write_watchdog_counter(perfctr_msr, "P4_IQ_COUNTER0"); - apic_write(APIC_LVTPC, APIC_DM_NMI); - cccr_val |= P4_CCCR_ENABLE; - wrmsr(cccr_msr, cccr_val, 0); - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = cccr_msr; - wd->check_bit = 1ULL<<39; - return 1; -fail1: - __release_perfctr_nmi(-1, perfctr_msr); -fail: - return 0; + apic_write_around(APIC_LVT0, APIC_DM_NMI); } -static void stop_p4_watchdog(void) +/* + * Enable timer based NMIs on all CPUs: + */ +void acpi_nmi_enable(void) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - wrmsr(wd->cccr_msr, 0, 0); - wrmsr(wd->evntsel_msr, 0, 0); - - __release_evntsel_nmi(-1, wd->evntsel_msr); - __release_perfctr_nmi(-1, wd->perfctr_msr); + if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC) + on_each_cpu(__acpi_nmi_enable, NULL, 0, 1); } -#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL -#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK - -static int setup_intel_arch_watchdog(void) +static void __acpi_nmi_disable(void *__unused) { - unsigned int ebx; - union cpuid10_eax eax; - unsigned int unused; - unsigned int perfctr_msr, evntsel_msr; - unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - /* - * Check whether the Architectural PerfMon supports - * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebx indicates event present. - */ - cpuid(10, &(eax.full), &ebx, &unused, &unused); - if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || - (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - goto fail; - - perfctr_msr = MSR_ARCH_PERFMON_PERFCTR1; - evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL1; - - if (!__reserve_perfctr_nmi(-1, perfctr_msr)) - goto fail; - - if (!__reserve_evntsel_nmi(-1, evntsel_msr)) - goto fail1; - - wrmsrl(perfctr_msr, 0UL); - - evntsel = ARCH_PERFMON_EVENTSEL_INT - | ARCH_PERFMON_EVENTSEL_OS - | ARCH_PERFMON_EVENTSEL_USR - | ARCH_PERFMON_NMI_EVENT_SEL - | ARCH_PERFMON_NMI_EVENT_UMASK; - - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - nmi_hz = adjust_for_32bit_ctr(nmi_hz); - write_watchdog_counter32(perfctr_msr, "INTEL_ARCH_PERFCTR0"); - apic_write(APIC_LVTPC, APIC_DM_NMI); - evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - wd->check_bit = 1ULL << (eax.split.bit_width - 1); - return 1; -fail1: - __release_perfctr_nmi(-1, perfctr_msr); -fail: - return 0; + apic_write(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED); } -static void stop_intel_arch_watchdog(void) +/* + * Disable timer based NMIs on all CPUs: + */ +void acpi_nmi_disable(void) { - unsigned int ebx; - union cpuid10_eax eax; - unsigned int unused; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - /* - * Check whether the Architectural PerfMon supports - * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebx indicates event present. - */ - cpuid(10, &(eax.full), &ebx, &unused, &unused); - if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || - (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - return; - - wrmsr(wd->evntsel_msr, 0, 0); - __release_evntsel_nmi(-1, wd->evntsel_msr); - __release_perfctr_nmi(-1, wd->perfctr_msr); + if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC) + on_each_cpu(__acpi_nmi_disable, NULL, 0, 1); } void setup_apic_nmi_watchdog (void *unused) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - /* only support LOCAL and IO APICs for now */ - if ((nmi_watchdog != NMI_LOCAL_APIC) && - (nmi_watchdog != NMI_IO_APIC)) - return; - - if (wd->enabled == 1) - return; + if (__get_cpu_var(wd_enabled)) + return; /* cheap hack to support suspend/resume */ /* if cpu0 is not active neither should the other cpus */ if ((smp_processor_id() != 0) && (atomic_read(&nmi_active) <= 0)) return; - if (nmi_watchdog == NMI_LOCAL_APIC) { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15 && - boot_cpu_data.x86 != 16) - return; - if (!setup_k7_watchdog()) - return; - break; - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - if (!setup_intel_arch_watchdog()) - return; - break; - } - switch (boot_cpu_data.x86) { - case 6: - if (boot_cpu_data.x86_model > 0xd) - return; - - if (!setup_p6_watchdog()) - return; - break; - case 15: - if (boot_cpu_data.x86_model > 0x4) - return; - - if (!setup_p4_watchdog()) - return; - break; - default: - return; - } - break; - default: + switch (nmi_watchdog) { + case NMI_LOCAL_APIC: + __get_cpu_var(wd_enabled) = 1; /* enable it before to avoid race with handler */ + if (lapic_watchdog_init(nmi_hz) < 0) { + __get_cpu_var(wd_enabled) = 0; return; } + /* FALL THROUGH */ + case NMI_IO_APIC: + __get_cpu_var(wd_enabled) = 1; + atomic_inc(&nmi_active); } - wd->enabled = 1; - atomic_inc(&nmi_active); } void stop_apic_nmi_watchdog(void *unused) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - /* only support LOCAL and IO APICs for now */ if ((nmi_watchdog != NMI_LOCAL_APIC) && (nmi_watchdog != NMI_IO_APIC)) return; - - if (wd->enabled == 0) + if (__get_cpu_var(wd_enabled) == 0) return; - - if (nmi_watchdog == NMI_LOCAL_APIC) { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - stop_k7_watchdog(); - break; - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - stop_intel_arch_watchdog(); - break; - } - switch (boot_cpu_data.x86) { - case 6: - if (boot_cpu_data.x86_model > 0xd) - break; - stop_p6_watchdog(); - break; - case 15: - if (boot_cpu_data.x86_model > 0x4) - break; - stop_p4_watchdog(); - break; - } - break; - default: - return; - } - } - wd->enabled = 0; + if (nmi_watchdog == NMI_LOCAL_APIC) + lapic_watchdog_stop(); + __get_cpu_var(wd_enabled) = 0; atomic_dec(&nmi_active); } @@ -1008,8 +328,6 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) unsigned int sum; int touched = 0; int cpu = smp_processor_id(); - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - u64 dummy; int rc=0; /* check for other users first */ @@ -1052,53 +370,20 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) alert_counter[cpu] = 0; } /* see if the nmi watchdog went off */ - if (wd->enabled) { - if (nmi_watchdog == NMI_LOCAL_APIC) { - rdmsrl(wd->perfctr_msr, dummy); - if (dummy & wd->check_bit){ - /* this wasn't a watchdog timer interrupt */ - goto done; - } - - /* only Intel P4 uses the cccr msr */ - if (wd->cccr_msr != 0) { - /* - * P4 quirks: - * - An overflown perfctr will assert its interrupt - * until the OVF flag in its CCCR is cleared. - * - LVTPC is masked on interrupt and must be - * unmasked by the LVTPC handler. - */ - rdmsrl(wd->cccr_msr, dummy); - dummy &= ~P4_CCCR_OVF; - wrmsrl(wd->cccr_msr, dummy); - apic_write(APIC_LVTPC, APIC_DM_NMI); - /* start the cycle over again */ - write_watchdog_counter(wd->perfctr_msr, NULL); - } - else if (wd->perfctr_msr == MSR_P6_PERFCTR0 || - wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR1) { - /* P6 based Pentium M need to re-unmask - * the apic vector but it doesn't hurt - * other P6 variant. - * ArchPerfom/Core Duo also needs this */ - apic_write(APIC_LVTPC, APIC_DM_NMI); - /* P6/ARCH_PERFMON has 32 bit counter write */ - write_watchdog_counter32(wd->perfctr_msr, NULL); - } else { - /* start the cycle over again */ - write_watchdog_counter(wd->perfctr_msr, NULL); - } - rc = 1; - } else if (nmi_watchdog == NMI_IO_APIC) { - /* don't know how to accurately check for this. - * just assume it was a watchdog timer interrupt - * This matches the old behaviour. - */ - rc = 1; - } + if (!__get_cpu_var(wd_enabled)) + return rc; + switch (nmi_watchdog) { + case NMI_LOCAL_APIC: + rc |= lapic_wd_event(nmi_hz); + break; + case NMI_IO_APIC: + /* don't know how to accurately check for this. + * just assume it was a watchdog timer interrupt + * This matches the old behaviour. + */ + rc = 1; + break; } -done: return rc; } @@ -1143,7 +428,7 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, } if (nmi_watchdog == NMI_DEFAULT) { - if (nmi_known_cpu() > 0) + if (lapic_watchdog_ok()) nmi_watchdog = NMI_LOCAL_APIC; else nmi_watchdog = NMI_IO_APIC; @@ -1179,11 +464,3 @@ void __trigger_all_cpu_backtrace(void) EXPORT_SYMBOL(nmi_active); EXPORT_SYMBOL(nmi_watchdog); -EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi); -EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit); -EXPORT_SYMBOL(reserve_perfctr_nmi); -EXPORT_SYMBOL(release_perfctr_nmi); -EXPORT_SYMBOL(reserve_evntsel_nmi); -EXPORT_SYMBOL(release_evntsel_nmi); -EXPORT_SYMBOL(disable_timer_nmi_watchdog); -EXPORT_SYMBOL(enable_timer_nmi_watchdog); diff --git a/include/asm-i386/nmi.h b/include/asm-i386/nmi.h index b04333ea6f31..fb1e133efd9f 100644 --- a/include/asm-i386/nmi.h +++ b/include/asm-i386/nmi.h @@ -50,4 +50,12 @@ void __trigger_all_cpu_backtrace(void); #endif +void lapic_watchdog_stop(void); +int lapic_watchdog_init(unsigned nmi_hz); +int lapic_wd_event(unsigned nmi_hz); +unsigned lapic_adjust_nmi_hz(unsigned hz); +int lapic_watchdog_ok(void); +void disable_lapic_nmi_watchdog(void); +void enable_lapic_nmi_watchdog(void); + #endif /* ASM_NMI_H */ -- cgit v1.2.3-59-g8ed1b From 05cb007dac9a50148daf87d0b9469e0cd05fd5e7 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:20 +0200 Subject: [PATCH] x86-64: Use the 32bit wd_ops for 64bit too. This mainly removes a lot of code, replacing it with calls into the new 32bit perfctr-watchdog.c Signed-off-by: Andi Kleen --- arch/x86_64/kernel/Makefile | 4 +- arch/x86_64/kernel/nmi.c | 678 +++----------------------------------------- include/asm-x86_64/nmi.h | 9 + 3 files changed, 45 insertions(+), 646 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index a613e13d0e75..4d94c51803d8 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile @@ -8,7 +8,8 @@ obj-y := process.o signal.o entry.o traps.o irq.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \ x8664_ksyms.o i387.o syscall.o vsyscall.o \ setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \ - pci-dma.o pci-nommu.o alternative.o hpet.o tsc.o bugs.o + pci-dma.o pci-nommu.o alternative.o hpet.o tsc.o bugs.o \ + perfctr-watchdog.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_X86_MCE) += mce.o therm_throt.o @@ -57,3 +58,4 @@ i8237-y += ../../i386/kernel/i8237.o msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o alternative-y += ../../i386/kernel/alternative.o pcspeaker-y += ../../i386/kernel/pcspeaker.o +perfctr-watchdog-y += ../../i386/kernel/cpu/perfctr-watchdog.o diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 010d3d9bd56a..6cd2b30e2ffc 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c @@ -27,28 +27,11 @@ #include #include #include -#include int unknown_nmi_panic; int nmi_watchdog_enabled; int panic_on_unrecovered_nmi; -/* perfctr_nmi_owner tracks the ownership of the perfctr registers: - * evtsel_nmi_owner tracks the ownership of the event selection - * - different performance counters/ event selection may be reserved for - * different subsystems this reservation system just tries to coordinate - * things a little - */ - -/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's - * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) - */ -#define NMI_MAX_COUNTER_BITS 66 -#define NMI_MAX_COUNTER_LONGS BITS_TO_LONGS(NMI_MAX_COUNTER_BITS) - -static DEFINE_PER_CPU(unsigned, perfctr_nmi_owner[NMI_MAX_COUNTER_LONGS]); -static DEFINE_PER_CPU(unsigned, evntsel_nmi_owner[NMI_MAX_COUNTER_LONGS]); - static cpumask_t backtrace_mask = CPU_MASK_NONE; /* nmi_active: @@ -63,191 +46,11 @@ int panic_on_timeout; unsigned int nmi_watchdog = NMI_DEFAULT; static unsigned int nmi_hz = HZ; -struct nmi_watchdog_ctlblk { - int enabled; - u64 check_bit; - unsigned int cccr_msr; - unsigned int perfctr_msr; /* the MSR to reset in NMI handler */ - unsigned int evntsel_msr; /* the MSR to select the events to handle */ -}; -static DEFINE_PER_CPU(struct nmi_watchdog_ctlblk, nmi_watchdog_ctlblk); +static DEFINE_PER_CPU(short, wd_enabled); /* local prototypes */ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu); -/* converts an msr to an appropriate reservation bit */ -static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr) -{ - /* returns the bit offset of the performance counter register */ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - return (msr - MSR_K7_PERFCTR0); - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return (msr - MSR_ARCH_PERFMON_PERFCTR0); - else - return (msr - MSR_P4_BPU_PERFCTR0); - } - return 0; -} - -/* converts an msr to an appropriate reservation bit */ -static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr) -{ - /* returns the bit offset of the event selection register */ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - return (msr - MSR_K7_EVNTSEL0); - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return (msr - MSR_ARCH_PERFMON_EVENTSEL0); - else - return (msr - MSR_P4_BSU_ESCR0); - } - return 0; -} - -/* checks for a bit availability (hack for oprofile) */ -int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) -{ - int cpu; - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - for_each_possible_cpu (cpu) { - if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu))) - return 0; - } - return 1; -} - -/* checks the an msr for availability */ -int avail_to_resrv_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - int cpu; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - for_each_possible_cpu (cpu) { - if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu))) - return 0; - } - return 1; -} - -static int __reserve_perfctr_nmi(int cpu, unsigned int msr) -{ - unsigned int counter; - if (cpu < 0) - cpu = smp_processor_id(); - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - if (!test_and_set_bit(counter, &per_cpu(perfctr_nmi_owner, cpu))) - return 1; - return 0; -} - -static void __release_perfctr_nmi(int cpu, unsigned int msr) -{ - unsigned int counter; - if (cpu < 0) - cpu = smp_processor_id(); - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - clear_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)); -} - -int reserve_perfctr_nmi(unsigned int msr) -{ - int cpu, i; - for_each_possible_cpu (cpu) { - if (!__reserve_perfctr_nmi(cpu, msr)) { - for_each_possible_cpu (i) { - if (i >= cpu) - break; - __release_perfctr_nmi(i, msr); - } - return 0; - } - } - return 1; -} - -void release_perfctr_nmi(unsigned int msr) -{ - int cpu; - for_each_possible_cpu (cpu) - __release_perfctr_nmi(cpu, msr); -} - -int __reserve_evntsel_nmi(int cpu, unsigned int msr) -{ - unsigned int counter; - if (cpu < 0) - cpu = smp_processor_id(); - - counter = nmi_evntsel_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - if (!test_and_set_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0])) - return 1; - return 0; -} - -static void __release_evntsel_nmi(int cpu, unsigned int msr) -{ - unsigned int counter; - if (cpu < 0) - cpu = smp_processor_id(); - - counter = nmi_evntsel_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - clear_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0]); -} - -int reserve_evntsel_nmi(unsigned int msr) -{ - int cpu, i; - for_each_possible_cpu (cpu) { - if (!__reserve_evntsel_nmi(cpu, msr)) { - for_each_possible_cpu (i) { - if (i >= cpu) - break; - __release_evntsel_nmi(i, msr); - } - return 0; - } - } - return 1; -} - -void release_evntsel_nmi(unsigned int msr) -{ - int cpu; - for_each_possible_cpu (cpu) { - __release_evntsel_nmi(cpu, msr); - } -} - -static __cpuinit inline int nmi_known_cpu(void) -{ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - return boot_cpu_data.x86 == 15 || boot_cpu_data.x86 == 16; - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return 1; - else - return (boot_cpu_data.x86 == 15); - } - return 0; -} - /* Run after command line and cpu_init init, but before all other checks */ void nmi_watchdog_default(void) { @@ -277,23 +80,6 @@ static __init void nmi_cpu_busy(void *data) } #endif -static unsigned int adjust_for_32bit_ctr(unsigned int hz) -{ - unsigned int retval = hz; - - /* - * On Intel CPUs with ARCH_PERFMON only 32 bits in the counter - * are writable, with higher bits sign extending from bit 31. - * So, we can only program the counter with 31 bit values and - * 32nd bit should be 1, for 33.. to be 1. - * Find the appropriate nmi_hz - */ - if ((((u64)cpu_khz * 1000) / retval) > 0x7fffffffULL) { - retval = ((u64)cpu_khz * 1000) / 0x7fffffffUL + 1; - } - return retval; -} - int __init check_nmi_watchdog (void) { int *counts; @@ -322,14 +108,14 @@ int __init check_nmi_watchdog (void) mdelay((20*1000)/nmi_hz); // wait 20 ticks for_each_online_cpu(cpu) { - if (!per_cpu(nmi_watchdog_ctlblk, cpu).enabled) + if (!per_cpu(wd_enabled, cpu)) continue; if (cpu_pda(cpu)->__nmi_count - counts[cpu] <= 5) { printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n", cpu, counts[cpu], cpu_pda(cpu)->__nmi_count); - per_cpu(nmi_watchdog_ctlblk, cpu).enabled = 0; + per_cpu(wd_enabled, cpu) = 0; atomic_dec(&nmi_active); } } @@ -344,13 +130,8 @@ int __init check_nmi_watchdog (void) /* now that we know it works we can reduce NMI frequency to something more reasonable; makes a difference in some configs */ - if (nmi_watchdog == NMI_LOCAL_APIC) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - nmi_hz = 1; - if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR1) - nmi_hz = adjust_for_32bit_ctr(nmi_hz); - } + if (nmi_watchdog == NMI_LOCAL_APIC) + nmi_hz = lapic_adjust_nmi_hz(1); kfree(counts); return 0; @@ -379,57 +160,6 @@ int __init setup_nmi_watchdog(char *str) __setup("nmi_watchdog=", setup_nmi_watchdog); -static void disable_lapic_nmi_watchdog(void) -{ - BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); - - if (atomic_read(&nmi_active) <= 0) - return; - - on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1); - - BUG_ON(atomic_read(&nmi_active) != 0); -} - -static void enable_lapic_nmi_watchdog(void) -{ - BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); - - /* are we already enabled */ - if (atomic_read(&nmi_active) != 0) - return; - - /* are we lapic aware */ - if (nmi_known_cpu() <= 0) - return; - - on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); - touch_nmi_watchdog(); -} - -void disable_timer_nmi_watchdog(void) -{ - BUG_ON(nmi_watchdog != NMI_IO_APIC); - - if (atomic_read(&nmi_active) <= 0) - return; - - disable_irq(0); - on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1); - - BUG_ON(atomic_read(&nmi_active) != 0); -} - -void enable_timer_nmi_watchdog(void) -{ - BUG_ON(nmi_watchdog != NMI_IO_APIC); - - if (atomic_read(&nmi_active) == 0) { - touch_nmi_watchdog(); - on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); - enable_irq(0); - } -} static void __acpi_nmi_disable(void *__unused) { @@ -515,275 +245,9 @@ late_initcall(init_lapic_nmi_sysfs); #endif /* CONFIG_PM */ -/* - * Activate the NMI watchdog via the local APIC. - * Original code written by Keith Owens. - */ - -/* Note that these events don't tick when the CPU idles. This means - the frequency varies with CPU load. */ - -#define K7_EVNTSEL_ENABLE (1 << 22) -#define K7_EVNTSEL_INT (1 << 20) -#define K7_EVNTSEL_OS (1 << 17) -#define K7_EVNTSEL_USR (1 << 16) -#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 -#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING - -static int setup_k7_watchdog(void) -{ - unsigned int perfctr_msr, evntsel_msr; - unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - perfctr_msr = MSR_K7_PERFCTR0; - evntsel_msr = MSR_K7_EVNTSEL0; - if (!__reserve_perfctr_nmi(-1, perfctr_msr)) - goto fail; - - if (!__reserve_evntsel_nmi(-1, evntsel_msr)) - goto fail1; - - /* Simulator may not support it */ - if (checking_wrmsrl(evntsel_msr, 0UL)) - goto fail2; - wrmsrl(perfctr_msr, 0UL); - - evntsel = K7_EVNTSEL_INT - | K7_EVNTSEL_OS - | K7_EVNTSEL_USR - | K7_NMI_EVENT; - - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - wrmsrl(perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); - apic_write(APIC_LVTPC, APIC_DM_NMI); - evntsel |= K7_EVNTSEL_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - wd->check_bit = 1ULL<<63; - return 1; -fail2: - __release_evntsel_nmi(-1, evntsel_msr); -fail1: - __release_perfctr_nmi(-1, perfctr_msr); -fail: - return 0; -} - -static void stop_k7_watchdog(void) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - wrmsr(wd->evntsel_msr, 0, 0); - - __release_evntsel_nmi(-1, wd->evntsel_msr); - __release_perfctr_nmi(-1, wd->perfctr_msr); -} - -/* Note that these events don't tick when the CPU idles. This means - the frequency varies with CPU load. */ - -#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) -#define P4_ESCR_EVENT_SELECT(N) ((N)<<25) -#define P4_ESCR_OS (1<<3) -#define P4_ESCR_USR (1<<2) -#define P4_CCCR_OVF_PMI0 (1<<26) -#define P4_CCCR_OVF_PMI1 (1<<27) -#define P4_CCCR_THRESHOLD(N) ((N)<<20) -#define P4_CCCR_COMPLEMENT (1<<19) -#define P4_CCCR_COMPARE (1<<18) -#define P4_CCCR_REQUIRED (3<<16) -#define P4_CCCR_ESCR_SELECT(N) ((N)<<13) -#define P4_CCCR_ENABLE (1<<12) -#define P4_CCCR_OVF (1<<31) -/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter - CRU_ESCR0 (with any non-null event selector) through a complemented - max threshold. [IA32-Vol3, Section 14.9.9] */ - -static int setup_p4_watchdog(void) -{ - unsigned int perfctr_msr, evntsel_msr, cccr_msr; - unsigned int evntsel, cccr_val; - unsigned int misc_enable, dummy; - unsigned int ht_num; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - rdmsr(MSR_IA32_MISC_ENABLE, misc_enable, dummy); - if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL)) - return 0; - -#ifdef CONFIG_SMP - /* detect which hyperthread we are on */ - if (smp_num_siblings == 2) { - unsigned int ebx, apicid; - - ebx = cpuid_ebx(1); - apicid = (ebx >> 24) & 0xff; - ht_num = apicid & 1; - } else -#endif - ht_num = 0; - - /* performance counters are shared resources - * assign each hyperthread its own set - * (re-use the ESCR0 register, seems safe - * and keeps the cccr_val the same) - */ - if (!ht_num) { - /* logical cpu 0 */ - perfctr_msr = MSR_P4_IQ_PERFCTR0; - evntsel_msr = MSR_P4_CRU_ESCR0; - cccr_msr = MSR_P4_IQ_CCCR0; - cccr_val = P4_CCCR_OVF_PMI0 | P4_CCCR_ESCR_SELECT(4); - } else { - /* logical cpu 1 */ - perfctr_msr = MSR_P4_IQ_PERFCTR1; - evntsel_msr = MSR_P4_CRU_ESCR0; - cccr_msr = MSR_P4_IQ_CCCR1; - cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4); - } - - if (!__reserve_perfctr_nmi(-1, perfctr_msr)) - goto fail; - - if (!__reserve_evntsel_nmi(-1, evntsel_msr)) - goto fail1; - - evntsel = P4_ESCR_EVENT_SELECT(0x3F) - | P4_ESCR_OS - | P4_ESCR_USR; - - cccr_val |= P4_CCCR_THRESHOLD(15) - | P4_CCCR_COMPLEMENT - | P4_CCCR_COMPARE - | P4_CCCR_REQUIRED; - - wrmsr(evntsel_msr, evntsel, 0); - wrmsr(cccr_msr, cccr_val, 0); - wrmsrl(perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); - apic_write(APIC_LVTPC, APIC_DM_NMI); - cccr_val |= P4_CCCR_ENABLE; - wrmsr(cccr_msr, cccr_val, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = cccr_msr; - wd->check_bit = 1ULL<<39; - return 1; -fail1: - __release_perfctr_nmi(-1, perfctr_msr); -fail: - return 0; -} - -static void stop_p4_watchdog(void) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - wrmsr(wd->cccr_msr, 0, 0); - wrmsr(wd->evntsel_msr, 0, 0); - - __release_evntsel_nmi(-1, wd->evntsel_msr); - __release_perfctr_nmi(-1, wd->perfctr_msr); -} - -#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL -#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK - -static int setup_intel_arch_watchdog(void) -{ - unsigned int ebx; - union cpuid10_eax eax; - unsigned int unused; - unsigned int perfctr_msr, evntsel_msr; - unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - /* - * Check whether the Architectural PerfMon supports - * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebx indicates event present. - */ - cpuid(10, &(eax.full), &ebx, &unused, &unused); - if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || - (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - goto fail; - - perfctr_msr = MSR_ARCH_PERFMON_PERFCTR1; - evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL1; - - if (!__reserve_perfctr_nmi(-1, perfctr_msr)) - goto fail; - - if (!__reserve_evntsel_nmi(-1, evntsel_msr)) - goto fail1; - - wrmsrl(perfctr_msr, 0UL); - - evntsel = ARCH_PERFMON_EVENTSEL_INT - | ARCH_PERFMON_EVENTSEL_OS - | ARCH_PERFMON_EVENTSEL_USR - | ARCH_PERFMON_NMI_EVENT_SEL - | ARCH_PERFMON_NMI_EVENT_UMASK; - - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - - nmi_hz = adjust_for_32bit_ctr(nmi_hz); - wrmsr(perfctr_msr, (u32)(-((u64)cpu_khz * 1000 / nmi_hz)), 0); - - apic_write(APIC_LVTPC, APIC_DM_NMI); - evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - wd->check_bit = 1ULL << (eax.split.bit_width - 1); - return 1; -fail1: - __release_perfctr_nmi(-1, perfctr_msr); -fail: - return 0; -} - -static void stop_intel_arch_watchdog(void) -{ - unsigned int ebx; - union cpuid10_eax eax; - unsigned int unused; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - /* - * Check whether the Architectural PerfMon supports - * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebx indicates event present. - */ - cpuid(10, &(eax.full), &ebx, &unused, &unused); - if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || - (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - return; - - wrmsr(wd->evntsel_msr, 0, 0); - - __release_evntsel_nmi(-1, wd->evntsel_msr); - __release_perfctr_nmi(-1, wd->perfctr_msr); -} - void setup_apic_nmi_watchdog(void *unused) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - /* only support LOCAL and IO APICs for now */ - if ((nmi_watchdog != NMI_LOCAL_APIC) && - (nmi_watchdog != NMI_IO_APIC)) - return; - - if (wd->enabled == 1) + if (__get_cpu_var(wd_enabled) == 1) return; /* cheap hack to support suspend/resume */ @@ -791,62 +255,31 @@ void setup_apic_nmi_watchdog(void *unused) if ((smp_processor_id() != 0) && (atomic_read(&nmi_active) <= 0)) return; - if (nmi_watchdog == NMI_LOCAL_APIC) { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - if (strstr(boot_cpu_data.x86_model_id, "Screwdriver")) - return; - if (!setup_k7_watchdog()) - return; - break; - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - if (!setup_intel_arch_watchdog()) - return; - break; - } - if (!setup_p4_watchdog()) - return; - break; - default: + switch (nmi_watchdog) { + case NMI_LOCAL_APIC: + __get_cpu_var(wd_enabled) = 1; + if (lapic_watchdog_init(nmi_hz) < 0) { + __get_cpu_var(wd_enabled) = 0; return; } + /* FALL THROUGH */ + case NMI_IO_APIC: + __get_cpu_var(wd_enabled) = 1; + atomic_inc(&nmi_active); } - wd->enabled = 1; - atomic_inc(&nmi_active); } void stop_apic_nmi_watchdog(void *unused) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - /* only support LOCAL and IO APICs for now */ if ((nmi_watchdog != NMI_LOCAL_APIC) && (nmi_watchdog != NMI_IO_APIC)) return; - - if (wd->enabled == 0) + if (__get_cpu_var(wd_enabled) == 0) return; - - if (nmi_watchdog == NMI_LOCAL_APIC) { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - if (strstr(boot_cpu_data.x86_model_id, "Screwdriver")) - return; - stop_k7_watchdog(); - break; - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - stop_intel_arch_watchdog(); - break; - } - stop_p4_watchdog(); - break; - default: - return; - } - } - wd->enabled = 0; + if (nmi_watchdog == NMI_LOCAL_APIC) + lapic_watchdog_stop(); + __get_cpu_var(wd_enabled) = 0; atomic_dec(&nmi_active); } @@ -885,9 +318,7 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) int sum; int touched = 0; int cpu = smp_processor_id(); - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - u64 dummy; - int rc=0; + int rc = 0; /* check for other users first */ if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) @@ -934,55 +365,20 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) } /* see if the nmi watchdog went off */ - if (wd->enabled) { - if (nmi_watchdog == NMI_LOCAL_APIC) { - rdmsrl(wd->perfctr_msr, dummy); - if (dummy & wd->check_bit){ - /* this wasn't a watchdog timer interrupt */ - goto done; - } - - /* only Intel uses the cccr msr */ - if (wd->cccr_msr != 0) { - /* - * P4 quirks: - * - An overflown perfctr will assert its interrupt - * until the OVF flag in its CCCR is cleared. - * - LVTPC is masked on interrupt and must be - * unmasked by the LVTPC handler. - */ - rdmsrl(wd->cccr_msr, dummy); - dummy &= ~P4_CCCR_OVF; - wrmsrl(wd->cccr_msr, dummy); - apic_write(APIC_LVTPC, APIC_DM_NMI); - /* start the cycle over again */ - wrmsrl(wd->perfctr_msr, - -((u64)cpu_khz * 1000 / nmi_hz)); - } else if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR1) { - /* - * ArchPerfom/Core Duo needs to re-unmask - * the apic vector - */ - apic_write(APIC_LVTPC, APIC_DM_NMI); - /* ARCH_PERFMON has 32 bit counter writes */ - wrmsr(wd->perfctr_msr, - (u32)(-((u64)cpu_khz * 1000 / nmi_hz)), 0); - } else { - /* start the cycle over again */ - wrmsrl(wd->perfctr_msr, - -((u64)cpu_khz * 1000 / nmi_hz)); - } - rc = 1; - } else if (nmi_watchdog == NMI_IO_APIC) { - /* don't know how to accurately check for this. - * just assume it was a watchdog timer interrupt - * This matches the old behaviour. - */ - rc = 1; - } else - printk(KERN_WARNING "Unknown enabled NMI hardware?!\n"); + if (!__get_cpu_var(wd_enabled)) + return rc; + switch (nmi_watchdog) { + case NMI_LOCAL_APIC: + rc |= lapic_wd_event(nmi_hz); + break; + case NMI_IO_APIC: + /* don't know how to accurately check for this. + * just assume it was a watchdog timer interrupt + * This matches the old behaviour. + */ + rc = 1; + break; } -done: return rc; } @@ -1067,12 +463,4 @@ void __trigger_all_cpu_backtrace(void) EXPORT_SYMBOL(nmi_active); EXPORT_SYMBOL(nmi_watchdog); -EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi); -EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit); -EXPORT_SYMBOL(reserve_perfctr_nmi); -EXPORT_SYMBOL(release_perfctr_nmi); -EXPORT_SYMBOL(reserve_evntsel_nmi); -EXPORT_SYMBOL(release_evntsel_nmi); -EXPORT_SYMBOL(disable_timer_nmi_watchdog); -EXPORT_SYMBOL(enable_timer_nmi_watchdog); EXPORT_SYMBOL(touch_nmi_watchdog); diff --git a/include/asm-x86_64/nmi.h b/include/asm-x86_64/nmi.h index 72375e7d32a8..d0a7f53b1497 100644 --- a/include/asm-x86_64/nmi.h +++ b/include/asm-x86_64/nmi.h @@ -80,4 +80,13 @@ extern int unknown_nmi_panic; void __trigger_all_cpu_backtrace(void); #define trigger_all_cpu_backtrace() __trigger_all_cpu_backtrace() + +void lapic_watchdog_stop(void); +int lapic_watchdog_init(unsigned nmi_hz); +int lapic_wd_event(unsigned nmi_hz); +unsigned lapic_adjust_nmi_hz(unsigned hz); +int lapic_watchdog_ok(void); +void disable_lapic_nmi_watchdog(void); +void enable_lapic_nmi_watchdog(void); + #endif /* ASM_NMI_H */ -- cgit v1.2.3-59-g8ed1b From 4637a74cf2ac3a3696d385c8624d84de789d1bbe Mon Sep 17 00:00:00 2001 From: "David P. Reed" Date: Wed, 2 May 2007 19:27:20 +0200 Subject: [PATCH] x86-64: Avoid overflows during apic timer calibration - Use 64bit TSC calculations to avoid handling overflow - Use 32bit unsigned arithmetic for the APIC timer. This way overflows are handled correctly. - Fix exit check of loop to account for apic timer counting down Signed-off-by: dpreed@reed.com Signed-off-by: Andi Kleen --- arch/x86_64/kernel/apic.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index 943ec4d1bd8e..d198f7d82e5a 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c @@ -839,14 +839,15 @@ static void setup_APIC_timer(unsigned int clocks) static int __init calibrate_APIC_clock(void) { - int apic, apic_start, tsc, tsc_start; + unsigned apic, apic_start; + unsigned long tsc, tsc_start; int result; /* * Put whatever arbitrary (but long enough) timeout * value into the APIC clock, we just want to get the * counter running for calibration. */ - __setup_APIC_LVTT(1000000000); + __setup_APIC_LVTT(4000000000); apic_start = apic_read(APIC_TMCCT); #ifdef CONFIG_X86_PM_TIMER @@ -857,13 +858,13 @@ static int __init calibrate_APIC_clock(void) } else #endif { - rdtscl(tsc_start); + rdtscll(tsc_start); do { apic = apic_read(APIC_TMCCT); - rdtscl(tsc); + rdtscll(tsc); } while ((tsc - tsc_start) < TICK_COUNT && - (apic - apic_start) < TICK_COUNT); + (apic_start - apic) < TICK_COUNT); result = (apic_start - apic) * 1000L * tsc_khz / (tsc - tsc_start); -- cgit v1.2.3-59-g8ed1b From 72b1b1d0133d7eb4040697f1052bf92123fb051b Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:20 +0200 Subject: [PATCH] x86-64: Use symbolic CPU features in early CPUID check Dead to magic numbers! Generated code is the same. Signed-off-by: Andi Kleen --- arch/x86_64/kernel/verify_cpu.S | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/verify_cpu.S b/arch/x86_64/kernel/verify_cpu.S index 72edabd2ef9a..e035f5948199 100644 --- a/arch/x86_64/kernel/verify_cpu.S +++ b/arch/x86_64/kernel/verify_cpu.S @@ -30,18 +30,27 @@ * appropriately. Either display a message or halt. */ -verify_cpu: +#include +verify_cpu: pushfl # Save caller passed flags pushl $0 # Kill any dangerous flags popfl - /* minimum CPUID flags for x86-64 */ - /* see http://www.x86-64.org/lists/discuss/msg02971.html */ -#define SSE_MASK ((1<<25)|(1<<26)) -#define REQUIRED_MASK1 ((1<<0)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<8)|\ - (1<<13)|(1<<15)|(1<<24)) -#define REQUIRED_MASK2 (1<<29) + /* minimum CPUID flags for x86-64 as defined by AMD */ +#define M(x) (1<<(x)) +#define M2(a,b) M(a)|M(b) +#define M4(a,b,c,d) M(a)|M(b)|M(c)|M(d) + +#define SSE_MASK \ + (M2(X86_FEATURE_XMM,X86_FEATURE_XMM2)) +#define REQUIRED_MASK1 \ + (M4(X86_FEATURE_FPU,X86_FEATURE_PSE,X86_FEATURE_TSC,X86_FEATURE_MSR)|\ + M4(X86_FEATURE_PAE,X86_FEATURE_CX8,X86_FEATURE_PGE,X86_FEATURE_CMOV)|\ + M(X86_FEATURE_FXSR)) +#define REQUIRED_MASK2 \ + (M(X86_FEATURE_LM - 32)) + pushfl # standard way to check for cpuid popl %eax movl %eax,%ebx -- cgit v1.2.3-59-g8ed1b From fa0a00910925fdbd3a528404a47817b3a9fda5be Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:20 +0200 Subject: [PATCH] x86-64: Drop -traditional for arch/x86_64/boot Follows i386 and useful cleanup. Signed-off-by: Andi Kleen --- arch/x86_64/boot/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/boot/Makefile b/arch/x86_64/boot/Makefile index deb063e7762d..ee6f6505f95f 100644 --- a/arch/x86_64/boot/Makefile +++ b/arch/x86_64/boot/Makefile @@ -36,7 +36,7 @@ subdir- := compressed/ #Let make clean descend in compressed/ # --------------------------------------------------------------------------- $(obj)/bzImage: IMAGE_OFFSET := 0x100000 -$(obj)/bzImage: EXTRA_AFLAGS := -traditional $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__ +$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__ $(obj)/bzImage: BUILDFLAGS := -b quiet_cmd_image = BUILD $@ -- cgit v1.2.3-59-g8ed1b From 484ad393659f20d784a3a93613fb3fd3d9f171fa Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:20 +0200 Subject: [PATCH] i386: Drop -traditional in arch/i386/boot Needed for followon patch Signed-off-by: Andi Kleen --- arch/i386/boot/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile index e97946626064..bfbc32098a4a 100644 --- a/arch/i386/boot/Makefile +++ b/arch/i386/boot/Makefile @@ -36,9 +36,9 @@ HOSTCFLAGS_build.o := $(LINUXINCLUDE) # --------------------------------------------------------------------------- $(obj)/zImage: IMAGE_OFFSET := 0x1000 -$(obj)/zImage: EXTRA_AFLAGS := -traditional $(SVGA_MODE) $(RAMDISK) +$(obj)/zImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) $(obj)/bzImage: IMAGE_OFFSET := 0x100000 -$(obj)/bzImage: EXTRA_AFLAGS := -traditional $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__ +$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__ $(obj)/bzImage: BUILDFLAGS := -b quiet_cmd_image = BUILD $@ -- cgit v1.2.3-59-g8ed1b From c7f81c9453375d6416658995eafd3397cb9bba1d Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:20 +0200 Subject: [PATCH] i386: Verify important CPUID bits in real mode Check some CPUID bits that are needed for compiler generated early in boot. When the system is still in real mode before changing the VESA BIOS mode it is possible to still display an visible error message on the screen. Similar to x86-64. Includes cleanups from Eric Biederman Signed-off-by: Andi Kleen --- arch/i386/Kconfig.cpu | 22 ++++++++++-- arch/i386/boot/setup.S | 17 ++++++++++ arch/i386/kernel/verify_cpu.S | 65 ++++++++++++++++++++++++++++++++++++ include/asm-i386/cpufeature.h | 3 ++ include/asm-i386/required-features.h | 34 +++++++++++++++++++ 5 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 arch/i386/kernel/verify_cpu.S create mode 100644 include/asm-i386/required-features.h (limited to 'arch') diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu index b1af9f50a143..dce6124cb842 100644 --- a/arch/i386/Kconfig.cpu +++ b/arch/i386/Kconfig.cpu @@ -240,14 +240,19 @@ config X86_L1_CACHE_SHIFT default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 +config X86_XADD + bool + depends on !M386 + default y + config RWSEM_GENERIC_SPINLOCK bool - depends on M386 + depends on !X86_XADD default y config RWSEM_XCHGADD_ALGORITHM bool - depends on !M386 + depends on X86_XADD default y config ARCH_HAS_ILOG2_U32 @@ -331,3 +336,16 @@ config X86_TSC bool depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ default y + +# this should be set for all -march=.. options where the compiler +# generates cmov. +config X86_CMOV + bool + depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7) + default y + +config X86_MINIMUM_CPU_MODEL + int + default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP + default "0" + diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S index b74b7f40b79c..f8b3b9cda2b1 100644 --- a/arch/i386/boot/setup.S +++ b/arch/i386/boot/setup.S @@ -302,7 +302,24 @@ good_sig: loader_panic_mess: .string "Wrong loader, giving up..." +# check minimum cpuid +# we do this here because it is the last place we can actually +# show a user visible error message. Later the video modus +# might be already messed up. loader_ok: + call verify_cpu + testl %eax,%eax + jz cpu_ok + lea cpu_panic_mess,%si + call prtstr +1: jmp 1b + +cpu_panic_mess: + .asciz "PANIC: CPU too old for this kernel." + +#include "../kernel/verify_cpu.S" + +cpu_ok: # Get memory size (extended mem, kB) xorl %eax, %eax diff --git a/arch/i386/kernel/verify_cpu.S b/arch/i386/kernel/verify_cpu.S new file mode 100644 index 000000000000..e51a8695d54e --- /dev/null +++ b/arch/i386/kernel/verify_cpu.S @@ -0,0 +1,65 @@ +/* Check if CPU has some minimum CPUID bits + This runs in 16bit mode so that the caller can still use the BIOS + to output errors on the screen */ +#include + +verify_cpu: + pushfl # Save caller passed flags + pushl $0 # Kill any dangerous flags + popfl + +#if CONFIG_X86_MINIMUM_CPU_MODEL >= 4 + pushfl + orl $(1<<18),(%esp) # try setting AC + popfl + pushfl + popl %eax + testl $(1<<18),%eax + jz bad +#endif +#if REQUIRED_MASK1 != 0 + pushfl # standard way to check for cpuid + popl %eax + movl %eax,%ebx + xorl $0x200000,%eax + pushl %eax + popfl + pushfl + popl %eax + cmpl %eax,%ebx + pushfl # standard way to check for cpuid + popl %eax + movl %eax,%ebx + xorl $0x200000,%eax + pushl %eax + popfl + pushfl + popl %eax + cmpl %eax,%ebx + jz bad # REQUIRED_MASK1 != 0 requires CPUID + + movl $0x0,%eax # See if cpuid 1 is implemented + cpuid + cmpl $0x1,%eax + jb bad # no cpuid 1 + + movl $0x1,%eax # Does the cpu have what it takes + cpuid + +#if CONFIG_X86_MINIMUM_CPU_MODEL > 4 +#error add proper model checking here +#endif + + andl $REQUIRED_MASK1,%edx + xorl $REQUIRED_MASK1,%edx + jnz bad +#endif /* REQUIRED_MASK1 */ + + popfl + xor %eax,%eax + ret + +bad: + popfl + movl $1,%eax + ret diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h index d1b8e4ab6c1a..e66d004aa651 100644 --- a/include/asm-i386/cpufeature.h +++ b/include/asm-i386/cpufeature.h @@ -7,7 +7,10 @@ #ifndef __ASM_I386_CPUFEATURE_H #define __ASM_I386_CPUFEATURE_H +#ifndef __ASSEMBLY__ #include +#endif +#include #define NCAPINTS 7 /* N 32-bit words worth of info */ diff --git a/include/asm-i386/required-features.h b/include/asm-i386/required-features.h new file mode 100644 index 000000000000..9db866c1e64c --- /dev/null +++ b/include/asm-i386/required-features.h @@ -0,0 +1,34 @@ +#ifndef _ASM_REQUIRED_FEATURES_H +#define _ASM_REQUIRED_FEATURES_H 1 + +/* Define minimum CPUID feature set for kernel These bits are checked + really early to actually display a visible error message before the + kernel dies. Only add word 0 bits here + + Some requirements that are not in CPUID yet are also in the + CONFIG_X86_MINIMUM_CPU mode which is checked too. + + The real information is in arch/i386/Kconfig.cpu, this just converts + the CONFIGs into a bitmask */ + +#ifdef CONFIG_X86_PAE +#define NEED_PAE (1< Date: Wed, 2 May 2007 19:27:20 +0200 Subject: [PATCH] i386: Implement X86_FEATURE_SYNC_RDTSC on i386 Syncs up with x86-64. Signed-off-by: Andi Kleen --- arch/i386/kernel/cpu/intel.c | 4 +++- include/asm-i386/cpufeature.h | 1 + include/asm-i386/tsc.h | 4 ---- 3 files changed, 4 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c index 56fe26584957..dc4e08147b1f 100644 --- a/arch/i386/kernel/cpu/intel.c +++ b/arch/i386/kernel/cpu/intel.c @@ -188,8 +188,10 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) } #endif - if (c->x86 == 15) + if (c->x86 == 15) { set_bit(X86_FEATURE_P4, c->x86_capability); + set_bit(X86_FEATURE_SYNC_RDTSC, c->x86_capability); + } if (c->x86 == 6) set_bit(X86_FEATURE_P3, c->x86_capability); if ((c->x86 == 0xf && c->x86_model >= 0x03) || diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h index 20e849ae6ddc..b8a3a5a85fd3 100644 --- a/include/asm-i386/cpufeature.h +++ b/include/asm-i386/cpufeature.h @@ -79,6 +79,7 @@ #define X86_FEATURE_PEBS (3*32+12) /* Precise-Event Based Sampling */ #define X86_FEATURE_BTS (3*32+13) /* Branch Trace Store */ #define X86_FEATURE_LAPIC_TIMER_BROKEN (3*32+ 14) /* lapic timer broken in C1 */ +#define X86_FEATURE_SYNC_RDTSC (3*32+15) /* RDTSC synchronizes the CPU */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ diff --git a/include/asm-i386/tsc.h b/include/asm-i386/tsc.h index 346976632e15..0181f9df7539 100644 --- a/include/asm-i386/tsc.h +++ b/include/asm-i386/tsc.h @@ -35,7 +35,6 @@ static inline cycles_t get_cycles(void) static __always_inline cycles_t get_cycles_sync(void) { unsigned long long ret; -#ifdef X86_FEATURE_SYNC_RDTSC unsigned eax; /* @@ -44,9 +43,6 @@ static __always_inline cycles_t get_cycles_sync(void) */ alternative_io("cpuid", ASM_NOP2, X86_FEATURE_SYNC_RDTSC, "=a" (eax), "0" (1) : "ebx","ecx","edx","memory"); -#else - sync_core(); -#endif rdtscll(ret); return ret; -- cgit v1.2.3-59-g8ed1b From 3bea9c9793a17053e05d970e5d90d48fc9fce07d Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:21 +0200 Subject: [PATCH] x86-64: Don't enable NUMA for a single node in K8 NUMA scanning This was supposed to see the full memory on a ASUS A8SX motherboard with 4GB RAM where the northbridge reports less memory, but it didn't help there. But it's a reasonable change so let's include it anyways. Signed-off-by: Andi Kleen --- arch/x86_64/mm/k8topology.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/mm/k8topology.c b/arch/x86_64/mm/k8topology.c index 60e860e5ef4c..f983c75825d0 100644 --- a/arch/x86_64/mm/k8topology.c +++ b/arch/x86_64/mm/k8topology.c @@ -62,6 +62,8 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end) reg = read_pci_config(0, nb, 0, 0x60); numnodes = ((reg >> 4) & 0xF) + 1; + if (numnodes <= 1) + return -1; printk(KERN_INFO "Number of nodes %d\n", numnodes); -- cgit v1.2.3-59-g8ed1b From ec1180db2ca2ec8692ce101560eff9eedf561781 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:21 +0200 Subject: [PATCH] i386: Little cleanups in smpboot.c - Remove #if that is always set - Fix warning Signed-off-by: Andi Kleen --- arch/i386/kernel/smpboot.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index a768eceeac37..a4b7ad283f49 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -516,7 +516,6 @@ static void unmap_cpu_to_logical_apicid(int cpu) unmap_cpu_to_node(cpu); } -#if APIC_DEBUG static inline void __inquire_remote_apic(int apicid) { int i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 }; @@ -548,14 +547,13 @@ static inline void __inquire_remote_apic(int apicid) switch (status) { case APIC_ICR_RR_VALID: status = apic_read(APIC_RRR); - printk("%08x\n", status); + printk("%lx\n", status); break; default: printk("failed\n"); } } } -#endif #ifdef WAKE_SECONDARY_VIA_NMI /* -- cgit v1.2.3-59-g8ed1b From c812d6c198c5f39a6ea22a9a12d518cd3714af16 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:21 +0200 Subject: [PATCH] i386: Remove copy_*_user BUG_ONs for (size < 0) access_ok checks this case anyways, no need to check twice. Signed-off-by: Andi Kleen --- arch/i386/lib/usercopy.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'arch') diff --git a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c index 086b3726862a..9f38b12b4af1 100644 --- a/arch/i386/lib/usercopy.c +++ b/arch/i386/lib/usercopy.c @@ -716,7 +716,6 @@ do { \ unsigned long __copy_to_user_ll(void __user *to, const void *from, unsigned long n) { - BUG_ON((long) n < 0); #ifndef CONFIG_X86_WP_WORKS_OK if (unlikely(boot_cpu_data.wp_works_ok == 0) && ((unsigned long )to) < TASK_SIZE) { @@ -785,7 +784,6 @@ EXPORT_SYMBOL(__copy_to_user_ll); unsigned long __copy_from_user_ll(void *to, const void __user *from, unsigned long n) { - BUG_ON((long)n < 0); if (movsl_is_ok(to, from, n)) __copy_user_zeroing(to, from, n); else @@ -797,7 +795,6 @@ EXPORT_SYMBOL(__copy_from_user_ll); unsigned long __copy_from_user_ll_nozero(void *to, const void __user *from, unsigned long n) { - BUG_ON((long)n < 0); if (movsl_is_ok(to, from, n)) __copy_user(to, from, n); else @@ -810,7 +807,6 @@ EXPORT_SYMBOL(__copy_from_user_ll_nozero); unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from, unsigned long n) { - BUG_ON((long)n < 0); #ifdef CONFIG_X86_INTEL_USERCOPY if ( n > 64 && cpu_has_xmm2) n = __copy_user_zeroing_intel_nocache(to, from, n); @@ -825,7 +821,6 @@ unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from, unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *from, unsigned long n) { - BUG_ON((long)n < 0); #ifdef CONFIG_X86_INTEL_USERCOPY if ( n > 64 && cpu_has_xmm2) n = __copy_user_intel_nocache(to, from, n); @@ -853,7 +848,6 @@ unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *fr unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) { - BUG_ON((long) n < 0); if (access_ok(VERIFY_WRITE, to, n)) n = __copy_to_user(to, from, n); return n; @@ -879,7 +873,6 @@ EXPORT_SYMBOL(copy_to_user); unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) { - BUG_ON((long) n < 0); if (access_ok(VERIFY_READ, from, n)) n = __copy_from_user(to, from, n); else -- cgit v1.2.3-59-g8ed1b From 2136220d00d84e5dd923f23552f75b1864a76f21 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:21 +0200 Subject: [PATCH] x86-64: Remove CONFIG_REORDER The option never worked well and functionlist wasn't well maintained. Also it made the build very slow on many binutils version. So just remove it. Cc: arjan@linux.intel.com Signed-off-by: Andi Kleen --- arch/x86_64/Kconfig | 8 - arch/x86_64/Makefile | 1 - arch/x86_64/kernel/functionlist | 1284 -------------------------------------- arch/x86_64/kernel/vmlinux.lds.S | 3 - 4 files changed, 1296 deletions(-) delete mode 100644 arch/x86_64/kernel/functionlist (limited to 'arch') diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 715632026073..1cad418373c3 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -660,14 +660,6 @@ config CC_STACKPROTECTOR_ALL source kernel/Kconfig.hz -config REORDER - bool "Function reordering" - default n - help - This option enables the toolchain to reorder functions for a more - optimal TLB usage. If you have pretty much any version of binutils, - this can increase your kernel build time by roughly one minute. - config K8_NB def_bool y depends on AGP_AMD64 || IOMMU || (PCI && NUMA) diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index 803cfcc9b346..29617ae3926d 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile @@ -40,7 +40,6 @@ cflags-y += -m64 cflags-y += -mno-red-zone cflags-y += -mcmodel=kernel cflags-y += -pipe -cflags-kernel-$(CONFIG_REORDER) += -ffunction-sections cflags-y += -Wno-sign-compare cflags-y += -fno-asynchronous-unwind-tables ifneq ($(CONFIG_DEBUG_INFO),y) diff --git a/arch/x86_64/kernel/functionlist b/arch/x86_64/kernel/functionlist deleted file mode 100644 index 7ae18ec12454..000000000000 --- a/arch/x86_64/kernel/functionlist +++ /dev/null @@ -1,1284 +0,0 @@ -*(.text.flush_thread) -*(.text.check_poison_obj) -*(.text.copy_page) -*(.text.__set_personality) -*(.text.gart_map_sg) -*(.text.kmem_cache_free) -*(.text.find_get_page) -*(.text._raw_spin_lock) -*(.text.ide_outb) -*(.text.unmap_vmas) -*(.text.copy_page_range) -*(.text.kprobe_handler) -*(.text.__handle_mm_fault) -*(.text.__d_lookup) -*(.text.copy_user_generic) -*(.text.__link_path_walk) -*(.text.get_page_from_freelist) -*(.text.kmem_cache_alloc) -*(.text.drive_cmd_intr) -*(.text.ia32_setup_sigcontext) -*(.text.huge_pte_offset) -*(.text.do_page_fault) -*(.text.page_remove_rmap) -*(.text.release_pages) -*(.text.ide_end_request) -*(.text.__mutex_lock_slowpath) -*(.text.__find_get_block) -*(.text.kfree) -*(.text.vfs_read) -*(.text._raw_spin_unlock) -*(.text.free_hot_cold_page) -*(.text.fget_light) -*(.text.schedule) -*(.text.memcmp) -*(.text.touch_atime) -*(.text.__might_sleep) -*(.text.__down_read_trylock) -*(.text.arch_pick_mmap_layout) -*(.text.find_vma) -*(.text.__make_request) -*(.text.do_generic_mapping_read) -*(.text.mutex_lock_interruptible) -*(.text.__generic_file_aio_read) -*(.text._atomic_dec_and_lock) -*(.text.__wake_up_bit) -*(.text.add_to_page_cache) -*(.text.cache_alloc_debugcheck_after) -*(.text.vm_normal_page) -*(.text.mutex_debug_check_no_locks_freed) -*(.text.net_rx_action) -*(.text.__find_first_zero_bit) -*(.text.put_page) -*(.text._raw_read_lock) -*(.text.__delay) -*(.text.dnotify_parent) -*(.text.do_path_lookup) -*(.text.do_sync_read) -*(.text.do_lookup) -*(.text.bit_waitqueue) -*(.text.file_read_actor) -*(.text.strncpy_from_user) -*(.text.__pagevec_lru_add_active) -*(.text.fget) -*(.text.dput) -*(.text.__strnlen_user) -*(.text.inotify_inode_queue_event) -*(.text.rw_verify_area) -*(.text.ide_intr) -*(.text.inotify_dentry_parent_queue_event) -*(.text.permission) -*(.text.memscan) -*(.text.hpet_rtc_interrupt) -*(.text.do_mmap_pgoff) -*(.text.current_fs_time) -*(.text.vfs_getattr) -*(.text.kmem_flagcheck) -*(.text.mark_page_accessed) -*(.text.free_pages_and_swap_cache) -*(.text.generic_fillattr) -*(.text.__block_prepare_write) -*(.text.__set_page_dirty_nobuffers) -*(.text.link_path_walk) -*(.text.find_get_pages_tag) -*(.text.ide_do_request) -*(.text.__alloc_pages) -*(.text.generic_permission) -*(.text.mod_page_state_offset) -*(.text.free_pgd_range) -*(.text.generic_file_buffered_write) -*(.text.number) -*(.text.ide_do_rw_disk) -*(.text.__brelse) -*(.text.__mod_page_state_offset) -*(.text.rotate_reclaimable_page) -*(.text.find_vma_prepare) -*(.text.find_vma_prev) -*(.text.lru_cache_add_active) -*(.text.__kmalloc_track_caller) -*(.text.smp_invalidate_interrupt) -*(.text.handle_IRQ_event) -*(.text.__find_get_block_slow) -*(.text.do_wp_page) -*(.text.do_select) -*(.text.set_user_nice) -*(.text.sys_read) -*(.text.do_munmap) -*(.text.csum_partial) -*(.text.__do_softirq) -*(.text.may_open) -*(.text.getname) -*(.text.get_empty_filp) -*(.text.__fput) -*(.text.remove_mapping) -*(.text.filp_ctor) -*(.text.poison_obj) -*(.text.unmap_region) -*(.text.test_set_page_writeback) -*(.text.__do_page_cache_readahead) -*(.text.sock_def_readable) -*(.text.ide_outl) -*(.text.shrink_zone) -*(.text.rb_insert_color) -*(.text.get_request) -*(.text.sys_pread64) -*(.text.spin_bug) -*(.text.ide_outsl) -*(.text.mask_and_ack_8259A) -*(.text.filemap_nopage) -*(.text.page_add_file_rmap) -*(.text.find_lock_page) -*(.text.tcp_poll) -*(.text.__mark_inode_dirty) -*(.text.file_ra_state_init) -*(.text.generic_file_llseek) -*(.text.__pagevec_lru_add) -*(.text.page_cache_readahead) -*(.text.n_tty_receive_buf) -*(.text.zonelist_policy) -*(.text.vma_adjust) -*(.text.test_clear_page_dirty) -*(.text.sync_buffer) -*(.text.do_exit) -*(.text.__bitmap_weight) -*(.text.alloc_pages_current) -*(.text.get_unused_fd) -*(.text.zone_watermark_ok) -*(.text.cpuset_update_task_memory_state) -*(.text.__bitmap_empty) -*(.text.sys_munmap) -*(.text.__inode_dir_notify) -*(.text.__generic_file_aio_write_nolock) -*(.text.__pte_alloc) -*(.text.sys_select) -*(.text.vm_acct_memory) -*(.text.vfs_write) -*(.text.__lru_add_drain) -*(.text.prio_tree_insert) -*(.text.generic_file_aio_read) -*(.text.vma_merge) -*(.text.block_write_full_page) -*(.text.__page_set_anon_rmap) -*(.text.apic_timer_interrupt) -*(.text.release_console_sem) -*(.text.sys_write) -*(.text.sys_brk) -*(.text.dup_mm) -*(.text.read_current_timer) -*(.text.ll_rw_block) -*(.text.blk_rq_map_sg) -*(.text.dbg_userword) -*(.text.__block_commit_write) -*(.text.cache_grow) -*(.text.copy_strings) -*(.text.release_task) -*(.text.do_sync_write) -*(.text.unlock_page) -*(.text.load_elf_binary) -*(.text.__follow_mount) -*(.text.__getblk) -*(.text.do_sys_open) -*(.text.current_kernel_time) -*(.text.call_rcu) -*(.text.write_chan) -*(.text.vsnprintf) -*(.text.dummy_inode_setsecurity) -*(.text.submit_bh) -*(.text.poll_freewait) -*(.text.bio_alloc_bioset) -*(.text.skb_clone) -*(.text.page_waitqueue) -*(.text.__mutex_lock_interruptible_slowpath) -*(.text.get_index) -*(.text.csum_partial_copy_generic) -*(.text.bad_range) -*(.text.remove_vma) -*(.text.cp_new_stat) -*(.text.alloc_arraycache) -*(.text.test_clear_page_writeback) -*(.text.strsep) -*(.text.open_namei) -*(.text._raw_read_unlock) -*(.text.get_vma_policy) -*(.text.__down_write_trylock) -*(.text.find_get_pages) -*(.text.tcp_rcv_established) -*(.text.generic_make_request) -*(.text.__block_write_full_page) -*(.text.cfq_set_request) -*(.text.sys_inotify_init) -*(.text.split_vma) -*(.text.__mod_timer) -*(.text.get_options) -*(.text.vma_link) -*(.text.mpage_writepages) -*(.text.truncate_complete_page) -*(.text.tcp_recvmsg) -*(.text.sigprocmask) -*(.text.filemap_populate) -*(.text.sys_close) -*(.text.inotify_dev_queue_event) -*(.text.do_task_stat) -*(.text.__dentry_open) -*(.text.unlink_file_vma) -*(.text.__pollwait) -*(.text.packet_rcv_spkt) -*(.text.drop_buffers) -*(.text.free_pgtables) -*(.text.generic_file_direct_write) -*(.text.copy_process) -*(.text.netif_receive_skb) -*(.text.dnotify_flush) -*(.text.print_bad_pte) -*(.text.anon_vma_unlink) -*(.text.sys_mprotect) -*(.text.sync_sb_inodes) -*(.text.find_inode_fast) -*(.text.dummy_inode_readlink) -*(.text.putname) -*(.text.init_smp_flush) -*(.text.dbg_redzone2) -*(.text.sk_run_filter) -*(.text.may_expand_vm) -*(.text.generic_file_aio_write) -*(.text.find_next_zero_bit) -*(.text.file_kill) -*(.text.audit_getname) -*(.text.arch_unmap_area_topdown) -*(.text.alloc_page_vma) -*(.text.tcp_transmit_skb) -*(.text.rb_next) -*(.text.dbg_redzone1) -*(.text.generic_file_mmap) -*(.text.vfs_fstat) -*(.text.sys_time) -*(.text.page_lock_anon_vma) -*(.text.get_unmapped_area) -*(.text.remote_llseek) -*(.text.__up_read) -*(.text.fd_install) -*(.text.eventpoll_init_file) -*(.text.dma_alloc_coherent) -*(.text.create_empty_buffers) -*(.text.__mutex_unlock_slowpath) -*(.text.dup_fd) -*(.text.d_alloc) -*(.text.tty_ldisc_try) -*(.text.sys_stime) -*(.text.__rb_rotate_right) -*(.text.d_validate) -*(.text.rb_erase) -*(.text.path_release) -*(.text.memmove) -*(.text.invalidate_complete_page) -*(.text.clear_inode) -*(.text.cache_estimate) -*(.text.alloc_buffer_head) -*(.text.smp_call_function_interrupt) -*(.text.flush_tlb_others) -*(.text.file_move) -*(.text.balance_dirty_pages_ratelimited) -*(.text.vma_prio_tree_add) -*(.text.timespec_trunc) -*(.text.mempool_alloc) -*(.text.iget_locked) -*(.text.d_alloc_root) -*(.text.cpuset_populate_dir) -*(.text.anon_vma_prepare) -*(.text.sys_newstat) -*(.text.alloc_page_interleave) -*(.text.__path_lookup_intent_open) -*(.text.__pagevec_free) -*(.text.inode_init_once) -*(.text.free_vfsmnt) -*(.text.__user_walk_fd) -*(.text.cfq_idle_slice_timer) -*(.text.sys_mmap) -*(.text.sys_llseek) -*(.text.prio_tree_remove) -*(.text.filp_close) -*(.text.file_permission) -*(.text.vma_prio_tree_remove) -*(.text.tcp_ack) -*(.text.nameidata_to_filp) -*(.text.sys_lseek) -*(.text.percpu_counter_mod) -*(.text.igrab) -*(.text.__bread) -*(.text.alloc_inode) -*(.text.filldir) -*(.text.__rb_rotate_left) -*(.text.irq_affinity_write_proc) -*(.text.init_request_from_bio) -*(.text.find_or_create_page) -*(.text.tty_poll) -*(.text.tcp_sendmsg) -*(.text.ide_wait_stat) -*(.text.free_buffer_head) -*(.text.flush_signal_handlers) -*(.text.tcp_v4_rcv) -*(.text.nr_blockdev_pages) -*(.text.locks_remove_flock) -*(.text.__iowrite32_copy) -*(.text.do_filp_open) -*(.text.try_to_release_page) -*(.text.page_add_new_anon_rmap) -*(.text.kmem_cache_size) -*(.text.eth_type_trans) -*(.text.try_to_free_buffers) -*(.text.schedule_tail) -*(.text.proc_lookup) -*(.text.no_llseek) -*(.text.kfree_skbmem) -*(.text.do_wait) -*(.text.do_mpage_readpage) -*(.text.vfs_stat_fd) -*(.text.tty_write) -*(.text.705) -*(.text.sync_page) -*(.text.__remove_shared_vm_struct) -*(.text.__kfree_skb) -*(.text.sock_poll) -*(.text.get_request_wait) -*(.text.do_sigaction) -*(.text.do_brk) -*(.text.tcp_event_data_recv) -*(.text.read_chan) -*(.text.pipe_writev) -*(.text.__emul_lookup_dentry) -*(.text.rtc_get_rtc_time) -*(.text.print_objinfo) -*(.text.file_update_time) -*(.text.do_signal) -*(.text.disable_8259A_irq) -*(.text.blk_queue_bounce) -*(.text.__anon_vma_link) -*(.text.__vma_link) -*(.text.vfs_rename) -*(.text.sys_newlstat) -*(.text.sys_newfstat) -*(.text.sys_mknod) -*(.text.__show_regs) -*(.text.iput) -*(.text.get_signal_to_deliver) -*(.text.flush_tlb_page) -*(.text.debug_mutex_wake_waiter) -*(.text.copy_thread) -*(.text.clear_page_dirty_for_io) -*(.text.buffer_io_error) -*(.text.vfs_permission) -*(.text.truncate_inode_pages_range) -*(.text.sys_recvfrom) -*(.text.remove_suid) -*(.text.mark_buffer_dirty) -*(.text.local_bh_enable) -*(.text.get_zeroed_page) -*(.text.get_vmalloc_info) -*(.text.flush_old_exec) -*(.text.dummy_inode_permission) -*(.text.__bio_add_page) -*(.text.prio_tree_replace) -*(.text.notify_change) -*(.text.mntput_no_expire) -*(.text.fput) -*(.text.__end_that_request_first) -*(.text.wake_up_bit) -*(.text.unuse_mm) -*(.text.shrink_icache_memory) -*(.text.sched_balance_self) -*(.text.__pmd_alloc) -*(.text.pipe_poll) -*(.text.normal_poll) -*(.text.__free_pages) -*(.text.follow_mount) -*(.text.cdrom_start_packet_command) -*(.text.blk_recount_segments) -*(.text.bio_put) -*(.text.__alloc_skb) -*(.text.__wake_up) -*(.text.vm_stat_account) -*(.text.sys_fcntl) -*(.text.sys_fadvise64) -*(.text._raw_write_unlock) -*(.text.__pud_alloc) -*(.text.alloc_page_buffers) -*(.text.vfs_llseek) -*(.text.sockfd_lookup) -*(.text._raw_write_lock) -*(.text.put_compound_page) -*(.text.prune_dcache) -*(.text.pipe_readv) -*(.text.mempool_free) -*(.text.make_ahead_window) -*(.text.lru_add_drain) -*(.text.constant_test_bit) -*(.text.__clear_user) -*(.text.arch_unmap_area) -*(.text.anon_vma_link) -*(.text.sys_chroot) -*(.text.setup_arg_pages) -*(.text.radix_tree_preload) -*(.text.init_rwsem) -*(.text.generic_osync_inode) -*(.text.generic_delete_inode) -*(.text.do_sys_poll) -*(.text.dev_queue_xmit) -*(.text.default_llseek) -*(.text.__writeback_single_inode) -*(.text.vfs_ioctl) -*(.text.__up_write) -*(.text.unix_poll) -*(.text.sys_rt_sigprocmask) -*(.text.sock_recvmsg) -*(.text.recalc_bh_state) -*(.text.__put_unused_fd) -*(.text.process_backlog) -*(.text.locks_remove_posix) -*(.text.lease_modify) -*(.text.expand_files) -*(.text.end_buffer_read_nobh) -*(.text.d_splice_alias) -*(.text.debug_mutex_init_waiter) -*(.text.copy_from_user) -*(.text.cap_vm_enough_memory) -*(.text.show_vfsmnt) -*(.text.release_sock) -*(.text.pfifo_fast_enqueue) -*(.text.half_md4_transform) -*(.text.fs_may_remount_ro) -*(.text.do_fork) -*(.text.copy_hugetlb_page_range) -*(.text.cache_free_debugcheck) -*(.text.__tcp_select_window) -*(.text.task_handoff_register) -*(.text.sys_open) -*(.text.strlcpy) -*(.text.skb_copy_datagram_iovec) -*(.text.set_up_list3s) -*(.text.release_open_intent) -*(.text.qdisc_restart) -*(.text.n_tty_chars_in_buffer) -*(.text.inode_change_ok) -*(.text.__downgrade_write) -*(.text.debug_mutex_unlock) -*(.text.add_timer_randomness) -*(.text.sock_common_recvmsg) -*(.text.set_bh_page) -*(.text.printk_lock) -*(.text.path_release_on_umount) -*(.text.ip_output) -*(.text.ide_build_dmatable) -*(.text.__get_user_8) -*(.text.end_buffer_read_sync) -*(.text.__d_path) -*(.text.d_move) -*(.text.del_timer) -*(.text.constant_test_bit) -*(.text.blockable_page_cache_readahead) -*(.text.tty_read) -*(.text.sys_readlink) -*(.text.sys_faccessat) -*(.text.read_swap_cache_async) -*(.text.pty_write_room) -*(.text.page_address_in_vma) -*(.text.kthread) -*(.text.cfq_exit_io_context) -*(.text.__tcp_push_pending_frames) -*(.text.sys_pipe) -*(.text.submit_bio) -*(.text.pid_revalidate) -*(.text.page_referenced_file) -*(.text.lock_sock) -*(.text.get_page_state_node) -*(.text.generic_block_bmap) -*(.text.do_setitimer) -*(.text.dev_queue_xmit_nit) -*(.text.copy_from_read_buf) -*(.text.__const_udelay) -*(.text.console_conditional_schedule) -*(.text.wake_up_new_task) -*(.text.wait_for_completion_interruptible) -*(.text.tcp_rcv_rtt_update) -*(.text.sys_mlockall) -*(.text.set_fs_altroot) -*(.text.schedule_timeout) -*(.text.nr_free_pagecache_pages) -*(.text.nf_iterate) -*(.text.mapping_tagged) -*(.text.ip_queue_xmit) -*(.text.ip_local_deliver) -*(.text.follow_page) -*(.text.elf_map) -*(.text.dummy_file_permission) -*(.text.dispose_list) -*(.text.dentry_open) -*(.text.dentry_iput) -*(.text.bio_alloc) -*(.text.wait_on_page_bit) -*(.text.vfs_readdir) -*(.text.vfs_lstat) -*(.text.seq_escape) -*(.text.__posix_lock_file) -*(.text.mm_release) -*(.text.kref_put) -*(.text.ip_rcv) -*(.text.__iget) -*(.text.free_pages) -*(.text.find_mergeable_anon_vma) -*(.text.find_extend_vma) -*(.text.dummy_inode_listsecurity) -*(.text.bio_add_page) -*(.text.__vm_enough_memory) -*(.text.vfs_stat) -*(.text.tty_paranoia_check) -*(.text.tcp_read_sock) -*(.text.tcp_data_queue) -*(.text.sys_uname) -*(.text.sys_renameat) -*(.text.__strncpy_from_user) -*(.text.__mutex_init) -*(.text.__lookup_hash) -*(.text.kref_get) -*(.text.ip_route_input) -*(.text.__insert_inode_hash) -*(.text.do_sock_write) -*(.text.blk_done_softirq) -*(.text.__wake_up_sync) -*(.text.__vma_link_rb) -*(.text.tty_ioctl) -*(.text.tracesys) -*(.text.sys_getdents) -*(.text.sys_dup) -*(.text.stub_execve) -*(.text.sha_transform) -*(.text.radix_tree_tag_clear) -*(.text.put_unused_fd) -*(.text.put_files_struct) -*(.text.mpage_readpages) -*(.text.may_delete) -*(.text.kmem_cache_create) -*(.text.ip_mc_output) -*(.text.interleave_nodes) -*(.text.groups_search) -*(.text.generic_drop_inode) -*(.text.generic_commit_write) -*(.text.fcntl_setlk) -*(.text.exit_mmap) -*(.text.end_page_writeback) -*(.text.__d_rehash) -*(.text.debug_mutex_free_waiter) -*(.text.csum_ipv6_magic) -*(.text.count) -*(.text.cleanup_rbuf) -*(.text.check_spinlock_acquired_node) -*(.text.can_vma_merge_after) -*(.text.bio_endio) -*(.text.alloc_pidmap) -*(.text.write_ldt) -*(.text.vmtruncate_range) -*(.text.vfs_create) -*(.text.__user_walk) -*(.text.update_send_head) -*(.text.unmap_underlying_metadata) -*(.text.tty_ldisc_deref) -*(.text.tcp_setsockopt) -*(.text.tcp_send_ack) -*(.text.sys_pause) -*(.text.sys_gettimeofday) -*(.text.sync_dirty_buffer) -*(.text.strncmp) -*(.text.release_posix_timer) -*(.text.proc_file_read) -*(.text.prepare_to_wait) -*(.text.locks_mandatory_locked) -*(.text.interruptible_sleep_on_timeout) -*(.text.inode_sub_bytes) -*(.text.in_group_p) -*(.text.hrtimer_try_to_cancel) -*(.text.filldir64) -*(.text.fasync_helper) -*(.text.dummy_sb_pivotroot) -*(.text.d_lookup) -*(.text.d_instantiate) -*(.text.__d_find_alias) -*(.text.cpu_idle_wait) -*(.text.cond_resched_lock) -*(.text.chown_common) -*(.text.blk_congestion_wait) -*(.text.activate_page) -*(.text.unlock_buffer) -*(.text.tty_wakeup) -*(.text.tcp_v4_do_rcv) -*(.text.tcp_current_mss) -*(.text.sys_openat) -*(.text.sys_fchdir) -*(.text.strnlen_user) -*(.text.strnlen) -*(.text.strchr) -*(.text.sock_common_getsockopt) -*(.text.skb_checksum) -*(.text.remove_wait_queue) -*(.text.rb_replace_node) -*(.text.radix_tree_node_ctor) -*(.text.pty_chars_in_buffer) -*(.text.profile_hit) -*(.text.prio_tree_left) -*(.text.pgd_clear_bad) -*(.text.pfifo_fast_dequeue) -*(.text.page_referenced) -*(.text.open_exec) -*(.text.mmput) -*(.text.mm_init) -*(.text.__ide_dma_off_quietly) -*(.text.ide_dma_intr) -*(.text.hrtimer_start) -*(.text.get_io_context) -*(.text.__get_free_pages) -*(.text.find_first_zero_bit) -*(.text.file_free_rcu) -*(.text.dummy_socket_sendmsg) -*(.text.do_unlinkat) -*(.text.do_arch_prctl) -*(.text.destroy_inode) -*(.text.can_vma_merge_before) -*(.text.block_sync_page) -*(.text.block_prepare_write) -*(.text.bio_init) -*(.text.arch_ptrace) -*(.text.wake_up_inode) -*(.text.wait_on_retry_sync_kiocb) -*(.text.vma_prio_tree_next) -*(.text.tcp_rcv_space_adjust) -*(.text.__tcp_ack_snd_check) -*(.text.sys_utime) -*(.text.sys_recvmsg) -*(.text.sys_mremap) -*(.text.sys_bdflush) -*(.text.sleep_on) -*(.text.set_page_dirty_lock) -*(.text.seq_path) -*(.text.schedule_timeout_interruptible) -*(.text.sched_fork) -*(.text.rt_run_flush) -*(.text.profile_munmap) -*(.text.prepare_binprm) -*(.text.__pagevec_release_nonlru) -*(.text.m_show) -*(.text.lookup_mnt) -*(.text.__lookup_mnt) -*(.text.lock_timer_base) -*(.text.is_subdir) -*(.text.invalidate_bh_lru) -*(.text.init_buffer_head) -*(.text.ifind_fast) -*(.text.ide_dma_start) -*(.text.__get_page_state) -*(.text.flock_to_posix_lock) -*(.text.__find_symbol) -*(.text.do_futex) -*(.text.do_execve) -*(.text.dirty_writeback_centisecs_handler) -*(.text.dev_watchdog) -*(.text.can_share_swap_page) -*(.text.blkdev_put) -*(.text.bio_get_nr_vecs) -*(.text.xfrm_compile_policy) -*(.text.vma_prio_tree_insert) -*(.text.vfs_lstat_fd) -*(.text.__user_path_lookup_open) -*(.text.thread_return) -*(.text.tcp_send_delayed_ack) -*(.text.sock_def_error_report) -*(.text.shrink_slab) -*(.text.serial_out) -*(.text.seq_read) -*(.text.secure_ip_id) -*(.text.search_binary_handler) -*(.text.proc_pid_unhash) -*(.text.pagevec_lookup) -*(.text.new_inode) -*(.text.memcpy_toiovec) -*(.text.locks_free_lock) -*(.text.__lock_page) -*(.text.__lock_buffer) -*(.text.load_module) -*(.text.is_bad_inode) -*(.text.invalidate_inode_buffers) -*(.text.insert_vm_struct) -*(.text.inode_setattr) -*(.text.inode_add_bytes) -*(.text.ide_read_24) -*(.text.ide_get_error_location) -*(.text.ide_do_drive_cmd) -*(.text.get_locked_pte) -*(.text.get_filesystem_list) -*(.text.generic_file_open) -*(.text.follow_down) -*(.text.find_next_bit) -*(.text.__find_first_bit) -*(.text.exit_mm) -*(.text.exec_keys) -*(.text.end_buffer_write_sync) -*(.text.end_bio_bh_io_sync) -*(.text.dummy_socket_shutdown) -*(.text.d_rehash) -*(.text.d_path) -*(.text.do_ioctl) -*(.text.dget_locked) -*(.text.copy_thread_group_keys) -*(.text.cdrom_end_request) -*(.text.cap_bprm_apply_creds) -*(.text.blk_rq_bio_prep) -*(.text.__bitmap_intersects) -*(.text.bio_phys_segments) -*(.text.bio_free) -*(.text.arch_get_unmapped_area_topdown) -*(.text.writeback_in_progress) -*(.text.vfs_follow_link) -*(.text.tcp_rcv_state_process) -*(.text.tcp_check_space) -*(.text.sys_stat) -*(.text.sys_rt_sigreturn) -*(.text.sys_rt_sigaction) -*(.text.sys_remap_file_pages) -*(.text.sys_pwrite64) -*(.text.sys_fchownat) -*(.text.sys_fchmodat) -*(.text.strncat) -*(.text.strlcat) -*(.text.strcmp) -*(.text.steal_locks) -*(.text.sock_create) -*(.text.sk_stream_rfree) -*(.text.sk_stream_mem_schedule) -*(.text.skip_atoi) -*(.text.sk_alloc) -*(.text.show_stat) -*(.text.set_fs_pwd) -*(.text.set_binfmt) -*(.text.pty_unthrottle) -*(.text.proc_symlink) -*(.text.pipe_release) -*(.text.pageout) -*(.text.n_tty_write_wakeup) -*(.text.n_tty_ioctl) -*(.text.nr_free_zone_pages) -*(.text.migration_thread) -*(.text.mempool_free_slab) -*(.text.meminfo_read_proc) -*(.text.max_sane_readahead) -*(.text.lru_cache_add) -*(.text.kill_fasync) -*(.text.kernel_read) -*(.text.invalidate_mapping_pages) -*(.text.inode_has_buffers) -*(.text.init_once) -*(.text.inet_sendmsg) -*(.text.idedisk_issue_flush) -*(.text.generic_file_write) -*(.text.free_more_memory) -*(.text.__free_fdtable) -*(.text.filp_dtor) -*(.text.exit_sem) -*(.text.exit_itimers) -*(.text.error_interrupt) -*(.text.end_buffer_async_write) -*(.text.eligible_child) -*(.text.elf_map) -*(.text.dump_task_regs) -*(.text.dummy_task_setscheduler) -*(.text.dummy_socket_accept) -*(.text.dummy_file_free_security) -*(.text.__down_read) -*(.text.do_sock_read) -*(.text.do_sigaltstack) -*(.text.do_mremap) -*(.text.current_io_context) -*(.text.cpu_swap_callback) -*(.text.copy_vma) -*(.text.cap_bprm_set_security) -*(.text.blk_insert_request) -*(.text.bio_map_kern_endio) -*(.text.bio_hw_segments) -*(.text.bictcp_cong_avoid) -*(.text.add_interrupt_randomness) -*(.text.wait_for_completion) -*(.text.version_read_proc) -*(.text.unix_write_space) -*(.text.tty_ldisc_ref_wait) -*(.text.tty_ldisc_put) -*(.text.try_to_wake_up) -*(.text.tcp_v4_tw_remember_stamp) -*(.text.tcp_try_undo_dsack) -*(.text.tcp_may_send_now) -*(.text.sys_waitid) -*(.text.sys_sched_getparam) -*(.text.sys_getppid) -*(.text.sys_getcwd) -*(.text.sys_dup2) -*(.text.sys_chmod) -*(.text.sys_chdir) -*(.text.sprintf) -*(.text.sock_wfree) -*(.text.sock_aio_write) -*(.text.skb_drop_fraglist) -*(.text.skb_dequeue) -*(.text.set_close_on_exec) -*(.text.set_brk) -*(.text.seq_puts) -*(.text.SELECT_DRIVE) -*(.text.sched_exec) -*(.text.return_EIO) -*(.text.remove_from_page_cache) -*(.text.rcu_start_batch) -*(.text.__put_task_struct) -*(.text.proc_pid_readdir) -*(.text.proc_get_inode) -*(.text.prepare_to_wait_exclusive) -*(.text.pipe_wait) -*(.text.pipe_new) -*(.text.pdflush_operation) -*(.text.__pagevec_release) -*(.text.pagevec_lookup_tag) -*(.text.packet_rcv) -*(.text.n_tty_set_room) -*(.text.nr_free_pages) -*(.text.__net_timestamp) -*(.text.mpage_end_io_read) -*(.text.mod_timer) -*(.text.__memcpy) -*(.text.mb_cache_shrink_fn) -*(.text.lock_rename) -*(.text.kstrdup) -*(.text.is_ignored) -*(.text.int_very_careful) -*(.text.inotify_inode_is_dead) -*(.text.inotify_get_cookie) -*(.text.inode_get_bytes) -*(.text.init_timer) -*(.text.init_dev) -*(.text.inet_getname) -*(.text.ide_map_sg) -*(.text.__ide_dma_end) -*(.text.hrtimer_get_remaining) -*(.text.get_task_mm) -*(.text.get_random_int) -*(.text.free_pipe_info) -*(.text.filemap_write_and_wait_range) -*(.text.exit_thread) -*(.text.enter_idle) -*(.text.end_that_request_first) -*(.text.end_8259A_irq) -*(.text.dummy_file_alloc_security) -*(.text.do_group_exit) -*(.text.debug_mutex_init) -*(.text.cpuset_exit) -*(.text.cpu_idle) -*(.text.copy_semundo) -*(.text.copy_files) -*(.text.chrdev_open) -*(.text.cdrom_transfer_packet_command) -*(.text.cdrom_mode_sense) -*(.text.blk_phys_contig_segment) -*(.text.blk_get_queue) -*(.text.bio_split) -*(.text.audit_alloc) -*(.text.anon_pipe_buf_release) -*(.text.add_wait_queue_exclusive) -*(.text.add_wait_queue) -*(.text.acct_process) -*(.text.account) -*(.text.zeromap_page_range) -*(.text.yield) -*(.text.writeback_acquire) -*(.text.worker_thread) -*(.text.wait_on_page_writeback_range) -*(.text.__wait_on_buffer) -*(.text.vscnprintf) -*(.text.vmalloc_to_pfn) -*(.text.vgacon_save_screen) -*(.text.vfs_unlink) -*(.text.vfs_rmdir) -*(.text.unregister_md_personality) -*(.text.unlock_new_inode) -*(.text.unix_stream_sendmsg) -*(.text.unix_stream_recvmsg) -*(.text.unhash_process) -*(.text.udp_v4_lookup_longway) -*(.text.tty_ldisc_flush) -*(.text.tty_ldisc_enable) -*(.text.tty_hung_up_p) -*(.text.tty_buffer_free_all) -*(.text.tso_fragment) -*(.text.try_to_del_timer_sync) -*(.text.tcp_v4_err) -*(.text.tcp_unhash) -*(.text.tcp_seq_next) -*(.text.tcp_select_initial_window) -*(.text.tcp_sacktag_write_queue) -*(.text.tcp_cwnd_validate) -*(.text.sys_vhangup) -*(.text.sys_uselib) -*(.text.sys_symlink) -*(.text.sys_signal) -*(.text.sys_poll) -*(.text.sys_mount) -*(.text.sys_kill) -*(.text.sys_ioctl) -*(.text.sys_inotify_add_watch) -*(.text.sys_getuid) -*(.text.sys_getrlimit) -*(.text.sys_getitimer) -*(.text.sys_getgroups) -*(.text.sys_ftruncate) -*(.text.sysfs_lookup) -*(.text.sys_exit_group) -*(.text.stub_fork) -*(.text.sscanf) -*(.text.sock_map_fd) -*(.text.sock_get_timestamp) -*(.text.__sock_create) -*(.text.smp_call_function_single) -*(.text.sk_stop_timer) -*(.text.skb_copy_and_csum_datagram) -*(.text.__skb_checksum_complete) -*(.text.single_next) -*(.text.sigqueue_alloc) -*(.text.shrink_dcache_parent) -*(.text.select_idle_routine) -*(.text.run_workqueue) -*(.text.run_local_timers) -*(.text.remove_inode_hash) -*(.text.remove_dquot_ref) -*(.text.register_binfmt) -*(.text.read_cache_pages) -*(.text.rb_last) -*(.text.pty_open) -*(.text.proc_root_readdir) -*(.text.proc_pid_flush) -*(.text.proc_pident_lookup) -*(.text.proc_fill_super) -*(.text.proc_exe_link) -*(.text.posix_locks_deadlock) -*(.text.pipe_iov_copy_from_user) -*(.text.opost) -*(.text.nf_register_hook) -*(.text.netif_rx_ni) -*(.text.m_start) -*(.text.mpage_writepage) -*(.text.mm_alloc) -*(.text.memory_open) -*(.text.mark_buffer_async_write) -*(.text.lru_add_drain_all) -*(.text.locks_init_lock) -*(.text.locks_delete_lock) -*(.text.lock_hrtimer_base) -*(.text.load_script) -*(.text.__kill_fasync) -*(.text.ip_mc_sf_allow) -*(.text.__ioremap) -*(.text.int_with_check) -*(.text.int_sqrt) -*(.text.install_thread_keyring) -*(.text.init_page_buffers) -*(.text.inet_sock_destruct) -*(.text.idle_notifier_register) -*(.text.ide_execute_command) -*(.text.ide_end_drive_cmd) -*(.text.__ide_dma_host_on) -*(.text.hrtimer_run_queues) -*(.text.hpet_mask_rtc_irq_bit) -*(.text.__get_zone_counts) -*(.text.get_zone_counts) -*(.text.get_write_access) -*(.text.get_fs_struct) -*(.text.get_dirty_limits) -*(.text.generic_readlink) -*(.text.free_hot_page) -*(.text.finish_wait) -*(.text.find_inode) -*(.text.find_first_bit) -*(.text.__filemap_fdatawrite_range) -*(.text.__filemap_copy_from_user_iovec) -*(.text.exit_aio) -*(.text.elv_set_request) -*(.text.elv_former_request) -*(.text.dup_namespace) -*(.text.dupfd) -*(.text.dummy_socket_getsockopt) -*(.text.dummy_sb_post_mountroot) -*(.text.dummy_quotactl) -*(.text.dummy_inode_rename) -*(.text.__do_SAK) -*(.text.do_pipe) -*(.text.do_fsync) -*(.text.d_instantiate_unique) -*(.text.d_find_alias) -*(.text.deny_write_access) -*(.text.dentry_unhash) -*(.text.d_delete) -*(.text.datagram_poll) -*(.text.cpuset_fork) -*(.text.cpuid_read) -*(.text.copy_namespace) -*(.text.cond_resched) -*(.text.check_version) -*(.text.__change_page_attr) -*(.text.cfq_slab_kill) -*(.text.cfq_completed_request) -*(.text.cdrom_pc_intr) -*(.text.cdrom_decode_status) -*(.text.cap_capset_check) -*(.text.blk_put_request) -*(.text.bio_fs_destructor) -*(.text.bictcp_min_cwnd) -*(.text.alloc_chrdev_region) -*(.text.add_element) -*(.text.acct_update_integrals) -*(.text.write_boundary_block) -*(.text.writeback_release) -*(.text.writeback_inodes) -*(.text.wake_up_state) -*(.text.__wake_up_locked) -*(.text.wake_futex) -*(.text.wait_task_inactive) -*(.text.__wait_on_freeing_inode) -*(.text.wait_noreap_copyout) -*(.text.vmstat_start) -*(.text.vgacon_do_font_op) -*(.text.vfs_readv) -*(.text.vfs_quota_sync) -*(.text.update_queue) -*(.text.unshare_files) -*(.text.unmap_vm_area) -*(.text.unix_socketpair) -*(.text.unix_release_sock) -*(.text.unix_detach_fds) -*(.text.unix_create1) -*(.text.unix_bind) -*(.text.udp_sendmsg) -*(.text.udp_rcv) -*(.text.udp_queue_rcv_skb) -*(.text.uart_write) -*(.text.uart_startup) -*(.text.uart_open) -*(.text.tty_vhangup) -*(.text.tty_termios_baud_rate) -*(.text.tty_release) -*(.text.tty_ldisc_ref) -*(.text.throttle_vm_writeout) -*(.text.058) -*(.text.tcp_xmit_probe_skb) -*(.text.tcp_v4_send_check) -*(.text.tcp_v4_destroy_sock) -*(.text.tcp_sync_mss) -*(.text.tcp_snd_test) -*(.text.tcp_slow_start) -*(.text.tcp_send_fin) -*(.text.tcp_rtt_estimator) -*(.text.tcp_parse_options) -*(.text.tcp_ioctl) -*(.text.tcp_init_tso_segs) -*(.text.tcp_init_cwnd) -*(.text.tcp_getsockopt) -*(.text.tcp_fin) -*(.text.tcp_connect) -*(.text.tcp_cong_avoid) -*(.text.__tcp_checksum_complete_user) -*(.text.task_dumpable) -*(.text.sys_wait4) -*(.text.sys_utimes) -*(.text.sys_symlinkat) -*(.text.sys_socketpair) -*(.text.sys_rmdir) -*(.text.sys_readahead) -*(.text.sys_nanosleep) -*(.text.sys_linkat) -*(.text.sys_fstat) -*(.text.sysfs_readdir) -*(.text.sys_execve) -*(.text.sysenter_tracesys) -*(.text.sys_chown) -*(.text.stub_clone) -*(.text.strrchr) -*(.text.strncpy) -*(.text.stopmachine_set_state) -*(.text.sock_sendmsg) -*(.text.sock_release) -*(.text.sock_fasync) -*(.text.sock_close) -*(.text.sk_stream_write_space) -*(.text.sk_reset_timer) -*(.text.skb_split) -*(.text.skb_recv_datagram) -*(.text.skb_queue_tail) -*(.text.sk_attach_filter) -*(.text.si_swapinfo) -*(.text.simple_strtoll) -*(.text.set_termios) -*(.text.set_task_comm) -*(.text.set_shrinker) -*(.text.set_normalized_timespec) -*(.text.set_brk) -*(.text.serial_in) -*(.text.seq_printf) -*(.text.secure_dccp_sequence_number) -*(.text.rwlock_bug) -*(.text.rt_hash_code) -*(.text.__rta_fill) -*(.text.__request_resource) -*(.text.relocate_new_kernel) -*(.text.release_thread) -*(.text.release_mem) -*(.text.rb_prev) -*(.text.rb_first) -*(.text.random_poll) -*(.text.__put_super_and_need_restart) -*(.text.pty_write) -*(.text.ptrace_stop) -*(.text.proc_self_readlink) -*(.text.proc_root_lookup) -*(.text.proc_root_link) -*(.text.proc_pid_make_inode) -*(.text.proc_pid_attr_write) -*(.text.proc_lookupfd) -*(.text.proc_delete_inode) -*(.text.posix_same_owner) -*(.text.posix_block_lock) -*(.text.poll_initwait) -*(.text.pipe_write) -*(.text.pipe_read_fasync) -*(.text.pipe_ioctl) -*(.text.pdflush) -*(.text.pci_user_read_config_dword) -*(.text.page_readlink) -*(.text.null_lseek) -*(.text.nf_hook_slow) -*(.text.netlink_sock_destruct) -*(.text.netlink_broadcast) -*(.text.neigh_resolve_output) -*(.text.name_to_int) -*(.text.mwait_idle) -*(.text.mutex_trylock) -*(.text.mutex_debug_check_no_locks_held) -*(.text.m_stop) -*(.text.mpage_end_io_write) -*(.text.mpage_alloc) -*(.text.move_page_tables) -*(.text.mounts_open) -*(.text.__memset) -*(.text.memcpy_fromiovec) -*(.text.make_8259A_irq) -*(.text.lookup_user_key_possessed) -*(.text.lookup_create) -*(.text.locks_insert_lock) -*(.text.locks_alloc_lock) -*(.text.kthread_should_stop) -*(.text.kswapd) -*(.text.kobject_uevent) -*(.text.kobject_get_path) -*(.text.kobject_get) -*(.text.klist_children_put) -*(.text.__ip_route_output_key) -*(.text.ip_flush_pending_frames) -*(.text.ip_compute_csum) -*(.text.ip_append_data) -*(.text.ioc_set_batching) -*(.text.invalidate_inode_pages) -*(.text.__invalidate_device) -*(.text.install_arg_page) -*(.text.in_sched_functions) -*(.text.inotify_unmount_inodes) -*(.text.init_once) -*(.text.init_cdrom_command) -*(.text.inet_stream_connect) -*(.text.inet_sk_rebuild_header) -*(.text.inet_csk_addr2sockaddr) -*(.text.inet_create) -*(.text.ifind) -*(.text.ide_setup_dma) -*(.text.ide_outsw) -*(.text.ide_fixstring) -*(.text.ide_dma_setup) -*(.text.ide_cdrom_packet) -*(.text.ide_cd_put) -*(.text.ide_build_sglist) -*(.text.i8259A_shutdown) -*(.text.hung_up_tty_ioctl) -*(.text.hrtimer_nanosleep) -*(.text.hrtimer_init) -*(.text.hrtimer_cancel) -*(.text.hash_futex) -*(.text.group_send_sig_info) -*(.text.grab_cache_page_nowait) -*(.text.get_wchan) -*(.text.get_stack) -*(.text.get_page_state) -*(.text.getnstimeofday) -*(.text.get_node) -*(.text.get_kprobe) -*(.text.generic_unplug_device) -*(.text.free_task) -*(.text.frag_show) -*(.text.find_next_zero_string) -*(.text.filp_open) -*(.text.fillonedir) -*(.text.exit_io_context) -*(.text.exit_idle) -*(.text.exact_lock) -*(.text.eth_header) -*(.text.dummy_unregister_security) -*(.text.dummy_socket_post_create) -*(.text.dummy_socket_listen) -*(.text.dummy_quota_on) -*(.text.dummy_inode_follow_link) -*(.text.dummy_file_receive) -*(.text.dummy_file_mprotect) -*(.text.dummy_file_lock) -*(.text.dummy_file_ioctl) -*(.text.dummy_bprm_post_apply_creds) -*(.text.do_writepages) -*(.text.__down_interruptible) -*(.text.do_notify_resume) -*(.text.do_acct_process) -*(.text.del_timer_sync) -*(.text.default_rebuild_header) -*(.text.d_callback) -*(.text.dcache_readdir) -*(.text.ctrl_dumpfamily) -*(.text.cpuset_rmdir) -*(.text.copy_strings_kernel) -*(.text.con_write_room) -*(.text.complete_all) -*(.text.collect_sigign_sigcatch) -*(.text.clear_user) -*(.text.check_unthrottle) -*(.text.cdrom_release) -*(.text.cdrom_newpc_intr) -*(.text.cdrom_ioctl) -*(.text.cdrom_check_status) -*(.text.cdev_put) -*(.text.cdev_add) -*(.text.cap_ptrace) -*(.text.cap_bprm_secureexec) -*(.text.cache_alloc_refill) -*(.text.bmap) -*(.text.blk_run_queue) -*(.text.blk_queue_dma_alignment) -*(.text.blk_ordered_req_seq) -*(.text.blk_backing_dev_unplug) -*(.text.__bitmap_subset) -*(.text.__bitmap_and) -*(.text.bio_unmap_user) -*(.text.__bforget) -*(.text.bd_forget) -*(.text.bad_pipe_w) -*(.text.bad_get_user) -*(.text.audit_free) -*(.text.anon_vma_ctor) -*(.text.anon_pipe_buf_map) -*(.text.alloc_sock_iocb) -*(.text.alloc_fdset) -*(.text.aio_kick_handler) -*(.text.__add_entropy_words) -*(.text.add_disk_randomness) diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 32e427a95ffd..88cfa50b424d 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -30,9 +30,6 @@ SECTIONS /* First the code that has to be first for bootstrapping */ *(.bootstrap.text) _stext = .; - /* Then all the functions that are "hot" in profiles, to group them - onto the same hugetlb entry */ - #include "functionlist" /* Then the rest */ *(.text) SCHED_TEXT -- cgit v1.2.3-59-g8ed1b From fac15a8e4d4c36eb4676bfd2c30ea16ad05c401a Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:21 +0200 Subject: [PATCH] x86-64: Share identical video.S between i386 and x86-64 Signed-off-by: Andi Kleen --- arch/x86_64/boot/setup.S | 2 +- arch/x86_64/boot/video.S | 2043 ---------------------------------------------- 2 files changed, 1 insertion(+), 2044 deletions(-) delete mode 100644 arch/x86_64/boot/video.S (limited to 'arch') diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S index 4f8851000d7e..e9e33f949697 100644 --- a/arch/x86_64/boot/setup.S +++ b/arch/x86_64/boot/setup.S @@ -807,7 +807,7 @@ gdt_48: # Include video setup & detection code -#include "video.S" +#include "../../i386/boot/video.S" # Setup signature -- must be last setup_sig1: .word SIG1 diff --git a/arch/x86_64/boot/video.S b/arch/x86_64/boot/video.S deleted file mode 100644 index 8143c9516cb4..000000000000 --- a/arch/x86_64/boot/video.S +++ /dev/null @@ -1,2043 +0,0 @@ -/* video.S - * - * Display adapter & video mode setup, version 2.13 (14-May-99) - * - * Copyright (C) 1995 -- 1998 Martin Mares - * Based on the original setup.S code (C) Linus Torvalds and Mats Anderson - * - * Rewritten to use GNU 'as' by Chris Noe May 1999 - * - * For further information, look at Documentation/svga.txt. - * - */ - -/* Enable autodetection of SVGA adapters and modes. */ -#undef CONFIG_VIDEO_SVGA - -/* Enable autodetection of VESA modes */ -#define CONFIG_VIDEO_VESA - -/* Enable compacting of mode table */ -#define CONFIG_VIDEO_COMPACT - -/* Retain screen contents when switching modes */ -#define CONFIG_VIDEO_RETAIN - -/* Enable local mode list */ -#undef CONFIG_VIDEO_LOCAL - -/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */ -#undef CONFIG_VIDEO_400_HACK - -/* Hack that lets you force specific BIOS mode ID and specific dimensions */ -#undef CONFIG_VIDEO_GFX_HACK -#define VIDEO_GFX_BIOS_AX 0x4f02 /* 800x600 on ThinkPad */ -#define VIDEO_GFX_BIOS_BX 0x0102 -#define VIDEO_GFX_DUMMY_RESOLUTION 0x6425 /* 100x37 */ - -/* This code uses an extended set of video mode numbers. These include: - * Aliases for standard modes - * NORMAL_VGA (-1) - * EXTENDED_VGA (-2) - * ASK_VGA (-3) - * Video modes numbered by menu position -- NOT RECOMMENDED because of lack - * of compatibility when extending the table. These are between 0x00 and 0xff. - */ -#define VIDEO_FIRST_MENU 0x0000 - -/* Standard BIOS video modes (BIOS number + 0x0100) */ -#define VIDEO_FIRST_BIOS 0x0100 - -/* VESA BIOS video modes (VESA number + 0x0200) */ -#define VIDEO_FIRST_VESA 0x0200 - -/* Video7 special modes (BIOS number + 0x0900) */ -#define VIDEO_FIRST_V7 0x0900 - -/* Special video modes */ -#define VIDEO_FIRST_SPECIAL 0x0f00 -#define VIDEO_80x25 0x0f00 -#define VIDEO_8POINT 0x0f01 -#define VIDEO_80x43 0x0f02 -#define VIDEO_80x28 0x0f03 -#define VIDEO_CURRENT_MODE 0x0f04 -#define VIDEO_80x30 0x0f05 -#define VIDEO_80x34 0x0f06 -#define VIDEO_80x60 0x0f07 -#define VIDEO_GFX_HACK 0x0f08 -#define VIDEO_LAST_SPECIAL 0x0f09 - -/* Video modes given by resolution */ -#define VIDEO_FIRST_RESOLUTION 0x1000 - -/* The "recalculate timings" flag */ -#define VIDEO_RECALC 0x8000 - -/* Positions of various video parameters passed to the kernel */ -/* (see also include/linux/tty.h) */ -#define PARAM_CURSOR_POS 0x00 -#define PARAM_VIDEO_PAGE 0x04 -#define PARAM_VIDEO_MODE 0x06 -#define PARAM_VIDEO_COLS 0x07 -#define PARAM_VIDEO_EGA_BX 0x0a -#define PARAM_VIDEO_LINES 0x0e -#define PARAM_HAVE_VGA 0x0f -#define PARAM_FONT_POINTS 0x10 - -#define PARAM_LFB_WIDTH 0x12 -#define PARAM_LFB_HEIGHT 0x14 -#define PARAM_LFB_DEPTH 0x16 -#define PARAM_LFB_BASE 0x18 -#define PARAM_LFB_SIZE 0x1c -#define PARAM_LFB_LINELENGTH 0x24 -#define PARAM_LFB_COLORS 0x26 -#define PARAM_VESAPM_SEG 0x2e -#define PARAM_VESAPM_OFF 0x30 -#define PARAM_LFB_PAGES 0x32 -#define PARAM_VESA_ATTRIB 0x34 -#define PARAM_CAPABILITIES 0x36 - -/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */ -#ifdef CONFIG_VIDEO_RETAIN -#define DO_STORE call store_screen -#else -#define DO_STORE -#endif /* CONFIG_VIDEO_RETAIN */ - -# This is the main entry point called by setup.S -# %ds *must* be pointing to the bootsector -video: pushw %ds # We use different segments - pushw %ds # FS contains original DS - popw %fs - pushw %cs # DS is equal to CS - popw %ds - pushw %cs # ES is equal to CS - popw %es - xorw %ax, %ax - movw %ax, %gs # GS is zero - cld - call basic_detect # Basic adapter type testing (EGA/VGA/MDA/CGA) -#ifdef CONFIG_VIDEO_SELECT - movw %fs:(0x01fa), %ax # User selected video mode - cmpw $ASK_VGA, %ax # Bring up the menu - jz vid2 - - call mode_set # Set the mode - jc vid1 - - leaw badmdt, %si # Invalid mode ID - call prtstr -vid2: call mode_menu -vid1: -#ifdef CONFIG_VIDEO_RETAIN - call restore_screen # Restore screen contents -#endif /* CONFIG_VIDEO_RETAIN */ - call store_edid -#endif /* CONFIG_VIDEO_SELECT */ - call mode_params # Store mode parameters - popw %ds # Restore original DS - ret - -# Detect if we have CGA, MDA, EGA or VGA and pass it to the kernel. -basic_detect: - movb $0, %fs:(PARAM_HAVE_VGA) - movb $0x12, %ah # Check EGA/VGA - movb $0x10, %bl - int $0x10 - movw %bx, %fs:(PARAM_VIDEO_EGA_BX) # Identifies EGA to the kernel - cmpb $0x10, %bl # No, it's a CGA/MDA/HGA card. - je basret - - incb adapter - movw $0x1a00, %ax # Check EGA or VGA? - int $0x10 - cmpb $0x1a, %al # 1a means VGA... - jne basret # anything else is EGA. - - incb %fs:(PARAM_HAVE_VGA) # We've detected a VGA - incb adapter -basret: ret - -# Store the video mode parameters for later usage by the kernel. -# This is done by asking the BIOS except for the rows/columns -# parameters in the default 80x25 mode -- these are set directly, -# because some very obscure BIOSes supply insane values. -mode_params: -#ifdef CONFIG_VIDEO_SELECT - cmpb $0, graphic_mode - jnz mopar_gr -#endif - movb $0x03, %ah # Read cursor position - xorb %bh, %bh - int $0x10 - movw %dx, %fs:(PARAM_CURSOR_POS) - movb $0x0f, %ah # Read page/mode/width - int $0x10 - movw %bx, %fs:(PARAM_VIDEO_PAGE) - movw %ax, %fs:(PARAM_VIDEO_MODE) # Video mode and screen width - cmpb $0x7, %al # MDA/HGA => segment differs - jnz mopar0 - - movw $0xb000, video_segment -mopar0: movw %gs:(0x485), %ax # Font size - movw %ax, %fs:(PARAM_FONT_POINTS) # (valid only on EGA/VGA) - movw force_size, %ax # Forced size? - orw %ax, %ax - jz mopar1 - - movb %ah, %fs:(PARAM_VIDEO_COLS) - movb %al, %fs:(PARAM_VIDEO_LINES) - ret - -mopar1: movb $25, %al - cmpb $0, adapter # If we are on CGA/MDA/HGA, the - jz mopar2 # screen must have 25 lines. - - movb %gs:(0x484), %al # On EGA/VGA, use the EGA+ BIOS - incb %al # location of max lines. -mopar2: movb %al, %fs:(PARAM_VIDEO_LINES) - ret - -#ifdef CONFIG_VIDEO_SELECT -# Fetching of VESA frame buffer parameters -mopar_gr: - leaw modelist+1024, %di - movb $0x23, %fs:(PARAM_HAVE_VGA) - movw 16(%di), %ax - movw %ax, %fs:(PARAM_LFB_LINELENGTH) - movw 18(%di), %ax - movw %ax, %fs:(PARAM_LFB_WIDTH) - movw 20(%di), %ax - movw %ax, %fs:(PARAM_LFB_HEIGHT) - movb 25(%di), %al - movb $0, %ah - movw %ax, %fs:(PARAM_LFB_DEPTH) - movb 29(%di), %al - movb $0, %ah - movw %ax, %fs:(PARAM_LFB_PAGES) - movl 40(%di), %eax - movl %eax, %fs:(PARAM_LFB_BASE) - movl 31(%di), %eax - movl %eax, %fs:(PARAM_LFB_COLORS) - movl 35(%di), %eax - movl %eax, %fs:(PARAM_LFB_COLORS+4) - movw 0(%di), %ax - movw %ax, %fs:(PARAM_VESA_ATTRIB) - -# get video mem size - leaw modelist+1024, %di - movw $0x4f00, %ax - int $0x10 - xorl %eax, %eax - movw 18(%di), %ax - movl %eax, %fs:(PARAM_LFB_SIZE) - -# store mode capabilities - movl 10(%di), %eax - movl %eax, %fs:(PARAM_CAPABILITIES) - -# switching the DAC to 8-bit is for <= 8 bpp only - movw %fs:(PARAM_LFB_DEPTH), %ax - cmpw $8, %ax - jg dac_done - -# get DAC switching capability - xorl %eax, %eax - movb 10(%di), %al - testb $1, %al - jz dac_set - -# attempt to switch DAC to 8-bit - movw $0x4f08, %ax - movw $0x0800, %bx - int $0x10 - cmpw $0x004f, %ax - jne dac_set - movb %bh, dac_size # store actual DAC size - -dac_set: -# set color size to DAC size - movb dac_size, %al - movb %al, %fs:(PARAM_LFB_COLORS+0) - movb %al, %fs:(PARAM_LFB_COLORS+2) - movb %al, %fs:(PARAM_LFB_COLORS+4) - movb %al, %fs:(PARAM_LFB_COLORS+6) - -# set color offsets to 0 - movb $0, %fs:(PARAM_LFB_COLORS+1) - movb $0, %fs:(PARAM_LFB_COLORS+3) - movb $0, %fs:(PARAM_LFB_COLORS+5) - movb $0, %fs:(PARAM_LFB_COLORS+7) - -dac_done: -# get protected mode interface informations - movw $0x4f0a, %ax - xorw %bx, %bx - xorw %di, %di - int $0x10 - cmp $0x004f, %ax - jnz no_pm - - movw %es, %fs:(PARAM_VESAPM_SEG) - movw %di, %fs:(PARAM_VESAPM_OFF) -no_pm: ret - -# The video mode menu -mode_menu: - leaw keymsg, %si # "Return/Space/Timeout" message - call prtstr - call flush -nokey: call getkt - - cmpb $0x0d, %al # ENTER ? - je listm # yes - manual mode selection - - cmpb $0x20, %al # SPACE ? - je defmd1 # no - repeat - - call beep - jmp nokey - -defmd1: ret # No mode chosen? Default 80x25 - -listm: call mode_table # List mode table -listm0: leaw name_bann, %si # Print adapter name - call prtstr - movw card_name, %si - orw %si, %si - jnz an2 - - movb adapter, %al - leaw old_name, %si - orb %al, %al - jz an1 - - leaw ega_name, %si - decb %al - jz an1 - - leaw vga_name, %si - jmp an1 - -an2: call prtstr - leaw svga_name, %si -an1: call prtstr - leaw listhdr, %si # Table header - call prtstr - movb $0x30, %dl # DL holds mode number - leaw modelist, %si -lm1: cmpw $ASK_VGA, (%si) # End? - jz lm2 - - movb %dl, %al # Menu selection number - call prtchr - call prtsp2 - lodsw - call prthw # Mode ID - call prtsp2 - movb 0x1(%si), %al - call prtdec # Rows - movb $0x78, %al # the letter 'x' - call prtchr - lodsw - call prtdec # Columns - movb $0x0d, %al # New line - call prtchr - movb $0x0a, %al - call prtchr - incb %dl # Next character - cmpb $0x3a, %dl - jnz lm1 - - movb $0x61, %dl - jmp lm1 - -lm2: leaw prompt, %si # Mode prompt - call prtstr - leaw edit_buf, %di # Editor buffer -lm3: call getkey - cmpb $0x0d, %al # Enter? - jz lment - - cmpb $0x08, %al # Backspace? - jz lmbs - - cmpb $0x20, %al # Printable? - jc lm3 - - cmpw $edit_buf+4, %di # Enough space? - jz lm3 - - stosb - call prtchr - jmp lm3 - -lmbs: cmpw $edit_buf, %di # Backspace - jz lm3 - - decw %di - movb $0x08, %al - call prtchr - call prtspc - movb $0x08, %al - call prtchr - jmp lm3 - -lment: movb $0, (%di) - leaw crlft, %si - call prtstr - leaw edit_buf, %si - cmpb $0, (%si) # Empty string = default mode - jz lmdef - - cmpb $0, 1(%si) # One character = menu selection - jz mnusel - - cmpw $0x6373, (%si) # "scan" => mode scanning - jnz lmhx - - cmpw $0x6e61, 2(%si) - jz lmscan - -lmhx: xorw %bx, %bx # Else => mode ID in hex -lmhex: lodsb - orb %al, %al - jz lmuse1 - - subb $0x30, %al - jc lmbad - - cmpb $10, %al - jc lmhx1 - - subb $7, %al - andb $0xdf, %al - cmpb $10, %al - jc lmbad - - cmpb $16, %al - jnc lmbad - -lmhx1: shlw $4, %bx - orb %al, %bl - jmp lmhex - -lmuse1: movw %bx, %ax - jmp lmuse - -mnusel: lodsb # Menu selection - xorb %ah, %ah - subb $0x30, %al - jc lmbad - - cmpb $10, %al - jc lmuse - - cmpb $0x61-0x30, %al - jc lmbad - - subb $0x61-0x30-10, %al - cmpb $36, %al - jnc lmbad - -lmuse: call mode_set - jc lmdef - -lmbad: leaw unknt, %si - call prtstr - jmp lm2 -lmscan: cmpb $0, adapter # Scanning only on EGA/VGA - jz lmbad - - movw $0, mt_end # Scanning of modes is - movb $1, scanning # done as new autodetection. - call mode_table - jmp listm0 -lmdef: ret - -# Additional parts of mode_set... (relative jumps, you know) -setv7: # Video7 extended modes - DO_STORE - subb $VIDEO_FIRST_V7>>8, %bh - movw $0x6f05, %ax - int $0x10 - stc - ret - -_setrec: jmp setrec # Ugly... -_set_80x25: jmp set_80x25 - -# Aliases for backward compatibility. -setalias: - movw $VIDEO_80x25, %ax - incw %bx - jz mode_set - - movb $VIDEO_8POINT-VIDEO_FIRST_SPECIAL, %al - incw %bx - jnz setbad # Fall-through! - -# Setting of user mode (AX=mode ID) => CF=success -mode_set: - movw %ax, %fs:(0x01fa) # Store mode for use in acpi_wakeup.S - movw %ax, %bx - cmpb $0xff, %ah - jz setalias - - testb $VIDEO_RECALC>>8, %ah - jnz _setrec - - cmpb $VIDEO_FIRST_RESOLUTION>>8, %ah - jnc setres - - cmpb $VIDEO_FIRST_SPECIAL>>8, %ah - jz setspc - - cmpb $VIDEO_FIRST_V7>>8, %ah - jz setv7 - - cmpb $VIDEO_FIRST_VESA>>8, %ah - jnc check_vesa - - orb %ah, %ah - jz setmenu - - decb %ah - jz setbios - -setbad: clc - movb $0, do_restore # The screen needn't be restored - ret - -setvesa: - DO_STORE - subb $VIDEO_FIRST_VESA>>8, %bh - movw $0x4f02, %ax # VESA BIOS mode set call - int $0x10 - cmpw $0x004f, %ax # AL=4f if implemented - jnz setbad # AH=0 if OK - - stc - ret - -setbios: - DO_STORE - int $0x10 # Standard BIOS mode set call - pushw %bx - movb $0x0f, %ah # Check if really set - int $0x10 - popw %bx - cmpb %bl, %al - jnz setbad - - stc - ret - -setspc: xorb %bh, %bh # Set special mode - cmpb $VIDEO_LAST_SPECIAL-VIDEO_FIRST_SPECIAL, %bl - jnc setbad - - addw %bx, %bx - jmp *spec_inits(%bx) - -setmenu: - orb %al, %al # 80x25 is an exception - jz _set_80x25 - - pushw %bx # Set mode chosen from menu - call mode_table # Build the mode table - popw %ax - shlw $2, %ax - addw %ax, %si - cmpw %di, %si - jnc setbad - - movw (%si), %ax # Fetch mode ID -_m_s: jmp mode_set - -setres: pushw %bx # Set mode chosen by resolution - call mode_table - popw %bx - xchgb %bl, %bh -setr1: lodsw - cmpw $ASK_VGA, %ax # End of the list? - jz setbad - - lodsw - cmpw %bx, %ax - jnz setr1 - - movw -4(%si), %ax # Fetch mode ID - jmp _m_s - -check_vesa: -#ifdef CONFIG_FIRMWARE_EDID - leaw modelist+1024, %di - movw $0x4f00, %ax - int $0x10 - cmpw $0x004f, %ax - jnz setbad - - movw 4(%di), %ax - movw %ax, vbe_version -#endif - leaw modelist+1024, %di - subb $VIDEO_FIRST_VESA>>8, %bh - movw %bx, %cx # Get mode information structure - movw $0x4f01, %ax - int $0x10 - addb $VIDEO_FIRST_VESA>>8, %bh - cmpw $0x004f, %ax - jnz setbad - - movb (%di), %al # Check capabilities. - andb $0x19, %al - cmpb $0x09, %al - jz setvesa # This is a text mode - - movb (%di), %al # Check capabilities. - andb $0x99, %al - cmpb $0x99, %al - jnz _setbad # Doh! No linear frame buffer. - - subb $VIDEO_FIRST_VESA>>8, %bh - orw $0x4000, %bx # Use linear frame buffer - movw $0x4f02, %ax # VESA BIOS mode set call - int $0x10 - cmpw $0x004f, %ax # AL=4f if implemented - jnz _setbad # AH=0 if OK - - movb $1, graphic_mode # flag graphic mode - movb $0, do_restore # no screen restore - stc - ret - -_setbad: jmp setbad # Ugly... - -# Recalculate vertical display end registers -- this fixes various -# inconsistencies of extended modes on many adapters. Called when -# the VIDEO_RECALC flag is set in the mode ID. - -setrec: subb $VIDEO_RECALC>>8, %ah # Set the base mode - call mode_set - jnc rct3 - - movw %gs:(0x485), %ax # Font size in pixels - movb %gs:(0x484), %bl # Number of rows - incb %bl - mulb %bl # Number of visible - decw %ax # scan lines - 1 - movw $0x3d4, %dx - movw %ax, %bx - movb $0x12, %al # Lower 8 bits - movb %bl, %ah - outw %ax, %dx - movb $0x07, %al # Bits 8 and 9 in the overflow register - call inidx - xchgb %al, %ah - andb $0xbd, %ah - shrb %bh - jnc rct1 - orb $0x02, %ah -rct1: shrb %bh - jnc rct2 - orb $0x40, %ah -rct2: movb $0x07, %al - outw %ax, %dx - stc -rct3: ret - -# Table of routines for setting of the special modes. -spec_inits: - .word set_80x25 - .word set_8pixel - .word set_80x43 - .word set_80x28 - .word set_current - .word set_80x30 - .word set_80x34 - .word set_80x60 - .word set_gfx - -# Set the 80x25 mode. If already set, do nothing. -set_80x25: - movw $0x5019, force_size # Override possibly broken BIOS -use_80x25: -#ifdef CONFIG_VIDEO_400_HACK - movw $0x1202, %ax # Force 400 scan lines - movb $0x30, %bl - int $0x10 -#else - movb $0x0f, %ah # Get current mode ID - int $0x10 - cmpw $0x5007, %ax # Mode 7 (80x25 mono) is the only one available - jz st80 # on CGA/MDA/HGA and is also available on EGAM - - cmpw $0x5003, %ax # Unknown mode, force 80x25 color - jnz force3 - -st80: cmpb $0, adapter # CGA/MDA/HGA => mode 3/7 is always 80x25 - jz set80 - - movb %gs:(0x0484), %al # This is EGA+ -- beware of 80x50 etc. - orb %al, %al # Some buggy BIOS'es set 0 rows - jz set80 - - cmpb $24, %al # It's hopefully correct - jz set80 -#endif /* CONFIG_VIDEO_400_HACK */ -force3: DO_STORE - movw $0x0003, %ax # Forced set - int $0x10 -set80: stc - ret - -# Set the 80x50/80x43 8-pixel mode. Simple BIOS calls. -set_8pixel: - DO_STORE - call use_80x25 # The base is 80x25 -set_8pt: - movw $0x1112, %ax # Use 8x8 font - xorb %bl, %bl - int $0x10 - movw $0x1200, %ax # Use alternate print screen - movb $0x20, %bl - int $0x10 - movw $0x1201, %ax # Turn off cursor emulation - movb $0x34, %bl - int $0x10 - movb $0x01, %ah # Define cursor scan lines 6-7 - movw $0x0607, %cx - int $0x10 -set_current: - stc - ret - -# Set the 80x28 mode. This mode works on all VGA's, because it's a standard -# 80x25 mode with 14-point fonts instead of 16-point. -set_80x28: - DO_STORE - call use_80x25 # The base is 80x25 -set14: movw $0x1111, %ax # Use 9x14 font - xorb %bl, %bl - int $0x10 - movb $0x01, %ah # Define cursor scan lines 11-12 - movw $0x0b0c, %cx - int $0x10 - stc - ret - -# Set the 80x43 mode. This mode is works on all VGA's. -# It's a 350-scanline mode with 8-pixel font. -set_80x43: - DO_STORE - movw $0x1201, %ax # Set 350 scans - movb $0x30, %bl - int $0x10 - movw $0x0003, %ax # Reset video mode - int $0x10 - jmp set_8pt # Use 8-pixel font - -# Set the 80x30 mode (all VGA's). 480 scanlines, 16-pixel font. -set_80x30: - call use_80x25 # Start with real 80x25 - DO_STORE - movw $0x3cc, %dx # Get CRTC port - inb %dx, %al - movb $0xd4, %dl - rorb %al # Mono or color? - jc set48a - - movb $0xb4, %dl -set48a: movw $0x0c11, %ax # Vertical sync end (also unlocks CR0-7) - call outidx - movw $0x0b06, %ax # Vertical total - call outidx - movw $0x3e07, %ax # (Vertical) overflow - call outidx - movw $0xea10, %ax # Vertical sync start - call outidx - movw $0xdf12, %ax # Vertical display end - call outidx - movw $0xe715, %ax # Vertical blank start - call outidx - movw $0x0416, %ax # Vertical blank end - call outidx - pushw %dx - movb $0xcc, %dl # Misc output register (read) - inb %dx, %al - movb $0xc2, %dl # (write) - andb $0x0d, %al # Preserve clock select bits and color bit - orb $0xe2, %al # Set correct sync polarity - outb %al, %dx - popw %dx - movw $0x501e, force_size - stc # That's all. - ret - -# Set the 80x34 mode (all VGA's). 480 scans, 14-pixel font. -set_80x34: - call set_80x30 # Set 480 scans - call set14 # And 14-pt font - movw $0xdb12, %ax # VGA vertical display end - movw $0x5022, force_size -setvde: call outidx - stc - ret - -# Set the 80x60 mode (all VGA's). 480 scans, 8-pixel font. -set_80x60: - call set_80x30 # Set 480 scans - call set_8pt # And 8-pt font - movw $0xdf12, %ax # VGA vertical display end - movw $0x503c, force_size - jmp setvde - -# Special hack for ThinkPad graphics -set_gfx: -#ifdef CONFIG_VIDEO_GFX_HACK - movw $VIDEO_GFX_BIOS_AX, %ax - movw $VIDEO_GFX_BIOS_BX, %bx - int $0x10 - movw $VIDEO_GFX_DUMMY_RESOLUTION, force_size - stc -#endif - ret - -#ifdef CONFIG_VIDEO_RETAIN - -# Store screen contents to temporary buffer. -store_screen: - cmpb $0, do_restore # Already stored? - jnz stsr - - testb $CAN_USE_HEAP, loadflags # Have we space for storing? - jz stsr - - pushw %ax - pushw %bx - pushw force_size # Don't force specific size - movw $0, force_size - call mode_params # Obtain params of current mode - popw force_size - movb %fs:(PARAM_VIDEO_LINES), %ah - movb %fs:(PARAM_VIDEO_COLS), %al - movw %ax, %bx # BX=dimensions - mulb %ah - movw %ax, %cx # CX=number of characters - addw %ax, %ax # Calculate image size - addw $modelist+1024+4, %ax - cmpw heap_end_ptr, %ax - jnc sts1 # Unfortunately, out of memory - - movw %fs:(PARAM_CURSOR_POS), %ax # Store mode params - leaw modelist+1024, %di - stosw - movw %bx, %ax - stosw - pushw %ds # Store the screen - movw video_segment, %ds - xorw %si, %si - rep - movsw - popw %ds - incb do_restore # Screen will be restored later -sts1: popw %bx - popw %ax -stsr: ret - -# Restore screen contents from temporary buffer. -restore_screen: - cmpb $0, do_restore # Has the screen been stored? - jz res1 - - call mode_params # Get parameters of current mode - movb %fs:(PARAM_VIDEO_LINES), %cl - movb %fs:(PARAM_VIDEO_COLS), %ch - leaw modelist+1024, %si # Screen buffer - lodsw # Set cursor position - movw %ax, %dx - cmpb %cl, %dh - jc res2 - - movb %cl, %dh - decb %dh -res2: cmpb %ch, %dl - jc res3 - - movb %ch, %dl - decb %dl -res3: movb $0x02, %ah - movb $0x00, %bh - int $0x10 - lodsw # Display size - movb %ah, %dl # DL=number of lines - movb $0, %ah # BX=phys. length of orig. line - movw %ax, %bx - cmpb %cl, %dl # Too many? - jc res4 - - pushw %ax - movb %dl, %al - subb %cl, %al - mulb %bl - addw %ax, %si - addw %ax, %si - popw %ax - movb %cl, %dl -res4: cmpb %ch, %al # Too wide? - jc res5 - - movb %ch, %al # AX=width of src. line -res5: movb $0, %cl - xchgb %ch, %cl - movw %cx, %bp # BP=width of dest. line - pushw %es - movw video_segment, %es - xorw %di, %di # Move the data - addw %bx, %bx # Convert BX and BP to _bytes_ - addw %bp, %bp -res6: pushw %si - pushw %di - movw %ax, %cx - rep - movsw - popw %di - popw %si - addw %bp, %di - addw %bx, %si - decb %dl - jnz res6 - - popw %es # Done -res1: ret -#endif /* CONFIG_VIDEO_RETAIN */ - -# Write to indexed VGA register (AL=index, AH=data, DX=index reg. port) -outidx: outb %al, %dx - pushw %ax - movb %ah, %al - incw %dx - outb %al, %dx - decw %dx - popw %ax - ret - -# Build the table of video modes (stored after the setup.S code at the -# `modelist' label. Each video mode record looks like: -# .word MODE-ID (our special mode ID (see above)) -# .byte rows (number of rows) -# .byte columns (number of columns) -# Returns address of the end of the table in DI, the end is marked -# with a ASK_VGA ID. -mode_table: - movw mt_end, %di # Already filled? - orw %di, %di - jnz mtab1x - - leaw modelist, %di # Store standard modes: - movl $VIDEO_80x25 + 0x50190000, %eax # The 80x25 mode (ALL) - stosl - movb adapter, %al # CGA/MDA/HGA -- no more modes - orb %al, %al - jz mtabe - - decb %al - jnz mtabv - - movl $VIDEO_8POINT + 0x502b0000, %eax # The 80x43 EGA mode - stosl - jmp mtabe - -mtab1x: jmp mtab1 - -mtabv: leaw vga_modes, %si # All modes for std VGA - movw $vga_modes_end-vga_modes, %cx - rep # I'm unable to use movsw as I don't know how to store a half - movsb # of the expression above to cx without using explicit shr. - - cmpb $0, scanning # Mode scan requested? - jz mscan1 - - call mode_scan -mscan1: - -#ifdef CONFIG_VIDEO_LOCAL - call local_modes -#endif /* CONFIG_VIDEO_LOCAL */ - -#ifdef CONFIG_VIDEO_VESA - call vesa_modes # Detect VESA VGA modes -#endif /* CONFIG_VIDEO_VESA */ - -#ifdef CONFIG_VIDEO_SVGA - cmpb $0, scanning # Bypass when scanning - jnz mscan2 - - call svga_modes # Detect SVGA cards & modes -mscan2: -#endif /* CONFIG_VIDEO_SVGA */ - -mtabe: - -#ifdef CONFIG_VIDEO_COMPACT - leaw modelist, %si - movw %di, %dx - movw %si, %di -cmt1: cmpw %dx, %si # Scan all modes - jz cmt2 - - leaw modelist, %bx # Find in previous entries - movw 2(%si), %cx -cmt3: cmpw %bx, %si - jz cmt4 - - cmpw 2(%bx), %cx # Found => don't copy this entry - jz cmt5 - - addw $4, %bx - jmp cmt3 - -cmt4: movsl # Copy entry - jmp cmt1 - -cmt5: addw $4, %si # Skip entry - jmp cmt1 - -cmt2: -#endif /* CONFIG_VIDEO_COMPACT */ - - movw $ASK_VGA, (%di) # End marker - movw %di, mt_end -mtab1: leaw modelist, %si # SI=mode list, DI=list end -ret0: ret - -# Modes usable on all standard VGAs -vga_modes: - .word VIDEO_8POINT - .word 0x5032 # 80x50 - .word VIDEO_80x43 - .word 0x502b # 80x43 - .word VIDEO_80x28 - .word 0x501c # 80x28 - .word VIDEO_80x30 - .word 0x501e # 80x30 - .word VIDEO_80x34 - .word 0x5022 # 80x34 - .word VIDEO_80x60 - .word 0x503c # 80x60 -#ifdef CONFIG_VIDEO_GFX_HACK - .word VIDEO_GFX_HACK - .word VIDEO_GFX_DUMMY_RESOLUTION -#endif - -vga_modes_end: -# Detect VESA modes. - -#ifdef CONFIG_VIDEO_VESA -vesa_modes: - cmpb $2, adapter # VGA only - jnz ret0 - - movw %di, %bp # BP=original mode table end - addw $0x200, %di # Buffer space - movw $0x4f00, %ax # VESA Get card info call - int $0x10 - movw %bp, %di - cmpw $0x004f, %ax # Successful? - jnz ret0 - - cmpw $0x4556, 0x200(%di) - jnz ret0 - - cmpw $0x4153, 0x202(%di) - jnz ret0 - - movw $vesa_name, card_name # Set name to "VESA VGA" - pushw %gs - lgsw 0x20e(%di), %si # GS:SI=mode list - movw $128, %cx # Iteration limit -vesa1: -# gas version 2.9.1, using BFD version 2.9.1.0.23 buggers the next inst. -# XXX: lodsw %gs:(%si), %ax # Get next mode in the list - gs; lodsw - cmpw $0xffff, %ax # End of the table? - jz vesar - - cmpw $0x0080, %ax # Check validity of mode ID - jc vesa2 - - orb %ah, %ah # Valid IDs: 0x0000-0x007f/0x0100-0x07ff - jz vesan # Certain BIOSes report 0x80-0xff! - - cmpw $0x0800, %ax - jnc vesae - -vesa2: pushw %cx - movw %ax, %cx # Get mode information structure - movw $0x4f01, %ax - int $0x10 - movw %cx, %bx # BX=mode number - addb $VIDEO_FIRST_VESA>>8, %bh - popw %cx - cmpw $0x004f, %ax - jnz vesan # Don't report errors (buggy BIOSES) - - movb (%di), %al # Check capabilities. We require - andb $0x19, %al # a color text mode. - cmpb $0x09, %al - jnz vesan - - cmpw $0xb800, 8(%di) # Standard video memory address required - jnz vesan - - testb $2, (%di) # Mode characteristics supplied? - movw %bx, (%di) # Store mode number - jz vesa3 - - xorw %dx, %dx - movw 0x12(%di), %bx # Width - orb %bh, %bh - jnz vesan - - movb %bl, 0x3(%di) - movw 0x14(%di), %ax # Height - orb %ah, %ah - jnz vesan - - movb %al, 2(%di) - mulb %bl - cmpw $8193, %ax # Small enough for Linux console driver? - jnc vesan - - jmp vesaok - -vesa3: subw $0x8108, %bx # This mode has no detailed info specified, - jc vesan # so it must be a standard VESA mode. - - cmpw $5, %bx - jnc vesan - - movw vesa_text_mode_table(%bx), %ax - movw %ax, 2(%di) -vesaok: addw $4, %di # The mode is valid. Store it. -vesan: loop vesa1 # Next mode. Limit exceeded => error -vesae: leaw vesaer, %si - call prtstr - movw %bp, %di # Discard already found modes. -vesar: popw %gs - ret - -# Dimensions of standard VESA text modes -vesa_text_mode_table: - .byte 60, 80 # 0108 - .byte 25, 132 # 0109 - .byte 43, 132 # 010A - .byte 50, 132 # 010B - .byte 60, 132 # 010C -#endif /* CONFIG_VIDEO_VESA */ - -# Scan for video modes. A bit dirty, but should work. -mode_scan: - movw $0x0100, %cx # Start with mode 0 -scm1: movb $0, %ah # Test the mode - movb %cl, %al - int $0x10 - movb $0x0f, %ah - int $0x10 - cmpb %cl, %al - jnz scm2 # Mode not set - - movw $0x3c0, %dx # Test if it's a text mode - movb $0x10, %al # Mode bits - call inidx - andb $0x03, %al - jnz scm2 - - movb $0xce, %dl # Another set of mode bits - movb $0x06, %al - call inidx - shrb %al - jc scm2 - - movb $0xd4, %dl # Cursor location - movb $0x0f, %al - call inidx - orb %al, %al - jnz scm2 - - movw %cx, %ax # Ok, store the mode - stosw - movb %gs:(0x484), %al # Number of rows - incb %al - stosb - movw %gs:(0x44a), %ax # Number of columns - stosb -scm2: incb %cl - jns scm1 - - movw $0x0003, %ax # Return back to mode 3 - int $0x10 - ret - -tstidx: outw %ax, %dx # OUT DX,AX and inidx -inidx: outb %al, %dx # Read from indexed VGA register - incw %dx # AL=index, DX=index reg port -> AL=data - inb %dx, %al - decw %dx - ret - -# Try to detect type of SVGA card and supply (usually approximate) video -# mode table for it. - -#ifdef CONFIG_VIDEO_SVGA -svga_modes: - leaw svga_table, %si # Test all known SVGA adapters -dosvga: lodsw - movw %ax, %bp # Default mode table - orw %ax, %ax - jz didsv1 - - lodsw # Pointer to test routine - pushw %si - pushw %di - pushw %es - movw $0xc000, %bx - movw %bx, %es - call *%ax # Call test routine - popw %es - popw %di - popw %si - orw %bp, %bp - jz dosvga - - movw %bp, %si # Found, copy the modes - movb svga_prefix, %ah -cpsvga: lodsb - orb %al, %al - jz didsv - - stosw - movsw - jmp cpsvga - -didsv: movw %si, card_name # Store pointer to card name -didsv1: ret - -# Table of all known SVGA cards. For each card, we store a pointer to -# a table of video modes supported by the card and a pointer to a routine -# used for testing of presence of the card. The video mode table is always -# followed by the name of the card or the chipset. -svga_table: - .word ati_md, ati_test - .word oak_md, oak_test - .word paradise_md, paradise_test - .word realtek_md, realtek_test - .word s3_md, s3_test - .word chips_md, chips_test - .word video7_md, video7_test - .word cirrus5_md, cirrus5_test - .word cirrus6_md, cirrus6_test - .word cirrus1_md, cirrus1_test - .word ahead_md, ahead_test - .word everex_md, everex_test - .word genoa_md, genoa_test - .word trident_md, trident_test - .word tseng_md, tseng_test - .word 0 - -# Test routines and mode tables: - -# S3 - The test algorithm was taken from the SuperProbe package -# for XFree86 1.2.1. Report bugs to Christoph.Niemann@linux.org -s3_test: - movw $0x0f35, %cx # we store some constants in cl/ch - movw $0x03d4, %dx - movb $0x38, %al - call inidx - movb %al, %bh # store current CRT-register 0x38 - movw $0x0038, %ax - call outidx # disable writing to special regs - movb %cl, %al # check whether we can write special reg 0x35 - call inidx - movb %al, %bl # save the current value of CRT reg 0x35 - andb $0xf0, %al # clear bits 0-3 - movb %al, %ah - movb %cl, %al # and write it to CRT reg 0x35 - call outidx - call inidx # now read it back - andb %ch, %al # clear the upper 4 bits - jz s3_2 # the first test failed. But we have a - - movb %bl, %ah # second chance - movb %cl, %al - call outidx - jmp s3_1 # do the other tests - -s3_2: movw %cx, %ax # load ah with 0xf and al with 0x35 - orb %bl, %ah # set the upper 4 bits of ah with the orig value - call outidx # write ... - call inidx # ... and reread - andb %cl, %al # turn off the upper 4 bits - pushw %ax - movb %bl, %ah # restore old value in register 0x35 - movb %cl, %al - call outidx - popw %ax - cmpb %ch, %al # setting lower 4 bits was successful => bad - je no_s3 # writing is allowed => this is not an S3 - -s3_1: movw $0x4838, %ax # allow writing to special regs by putting - call outidx # magic number into CRT-register 0x38 - movb %cl, %al # check whether we can write special reg 0x35 - call inidx - movb %al, %bl - andb $0xf0, %al - movb %al, %ah - movb %cl, %al - call outidx - call inidx - andb %ch, %al - jnz no_s3 # no, we can't write => no S3 - - movw %cx, %ax - orb %bl, %ah - call outidx - call inidx - andb %ch, %al - pushw %ax - movb %bl, %ah # restore old value in register 0x35 - movb %cl, %al - call outidx - popw %ax - cmpb %ch, %al - jne no_s31 # writing not possible => no S3 - movb $0x30, %al - call inidx # now get the S3 id ... - leaw idS3, %di - movw $0x10, %cx - repne - scasb - je no_s31 - - movb %bh, %ah - movb $0x38, %al - jmp s3rest - -no_s3: movb $0x35, %al # restore CRT register 0x35 - movb %bl, %ah - call outidx -no_s31: xorw %bp, %bp # Detection failed -s3rest: movb %bh, %ah - movb $0x38, %al # restore old value of CRT register 0x38 - jmp outidx - -idS3: .byte 0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95 - .byte 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0 - -s3_md: .byte 0x54, 0x2b, 0x84 - .byte 0x55, 0x19, 0x84 - .byte 0 - .ascii "S3" - .byte 0 - -# ATI cards. -ati_test: - leaw idati, %si - movw $0x31, %di - movw $0x09, %cx - repe - cmpsb - je atiok - - xorw %bp, %bp -atiok: ret - -idati: .ascii "761295520" - -ati_md: .byte 0x23, 0x19, 0x84 - .byte 0x33, 0x2c, 0x84 - .byte 0x22, 0x1e, 0x64 - .byte 0x21, 0x19, 0x64 - .byte 0x58, 0x21, 0x50 - .byte 0x5b, 0x1e, 0x50 - .byte 0 - .ascii "ATI" - .byte 0 - -# AHEAD -ahead_test: - movw $0x200f, %ax - movw $0x3ce, %dx - outw %ax, %dx - incw %dx - inb %dx, %al - cmpb $0x20, %al - je isahed - - cmpb $0x21, %al - je isahed - - xorw %bp, %bp -isahed: ret - -ahead_md: - .byte 0x22, 0x2c, 0x84 - .byte 0x23, 0x19, 0x84 - .byte 0x24, 0x1c, 0x84 - .byte 0x2f, 0x32, 0xa0 - .byte 0x32, 0x22, 0x50 - .byte 0x34, 0x42, 0x50 - .byte 0 - .ascii "Ahead" - .byte 0 - -# Chips & Tech. -chips_test: - movw $0x3c3, %dx - inb %dx, %al - orb $0x10, %al - outb %al, %dx - movw $0x104, %dx - inb %dx, %al - movb %al, %bl - movw $0x3c3, %dx - inb %dx, %al - andb $0xef, %al - outb %al, %dx - cmpb $0xa5, %bl - je cantok - - xorw %bp, %bp -cantok: ret - -chips_md: - .byte 0x60, 0x19, 0x84 - .byte 0x61, 0x32, 0x84 - .byte 0 - .ascii "Chips & Technologies" - .byte 0 - -# Cirrus Logic 5X0 -cirrus1_test: - movw $0x3d4, %dx - movb $0x0c, %al - outb %al, %dx - incw %dx - inb %dx, %al - movb %al, %bl - xorb %al, %al - outb %al, %dx - decw %dx - movb $0x1f, %al - outb %al, %dx - incw %dx - inb %dx, %al - movb %al, %bh - xorb %ah, %ah - shlb $4, %al - movw %ax, %cx - movb %bh, %al - shrb $4, %al - addw %ax, %cx - shlw $8, %cx - addw $6, %cx - movw %cx, %ax - movw $0x3c4, %dx - outw %ax, %dx - incw %dx - inb %dx, %al - andb %al, %al - jnz nocirr - - movb %bh, %al - outb %al, %dx - inb %dx, %al - cmpb $0x01, %al - je iscirr - -nocirr: xorw %bp, %bp -iscirr: movw $0x3d4, %dx - movb %bl, %al - xorb %ah, %ah - shlw $8, %ax - addw $0x0c, %ax - outw %ax, %dx - ret - -cirrus1_md: - .byte 0x1f, 0x19, 0x84 - .byte 0x20, 0x2c, 0x84 - .byte 0x22, 0x1e, 0x84 - .byte 0x31, 0x25, 0x64 - .byte 0 - .ascii "Cirrus Logic 5X0" - .byte 0 - -# Cirrus Logic 54XX -cirrus5_test: - movw $0x3c4, %dx - movb $6, %al - call inidx - movb %al, %bl # BL=backup - movw $6, %ax - call tstidx - cmpb $0x0f, %al - jne c5fail - - movw $0x1206, %ax - call tstidx - cmpb $0x12, %al - jne c5fail - - movb $0x1e, %al - call inidx - movb %al, %bh - movb %bh, %ah - andb $0xc0, %ah - movb $0x1e, %al - call tstidx - andb $0x3f, %al - jne c5xx - - movb $0x1e, %al - movb %bh, %ah - orb $0x3f, %ah - call tstidx - xorb $0x3f, %al - andb $0x3f, %al -c5xx: pushf - movb $0x1e, %al - movb %bh, %ah - outw %ax, %dx - popf - je c5done - -c5fail: xorw %bp, %bp -c5done: movb $6, %al - movb %bl, %ah - outw %ax, %dx - ret - -cirrus5_md: - .byte 0x14, 0x19, 0x84 - .byte 0x54, 0x2b, 0x84 - .byte 0 - .ascii "Cirrus Logic 54XX" - .byte 0 - -# Cirrus Logic 64XX -- no known extra modes, but must be identified, because -# it's misidentified by the Ahead test. -cirrus6_test: - movw $0x3ce, %dx - movb $0x0a, %al - call inidx - movb %al, %bl # BL=backup - movw $0xce0a, %ax - call tstidx - orb %al, %al - jne c2fail - - movw $0xec0a, %ax - call tstidx - cmpb $0x01, %al - jne c2fail - - movb $0xaa, %al - call inidx # 4X, 5X, 7X and 8X are valid 64XX chip ID's. - shrb $4, %al - subb $4, %al - jz c6done - - decb %al - jz c6done - - subb $2, %al - jz c6done - - decb %al - jz c6done - -c2fail: xorw %bp, %bp -c6done: movb $0x0a, %al - movb %bl, %ah - outw %ax, %dx - ret - -cirrus6_md: - .byte 0 - .ascii "Cirrus Logic 64XX" - .byte 0 - -# Everex / Trident -everex_test: - movw $0x7000, %ax - xorw %bx, %bx - int $0x10 - cmpb $0x70, %al - jne noevrx - - shrw $4, %dx - cmpw $0x678, %dx - je evtrid - - cmpw $0x236, %dx - jne evrxok - -evtrid: leaw trident_md, %bp -evrxok: ret - -noevrx: xorw %bp, %bp - ret - -everex_md: - .byte 0x03, 0x22, 0x50 - .byte 0x04, 0x3c, 0x50 - .byte 0x07, 0x2b, 0x64 - .byte 0x08, 0x4b, 0x64 - .byte 0x0a, 0x19, 0x84 - .byte 0x0b, 0x2c, 0x84 - .byte 0x16, 0x1e, 0x50 - .byte 0x18, 0x1b, 0x64 - .byte 0x21, 0x40, 0xa0 - .byte 0x40, 0x1e, 0x84 - .byte 0 - .ascii "Everex/Trident" - .byte 0 - -# Genoa. -genoa_test: - leaw idgenoa, %si # Check Genoa 'clues' - xorw %ax, %ax - movb %es:(0x37), %al - movw %ax, %di - movw $0x04, %cx - decw %si - decw %di -l1: incw %si - incw %di - movb (%si), %al - testb %al, %al - jz l2 - - cmpb %es:(%di), %al -l2: loope l1 - orw %cx, %cx - je isgen - - xorw %bp, %bp -isgen: ret - -idgenoa: .byte 0x77, 0x00, 0x99, 0x66 - -genoa_md: - .byte 0x58, 0x20, 0x50 - .byte 0x5a, 0x2a, 0x64 - .byte 0x60, 0x19, 0x84 - .byte 0x61, 0x1d, 0x84 - .byte 0x62, 0x20, 0x84 - .byte 0x63, 0x2c, 0x84 - .byte 0x64, 0x3c, 0x84 - .byte 0x6b, 0x4f, 0x64 - .byte 0x72, 0x3c, 0x50 - .byte 0x74, 0x42, 0x50 - .byte 0x78, 0x4b, 0x64 - .byte 0 - .ascii "Genoa" - .byte 0 - -# OAK -oak_test: - leaw idoakvga, %si - movw $0x08, %di - movw $0x08, %cx - repe - cmpsb - je isoak - - xorw %bp, %bp -isoak: ret - -idoakvga: .ascii "OAK VGA " - -oak_md: .byte 0x4e, 0x3c, 0x50 - .byte 0x4f, 0x3c, 0x84 - .byte 0x50, 0x19, 0x84 - .byte 0x51, 0x2b, 0x84 - .byte 0 - .ascii "OAK" - .byte 0 - -# WD Paradise. -paradise_test: - leaw idparadise, %si - movw $0x7d, %di - movw $0x04, %cx - repe - cmpsb - je ispara - - xorw %bp, %bp -ispara: ret - -idparadise: .ascii "VGA=" - -paradise_md: - .byte 0x41, 0x22, 0x50 - .byte 0x47, 0x1c, 0x84 - .byte 0x55, 0x19, 0x84 - .byte 0x54, 0x2c, 0x84 - .byte 0 - .ascii "Paradise" - .byte 0 - -# Trident. -trident_test: - movw $0x3c4, %dx - movb $0x0e, %al - outb %al, %dx - incw %dx - inb %dx, %al - xchgb %al, %ah - xorb %al, %al - outb %al, %dx - inb %dx, %al - xchgb %ah, %al - movb %al, %bl # Strange thing ... in the book this wasn't - andb $0x02, %bl # necessary but it worked on my card which - jz setb2 # is a trident. Without it the screen goes - # blurred ... - andb $0xfd, %al - jmp clrb2 - -setb2: orb $0x02, %al -clrb2: outb %al, %dx - andb $0x0f, %ah - cmpb $0x02, %ah - je istrid - - xorw %bp, %bp -istrid: ret - -trident_md: - .byte 0x50, 0x1e, 0x50 - .byte 0x51, 0x2b, 0x50 - .byte 0x52, 0x3c, 0x50 - .byte 0x57, 0x19, 0x84 - .byte 0x58, 0x1e, 0x84 - .byte 0x59, 0x2b, 0x84 - .byte 0x5a, 0x3c, 0x84 - .byte 0 - .ascii "Trident" - .byte 0 - -# Tseng. -tseng_test: - movw $0x3cd, %dx - inb %dx, %al # Could things be this simple ! :-) - movb %al, %bl - movb $0x55, %al - outb %al, %dx - inb %dx, %al - movb %al, %ah - movb %bl, %al - outb %al, %dx - cmpb $0x55, %ah - je istsen - -isnot: xorw %bp, %bp -istsen: ret - -tseng_md: - .byte 0x26, 0x3c, 0x50 - .byte 0x2a, 0x28, 0x64 - .byte 0x23, 0x19, 0x84 - .byte 0x24, 0x1c, 0x84 - .byte 0x22, 0x2c, 0x84 - .byte 0x21, 0x3c, 0x84 - .byte 0 - .ascii "Tseng" - .byte 0 - -# Video7. -video7_test: - movw $0x3cc, %dx - inb %dx, %al - movw $0x3b4, %dx - andb $0x01, %al - jz even7 - - movw $0x3d4, %dx -even7: movb $0x0c, %al - outb %al, %dx - incw %dx - inb %dx, %al - movb %al, %bl - movb $0x55, %al - outb %al, %dx - inb %dx, %al - decw %dx - movb $0x1f, %al - outb %al, %dx - incw %dx - inb %dx, %al - movb %al, %bh - decw %dx - movb $0x0c, %al - outb %al, %dx - incw %dx - movb %bl, %al - outb %al, %dx - movb $0x55, %al - xorb $0xea, %al - cmpb %bh, %al - jne isnot - - movb $VIDEO_FIRST_V7>>8, svga_prefix # Use special mode switching - ret - -video7_md: - .byte 0x40, 0x2b, 0x50 - .byte 0x43, 0x3c, 0x50 - .byte 0x44, 0x3c, 0x64 - .byte 0x41, 0x19, 0x84 - .byte 0x42, 0x2c, 0x84 - .byte 0x45, 0x1c, 0x84 - .byte 0 - .ascii "Video 7" - .byte 0 - -# Realtek VGA -realtek_test: - leaw idrtvga, %si - movw $0x45, %di - movw $0x0b, %cx - repe - cmpsb - je isrt - - xorw %bp, %bp -isrt: ret - -idrtvga: .ascii "REALTEK VGA" - -realtek_md: - .byte 0x1a, 0x3c, 0x50 - .byte 0x1b, 0x19, 0x84 - .byte 0x1c, 0x1e, 0x84 - .byte 0x1d, 0x2b, 0x84 - .byte 0x1e, 0x3c, 0x84 - .byte 0 - .ascii "REALTEK" - .byte 0 - -#endif /* CONFIG_VIDEO_SVGA */ - -# User-defined local mode table (VGA only) -#ifdef CONFIG_VIDEO_LOCAL -local_modes: - leaw local_mode_table, %si -locm1: lodsw - orw %ax, %ax - jz locm2 - - stosw - movsw - jmp locm1 - -locm2: ret - -# This is the table of local video modes which can be supplied manually -# by the user. Each entry consists of mode ID (word) and dimensions -# (byte for column count and another byte for row count). These modes -# are placed before all SVGA and VESA modes and override them if table -# compacting is enabled. The table must end with a zero word followed -# by NUL-terminated video adapter name. -local_mode_table: - .word 0x0100 # Example: 40x25 - .byte 25,40 - .word 0 - .ascii "Local" - .byte 0 -#endif /* CONFIG_VIDEO_LOCAL */ - -# Read a key and return the ASCII code in al, scan code in ah -getkey: xorb %ah, %ah - int $0x16 - ret - -# Read a key with a timeout of 30 seconds. -# The hardware clock is used to get the time. -getkt: call gettime - addb $30, %al # Wait 30 seconds - cmpb $60, %al - jl lminute - - subb $60, %al -lminute: - movb %al, %cl -again: movb $0x01, %ah - int $0x16 - jnz getkey # key pressed, so get it - - call gettime - cmpb %cl, %al - jne again - - movb $0x20, %al # timeout, return `space' - ret - -# Flush the keyboard buffer -flush: movb $0x01, %ah - int $0x16 - jz empty - - xorb %ah, %ah - int $0x16 - jmp flush - -empty: ret - -# Print hexadecimal number. -prthw: pushw %ax - movb %ah, %al - call prthb - popw %ax -prthb: pushw %ax - shrb $4, %al - call prthn - popw %ax - andb $0x0f, %al -prthn: cmpb $0x0a, %al - jc prth1 - - addb $0x07, %al -prth1: addb $0x30, %al - jmp prtchr - -# Print decimal number in al -prtdec: pushw %ax - pushw %cx - xorb %ah, %ah - movb $0x0a, %cl - idivb %cl - cmpb $0x09, %al - jbe lt100 - - call prtdec - jmp skip10 - -lt100: addb $0x30, %al - call prtchr -skip10: movb %ah, %al - addb $0x30, %al - call prtchr - popw %cx - popw %ax - ret - -store_edid: -#ifdef CONFIG_FIRMWARE_EDID - pushw %es # just save all registers - pushw %ax - pushw %bx - pushw %cx - pushw %dx - pushw %di - - pushw %fs - popw %es - - movl $0x13131313, %eax # memset block with 0x13 - movw $32, %cx - movw $0x140, %di - cld - rep - stosl - - cmpw $0x0200, vbe_version # only do EDID on >= VBE2.0 - jl no_edid - - pushw %es # save ES - xorw %di, %di # Report Capability - pushw %di - popw %es # ES:DI must be 0:0 - movw $0x4f15, %ax - xorw %bx, %bx - xorw %cx, %cx - int $0x10 - popw %es # restore ES - - cmpb $0x00, %ah # call successful - jne no_edid - - cmpb $0x4f, %al # function supported - jne no_edid - - movw $0x4f15, %ax # do VBE/DDC - movw $0x01, %bx - movw $0x00, %cx - movw $0x00, %dx - movw $0x140, %di - int $0x10 - -no_edid: - popw %di # restore all registers - popw %dx - popw %cx - popw %bx - popw %ax - popw %es -#endif - ret - -# VIDEO_SELECT-only variables -mt_end: .word 0 # End of video mode table if built -edit_buf: .space 6 # Line editor buffer -card_name: .word 0 # Pointer to adapter name -scanning: .byte 0 # Performing mode scan -do_restore: .byte 0 # Screen contents altered during mode change -svga_prefix: .byte VIDEO_FIRST_BIOS>>8 # Default prefix for BIOS modes -graphic_mode: .byte 0 # Graphic mode with a linear frame buffer -dac_size: .byte 6 # DAC bit depth -vbe_version: .word 0 # VBE bios version - -# Status messages -keymsg: .ascii "Press to see video modes available, " - .ascii " to continue or wait 30 secs" - .byte 0x0d, 0x0a, 0 - -listhdr: .byte 0x0d, 0x0a - .ascii "Mode: COLSxROWS:" - -crlft: .byte 0x0d, 0x0a, 0 - -prompt: .byte 0x0d, 0x0a - .asciz "Enter mode number or `scan': " - -unknt: .asciz "Unknown mode ID. Try again." - -badmdt: .ascii "You passed an undefined mode number." - .byte 0x0d, 0x0a, 0 - -vesaer: .ascii "Error: Scanning of VESA modes failed. Please " - .ascii "report to ." - .byte 0x0d, 0x0a, 0 - -old_name: .asciz "CGA/MDA/HGA" - -ega_name: .asciz "EGA" - -svga_name: .ascii " " - -vga_name: .asciz "VGA" - -vesa_name: .asciz "VESA" - -name_bann: .asciz "Video adapter: " -#endif /* CONFIG_VIDEO_SELECT */ - -# Other variables: -adapter: .byte 0 # Video adapter: 0=CGA/MDA/HGA,1=EGA,2=VGA -video_segment: .word 0xb800 # Video memory segment -force_size: .word 0 # Use this size instead of the one in BIOS vars -- cgit v1.2.3-59-g8ed1b From f19cccf366a07e05703c90038704a3a5ffcb0607 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:21 +0200 Subject: [PATCH] x86-64: Fix allnoconfig error in genapic_flat.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix: In file included from include2/asm/apic.h:5, from include2/asm/smp.h:15, from linux/arch/x86_64/kernel/genapic_flat.c:18: linux/include/linux/pm.h: In function ‘call_platform_enable_wakeup’: linux/include/linux/pm.h:331: error: ‘EIO’ undeclared (first use in this function) linux/include/linux/pm.h:331: error: (Each undeclared identifier is reported only once linux/include/linux/pm.h:331: error: for each function it appears in.) Signed-off-by: Andi Kleen --- arch/x86_64/kernel/genapic_flat.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c index 01d3939e3a9c..ecb01eefdd27 100644 --- a/arch/x86_64/kernel/genapic_flat.c +++ b/arch/x86_64/kernel/genapic_flat.c @@ -8,6 +8,7 @@ * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and * James Cleverdon. */ +#include #include #include #include -- cgit v1.2.3-59-g8ed1b From 1306383282aaf58e85e5461404db367be0f88dca Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 2 May 2007 19:27:21 +0200 Subject: [PATCH] i386: Drop noisy e820 debugging printks Signed-off-by: Andi Kleen --- arch/i386/kernel/e820.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c index 829beec9247e..9645bb51f76a 100644 --- a/arch/i386/kernel/e820.c +++ b/arch/i386/kernel/e820.c @@ -393,10 +393,8 @@ int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) ____________________33__ ______________________4_ */ - printk("sanitize start\n"); /* if there's only one memory region, don't bother */ if (*pnr_map < 2) { - printk("sanitize bail 0\n"); return -1; } @@ -405,7 +403,6 @@ int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) /* bail out if we find any unreasonable addresses in bios map */ for (i=0; isize; unsigned long long end = start + size; unsigned long type = biosmap->type; - printk("copy_e820_map() start: %016Lx size: %016Lx end: %016Lx type: %ld\n", start, size, end, type); /* Overflow in 64 bits? Ignore the memory map. */ if (start > end) @@ -543,17 +538,11 @@ int __init copy_e820_map(struct e820entry * biosmap, int nr_map) * Not right. Fix it up. */ if (type == E820_RAM) { - printk("copy_e820_map() type is E820_RAM\n"); if (start < 0x100000ULL && end > 0xA0000ULL) { - printk("copy_e820_map() lies in range...\n"); - if (start < 0xA0000ULL) { - printk("copy_e820_map() start < 0xA0000ULL\n"); + if (start < 0xA0000ULL) add_memory_region(start, 0xA0000ULL-start, type); - } - if (end <= 0x100000ULL) { - printk("copy_e820_map() end <= 0x100000ULL\n"); + if (end <= 0x100000ULL) continue; - } start = 0x100000ULL; size = end - start; } -- cgit v1.2.3-59-g8ed1b From 6c2af35820f100bde7b9de8a00a76faa7af6bede Mon Sep 17 00:00:00 2001 From: Bill Irwin Date: Wed, 2 May 2007 19:27:22 +0200 Subject: [PATCH] i386: Add missing !X86_PAE dependincy to the 2G/2G split. Only 1GB-aligned kernel/user splits are now handled for PAE. The 2GB/2GB split attempts to avoid aliasing vmallocspace with the 1:1 mapping for physical memory by using an actual split of 1.875/2.125 to accommodate 128MB of vmallocspace out of what would otherwise be a full 2GB for userspace. That attempt disturbs the alignment required by PAE for 2GB/2GB splits, and furthermore does not provide a 2GB/2GB split as advertised. This patch resolves the issues here in two manners. The first is by providing a true 2GB/2GB split in addition to the 1.875/2.125 split. The second is by renaming the 1.875/2.125 split to CONFIG_VMSPLIT_2G_OPT analogously to CONFIG_VMSPLIT_3G_OPT, which performs a similar manuever to avoid aliasing vmallocspace with the 1:1 mapping for physical memory around the 3GB boundary. With the 1.875/2.125 split properly-named, its config option is then tagged as depending on !HIGHMEM to express the PAE implementation's current inability to deal with such unaligned splits. This patch is essentially a combination of two patches, one written by Eric Biederman and the other by Eric Dumazet. If they could add their Signed-off-by: to this, I'd be much obliged. Signed-off-by: William Irwin Signed-off-by: Andi Kleen Cc: Eric Dumazet Cc: Mark Lord Cc: Eric W. Biederman Cc: Andi Kleen --- arch/i386/Kconfig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 1a94a73fe801..c6f8d6856c4d 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -571,6 +571,9 @@ choice bool "3G/1G user/kernel split (for full 1G low memory)" config VMSPLIT_2G bool "2G/2G user/kernel split" + config VMSPLIT_2G_OPT + depends on !HIGHMEM + bool "2G/2G user/kernel split (for full 2G low memory)" config VMSPLIT_1G bool "1G/3G user/kernel split" endchoice @@ -578,7 +581,8 @@ endchoice config PAGE_OFFSET hex default 0xB0000000 if VMSPLIT_3G_OPT - default 0x78000000 if VMSPLIT_2G + default 0x80000000 if VMSPLIT_2G + default 0x78000000 if VMSPLIT_2G_OPT default 0x40000000 if VMSPLIT_1G default 0xC0000000 -- cgit v1.2.3-59-g8ed1b From b5229dbb857f61d77d8d4048d9033387a5411b8e Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Wed, 2 May 2007 19:27:22 +0200 Subject: [PATCH] i386: Some additional chipset register values validation. On i945, a mmconfig range hitting the f0000000-ffffffff zone conflicts with the APIC registers and others. Consider it invalid. On E7520, values 0000 and f000 for the window register are defined invalid in the documentation. I haven't seen a bios use these values, but who trusts biosen these days? Signed-off-by: Olivier Galibert Signed-off-by: Andi Kleen arch/i386/pci/mmconfig-shared.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) --- arch/i386/pci/mmconfig-shared.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/i386/pci/mmconfig-shared.c b/arch/i386/pci/mmconfig-shared.c index 747d8c63b0c4..c7cabeed4d7b 100644 --- a/arch/i386/pci/mmconfig-shared.c +++ b/arch/i386/pci/mmconfig-shared.c @@ -60,14 +60,19 @@ static const char __init *pci_mmcfg_e7520(void) u32 win; pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0xce, 2, &win); - pci_mmcfg_config_num = 1; - pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL); - if (!pci_mmcfg_config) - return NULL; - pci_mmcfg_config[0].address = (win & 0xf000) << 16; - pci_mmcfg_config[0].pci_segment = 0; - pci_mmcfg_config[0].start_bus_number = 0; - pci_mmcfg_config[0].end_bus_number = 255; + win = win & 0xf000; + if(win == 0x0000 || win == 0xf000) + pci_mmcfg_config_num = 0; + else { + pci_mmcfg_config_num = 1; + pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL); + if (!pci_mmcfg_config) + return NULL; + pci_mmcfg_config[0].address = win << 16; + pci_mmcfg_config[0].pci_segment = 0; + pci_mmcfg_config[0].start_bus_number = 0; + pci_mmcfg_config[0].end_bus_number = 255; + } return "Intel Corporation E7520 Memory Controller Hub"; } @@ -108,6 +113,10 @@ static const char __init *pci_mmcfg_intel_945(void) if ((pciexbar & mask) & 0x0fffffffU) pci_mmcfg_config_num = 0; + /* Don't hit the APIC registers and their friends */ + if ((pciexbar & mask) >= 0xf0000000U) + pci_mmcfg_config_num = 0; + if (pci_mmcfg_config_num) { pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL); if (!pci_mmcfg_config) -- cgit v1.2.3-59-g8ed1b From a3193348d407baaa7aef79decfa0e9a7fef74a17 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Wed, 2 May 2007 19:27:22 +0200 Subject: [PATCH] i386: type may be unused In the case of !CONFIG_PCI_DIRECT && !CONFIG_PCI_MMCONFIG, type is unreferened. Cc: Andi Kleen Signed-off-by: David Rientjes Signed-off-by: Andi Kleen --- arch/i386/pci/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/pci/init.c b/arch/i386/pci/init.c index b21b6da8ab1d..1cf11af96de2 100644 --- a/arch/i386/pci/init.c +++ b/arch/i386/pci/init.c @@ -6,7 +6,7 @@ in the right sequence from here. */ static __init int pci_access_init(void) { - int type = 0; + int type __attribute__((unused)) = 0; #ifdef CONFIG_PCI_DIRECT type = pci_direct_probe(); -- cgit v1.2.3-59-g8ed1b From 35060b6a9a4e1c89bc6fbea61090e302dbc61847 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Wed, 2 May 2007 19:27:22 +0200 Subject: [PATCH] i386: Don't delete cpu_devs data to identify different x86 types in late_initcall In arch/i386/cpu/common.c there is: cpu_devs[X86_VENDOR_INTEL] cpu_devs[X86_VENDOR_CYRIX] cpu_devs[X86_VENDOR_AMD] ... They are all filled with data early. The data (struct) got set to NULL for all, but Intel in different late_initcall (exit_cpu_vendor) calls. I don't see what sense this makes at all, maybe something that got forgotten with the HOTPLUG_CPU extenstions? Please check/review whether initdata, cpuinitdata is still ok and this still works with HOTPLUG_CPU and without, it should... Signed-off-by: Thomas Renninger Signed-off-by: Andi Kleen Cc: davej@redhat.com --- arch/i386/kernel/cpu/amd.c | 10 ---------- arch/i386/kernel/cpu/centaur.c | 10 ---------- arch/i386/kernel/cpu/cyrix.c | 19 ------------------- arch/i386/kernel/cpu/nexgen.c | 10 ---------- arch/i386/kernel/cpu/rise.c | 9 --------- arch/i386/kernel/cpu/transmeta.c | 10 ---------- arch/i386/kernel/cpu/umc.c | 10 ---------- 7 files changed, 78 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index 197cda62caa3..4fec702afd7e 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c @@ -319,13 +319,3 @@ int __init amd_init_cpu(void) cpu_devs[X86_VENDOR_AMD] = &amd_cpu_dev; return 0; } - -//early_arch_initcall(amd_init_cpu); - -static int __init amd_exit_cpu(void) -{ - cpu_devs[X86_VENDOR_AMD] = NULL; - return 0; -} - -late_initcall(amd_exit_cpu); diff --git a/arch/i386/kernel/cpu/centaur.c b/arch/i386/kernel/cpu/centaur.c index 8c25047975c0..473eac883c7b 100644 --- a/arch/i386/kernel/cpu/centaur.c +++ b/arch/i386/kernel/cpu/centaur.c @@ -469,13 +469,3 @@ int __init centaur_init_cpu(void) cpu_devs[X86_VENDOR_CENTAUR] = ¢aur_cpu_dev; return 0; } - -//early_arch_initcall(centaur_init_cpu); - -static int __init centaur_exit_cpu(void) -{ - cpu_devs[X86_VENDOR_CENTAUR] = NULL; - return 0; -} - -late_initcall(centaur_exit_cpu); diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c index e77f8e1cf7aa..0b8411a864fb 100644 --- a/arch/i386/kernel/cpu/cyrix.c +++ b/arch/i386/kernel/cpu/cyrix.c @@ -448,16 +448,6 @@ int __init cyrix_init_cpu(void) return 0; } -//early_arch_initcall(cyrix_init_cpu); - -static int __init cyrix_exit_cpu(void) -{ - cpu_devs[X86_VENDOR_CYRIX] = NULL; - return 0; -} - -late_initcall(cyrix_exit_cpu); - static struct cpu_dev nsc_cpu_dev __cpuinitdata = { .c_vendor = "NSC", .c_ident = { "Geode by NSC" }, @@ -470,12 +460,3 @@ int __init nsc_init_cpu(void) return 0; } -//early_arch_initcall(nsc_init_cpu); - -static int __init nsc_exit_cpu(void) -{ - cpu_devs[X86_VENDOR_NSC] = NULL; - return 0; -} - -late_initcall(nsc_exit_cpu); diff --git a/arch/i386/kernel/cpu/nexgen.c b/arch/i386/kernel/cpu/nexgen.c index 8bf23cc80c63..961fbe1a748f 100644 --- a/arch/i386/kernel/cpu/nexgen.c +++ b/arch/i386/kernel/cpu/nexgen.c @@ -58,13 +58,3 @@ int __init nexgen_init_cpu(void) cpu_devs[X86_VENDOR_NEXGEN] = &nexgen_cpu_dev; return 0; } - -//early_arch_initcall(nexgen_init_cpu); - -static int __init nexgen_exit_cpu(void) -{ - cpu_devs[X86_VENDOR_NEXGEN] = NULL; - return 0; -} - -late_initcall(nexgen_exit_cpu); diff --git a/arch/i386/kernel/cpu/rise.c b/arch/i386/kernel/cpu/rise.c index 9317f7414989..50076f22e90f 100644 --- a/arch/i386/kernel/cpu/rise.c +++ b/arch/i386/kernel/cpu/rise.c @@ -50,12 +50,3 @@ int __init rise_init_cpu(void) return 0; } -//early_arch_initcall(rise_init_cpu); - -static int __init rise_exit_cpu(void) -{ - cpu_devs[X86_VENDOR_RISE] = NULL; - return 0; -} - -late_initcall(rise_exit_cpu); diff --git a/arch/i386/kernel/cpu/transmeta.c b/arch/i386/kernel/cpu/transmeta.c index 5678d46863c6..6471a5a13202 100644 --- a/arch/i386/kernel/cpu/transmeta.c +++ b/arch/i386/kernel/cpu/transmeta.c @@ -112,13 +112,3 @@ int __init transmeta_init_cpu(void) cpu_devs[X86_VENDOR_TRANSMETA] = &transmeta_cpu_dev; return 0; } - -//early_arch_initcall(transmeta_init_cpu); - -static int __init transmeta_exit_cpu(void) -{ - cpu_devs[X86_VENDOR_TRANSMETA] = NULL; - return 0; -} - -late_initcall(transmeta_exit_cpu); diff --git a/arch/i386/kernel/cpu/umc.c b/arch/i386/kernel/cpu/umc.c index 1bf3f87e9c5b..a7a4e75bdcd7 100644 --- a/arch/i386/kernel/cpu/umc.c +++ b/arch/i386/kernel/cpu/umc.c @@ -24,13 +24,3 @@ int __init umc_init_cpu(void) cpu_devs[X86_VENDOR_UMC] = &umc_cpu_dev; return 0; } - -//early_arch_initcall(umc_init_cpu); - -static int __init umc_exit_cpu(void) -{ - cpu_devs[X86_VENDOR_UMC] = NULL; - return 0; -} - -late_initcall(umc_exit_cpu); -- cgit v1.2.3-59-g8ed1b From 823bccfc4002296ba88c3ad0f049e1abd8108d30 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 13 Apr 2007 13:15:19 -0700 Subject: remove "struct subsystem" as it is no longer needed We need to work on cleaning up the relationship between kobjects, ksets and ktypes. The removal of 'struct subsystem' is the first step of this, especially as it is not really needed at all. Thanks to Kay for fixing the bugs in this patch. Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-omap1/pm.c | 6 +-- arch/powerpc/kernel/vio.c | 4 +- arch/powerpc/platforms/pseries/power.c | 8 +-- arch/s390/kernel/ipl.c | 32 ++++++------ block/genhd.c | 12 ++--- drivers/base/base.h | 2 + drivers/base/bus.c | 16 +++--- drivers/base/class.c | 18 +++---- drivers/base/core.c | 22 ++++---- drivers/base/firmware.c | 6 +-- drivers/base/power/shutdown.c | 4 +- drivers/base/sys.c | 14 ++--- drivers/firmware/efivars.c | 12 ++--- drivers/input/evdev.c | 4 +- drivers/input/joydev.c | 4 +- drivers/input/mousedev.c | 4 +- drivers/input/tsdev.c | 4 +- drivers/parisc/pdc_stable.c | 94 +++++++++++++++++----------------- drivers/pci/hotplug/acpiphp_ibm.c | 4 +- drivers/pci/hotplug/pci_hotplug_core.c | 4 +- fs/configfs/mount.c | 2 +- fs/debugfs/inode.c | 2 +- fs/dlm/lockspace.c | 2 +- fs/ecryptfs/main.c | 12 ++--- fs/fuse/inode.c | 4 +- fs/gfs2/locking/dlm/sysfs.c | 2 +- fs/gfs2/sys.c | 2 +- fs/ocfs2/cluster/masklog.c | 4 +- fs/ocfs2/cluster/masklog.h | 2 +- fs/ocfs2/cluster/sys.c | 7 ++- fs/partitions/check.c | 6 +-- fs/sysfs/file.c | 11 ++-- include/acpi/acpi_bus.h | 2 +- include/linux/device.h | 8 +-- include/linux/fs.h | 2 +- include/linux/kobject.h | 58 +++++++++------------ include/linux/module.h | 2 +- include/linux/pci_hotplug.h | 2 +- kernel/ksysfs.c | 12 ++--- kernel/module.c | 8 +-- kernel/params.c | 2 + kernel/power/disk.c | 14 ++--- kernel/power/main.c | 10 ++-- kernel/power/power.h | 2 +- lib/kobject.c | 69 +++---------------------- security/inode.c | 2 +- 46 files changed, 231 insertions(+), 292 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index 0383ab334270..6f4ea4bda5e0 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -72,12 +72,12 @@ static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; static unsigned short enable_dyn_sleep = 1; -static ssize_t omap_pm_sleep_while_idle_show(struct subsystem * subsys, char *buf) +static ssize_t omap_pm_sleep_while_idle_show(struct kset *kset, char *buf) { return sprintf(buf, "%hu\n", enable_dyn_sleep); } -static ssize_t omap_pm_sleep_while_idle_store(struct subsystem * subsys, +static ssize_t omap_pm_sleep_while_idle_store(struct kset *kset, const char * buf, size_t n) { @@ -100,7 +100,7 @@ static struct subsys_attribute sleep_while_idle_attr = { .store = omap_pm_sleep_while_idle_store, }; -extern struct subsystem power_subsys; +extern struct kset power_subsys; static void (*omap_sram_idle)(void) = NULL; static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL; diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 9eaefac5053f..b2c1b67a10a7 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -37,7 +37,7 @@ #include #include -extern struct subsystem devices_subsys; /* needed for vio_find_name() */ +extern struct kset devices_subsys; /* needed for vio_find_name() */ static struct vio_dev vio_bus_device = { /* fake "parent" device */ .name = vio_bus_device.dev.bus_id, @@ -427,7 +427,7 @@ static struct vio_dev *vio_find_name(const char *kobj_name) { struct kobject *found; - found = kset_find_obj(&devices_subsys.kset, kobj_name); + found = kset_find_obj(&devices_subsys, kobj_name); if (!found) return NULL; diff --git a/arch/powerpc/platforms/pseries/power.c b/arch/powerpc/platforms/pseries/power.c index 2624b71df73d..73e69023d90a 100644 --- a/arch/powerpc/platforms/pseries/power.c +++ b/arch/powerpc/platforms/pseries/power.c @@ -28,13 +28,13 @@ unsigned long rtas_poweron_auto; /* default and normal state is 0 */ -static ssize_t auto_poweron_show(struct subsystem *subsys, char *buf) +static ssize_t auto_poweron_show(struct kset *kset, char *buf) { return sprintf(buf, "%lu\n", rtas_poweron_auto); } static ssize_t -auto_poweron_store(struct subsystem *subsys, const char *buf, size_t n) +auto_poweron_store(struct kset *kset, const char *buf, size_t n) { int ret; unsigned long ups_restart; @@ -72,12 +72,12 @@ static int __init pm_init(void) { int error = subsystem_register(&power_subsys); if (!error) - error = sysfs_create_group(&power_subsys.kset.kobj,&attr_group); + error = sysfs_create_group(&power_subsys.kobj, &attr_group); return error; } core_initcall(pm_init); #else -extern struct subsystem power_subsys; +extern struct kset power_subsys; static int __init apo_pm_init(void) { diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 06833ac2b115..0ea048d350d8 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -164,7 +164,7 @@ EXPORT_SYMBOL_GPL(diag308); /* SYSFS */ #define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value) \ -static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \ +static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \ char *page) \ { \ return sprintf(page, _format, _value); \ @@ -173,13 +173,13 @@ static struct subsys_attribute sys_##_prefix##_##_name##_attr = \ __ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL); #define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value) \ -static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \ +static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \ char *page) \ { \ return sprintf(page, _fmt_out, \ (unsigned long long) _value); \ } \ -static ssize_t sys_##_prefix##_##_name##_store(struct subsystem *subsys,\ +static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset, \ const char *buf, size_t len) \ { \ unsigned long long value; \ @@ -194,12 +194,12 @@ static struct subsys_attribute sys_##_prefix##_##_name##_attr = \ sys_##_prefix##_##_name##_store); #define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\ -static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \ +static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \ char *page) \ { \ return sprintf(page, _fmt_out, _value); \ } \ -static ssize_t sys_##_prefix##_##_name##_store(struct subsystem *subsys,\ +static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset, \ const char *buf, size_t len) \ { \ if (sscanf(buf, _fmt_in, _value) != 1) \ @@ -272,14 +272,14 @@ void __init setup_ipl_info(void) struct ipl_info ipl_info; EXPORT_SYMBOL_GPL(ipl_info); -static ssize_t ipl_type_show(struct subsystem *subsys, char *page) +static ssize_t ipl_type_show(struct kset *kset, char *page) { return sprintf(page, "%s\n", ipl_type_str(ipl_info.type)); } static struct subsys_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); -static ssize_t sys_ipl_device_show(struct subsystem *subsys, char *page) +static ssize_t sys_ipl_device_show(struct kset *kset, char *page) { struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; @@ -371,7 +371,7 @@ static struct attribute_group ipl_fcp_attr_group = { /* CCW ipl device attributes */ -static ssize_t ipl_ccw_loadparm_show(struct subsystem *subsys, char *page) +static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page) { char loadparm[LOADPARM_LEN + 1] = {}; @@ -469,7 +469,7 @@ static void reipl_get_ascii_loadparm(char *loadparm) strstrip(loadparm); } -static ssize_t reipl_ccw_loadparm_show(struct subsystem *subsys, char *page) +static ssize_t reipl_ccw_loadparm_show(struct kset *kset, char *page) { char buf[LOADPARM_LEN + 1]; @@ -477,7 +477,7 @@ static ssize_t reipl_ccw_loadparm_show(struct subsystem *subsys, char *page) return sprintf(page, "%s\n", buf); } -static ssize_t reipl_ccw_loadparm_store(struct subsystem *subsys, +static ssize_t reipl_ccw_loadparm_store(struct kset *kset, const char *buf, size_t len) { int i, lp_len; @@ -572,12 +572,12 @@ static int reipl_set_type(enum ipl_type type) return 0; } -static ssize_t reipl_type_show(struct subsystem *subsys, char *page) +static ssize_t reipl_type_show(struct kset *kset, char *page) { return sprintf(page, "%s\n", ipl_type_str(reipl_type)); } -static ssize_t reipl_type_store(struct subsystem *subsys, const char *buf, +static ssize_t reipl_type_store(struct kset *kset, const char *buf, size_t len) { int rc = -EINVAL; @@ -665,12 +665,12 @@ static int dump_set_type(enum dump_type type) return 0; } -static ssize_t dump_type_show(struct subsystem *subsys, char *page) +static ssize_t dump_type_show(struct kset *kset, char *page) { return sprintf(page, "%s\n", dump_type_str(dump_type)); } -static ssize_t dump_type_store(struct subsystem *subsys, const char *buf, +static ssize_t dump_type_store(struct kset *kset, const char *buf, size_t len) { int rc = -EINVAL; @@ -697,12 +697,12 @@ static decl_subsys(shutdown_actions, NULL, NULL); /* on panic */ -static ssize_t on_panic_show(struct subsystem *subsys, char *page) +static ssize_t on_panic_show(struct kset *kset, char *page) { return sprintf(page, "%s\n", shutdown_action_str(on_panic_action)); } -static ssize_t on_panic_store(struct subsystem *subsys, const char *buf, +static ssize_t on_panic_store(struct kset *kset, const char *buf, size_t len) { if (strncmp(buf, SHUTDOWN_REIPL_STR, strlen(SHUTDOWN_REIPL_STR)) == 0) diff --git a/block/genhd.c b/block/genhd.c index 441432a142f2..b5664440896c 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -17,7 +17,7 @@ #include #include -struct subsystem block_subsys; +struct kset block_subsys; static DEFINE_MUTEX(block_subsys_lock); /* @@ -221,7 +221,7 @@ static void *part_start(struct seq_file *part, loff_t *pos) loff_t l = *pos; mutex_lock(&block_subsys_lock); - list_for_each(p, &block_subsys.kset.list) + list_for_each(p, &block_subsys.list) if (!l--) return list_entry(p, struct gendisk, kobj.entry); return NULL; @@ -231,7 +231,7 @@ static void *part_next(struct seq_file *part, void *v, loff_t *pos) { struct list_head *p = ((struct gendisk *)v)->kobj.entry.next; ++*pos; - return p==&block_subsys.kset.list ? NULL : + return p==&block_subsys.list ? NULL : list_entry(p, struct gendisk, kobj.entry); } @@ -246,7 +246,7 @@ static int show_partition(struct seq_file *part, void *v) int n; char buf[BDEVNAME_SIZE]; - if (&sgp->kobj.entry == block_subsys.kset.list.next) + if (&sgp->kobj.entry == block_subsys.list.next) seq_puts(part, "major minor #blocks name\n\n"); /* Don't show non-partitionable removeable devices or empty devices */ @@ -565,7 +565,7 @@ static void *diskstats_start(struct seq_file *part, loff_t *pos) struct list_head *p; mutex_lock(&block_subsys_lock); - list_for_each(p, &block_subsys.kset.list) + list_for_each(p, &block_subsys.list) if (!k--) return list_entry(p, struct gendisk, kobj.entry); return NULL; @@ -575,7 +575,7 @@ static void *diskstats_next(struct seq_file *part, void *v, loff_t *pos) { struct list_head *p = ((struct gendisk *)v)->kobj.entry.next; ++*pos; - return p==&block_subsys.kset.list ? NULL : + return p==&block_subsys.list ? NULL : list_entry(p, struct gendisk, kobj.entry); } diff --git a/drivers/base/base.h b/drivers/base/base.h index d597f2659b23..5512d84452f2 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -45,3 +45,5 @@ struct class_device_attribute *to_class_dev_attr(struct attribute *_attr) extern char *make_class_name(const char *name, struct kobject *kobj); extern void devres_release_all(struct device *dev); + +extern struct kset devices_subsys; diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 1d76e2349654..dca734819e50 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -17,7 +17,7 @@ #include "power/power.h" #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) -#define to_bus(obj) container_of(obj, struct bus_type, subsys.kset.kobj) +#define to_bus(obj) container_of(obj, struct bus_type, subsys.kobj) /* * sysfs bindings for drivers @@ -123,7 +123,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) { int error; if (get_bus(bus)) { - error = sysfs_create_file(&bus->subsys.kset.kobj, &attr->attr); + error = sysfs_create_file(&bus->subsys.kobj, &attr->attr); put_bus(bus); } else error = -EINVAL; @@ -133,7 +133,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr) { if (get_bus(bus)) { - sysfs_remove_file(&bus->subsys.kset.kobj, &attr->attr); + sysfs_remove_file(&bus->subsys.kobj, &attr->attr); put_bus(bus); } } @@ -397,7 +397,7 @@ static void device_remove_attrs(struct bus_type * bus, struct device * dev) static int make_deprecated_bus_links(struct device *dev) { return sysfs_create_link(&dev->kobj, - &dev->bus->subsys.kset.kobj, "bus"); + &dev->bus->subsys.kobj, "bus"); } static void remove_deprecated_bus_links(struct device *dev) @@ -431,7 +431,7 @@ int bus_add_device(struct device * dev) if (error) goto out_id; error = sysfs_create_link(&dev->kobj, - &dev->bus->subsys.kset.kobj, "subsystem"); + &dev->bus->subsys.kobj, "subsystem"); if (error) goto out_subsys; error = make_deprecated_bus_links(dev); @@ -810,7 +810,7 @@ int bus_register(struct bus_type * bus) BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier); - retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name); + retval = kobject_set_name(&bus->subsys.kobj, "%s", bus->name); if (retval) goto out; @@ -820,13 +820,13 @@ int bus_register(struct bus_type * bus) goto out; kobject_set_name(&bus->devices.kobj, "devices"); - bus->devices.subsys = &bus->subsys; + bus->devices.kobj.parent = &bus->subsys.kobj; retval = kset_register(&bus->devices); if (retval) goto bus_devices_fail; kobject_set_name(&bus->drivers.kobj, "drivers"); - bus->drivers.subsys = &bus->subsys; + bus->drivers.kobj.parent = &bus->subsys.kobj; bus->drivers.ktype = &ktype_driver; retval = kset_register(&bus->drivers); if (retval) diff --git a/drivers/base/class.c b/drivers/base/class.c index 80bbb2074636..20c4ea6eb50d 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -19,10 +19,8 @@ #include #include "base.h" -extern struct subsystem devices_subsys; - #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) -#define to_class(obj) container_of(obj, struct class, subsys.kset.kobj) +#define to_class(obj) container_of(obj, struct class, subsys.kobj) static ssize_t class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) @@ -80,7 +78,7 @@ int class_create_file(struct class * cls, const struct class_attribute * attr) { int error; if (cls) { - error = sysfs_create_file(&cls->subsys.kset.kobj, &attr->attr); + error = sysfs_create_file(&cls->subsys.kobj, &attr->attr); } else error = -EINVAL; return error; @@ -89,7 +87,7 @@ int class_create_file(struct class * cls, const struct class_attribute * attr) void class_remove_file(struct class * cls, const struct class_attribute * attr) { if (cls) - sysfs_remove_file(&cls->subsys.kset.kobj, &attr->attr); + sysfs_remove_file(&cls->subsys.kobj, &attr->attr); } static struct class *class_get(struct class *cls) @@ -147,7 +145,7 @@ int class_register(struct class * cls) INIT_LIST_HEAD(&cls->interfaces); kset_init(&cls->class_dirs); init_MUTEX(&cls->sem); - error = kobject_set_name(&cls->subsys.kset.kobj, "%s", cls->name); + error = kobject_set_name(&cls->subsys.kobj, "%s", cls->name); if (error) return error; @@ -611,7 +609,7 @@ int class_device_add(struct class_device *class_dev) if (parent_class_dev) class_dev->kobj.parent = &parent_class_dev->kobj; else - class_dev->kobj.parent = &parent_class->subsys.kset.kobj; + class_dev->kobj.parent = &parent_class->subsys.kobj; error = kobject_add(&class_dev->kobj); if (error) @@ -619,7 +617,7 @@ int class_device_add(struct class_device *class_dev) /* add the needed attributes to this device */ error = sysfs_create_link(&class_dev->kobj, - &parent_class->subsys.kset.kobj, "subsystem"); + &parent_class->subsys.kobj, "subsystem"); if (error) goto out3; class_dev->uevent_attr.attr.name = "uevent"; @@ -917,8 +915,8 @@ int __init classes_init(void) /* ick, this is ugly, the things we go through to keep from showing up * in sysfs... */ subsystem_init(&class_obj_subsys); - if (!class_obj_subsys.kset.subsys) - class_obj_subsys.kset.subsys = &class_obj_subsys; + if (!class_obj_subsys.kobj.parent) + class_obj_subsys.kobj.parent = &class_obj_subsys.kobj; return 0; } diff --git a/drivers/base/core.c b/drivers/base/core.c index 59d9816c332e..b78fc1e68264 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -565,7 +565,7 @@ static struct kobject * get_device_parent(struct device *dev, /* Set the parent to the class, not the parent device */ /* this keeps sysfs from having a symlink to make old udevs happy */ if (dev->class) - return &dev->class->subsys.kset.kobj; + return &dev->class->subsys.kobj; else if (parent) return &parent->kobj; @@ -577,7 +577,7 @@ static struct kobject *virtual_device_parent(struct device *dev) static struct kobject *virtual_dir = NULL; if (!virtual_dir) - virtual_dir = kobject_add_dir(&devices_subsys.kset.kobj, "virtual"); + virtual_dir = kobject_add_dir(&devices_subsys.kobj, "virtual"); return virtual_dir; } @@ -711,12 +711,12 @@ int device_add(struct device *dev) } if (dev->class) { - sysfs_create_link(&dev->kobj, &dev->class->subsys.kset.kobj, + sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj, "subsystem"); /* If this is not a "fake" compatible device, then create the * symlink from the class to the device. */ - if (dev->kobj.parent != &dev->class->subsys.kset.kobj) - sysfs_create_link(&dev->class->subsys.kset.kobj, + if (dev->kobj.parent != &dev->class->subsys.kobj) + sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, dev->bus_id); if (parent) { sysfs_create_link(&dev->kobj, &dev->parent->kobj, @@ -774,8 +774,8 @@ int device_add(struct device *dev) sysfs_remove_link(&dev->kobj, "subsystem"); /* If this is not a "fake" compatible device, remove the * symlink from the class to the device. */ - if (dev->kobj.parent != &dev->class->subsys.kset.kobj) - sysfs_remove_link(&dev->class->subsys.kset.kobj, + if (dev->kobj.parent != &dev->class->subsys.kobj) + sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); if (parent) { #ifdef CONFIG_SYSFS_DEPRECATED @@ -875,8 +875,8 @@ void device_del(struct device * dev) sysfs_remove_link(&dev->kobj, "subsystem"); /* If this is not a "fake" compatible device, remove the * symlink from the class to the device. */ - if (dev->kobj.parent != &dev->class->subsys.kset.kobj) - sysfs_remove_link(&dev->class->subsys.kset.kobj, + if (dev->kobj.parent != &dev->class->subsys.kobj) + sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); if (parent) { #ifdef CONFIG_SYSFS_DEPRECATED @@ -1192,9 +1192,9 @@ int device_rename(struct device *dev, char *new_name) #endif if (dev->class) { - sysfs_remove_link(&dev->class->subsys.kset.kobj, + sysfs_remove_link(&dev->class->subsys.kobj, old_symlink_name); - sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj, + sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, dev->bus_id); } put_device(dev); diff --git a/drivers/base/firmware.c b/drivers/base/firmware.c index cb1b98ae0d58..90c862932169 100644 --- a/drivers/base/firmware.c +++ b/drivers/base/firmware.c @@ -17,13 +17,13 @@ static decl_subsys(firmware, NULL, NULL); -int firmware_register(struct subsystem * s) +int firmware_register(struct kset *s) { - kset_set_kset_s(s, firmware_subsys); + kobj_set_kset_s(s, firmware_subsys); return subsystem_register(s); } -void firmware_unregister(struct subsystem * s) +void firmware_unregister(struct kset *s) { subsystem_unregister(s); } diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c index 58b6f77a1b34..a47ee1b70d20 100644 --- a/drivers/base/power/shutdown.c +++ b/drivers/base/power/shutdown.c @@ -16,8 +16,6 @@ #define to_dev(node) container_of(node, struct device, kobj.entry) -extern struct subsystem devices_subsys; - /** * We handle system devices differently - we suspend and shut them @@ -36,7 +34,7 @@ void device_shutdown(void) { struct device * dev, *devn; - list_for_each_entry_safe_reverse(dev, devn, &devices_subsys.kset.list, + list_for_each_entry_safe_reverse(dev, devn, &devices_subsys.list, kobj.entry) { if (dev->bus && dev->bus->shutdown) { dev_dbg(dev, "shutdown\n"); diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 04e5db445c74..29f1291966c1 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -25,7 +25,7 @@ #include "base.h" -extern struct subsystem devices_subsys; +extern struct kset devices_subsys; #define to_sysdev(k) container_of(k, struct sys_device, kobj) #define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr) @@ -138,7 +138,7 @@ int sysdev_class_register(struct sysdev_class * cls) pr_debug("Registering sysdev class '%s'\n", kobject_name(&cls->kset.kobj)); INIT_LIST_HEAD(&cls->drivers); - cls->kset.subsys = &system_subsys; + cls->kset.kobj.parent = &system_subsys.kobj; kset_set_kset_s(cls, system_subsys); return kset_register(&cls->kset); } @@ -309,7 +309,7 @@ void sysdev_shutdown(void) pr_debug("Shutting Down System Devices\n"); down(&sysdev_drivers_lock); - list_for_each_entry_reverse(cls, &system_subsys.kset.list, + list_for_each_entry_reverse(cls, &system_subsys.list, kset.kobj.entry) { struct sys_device * sysdev; @@ -384,7 +384,7 @@ int sysdev_suspend(pm_message_t state) pr_debug("Suspending System Devices\n"); - list_for_each_entry_reverse(cls, &system_subsys.kset.list, + list_for_each_entry_reverse(cls, &system_subsys.list, kset.kobj.entry) { pr_debug("Suspending type '%s':\n", @@ -457,7 +457,7 @@ gbl_driver: } /* resume other classes */ - list_for_each_entry_continue(cls, &system_subsys.kset.list, + list_for_each_entry_continue(cls, &system_subsys.list, kset.kobj.entry) { list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { pr_debug(" %s\n", kobject_name(&err_dev->kobj)); @@ -483,7 +483,7 @@ int sysdev_resume(void) pr_debug("Resuming System Devices\n"); - list_for_each_entry(cls, &system_subsys.kset.list, kset.kobj.entry) { + list_for_each_entry(cls, &system_subsys.list, kset.kobj.entry) { struct sys_device * sysdev; pr_debug("Resuming type '%s':\n", @@ -501,7 +501,7 @@ int sysdev_resume(void) int __init system_bus_init(void) { - system_subsys.kset.kobj.parent = &devices_subsys.kset.kobj; + system_subsys.kobj.parent = &devices_subsys.kobj; return subsystem_register(&system_subsys); } diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index c6281ccd4fe7..1324984a4c35 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -409,7 +409,7 @@ static struct kobj_type ktype_efivar = { }; static ssize_t -dummy(struct subsystem *sub, char *buf) +dummy(struct kset *kset, char *buf) { return -ENODEV; } @@ -422,7 +422,7 @@ efivar_unregister(struct efivar_entry *var) static ssize_t -efivar_create(struct subsystem *sub, const char *buf, size_t count) +efivar_create(struct kset *kset, const char *buf, size_t count) { struct efi_variable *new_var = (struct efi_variable *)buf; struct efivar_entry *search_efivar, *n; @@ -480,7 +480,7 @@ efivar_create(struct subsystem *sub, const char *buf, size_t count) } static ssize_t -efivar_delete(struct subsystem *sub, const char *buf, size_t count) +efivar_delete(struct kset *kset, const char *buf, size_t count) { struct efi_variable *del_var = (struct efi_variable *)buf; struct efivar_entry *search_efivar, *n; @@ -551,11 +551,11 @@ static struct subsys_attribute *var_subsys_attrs[] = { * the efivars driver */ static ssize_t -systab_read(struct subsystem *entry, char *buf) +systab_read(struct kset *kset, char *buf) { char *str = buf; - if (!entry || !buf) + if (!kset || !buf) return -EINVAL; if (efi.mps != EFI_INVALID_TABLE_ADDR) @@ -687,7 +687,7 @@ efivars_init(void) goto out_free; } - kset_set_kset_s(&vars_subsys, efi_subsys); + kobj_set_kset_s(&vars_subsys, efi_subsys); error = subsystem_register(&vars_subsys); diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 6439f378f6cc..6e55b2c5874e 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -650,7 +650,7 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct dev->cdev.dev, evdev->name); /* temporary symlink to keep userspace happy */ - sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, + sysfs_create_link(&input_class.subsys.kobj, &cdev->kobj, evdev->name); return &evdev->handle; @@ -661,7 +661,7 @@ static void evdev_disconnect(struct input_handle *handle) struct evdev *evdev = handle->private; struct evdev_list *list; - sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name); + sysfs_remove_link(&input_class.subsys.kobj, evdev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor)); evdev->exist = 0; diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 9f3529ad3fda..d2482e4f71be 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -539,7 +539,7 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct dev->cdev.dev, joydev->name); /* temporary symlink to keep userspace happy */ - sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, + sysfs_create_link(&input_class.subsys.kobj, &cdev->kobj, joydev->name); return &joydev->handle; @@ -550,7 +550,7 @@ static void joydev_disconnect(struct input_handle *handle) struct joydev *joydev = handle->private; struct joydev_list *list; - sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name); + sysfs_remove_link(&input_class.subsys.kobj, joydev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); joydev->exist = 0; diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 664bcc8116fc..074fee429d1b 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -661,7 +661,7 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru dev->cdev.dev, mousedev->name); /* temporary symlink to keep userspace happy */ - sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, + sysfs_create_link(&input_class.subsys.kobj, &cdev->kobj, mousedev->name); return &mousedev->handle; @@ -672,7 +672,7 @@ static void mousedev_disconnect(struct input_handle *handle) struct mousedev *mousedev = handle->private; struct mousedev_list *list; - sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name); + sysfs_remove_link(&input_class.subsys.kobj, mousedev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); mousedev->exist = 0; diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index 0300dca8591d..05dfc10bc079 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c @@ -420,7 +420,7 @@ static struct input_handle *tsdev_connect(struct input_handler *handler, dev->cdev.dev, tsdev->name); /* temporary symlink to keep userspace happy */ - sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, + sysfs_create_link(&input_class.subsys.kobj, &cdev->kobj, tsdev->name); return &tsdev->handle; @@ -431,7 +431,7 @@ static void tsdev_disconnect(struct input_handle *handle) struct tsdev *tsdev = handle->private; struct tsdev_list *list; - sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name); + sysfs_remove_link(&input_class.subsys.kobj, tsdev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor)); tsdev->exist = 0; diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index ea1b7a63598e..815e445c3125 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c @@ -520,17 +520,17 @@ static struct pdcspath_entry *pdcspath_entries[] = { /** * pdcs_size_read - Stable Storage size output. - * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. */ static ssize_t -pdcs_size_read(struct subsystem *entry, char *buf) +pdcs_size_read(struct kset *kset, char *buf) { char *out = buf; - - if (!entry || !buf) + + if (!kset || !buf) return -EINVAL; - + /* show the size of the stable storage */ out += sprintf(out, "%ld\n", pdcs_size); @@ -539,17 +539,17 @@ pdcs_size_read(struct subsystem *entry, char *buf) /** * pdcs_auto_read - Stable Storage autoboot/search flag output. - * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag */ static ssize_t -pdcs_auto_read(struct subsystem *entry, char *buf, int knob) +pdcs_auto_read(struct kset *kset, char *buf, int knob) { char *out = buf; struct pdcspath_entry *pathentry; - if (!entry || !buf) + if (!kset || !buf) return -EINVAL; /* Current flags are stored in primary boot path entry */ @@ -565,40 +565,40 @@ pdcs_auto_read(struct subsystem *entry, char *buf, int knob) /** * pdcs_autoboot_read - Stable Storage autoboot flag output. - * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. */ static inline ssize_t -pdcs_autoboot_read(struct subsystem *entry, char *buf) +pdcs_autoboot_read(struct kset *kset, char *buf) { - return pdcs_auto_read(entry, buf, PF_AUTOBOOT); + return pdcs_auto_read(kset, buf, PF_AUTOBOOT); } /** * pdcs_autosearch_read - Stable Storage autoboot flag output. - * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. */ static inline ssize_t -pdcs_autosearch_read(struct subsystem *entry, char *buf) +pdcs_autosearch_read(struct kset *kset, char *buf) { - return pdcs_auto_read(entry, buf, PF_AUTOSEARCH); + return pdcs_auto_read(kset, buf, PF_AUTOSEARCH); } /** * pdcs_timer_read - Stable Storage timer count output (in seconds). - * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. * * The value of the timer field correponds to a number of seconds in powers of 2. */ static ssize_t -pdcs_timer_read(struct subsystem *entry, char *buf) +pdcs_timer_read(struct kset *kset, char *buf) { char *out = buf; struct pdcspath_entry *pathentry; - if (!entry || !buf) + if (!kset || !buf) return -EINVAL; /* Current flags are stored in primary boot path entry */ @@ -615,15 +615,15 @@ pdcs_timer_read(struct subsystem *entry, char *buf) /** * pdcs_osid_read - Stable Storage OS ID register output. - * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. */ static ssize_t -pdcs_osid_read(struct subsystem *entry, char *buf) +pdcs_osid_read(struct kset *kset, char *buf) { char *out = buf; - if (!entry || !buf) + if (!kset || !buf) return -EINVAL; out += sprintf(out, "%s dependent data (0x%.4x)\n", @@ -634,18 +634,18 @@ pdcs_osid_read(struct subsystem *entry, char *buf) /** * pdcs_osdep1_read - Stable Storage OS-Dependent data area 1 output. - * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. * * This can hold 16 bytes of OS-Dependent data. */ static ssize_t -pdcs_osdep1_read(struct subsystem *entry, char *buf) +pdcs_osdep1_read(struct kset *kset, char *buf) { char *out = buf; u32 result[4]; - if (!entry || !buf) + if (!kset || !buf) return -EINVAL; if (pdc_stable_read(PDCS_ADDR_OSD1, &result, sizeof(result)) != PDC_OK) @@ -661,18 +661,18 @@ pdcs_osdep1_read(struct subsystem *entry, char *buf) /** * pdcs_diagnostic_read - Stable Storage Diagnostic register output. - * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. * * I have NFC how to interpret the content of that register ;-). */ static ssize_t -pdcs_diagnostic_read(struct subsystem *entry, char *buf) +pdcs_diagnostic_read(struct kset *kset, char *buf) { char *out = buf; u32 result; - if (!entry || !buf) + if (!kset || !buf) return -EINVAL; /* get diagnostic */ @@ -686,18 +686,18 @@ pdcs_diagnostic_read(struct subsystem *entry, char *buf) /** * pdcs_fastsize_read - Stable Storage FastSize register output. - * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. * * This register holds the amount of system RAM to be tested during boot sequence. */ static ssize_t -pdcs_fastsize_read(struct subsystem *entry, char *buf) +pdcs_fastsize_read(struct kset *kset, char *buf) { char *out = buf; u32 result; - if (!entry || !buf) + if (!kset || !buf) return -EINVAL; /* get fast-size */ @@ -715,13 +715,13 @@ pdcs_fastsize_read(struct subsystem *entry, char *buf) /** * pdcs_osdep2_read - Stable Storage OS-Dependent data area 2 output. - * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. * * This can hold pdcs_size - 224 bytes of OS-Dependent data, when available. */ static ssize_t -pdcs_osdep2_read(struct subsystem *entry, char *buf) +pdcs_osdep2_read(struct kset *kset, char *buf) { char *out = buf; unsigned long size; @@ -733,7 +733,7 @@ pdcs_osdep2_read(struct subsystem *entry, char *buf) size = pdcs_size - 224; - if (!entry || !buf) + if (!kset || !buf) return -EINVAL; for (i=0; i #include -int mlog_sys_init(struct subsystem *o2cb_subsys); +int mlog_sys_init(struct kset *o2cb_subsys); void mlog_sys_shutdown(void); #endif /* O2CLUSTER_MASKLOG_H */ diff --git a/fs/ocfs2/cluster/sys.c b/fs/ocfs2/cluster/sys.c index 1d9f6acafa2e..64f6f378fd09 100644 --- a/fs/ocfs2/cluster/sys.c +++ b/fs/ocfs2/cluster/sys.c @@ -42,7 +42,6 @@ struct o2cb_attribute { #define O2CB_ATTR(_name, _mode, _show, _store) \ struct o2cb_attribute o2cb_attr_##_name = __ATTR(_name, _mode, _show, _store) -#define to_o2cb_subsys(k) container_of(to_kset(k), struct subsystem, kset) #define to_o2cb_attr(_attr) container_of(_attr, struct o2cb_attribute, attr) static ssize_t o2cb_interface_revision_show(char *buf) @@ -79,7 +78,7 @@ static ssize_t o2cb_show(struct kobject * kobj, struct attribute * attr, char * buffer) { struct o2cb_attribute *o2cb_attr = to_o2cb_attr(attr); - struct subsystem *sbs = to_o2cb_subsys(kobj); + struct kset *sbs = to_kset(kobj); BUG_ON(sbs != &o2cb_subsys); @@ -93,7 +92,7 @@ o2cb_store(struct kobject * kobj, struct attribute * attr, const char * buffer, size_t count) { struct o2cb_attribute *o2cb_attr = to_o2cb_attr(attr); - struct subsystem *sbs = to_o2cb_subsys(kobj); + struct kset *sbs = to_kset(kobj); BUG_ON(sbs != &o2cb_subsys); @@ -112,7 +111,7 @@ int o2cb_sys_init(void) { int ret; - o2cb_subsys.kset.kobj.ktype = &o2cb_subsys_type; + o2cb_subsys.kobj.ktype = &o2cb_subsys_type; ret = subsystem_register(&o2cb_subsys); if (ret) return ret; diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 8a7d0035ad7a..f01572fca02f 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -312,7 +312,7 @@ static struct attribute * default_attrs[] = { NULL, }; -extern struct subsystem block_subsys; +extern struct kset block_subsys; static void part_release(struct kobject *kobj) { @@ -388,7 +388,7 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, kobject_add(&p->kobj); if (!disk->part_uevent_suppress) kobject_uevent(&p->kobj, KOBJ_ADD); - sysfs_create_link(&p->kobj, &block_subsys.kset.kobj, "subsystem"); + sysfs_create_link(&p->kobj, &block_subsys.kobj, "subsystem"); if (flags & ADDPART_FLAG_WHOLEDISK) { static struct attribute addpartattr = { .name = "whole_disk", @@ -444,7 +444,7 @@ static int disk_sysfs_symlinks(struct gendisk *disk) goto err_out_dev_link; } - err = sysfs_create_link(&disk->kobj, &block_subsys.kset.kobj, + err = sysfs_create_link(&disk->kobj, &block_subsys.kobj, "subsystem"); if (err) goto err_out_disk_name_lnk; diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index db0413a411d6..0e637adc2b87 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -13,8 +13,7 @@ #include "sysfs.h" -#define to_subsys(k) container_of(k,struct subsystem,kset.kobj) -#define to_sattr(a) container_of(a,struct subsys_attribute,attr) +#define to_sattr(a) container_of(a,struct subsys_attribute, attr) /* * Subsystem file operations. @@ -24,12 +23,12 @@ static ssize_t subsys_attr_show(struct kobject * kobj, struct attribute * attr, char * page) { - struct subsystem * s = to_subsys(kobj); + struct kset *kset = to_kset(kobj); struct subsys_attribute * sattr = to_sattr(attr); ssize_t ret = -EIO; if (sattr->show) - ret = sattr->show(s,page); + ret = sattr->show(kset, page); return ret; } @@ -37,12 +36,12 @@ static ssize_t subsys_attr_store(struct kobject * kobj, struct attribute * attr, const char * page, size_t count) { - struct subsystem * s = to_subsys(kobj); + struct kset *kset = to_kset(kobj); struct subsys_attribute * sattr = to_sattr(attr); ssize_t ret = -EIO; if (sattr->store) - ret = sattr->store(s,page,count); + ret = sattr->store(kset, page, count); return ret; } diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 0d9f984a60a1..16c3c441256e 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -316,7 +316,7 @@ struct acpi_bus_event { u32 data; }; -extern struct subsystem acpi_subsys; +extern struct kset acpi_subsys; /* * External Functions diff --git a/include/linux/device.h b/include/linux/device.h index a0cd2ced31a9..ee292fe87cb2 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -53,7 +53,7 @@ struct bus_type { const char * name; struct module * owner; - struct subsystem subsys; + struct kset subsys; struct kset drivers; struct kset devices; struct klist klist_devices; @@ -179,7 +179,7 @@ struct class { const char * name; struct module * owner; - struct subsystem subsys; + struct kset subsys; struct list_head children; struct list_head devices; struct list_head interfaces; @@ -559,8 +559,8 @@ extern void device_shutdown(void); /* drivers/base/firmware.c */ -extern int __must_check firmware_register(struct subsystem *); -extern void firmware_unregister(struct subsystem *); +extern int __must_check firmware_register(struct kset *); +extern void firmware_unregister(struct kset *); /* debugging and troubleshooting/diagnostic helpers. */ extern const char *dev_driver_string(struct device *dev); diff --git a/include/linux/fs.h b/include/linux/fs.h index 095a9c9a64fb..7c0077f06e24 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1416,7 +1416,7 @@ extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *, extern int vfs_statfs(struct dentry *, struct kstatfs *); /* /sys/fs */ -extern struct subsystem fs_subsys; +extern struct kset fs_subsys; #define FLOCK_VERIFY_READ 1 #define FLOCK_VERIFY_WRITE 2 diff --git a/include/linux/kobject.h b/include/linux/kobject.h index eb0e63ef297f..c288e41ba331 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -124,7 +124,6 @@ struct kset_uevent_ops { }; struct kset { - struct subsystem * subsys; struct kobj_type * ktype; struct list_head list; spinlock_t list_lock; @@ -171,32 +170,23 @@ extern struct kobject * kset_find_obj(struct kset *, const char *); #define set_kset_name(str) .kset = { .kobj = { .name = str } } - -struct subsystem { - struct kset kset; -}; - #define decl_subsys(_name,_type,_uevent_ops) \ -struct subsystem _name##_subsys = { \ - .kset = { \ - .kobj = { .name = __stringify(_name) }, \ - .ktype = _type, \ - .uevent_ops =_uevent_ops, \ - } \ +struct kset _name##_subsys = { \ + .kobj = { .name = __stringify(_name) }, \ + .ktype = _type, \ + .uevent_ops =_uevent_ops, \ } #define decl_subsys_name(_varname,_name,_type,_uevent_ops) \ -struct subsystem _varname##_subsys = { \ - .kset = { \ - .kobj = { .name = __stringify(_name) }, \ - .ktype = _type, \ - .uevent_ops =_uevent_ops, \ - } \ +struct kset _varname##_subsys = { \ + .kobj = { .name = __stringify(_name) }, \ + .ktype = _type, \ + .uevent_ops =_uevent_ops, \ } /* The global /sys/kernel/ subsystem for people to chain off of */ -extern struct subsystem kernel_subsys; +extern struct kset kernel_subsys; /* The global /sys/hypervisor/ subsystem */ -extern struct subsystem hypervisor_subsys; +extern struct kset hypervisor_subsys; /** * Helpers for setting the kset of registered objects. @@ -214,7 +204,7 @@ extern struct subsystem hypervisor_subsys; */ #define kobj_set_kset_s(obj,subsys) \ - (obj)->kobj.kset = &(subsys).kset + (obj)->kobj.kset = &(subsys) /** * kset_set_kset_s(obj,subsys) - set kset for embedded kset. @@ -228,7 +218,7 @@ extern struct subsystem hypervisor_subsys; */ #define kset_set_kset_s(obj,subsys) \ - (obj)->kset.kobj.kset = &(subsys).kset + (obj)->kset.kobj.kset = &(subsys) /** * subsys_set_kset(obj,subsys) - set kset for subsystem @@ -241,29 +231,31 @@ extern struct subsystem hypervisor_subsys; */ #define subsys_set_kset(obj,_subsys) \ - (obj)->subsys.kset.kobj.kset = &(_subsys).kset + (obj)->subsys.kobj.kset = &(_subsys) -extern void subsystem_init(struct subsystem *); -extern int __must_check subsystem_register(struct subsystem *); -extern void subsystem_unregister(struct subsystem *); +extern void subsystem_init(struct kset *); +extern int __must_check subsystem_register(struct kset *); +extern void subsystem_unregister(struct kset *); -static inline struct subsystem * subsys_get(struct subsystem * s) +static inline struct kset *subsys_get(struct kset *s) { - return s ? container_of(kset_get(&s->kset),struct subsystem,kset) : NULL; + if (s) + return kset_get(s); + return NULL; } -static inline void subsys_put(struct subsystem * s) +static inline void subsys_put(struct kset *s) { - kset_put(&s->kset); + kset_put(s); } struct subsys_attribute { struct attribute attr; - ssize_t (*show)(struct subsystem *, char *); - ssize_t (*store)(struct subsystem *, const char *, size_t); + ssize_t (*show)(struct kset *, char *); + ssize_t (*store)(struct kset *, const char *, size_t); }; -extern int __must_check subsys_create_file(struct subsystem * , +extern int __must_check subsys_create_file(struct kset *, struct subsys_attribute *); #if defined(CONFIG_HOTPLUG) diff --git a/include/linux/module.h b/include/linux/module.h index 95679eb8571e..f0b0faf42d5d 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -568,7 +568,7 @@ struct device_driver; #ifdef CONFIG_SYSFS struct module; -extern struct subsystem module_subsys; +extern struct kset module_subsys; int mod_sysfs_init(struct module *mod); int mod_sysfs_setup(struct module *mod, diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index a675a05c4091..ab4cb6ecd47c 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h @@ -174,7 +174,7 @@ extern int pci_hp_register (struct hotplug_slot *slot); extern int pci_hp_deregister (struct hotplug_slot *slot); extern int __must_check pci_hp_change_slot_info (struct hotplug_slot *slot, struct hotplug_slot_info *info); -extern struct subsystem pci_hotplug_slots_subsys; +extern struct kset pci_hotplug_slots_subsys; /* PCI Setting Record (Type 0) */ struct hpp_type0 { diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c index e0ffe4ab0917..559deca5ed15 100644 --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c @@ -24,18 +24,18 @@ static struct subsys_attribute _name##_attr = \ #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) /* current uevent sequence number */ -static ssize_t uevent_seqnum_show(struct subsystem *subsys, char *page) +static ssize_t uevent_seqnum_show(struct kset *kset, char *page) { return sprintf(page, "%llu\n", (unsigned long long)uevent_seqnum); } KERNEL_ATTR_RO(uevent_seqnum); /* uevent helper program, used during early boo */ -static ssize_t uevent_helper_show(struct subsystem *subsys, char *page) +static ssize_t uevent_helper_show(struct kset *kset, char *page) { return sprintf(page, "%s\n", uevent_helper); } -static ssize_t uevent_helper_store(struct subsystem *subsys, const char *page, size_t count) +static ssize_t uevent_helper_store(struct kset *kset, const char *page, size_t count) { if (count+1 > UEVENT_HELPER_PATH_LEN) return -ENOENT; @@ -49,13 +49,13 @@ KERNEL_ATTR_RW(uevent_helper); #endif #ifdef CONFIG_KEXEC -static ssize_t kexec_loaded_show(struct subsystem *subsys, char *page) +static ssize_t kexec_loaded_show(struct kset *kset, char *page) { return sprintf(page, "%d\n", !!kexec_image); } KERNEL_ATTR_RO(kexec_loaded); -static ssize_t kexec_crash_loaded_show(struct subsystem *subsys, char *page) +static ssize_t kexec_crash_loaded_show(struct kset *kset, char *page) { return sprintf(page, "%d\n", !!kexec_crash_image); } @@ -85,7 +85,7 @@ static int __init ksysfs_init(void) { int error = subsystem_register(&kernel_subsys); if (!error) - error = sysfs_create_group(&kernel_subsys.kset.kobj, + error = sysfs_create_group(&kernel_subsys.kobj, &kernel_attr_group); return error; diff --git a/kernel/module.c b/kernel/module.c index 9da5af668a20..ff982ec435fc 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -45,6 +45,8 @@ #include #include +extern int module_sysfs_initialized; + #if 0 #define DEBUGP printk #else @@ -1117,8 +1119,8 @@ int mod_sysfs_init(struct module *mod) { int err; - if (!module_subsys.kset.subsys) { - printk(KERN_ERR "%s: module_subsys not initialized\n", + if (!module_sysfs_initialized) { + printk(KERN_ERR "%s: module sysfs not initialized\n", mod->name); err = -EINVAL; goto out; @@ -2385,7 +2387,7 @@ void module_add_driver(struct module *mod, struct device_driver *drv) struct kobject *mkobj; /* Lookup built-in module entry in /sys/modules */ - mkobj = kset_find_obj(&module_subsys.kset, drv->mod_name); + mkobj = kset_find_obj(&module_subsys, drv->mod_name); if (mkobj) { mk = container_of(mkobj, struct module_kobject, kobj); /* remember our module structure */ diff --git a/kernel/params.c b/kernel/params.c index 1fc4ac746cd8..312172320b4c 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -691,6 +691,7 @@ static struct kset_uevent_ops module_uevent_ops = { }; decl_subsys(module, &module_ktype, &module_uevent_ops); +int module_sysfs_initialized; static struct kobj_type module_ktype = { .sysfs_ops = &module_sysfs_ops, @@ -709,6 +710,7 @@ static int __init param_sysfs_init(void) __FILE__, __LINE__, ret); return ret; } + module_sysfs_initialized = 1; param_sysfs_builtin(); diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 02e4fb69111a..8df51c23bba4 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c @@ -322,13 +322,13 @@ static const char * const pm_disk_modes[] = { * supports it (as determined from pm_ops->pm_disk_mode). */ -static ssize_t disk_show(struct subsystem * subsys, char * buf) +static ssize_t disk_show(struct kset *kset, char *buf) { return sprintf(buf, "%s\n", pm_disk_modes[pm_disk_mode]); } -static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n) +static ssize_t disk_store(struct kset *kset, const char *buf, size_t n) { int error = 0; int i; @@ -373,13 +373,13 @@ static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n) power_attr(disk); -static ssize_t resume_show(struct subsystem * subsys, char *buf) +static ssize_t resume_show(struct kset *kset, char *buf) { return sprintf(buf,"%d:%d\n", MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device)); } -static ssize_t resume_store(struct subsystem *subsys, const char *buf, size_t n) +static ssize_t resume_store(struct kset *kset, const char *buf, size_t n) { unsigned int maj, min; dev_t res; @@ -405,12 +405,12 @@ static ssize_t resume_store(struct subsystem *subsys, const char *buf, size_t n) power_attr(resume); -static ssize_t image_size_show(struct subsystem * subsys, char *buf) +static ssize_t image_size_show(struct kset *kset, char *buf) { return sprintf(buf, "%lu\n", image_size); } -static ssize_t image_size_store(struct subsystem * subsys, const char * buf, size_t n) +static ssize_t image_size_store(struct kset *kset, const char *buf, size_t n) { unsigned long size; @@ -439,7 +439,7 @@ static struct attribute_group attr_group = { static int __init pm_disk_init(void) { - return sysfs_create_group(&power_subsys.kset.kobj,&attr_group); + return sysfs_create_group(&power_subsys.kobj, &attr_group); } core_initcall(pm_disk_init); diff --git a/kernel/power/main.c b/kernel/power/main.c index 72419a3b1beb..b21c2a56f960 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -285,7 +285,7 @@ decl_subsys(power,NULL,NULL); * proper enumerated value, and initiates a suspend transition. */ -static ssize_t state_show(struct subsystem * subsys, char * buf) +static ssize_t state_show(struct kset *kset, char *buf) { int i; char * s = buf; @@ -298,7 +298,7 @@ static ssize_t state_show(struct subsystem * subsys, char * buf) return (s - buf); } -static ssize_t state_store(struct subsystem * subsys, const char * buf, size_t n) +static ssize_t state_store(struct kset *kset, const char *buf, size_t n) { suspend_state_t state = PM_SUSPEND_STANDBY; const char * const *s; @@ -325,13 +325,13 @@ power_attr(state); #ifdef CONFIG_PM_TRACE int pm_trace_enabled; -static ssize_t pm_trace_show(struct subsystem * subsys, char * buf) +static ssize_t pm_trace_show(struct kset *kset, char *buf) { return sprintf(buf, "%d\n", pm_trace_enabled); } static ssize_t -pm_trace_store(struct subsystem * subsys, const char * buf, size_t n) +pm_trace_store(struct kset *kset, const char *buf, size_t n) { int val; @@ -365,7 +365,7 @@ static int __init pm_init(void) { int error = subsystem_register(&power_subsys); if (!error) - error = sysfs_create_group(&power_subsys.kset.kobj,&attr_group); + error = sysfs_create_group(&power_subsys.kobj,&attr_group); return error; } diff --git a/kernel/power/power.h b/kernel/power/power.h index eb461b816bf4..5f842c3efc4b 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -35,7 +35,7 @@ static struct subsys_attribute _name##_attr = { \ .store = _name##_store, \ } -extern struct subsystem power_subsys; +extern struct kset power_subsys; /* References to section boundaries */ extern const void __nosave_begin, __nosave_end; diff --git a/lib/kobject.c b/lib/kobject.c index cecf2fbede3e..fc5f3f6e7329 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -582,22 +582,10 @@ void kset_init(struct kset * k) /** * kset_add - add a kset object to the hierarchy. * @k: kset. - * - * Simply, this adds the kset's embedded kobject to the - * hierarchy. - * We also try to make sure that the kset's embedded kobject - * has a parent before it is added. We only care if the embedded - * kobject is not part of a kset itself, since kobject_add() - * assigns a parent in that case. - * If that is the case, and the kset has a controlling subsystem, - * then we set the kset's parent to be said subsystem. */ int kset_add(struct kset * k) { - if (!k->kobj.parent && !k->kobj.kset && k->subsys) - k->kobj.parent = &k->subsys->kset.kobj; - return kobject_add(&k->kobj); } @@ -656,53 +644,28 @@ struct kobject * kset_find_obj(struct kset * kset, const char * name) return ret; } - -void subsystem_init(struct subsystem * s) +void subsystem_init(struct kset *s) { - kset_init(&s->kset); + kset_init(s); } -/** - * subsystem_register - register a subsystem. - * @s: the subsystem we're registering. - * - * Once we register the subsystem, we want to make sure that - * the kset points back to this subsystem. - */ - -int subsystem_register(struct subsystem * s) +int subsystem_register(struct kset *s) { - int error; - - if (!s) - return -EINVAL; - - subsystem_init(s); - pr_debug("subsystem %s: registering\n",s->kset.kobj.name); - - if (!(error = kset_add(&s->kset))) { - if (!s->kset.subsys) - s->kset.subsys = s; - } - return error; + return kset_register(s); } -void subsystem_unregister(struct subsystem * s) +void subsystem_unregister(struct kset *s) { - if (!s) - return; - pr_debug("subsystem %s: unregistering\n",s->kset.kobj.name); - kset_unregister(&s->kset); + kset_unregister(s); } - /** * subsystem_create_file - export sysfs attribute file. * @s: subsystem. * @a: subsystem attribute descriptor. */ -int subsys_create_file(struct subsystem * s, struct subsys_attribute * a) +int subsys_create_file(struct kset *s, struct subsys_attribute *a) { int error = 0; @@ -710,28 +673,12 @@ int subsys_create_file(struct subsystem * s, struct subsys_attribute * a) return -EINVAL; if (subsys_get(s)) { - error = sysfs_create_file(&s->kset.kobj,&a->attr); + error = sysfs_create_file(&s->kobj, &a->attr); subsys_put(s); } return error; } - -/** - * subsystem_remove_file - remove sysfs attribute file. - * @s: subsystem. - * @a: attribute desciptor. - */ -#if 0 -void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a) -{ - if (subsys_get(s)) { - sysfs_remove_file(&s->kset.kobj,&a->attr); - subsys_put(s); - } -} -#endif /* 0 */ - EXPORT_SYMBOL(kobject_init); EXPORT_SYMBOL(kobject_register); EXPORT_SYMBOL(kobject_unregister); diff --git a/security/inode.c b/security/inode.c index d7ecf89fbc74..307211ac7346 100644 --- a/security/inode.c +++ b/security/inode.c @@ -321,7 +321,7 @@ static int __init securityfs_init(void) { int retval; - kset_set_kset_s(&security_subsys, kernel_subsys); + kobj_set_kset_s(&security_subsys, kernel_subsys); retval = subsystem_register(&security_subsys); if (retval) return retval; -- cgit v1.2.3-59-g8ed1b From 6473d160b4aba8023bcf38519a5989694dfd51a7 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 6 Mar 2007 02:45:12 -0800 Subject: PCI: Cleanup the includes of I noticed that many source files include while they do not appear to need it. Here is an attempt to clean it all up. In order to find all possibly affected files, I searched for all files including but without any other occurence of "pci" or "PCI". I removed the include statement from all of these, then I compiled an allmodconfig kernel on both i386 and x86_64 and fixed the false positives manually. My tests covered 66% of the affected files, so there could be false positives remaining. Untested files are: arch/alpha/kernel/err_common.c arch/alpha/kernel/err_ev6.c arch/alpha/kernel/err_ev7.c arch/ia64/sn/kernel/huberror.c arch/ia64/sn/kernel/xpnet.c arch/m68knommu/kernel/dma.c arch/mips/lib/iomap.c arch/powerpc/platforms/pseries/ras.c arch/ppc/8260_io/enet.c arch/ppc/8260_io/fcc_enet.c arch/ppc/8xx_io/enet.c arch/ppc/syslib/ppc4xx_sgdma.c arch/sh64/mach-cayman/iomap.c arch/xtensa/kernel/xtensa_ksyms.c arch/xtensa/platform-iss/setup.c drivers/i2c/busses/i2c-at91.c drivers/i2c/busses/i2c-mpc.c drivers/media/video/saa711x.c drivers/misc/hdpuftrs/hdpu_cpustate.c drivers/misc/hdpuftrs/hdpu_nexus.c drivers/net/au1000_eth.c drivers/net/fec_8xx/fec_main.c drivers/net/fec_8xx/fec_mii.c drivers/net/fs_enet/fs_enet-main.c drivers/net/fs_enet/mac-fcc.c drivers/net/fs_enet/mac-fec.c drivers/net/fs_enet/mac-scc.c drivers/net/fs_enet/mii-bitbang.c drivers/net/fs_enet/mii-fec.c drivers/net/ibm_emac/ibm_emac_core.c drivers/net/lasi_82596.c drivers/parisc/hppb.c drivers/sbus/sbus.c drivers/video/g364fb.c drivers/video/platinumfb.c drivers/video/stifb.c drivers/video/valkyriefb.c include/asm-arm/arch-ixp4xx/dma.h sound/oss/au1550_ac97.c I would welcome test reports for these files. I am fine with removing the untested files from the patch if the general opinion is that these changes aren't safe. The tested part would still be nice to have. Note that this patch depends on another header fixup patch I submitted to LKML yesterday: [PATCH] scatterlist.h needs types.h http://lkml.org/lkml/2007/3/01/141 Signed-off-by: Jean Delvare Cc: Badari Pulavarty Signed-off-by: Greg Kroah-Hartman --- arch/alpha/kernel/err_common.c | 1 - arch/alpha/kernel/err_ev6.c | 1 - arch/alpha/kernel/err_ev7.c | 1 - arch/i386/kernel/cpu/cpufreq/speedstep-lib.c | 1 - arch/i386/kernel/cpu/cpufreq/speedstep-smi.c | 2 +- arch/ia64/sn/kernel/huberror.c | 1 - arch/ia64/sn/kernel/xpnet.c | 1 - arch/m68knommu/kernel/dma.c | 1 - arch/mips/lib/iomap.c | 1 - arch/powerpc/platforms/pseries/ras.c | 1 - arch/ppc/8260_io/enet.c | 1 - arch/ppc/8260_io/fcc_enet.c | 1 - arch/ppc/8xx_io/enet.c | 1 - arch/ppc/syslib/ppc4xx_sgdma.c | 1 - arch/sh64/mach-cayman/iomap.c | 1 - arch/xtensa/kernel/xtensa_ksyms.c | 1 - arch/xtensa/platform-iss/setup.c | 1 - drivers/atm/adummy.c | 1 - drivers/char/hw_random/via-rng.c | 1 - drivers/char/pcmcia/synclink_cs.c | 1 - drivers/char/tpm/tpm.h | 1 - drivers/char/watchdog/sc1200wdt.c | 1 - drivers/char/watchdog/scx200_wdt.c | 2 +- drivers/i2c/busses/i2c-at91.c | 1 - drivers/i2c/busses/i2c-mpc.c | 1 - drivers/i2c/busses/i2c-pca-isa.c | 1 - drivers/ieee1394/hosts.c | 1 - drivers/infiniband/core/cm.c | 1 - drivers/infiniband/core/iwcm.c | 1 - drivers/infiniband/core/mad_priv.h | 1 - drivers/infiniband/core/multicast.c | 1 - drivers/infiniband/core/sa_query.c | 1 - drivers/infiniband/core/user_mad.c | 1 - drivers/infiniband/hw/ipath/ipath_fs.c | 1 - drivers/infiniband/hw/ipath/ipath_layer.c | 1 - drivers/infiniband/hw/ipath/ipath_stats.c | 2 -- drivers/infiniband/hw/ipath/ipath_sysfs.c | 1 - drivers/infiniband/hw/mthca/mthca_memfree.h | 1 - drivers/infiniband/ulp/ipoib/ipoib.h | 1 - drivers/isdn/hisax/netjet.c | 1 - drivers/isdn/hysdn/hysdn_proclog.c | 1 - drivers/media/dvb/cinergyT2/cinergyT2.c | 2 +- drivers/media/video/adv7170.c | 1 - drivers/media/video/adv7175.c | 1 - drivers/media/video/bt819.c | 1 - drivers/media/video/bt856.c | 1 - drivers/media/video/bt866.c | 1 - drivers/media/video/cx88/cx88-tvaudio.c | 1 - drivers/media/video/em28xx/em28xx-cards.c | 1 - drivers/media/video/saa7111.c | 1 - drivers/media/video/saa7114.c | 1 - drivers/media/video/saa711x.c | 1 - drivers/media/video/saa7185.c | 1 - drivers/misc/hdpuftrs/hdpu_cpustate.c | 1 - drivers/misc/hdpuftrs/hdpu_nexus.c | 1 - drivers/mtd/devices/doc2000.c | 1 - drivers/mtd/devices/doc2001.c | 1 - drivers/mtd/devices/doc2001plus.c | 1 - drivers/mtd/devices/docecc.c | 1 - drivers/mtd/inftlmount.c | 1 - drivers/mtd/nand/cs553x_nand.c | 1 - drivers/mtd/nftlcore.c | 1 - drivers/net/atl1/atl1_param.c | 1 - drivers/net/au1000_eth.c | 1 - drivers/net/fec_8xx/fec_main.c | 1 - drivers/net/fec_8xx/fec_mii.c | 1 - drivers/net/fs_enet/fs_enet-main.c | 1 - drivers/net/fs_enet/mac-fcc.c | 1 - drivers/net/fs_enet/mac-fec.c | 1 - drivers/net/fs_enet/mac-scc.c | 1 - drivers/net/fs_enet/mii-bitbang.c | 1 - drivers/net/fs_enet/mii-fec.c | 1 - drivers/net/ibm_emac/ibm_emac_core.c | 1 - drivers/net/ixgb/ixgb_osdep.h | 1 - drivers/net/lasi_82596.c | 1 - drivers/net/tokenring/madgemc.c | 1 - drivers/net/tokenring/smctr.c | 1 - drivers/net/tulip/21142.c | 1 - drivers/net/tulip/pnic.c | 1 - drivers/net/tulip/pnic2.c | 1 - drivers/net/tulip/timer.c | 1 - drivers/net/tulip/tulip.h | 1 + drivers/net/wan/lmc/lmc_media.c | 1 - drivers/net/wan/lmc/lmc_proto.c | 1 - drivers/net/wan/pc300_tty.c | 1 - drivers/parisc/hppb.c | 2 -- drivers/pcmcia/cs.c | 1 - drivers/pcmcia/socket_sysfs.c | 1 - drivers/sbus/sbus.c | 1 - drivers/scsi/aacraid/dpcsup.c | 1 - drivers/scsi/aacraid/sa.c | 1 - drivers/scsi/aha1542.c | 1 - drivers/scsi/aic94xx/aic94xx_scb.c | 1 - drivers/scsi/arcmsr/arcmsr_attr.c | 1 - drivers/scsi/libsas/sas_expander.c | 1 - drivers/scsi/libsrp.c | 1 - drivers/usb/net/kaweth.c | 1 - drivers/video/aty/radeon_i2c.c | 1 - drivers/video/g364fb.c | 1 - drivers/video/platinumfb.c | 1 - drivers/video/stifb.c | 1 - drivers/video/valkyriefb.c | 1 - include/asm-arm/arch-ixp4xx/dma.h | 1 - include/rdma/ib_mad.h | 2 -- sound/core/init.c | 1 - sound/oss/au1550_ac97.c | 1 - sound/oss/soundcard.c | 1 + sound/pci/ca0106/ca0106_mixer.c | 2 +- sound/pci/ca0106/ca0106_proc.c | 2 +- sound/pci/cs46xx/dsp_spos.c | 1 - sound/pci/cs46xx/dsp_spos_scb_lib.c | 1 - sound/pci/hda/hda_generic.c | 1 - sound/pci/hda/hda_proc.c | 1 - sound/pci/hda/patch_atihdmi.c | 1 - sound/pci/hda/patch_si3054.c | 1 - sound/pci/hda/patch_via.c | 1 - 116 files changed, 7 insertions(+), 117 deletions(-) (limited to 'arch') diff --git a/arch/alpha/kernel/err_common.c b/arch/alpha/kernel/err_common.c index 687580b16b41..13d53b1c9657 100644 --- a/arch/alpha/kernel/err_common.c +++ b/arch/alpha/kernel/err_common.c @@ -7,7 +7,6 @@ */ #include -#include #include #include diff --git a/arch/alpha/kernel/err_ev6.c b/arch/alpha/kernel/err_ev6.c index 69b5f4ea7355..11aee012a8ae 100644 --- a/arch/alpha/kernel/err_ev6.c +++ b/arch/alpha/kernel/err_ev6.c @@ -7,7 +7,6 @@ */ #include -#include #include #include diff --git a/arch/alpha/kernel/err_ev7.c b/arch/alpha/kernel/err_ev7.c index 95463ab1cf35..bc799f72d8c1 100644 --- a/arch/alpha/kernel/err_ev7.c +++ b/arch/alpha/kernel/err_ev7.c @@ -7,7 +7,6 @@ */ #include -#include #include #include diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c index d59277c00911..b1acc8ce3167 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c index ff0d89806114..e1c509aa3054 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c @@ -17,10 +17,10 @@ #include #include #include -#include #include #include #include +#include #include "speedstep-lib.h" diff --git a/arch/ia64/sn/kernel/huberror.c b/arch/ia64/sn/kernel/huberror.c index fcf7f93c4b61..2c3f9dfca78b 100644 --- a/arch/ia64/sn/kernel/huberror.c +++ b/arch/ia64/sn/kernel/huberror.c @@ -8,7 +8,6 @@ #include #include -#include #include #include #include "ioerror.h" diff --git a/arch/ia64/sn/kernel/xpnet.c b/arch/ia64/sn/kernel/xpnet.c index 5419acb89a8c..88fad85ceeff 100644 --- a/arch/ia64/sn/kernel/xpnet.c +++ b/arch/ia64/sn/kernel/xpnet.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include diff --git a/arch/m68knommu/kernel/dma.c b/arch/m68knommu/kernel/dma.c index 14b19c4161f4..0a25874a2aae 100644 --- a/arch/m68knommu/kernel/dma.c +++ b/arch/m68knommu/kernel/dma.c @@ -8,7 +8,6 @@ #include #include #include -#include #include void *dma_alloc_coherent(struct device *dev, size_t size, diff --git a/arch/mips/lib/iomap.c b/arch/mips/lib/iomap.c index d51d5cb0a4a9..e3acb2dad33a 100644 --- a/arch/mips/lib/iomap.c +++ b/arch/mips/lib/iomap.c @@ -6,7 +6,6 @@ * (C) Copyright 2007 MIPS Technologies, Inc. * written by Ralf Baechle */ -#include #include #include diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index 53aa04101ced..3a393c7f390e 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c index 48ce84f5be93..4c0a7d732f69 100644 --- a/arch/ppc/8260_io/enet.c +++ b/arch/ppc/8260_io/enet.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c index 9db825fe37f0..cab395da25da 100644 --- a/arch/ppc/8260_io/fcc_enet.c +++ b/arch/ppc/8260_io/fcc_enet.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c index bfa3f52996d1..e58288e14369 100644 --- a/arch/ppc/8xx_io/enet.c +++ b/arch/ppc/8xx_io/enet.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/syslib/ppc4xx_sgdma.c b/arch/ppc/syslib/ppc4xx_sgdma.c index 939abe3c1f45..5dadca3e0d61 100644 --- a/arch/ppc/syslib/ppc4xx_sgdma.c +++ b/arch/ppc/syslib/ppc4xx_sgdma.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/arch/sh64/mach-cayman/iomap.c b/arch/sh64/mach-cayman/iomap.c index 2d06e9a55137..a5c645f02d57 100644 --- a/arch/sh64/mach-cayman/iomap.c +++ b/arch/sh64/mach-cayman/iomap.c @@ -9,7 +9,6 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ -#include #include #include diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index 0b4cb93db5a3..cd7e6a020602 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/arch/xtensa/platform-iss/setup.c b/arch/xtensa/platform-iss/setup.c index c8a42b60c57a..f60c8cf6dfbe 100644 --- a/arch/xtensa/platform-iss/setup.c +++ b/arch/xtensa/platform-iss/setup.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c index 8d60c4eb54fe..2ebd07f2ef81 100644 --- a/drivers/atm/adummy.c +++ b/drivers/atm/adummy.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c index 9ebf84d18655..ec435cb25c4f 100644 --- a/drivers/char/hw_random/via-rng.c +++ b/drivers/char/hw_random/via-rng.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 157b1d09ab55..13808f6083a0 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index bb9a43c6cf3d..9f273f032b0f 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -19,7 +19,6 @@ * */ #include -#include #include #include #include diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c index 1e4a8d751a71..2f7ba7a514fe 100644 --- a/drivers/char/watchdog/sc1200wdt.c +++ b/drivers/char/watchdog/sc1200wdt.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include diff --git a/drivers/char/watchdog/scx200_wdt.c b/drivers/char/watchdog/scx200_wdt.c index fc0e0347f9d2..d4fd0fa2f176 100644 --- a/drivers/char/watchdog/scx200_wdt.c +++ b/drivers/char/watchdog/scx200_wdt.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index 67f91bdda089..f35156c58922 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index ee65aa1be13a..c6b6898592b1 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c index cc6536a19eca..6b03e0d0a8e3 100644 --- a/drivers/i2c/busses/i2c-pca-isa.c +++ b/drivers/i2c/busses/i2c-pca-isa.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c index 6164a9a83396..bd0755c789c5 100644 --- a/drivers/ieee1394/hosts.c +++ b/drivers/ieee1394/hosts.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 842cd0b53e91..eff591deeb46 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index 891d1fa7b2eb..223b1aa7d92b 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h index de89717f49fe..9be5cc00a3a9 100644 --- a/drivers/infiniband/core/mad_priv.h +++ b/drivers/infiniband/core/mad_priv.h @@ -39,7 +39,6 @@ #include #include -#include #include #include #include diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c index 4a579b3a1c90..1e13ab42b70b 100644 --- a/drivers/infiniband/core/multicast.c +++ b/drivers/infiniband/core/multicast.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 9a7eaadb1688..6469406ea9d8 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 8199b83052a9..d97ded25c4ff 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c index ed55979bfd34..036ed1ef1796 100644 --- a/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/drivers/infiniband/hw/ipath/ipath_fs.c @@ -38,7 +38,6 @@ #include #include #include -#include #include "ipath_kernel.h" diff --git a/drivers/infiniband/hw/ipath/ipath_layer.c b/drivers/infiniband/hw/ipath/ipath_layer.c index e46aa4ed2a7e..05a1d2b01d9d 100644 --- a/drivers/infiniband/hw/ipath/ipath_layer.c +++ b/drivers/infiniband/hw/ipath/ipath_layer.c @@ -37,7 +37,6 @@ */ #include -#include #include #include "ipath_kernel.h" diff --git a/drivers/infiniband/hw/ipath/ipath_stats.c b/drivers/infiniband/hw/ipath/ipath_stats.c index 9307f7187ca5..d8b5e4cefe25 100644 --- a/drivers/infiniband/hw/ipath/ipath_stats.c +++ b/drivers/infiniband/hw/ipath/ipath_stats.c @@ -31,8 +31,6 @@ * SOFTWARE. */ -#include - #include "ipath_kernel.h" struct infinipath_stats ipath_stats; diff --git a/drivers/infiniband/hw/ipath/ipath_sysfs.c b/drivers/infiniband/hw/ipath/ipath_sysfs.c index ffa6318ad0cc..4dc398d5e011 100644 --- a/drivers/infiniband/hw/ipath/ipath_sysfs.c +++ b/drivers/infiniband/hw/ipath/ipath_sysfs.c @@ -32,7 +32,6 @@ */ #include -#include #include "ipath_kernel.h" #include "ipath_common.h" diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h index 594144145f45..a1ab06847b75 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.h +++ b/drivers/infiniband/hw/mthca/mthca_memfree.h @@ -38,7 +38,6 @@ #define MTHCA_MEMFREE_H #include -#include #include #define MTHCA_ICM_CHUNK_LEN \ diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index fd558267d1cb..d8f6bb4f53fc 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c index 38f648f9b0ed..02c6fbaeccf8 100644 --- a/drivers/isdn/hisax/netjet.c +++ b/drivers/isdn/hisax/netjet.c @@ -19,7 +19,6 @@ #include "isac.h" #include "hscx.h" #include "isdnl1.h" -#include #include #include #include diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c index f7e83a86f444..4c7dedac0e51 100644 --- a/drivers/isdn/hysdn/hysdn_proclog.c +++ b/drivers/isdn/hysdn/hysdn_proclog.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "hysdn_defs.h" diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index a6cbbdd262d6..34d7abc900d7 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -26,11 +26,11 @@ #include #include #include -#include #include #include #include #include +#include #include "dmxdev.h" #include "dvb_demux.h" diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c index 2aa9ce920607..823cd6cc471e 100644 --- a/drivers/media/video/adv7170.c +++ b/drivers/media/video/adv7170.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index a3246a283aa4..05c7820fe53e 100644 --- a/drivers/media/video/adv7175.c +++ b/drivers/media/video/adv7175.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index 68673863d5c9..59a43603b5cb 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c index 42e2299dcb22..853b1a3d6a1d 100644 --- a/drivers/media/video/bt856.c +++ b/drivers/media/video/bt856.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c index 772fd52d551a..2e4cf1efdd21 100644 --- a/drivers/media/video/bt866.c +++ b/drivers/media/video/bt866.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index 97ef421dd093..e627062fde3a 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index ed882ebc7b95..418ea8b7f85a 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -23,7 +23,6 @@ #include #include -#include #include #include #include diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c index 44dc7479119c..74839f98b7c4 100644 --- a/drivers/media/video/saa7111.c +++ b/drivers/media/video/saa7111.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c index 2ce3321ab995..87c3144ec7fc 100644 --- a/drivers/media/video/saa7114.c +++ b/drivers/media/video/saa7114.c @@ -39,7 +39,6 @@ #include #include -#include #include #include #include diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c index 269d7114a93a..80bf91187856 100644 --- a/drivers/media/video/saa711x.c +++ b/drivers/media/video/saa711x.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c index e0fdb1ab7580..339592e7722d 100644 --- a/drivers/media/video/saa7185.c +++ b/drivers/media/video/saa7185.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c index ca86f113f36a..276ba3c5143f 100644 --- a/drivers/misc/hdpuftrs/hdpu_cpustate.c +++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c index 6a51e99a8079..60c8b26f0678 100644 --- a/drivers/misc/hdpuftrs/hdpu_nexus.c +++ b/drivers/misc/hdpuftrs/hdpu_nexus.c @@ -18,7 +18,6 @@ #include #include #include -#include #include diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c index 8a0c4dec6351..c73e96bfafc6 100644 --- a/drivers/mtd/devices/doc2000.c +++ b/drivers/mtd/devices/doc2000.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c index 6f368aec5d5d..6413efc045e0 100644 --- a/drivers/mtd/devices/doc2001.c +++ b/drivers/mtd/devices/doc2001.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c index 88ba82df0fbb..2b30b587c6e8 100644 --- a/drivers/mtd/devices/doc2001plus.c +++ b/drivers/mtd/devices/doc2001plus.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mtd/devices/docecc.c b/drivers/mtd/devices/docecc.c index 52b5d638077f..fd8a8daba3a8 100644 --- a/drivers/mtd/devices/docecc.c +++ b/drivers/mtd/devices/docecc.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c index acf3ba223298..ecac0e438f49 100644 --- a/drivers/mtd/inftlmount.c +++ b/drivers/mtd/inftlmount.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index 8296305c8297..89deff007116 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c index e6ef7d7f9f14..0c9ce19ea27a 100644 --- a/drivers/mtd/nftlcore.c +++ b/drivers/mtd/nftlcore.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/atl1/atl1_param.c b/drivers/net/atl1/atl1_param.c index c407214339f6..bcd0bd891722 100644 --- a/drivers/net/atl1/atl1_param.c +++ b/drivers/net/atl1/atl1_param.c @@ -22,7 +22,6 @@ */ #include -#include #include #include "atl1.h" diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index d10fb80e9a63..c39ab803c5d8 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -45,7 +45,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fec_8xx/fec_main.c b/drivers/net/fec_8xx/fec_main.c index e824d5d231af..88efe9731bab 100644 --- a/drivers/net/fec_8xx/fec_main.c +++ b/drivers/net/fec_8xx/fec_main.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fec_8xx/fec_mii.c b/drivers/net/fec_8xx/fec_mii.c index e79700abf7b6..b3fa0d6a159c 100644 --- a/drivers/net/fec_8xx/fec_mii.c +++ b/drivers/net/fec_8xx/fec_mii.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index e2ddd617493a..a4a2a0ea43d3 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index 8545e84fc9a0..5603121132cd 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index cdcfb96f360f..04b4f80a1cde 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index 65925b5a224f..d0f28981b55a 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c index f91447837fd4..d3840108ffbd 100644 --- a/drivers/net/fs_enet/mii-bitbang.c +++ b/drivers/net/fs_enet/mii-bitbang.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index 235b177fb9ac..0a563a83016f 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c index 3d82d46f4998..50035ebd4f52 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.c +++ b/drivers/net/ibm_emac/ibm_emac_core.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/ixgb/ixgb_osdep.h b/drivers/net/ixgb/ixgb_osdep.h index 8434d752fd81..9e04a6b3ae0d 100644 --- a/drivers/net/ixgb/ixgb_osdep.h +++ b/drivers/net/ixgb/ixgb_osdep.h @@ -34,7 +34,6 @@ #define _IXGB_OSDEP_H_ #include -#include #include #include #include diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c index 0edcd125fd61..6b49fc4bd1a1 100644 --- a/drivers/net/lasi_82596.c +++ b/drivers/net/lasi_82596.c @@ -81,7 +81,6 @@ #include #include #include -#include #include #include diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c index ed274d6909d0..f8f4d74f01f1 100644 --- a/drivers/net/tokenring/madgemc.c +++ b/drivers/net/tokenring/madgemc.c @@ -23,7 +23,6 @@ static const char version[] = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n"; #include #include #include -#include #include #include #include diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index 9bbea5c8acf4..58d7e5d452fa 100644 --- a/drivers/net/tokenring/smctr.c +++ b/drivers/net/tokenring/smctr.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c index 942b839ccc5b..6c400ccd38b4 100644 --- a/drivers/net/tulip/21142.c +++ b/drivers/net/tulip/21142.c @@ -14,7 +14,6 @@ */ -#include #include #include "tulip.h" diff --git a/drivers/net/tulip/pnic.c b/drivers/net/tulip/pnic.c index 85a521e0d052..be82a2effee3 100644 --- a/drivers/net/tulip/pnic.c +++ b/drivers/net/tulip/pnic.c @@ -15,7 +15,6 @@ */ #include -#include #include #include "tulip.h" diff --git a/drivers/net/tulip/pnic2.c b/drivers/net/tulip/pnic2.c index c31be0e377a8..4e4a879c3fa5 100644 --- a/drivers/net/tulip/pnic2.c +++ b/drivers/net/tulip/pnic2.c @@ -76,7 +76,6 @@ -#include #include "tulip.h" #include diff --git a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c index df326fe1cc8f..d2c1f42109b0 100644 --- a/drivers/net/tulip/timer.c +++ b/drivers/net/tulip/timer.c @@ -14,7 +14,6 @@ */ -#include #include "tulip.h" diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h index c840d2e67b23..16f26a8364f0 100644 --- a/drivers/net/tulip/tulip.h +++ b/drivers/net/tulip/tulip.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wan/lmc/lmc_media.c b/drivers/net/wan/lmc/lmc_media.c index ae01555d24cf..574737b55f39 100644 --- a/drivers/net/wan/lmc/lmc_media.c +++ b/drivers/net/wan/lmc/lmc_media.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wan/lmc/lmc_proto.c b/drivers/net/wan/lmc/lmc_proto.c index 74876c0073e8..31e1799571ad 100644 --- a/drivers/net/wan/lmc/lmc_proto.c +++ b/drivers/net/wan/lmc/lmc_proto.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c index 07dbdfbfc15d..e24a7b095dd6 100644 --- a/drivers/net/wan/pc300_tty.c +++ b/drivers/net/wan/pc300_tty.c @@ -38,7 +38,6 @@ #include #include -#include #include #include #include diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c index 9bb4db552f3c..a68b3b3761a2 100644 --- a/drivers/parisc/hppb.c +++ b/drivers/parisc/hppb.c @@ -22,8 +22,6 @@ #include #include -#include - struct hppb_card { unsigned long hpa; struct resource mmio_region; diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index ac004248324a..50cad3a59a6c 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index ea5765c3bdc0..a2bb46526b56 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c index eee590a51d8a..002643392d42 100644 --- a/drivers/sbus/sbus.c +++ b/drivers/sbus/sbus.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index d38b628be1ad..66aeb57dcc2d 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c index 6f1a1780efce..f4b5e9742ab0 100644 --- a/drivers/scsi/aacraid/sa.c +++ b/drivers/scsi/aacraid/sa.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index 1d239f6c0103..cbbfbc9f3e0f 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c index 8f43ff772f23..db6ab1a3b81e 100644 --- a/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/drivers/scsi/aic94xx/aic94xx_scb.c @@ -24,7 +24,6 @@ * */ -#include #include #include "aic94xx.h" diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c index 12497da5529d..03bfed61bffc 100644 --- a/drivers/scsi/arcmsr/arcmsr_attr.c +++ b/drivers/scsi/arcmsr/arcmsr_attr.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index dc70c180e115..e34442e405e8 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -22,7 +22,6 @@ * */ -#include #include #include "sas_internal.h" diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index 89403b00e042..6335830df810 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index a0cc05d21a6a..60d29440f316 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c @@ -55,7 +55,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c index 508479920705..7db9de681716 100644 --- a/drivers/video/aty/radeon_i2c.c +++ b/drivers/video/aty/radeon_i2c.c @@ -1,7 +1,6 @@ #include #include #include -#include #include diff --git a/drivers/video/g364fb.c b/drivers/video/g364fb.c index ca93a75f2997..b7655c05da53 100644 --- a/drivers/video/g364fb.c +++ b/drivers/video/g364fb.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 233871655824..e64f8b5d0056 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index 69f3b264a22e..c97709ecbad0 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -64,7 +64,6 @@ #include #include #include -#include #include /* for HP-UX compatibility */ #include diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c index 06fc19a61192..ad66f070acb8 100644 --- a/drivers/video/valkyriefb.c +++ b/drivers/video/valkyriefb.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include diff --git a/include/asm-arm/arch-ixp4xx/dma.h b/include/asm-arm/arch-ixp4xx/dma.h index 789f7f53c357..2c7f5327d80f 100644 --- a/include/asm-arm/arch-ixp4xx/dma.h +++ b/include/asm-arm/arch-ixp4xx/dma.h @@ -12,7 +12,6 @@ #define __ASM_ARCH_DMA_H #include -#include #include #include #include diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h index 585d28e960dd..739fa4d0e539 100644 --- a/include/rdma/ib_mad.h +++ b/include/rdma/ib_mad.h @@ -39,8 +39,6 @@ #if !defined( IB_MAD_H ) #define IB_MAD_H -#include - #include /* Management base version */ diff --git a/sound/core/init.c b/sound/core/init.c index 4a431e3ea3a2..f2fe35737186 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c index a339f0c0d512..23018a7c063a 100644 --- a/sound/oss/au1550_ac97.c +++ b/sound/oss/au1550_ac97.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c index dcd8d6d2f56f..a9c23b2502ad 100644 --- a/sound/oss/soundcard.c +++ b/sound/oss/soundcard.c @@ -44,6 +44,7 @@ #include #include #include +#include /* * This ought to be moved into include/asm/dma.h diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index b913a1fb8c21..9c3a9c8d1dc2 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c @@ -62,7 +62,6 @@ #include #include #include -#include #include #include #include @@ -71,6 +70,7 @@ #include #include #include +#include #include "ca0106.h" diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c index 75ca421eb3a1..ae80f51d8c4f 100644 --- a/sound/pci/ca0106/ca0106_proc.c +++ b/sound/pci/ca0106/ca0106_proc.c @@ -64,7 +64,6 @@ #include #include #include -#include #include #include #include @@ -73,6 +72,7 @@ #include #include #include +#include #include "ca0106.h" diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c index 89c402770a1d..336e77e2600c 100644 --- a/sound/pci/cs46xx/dsp_spos.c +++ b/sound/pci/cs46xx/dsp_spos.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c index 343f51d5311b..57e357de1500 100644 --- a/sound/pci/cs46xx/dsp_spos_scb_lib.c +++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 1589d2f2917f..1e5ff0cd3709 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include "hda_codec.h" #include "hda_local.h" diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 17df4d0fe135..e313e685f161 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -23,7 +23,6 @@ #include #include -#include #include #include "hda_codec.h" #include "hda_local.h" diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c index 7333f275decd..831469d3a923 100644 --- a/sound/pci/hda/patch_atihdmi.c +++ b/sound/pci/hda/patch_atihdmi.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "hda_codec.h" #include "hda_local.h" diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c index ed5e45e35963..6fcda9bcf0cf 100644 --- a/sound/pci/hda/patch_si3054.c +++ b/sound/pci/hda/patch_si3054.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include "hda_codec.h" #include "hda_local.h" diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 4c839b031729..2b11ac8689b9 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include "hda_codec.h" #include "hda_local.h" -- cgit v1.2.3-59-g8ed1b From 40ee9e9f8d52d85f2446bbdda7823a3f1de62f3f Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Sat, 24 Mar 2007 11:03:32 -0700 Subject: PCI: fix sysfs rom file creation for BIOS ROM shadows At one time, if a BIOS ROM shadow was detected for the boot video device (stored at offset 0xc0000), we'd set a special resource flag, IORESOURCE_ROM_SHADOW, so that the sysfs ROM file code could handle it properly. That broke along the way somewhere though, so current kernels will be missing 'rom' files in sysfs if the video device doesn't have an explicit ROM BAR. This patch fixes the regression by moving the video fixup quirk to a little later in the boot cycle (to avoid having its work undone by PCI resource allocation) and checking in the PCI sysfs code whether a rom file should be created due to a shadow resource, which is also moved to a little later in the boot cycle so it will occur after the video fixup. Tested and works on my i386 test box. Signed-off-by: Jesse Barnes Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/fixup.c | 2 +- drivers/pci/pci-sysfs.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index 8053b17ab647..b62eafb997bc 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c @@ -354,7 +354,7 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev) printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev)); } } -DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); +DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); /* * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A. diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index cd913a2a416f..29676fe4f23e 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -620,7 +620,8 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) goto err_bin_file; /* If the device has a ROM, try to expose it in sysfs. */ - if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) { + if (pci_resource_len(pdev, PCI_ROM_RESOURCE) || + (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)) { rom_attr = kzalloc(sizeof(*rom_attr), GFP_ATOMIC); if (rom_attr) { pdev->rom_attr = rom_attr; @@ -695,4 +696,4 @@ static int __init pci_sysfs_init(void) return 0; } -__initcall(pci_sysfs_init); +late_initcall(pci_sysfs_init); -- cgit v1.2.3-59-g8ed1b From bab41e9be75121c473b00df2ffa33af3c44066a7 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 5 Apr 2007 17:19:09 +1000 Subject: PCI: Convert to alloc_pci_dev() Convert code that allocs a struct pci_dev to use alloc_pci_dev(). Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/kernel/pci_64.c | 2 +- drivers/char/agp/alpha-agp.c | 2 +- drivers/char/agp/parisc-agp.c | 2 +- drivers/pci/hotplug/fakephp.c | 2 +- drivers/pci/probe.c | 2 +- drivers/scsi/megaraid.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 60d7d4baa227..7138092826aa 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -340,7 +340,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, struct pci_dev *dev; const char *type; - dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); + dev = alloc_pci_dev(); if (!dev) return NULL; type = of_get_property(node, "device_type", NULL); diff --git a/drivers/char/agp/alpha-agp.c b/drivers/char/agp/alpha-agp.c index b0acf41c0db9..aa8f3a39a704 100644 --- a/drivers/char/agp/alpha-agp.c +++ b/drivers/char/agp/alpha-agp.c @@ -173,7 +173,7 @@ alpha_core_agp_setup(void) /* * Build a fake pci_dev struct */ - pdev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); + pdev = alloc_pci_dev(); if (!pdev) return -ENOMEM; pdev->vendor = 0xffff; diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c index 3d83b461ccad..f4562cc22343 100644 --- a/drivers/char/agp/parisc-agp.c +++ b/drivers/char/agp/parisc-agp.c @@ -329,7 +329,7 @@ parisc_agp_setup(void __iomem *ioc_hpa, void __iomem *lba_hpa) struct agp_bridge_data *bridge; int error = 0; - fake_bridge_dev = kmalloc(sizeof (struct pci_dev), GFP_KERNEL); + fake_bridge_dev = alloc_pci_dev(); if (!fake_bridge_dev) { error = -ENOMEM; goto fail; diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index e27907c91d92..027f6865d7e3 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c @@ -238,7 +238,7 @@ static void pci_rescan_bus(const struct pci_bus *bus) { unsigned int devfn; struct pci_dev *dev; - dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); + dev = alloc_pci_dev(); if (!dev) return; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 70d37bbf09bb..c659f8ae441a 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -900,7 +900,7 @@ pci_scan_device(struct pci_bus *bus, int devfn) if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type)) return NULL; - dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); + dev = alloc_pci_dev(); if (!dev) return NULL; diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 0aa3304f6b9b..7fc6e06ea7e1 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -2088,7 +2088,7 @@ megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor) static inline int make_local_pdev(adapter_t *adapter, struct pci_dev **pdev) { - *pdev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); + *pdev = alloc_pci_dev(); if( *pdev == NULL ) return -1; -- cgit v1.2.3-59-g8ed1b From f282b97021ddc95c6092b9016f667c0963858fb1 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 18 Apr 2007 18:46:20 +1000 Subject: msi: introduce ARCH_SUPPORTS_MSI Kconfig option (rev2) Allows architectures to advertise that they support MSI rather than listing each architecture as a PCI_MSI dependency. Signed-off-by: Dan Williams Acked-by: "Eric W. Biederman" Signed-off-by: Greg Kroah-Hartman --- arch/arm/Kconfig | 1 + arch/i386/Kconfig | 1 + arch/ia64/Kconfig | 1 + arch/sparc64/Kconfig | 1 + arch/x86_64/Kconfig | 1 + drivers/pci/Kconfig | 6 +++++- 6 files changed, 10 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e7baca29f3fb..db00376aca15 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -255,6 +255,7 @@ config ARCH_IOP13XX depends on MMU select PLAT_IOP select PCI + select ARCH_SUPPORTS_MSI help Support for Intel's IOP13XX (XScale) family of processors. diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 53d62373a524..bcf2fc408a1a 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -1073,6 +1073,7 @@ config PCI bool "PCI support" if !X86_VISWS depends on !X86_VOYAGER default y if X86_VISWS + select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC) help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index e19185d26554..3b71f97d0b60 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -14,6 +14,7 @@ config IA64 select PCI if (!IA64_HP_SIM) select ACPI if (!IA64_HP_SIM) select PM if (!IA64_HP_SIM) + select ARCH_SUPPORTS_MSI default y help The Itanium Processor Family is Intel's 64-bit successor to diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 590a41b864b9..be9e10b94ef8 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -306,6 +306,7 @@ config SUN_IO config PCI bool "PCI support" + select ARCH_SUPPORTS_MSI help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 56eb14c98475..e9b4f058a49a 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -676,6 +676,7 @@ menu "Bus options (PCI etc.)" config PCI bool "PCI support" + select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC) # x86-64 doesn't support PCI BIOS access from long mode so always go direct. config PCI_DIRECT diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 5ea5bc70cb82..70efe8f285a6 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -1,10 +1,14 @@ # # PCI configuration # +config ARCH_SUPPORTS_MSI + bool + default n + config PCI_MSI bool "Message Signaled Interrupts (MSI and MSI-X)" depends on PCI - depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64 || SPARC64 + depends on ARCH_SUPPORTS_MSI help This allows device drivers to enable MSI (Message Signaled Interrupts). Message Signaled Interrupts enable a device to -- cgit v1.2.3-59-g8ed1b From 7fe3730de729b758e9f69b862b9255d998671b5f Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 18 Apr 2007 19:39:21 +1000 Subject: MSI: arch must connect the irq and the msi_desc set_irq_msi() currently connects an irq_desc to an msi_desc. The archs call it at some point in their setup routine, and then the generic code sets up the reverse mapping from the msi_desc back to the irq. set_irq_msi() should do both connections, making it the one and only call required to connect an irq with it's MSI desc and vice versa. The arch code MUST call set_irq_msi(), and it must do so only once it's sure it's not going to fail the irq allocation. Given that there's no need for the arch to return the irq anymore, the return value from the arch setup routine just becomes 0 for success and anything else for failure. Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- arch/i386/kernel/io_apic.c | 4 ++-- arch/ia64/sn/kernel/msi_sn.c | 4 ++-- arch/sparc64/kernel/pci.c | 4 ++-- arch/sparc64/kernel/pci_sun4v.c | 4 ++-- arch/x86_64/kernel/io_apic.c | 4 ++-- drivers/pci/msi.c | 23 +++++++++-------------- kernel/irq/chip.c | 3 +++ 7 files changed, 22 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index b3ab8ffebd27..89d85d244926 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -2611,19 +2611,19 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) if (irq < 0) return irq; - set_irq_msi(irq, desc); ret = msi_compose_msg(dev, irq, &msg); if (ret < 0) { destroy_irq(irq); return ret; } + set_irq_msi(irq, desc); write_msi_msg(irq, &msg); set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); - return irq; + return 0; } void arch_teardown_msi_irq(unsigned int irq) diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c index 49873aa4a37d..83f190ffe350 100644 --- a/arch/ia64/sn/kernel/msi_sn.c +++ b/arch/ia64/sn/kernel/msi_sn.c @@ -87,7 +87,6 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry) if (irq < 0) return irq; - set_irq_msi(irq, entry); /* * Set up the vector plumbing. Let the prom (via sn_intr_alloc) * decide which cpu to direct this msi at by default. @@ -144,10 +143,11 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry) */ msg.data = 0x100 + irq; + set_irq_msi(irq, entry); write_msi_msg(irq, &msg); set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq); - return irq; + return 0; } #ifdef CONFIG_SMP diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 023af41ad68d..9a549547cb2b 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -1092,10 +1092,10 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) return -EINVAL; err = p->setup_msi_irq(&virt_irq, pdev, desc); - if (err < 0) + if (err) return err; - return virt_irq; + return 0; } void arch_teardown_msi_irq(unsigned int virt_irq) diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 94295c219329..1ccf4c9a9a43 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -1169,8 +1169,6 @@ static int pci_sun4v_setup_msi_irq(unsigned int *virt_irq_p, if (!devino) goto out_err; - set_irq_msi(*virt_irq_p, entry); - msiqid = ((devino - pbm->msiq_first_devino) + pbm->msiq_first); @@ -1204,6 +1202,8 @@ static int pci_sun4v_setup_msi_irq(unsigned int *virt_irq_p, msg.address_lo = pbm->msi32_start; } msg.data = msi_num; + + set_irq_msi(*virt_irq_p, entry); write_msi_msg(*virt_irq_p, &msg); irq_install_pre_handler(*virt_irq_p, diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index c6a5bc7e8118..b7d2b76b92d4 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -1983,18 +1983,18 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) if (irq < 0) return irq; - set_irq_msi(irq, desc); ret = msi_compose_msg(dev, irq, &msg); if (ret < 0) { destroy_irq(irq); return ret; } + set_irq_msi(irq, desc); write_msi_msg(irq, &msg); set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); - return irq; + return 0; } void arch_teardown_msi_irq(unsigned int irq) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 7a44ba467481..88362f1bd9cf 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -297,7 +297,7 @@ void pci_restore_msi_state(struct pci_dev *dev) static int msi_capability_init(struct pci_dev *dev) { struct msi_desc *entry; - int pos, irq; + int pos, ret; u16 control; msi_set_enable(dev, 0); /* Ensure msi is disabled as I set it up */ @@ -335,21 +335,19 @@ static int msi_capability_init(struct pci_dev *dev) maskbits); } /* Configure MSI capability structure */ - irq = arch_setup_msi_irq(dev, entry); - if (irq < 0) { + ret = arch_setup_msi_irq(dev, entry); + if (ret) { kfree(entry); - return irq; + return ret; } - entry->irq = irq; list_add(&entry->list, &dev->msi_list); - set_irq_msi(irq, entry); /* Set MSI enabled bits */ pci_intx(dev, 0); /* disable intx */ msi_set_enable(dev, 1); dev->msi_enabled = 1; - dev->irq = irq; + dev->irq = entry->irq; return 0; } @@ -367,7 +365,7 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, int nvec) { struct msi_desc *entry; - int irq, pos, i, j, nr_entries; + int irq, pos, i, j, nr_entries, ret; unsigned long phys_addr; u32 table_offset; u16 control; @@ -407,16 +405,13 @@ static int msix_capability_init(struct pci_dev *dev, entry->mask_base = base; /* Configure MSI-X capability structure */ - irq = arch_setup_msi_irq(dev, entry); - if (irq < 0) { + ret = arch_setup_msi_irq(dev, entry); + if (ret) { kfree(entry); break; } - entry->irq = irq; - entries[i].vector = irq; + entries[i].vector = entry->irq; list_add(&entry->list, &dev->msi_list); - - set_irq_msi(irq, entry); } if (i != nvec) { int avail = i - 1; diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 0133f4f9e9f0..615ce97c6cfd 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -185,6 +186,8 @@ int set_irq_msi(unsigned int irq, struct msi_desc *entry) desc = irq_desc + irq; spin_lock_irqsave(&desc->lock, flags); desc->msi_desc = entry; + if (entry) + entry->irq = irq; spin_unlock_irqrestore(&desc->lock, flags); return 0; } -- cgit v1.2.3-59-g8ed1b From f14e3136509e3825a83f6689cb709f41dfacea47 Mon Sep 17 00:00:00 2001 From: Chuck Ebbert Date: Tue, 10 Apr 2007 10:25:44 -0400 Subject: PCI: add debug information to resource collision message Add more information to PCI resource collision message to help with debugging. Signed-off-by: Chuck Ebbert Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/i386.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c index 43005f044424..bcd2f94b732c 100644 --- a/arch/i386/pci/i386.c +++ b/arch/i386/pci/i386.c @@ -246,8 +246,8 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) continue; if (!r->start && r->end) { printk(KERN_ERR "PCI: Device %s not available " - "because of resource collisions\n", - pci_name(dev)); + "because of resource %d collisions\n", + pci_name(dev), idx); return -EINVAL; } if (r->flags & IORESOURCE_IO) -- cgit v1.2.3-59-g8ed1b From e90ddd813df7897af34226ed1cd442f7a182816e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 2 May 2007 17:59:44 +0100 Subject: [ARM] 4348/4: iop3xx: Give Linux control over PCI initialization Currently the iop3xx platform support code assumes that RedBoot is the bootloader and has already initialized the ATU. Linux should handle this initialization for three reasons: 1/ The memory map that RedBoot sets up is not optimal (page_to_dma and virt_to_phys return different addresses). The effect of this is that using the dma mapping API for the internal bus dma units generates pci bus addresses that are incorrect for the internal bus. 2/ Not all iop platforms use RedBoot 3/ If the ATU is already initialized it indicates that the iop is an add-in card in another host, it does not own the PCI bus, and should not be re-initialized. Changelog: * rather than change nr_controllers to zero, simply do not call pci_common_init Cc: Lennert Buytenhek Signed-off-by: Dan Williams Signed-off-by: Russell King --- arch/arm/mach-iop32x/Kconfig | 8 ++ arch/arm/mach-iop32x/iq31244.c | 11 ++- arch/arm/mach-iop32x/iq80321.c | 3 +- arch/arm/mach-iop33x/Kconfig | 8 ++ arch/arm/mach-iop33x/iq80331.c | 3 +- arch/arm/mach-iop33x/iq80332.c | 3 +- arch/arm/plat-iop/pci.c | 140 ++++++++++++++++++++++++++++++++++- include/asm-arm/arch-iop32x/iop32x.h | 9 +++ include/asm-arm/arch-iop32x/memory.h | 4 +- include/asm-arm/arch-iop33x/iop33x.h | 10 +++ include/asm-arm/arch-iop33x/memory.h | 4 +- include/asm-arm/hardware/iop3xx.h | 22 +++++- 12 files changed, 209 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-iop32x/Kconfig b/arch/arm/mach-iop32x/Kconfig index 9dd49cff21ff..9bb02b6d7ae1 100644 --- a/arch/arm/mach-iop32x/Kconfig +++ b/arch/arm/mach-iop32x/Kconfig @@ -34,6 +34,14 @@ config MACH_N2100 Say Y here if you want to run your kernel on the Thecus n2100 NAS appliance. +config IOP3XX_ATU + bool "Enable the PCI Controller" + default y + help + Say Y here if you want the IOP to initialize its PCI Controller. + Say N if the IOP is an add in card, the host system owns the PCI + bus in this case. + endmenu endif diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c index 60e74309a458..7b21c6e13e59 100644 --- a/arch/arm/mach-iop32x/iq31244.c +++ b/arch/arm/mach-iop32x/iq31244.c @@ -178,9 +178,10 @@ static struct hw_pci iq31244_pci __initdata = { static int __init iq31244_pci_init(void) { - if (is_ep80219()) - pci_common_init(&ep80219_pci); - else if (machine_is_iq31244()) { + if (is_ep80219()) { + if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) + pci_common_init(&ep80219_pci); + } else if (machine_is_iq31244()) { if (is_80219()) { printk("note: iq31244 board type has been selected\n"); printk("note: to select ep80219 operation:\n"); @@ -189,7 +190,9 @@ static int __init iq31244_pci_init(void) printk("\t2/ update boot loader to pass" " the ep80219 id: %d\n", MACH_TYPE_EP80219); } - pci_common_init(&iq31244_pci); + + if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) + pci_common_init(&iq31244_pci); } return 0; diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c index 361c70c0f64c..bc25fb91e7b9 100644 --- a/arch/arm/mach-iop32x/iq80321.c +++ b/arch/arm/mach-iop32x/iq80321.c @@ -113,7 +113,8 @@ static struct hw_pci iq80321_pci __initdata = { static int __init iq80321_pci_init(void) { - if (machine_is_iq80321()) + if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) && + machine_is_iq80321()) pci_common_init(&iq80321_pci); return 0; diff --git a/arch/arm/mach-iop33x/Kconfig b/arch/arm/mach-iop33x/Kconfig index 9aa016bb18f9..45598e096898 100644 --- a/arch/arm/mach-iop33x/Kconfig +++ b/arch/arm/mach-iop33x/Kconfig @@ -16,6 +16,14 @@ config MACH_IQ80332 Say Y here if you want to run your kernel on the Intel IQ80332 evaluation kit for the IOP332 chipset. +config IOP3XX_ATU + bool "Enable the PCI Controller" + default y + help + Say Y here if you want the IOP to initialize its PCI Controller. + Say N if the IOP is an add in card, the host system owns the PCI + bus in this case. + endmenu endif diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c index 1a9e36138d80..376c932830be 100644 --- a/arch/arm/mach-iop33x/iq80331.c +++ b/arch/arm/mach-iop33x/iq80331.c @@ -96,7 +96,8 @@ static struct hw_pci iq80331_pci __initdata = { static int __init iq80331_pci_init(void) { - if (machine_is_iq80331()) + if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) && + machine_is_iq80331()) pci_common_init(&iq80331_pci); return 0; diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c index 96d6f0f3cd21..58c81496c6f6 100644 --- a/arch/arm/mach-iop33x/iq80332.c +++ b/arch/arm/mach-iop33x/iq80332.c @@ -96,7 +96,8 @@ static struct hw_pci iq80332_pci __initdata = { static int __init iq80332_pci_init(void) { - if (machine_is_iq80332()) + if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) && + machine_is_iq80332()) pci_common_init(&iq80332_pci); return 0; diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c index b5f6ec35aafb..e2744b7227c5 100644 --- a/arch/arm/plat-iop/pci.c +++ b/arch/arm/plat-iop/pci.c @@ -55,7 +55,7 @@ static u32 iop3xx_cfg_address(struct pci_bus *bus, int devfn, int where) * This routine checks the status of the last configuration cycle. If an error * was detected it returns a 1, else it returns a 0. The errors being checked * are parity, master abort, target abort (master and target). These types of - * errors occure during a config cycle where there is no device, like during + * errors occur during a config cycle where there is no device, like during * the discovery stage. */ static int iop3xx_pci_status(void) @@ -223,8 +223,111 @@ struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *sys) return pci_scan_bus(sys->busnr, &iop3xx_ops, sys); } +void __init iop3xx_atu_setup(void) +{ + /* BAR 0 ( Disabled ) */ + *IOP3XX_IAUBAR0 = 0x0; + *IOP3XX_IABAR0 = 0x0; + *IOP3XX_IATVR0 = 0x0; + *IOP3XX_IALR0 = 0x0; + + /* BAR 1 ( Disabled ) */ + *IOP3XX_IAUBAR1 = 0x0; + *IOP3XX_IABAR1 = 0x0; + *IOP3XX_IALR1 = 0x0; + + /* BAR 2 (1:1 mapping with Physical RAM) */ + /* Set limit and enable */ + *IOP3XX_IALR2 = ~((u32)IOP3XX_MAX_RAM_SIZE - 1) & ~0x1; + *IOP3XX_IAUBAR2 = 0x0; + + /* Align the inbound bar with the base of memory */ + *IOP3XX_IABAR2 = PHYS_OFFSET | + PCI_BASE_ADDRESS_MEM_TYPE_64 | + PCI_BASE_ADDRESS_MEM_PREFETCH; + + *IOP3XX_IATVR2 = PHYS_OFFSET; + + /* Outbound window 0 */ + *IOP3XX_OMWTVR0 = IOP3XX_PCI_LOWER_MEM_PA; + *IOP3XX_OUMWTVR0 = 0; + + /* Outbound window 1 */ + *IOP3XX_OMWTVR1 = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE; + *IOP3XX_OUMWTVR1 = 0; + + /* BAR 3 ( Disabled ) */ + *IOP3XX_IAUBAR3 = 0x0; + *IOP3XX_IABAR3 = 0x0; + *IOP3XX_IATVR3 = 0x0; + *IOP3XX_IALR3 = 0x0; + + /* Setup the I/O Bar + */ + *IOP3XX_OIOWTVR = IOP3XX_PCI_LOWER_IO_PA;; + + /* Enable inbound and outbound cycles + */ + *IOP3XX_ATUCMD |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | + PCI_COMMAND_PARITY | PCI_COMMAND_SERR; + *IOP3XX_ATUCR |= IOP3XX_ATUCR_OUT_EN; +} + +void __init iop3xx_atu_disable(void) +{ + *IOP3XX_ATUCMD = 0; + *IOP3XX_ATUCR = 0; + + /* wait for cycles to quiesce */ + while (*IOP3XX_PCSR & (IOP3XX_PCSR_OUT_Q_BUSY | + IOP3XX_PCSR_IN_Q_BUSY)) + cpu_relax(); + + /* BAR 0 ( Disabled ) */ + *IOP3XX_IAUBAR0 = 0x0; + *IOP3XX_IABAR0 = 0x0; + *IOP3XX_IATVR0 = 0x0; + *IOP3XX_IALR0 = 0x0; + + /* BAR 1 ( Disabled ) */ + *IOP3XX_IAUBAR1 = 0x0; + *IOP3XX_IABAR1 = 0x0; + *IOP3XX_IALR1 = 0x0; + + /* BAR 2 ( Disabled ) */ + *IOP3XX_IAUBAR2 = 0x0; + *IOP3XX_IABAR2 = 0x0; + *IOP3XX_IATVR2 = 0x0; + *IOP3XX_IALR2 = 0x0; + + /* BAR 3 ( Disabled ) */ + *IOP3XX_IAUBAR3 = 0x0; + *IOP3XX_IABAR3 = 0x0; + *IOP3XX_IATVR3 = 0x0; + *IOP3XX_IALR3 = 0x0; + + /* Clear the outbound windows */ + *IOP3XX_OIOWTVR = 0; + + /* Outbound window 0 */ + *IOP3XX_OMWTVR0 = 0; + *IOP3XX_OUMWTVR0 = 0; + + /* Outbound window 1 */ + *IOP3XX_OMWTVR1 = 0; + *IOP3XX_OUMWTVR1 = 0; +} + +/* Flag to determine whether the ATU is initialized and the PCI bus scanned */ +int init_atu; + void iop3xx_pci_preinit(void) { + if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) { + iop3xx_atu_disable(); + iop3xx_atu_setup(); + } + DBG("PCI: Intel 803xx PCI init code.\n"); DBG("ATU: IOP3XX_ATUCMD=0x%04x\n", *IOP3XX_ATUCMD); DBG("ATU: IOP3XX_OMWTVR0=0x%04x, IOP3XX_OIOWTVR=0x%04x\n", @@ -245,3 +348,38 @@ void iop3xx_pci_preinit(void) hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, "imprecise external abort"); } + +/* allow init_atu to be user overridden */ +static int __init iop3xx_init_atu_setup(char *str) +{ + init_atu = IOP3XX_INIT_ATU_DEFAULT; + if (str) { + while (*str != '\0') { + switch (*str) { + case 'y': + case 'Y': + init_atu = IOP3XX_INIT_ATU_ENABLE; + break; + case 'n': + case 'N': + init_atu = IOP3XX_INIT_ATU_DISABLE; + break; + case ',': + case '=': + break; + default: + printk(KERN_DEBUG "\"%s\" malformed at " + "character: \'%c\'", + __FUNCTION__, + *str); + *(str + 1) = '\0'; + } + str++; + } + } + + return 1; +} + +__setup("iop3xx_init_atu", iop3xx_init_atu_setup); + diff --git a/include/asm-arm/arch-iop32x/iop32x.h b/include/asm-arm/arch-iop32x/iop32x.h index 2e9469047eb1..0d8af57221a1 100644 --- a/include/asm-arm/arch-iop32x/iop32x.h +++ b/include/asm-arm/arch-iop32x/iop32x.h @@ -24,5 +24,14 @@ #include +/* ATU Parameters + * set up a 1:1 bus to physical ram relationship + * w/ physical ram on top of pci in the memory map + */ +#define IOP32X_MAX_RAM_SIZE 0x40000000UL +#define IOP3XX_MAX_RAM_SIZE IOP32X_MAX_RAM_SIZE +#define IOP3XX_PCI_LOWER_MEM_BA 0x80000000 +#define IOP32X_PCI_MEM_WINDOW_SIZE 0x04000000 +#define IOP3XX_PCI_MEM_WINDOW_SIZE IOP32X_PCI_MEM_WINDOW_SIZE #endif diff --git a/include/asm-arm/arch-iop32x/memory.h b/include/asm-arm/arch-iop32x/memory.h index 764cd3f0d416..c51072af214e 100644 --- a/include/asm-arm/arch-iop32x/memory.h +++ b/include/asm-arm/arch-iop32x/memory.h @@ -19,8 +19,8 @@ * bus_to_virt: Used to convert an address for DMA operations * to an address that the kernel can use. */ -#define __virt_to_bus(x) (((__virt_to_phys(x)) & ~(*IOP3XX_IATVR2)) | ((*IOP3XX_IABAR2) & 0xfffffff0)) -#define __bus_to_virt(x) (__phys_to_virt(((x) & ~(*IOP3XX_IALR2)) | ( *IOP3XX_IATVR2))) +#define __virt_to_bus(x) (__virt_to_phys(x)) +#define __bus_to_virt(x) (__phys_to_virt(x)) #endif diff --git a/include/asm-arm/arch-iop33x/iop33x.h b/include/asm-arm/arch-iop33x/iop33x.h index 7ac6e93db5ff..766985b9a723 100644 --- a/include/asm-arm/arch-iop33x/iop33x.h +++ b/include/asm-arm/arch-iop33x/iop33x.h @@ -29,5 +29,15 @@ #define IOP33X_UART1_PHYS (IOP3XX_PERIPHERAL_PHYS_BASE + 0x1740) #define IOP33X_UART1_VIRT (IOP3XX_PERIPHERAL_VIRT_BASE + 0x1740) +/* ATU Parameters + * set up a 1:1 bus to physical ram relationship + * w/ pci on top of physical ram in memory map + */ +#define IOP33X_MAX_RAM_SIZE 0x80000000UL +#define IOP3XX_MAX_RAM_SIZE IOP33X_MAX_RAM_SIZE +#define IOP3XX_PCI_LOWER_MEM_BA (PHYS_OFFSET + IOP33X_MAX_RAM_SIZE) +#define IOP33X_PCI_MEM_WINDOW_SIZE 0x08000000 +#define IOP3XX_PCI_MEM_WINDOW_SIZE IOP33X_PCI_MEM_WINDOW_SIZE + #endif diff --git a/include/asm-arm/arch-iop33x/memory.h b/include/asm-arm/arch-iop33x/memory.h index 0d39139b241e..c8749127d6ab 100644 --- a/include/asm-arm/arch-iop33x/memory.h +++ b/include/asm-arm/arch-iop33x/memory.h @@ -19,8 +19,8 @@ * bus_to_virt: Used to convert an address for DMA operations * to an address that the kernel can use. */ -#define __virt_to_bus(x) (((__virt_to_phys(x)) & ~(*IOP3XX_IATVR2)) | ((*IOP3XX_IABAR2) & 0xfffffff0)) -#define __bus_to_virt(x) (__phys_to_virt(((x) & ~(*IOP3XX_IALR2)) | ( *IOP3XX_IATVR2))) +#define __virt_to_bus(x) (__virt_to_phys(x)) +#define __bus_to_virt(x) (__phys_to_virt(x)) #endif diff --git a/include/asm-arm/hardware/iop3xx.h b/include/asm-arm/hardware/iop3xx.h index 15141a9caca8..ebbcd9be3fe5 100644 --- a/include/asm-arm/hardware/iop3xx.h +++ b/include/asm-arm/hardware/iop3xx.h @@ -28,6 +28,7 @@ extern void gpio_line_config(int line, int direction); extern int gpio_line_get(int line); extern void gpio_line_set(int line, int value); +extern int init_atu; #endif @@ -103,6 +104,21 @@ extern void gpio_line_set(int line, int value); #define IOP3XX_PCIXCMD (volatile u16 *)IOP3XX_REG_ADDR(0x01e2) #define IOP3XX_PCIXSR (volatile u32 *)IOP3XX_REG_ADDR(0x01e4) #define IOP3XX_PCIIRSR (volatile u32 *)IOP3XX_REG_ADDR(0x01ec) +#define IOP3XX_PCSR_OUT_Q_BUSY (1 << 15) +#define IOP3XX_PCSR_IN_Q_BUSY (1 << 14) +#define IOP3XX_ATUCR_OUT_EN (1 << 1) + +#define IOP3XX_INIT_ATU_DEFAULT 0 +#define IOP3XX_INIT_ATU_DISABLE -1 +#define IOP3XX_INIT_ATU_ENABLE 1 + +#ifdef CONFIG_IOP3XX_ATU +#define iop3xx_get_init_atu(x) (init_atu == IOP3XX_INIT_ATU_DEFAULT ?\ + IOP3XX_INIT_ATU_ENABLE : init_atu) +#else +#define iop3xx_get_init_atu(x) (init_atu == IOP3XX_INIT_ATU_DEFAULT ?\ + IOP3XX_INIT_ATU_DISABLE : init_atu) +#endif /* Messaging Unit */ #define IOP3XX_IMR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0310) @@ -253,14 +269,12 @@ extern void gpio_line_set(int line, int value); /* * IOP3XX I/O and Mem space regions for PCI autoconfiguration */ -#define IOP3XX_PCI_MEM_WINDOW_SIZE 0x04000000 -#define IOP3XX_PCI_LOWER_MEM_PA 0x80000000 -#define IOP3XX_PCI_LOWER_MEM_BA (*IOP3XX_OMWTVR0) +#define IOP3XX_PCI_LOWER_MEM_PA 0x80000000 #define IOP3XX_PCI_IO_WINDOW_SIZE 0x00010000 #define IOP3XX_PCI_LOWER_IO_PA 0x90000000 #define IOP3XX_PCI_LOWER_IO_VA 0xfe000000 -#define IOP3XX_PCI_LOWER_IO_BA (*IOP3XX_OIOWTVR) +#define IOP3XX_PCI_LOWER_IO_BA 0x90000000 #define IOP3XX_PCI_UPPER_IO_PA (IOP3XX_PCI_LOWER_IO_PA +\ IOP3XX_PCI_IO_WINDOW_SIZE - 1) #define IOP3XX_PCI_UPPER_IO_VA (IOP3XX_PCI_LOWER_IO_VA +\ -- cgit v1.2.3-59-g8ed1b From d2dd8b1fed314d22c50965f78f6895117c4abfc8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 2 May 2007 17:47:47 +0100 Subject: [ARM] 4342/2: iop13xx: add resource definitions for the tpmi units The tpmi units interface with the SAS controller on iop348. Signed-off-by: Dan Williams Signed-off-by: Russell King --- arch/arm/mach-iop13xx/Makefile | 1 + arch/arm/mach-iop13xx/iq81340mc.c | 1 + arch/arm/mach-iop13xx/iq81340sc.c | 1 + arch/arm/mach-iop13xx/tpmi.c | 234 +++++++++++++++++++++++++++++++++ include/asm-arm/arch-iop13xx/iop13xx.h | 1 + 5 files changed, 238 insertions(+) create mode 100644 arch/arm/mach-iop13xx/tpmi.c (limited to 'arch') diff --git a/arch/arm/mach-iop13xx/Makefile b/arch/arm/mach-iop13xx/Makefile index 4185e0586c33..da1609dc0dee 100644 --- a/arch/arm/mach-iop13xx/Makefile +++ b/arch/arm/mach-iop13xx/Makefile @@ -7,5 +7,6 @@ obj-$(CONFIG_ARCH_IOP13XX) += setup.o obj-$(CONFIG_ARCH_IOP13XX) += irq.o obj-$(CONFIG_ARCH_IOP13XX) += pci.o obj-$(CONFIG_ARCH_IOP13XX) += io.o +obj-$(CONFIG_ARCH_IOP13XX) += tpmi.o obj-$(CONFIG_MACH_IQ81340SC) += iq81340sc.o obj-$(CONFIG_MACH_IQ81340MC) += iq81340mc.o diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c index 1ae08cc04b48..268a8d84999c 100644 --- a/arch/arm/mach-iop13xx/iq81340mc.c +++ b/arch/arm/mach-iop13xx/iq81340mc.c @@ -75,6 +75,7 @@ static void __init iq81340mc_init(void) { iop13xx_platform_init(); iq81340mc_pci_init(); + iop13xx_add_tpmi_devices(); } static void __init iq81340mc_timer_init(void) diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c index 0f8801406f23..a51ffd2683e5 100644 --- a/arch/arm/mach-iop13xx/iq81340sc.c +++ b/arch/arm/mach-iop13xx/iq81340sc.c @@ -77,6 +77,7 @@ static void __init iq81340sc_init(void) { iop13xx_platform_init(); iq81340sc_pci_init(); + iop13xx_add_tpmi_devices(); } static void __init iq81340sc_timer_init(void) diff --git a/arch/arm/mach-iop13xx/tpmi.c b/arch/arm/mach-iop13xx/tpmi.c new file mode 100644 index 000000000000..d3dc278213da --- /dev/null +++ b/arch/arm/mach-iop13xx/tpmi.c @@ -0,0 +1,234 @@ +/* + * iop13xx tpmi device resources + * Copyright (c) 2005-2006, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +/* assumes CONTROLLER_ONLY# is never asserted in the ESSR register */ +#define IOP13XX_TPMI_MMR(dev) IOP13XX_REG_ADDR32_PHYS(0x48000 + (dev << 12)) +#define IOP13XX_TPMI_MEM(dev) IOP13XX_REG_ADDR32_PHYS(0x60000 + (dev << 13)) +#define IOP13XX_TPMI_CTRL(dev) IOP13XX_REG_ADDR32_PHYS(0x50000 + (dev << 10)) +#define IOP13XX_TPMI_MMR_SIZE (SZ_4K - 1) +#define IOP13XX_TPMI_MEM_SIZE (255) +#define IOP13XX_TPMI_MEM_CTRL (SZ_1K - 1) +#define IOP13XX_TPMI_RESOURCE_MMR 0 +#define IOP13XX_TPMI_RESOURCE_MEM 1 +#define IOP13XX_TPMI_RESOURCE_CTRL 2 +#define IOP13XX_TPMI_RESOURCE_IRQ 3 + +static struct resource iop13xx_tpmi_0_resources[] = { + [IOP13XX_TPMI_RESOURCE_MMR] = { + .start = IOP13XX_TPMI_MMR(4), /* tpmi0 starts at dev == 4 */ + .end = IOP13XX_TPMI_MMR(4) + IOP13XX_TPMI_MMR_SIZE, + .flags = IORESOURCE_MEM, + }, + [IOP13XX_TPMI_RESOURCE_MEM] = { + .start = IOP13XX_TPMI_MEM(0), + .end = IOP13XX_TPMI_MEM(0) + IOP13XX_TPMI_MEM_SIZE, + .flags = IORESOURCE_MEM, + }, + [IOP13XX_TPMI_RESOURCE_CTRL] = { + .start = IOP13XX_TPMI_CTRL(0), + .end = IOP13XX_TPMI_CTRL(0) + IOP13XX_TPMI_MEM_CTRL, + .flags = IORESOURCE_MEM, + }, + [IOP13XX_TPMI_RESOURCE_IRQ] = { + .start = IRQ_IOP13XX_TPMI0_OUT, + .end = IRQ_IOP13XX_TPMI0_OUT, + .flags = IORESOURCE_IRQ + } +}; + +static struct resource iop13xx_tpmi_1_resources[] = { + [IOP13XX_TPMI_RESOURCE_MMR] = { + .start = IOP13XX_TPMI_MMR(1), + .end = IOP13XX_TPMI_MMR(1) + IOP13XX_TPMI_MMR_SIZE, + .flags = IORESOURCE_MEM, + }, + [IOP13XX_TPMI_RESOURCE_MEM] = { + .start = IOP13XX_TPMI_MEM(1), + .end = IOP13XX_TPMI_MEM(1) + IOP13XX_TPMI_MEM_SIZE, + .flags = IORESOURCE_MEM, + }, + [IOP13XX_TPMI_RESOURCE_CTRL] = { + .start = IOP13XX_TPMI_CTRL(1), + .end = IOP13XX_TPMI_CTRL(1) + IOP13XX_TPMI_MEM_CTRL, + .flags = IORESOURCE_MEM, + }, + [IOP13XX_TPMI_RESOURCE_IRQ] = { + .start = IRQ_IOP13XX_TPMI1_OUT, + .end = IRQ_IOP13XX_TPMI1_OUT, + .flags = IORESOURCE_IRQ + } +}; + +static struct resource iop13xx_tpmi_2_resources[] = { + [IOP13XX_TPMI_RESOURCE_MMR] = { + .start = IOP13XX_TPMI_MMR(2), + .end = IOP13XX_TPMI_MMR(2) + IOP13XX_TPMI_MMR_SIZE, + .flags = IORESOURCE_MEM, + }, + [IOP13XX_TPMI_RESOURCE_MEM] = { + .start = IOP13XX_TPMI_MEM(2), + .end = IOP13XX_TPMI_MEM(2) + IOP13XX_TPMI_MEM_SIZE, + .flags = IORESOURCE_MEM, + }, + [IOP13XX_TPMI_RESOURCE_CTRL] = { + .start = IOP13XX_TPMI_CTRL(2), + .end = IOP13XX_TPMI_CTRL(2) + IOP13XX_TPMI_MEM_CTRL, + .flags = IORESOURCE_MEM, + }, + [IOP13XX_TPMI_RESOURCE_IRQ] = { + .start = IRQ_IOP13XX_TPMI2_OUT, + .end = IRQ_IOP13XX_TPMI2_OUT, + .flags = IORESOURCE_IRQ + } +}; + +static struct resource iop13xx_tpmi_3_resources[] = { + [IOP13XX_TPMI_RESOURCE_MMR] = { + .start = IOP13XX_TPMI_MMR(3), + .end = IOP13XX_TPMI_MMR(3) + IOP13XX_TPMI_MMR_SIZE, + .flags = IORESOURCE_MEM, + }, + [IOP13XX_TPMI_RESOURCE_MEM] = { + .start = IOP13XX_TPMI_MEM(3), + .end = IOP13XX_TPMI_MEM(3) + IOP13XX_TPMI_MEM_SIZE, + .flags = IORESOURCE_MEM, + }, + [IOP13XX_TPMI_RESOURCE_CTRL] = { + .start = IOP13XX_TPMI_CTRL(3), + .end = IOP13XX_TPMI_CTRL(3) + IOP13XX_TPMI_MEM_CTRL, + .flags = IORESOURCE_MEM, + }, + [IOP13XX_TPMI_RESOURCE_IRQ] = { + .start = IRQ_IOP13XX_TPMI3_OUT, + .end = IRQ_IOP13XX_TPMI3_OUT, + .flags = IORESOURCE_IRQ + } +}; + +u64 iop13xx_tpmi_mask = DMA_64BIT_MASK; +static struct platform_device iop13xx_tpmi_0_device = { + .name = "iop-tpmi", + .id = 0, + .num_resources = 4, + .resource = iop13xx_tpmi_0_resources, + .dev = { + .dma_mask = &iop13xx_tpmi_mask, + .coherent_dma_mask = DMA_64BIT_MASK, + }, +}; + +static struct platform_device iop13xx_tpmi_1_device = { + .name = "iop-tpmi", + .id = 1, + .num_resources = 4, + .resource = iop13xx_tpmi_1_resources, + .dev = { + .dma_mask = &iop13xx_tpmi_mask, + .coherent_dma_mask = DMA_64BIT_MASK, + }, +}; + +static struct platform_device iop13xx_tpmi_2_device = { + .name = "iop-tpmi", + .id = 2, + .num_resources = 4, + .resource = iop13xx_tpmi_2_resources, + .dev = { + .dma_mask = &iop13xx_tpmi_mask, + .coherent_dma_mask = DMA_64BIT_MASK, + }, +}; + +static struct platform_device iop13xx_tpmi_3_device = { + .name = "iop-tpmi", + .id = 3, + .num_resources = 4, + .resource = iop13xx_tpmi_3_resources, + .dev = { + .dma_mask = &iop13xx_tpmi_mask, + .coherent_dma_mask = DMA_64BIT_MASK, + }, +}; + +__init void iop13xx_add_tpmi_devices(void) +{ + unsigned short device_id; + + /* tpmi's not present on iop341 or iop342 */ + if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX) + /* ATUE must be present */ + device_id = __raw_readw(IOP13XX_ATUE_DID); + else + /* ATUX must be present */ + device_id = __raw_readw(IOP13XX_ATUX_DID); + + switch (device_id) { + /* iop34[1|2] 0-tpmi */ + case 0x3380: + case 0x3384: + case 0x3388: + case 0x338c: + case 0x3382: + case 0x3386: + case 0x338a: + case 0x338e: + return; + /* iop348 1-tpmi */ + case 0x3310: + case 0x3312: + case 0x3314: + case 0x3318: + case 0x331a: + case 0x331c: + case 0x33c0: + case 0x33c2: + case 0x33c4: + case 0x33c8: + case 0x33ca: + case 0x33cc: + case 0x33b0: + case 0x33b2: + case 0x33b4: + case 0x33b8: + case 0x33ba: + case 0x33bc: + case 0x3320: + case 0x3322: + case 0x3324: + case 0x3328: + case 0x332a: + case 0x332c: + platform_device_register(&iop13xx_tpmi_0_device); + return; + default: + platform_device_register(&iop13xx_tpmi_0_device); + platform_device_register(&iop13xx_tpmi_1_device); + platform_device_register(&iop13xx_tpmi_2_device); + platform_device_register(&iop13xx_tpmi_3_device); + return; + } +} diff --git a/include/asm-arm/arch-iop13xx/iop13xx.h b/include/asm-arm/arch-iop13xx/iop13xx.h index c8762ae8f628..85707e9c3325 100644 --- a/include/asm-arm/arch-iop13xx/iop13xx.h +++ b/include/asm-arm/arch-iop13xx/iop13xx.h @@ -8,6 +8,7 @@ extern u32 iop13xx_atue_pmmr_offset; void iop13xx_init_irq(void); void iop13xx_map_io(void); void iop13xx_platform_init(void); +void iop13xx_add_tpmi_devices(void); void iop13xx_init_irq(void); /* CPUID CP6 R0 Page 0 */ -- cgit v1.2.3-59-g8ed1b From 99cce8f7b10716f8fdbaca21a7f3ba000119ad3b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 3 May 2007 00:18:34 +0100 Subject: [ARM] 4356/1: arm: fix handling of svc mode undefined instructions Now that do_undefinstr handles kernel and user mode undefined instruction exceptions it must not assume that interrupts are enabled at entry. Signed-off-by: Dan Williams Signed-off-by: Russell King --- arch/arm/kernel/traps.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 6055ab4b58d9..f05e66b0f868 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -286,6 +286,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) struct undef_hook *hook; siginfo_t info; void __user *pc; + unsigned long flags; /* * According to the ARM ARM, PC is 2 or 4 bytes ahead, @@ -304,7 +305,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) get_user(instr, (u32 __user *)pc); } - spin_lock_irq(&undef_lock); + spin_lock_irqsave(&undef_lock, flags); list_for_each_entry(hook, &undef_hook, node) { if ((instr & hook->instr_mask) == hook->instr_val && (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) { @@ -314,7 +315,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) } } } - spin_unlock_irq(&undef_lock); + spin_unlock_irqrestore(&undef_lock, flags); #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_UNDEFINED) { -- cgit v1.2.3-59-g8ed1b From e8788babe6ddb35ab041a146d6b3e18874513566 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Wed, 2 May 2007 17:14:57 +0100 Subject: [ARM] 4351/1: AT91: Define rest of peripheral clocks Define and register the remaining peripheral clocks for the AT91 processors. AT91SAM9261 clocks patch by Ivan Zhakov. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91/at91rm9200.c | 19 +++++++++++++++- arch/arm/mach-at91/at91sam9260.c | 7 +++++- arch/arm/mach-at91/at91sam9261.c | 19 +++++++++++++++- arch/arm/mach-at91/at91sam9263.c | 48 +++++++++++++++++++++++++++++++++++----- 4 files changed, 84 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index 2ddcdd69df7d..2cad2bf864be 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -117,6 +117,21 @@ static struct clk pioD_clk = { .pmc_mask = 1 << AT91RM9200_ID_PIOD, .type = CLK_TYPE_PERIPHERAL, }; +static struct clk ssc0_clk = { + .name = "ssc0_clk", + .pmc_mask = 1 << AT91RM9200_ID_SSC0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc1_clk = { + .name = "ssc1_clk", + .pmc_mask = 1 << AT91RM9200_ID_SSC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc2_clk = { + .name = "ssc2_clk", + .pmc_mask = 1 << AT91RM9200_ID_SSC2, + .type = CLK_TYPE_PERIPHERAL, +}; static struct clk tc0_clk = { .name = "tc0_clk", .pmc_mask = 1 << AT91RM9200_ID_TC0, @@ -161,7 +176,9 @@ static struct clk *periph_clocks[] __initdata = { &udc_clk, &twi_clk, &spi_clk, - // ssc 0 .. ssc2 + &ssc0_clk, + &ssc1_clk, + &ssc2_clk, &tc0_clk, &tc1_clk, &tc2_clk, diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 6ea41d8266cb..e47381e8aaba 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -119,6 +119,11 @@ static struct clk spi1_clk = { .pmc_mask = 1 << AT91SAM9260_ID_SPI1, .type = CLK_TYPE_PERIPHERAL, }; +static struct clk ssc_clk = { + .name = "ssc_clk", + .pmc_mask = 1 << AT91SAM9260_ID_SSC, + .type = CLK_TYPE_PERIPHERAL, +}; static struct clk tc0_clk = { .name = "tc0_clk", .pmc_mask = 1 << AT91SAM9260_ID_TC0, @@ -193,7 +198,7 @@ static struct clk *periph_clocks[] __initdata = { &twi_clk, &spi0_clk, &spi1_clk, - // ssc + &ssc_clk, &tc0_clk, &tc1_clk, &tc2_clk, diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 784d1e682d6d..dfe8c39c9fb9 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -97,6 +97,21 @@ static struct clk spi1_clk = { .pmc_mask = 1 << AT91SAM9261_ID_SPI1, .type = CLK_TYPE_PERIPHERAL, }; +static struct clk ssc0_clk = { + .name = "ssc0_clk", + .pmc_mask = 1 << AT91SAM9261_ID_SSC0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc1_clk = { + .name = "ssc1_clk", + .pmc_mask = 1 << AT91SAM9261_ID_SSC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc2_clk = { + .name = "ssc2_clk", + .pmc_mask = 1 << AT91SAM9261_ID_SSC2, + .type = CLK_TYPE_PERIPHERAL, +}; static struct clk tc0_clk = { .name = "tc0_clk", .pmc_mask = 1 << AT91SAM9261_ID_TC0, @@ -135,7 +150,9 @@ static struct clk *periph_clocks[] __initdata = { &twi_clk, &spi0_clk, &spi1_clk, - // ssc 0 .. ssc2 + &ssc0_clk, + &ssc1_clk, + &ssc2_clk, &tc0_clk, &tc1_clk, &tc2_clk, diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 0e89a7fca3fa..00e27b177857 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -87,6 +87,11 @@ static struct clk mmc1_clk = { .pmc_mask = 1 << AT91SAM9263_ID_MCI1, .type = CLK_TYPE_PERIPHERAL, }; +static struct clk can_clk = { + .name = "can_clk", + .pmc_mask = 1 << AT91SAM9263_ID_CAN, + .type = CLK_TYPE_PERIPHERAL, +}; static struct clk twi_clk = { .name = "twi_clk", .pmc_mask = 1 << AT91SAM9263_ID_TWI, @@ -102,16 +107,46 @@ static struct clk spi1_clk = { .pmc_mask = 1 << AT91SAM9263_ID_SPI1, .type = CLK_TYPE_PERIPHERAL, }; +static struct clk ssc0_clk = { + .name = "ssc0_clk", + .pmc_mask = 1 << AT91SAM9263_ID_SSC0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc1_clk = { + .name = "ssc1_clk", + .pmc_mask = 1 << AT91SAM9263_ID_SSC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ac97_clk = { + .name = "ac97_clk", + .pmc_mask = 1 << AT91SAM9263_ID_AC97C, + .type = CLK_TYPE_PERIPHERAL, +}; static struct clk tcb_clk = { .name = "tcb_clk", .pmc_mask = 1 << AT91SAM9263_ID_TCB, .type = CLK_TYPE_PERIPHERAL, }; +static struct clk pwmc_clk = { + .name = "pwmc_clk", + .pmc_mask = 1 << AT91SAM9263_ID_PWMC, + .type = CLK_TYPE_PERIPHERAL, +}; static struct clk macb_clk = { .name = "macb_clk", .pmc_mask = 1 << AT91SAM9263_ID_EMAC, .type = CLK_TYPE_PERIPHERAL, }; +static struct clk dma_clk = { + .name = "dma_clk", + .pmc_mask = 1 << AT91SAM9263_ID_DMA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twodge_clk = { + .name = "2dge_clk", + .pmc_mask = 1 << AT91SAM9263_ID_2DGE, + .type = CLK_TYPE_PERIPHERAL, +}; static struct clk udc_clk = { .name = "udc_clk", .pmc_mask = 1 << AT91SAM9263_ID_UDP, @@ -142,20 +177,21 @@ static struct clk *periph_clocks[] __initdata = { &usart2_clk, &mmc0_clk, &mmc1_clk, - // can + &can_clk, &twi_clk, &spi0_clk, &spi1_clk, - // ssc0 .. ssc1 - // ac97 + &ssc0_clk, + &ssc1_clk, + &ac97_clk, &tcb_clk, - // pwmc + &pwmc_clk, &macb_clk, - // 2dge + &twodge_clk, &udc_clk, &isi_clk, &lcdc_clk, - // dma + &dma_clk, &ohci_clk, // irq0 .. irq1 }; -- cgit v1.2.3-59-g8ed1b From 7776a94c311504f26e73060920dfb3ccf02786b7 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Wed, 2 May 2007 17:46:49 +0100 Subject: [ARM] 4352/1: AT91: Platform data for LCD and AC97. Define resources, platform_device and device registration functions for the LCD and AC97 controllers on the AT91SAM9263. Also update the AT91SAM9261 to use the common atmel_lcdfb driver. Signed-off-by: Nicolas Ferre Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91/at91sam9261_devices.c | 10 +-- arch/arm/mach-at91/at91sam9263_devices.c | 124 +++++++++++++++++++++++++++++++ include/asm-arm/arch-at91/board.h | 12 ++- 3 files changed, 140 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index e1504766fd64..8e781997716a 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -430,9 +430,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) * LCD Controller * -------------------------------------------------------------------- */ -#if defined(CONFIG_FB_AT91) || defined(CONFIG_FB_AT91_MODULE) +#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) static u64 lcdc_dmamask = 0xffffffffUL; -static struct at91fb_info lcdc_data; +static struct atmel_lcdfb_info lcdc_data; static struct resource lcdc_resources[] = { [0] = { @@ -455,7 +455,7 @@ static struct resource lcdc_resources[] = { }; static struct platform_device at91_lcdc_device = { - .name = "at91-fb", + .name = "atmel_lcdfb", .id = 0, .dev = { .dma_mask = &lcdc_dmamask, @@ -466,7 +466,7 @@ static struct platform_device at91_lcdc_device = { .num_resources = ARRAY_SIZE(lcdc_resources), }; -void __init at91_add_device_lcdc(struct at91fb_info *data) +void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) { if (!data) { return; @@ -499,7 +499,7 @@ void __init at91_add_device_lcdc(struct at91fb_info *data) platform_device_register(&at91_lcdc_device); } #else -void __init at91_add_device_lcdc(struct at91fb_info *data) {} +void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} #endif diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index b77121f27f34..2b2e18a67128 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -572,6 +572,130 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) #endif +/* -------------------------------------------------------------------- + * AC97 + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE) +static u64 ac97_dmamask = 0xffffffffUL; +static struct atmel_ac97_data ac97_data; + +static struct resource ac97_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_AC97C, + .end = AT91SAM9263_BASE_AC97C + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_AC97C, + .end = AT91SAM9263_ID_AC97C, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9263_ac97_device = { + .name = "ac97c", + .id = 1, + .dev = { + .dma_mask = &ac97_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &ac97_data, + }, + .resource = ac97_resources, + .num_resources = ARRAY_SIZE(ac97_resources), +}; + +void __init at91_add_device_ac97(struct atmel_ac97_data *data) +{ + if (!data) + return; + + at91_set_A_periph(AT91_PIN_PB0, 0); /* AC97FS */ + at91_set_A_periph(AT91_PIN_PB1, 0); /* AC97CK */ + at91_set_A_periph(AT91_PIN_PB2, 0); /* AC97TX */ + at91_set_A_periph(AT91_PIN_PB3, 0); /* AC97RX */ + + /* reset */ + if (data->reset_pin) + at91_set_gpio_output(data->reset_pin, 0); + + ac97_data = *ek_data; + platform_device_register(&at91sam9263_ac97_device); +} +#else +void __init at91_add_device_ac97(struct atmel_ac97_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * LCD Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) +static u64 lcdc_dmamask = 0xffffffffUL; +static struct atmel_lcdfb_info lcdc_data; + +static struct resource lcdc_resources[] = { + [0] = { + .start = AT91SAM9263_LCDC_BASE, + .end = AT91SAM9263_LCDC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_LCDC, + .end = AT91SAM9263_ID_LCDC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_lcdc_device = { + .name = "atmel_lcdfb", + .id = 0, + .dev = { + .dma_mask = &lcdc_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &lcdc_data, + }, + .resource = lcdc_resources, + .num_resources = ARRAY_SIZE(lcdc_resources), +}; + +void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) +{ + if (!data) + return; + + at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */ + at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */ + at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */ + at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */ + at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */ + at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */ + at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */ + at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */ + at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */ + at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */ + at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */ + at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */ + at91_set_B_periph(AT91_PIN_PC12, 0); /* LCDD13 */ + at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */ + at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */ + at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */ + at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */ + at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */ + at91_set_B_periph(AT91_PIN_PC17, 0); /* LCDD21 */ + at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */ + at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */ + + lcdc_data = *data; + platform_device_register(&at91_lcdc_device); +} +#else +void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} +#endif + + /* -------------------------------------------------------------------- * LEDs * -------------------------------------------------------------------- */ diff --git a/include/asm-arm/arch-at91/board.h b/include/asm-arm/arch-at91/board.h index 7b9903c2c447..7a34a5b1fed0 100644 --- a/include/asm-arm/arch-at91/board.h +++ b/include/asm-arm/arch-at91/board.h @@ -62,7 +62,7 @@ struct at91_mmc_data { }; extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data); - /* Ethernet */ + /* Ethernet (EMAC & MACB) */ struct at91_eth_data { u8 phy_irq_pin; /* PHY IRQ */ u8 is_rmii; /* using RMII interface? */ @@ -114,6 +114,16 @@ struct atmel_uart_data { }; extern void __init at91_add_device_serial(void); + /* LCD Controller */ +struct atmel_lcdfb_info; +extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data); + + /* AC97 */ +struct atmel_ac97_data { + u8 reset_pin; /* reset */ +} +extern void __init at91_add_device_ac97(struct atmel_ac97_data *data); + /* LEDs */ extern u8 at91_leds_cpu; extern u8 at91_leds_timer; -- cgit v1.2.3-59-g8ed1b From 235227285b3e4bae616be5720e6dedb49b914e9d Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Wed, 2 May 2007 17:58:51 +0100 Subject: [ARM] 4353/1: AT91: Support ADS7846 touchsceen on SAM9261-EK board Add support for the ADS7846 Touchscreen found on the Atmel AT91SAM9261-EK board. Original patch by Morten Larsen. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91/board-sam9261ek.c | 52 ++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index b7e772467cf6..bcf71536cc6d 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -194,6 +195,41 @@ static struct at91_nand_data __initdata ek_nand_data = { #endif }; +/* + * ADS7846 Touchscreen + */ +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + +static int ads7843_pendown_state(void) +{ + return !at91_get_gpio_value(AT91_PIN_PC2); /* Touchscreen PENIRQ */ +} + +static struct ads7846_platform_data ads_info = { + .model = 7843, + .x_min = 150, + .x_max = 3830, + .y_min = 190, + .y_max = 3830, + .vref_delay_usecs = 100, + .x_plate_ohms = 450, + .y_plate_ohms = 250, + .pressure_max = 15000, + .debounce_max = 1, + .debounce_rep = 0, + .debounce_tol = (~0), + .get_pendown_state = ads7843_pendown_state, +}; + +static void __init ek_add_device_ts(void) +{ + at91_set_B_periph(AT91_PIN_PC2, 1); /* External IRQ0, with pullup */ + at91_set_gpio_input(AT91_PIN_PA11, 1); /* Touchscreen BUSY signal */ +} +#else +static void __init ek_add_device_ts(void) {} +#endif + /* * SPI devices */ @@ -204,6 +240,16 @@ static struct spi_board_info ek_spi_devices[] = { .max_speed_hz = 15 * 1000 * 1000, .bus_num = 0, }, +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + { + .modalias = "ads7846", + .chip_select = 2, + .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ + .bus_num = 0, + .platform_data = &ads_info, + .irq = AT91SAM9261_ID_IRQ0, + }, +#endif #if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) { /* DataFlash card - jumper (J12) configurable to CS3 or CS0 */ .modalias = "mtd_dataflash", @@ -211,9 +257,9 @@ static struct spi_board_info ek_spi_devices[] = { .max_speed_hz = 15 * 1000 * 1000, .bus_num = 0, }, -#elif defined(CONFIG_SND_AT73C213) +#elif defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) { /* AT73C213 DAC */ - .modalias = "snd_at73c213", + .modalias = "at73c213", .chip_select = 3, .max_speed_hz = 10 * 1000 * 1000, .bus_num = 0, @@ -241,6 +287,8 @@ static void __init ek_board_init(void) #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) /* SPI */ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* Touchscreen */ + ek_add_device_ts(); #else /* MMC */ at91_add_device_mmc(0, &ek_mmc_data); -- cgit v1.2.3-59-g8ed1b From 7c73628f24ea73479232d1b608359aa7d8d2c95d Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Wed, 2 May 2007 18:00:45 +0100 Subject: [ARM] 4354/1: AT91: Support ADS7846 touchsceen on SAM9263-EK board Add support for the ADS7846 Touchscreen found on the Atmel AT91SAM9263-EK board. Signed-off-by: Nicolas Ferre Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91/board-sam9263ek.c | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index 8fdce11a880c..81d3d6a0a86a 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -85,6 +86,40 @@ static struct at91_udc_data __initdata ek_udc_data = { }; +/* + * ADS7846 Touchscreen + */ +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) +static int ads7843_pendown_state(void) +{ + return !at91_get_gpio_value(AT91_PIN_PA15); /* Touchscreen PENIRQ */ +} + +static struct ads7846_platform_data ads_info = { + .model = 7843, + .x_min = 150, + .x_max = 3830, + .y_min = 190, + .y_max = 3830, + .vref_delay_usecs = 100, + .x_plate_ohms = 450, + .y_plate_ohms = 250, + .pressure_max = 15000, + .debounce_max = 1, + .debounce_rep = 0, + .debounce_tol = (~0), + .get_pendown_state = ads7843_pendown_state, +}; + +static void __init ek_add_device_ts(void) +{ + at91_set_B_periph(AT91_PIN_PA15, 1); /* External IRQ1, with pullup */ + at91_set_gpio_input(AT91_PIN_PA31, 1); /* Touchscreen BUSY signal */ +} +#else +static void __init ek_add_device_ts(void) {} +#endif + /* * SPI devices. */ @@ -97,6 +132,16 @@ static struct spi_board_info ek_spi_devices[] = { .bus_num = 0, }, #endif +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + { + .modalias = "ads7846", + .chip_select = 3, + .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ + .bus_num = 0, + .platform_data = &ads_info, + .irq = AT91SAM9263_ID_IRQ1, + }, +#endif }; @@ -157,7 +202,10 @@ static void __init ek_board_init(void) /* USB Device */ at91_add_device_udc(&ek_udc_data); /* SPI */ + at91_set_gpio_output(AT91_PIN_PE20, 1); /* select spi0 clock */ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* Touchscreen */ + ek_add_device_ts(); /* MMC */ at91_add_device_mmc(1, &ek_mmc_data); /* NAND */ -- cgit v1.2.3-59-g8ed1b From 69f4f331a0f78470f0bc42ba8db8d6cdd9cae4a9 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 2 Apr 2007 13:53:15 +0100 Subject: [ARM] Set coherent DMA mask for Acorn expansion cards Although expansion cards can't do bus-master DMA, subsystems want to be able to use coherent memory for DMA purposes to these cards. Therefore, set the coherent DMA mask to allow such memory to be allocated. Signed-off-by: Russell King --- arch/arm/kernel/ecard.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index f1c0fb974177..6eb80acea379 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -825,6 +825,7 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot) ec->dev.bus = &ecard_bus_type; ec->dev.dma_mask = &ec->dma_mask; ec->dma_mask = (u64)0xffffffff; + ec->dev.coherent_dma_mask = ec->dma_mask; if (slot < 4) { ec_set_resource(ec, ECARD_RES_MEMC, -- cgit v1.2.3-59-g8ed1b From a17dba8df9848c548912fbe9bf4b28c5a67c5413 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Apr 2007 15:55:06 +0100 Subject: [ARM] Add platform support for PATA on RiscPC Add pata_platform device for RiscPC, thereby converting the primary IDE channel on the machine to PATA. Acked-by: Jeff Garzik Signed-off-by: Russell King --- arch/arm/mach-rpc/riscpc.c | 35 +++++++++++++++++++++++++++++++++++ drivers/ata/Kconfig | 2 +- 2 files changed, 36 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c index 208a2b5dba1b..570cf937e73b 100644 --- a/arch/arm/mach-rpc/riscpc.c +++ b/arch/arm/mach-rpc/riscpc.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -159,11 +160,45 @@ static struct platform_device serial_device = { }, }; +static struct pata_platform_info pata_platform_data = { + .ioport_shift = 2, +}; + +static struct resource pata_resources[] = { + [0] = { + .start = 0x030107c0, + .end = 0x030107df, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 0x03010fd8, + .end = 0x03010fdb, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = IRQ_HARDDISK, + .end = IRQ_HARDDISK, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device pata_device = { + .name = "pata_platform", + .id = -1, + .num_resources = ARRAY_SIZE(pata_resources), + .resource = pata_resources, + .dev = { + .platform_data = &pata_platform_data, + .coherent_dma_mask = ~0, /* grumble */ + }, +}; + static struct platform_device *devs[] __initdata = { &iomd_device, &kbd_device, &serial_device, &acornfb_device, + &pata_device, }; static int __init rpc_init(void) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 7bdbe5a914d0..e0820e8dd1c7 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -545,7 +545,7 @@ config PATA_WINBOND_VLB config PATA_PLATFORM tristate "Generic platform device PATA support" - depends on EMBEDDED + depends on EMBEDDED || ARCH_RPC help This option enables support for generic directly connected ATA devices commonly found on embedded systems. -- cgit v1.2.3-59-g8ed1b From 134c99e907ef2572cdaa148c191984b95d671981 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Thu, 26 Apr 2007 00:04:40 -0700 Subject: [ARM] ecard: convert to use the kthread API This patch modifies the startup of kecardd to use kthread_run not a kernel_thread combination of kernel_thread and daemonize. Making the code slightly simpler and more maintainable. Signed-off-by: Eric W. Biederman Signed-off-by: Andrew Morton Signed-off-by: Russell King --- arch/arm/kernel/ecard.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index 6eb80acea379..869de6d3ad53 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -263,8 +264,6 @@ static int ecard_init_mm(void) static int ecard_task(void * unused) { - daemonize("kecardd"); - /* * Allocate a mm. We're not a lazy-TLB kernel task since we need * to set page table entries where the user space would be. Note @@ -1059,13 +1058,14 @@ ecard_probe(int slot, card_type_t type) */ static int __init ecard_init(void) { - int slot, irqhw, ret; + struct task_struct *task; + int slot, irqhw; - ret = kernel_thread(ecard_task, NULL, CLONE_KERNEL); - if (ret < 0) { + task = kthread_run(ecard_task, NULL, "kecardd"); + if (IS_ERR(task)) { printk(KERN_ERR "Ecard: unable to create kernel thread: %d\n", - ret); - return ret; + PTR_ERR(task)); + return PTR_ERR(task); } printk("Probing expansion cards\n"); -- cgit v1.2.3-59-g8ed1b From e6aeb47da6e02ec9807d30a368d4fc37972b022f Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 3 May 2007 10:55:46 +0100 Subject: [ARM] ecard: silence new warning caused by previous commit PTR_ERR()'s type is unsigned long, so formats when printing must be %ld, not %d. Signed-off-by: Russell King --- arch/arm/kernel/ecard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index 869de6d3ad53..64d5ba1a1337 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -1063,7 +1063,7 @@ static int __init ecard_init(void) task = kthread_run(ecard_task, NULL, "kecardd"); if (IS_ERR(task)) { - printk(KERN_ERR "Ecard: unable to create kernel thread: %d\n", + printk(KERN_ERR "Ecard: unable to create kernel thread: %ld\n", PTR_ERR(task)); return PTR_ERR(task); } -- cgit v1.2.3-59-g8ed1b From c0b04d1b2c427629b2dbe066422a507ad855bf61 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 3 May 2007 10:20:47 +0100 Subject: [ARM] ecard: Move private ecard junk out of asm/ecard.h Move ecard.c private junk from asm/ecard.h to a local header file. Signed-off-by: Russell King --- arch/arm/kernel/ecard.c | 2 ++ arch/arm/kernel/ecard.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ include/asm-arm/ecard.h | 50 ------------------------------------------- 3 files changed, 58 insertions(+), 50 deletions(-) create mode 100644 arch/arm/kernel/ecard.h (limited to 'arch') diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index 64d5ba1a1337..85f4db6efa7c 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -51,6 +51,8 @@ #include #include +#include "ecard.h" + #ifndef CONFIG_ARCH_RPC #define HAVE_EXPMASK #endif diff --git a/arch/arm/kernel/ecard.h b/arch/arm/kernel/ecard.h new file mode 100644 index 000000000000..d7c2dacf935d --- /dev/null +++ b/arch/arm/kernel/ecard.h @@ -0,0 +1,56 @@ +/* + * ecard.h + * + * Copyright 2007 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* Definitions internal to ecard.c - for it's use only!! + * + * External expansion card header as read from the card + */ +struct ex_ecid { + unsigned char r_irq:1; + unsigned char r_zero:1; + unsigned char r_fiq:1; + unsigned char r_id:4; + unsigned char r_a:1; + + unsigned char r_cd:1; + unsigned char r_is:1; + unsigned char r_w:2; + unsigned char r_r1:4; + + unsigned char r_r2:8; + + unsigned char r_prod[2]; + + unsigned char r_manu[2]; + + unsigned char r_country; + + unsigned char r_fiqmask; + unsigned char r_fiqoff[3]; + + unsigned char r_irqmask; + unsigned char r_irqoff[3]; +}; + +/* + * Chunk directory entry as read from the card + */ +struct ex_chunk_dir { + unsigned char r_id; + unsigned char r_len[3]; + unsigned long r_start; + union { + char string[256]; + char data[1]; + } d; +#define c_id(x) ((x)->r_id) +#define c_len(x) ((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16)) +#define c_start(x) ((x)->r_start) +}; diff --git a/include/asm-arm/ecard.h b/include/asm-arm/ecard.h index a0ae2b954d29..bd4b5769dc4e 100644 --- a/include/asm-arm/ecard.h +++ b/include/asm-arm/ecard.h @@ -224,56 +224,6 @@ ecard_address(struct expansion_card *ec, card_type_t type, card_speed_t speed) extern int ecard_request_resources(struct expansion_card *ec); extern void ecard_release_resources(struct expansion_card *ec); -#ifdef ECARD_C -/* Definitions internal to ecard.c - for it's use only!! - * - * External expansion card header as read from the card - */ -struct ex_ecid { - unsigned char r_irq:1; - unsigned char r_zero:1; - unsigned char r_fiq:1; - unsigned char r_id:4; - unsigned char r_a:1; - - unsigned char r_cd:1; - unsigned char r_is:1; - unsigned char r_w:2; - unsigned char r_r1:4; - - unsigned char r_r2:8; - - unsigned char r_prod[2]; - - unsigned char r_manu[2]; - - unsigned char r_country; - - unsigned char r_fiqmask; - unsigned char r_fiqoff[3]; - - unsigned char r_irqmask; - unsigned char r_irqoff[3]; -}; - -/* - * Chunk directory entry as read from the card - */ -struct ex_chunk_dir { - unsigned char r_id; - unsigned char r_len[3]; - unsigned long r_start; - union { - char string[256]; - char data[1]; - } d; -#define c_id(x) ((x)->r_id) -#define c_len(x) ((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16)) -#define c_start(x) ((x)->r_start) -}; - -#endif - extern struct bus_type ecard_bus_type; #define ECARD_DEV(_d) container_of((_d), struct expansion_card, dev) -- cgit v1.2.3-59-g8ed1b From 5559bca8e66f968192a5416d953c88cc3389cb22 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 3 May 2007 10:47:37 +0100 Subject: [ARM] ecard: Convert card type enum to a flag 'type' in the struct expansion_card is only used to indicate whether this card is an EASI card or not. Therefore, having it as an enum is wasteful (and introduces additional noise when we come to remove the enum.) Convert it to a mere flag instead. Signed-off-by: Russell King --- arch/arm/kernel/ecard.c | 10 +++++----- include/asm-arm/ecard.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index 85f4db6efa7c..bdbd7da99286 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -126,7 +126,7 @@ static void ecard_task_reset(struct ecard_request *req) res = ec->slot_no == 8 ? &ec->resource[ECARD_RES_MEMC] - : ec->type == ECARD_EASI + : ec->easi ? &ec->resource[ECARD_RES_EASI] : &ec->resource[ECARD_RES_IOCSYNC]; @@ -181,7 +181,7 @@ static void ecard_task_readbytes(struct ecard_request *req) index += 1; } } else { - unsigned long base = (ec->type == ECARD_EASI + unsigned long base = (ec->easi ? &ec->resource[ECARD_RES_EASI] : &ec->resource[ECARD_RES_IOCSYNC])->start; void __iomem *pbase = (void __iomem *)base; @@ -728,7 +728,7 @@ static int ecard_prints(char *buffer, ecard_t *ec) char *start = buffer; buffer += sprintf(buffer, " %d: %s ", ec->slot_no, - ec->type == ECARD_EASI ? "EASI" : " "); + ec->easi ? "EASI" : " "); if (ec->cid.id == 0) { struct in_chunk_dir incd; @@ -815,7 +815,7 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot) } ec->slot_no = slot; - ec->type = type; + ec->easi = type == ECARD_EASI; ec->irq = NO_IRQ; ec->fiq = NO_IRQ; ec->dma = NO_DMA; @@ -909,7 +909,7 @@ static ssize_t ecard_show_device(struct device *dev, struct device_attribute *at static ssize_t ecard_show_type(struct device *dev, struct device_attribute *attr, char *buf) { struct expansion_card *ec = ECARD_DEV(dev); - return sprintf(buf, "%s\n", ec->type == ECARD_EASI ? "EASI" : "IOC"); + return sprintf(buf, "%s\n", ec->easi ? "EASI" : "IOC"); } static struct device_attribute ecard_dev_attrs[] = { diff --git a/include/asm-arm/ecard.h b/include/asm-arm/ecard.h index bd4b5769dc4e..3a6d3eb27622 100644 --- a/include/asm-arm/ecard.h +++ b/include/asm-arm/ecard.h @@ -160,6 +160,7 @@ struct expansion_card { unsigned char irqmask; /* IRQ mask */ unsigned char fiqmask; /* FIQ mask */ unsigned char claimed; /* Card claimed? */ + unsigned char easi; /* EASI card */ void *irq_data; /* Data for use for IRQ by card */ void *fiq_data; /* Data for use for FIQ by card */ @@ -169,7 +170,6 @@ struct expansion_card { CONST unsigned int dma; /* DMA number (for request_dma) */ CONST unsigned int irq; /* IRQ number (for request_irq) */ CONST unsigned int fiq; /* FIQ number (for request_irq) */ - CONST card_type_t type; /* Type of card */ CONST struct in_ecid cid; /* Card Identification */ /* Private internal data */ -- cgit v1.2.3-59-g8ed1b From 93afa75230f5969d559386e52819f54bb1182327 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Thu, 3 May 2007 14:39:41 +0100 Subject: [ARM] 4355/2: AT91: SAM9260-EK and SAM9263-EK board updates Various small changes for the Atmel AT91SAM9260-EK and AT91SAM9263-EK boards. SAM9260-EK: - Register I2C device. SAM9263-EK: - Add platform_data and register MACB device. (Patch by Nicolas Ferre) - Add platform_data and register AC97 device. (Patch by Nicolas Ferre) - Register I2C device. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91/board-sam9260ek.c | 6 ++++-- arch/arm/mach-at91/board-sam9263ek.c | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c index 7a31db01b6fe..65fa532bb4ac 100644 --- a/arch/arm/mach-at91/board-sam9260ek.c +++ b/arch/arm/mach-at91/board-sam9260ek.c @@ -104,9 +104,9 @@ static struct spi_board_info ek_spi_devices[] = { }, #endif #endif -#if defined(CONFIG_SND_AT73C213) +#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) { /* AT73C213 DAC */ - .modalias = "snd_at73c213", + .modalias = "at73c213", .chip_select = 0, .max_speed_hz = 10 * 1000 * 1000, .bus_num = 1, @@ -188,6 +188,8 @@ static void __init ek_board_init(void) at91_add_device_eth(&ek_macb_data); /* MMC */ at91_add_device_mmc(0, &ek_mmc_data); + /* I2C */ + at91_add_device_i2c(); } MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK") diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index 81d3d6a0a86a..f57458559fb6 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -156,6 +156,14 @@ static struct at91_mmc_data __initdata ek_mmc_data = { }; +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .is_rmii = 1, +}; + + /* * NAND flash */ @@ -193,6 +201,14 @@ static struct at91_nand_data __initdata ek_nand_data = { }; +/* + * AC97 + */ +static struct atmel_ac97_data ek_ac97_data = { + .reset_pin = AT91_PIN_PA13, +}; + + static void __init ek_board_init(void) { /* Serial */ @@ -208,8 +224,14 @@ static void __init ek_board_init(void) ek_add_device_ts(); /* MMC */ at91_add_device_mmc(1, &ek_mmc_data); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); /* NAND */ at91_add_device_nand(&ek_nand_data); + /* I2C */ + at91_add_device_i2c(); + /* AC97 */ + at91_add_device_ac97(&ek_ac97_data); } MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") -- cgit v1.2.3-59-g8ed1b From 40435792525c49cf126ba92d223e877acb5ce021 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 21 Feb 2007 15:58:13 +0100 Subject: [ARM] 4227/1: minor head.S fixups Let's surround constructs like: orr r3, r3, #(KERNEL_RAM_PADDR & 0x00f00000) between .if .endif since (KERNEL_RAM_PADDR & 0x00f00000) is 0 in 99% of all cases. Also let's mask PHYS_OFFSET with 0x00f00000 instead of 0x00e00000. Section mappings are really 1MB not 2MB and the 2MB groupping is a higher level issue already much better enforced with #if (PHYS_OFFSET & 0x001fffff) #error "PHYS_OFFSET must be at an even 2MiB boundary!" #endif at the top of the file. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/kernel/head.S | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 66db0a9bf0bc..1d35edacc011 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -257,7 +257,9 @@ __create_page_tables: * Map some ram to cover our .data and .bss areas. */ orr r3, r7, #(KERNEL_RAM_PADDR & 0xff000000) + .if (KERNEL_RAM_PADDR & 0x00f00000) orr r3, r3, #(KERNEL_RAM_PADDR & 0x00f00000) + .endif add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18 str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]! ldr r6, =(_end - 1) @@ -274,7 +276,9 @@ __create_page_tables: */ add r0, r4, #PAGE_OFFSET >> 18 orr r6, r7, #(PHYS_OFFSET & 0xff000000) - orr r6, r6, #(PHYS_OFFSET & 0x00e00000) + .if (PHYS_OFFSET & 0x00f00000) + orr r6, r6, #(PHYS_OFFSET & 0x00f00000) + .endif str r6, [r0] #ifdef CONFIG_DEBUG_LL -- cgit v1.2.3-59-g8ed1b From 7562f876cd93800f2f8c89445f2a563590b24e09 Mon Sep 17 00:00:00 2001 From: Pavel Emelianov Date: Thu, 3 May 2007 15:13:45 -0700 Subject: [NET]: Rework dev_base via list_head (v3) Cleanup of dev_base list use, with the aim to simplify making device list per-namespace. In almost every occasion, use of dev_base variable and dev->next pointer could be easily replaced by for_each_netdev loop. A few most complicated places were converted to using first_netdev()/next_netdev(). Signed-off-by: Pavel Emelianov Acked-by: Kirill Korotaev Signed-off-by: David S. Miller --- arch/s390/appldata/appldata_net_sum.c | 2 +- arch/sparc64/solaris/ioctl.c | 3 +- drivers/block/aoe/aoecmd.c | 8 ++-- drivers/net/wireless/strip.c | 4 +- drivers/parisc/led.c | 2 +- fs/afs/netdevices.c | 2 +- include/linux/netdevice.h | 26 ++++++++++- net/8021q/vlan.c | 3 +- net/8021q/vlanproc.c | 36 ++++++++++----- net/bridge/br_if.c | 4 +- net/bridge/br_ioctl.c | 4 +- net/bridge/br_netlink.c | 3 +- net/core/dev.c | 84 ++++++++++++++++------------------ net/core/dev_mcast.c | 5 +-- net/core/rtnetlink.c | 7 ++- net/decnet/af_decnet.c | 11 +++-- net/decnet/dn_dev.c | 85 +++++++++++++++++------------------ net/decnet/dn_fib.c | 2 +- net/decnet/dn_route.c | 14 +++--- net/ipv4/devinet.c | 17 ++++--- net/ipv4/igmp.c | 15 +++---- net/ipv4/ipconfig.c | 2 +- net/ipv6/addrconf.c | 28 +++++++----- net/ipv6/anycast.c | 17 ++++--- net/ipv6/mcast.c | 15 +++---- net/llc/llc_core.c | 10 ++++- net/netrom/nr_route.c | 5 ++- net/rose/rose_route.c | 8 ++-- net/sched/sch_api.c | 7 ++- net/sctp/protocol.c | 2 +- net/tipc/eth_media.c | 12 ++--- 31 files changed, 249 insertions(+), 194 deletions(-) (limited to 'arch') diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c index a43f3488fecf..2180ac105b05 100644 --- a/arch/s390/appldata/appldata_net_sum.c +++ b/arch/s390/appldata/appldata_net_sum.c @@ -107,7 +107,7 @@ static void appldata_get_net_sum_data(void *data) tx_dropped = 0; collisions = 0; read_lock(&dev_base_lock); - for (dev = dev_base; dev != NULL; dev = dev->next) { + for_each_netdev(dev) { stats = dev->get_stats(dev); rx_packets += stats->rx_packets; tx_packets += stats->tx_packets; diff --git a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c index 330743c5b3d8..18352a498628 100644 --- a/arch/sparc64/solaris/ioctl.c +++ b/arch/sparc64/solaris/ioctl.c @@ -686,7 +686,8 @@ static inline int solaris_i(unsigned int fd, unsigned int cmd, u32 arg) int i = 0; read_lock_bh(&dev_base_lock); - for (d = dev_base; d; d = d->next) i++; + for_each_netdev(d) + i++; read_unlock_bh(&dev_base_lock); if (put_user (i, (int __user *)A(arg))) diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 1a6aeac5a1c3..01fbdd38e3be 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -194,15 +194,15 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) sl = sl_tail = NULL; read_lock(&dev_base_lock); - for (ifp = dev_base; ifp; dev_put(ifp), ifp = ifp->next) { + for_each_netdev(ifp) { dev_hold(ifp); if (!is_aoe_netif(ifp)) - continue; + goto cont; skb = new_skb(sizeof *h + sizeof *ch); if (skb == NULL) { printk(KERN_INFO "aoe: skb alloc failure\n"); - continue; + goto cont; } skb_put(skb, sizeof *h + sizeof *ch); skb->dev = ifp; @@ -221,6 +221,8 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) skb->next = sl; sl = skb; +cont: + dev_put(ifp); } read_unlock(&dev_base_lock); diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index 2a299a0676a6..ef32a5c1e818 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c @@ -1971,8 +1971,7 @@ static struct net_device *get_strip_dev(struct strip *strip_info) sizeof(zero_address))) { struct net_device *dev; read_lock_bh(&dev_base_lock); - dev = dev_base; - while (dev) { + for_each_netdev(dev) { if (dev->type == strip_info->dev->type && !memcmp(dev->dev_addr, &strip_info->true_dev_addr, @@ -1983,7 +1982,6 @@ static struct net_device *get_strip_dev(struct strip *strip_info) read_unlock_bh(&dev_base_lock); return (dev); } - dev = dev->next; } read_unlock_bh(&dev_base_lock); } diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index 3df82fe9ce8c..98be2880757d 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c @@ -365,7 +365,7 @@ static __inline__ int led_get_net_activity(void) * for reading should be OK */ read_lock(&dev_base_lock); rcu_read_lock(); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { struct net_device_stats *stats; struct in_device *in_dev = __in_dev_get_rcu(dev); if (!in_dev || !in_dev->ifa_list) diff --git a/fs/afs/netdevices.c b/fs/afs/netdevices.c index ce08977858e0..fc27d4b52e5f 100644 --- a/fs/afs/netdevices.c +++ b/fs/afs/netdevices.c @@ -47,7 +47,7 @@ int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, ASSERT(maxbufs > 0); rtnl_lock(); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { if (dev->type == ARPHRD_LOOPBACK && !wantloopback) continue; idev = __in_dev_get_rtnl(dev); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 4428f1c3c13c..30446222b396 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -304,7 +304,7 @@ struct net_device unsigned long state; - struct net_device *next; + struct list_head dev_list; /* The device initialization function. Called only once. */ int (*init)(struct net_device *dev); @@ -575,9 +575,31 @@ struct packet_type { #include extern struct net_device loopback_dev; /* The loopback */ -extern struct net_device *dev_base; /* All devices */ +extern struct list_head dev_base_head; /* All devices */ extern rwlock_t dev_base_lock; /* Device list lock */ +#define for_each_netdev(d) \ + list_for_each_entry(d, &dev_base_head, dev_list) +#define for_each_netdev_safe(d, n) \ + list_for_each_entry_safe(d, n, &dev_base_head, dev_list) +#define for_each_netdev_continue(d) \ + list_for_each_entry_continue(d, &dev_base_head, dev_list) +#define net_device_entry(lh) list_entry(lh, struct net_device, dev_list) + +static inline struct net_device *next_net_device(struct net_device *dev) +{ + struct list_head *lh; + + lh = dev->dev_list.next; + return lh == &dev_base_head ? NULL : net_device_entry(lh); +} + +static inline struct net_device *first_net_device(void) +{ + return list_empty(&dev_base_head) ? NULL : + net_device_entry(dev_base_head.next); +} + extern int netdev_boot_setup_check(struct net_device *dev); extern unsigned long netdev_boot_base(const char *prefix, int unit); extern struct net_device *dev_getbyhwaddr(unsigned short type, char *hwaddr); diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index c0c7bb8e9f07..bd93c45778d4 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -117,8 +117,7 @@ static void __exit vlan_cleanup_devices(void) struct net_device *dev, *nxt; rtnl_lock(); - for (dev = dev_base; dev; dev = nxt) { - nxt = dev->next; + for_each_netdev_safe(dev, nxt) { if (dev->priv_flags & IFF_802_1Q_VLAN) { unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev, VLAN_DEV_INFO(dev)->vlan_id); diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index 5e24f72602a1..d216a64421cd 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c @@ -237,13 +237,9 @@ int vlan_proc_rem_dev(struct net_device *vlandev) * The following few functions build the content of /proc/net/vlan/config */ -/* starting at dev, find a VLAN device */ -static struct net_device *vlan_skip(struct net_device *dev) +static inline int is_vlan_dev(struct net_device *dev) { - while (dev && !(dev->priv_flags & IFF_802_1Q_VLAN)) - dev = dev->next; - - return dev; + return dev->priv_flags & IFF_802_1Q_VLAN; } /* start read of /proc/net/vlan/config */ @@ -257,19 +253,35 @@ static void *vlan_seq_start(struct seq_file *seq, loff_t *pos) if (*pos == 0) return SEQ_START_TOKEN; - for (dev = vlan_skip(dev_base); dev && i < *pos; - dev = vlan_skip(dev->next), ++i); + for_each_netdev(dev) { + if (!is_vlan_dev(dev)) + continue; + + if (i++ == *pos) + return dev; + } - return (i == *pos) ? dev : NULL; + return NULL; } static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos) { + struct net_device *dev; + ++*pos; - return vlan_skip((v == SEQ_START_TOKEN) - ? dev_base - : ((struct net_device *)v)->next); + dev = (struct net_device *)v; + if (v == SEQ_START_TOKEN) + dev = net_device_entry(&dev_base_head); + + for_each_netdev_continue(dev) { + if (!is_vlan_dev(dev)) + continue; + + return dev; + } + + return NULL; } static void vlan_seq_stop(struct seq_file *seq, void *v) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 690573bbf012..849deaf14108 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -475,11 +475,9 @@ void __exit br_cleanup_bridges(void) struct net_device *dev, *nxt; rtnl_lock(); - for (dev = dev_base; dev; dev = nxt) { - nxt = dev->next; + for_each_netdev_safe(dev, nxt) if (dev->priv_flags & IFF_EBRIDGE) del_br(dev->priv); - } rtnl_unlock(); } diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index eda0fbfc923a..bb15e9e259b1 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -27,7 +27,9 @@ static int get_bridge_ifindices(int *indices, int num) struct net_device *dev; int i = 0; - for (dev = dev_base; dev && i < num; dev = dev->next) { + for_each_netdev(dev) { + if (i >= num) + break; if (dev->priv_flags & IFF_EBRIDGE) indices[i++] = dev->ifindex; } diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 35facc0c11c2..0fcf6f073064 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -109,7 +109,8 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) struct net_device *dev; int idx; - for (dev = dev_base, idx = 0; dev; dev = dev->next) { + idx = 0; + for_each_netdev(dev) { /* not a bridge port */ if (dev->br_port == NULL || idx < cb->args[0]) goto skip; diff --git a/net/core/dev.c b/net/core/dev.c index c305819b7266..f27d4ab181e6 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -156,13 +156,13 @@ static spinlock_t net_dma_event_lock; #endif /* - * The @dev_base list is protected by @dev_base_lock and the rtnl + * The @dev_base_head list is protected by @dev_base_lock and the rtnl * semaphore. * * Pure readers hold dev_base_lock for reading. * * Writers must hold the rtnl semaphore while they loop through the - * dev_base list, and hold dev_base_lock for writing when they do the + * dev_base_head list, and hold dev_base_lock for writing when they do the * actual updates. This allows pure readers to access the list even * while a writer is preparing to update it. * @@ -174,11 +174,10 @@ static spinlock_t net_dma_event_lock; * unregister_netdevice(), which must be called with the rtnl * semaphore held. */ -struct net_device *dev_base; -static struct net_device **dev_tail = &dev_base; +LIST_HEAD(dev_base_head); DEFINE_RWLOCK(dev_base_lock); -EXPORT_SYMBOL(dev_base); +EXPORT_SYMBOL(dev_base_head); EXPORT_SYMBOL(dev_base_lock); #define NETDEV_HASHBITS 8 @@ -567,11 +566,12 @@ struct net_device *dev_getbyhwaddr(unsigned short type, char *ha) ASSERT_RTNL(); - for (dev = dev_base; dev; dev = dev->next) + for_each_netdev(dev) if (dev->type == type && !memcmp(dev->dev_addr, ha, dev->addr_len)) - break; - return dev; + return dev; + + return NULL; } EXPORT_SYMBOL(dev_getbyhwaddr); @@ -581,11 +581,11 @@ struct net_device *__dev_getfirstbyhwtype(unsigned short type) struct net_device *dev; ASSERT_RTNL(); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) if (dev->type == type) - break; - } - return dev; + return dev; + + return NULL; } EXPORT_SYMBOL(__dev_getfirstbyhwtype); @@ -617,17 +617,19 @@ EXPORT_SYMBOL(dev_getfirstbyhwtype); struct net_device * dev_get_by_flags(unsigned short if_flags, unsigned short mask) { - struct net_device *dev; + struct net_device *dev, *ret; + ret = NULL; read_lock(&dev_base_lock); - for (dev = dev_base; dev != NULL; dev = dev->next) { + for_each_netdev(dev) { if (((dev->flags ^ if_flags) & mask) == 0) { dev_hold(dev); + ret = dev; break; } } read_unlock(&dev_base_lock); - return dev; + return ret; } /** @@ -693,7 +695,7 @@ int dev_alloc_name(struct net_device *dev, const char *name) if (!inuse) return -ENOMEM; - for (d = dev_base; d; d = d->next) { + for_each_netdev(d) { if (!sscanf(d->name, name, &i)) continue; if (i < 0 || i >= max_netdevices) @@ -975,7 +977,7 @@ int register_netdevice_notifier(struct notifier_block *nb) rtnl_lock(); err = raw_notifier_chain_register(&netdev_chain, nb); if (!err) { - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { nb->notifier_call(nb, NETDEV_REGISTER, dev); if (dev->flags & IFF_UP) @@ -2049,7 +2051,7 @@ static int dev_ifconf(char __user *arg) */ total = 0; - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { for (i = 0; i < NPROTO; i++) { if (gifconf_list[i]) { int done; @@ -2081,26 +2083,28 @@ static int dev_ifconf(char __user *arg) * This is invoked by the /proc filesystem handler to display a device * in detail. */ -static struct net_device *dev_get_idx(loff_t pos) +void *dev_seq_start(struct seq_file *seq, loff_t *pos) { + loff_t off; struct net_device *dev; - loff_t i; - for (i = 0, dev = dev_base; dev && i < pos; ++i, dev = dev->next); + read_lock(&dev_base_lock); + if (!*pos) + return SEQ_START_TOKEN; - return i == pos ? dev : NULL; -} + off = 1; + for_each_netdev(dev) + if (off++ == *pos) + return dev; -void *dev_seq_start(struct seq_file *seq, loff_t *pos) -{ - read_lock(&dev_base_lock); - return *pos ? dev_get_idx(*pos - 1) : SEQ_START_TOKEN; + return NULL; } void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) { ++*pos; - return v == SEQ_START_TOKEN ? dev_base : ((struct net_device *)v)->next; + return v == SEQ_START_TOKEN ? + first_net_device() : next_net_device((struct net_device *)v); } void dev_seq_stop(struct seq_file *seq, void *v) @@ -3082,11 +3086,9 @@ int register_netdevice(struct net_device *dev) set_bit(__LINK_STATE_PRESENT, &dev->state); - dev->next = NULL; dev_init_scheduler(dev); write_lock_bh(&dev_base_lock); - *dev_tail = dev; - dev_tail = &dev->next; + list_add_tail(&dev->dev_list, &dev_base_head); hlist_add_head(&dev->name_hlist, head); hlist_add_head(&dev->index_hlist, dev_index_hash(dev->ifindex)); dev_hold(dev); @@ -3360,8 +3362,6 @@ void synchronize_net(void) void unregister_netdevice(struct net_device *dev) { - struct net_device *d, **dp; - BUG_ON(dev_boot_phase); ASSERT_RTNL(); @@ -3381,19 +3381,11 @@ void unregister_netdevice(struct net_device *dev) dev_close(dev); /* And unlink it from device chain. */ - for (dp = &dev_base; (d = *dp) != NULL; dp = &d->next) { - if (d == dev) { - write_lock_bh(&dev_base_lock); - hlist_del(&dev->name_hlist); - hlist_del(&dev->index_hlist); - if (dev_tail == &dev->next) - dev_tail = dp; - *dp = d->next; - write_unlock_bh(&dev_base_lock); - break; - } - } - BUG_ON(!d); + write_lock_bh(&dev_base_lock); + list_del(&dev->dev_list); + hlist_del(&dev->name_hlist); + hlist_del(&dev->index_hlist); + write_unlock_bh(&dev_base_lock); dev->reg_state = NETREG_UNREGISTERING; diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index 7d57bf77f3a3..5a54053386c8 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c @@ -223,7 +223,7 @@ static void *dev_mc_seq_start(struct seq_file *seq, loff_t *pos) loff_t off = 0; read_lock(&dev_base_lock); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { if (off++ == *pos) return dev; } @@ -232,9 +232,8 @@ static void *dev_mc_seq_start(struct seq_file *seq, loff_t *pos) static void *dev_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos) { - struct net_device *dev = v; ++*pos; - return dev->next; + return next_net_device((struct net_device *)v); } static void dev_mc_seq_stop(struct seq_file *seq, void *v) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index cec111109155..8c971a2efe2a 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -539,13 +539,16 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) int s_idx = cb->args[0]; struct net_device *dev; - for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { + idx = 0; + for_each_netdev(dev) { if (idx < s_idx) - continue; + goto cont; if (rtnl_fill_ifinfo(skb, dev, NULL, 0, RTM_NEWLINK, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0) break; +cont: + idx++; } cb->args[0] = idx; diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index a205eaa87f52..9fbe87c93802 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -721,7 +721,7 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) struct sock *sk = sock->sk; struct dn_scp *scp = DN_SK(sk); struct sockaddr_dn *saddr = (struct sockaddr_dn *)uaddr; - struct net_device *dev; + struct net_device *dev, *ldev; int rv; if (addr_len != sizeof(struct sockaddr_dn)) @@ -746,14 +746,17 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if (!(saddr->sdn_flags & SDF_WILD)) { if (dn_ntohs(saddr->sdn_nodeaddrl)) { read_lock(&dev_base_lock); - for(dev = dev_base; dev; dev = dev->next) { + ldev = NULL; + for_each_netdev(dev) { if (!dev->dn_ptr) continue; - if (dn_dev_islocal(dev, dn_saddr2dn(saddr))) + if (dn_dev_islocal(dev, dn_saddr2dn(saddr))) { + ldev = dev; break; + } } read_unlock(&dev_base_lock); - if (dev == NULL) + if (ldev == NULL) return -EADDRNOTAVAIL; } } diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 5c2a9951b638..764a56a13e38 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -799,9 +799,10 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) skip_ndevs = cb->args[0]; skip_naddr = cb->args[1]; - for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) { + idx = 0; + for_each_netdev(dev) { if (idx < skip_ndevs) - continue; + goto cont; else if (idx > skip_ndevs) { /* Only skip over addresses for first dev dumped * in this iteration (idx == skip_ndevs) */ @@ -809,18 +810,20 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) } if ((dn_db = dev->dn_ptr) == NULL) - continue; + goto cont; for (ifa = dn_db->ifa_list, dn_idx = 0; ifa; ifa = ifa->ifa_next, dn_idx++) { if (dn_idx < skip_naddr) - continue; + goto cont; if (dn_nl_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, RTM_NEWADDR, NLM_F_MULTI) < 0) goto done; } +cont: + idx++; } done: cb->args[0] = idx; @@ -1296,7 +1299,7 @@ void dn_dev_devices_off(void) struct net_device *dev; rtnl_lock(); - for(dev = dev_base; dev; dev = dev->next) + for_each_netdev(dev) dn_dev_down(dev); rtnl_unlock(); @@ -1307,7 +1310,7 @@ void dn_dev_devices_on(void) struct net_device *dev; rtnl_lock(); - for(dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { if (dev->flags & IFF_UP) dn_dev_up(dev); } @@ -1325,62 +1328,56 @@ int unregister_dnaddr_notifier(struct notifier_block *nb) } #ifdef CONFIG_PROC_FS -static inline struct net_device *dn_dev_get_next(struct seq_file *seq, struct net_device *dev) +static inline int is_dn_dev(struct net_device *dev) { - do { - dev = dev->next; - } while(dev && !dev->dn_ptr); - - return dev; + return dev->dn_ptr != NULL; } -static struct net_device *dn_dev_get_idx(struct seq_file *seq, loff_t pos) +static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos) { + int i; struct net_device *dev; - dev = dev_base; - if (dev && !dev->dn_ptr) - dev = dn_dev_get_next(seq, dev); - if (pos) { - while(dev && (dev = dn_dev_get_next(seq, dev))) - --pos; - } - return dev; -} + read_lock(&dev_base_lock); -static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos) -{ - if (*pos) { - struct net_device *dev; - read_lock(&dev_base_lock); - dev = dn_dev_get_idx(seq, *pos - 1); - if (dev == NULL) - read_unlock(&dev_base_lock); - return dev; + if (*pos == 0) + return SEQ_START_TOKEN; + + i = 1; + for_each_netdev(dev) { + if (!is_dn_dev(dev)) + continue; + + if (i++ == *pos) + return dev; } - return SEQ_START_TOKEN; + + return NULL; } static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) { - struct net_device *dev = v; - loff_t one = 1; + struct net_device *dev; - if (v == SEQ_START_TOKEN) { - dev = dn_dev_seq_start(seq, &one); - } else { - dev = dn_dev_get_next(seq, dev); - if (dev == NULL) - read_unlock(&dev_base_lock); - } ++*pos; - return dev; + + dev = (struct net_device *)v; + if (v == SEQ_START_TOKEN) + dev = net_device_entry(&dev_base_head); + + for_each_netdev_continue(dev) { + if (!is_dn_dev(dev)) + continue; + + return dev; + } + + return NULL; } static void dn_dev_seq_stop(struct seq_file *seq, void *v) { - if (v && v != SEQ_START_TOKEN) - read_unlock(&dev_base_lock); + read_unlock(&dev_base_lock); } static char *dn_type2asc(char type) diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 310a86268d2b..d2bc19d47950 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c @@ -602,7 +602,7 @@ static void dn_fib_del_ifaddr(struct dn_ifaddr *ifa) /* Scan device list */ read_lock(&dev_base_lock); - for(dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { dn_db = dev->dn_ptr; if (dn_db == NULL) continue; diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 5d7337bcf0fe..a8bf106b7a61 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -886,7 +886,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old .iif = loopback_dev.ifindex, .oif = oldflp->oif }; struct dn_route *rt = NULL; - struct net_device *dev_out = NULL; + struct net_device *dev_out = NULL, *dev; struct neighbour *neigh = NULL; unsigned hash; unsigned flags = 0; @@ -925,15 +925,17 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old goto out; } read_lock(&dev_base_lock); - for(dev_out = dev_base; dev_out; dev_out = dev_out->next) { - if (!dev_out->dn_ptr) + for_each_netdev(dev) { + if (!dev->dn_ptr) continue; - if (!dn_dev_islocal(dev_out, oldflp->fld_src)) + if (!dn_dev_islocal(dev, oldflp->fld_src)) continue; - if ((dev_out->flags & IFF_LOOPBACK) && + if ((dev->flags & IFF_LOOPBACK) && oldflp->fld_dst && - !dn_dev_islocal(dev_out, oldflp->fld_dst)) + !dn_dev_islocal(dev, oldflp->fld_dst)) continue; + + dev_out = dev; break; } read_unlock(&dev_base_lock); diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 088888db8b3d..7f95e6e9beeb 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -910,7 +910,7 @@ no_in_dev: */ read_lock(&dev_base_lock); rcu_read_lock(); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { if ((in_dev = __in_dev_get_rcu(dev)) == NULL) continue; @@ -989,7 +989,7 @@ __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, read_lock(&dev_base_lock); rcu_read_lock(); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { if ((in_dev = __in_dev_get_rcu(dev))) { addr = confirm_addr_indev(in_dev, dst, local, scope); if (addr) @@ -1182,23 +1182,26 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) int s_ip_idx, s_idx = cb->args[0]; s_ip_idx = ip_idx = cb->args[1]; - for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) { + idx = 0; + for_each_netdev(dev) { if (idx < s_idx) - continue; + goto cont; if (idx > s_idx) s_ip_idx = 0; if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) - continue; + goto cont; for (ifa = in_dev->ifa_list, ip_idx = 0; ifa; ifa = ifa->ifa_next, ip_idx++) { if (ip_idx < s_ip_idx) - continue; + goto cont; if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, RTM_NEWADDR, NLM_F_MULTI) <= 0) goto done; } +cont: + idx++; } done: @@ -1243,7 +1246,7 @@ void inet_forward_change(void) ipv4_devconf_dflt.forwarding = on; read_lock(&dev_base_lock); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { struct in_device *in_dev; rcu_read_lock(); in_dev = __in_dev_get_rcu(dev); diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 2506021c2935..f4dd47453108 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -2288,9 +2288,8 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq) struct ip_mc_list *im = NULL; struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); - for (state->dev = dev_base, state->in_dev = NULL; - state->dev; - state->dev = state->dev->next) { + state->in_dev = NULL; + for_each_netdev(state->dev) { struct in_device *in_dev; in_dev = in_dev_get(state->dev); if (!in_dev) @@ -2316,7 +2315,7 @@ static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_li read_unlock(&state->in_dev->mc_list_lock); in_dev_put(state->in_dev); } - state->dev = state->dev->next; + state->dev = next_net_device(state->dev); if (!state->dev) { state->in_dev = NULL; break; @@ -2450,9 +2449,9 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq) struct ip_mc_list *im = NULL; struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq); - for (state->dev = dev_base, state->idev = NULL, state->im = NULL; - state->dev; - state->dev = state->dev->next) { + state->idev = NULL; + state->im = NULL; + for_each_netdev(state->dev) { struct in_device *idev; idev = in_dev_get(state->dev); if (unlikely(idev == NULL)) @@ -2488,7 +2487,7 @@ static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_l read_unlock(&state->idev->mc_list_lock); in_dev_put(state->idev); } - state->dev = state->dev->next; + state->dev = next_net_device(state->dev); if (!state->dev) { state->idev = NULL; goto out; diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 597c800b2fdc..342ca8d89458 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -192,7 +192,7 @@ static int __init ic_open_devs(void) if (dev_change_flags(&loopback_dev, loopback_dev.flags | IFF_UP) < 0) printk(KERN_ERR "IP-Config: Failed to open %s\n", loopback_dev.name); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { if (dev == &loopback_dev) continue; if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) : diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 3452433cbc96..d02685c6bc69 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -449,7 +449,7 @@ static void addrconf_forward_change(void) struct inet6_dev *idev; read_lock(&dev_base_lock); - for (dev=dev_base; dev; dev=dev->next) { + for_each_netdev(dev) { rcu_read_lock(); idev = __in6_dev_get(dev); if (idev) { @@ -911,7 +911,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, read_lock(&dev_base_lock); rcu_read_lock(); - for (dev = dev_base; dev; dev=dev->next) { + for_each_netdev(dev) { struct inet6_dev *idev; struct inet6_ifaddr *ifa; @@ -2064,7 +2064,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) return; } - for (dev = dev_base; dev != NULL; dev = dev->next) { + for_each_netdev(dev) { struct in_device * in_dev = __in_dev_get_rtnl(dev); if (in_dev && (dev->flags & IFF_UP)) { struct in_ifaddr * ifa; @@ -2225,7 +2225,7 @@ static void ip6_tnl_add_linklocal(struct inet6_dev *idev) return; } /* then try to inherit it from any device */ - for (link_dev = dev_base; link_dev; link_dev = link_dev->next) { + for_each_netdev(link_dev) { if (!ipv6_inherit_linklocal(idev, link_dev)) return; } @@ -3257,14 +3257,15 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, s_idx = cb->args[0]; s_ip_idx = ip_idx = cb->args[1]; - for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) { + idx = 0; + for_each_netdev(dev) { if (idx < s_idx) - continue; + goto cont; if (idx > s_idx) s_ip_idx = 0; ip_idx = 0; if ((idev = in6_dev_get(dev)) == NULL) - continue; + goto cont; read_lock_bh(&idev->lock); switch (type) { case UNICAST_ADDR: @@ -3311,6 +3312,8 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, } read_unlock_bh(&idev->lock); in6_dev_put(idev); +cont: + idx++; } done: if (err <= 0) { @@ -3575,16 +3578,19 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) struct inet6_dev *idev; read_lock(&dev_base_lock); - for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { + idx = 0; + for_each_netdev(dev) { if (idx < s_idx) - continue; + goto cont; if ((idev = in6_dev_get(dev)) == NULL) - continue; + goto cont; err = inet6_fill_ifinfo(skb, idev, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, RTM_NEWLINK, NLM_F_MULTI); in6_dev_put(idev); if (err <= 0) break; +cont: + idx++; } read_unlock(&dev_base_lock); cb->args[0] = idx; @@ -4247,7 +4253,7 @@ void __exit addrconf_cleanup(void) * clean dev list. */ - for (dev=dev_base; dev; dev=dev->next) { + for_each_netdev(dev) { if ((idev = __in6_dev_get(dev)) == NULL) continue; addrconf_ifdown(dev, 1); diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index 09117d63256f..9b81264eb78f 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c @@ -423,14 +423,18 @@ static int ipv6_chk_acast_dev(struct net_device *dev, struct in6_addr *addr) */ int ipv6_chk_acast_addr(struct net_device *dev, struct in6_addr *addr) { + int found = 0; + if (dev) return ipv6_chk_acast_dev(dev, addr); read_lock(&dev_base_lock); - for (dev=dev_base; dev; dev=dev->next) - if (ipv6_chk_acast_dev(dev, addr)) + for_each_netdev(dev) + if (ipv6_chk_acast_dev(dev, addr)) { + found = 1; break; + } read_unlock(&dev_base_lock); - return dev != 0; + return found; } @@ -447,9 +451,8 @@ static inline struct ifacaddr6 *ac6_get_first(struct seq_file *seq) struct ifacaddr6 *im = NULL; struct ac6_iter_state *state = ac6_seq_private(seq); - for (state->dev = dev_base, state->idev = NULL; - state->dev; - state->dev = state->dev->next) { + state->idev = NULL; + for_each_netdev(state->dev) { struct inet6_dev *idev; idev = in6_dev_get(state->dev); if (!idev) @@ -476,7 +479,7 @@ static struct ifacaddr6 *ac6_get_next(struct seq_file *seq, struct ifacaddr6 *im read_unlock_bh(&state->idev->lock); in6_dev_put(state->idev); } - state->dev = state->dev->next; + state->dev = next_net_device(state->dev); if (!state->dev) { state->idev = NULL; break; diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 6c2758951d60..3e308fb41b49 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -2331,9 +2331,8 @@ static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq) struct ifmcaddr6 *im = NULL; struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq); - for (state->dev = dev_base, state->idev = NULL; - state->dev; - state->dev = state->dev->next) { + state->idev = NULL; + for_each_netdev(state->dev) { struct inet6_dev *idev; idev = in6_dev_get(state->dev); if (!idev) @@ -2360,7 +2359,7 @@ static struct ifmcaddr6 *igmp6_mc_get_next(struct seq_file *seq, struct ifmcaddr read_unlock_bh(&state->idev->lock); in6_dev_put(state->idev); } - state->dev = state->dev->next; + state->dev = next_net_device(state->dev); if (!state->dev) { state->idev = NULL; break; @@ -2475,9 +2474,9 @@ static inline struct ip6_sf_list *igmp6_mcf_get_first(struct seq_file *seq) struct ifmcaddr6 *im = NULL; struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq); - for (state->dev = dev_base, state->idev = NULL, state->im = NULL; - state->dev; - state->dev = state->dev->next) { + state->idev = NULL; + state->im = NULL; + for_each_netdev(state->dev) { struct inet6_dev *idev; idev = in6_dev_get(state->dev); if (unlikely(idev == NULL)) @@ -2513,7 +2512,7 @@ static struct ip6_sf_list *igmp6_mcf_get_next(struct seq_file *seq, struct ip6_s read_unlock_bh(&state->idev->lock); in6_dev_put(state->idev); } - state->dev = state->dev->next; + state->dev = next_net_device(state->dev); if (!state->dev) { state->idev = NULL; goto out; diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c index d12413cff5bd..d4b13a031fd5 100644 --- a/net/llc/llc_core.c +++ b/net/llc/llc_core.c @@ -160,8 +160,14 @@ static struct packet_type llc_tr_packet_type = { static int __init llc_init(void) { - if (dev_base->next) - memcpy(llc_station_mac_sa, dev_base->next->dev_addr, ETH_ALEN); + struct net_device *dev; + + dev = first_net_device(); + if (dev != NULL) + dev = next_net_device(dev); + + if (dev != NULL) + memcpy(llc_station_mac_sa, dev->dev_addr, ETH_ALEN); else memset(llc_station_mac_sa, 0, ETH_ALEN); dev_add_pack(&llc_packet_type); diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c index 8e6bd4e9d82c..2f76e062609d 100644 --- a/net/netrom/nr_route.c +++ b/net/netrom/nr_route.c @@ -598,7 +598,7 @@ struct net_device *nr_dev_first(void) struct net_device *dev, *first = NULL; read_lock(&dev_base_lock); - for (dev = dev_base; dev != NULL; dev = dev->next) { + for_each_netdev(dev) { if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM) if (first == NULL || strncmp(dev->name, first->name, 3) < 0) first = dev; @@ -618,12 +618,13 @@ struct net_device *nr_dev_get(ax25_address *addr) struct net_device *dev; read_lock(&dev_base_lock); - for (dev = dev_base; dev != NULL; dev = dev->next) { + for_each_netdev(dev) { if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM && ax25cmp(addr, (ax25_address *)dev->dev_addr) == 0) { dev_hold(dev); goto out; } } + dev = NULL; out: read_unlock(&dev_base_lock); return dev; diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index 1f9aefd95a99..929a784a86d7 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c @@ -596,7 +596,7 @@ struct net_device *rose_dev_first(void) struct net_device *dev, *first = NULL; read_lock(&dev_base_lock); - for (dev = dev_base; dev != NULL; dev = dev->next) { + for_each_netdev(dev) { if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE) if (first == NULL || strncmp(dev->name, first->name, 3) < 0) first = dev; @@ -614,12 +614,13 @@ struct net_device *rose_dev_get(rose_address *addr) struct net_device *dev; read_lock(&dev_base_lock); - for (dev = dev_base; dev != NULL; dev = dev->next) { + for_each_netdev(dev) { if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) { dev_hold(dev); goto out; } } + dev = NULL; out: read_unlock(&dev_base_lock); return dev; @@ -630,10 +631,11 @@ static int rose_dev_exists(rose_address *addr) struct net_device *dev; read_lock(&dev_base_lock); - for (dev = dev_base; dev != NULL; dev = dev->next) { + for_each_netdev(dev) { if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) goto out; } + dev = NULL; out: read_unlock(&dev_base_lock); return dev != NULL; diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 8699e7006d80..bec600af03ca 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -894,9 +894,10 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb) s_idx = cb->args[0]; s_q_idx = q_idx = cb->args[1]; read_lock(&dev_base_lock); - for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { + idx = 0; + for_each_netdev(dev) { if (idx < s_idx) - continue; + goto cont; if (idx > s_idx) s_q_idx = 0; q_idx = 0; @@ -910,6 +911,8 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb) goto done; q_idx++; } +cont: + idx++; } done: diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index c361deb6cea9..d4afafc39138 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -170,7 +170,7 @@ static void sctp_get_local_addr_list(void) struct sctp_af *af; read_lock(&dev_base_lock); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { __list_for_each(pos, &sctp_address_families) { af = list_entry(pos, struct sctp_af, list); af->copy_addrlist(&sctp_local_addr_list, dev); diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index 67bb29b44d1b..0ee6ded18f3a 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c @@ -120,16 +120,18 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev, static int enable_bearer(struct tipc_bearer *tb_ptr) { - struct net_device *dev = dev_base; + struct net_device *dev, *pdev; struct eth_bearer *eb_ptr = ð_bearers[0]; struct eth_bearer *stop = ð_bearers[MAX_ETH_BEARERS]; char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; /* Find device with specified name */ - - while (dev && dev->name && strncmp(dev->name, driver_name, IFNAMSIZ)) { - dev = dev->next; - } + dev = NULL; + for_each_netdev(pdev) + if (!strncmp(dev->name, driver_name, IFNAMSIZ)) { + dev = pdev; + break; + } if (!dev) return -ENODEV; -- cgit v1.2.3-59-g8ed1b From 33464e3b57834e161add62b499492cf43e35e54c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 4 May 2007 18:47:46 +0200 Subject: [S390] get rid of kprobes notifier call chain. And here's a port of the powerpc patch to get rid of the notifier chain completely to s390. It's ontop of Martins patch as that one is in mainline already. Signed-off-by: Christoph Hellwig Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/kprobes.c | 3 +-- arch/s390/mm/fault.c | 40 +++++++++++++--------------------------- include/asm-s390/kdebug.h | 18 +++++++++++++++--- include/asm-s390/kprobes.h | 16 ++++------------ 4 files changed, 33 insertions(+), 44 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index 993f35381496..23c61f6d965b 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -516,7 +516,7 @@ out: return 1; } -static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) +int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) { struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); @@ -603,7 +603,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, ret = NOTIFY_STOP; break; case DIE_TRAP: - case DIE_PAGE_FAULT: /* kprobe_running() needs smp_processor_id() */ preempt_disable(); if (kprobe_running() && diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 2b76a879a7b5..91f705adc3f9 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -52,38 +52,24 @@ extern int sysctl_userprocess_debug; extern void die(const char *,struct pt_regs *,long); #ifdef CONFIG_KPROBES -static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); -int register_page_fault_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); -} - -int unregister_page_fault_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); -} - -static int __kprobes __notify_page_fault(struct pt_regs *regs, long err) -{ - struct die_args args = { .str = "page fault", - .trapnr = 14, - .signr = SIGSEGV }; - args.regs = regs; - args.err = err; - return atomic_notifier_call_chain(¬ify_page_fault_chain, - DIE_PAGE_FAULT, &args); -} - static inline int notify_page_fault(struct pt_regs *regs, long err) { - if (unlikely(kprobe_running())) - return __notify_page_fault(regs, err); - return NOTIFY_DONE; + int ret = 0; + + /* kprobe_running() needs smp_processor_id() */ + if (!user_mode(regs)) { + preempt_disable(); + if (kprobe_running() && kprobe_fault_handler(regs, 14)) + ret = 1; + preempt_enable(); + } + + return ret; } #else static inline int notify_page_fault(struct pt_regs *regs, long err) { - return NOTIFY_DONE; + return 0; } #endif @@ -319,7 +305,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int write) int space; int si_code; - if (notify_page_fault(regs, error_code) == NOTIFY_STOP) + if (notify_page_fault(regs, error_code)) return; tsk = current; diff --git a/include/asm-s390/kdebug.h b/include/asm-s390/kdebug.h index 1b50f89819a4..d2d7ad276148 100644 --- a/include/asm-s390/kdebug.h +++ b/include/asm-s390/kdebug.h @@ -22,8 +22,21 @@ struct die_args { */ extern int register_die_notifier(struct notifier_block *); extern int unregister_die_notifier(struct notifier_block *); -extern int register_page_fault_notifier(struct notifier_block *); -extern int unregister_page_fault_notifier(struct notifier_block *); + +/* + * These are only here because kprobes.c wants them to implement a + * blatant layering violation. Will hopefully go away soon once all + * architectures are updated. + */ +static inline int register_page_fault_notifier(struct notifier_block *nb) +{ + return 0; +} +static inline int unregister_page_fault_notifier(struct notifier_block *nb) +{ + return 0; +} + extern struct atomic_notifier_head s390die_chain; enum die_val { @@ -39,7 +52,6 @@ enum die_val { DIE_GPF, DIE_CALL, DIE_NMI_IPI, - DIE_PAGE_FAULT, }; static inline int notify_die(enum die_val val, const char *str, diff --git a/include/asm-s390/kprobes.h b/include/asm-s390/kprobes.h index b847ff0ec3fa..830fe4c4eea6 100644 --- a/include/asm-s390/kprobes.h +++ b/include/asm-s390/kprobes.h @@ -97,18 +97,10 @@ void kretprobe_trampoline(void); int is_prohibited_opcode(kprobe_opcode_t *instruction); void get_instruction_type(struct arch_specific_insn *ainsn); +int kprobe_fault_handler(struct pt_regs *regs, int trapnr); +int kprobe_exceptions_notify(struct notifier_block *self, + unsigned long val, void *data); + #define flush_insn_slot(p) do { } while (0) #endif /* _ASM_S390_KPROBES_H */ - -#ifdef CONFIG_KPROBES - -extern int kprobe_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data); -#else /* !CONFIG_KPROBES */ -static inline int kprobe_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data) -{ - return 0; -} -#endif -- cgit v1.2.3-59-g8ed1b From f67d1369665b2ce88227c40d9c9a6c8ba16bb866 Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Fri, 4 May 2007 18:47:47 +0200 Subject: [S390] aes-s390 key length. Register aes-s390 algorithms with the actual supported max keylen size Signed-off-by: Jan Glauber Signed-off-by: Martin Schwidefsky --- arch/s390/crypto/aes_s390.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 91636353f6f0..3660ca6a3306 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c @@ -119,7 +119,8 @@ static struct crypto_alg aes_alg = { .cra_name = "aes", .cra_driver_name = "aes-s390", .cra_priority = CRYPT_S390_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | + CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct s390_aes_ctx), .cra_module = THIS_MODULE, @@ -206,7 +207,8 @@ static struct crypto_alg ecb_aes_alg = { .cra_name = "ecb(aes)", .cra_driver_name = "ecb-aes-s390", .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | + CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct s390_aes_ctx), .cra_type = &crypto_blkcipher_type, @@ -300,7 +302,8 @@ static struct crypto_alg cbc_aes_alg = { .cra_name = "cbc(aes)", .cra_driver_name = "cbc-aes-s390", .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | + CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct s390_aes_ctx), .cra_type = &crypto_blkcipher_type, @@ -333,10 +336,14 @@ static int __init aes_init(void) return -EOPNOTSUPP; /* z9 109 and z9 BC/EC only support 128 bit key length */ - if (keylen_flag == AES_KEYLEN_128) + if (keylen_flag == AES_KEYLEN_128) { + aes_alg.cra_u.cipher.cia_max_keysize = AES_MIN_KEY_SIZE; + ecb_aes_alg.cra_u.blkcipher.max_keysize = AES_MIN_KEY_SIZE; + cbc_aes_alg.cra_u.blkcipher.max_keysize = AES_MIN_KEY_SIZE; printk(KERN_INFO "aes_s390: hardware acceleration only available for" "128 bit keys\n"); + } ret = crypto_register_alg(&aes_alg); if (ret) -- cgit v1.2.3-59-g8ed1b From d4ee453bcfcc0ce76de8522e099868dc440cba23 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 4 May 2007 18:47:48 +0200 Subject: [S390] Export uaccess as non-gpl symbol. Commit c1821c2e9711adc3cd298a16b7237c92a2cee78d introduced the uaccess structure that is used to select the correct set of user copy functions for the different execution modes (standard vs. noexec vs. z9 optimized user copy). The uaccess symbol is exported with EXPORT_SYMBOL_GPL. This breaks all non-gpl modules that use user copy. To make them work again change the export to EXPORT_SYMBOL. Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 3dfd0985861c..82b7fe32d86c 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -65,7 +65,7 @@ long psw_user_bits = (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | * User copy operations. */ struct uaccess_ops uaccess; -EXPORT_SYMBOL_GPL(uaccess); +EXPORT_SYMBOL(uaccess); /* * Machine setup.. -- cgit v1.2.3-59-g8ed1b From cf8ba7a95511b86608acb481ad96219fe2da4b3a Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 4 May 2007 18:48:28 +0200 Subject: [S390] add hardware capability support (ELF_HWCAP). Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/setup.c | 109 +++++++++++++++++++++++++++++++++++++++++++++ include/asm-s390/elf.h | 7 ++- include/asm-s390/lowcore.h | 10 +++-- 3 files changed, 120 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 82b7fe32d86c..6bfb0889eb10 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -74,6 +74,8 @@ unsigned int console_mode = 0; unsigned int console_devno = -1; unsigned int console_irq = -1; unsigned long machine_flags = 0; +unsigned long elf_hwcap = 0; +char elf_platform[ELF_PLATFORM_SIZE]; struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS]; volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ @@ -749,6 +751,98 @@ setup_memory(void) #endif } +static __init unsigned int stfl(void) +{ + asm volatile( + " .insn s,0xb2b10000,0(0)\n" /* stfl */ + "0:\n" + EX_TABLE(0b,0b)); + return S390_lowcore.stfl_fac_list; +} + +static __init int stfle(unsigned long long *list, int doublewords) +{ + typedef struct { unsigned long long _[doublewords]; } addrtype; + register unsigned long __nr asm("0") = doublewords - 1; + + asm volatile(".insn s,0xb2b00000,%0" /* stfle */ + : "=m" (*(addrtype *) list), "+d" (__nr) : : "cc"); + return __nr + 1; +} + +/* + * Setup hardware capabilities. + */ +static void __init setup_hwcaps(void) +{ + static const int stfl_bits[6] = { 0, 2, 7, 17, 19, 21 }; + struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data; + unsigned long long facility_list_extended; + unsigned int facility_list; + int i; + + facility_list = stfl(); + /* + * The store facility list bits numbers as found in the principles + * of operation are numbered with bit 1UL<<31 as number 0 to + * bit 1UL<<0 as number 31. + * Bit 0: instructions named N3, "backported" to esa-mode + * Bit 2: z/Architecture mode is active + * Bit 7: the store-facility-list-extended facility is installed + * Bit 17: the message-security assist is installed + * Bit 19: the long-displacement facility is installed + * Bit 21: the extended-immediate facility is installed + * These get translated to: + * HWCAP_S390_ESAN3 bit 0, HWCAP_S390_ZARCH bit 1, + * HWCAP_S390_STFLE bit 2, HWCAP_S390_MSA bit 3, + * HWCAP_S390_LDISP bit 4, and HWCAP_S390_EIMM bit 5. + */ + for (i = 0; i < 6; i++) + if (facility_list & (1UL << (31 - stfl_bits[i]))) + elf_hwcap |= 1UL << i; + + /* + * Check for additional facilities with store-facility-list-extended. + * stfle stores doublewords (8 byte) with bit 1ULL<<63 as bit 0 + * and 1ULL<<0 as bit 63. Bits 0-31 contain the same information + * as stored by stfl, bits 32-xxx contain additional facilities. + * How many facility words are stored depends on the number of + * doublewords passed to the instruction. The additional facilites + * are: + * Bit 43: decimal floating point facility is installed + * translated to: + * HWCAP_S390_DFP bit 6. + */ + if ((elf_hwcap & (1UL << 2)) && + stfle(&facility_list_extended, 1) > 0) { + if (facility_list_extended & (1ULL << (64 - 43))) + elf_hwcap |= 1UL << 6; + } + + switch (cpuinfo->cpu_id.machine) { + case 0x9672: +#if !defined(CONFIG_64BIT) + default: /* Use "g5" as default for 31 bit kernels. */ +#endif + strcpy(elf_platform, "g5"); + break; + case 0x2064: + case 0x2066: +#if defined(CONFIG_64BIT) + default: /* Use "z900" as default for 64 bit kernels. */ +#endif + strcpy(elf_platform, "z900"); + break; + case 0x2084: + case 0x2086: + strcpy(elf_platform, "z990"); + break; + case 0x2094: + strcpy(elf_platform, "z9-109"); + break; + } +} + /* * Setup function called from init/main.c just after the banner * was printed. @@ -804,6 +898,11 @@ setup_arch(char **cmdline_p) __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; smp_setup_cpu_possible_map(); + /* + * Setup capabilities (ELF_HWCAP & ELF_PLATFORM). + */ + setup_hwcaps(); + /* * Create kernel page tables and switch to virtual addressing. */ @@ -839,8 +938,12 @@ void print_cpu_info(struct cpuinfo_S390 *cpuinfo) static int show_cpuinfo(struct seq_file *m, void *v) { + static const char *hwcap_str[7] = { + "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp" + }; struct cpuinfo_S390 *cpuinfo; unsigned long n = (unsigned long) v - 1; + int i; s390_adjust_jiffies(); preempt_disable(); @@ -850,7 +953,13 @@ static int show_cpuinfo(struct seq_file *m, void *v) "bogomips per cpu: %lu.%02lu\n", num_online_cpus(), loops_per_jiffy/(500000/HZ), (loops_per_jiffy/(5000/HZ))%100); + seq_puts(m, "features\t: "); + for (i = 0; i < 7; i++) + if (hwcap_str[i] && (elf_hwcap & (1UL << i))) + seq_printf(m, "%s ", hwcap_str[i]); + seq_puts(m, "\n"); } + if (cpu_online(n)) { #ifdef CONFIG_SMP if (smp_processor_id() == n) diff --git a/include/asm-s390/elf.h b/include/asm-s390/elf.h index c0d629d61d3e..91d06325cc79 100644 --- a/include/asm-s390/elf.h +++ b/include/asm-s390/elf.h @@ -188,7 +188,8 @@ static inline int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs) /* This yields a mask that user programs can use to figure out what instruction set this CPU supports. */ -#define ELF_HWCAP (0) +extern unsigned long elf_hwcap; +#define ELF_HWCAP (elf_hwcap) /* This yields a string that ld.so will use to load implementation specific libraries for optimization. This is more specific in @@ -197,7 +198,9 @@ static inline int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs) For the moment, we have only optimizations for the Intel generations, but that could change... */ -#define ELF_PLATFORM (NULL) +#define ELF_PLATFORM_SIZE 8 +extern char elf_platform[]; +#define ELF_PLATFORM (elf_platform) #ifndef __s390x__ #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h index ffc9788a21a7..801a6fd35b5b 100644 --- a/include/asm-s390/lowcore.h +++ b/include/asm-s390/lowcore.h @@ -229,17 +229,19 @@ struct _lowcore __u16 subchannel_nr; /* 0x0ba */ __u32 io_int_parm; /* 0x0bc */ __u32 io_int_word; /* 0x0c0 */ - __u8 pad3[0xD4-0xC4]; /* 0x0c4 */ + __u8 pad3[0xc8-0xc4]; /* 0x0c4 */ + __u32 stfl_fac_list; /* 0x0c8 */ + __u8 pad4[0xd4-0xcc]; /* 0x0cc */ __u32 extended_save_area_addr; /* 0x0d4 */ __u32 cpu_timer_save_area[2]; /* 0x0d8 */ __u32 clock_comp_save_area[2]; /* 0x0e0 */ __u32 mcck_interruption_code[2]; /* 0x0e8 */ - __u8 pad4[0xf4-0xf0]; /* 0x0f0 */ + __u8 pad5[0xf4-0xf0]; /* 0x0f0 */ __u32 external_damage_code; /* 0x0f4 */ __u32 failing_storage_address; /* 0x0f8 */ - __u8 pad5[0x100-0xfc]; /* 0x0fc */ + __u8 pad6[0x100-0xfc]; /* 0x0fc */ __u32 st_status_fixed_logout[4];/* 0x100 */ - __u8 pad6[0x120-0x110]; /* 0x110 */ + __u8 pad7[0x120-0x110]; /* 0x110 */ __u32 access_regs_save_area[16];/* 0x120 */ __u32 floating_pt_save_area[8]; /* 0x160 */ __u32 gpregs_save_area[16]; /* 0x180 */ -- cgit v1.2.3-59-g8ed1b From c04cb856e20a8bf68762d60737b84328c1ab5900 Mon Sep 17 00:00:00 2001 From: Michael Schmitz Date: Tue, 1 May 2007 22:32:38 +0200 Subject: m68k: Atari keyboard and mouse support. Atari keyboard and mouse support. (reformating and Kconfig fixes by Roman Zippel) Signed-off-by: Michael Schmitz Signed-off-by: Roman Zippel Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/Kconfig | 3 + arch/m68k/atari/Makefile | 1 + arch/m68k/atari/atakeyb.c | 730 +++++++++++++++++++++++++++++++++++++++ drivers/input/keyboard/Kconfig | 11 + drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/atakbd.c | 134 +++++++ drivers/input/mouse/Kconfig | 11 + drivers/input/mouse/Makefile | 1 + drivers/input/mouse/atarimouse.c | 160 +++++++++ include/asm-m68k/atarikb.h | 6 + include/linux/input.h | 1 + 11 files changed, 1059 insertions(+) create mode 100644 arch/m68k/atari/atakeyb.c create mode 100644 drivers/input/keyboard/atakbd.c create mode 100644 drivers/input/mouse/atarimouse.c (limited to 'arch') diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index a8e1e604dfa8..b8536c7c0877 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -409,6 +409,9 @@ config STRAM_PROC help Say Y here to report ST-RAM usage statistics in /proc/stram. +config ATARI_KBD_CORE + bool + config HEARTBEAT bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40 default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300 diff --git a/arch/m68k/atari/Makefile b/arch/m68k/atari/Makefile index 8cb6236b39db..2cb86191f0aa 100644 --- a/arch/m68k/atari/Makefile +++ b/arch/m68k/atari/Makefile @@ -8,3 +8,4 @@ obj-y := config.o time.o debug.o ataints.o stdma.o \ ifeq ($(CONFIG_PCI),y) obj-$(CONFIG_HADES) += hades-pci.o endif +obj-$(CONFIG_ATARI_KBD_CORE) += atakeyb.o diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c new file mode 100644 index 000000000000..1c29603b16b3 --- /dev/null +++ b/arch/m68k/atari/atakeyb.c @@ -0,0 +1,730 @@ +/* + * linux/atari/atakeyb.c + * + * Atari Keyboard driver for 680x0 Linux + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +/* + * Atari support by Robert de Vries + * enhanced by Bjoern Brauel and Roman Hodek + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static void atakeyb_rep(unsigned long ignore); +extern unsigned int keymap_count; + +/* Hook for MIDI serial driver */ +void (*atari_MIDI_interrupt_hook) (void); +/* Hook for mouse driver */ +void (*atari_mouse_interrupt_hook) (char *); +/* Hook for keyboard inputdev driver */ +void (*atari_input_keyboard_interrupt_hook) (unsigned char, char); +/* Hook for mouse inputdev driver */ +void (*atari_input_mouse_interrupt_hook) (char *); + +/* variables for IKBD self test: */ + +/* state: 0: off; >0: in progress; >1: 0xf1 received */ +static volatile int ikbd_self_test; +/* timestamp when last received a char */ +static volatile unsigned long self_test_last_rcv; +/* bitmap of keys reported as broken */ +static unsigned long broken_keys[128/(sizeof(unsigned long)*8)] = { 0, }; + +#define BREAK_MASK (0x80) + +/* + * ++roman: The following changes were applied manually: + * + * - The Alt (= Meta) key works in combination with Shift and + * Control, e.g. Alt+Shift+a sends Meta-A (0xc1), Alt+Control+A sends + * Meta-Ctrl-A (0x81) ... + * + * - The parentheses on the keypad send '(' and ')' with all + * modifiers (as would do e.g. keypad '+'), but they cannot be used as + * application keys (i.e. sending Esc O c). + * + * - HELP and UNDO are mapped to be F21 and F24, resp, that send the + * codes "\E[M" and "\E[P". (This is better than the old mapping to + * F11 and F12, because these codes are on Shift+F1/2 anyway.) This + * way, applications that allow their own keyboard mappings + * (e.g. tcsh, X Windows) can be configured to use them in the way + * the label suggests (providing help or undoing). + * + * - Console switching is done with Alt+Fx (consoles 1..10) and + * Shift+Alt+Fx (consoles 11..20). + * + * - The misc. special function implemented in the kernel are mapped + * to the following key combinations: + * + * ClrHome -> Home/Find + * Shift + ClrHome -> End/Select + * Shift + Up -> Page Up + * Shift + Down -> Page Down + * Alt + Help -> show system status + * Shift + Help -> show memory info + * Ctrl + Help -> show registers + * Ctrl + Alt + Del -> Reboot + * Alt + Undo -> switch to last console + * Shift + Undo -> send interrupt + * Alt + Insert -> stop/start output (same as ^S/^Q) + * Alt + Up -> Scroll back console (if implemented) + * Alt + Down -> Scroll forward console (if implemented) + * Alt + CapsLock -> NumLock + * + * ++Andreas: + * + * - Help mapped to K_HELP + * - Undo mapped to K_UNDO (= K_F246) + * - Keypad Left/Right Parenthesis mapped to new K_PPAREN[LR] + */ + +static u_short ataplain_map[NR_KEYS] __initdata = { + 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf008, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf200, + 0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf200, 0xf200, 0xf114, + 0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200, + 0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf1ff, 0xf11b, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307, + 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303, + 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200 +}; + +typedef enum kb_state_t { + KEYBOARD, AMOUSE, RMOUSE, JOYSTICK, CLOCK, RESYNC +} KB_STATE_T; + +#define IS_SYNC_CODE(sc) ((sc) >= 0x04 && (sc) <= 0xfb) + +typedef struct keyboard_state { + unsigned char buf[6]; + int len; + KB_STATE_T state; +} KEYBOARD_STATE; + +KEYBOARD_STATE kb_state; + +#define DEFAULT_KEYB_REP_DELAY (HZ/4) +#define DEFAULT_KEYB_REP_RATE (HZ/25) + +/* These could be settable by some ioctl() in future... */ +static unsigned int key_repeat_delay = DEFAULT_KEYB_REP_DELAY; +static unsigned int key_repeat_rate = DEFAULT_KEYB_REP_RATE; + +static unsigned char rep_scancode; +static struct timer_list atakeyb_rep_timer = { + .function = atakeyb_rep, +}; + +static void atakeyb_rep(unsigned long ignore) +{ + /* Disable keyboard for the time we call handle_scancode(), else a race + * in the keyboard tty queue may happen */ + atari_disable_irq(IRQ_MFP_ACIA); + del_timer(&atakeyb_rep_timer); + + /* A keyboard int may have come in before we disabled the irq, so + * double-check whether rep_scancode is still != 0 */ + if (rep_scancode) { + init_timer(&atakeyb_rep_timer); + atakeyb_rep_timer.expires = jiffies + key_repeat_rate; + add_timer(&atakeyb_rep_timer); + + //handle_scancode(rep_scancode, 1); + if (atari_input_keyboard_interrupt_hook) + atari_input_keyboard_interrupt_hook(rep_scancode, 1); + } + + atari_enable_irq(IRQ_MFP_ACIA); +} + + +/* ++roman: If a keyboard overrun happened, we can't tell in general how much + * bytes have been lost and in which state of the packet structure we are now. + * This usually causes keyboards bytes to be interpreted as mouse movements + * and vice versa, which is very annoying. It seems better to throw away some + * bytes (that are usually mouse bytes) than to misinterpret them. Therefor I + * introduced the RESYNC state for IKBD data. In this state, the bytes up to + * one that really looks like a key event (0x04..0xf2) or the start of a mouse + * packet (0xf8..0xfb) are thrown away, but at most 2 bytes. This at least + * speeds up the resynchronization of the event structure, even if maybe a + * mouse movement is lost. However, nothing is perfect. For bytes 0x01..0x03, + * it's really hard to decide whether they're mouse or keyboard bytes. Since + * overruns usually occur when moving the Atari mouse rapidly, they're seen as + * mouse bytes here. If this is wrong, only a make code of the keyboard gets + * lost, which isn't too bad. Loosing a break code would be disastrous, + * because then the keyboard repeat strikes... + */ + +static irqreturn_t atari_keyboard_interrupt(int irq, void *dummy) +{ + u_char acia_stat; + int scancode; + int break_flag; + +repeat: + if (acia.mid_ctrl & ACIA_IRQ) + if (atari_MIDI_interrupt_hook) + atari_MIDI_interrupt_hook(); + acia_stat = acia.key_ctrl; + /* check out if the interrupt came from this ACIA */ + if (!((acia_stat | acia.mid_ctrl) & ACIA_IRQ)) + return IRQ_HANDLED; + + if (acia_stat & ACIA_OVRN) { + /* a very fast typist or a slow system, give a warning */ + /* ...happens often if interrupts were disabled for too long */ + printk(KERN_DEBUG "Keyboard overrun\n"); + scancode = acia.key_data; + /* Turn off autorepeating in case a break code has been lost */ + del_timer(&atakeyb_rep_timer); + rep_scancode = 0; + if (ikbd_self_test) + /* During self test, don't do resyncing, just process the code */ + goto interpret_scancode; + else if (IS_SYNC_CODE(scancode)) { + /* This code seem already to be the start of a new packet or a + * single scancode */ + kb_state.state = KEYBOARD; + goto interpret_scancode; + } else { + /* Go to RESYNC state and skip this byte */ + kb_state.state = RESYNC; + kb_state.len = 1; /* skip max. 1 another byte */ + goto repeat; + } + } + + if (acia_stat & ACIA_RDRF) { + /* received a character */ + scancode = acia.key_data; /* get it or reset the ACIA, I'll get it! */ + tasklet_schedule(&keyboard_tasklet); + interpret_scancode: + switch (kb_state.state) { + case KEYBOARD: + switch (scancode) { + case 0xF7: + kb_state.state = AMOUSE; + kb_state.len = 0; + break; + + case 0xF8: + case 0xF9: + case 0xFA: + case 0xFB: + kb_state.state = RMOUSE; + kb_state.len = 1; + kb_state.buf[0] = scancode; + break; + + case 0xFC: + kb_state.state = CLOCK; + kb_state.len = 0; + break; + + case 0xFE: + case 0xFF: + kb_state.state = JOYSTICK; + kb_state.len = 1; + kb_state.buf[0] = scancode; + break; + + case 0xF1: + /* during self-test, note that 0xf1 received */ + if (ikbd_self_test) { + ++ikbd_self_test; + self_test_last_rcv = jiffies; + break; + } + /* FALL THROUGH */ + + default: + break_flag = scancode & BREAK_MASK; + scancode &= ~BREAK_MASK; + if (ikbd_self_test) { + /* Scancodes sent during the self-test stand for broken + * keys (keys being down). The code *should* be a break + * code, but nevertheless some AT keyboard interfaces send + * make codes instead. Therefore, simply ignore + * break_flag... + */ + int keyval = plain_map[scancode], keytyp; + + set_bit(scancode, broken_keys); + self_test_last_rcv = jiffies; + keyval = plain_map[scancode]; + keytyp = KTYP(keyval) - 0xf0; + keyval = KVAL(keyval); + + printk(KERN_WARNING "Key with scancode %d ", scancode); + if (keytyp == KT_LATIN || keytyp == KT_LETTER) { + if (keyval < ' ') + printk("('^%c') ", keyval + '@'); + else + printk("('%c') ", keyval); + } + printk("is broken -- will be ignored.\n"); + break; + } else if (test_bit(scancode, broken_keys)) + break; + +#if 0 // FIXME; hangs at boot + if (break_flag) { + del_timer(&atakeyb_rep_timer); + rep_scancode = 0; + } else { + del_timer(&atakeyb_rep_timer); + rep_scancode = scancode; + atakeyb_rep_timer.expires = jiffies + key_repeat_delay; + add_timer(&atakeyb_rep_timer); + } +#endif + + // handle_scancode(scancode, !break_flag); + if (atari_input_keyboard_interrupt_hook) + atari_input_keyboard_interrupt_hook((unsigned char)scancode, !break_flag); + break; + } + break; + + case AMOUSE: + kb_state.buf[kb_state.len++] = scancode; + if (kb_state.len == 5) { + kb_state.state = KEYBOARD; + /* not yet used */ + /* wake up someone waiting for this */ + } + break; + + case RMOUSE: + kb_state.buf[kb_state.len++] = scancode; + if (kb_state.len == 3) { + kb_state.state = KEYBOARD; + if (atari_mouse_interrupt_hook) + atari_mouse_interrupt_hook(kb_state.buf); + } + break; + + case JOYSTICK: + kb_state.buf[1] = scancode; + kb_state.state = KEYBOARD; +#ifdef FIXED_ATARI_JOYSTICK + atari_joystick_interrupt(kb_state.buf); +#endif + break; + + case CLOCK: + kb_state.buf[kb_state.len++] = scancode; + if (kb_state.len == 6) { + kb_state.state = KEYBOARD; + /* wake up someone waiting for this. + But will this ever be used, as Linux keeps its own time. + Perhaps for synchronization purposes? */ + /* wake_up_interruptible(&clock_wait); */ + } + break; + + case RESYNC: + if (kb_state.len <= 0 || IS_SYNC_CODE(scancode)) { + kb_state.state = KEYBOARD; + goto interpret_scancode; + } + kb_state.len--; + break; + } + } + +#if 0 + if (acia_stat & ACIA_CTS) + /* cannot happen */; +#endif + + if (acia_stat & (ACIA_FE | ACIA_PE)) { + printk("Error in keyboard communication\n"); + } + + /* handle_scancode() can take a lot of time, so check again if + * some character arrived + */ + goto repeat; +} + +/* + * I write to the keyboard without using interrupts, I poll instead. + * This takes for the maximum length string allowed (7) at 7812.5 baud + * 8 data 1 start 1 stop bit: 9.0 ms + * If this takes too long for normal operation, interrupt driven writing + * is the solution. (I made a feeble attempt in that direction but I + * kept it simple for now.) + */ +void ikbd_write(const char *str, int len) +{ + u_char acia_stat; + + if ((len < 1) || (len > 7)) + panic("ikbd: maximum string length exceeded"); + while (len) { + acia_stat = acia.key_ctrl; + if (acia_stat & ACIA_TDRE) { + acia.key_data = *str++; + len--; + } + } +} + +/* Reset (without touching the clock) */ +void ikbd_reset(void) +{ + static const char cmd[2] = { 0x80, 0x01 }; + + ikbd_write(cmd, 2); + + /* + * if all's well code 0xF1 is returned, else the break codes of + * all keys making contact + */ +} + +/* Set mouse button action */ +void ikbd_mouse_button_action(int mode) +{ + char cmd[2] = { 0x07, mode }; + + ikbd_write(cmd, 2); +} + +/* Set relative mouse position reporting */ +void ikbd_mouse_rel_pos(void) +{ + static const char cmd[1] = { 0x08 }; + + ikbd_write(cmd, 1); +} + +/* Set absolute mouse position reporting */ +void ikbd_mouse_abs_pos(int xmax, int ymax) +{ + char cmd[5] = { 0x09, xmax>>8, xmax&0xFF, ymax>>8, ymax&0xFF }; + + ikbd_write(cmd, 5); +} + +/* Set mouse keycode mode */ +void ikbd_mouse_kbd_mode(int dx, int dy) +{ + char cmd[3] = { 0x0A, dx, dy }; + + ikbd_write(cmd, 3); +} + +/* Set mouse threshold */ +void ikbd_mouse_thresh(int x, int y) +{ + char cmd[3] = { 0x0B, x, y }; + + ikbd_write(cmd, 3); +} + +/* Set mouse scale */ +void ikbd_mouse_scale(int x, int y) +{ + char cmd[3] = { 0x0C, x, y }; + + ikbd_write(cmd, 3); +} + +/* Interrogate mouse position */ +void ikbd_mouse_pos_get(int *x, int *y) +{ + static const char cmd[1] = { 0x0D }; + + ikbd_write(cmd, 1); + + /* wait for returning bytes */ +} + +/* Load mouse position */ +void ikbd_mouse_pos_set(int x, int y) +{ + char cmd[6] = { 0x0E, 0x00, x>>8, x&0xFF, y>>8, y&0xFF }; + + ikbd_write(cmd, 6); +} + +/* Set Y=0 at bottom */ +void ikbd_mouse_y0_bot(void) +{ + static const char cmd[1] = { 0x0F }; + + ikbd_write(cmd, 1); +} + +/* Set Y=0 at top */ +void ikbd_mouse_y0_top(void) +{ + static const char cmd[1] = { 0x10 }; + + ikbd_write(cmd, 1); +} + +/* Resume */ +void ikbd_resume(void) +{ + static const char cmd[1] = { 0x11 }; + + ikbd_write(cmd, 1); +} + +/* Disable mouse */ +void ikbd_mouse_disable(void) +{ + static const char cmd[1] = { 0x12 }; + + ikbd_write(cmd, 1); +} + +/* Pause output */ +void ikbd_pause(void) +{ + static const char cmd[1] = { 0x13 }; + + ikbd_write(cmd, 1); +} + +/* Set joystick event reporting */ +void ikbd_joystick_event_on(void) +{ + static const char cmd[1] = { 0x14 }; + + ikbd_write(cmd, 1); +} + +/* Set joystick interrogation mode */ +void ikbd_joystick_event_off(void) +{ + static const char cmd[1] = { 0x15 }; + + ikbd_write(cmd, 1); +} + +/* Joystick interrogation */ +void ikbd_joystick_get_state(void) +{ + static const char cmd[1] = { 0x16 }; + + ikbd_write(cmd, 1); +} + +#if 0 +/* This disables all other ikbd activities !!!! */ +/* Set joystick monitoring */ +void ikbd_joystick_monitor(int rate) +{ + static const char cmd[2] = { 0x17, rate }; + + ikbd_write(cmd, 2); + + kb_state.state = JOYSTICK_MONITOR; +} +#endif + +/* some joystick routines not in yet (0x18-0x19) */ + +/* Disable joysticks */ +void ikbd_joystick_disable(void) +{ + static const char cmd[1] = { 0x1A }; + + ikbd_write(cmd, 1); +} + +/* Time-of-day clock set */ +void ikbd_clock_set(int year, int month, int day, int hour, int minute, int second) +{ + char cmd[7] = { 0x1B, year, month, day, hour, minute, second }; + + ikbd_write(cmd, 7); +} + +/* Interrogate time-of-day clock */ +void ikbd_clock_get(int *year, int *month, int *day, int *hour, int *minute, int second) +{ + static const char cmd[1] = { 0x1C }; + + ikbd_write(cmd, 1); +} + +/* Memory load */ +void ikbd_mem_write(int address, int size, char *data) +{ + panic("Attempt to write data into keyboard memory"); +} + +/* Memory read */ +void ikbd_mem_read(int address, char data[6]) +{ + char cmd[3] = { 0x21, address>>8, address&0xFF }; + + ikbd_write(cmd, 3); + + /* receive data and put it in data */ +} + +/* Controller execute */ +void ikbd_exec(int address) +{ + char cmd[3] = { 0x22, address>>8, address&0xFF }; + + ikbd_write(cmd, 3); +} + +/* Status inquiries (0x87-0x9A) not yet implemented */ + +/* Set the state of the caps lock led. */ +void atari_kbd_leds(unsigned int leds) +{ + char cmd[6] = {32, 0, 4, 1, 254 + ((leds & 4) != 0), 0}; + + ikbd_write(cmd, 6); +} + +/* + * The original code sometimes left the interrupt line of + * the ACIAs low forever. I hope, it is fixed now. + * + * Martin Rogge, 20 Aug 1995 + */ + +static int atari_keyb_done = 0; + +int __init atari_keyb_init(void) +{ + if (atari_keyb_done) + return 0; + + /* setup key map */ + memcpy(key_maps[0], ataplain_map, sizeof(plain_map)); + + kb_state.state = KEYBOARD; + kb_state.len = 0; + + request_irq(IRQ_MFP_ACIA, atari_keyboard_interrupt, IRQ_TYPE_SLOW, + "keyboard/mouse/MIDI", atari_keyboard_interrupt); + + atari_turnoff_irq(IRQ_MFP_ACIA); + do { + /* reset IKBD ACIA */ + acia.key_ctrl = ACIA_RESET | + (atari_switches & ATARI_SWITCH_IKBD) ? ACIA_RHTID : 0; + (void)acia.key_ctrl; + (void)acia.key_data; + + /* reset MIDI ACIA */ + acia.mid_ctrl = ACIA_RESET | + (atari_switches & ATARI_SWITCH_MIDI) ? ACIA_RHTID : 0; + (void)acia.mid_ctrl; + (void)acia.mid_data; + + /* divide 500kHz by 64 gives 7812.5 baud */ + /* 8 data no parity 1 start 1 stop bit */ + /* receive interrupt enabled */ + /* RTS low (except if switch selected), transmit interrupt disabled */ + acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RIE) | + ((atari_switches & ATARI_SWITCH_IKBD) ? + ACIA_RHTID : ACIA_RLTID); + + acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | + (atari_switches & ATARI_SWITCH_MIDI) ? ACIA_RHTID : 0; + + /* make sure the interrupt line is up */ + } while ((mfp.par_dt_reg & 0x10) == 0); + + /* enable ACIA Interrupts */ + mfp.active_edge &= ~0x10; + atari_turnon_irq(IRQ_MFP_ACIA); + + ikbd_self_test = 1; + ikbd_reset(); + /* wait for a period of inactivity (here: 0.25s), then assume the IKBD's + * self-test is finished */ + self_test_last_rcv = jiffies; + while (time_before(jiffies, self_test_last_rcv + HZ/4)) + barrier(); + /* if not incremented: no 0xf1 received */ + if (ikbd_self_test == 1) + printk(KERN_ERR "WARNING: keyboard self test failed!\n"); + ikbd_self_test = 0; + + ikbd_mouse_disable(); + ikbd_joystick_disable(); + +#ifdef FIXED_ATARI_JOYSTICK + atari_joystick_init(); +#endif + + // flag init done + atari_keyb_done = 1; + return 0; +} + + +int atari_kbdrate(struct kbd_repeat *k) +{ + if (k->delay > 0) { + /* convert from msec to jiffies */ + key_repeat_delay = (k->delay * HZ + 500) / 1000; + if (key_repeat_delay < 1) + key_repeat_delay = 1; + } + if (k->period > 0) { + key_repeat_rate = (k->period * HZ + 500) / 1000; + if (key_repeat_rate < 1) + key_repeat_rate = 1; + } + + k->delay = key_repeat_delay * 1000 / HZ; + k->period = key_repeat_rate * 1000 / HZ; + + return 0; +} + +int atari_kbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode) +{ +#ifdef CONFIG_MAGIC_SYSRQ + /* ALT+HELP pressed? */ + if ((keycode == 98) && ((shift_state & 0xff) == 8)) + *keycodep = 0xff; + else +#endif + *keycodep = keycode; + return 1; +} diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index f17e9c7d4b36..c845d5c4cbba 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -164,6 +164,17 @@ config KEYBOARD_AMIGA To compile this driver as a module, choose M here: the module will be called amikbd. +config KEYBOARD_ATARI + tristate "Atari keyboard" + depends on ATARI + select ATARI_KBD_CORE + help + Say Y here if you are running Linux on any Atari and have a keyboard + attached. + + To compile this driver as a module, choose M here: the + module will be called atakbd. + config KEYBOARD_HIL_OLD tristate "HP HIL keyboard support (simple driver)" depends on GSC || HP300 diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 586a0fe53be6..7aa59ee5a0b6 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o +obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o diff --git a/drivers/input/keyboard/atakbd.c b/drivers/input/keyboard/atakbd.c new file mode 100644 index 000000000000..ded1d6ac6ff3 --- /dev/null +++ b/drivers/input/keyboard/atakbd.c @@ -0,0 +1,134 @@ +/* + * atakbd.c + * + * Copyright (c) 2005 Michael Schmitz + * + * Based on amikbd.c, which is + * + * Copyright (c) 2000-2001 Vojtech Pavlik + * + * Based on the work of: + * Hamish Macdonald + */ + +/* + * Atari keyboard driver for Linux/m68k + * + * The low level init and interrupt stuff is handled in arch/mm68k/atari/atakeyb.c + * (the keyboard ACIA also handles the mouse and joystick data, and the keyboard + * interrupt is shared with the MIDI ACIA so MIDI data also get handled there). + * This driver only deals with handing key events off to the input layer. + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Should you need to contact me, the author, you can do so either by + * e-mail - mail your message to , or by paper mail: + * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +MODULE_AUTHOR("Michael Schmitz "); +MODULE_DESCRIPTION("Atari keyboard driver"); +MODULE_LICENSE("GPL"); + +static unsigned char atakbd_keycode[0x72]; + +static struct input_dev *atakbd_dev; + +static void atakbd_interrupt(unsigned char scancode, char down) +{ + + if (scancode < 0x72) { /* scancodes < 0xf2 are keys */ + + // report raw events here? + + scancode = atakbd_keycode[scancode]; + + if (scancode == KEY_CAPSLOCK) { /* CapsLock is a toggle switch key on Amiga */ + input_report_key(atakbd_dev, scancode, 1); + input_report_key(atakbd_dev, scancode, 0); + input_sync(atakbd_dev); + } else { + input_report_key(atakbd_dev, scancode, down); + input_sync(atakbd_dev); + } + } else /* scancodes >= 0xf2 are mouse data, most likely */ + printk(KERN_INFO "atakbd: unhandled scancode %x\n", scancode); + + return; +} + +static int __init atakbd_init(void) +{ + int i; + + if (!ATARIHW_PRESENT(ST_MFP)) + return -EIO; + + // TODO: request_mem_region if not done in arch code + + if (!(atakbd_dev = input_allocate_device())) + return -ENOMEM; + + // need to init core driver if not already done so + if (atari_keyb_init()) + return -ENODEV; + + atakbd_dev->name = "Atari Keyboard"; + atakbd_dev->phys = "atakbd/input0"; + atakbd_dev->id.bustype = BUS_ATARI; + atakbd_dev->id.vendor = 0x0001; + atakbd_dev->id.product = 0x0001; + atakbd_dev->id.version = 0x0100; + + atakbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + atakbd_dev->keycode = atakbd_keycode; + atakbd_dev->keycodesize = sizeof(unsigned char); + atakbd_dev->keycodemax = ARRAY_SIZE(atakbd_keycode); + + for (i = 1; i < 0x72; i++) { + atakbd_keycode[i] = i; + set_bit(atakbd_keycode[i], atakbd_dev->keybit); + } + + input_register_device(atakbd_dev); + + atari_input_keyboard_interrupt_hook = atakbd_interrupt; + + printk(KERN_INFO "input: %s at IKBD ACIA\n", atakbd_dev->name); + + return 0; +} + +static void __exit atakbd_exit(void) +{ + atari_input_keyboard_interrupt_hook = NULL; + input_unregister_device(atakbd_dev); +} + +module_init(atakbd_init); +module_exit(atakbd_exit); diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 35d998c3e578..b40784a60aa1 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -96,6 +96,17 @@ config MOUSE_AMIGA To compile this driver as a module, choose M here: the module will be called amimouse. +config MOUSE_ATARI + tristate "Atari mouse" + depends on ATARI + select ATARI_KBD_CORE + help + Say Y here if you have an Atari and want its native mouse + supported by the kernel. + + To compile this driver as a module, choose M here: the + module will be called atarimouse. + config MOUSE_RISCPC tristate "Acorn RiscPC mouse" depends on ARCH_ACORN diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 21a1de61a79b..700f61200dfc 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile @@ -5,6 +5,7 @@ # Each configuration option enables a list of files. obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o +obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o obj-$(CONFIG_MOUSE_INPORT) += inport.o obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o diff --git a/drivers/input/mouse/atarimouse.c b/drivers/input/mouse/atarimouse.c new file mode 100644 index 000000000000..43ab6566fb65 --- /dev/null +++ b/drivers/input/mouse/atarimouse.c @@ -0,0 +1,160 @@ +/* + * Atari mouse driver for Linux/m68k + * + * Copyright (c) 2005 Michael Schmitz + * + * Based on: + * Amiga mouse driver for Linux/m68k + * + * Copyright (c) 2000-2002 Vojtech Pavlik + * + */ +/* + * The low level init and interrupt stuff is handled in arch/mm68k/atari/atakeyb.c + * (the keyboard ACIA also handles the mouse and joystick data, and the keyboard + * interrupt is shared with the MIDI ACIA so MIDI data also get handled there). + * This driver only deals with handing key events off to the input layer. + * + * Largely based on the old: + * + * Atari Mouse Driver for Linux + * by Robert de Vries (robert@and.nl) 19Jul93 + * + * 16 Nov 1994 Andreas Schwab + * Compatibility with busmouse + * Support for three button mouse (shamelessly stolen from MiNT) + * third button wired to one of the joystick directions on joystick 1 + * + * 1996/02/11 Andreas Schwab + * Module support + * Allow multiple open's + * + * Converted to use new generic busmouse code. 5 Apr 1998 + * Russell King + */ + + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +MODULE_AUTHOR("Michael Schmitz "); +MODULE_DESCRIPTION("Atari mouse driver"); +MODULE_LICENSE("GPL"); + +static int mouse_threshold[2] = {2,2}; + +#ifdef __MODULE__ +MODULE_PARM(mouse_threshold, "2i"); +#endif +#ifdef FIXED_ATARI_JOYSTICK +extern int atari_mouse_buttons; +#endif +static int atamouse_used = 0; + +static struct input_dev *atamouse_dev; + +static void atamouse_interrupt(char *buf) +{ + int buttons, dx, dy; + +/* ikbd_mouse_disable(); */ + + buttons = (buf[0] & 1) | ((buf[0] & 2) << 1); +#ifdef FIXED_ATARI_JOYSTICK + buttons |= atari_mouse_buttons & 2; + atari_mouse_buttons = buttons; +#endif +/* ikbd_mouse_rel_pos(); */ + + /* only relative events get here */ + dx = buf[1]; + dy = -buf[2]; + + input_report_rel(atamouse_dev, REL_X, dx); + input_report_rel(atamouse_dev, REL_Y, dy); + + input_report_key(atamouse_dev, BTN_LEFT, buttons & 0x1); + input_report_key(atamouse_dev, BTN_MIDDLE, buttons & 0x2); + input_report_key(atamouse_dev, BTN_RIGHT, buttons & 0x4); + + input_sync(atamouse_dev); + + return; +} + +static int atamouse_open(struct input_dev *dev) +{ + if (atamouse_used++) + return 0; + +#ifdef FIXED_ATARI_JOYSTICK + atari_mouse_buttons = 0; +#endif + ikbd_mouse_y0_top(); + ikbd_mouse_thresh(mouse_threshold[0], mouse_threshold[1]); + ikbd_mouse_rel_pos(); + atari_input_mouse_interrupt_hook = atamouse_interrupt; + return 0; +} + +static void atamouse_close(struct input_dev *dev) +{ + if (!--atamouse_used) { + ikbd_mouse_disable(); + atari_mouse_interrupt_hook = NULL; + } +} + +static int __init atamouse_init(void) +{ + if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ST_MFP)) + return -ENODEV; + + if (!(atamouse_dev = input_allocate_device())) + return -ENOMEM; + + if (!(atari_keyb_init())) + return -ENODEV; + + atamouse_dev->name = "Atari mouse"; + atamouse_dev->phys = "atamouse/input0"; + atamouse_dev->id.bustype = BUS_ATARI; + atamouse_dev->id.vendor = 0x0001; + atamouse_dev->id.product = 0x0002; + atamouse_dev->id.version = 0x0100; + + atamouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + atamouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); + atamouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + atamouse_dev->open = atamouse_open; + atamouse_dev->close = atamouse_close; + + input_register_device(atamouse_dev); + + printk(KERN_INFO "input: %s at keyboard ACIA\n", atamouse_dev->name); + return 0; +} + +static void __exit atamouse_exit(void) +{ + input_unregister_device(atamouse_dev); +} + +module_init(atamouse_init); +module_exit(atamouse_exit); diff --git a/include/asm-m68k/atarikb.h b/include/asm-m68k/atarikb.h index 18926058fde7..546e7da5804f 100644 --- a/include/asm-m68k/atarikb.h +++ b/include/asm-m68k/atarikb.h @@ -36,5 +36,11 @@ void ikbd_joystick_disable(void); extern void (*atari_MIDI_interrupt_hook) (void); /* Hook for mouse driver */ extern void (*atari_mouse_interrupt_hook) (char *); +/* Hook for keyboard inputdev driver */ +extern void (*atari_input_keyboard_interrupt_hook) (unsigned char, char); +/* Hook for mouse inputdev driver */ +extern void (*atari_input_mouse_interrupt_hook) (char *); + +int atari_keyb_init(void); #endif /* _LINUX_ATARIKB_H */ diff --git a/include/linux/input.h b/include/linux/input.h index bde65c8a3519..327122548c4d 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -676,6 +676,7 @@ struct input_absinfo { #define BUS_I2C 0x18 #define BUS_HOST 0x19 #define BUS_GSC 0x1A +#define BUS_ATARI 0x1B /* * Values describing the status of a force-feedback effect -- cgit v1.2.3-59-g8ed1b From ec0203e75360638237299b78a7b0d343301075b3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 1 May 2007 22:32:40 +0200 Subject: m68k: CROSS_COMPILE = m68k-linux-gnu- Recent cross-compilers are called m68k-linux-gnu-gcc instead of m68k-linux-gcc Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile index 34d826d10f1b..c20831a7e1a9 100644 --- a/arch/m68k/Makefile +++ b/arch/m68k/Makefile @@ -21,7 +21,7 @@ AS += -m68020 LDFLAGS := -m m68kelf ifneq ($(COMPILE_ARCH),$(ARCH)) # prefix for cross-compiling binaries - CROSS_COMPILE = m68k-linux- + CROSS_COMPILE = m68k-linux-gnu- endif ifdef CONFIG_SUN3 -- cgit v1.2.3-59-g8ed1b From 6ff5801acbb643e81d3420ac0f37c96089309063 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Tue, 1 May 2007 22:32:43 +0200 Subject: m68k: reformat various m68k files Reformat various m68k files, so they actually look like Linux sources. Signed-off-by: Roman Zippel Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/amiga/config.c | 1076 +++++++++++++++++++++++----------------------- arch/m68k/atari/config.c | 989 ++++++++++++++++++++---------------------- arch/m68k/atari/debug.c | 474 ++++++++++---------- arch/m68k/kernel/entry.S | 2 +- arch/m68k/kernel/head.S | 2 +- arch/m68k/kernel/setup.c | 371 ++++++++-------- arch/m68k/mac/config.c | 161 +++---- arch/m68k/mac/debug.c | 323 +++++++------- arch/m68k/q40/config.c | 265 ++++++------ arch/m68k/sun3x/prom.c | 127 +++--- 10 files changed, 1865 insertions(+), 1925 deletions(-) (limited to 'arch') diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c index 3204f412cad8..c3b69b1b0cef 100644 --- a/arch/m68k/amiga/config.c +++ b/arch/m68k/amiga/config.c @@ -22,9 +22,7 @@ #include #include #include -#ifdef CONFIG_ZORRO #include -#endif #include #include @@ -62,21 +60,21 @@ static char s_cdtv[] __initdata = "CDTV"; static char s_cd32[] __initdata = "CD32"; static char s_draco[] __initdata = "Draco"; static char *amiga_models[] __initdata = { - [AMI_500-AMI_500] = s_a500, - [AMI_500PLUS-AMI_500] = s_a500p, - [AMI_600-AMI_500] = s_a600, - [AMI_1000-AMI_500] = s_a1000, - [AMI_1200-AMI_500] = s_a1200, - [AMI_2000-AMI_500] = s_a2000, - [AMI_2500-AMI_500] = s_a2500, - [AMI_3000-AMI_500] = s_a3000, - [AMI_3000T-AMI_500] = s_a3000t, - [AMI_3000PLUS-AMI_500] = s_a3000p, - [AMI_4000-AMI_500] = s_a4000, - [AMI_4000T-AMI_500] = s_a4000t, - [AMI_CDTV-AMI_500] = s_cdtv, - [AMI_CD32-AMI_500] = s_cd32, - [AMI_DRACO-AMI_500] = s_draco, + [AMI_500-AMI_500] = s_a500, + [AMI_500PLUS-AMI_500] = s_a500p, + [AMI_600-AMI_500] = s_a600, + [AMI_1000-AMI_500] = s_a1000, + [AMI_1200-AMI_500] = s_a1200, + [AMI_2000-AMI_500] = s_a2000, + [AMI_2500-AMI_500] = s_a2500, + [AMI_3000-AMI_500] = s_a3000, + [AMI_3000T-AMI_500] = s_a3000t, + [AMI_3000PLUS-AMI_500] = s_a3000p, + [AMI_4000-AMI_500] = s_a4000, + [AMI_4000T-AMI_500] = s_a4000t, + [AMI_CDTV-AMI_500] = s_cdtv, + [AMI_CD32-AMI_500] = s_cd32, + [AMI_DRACO-AMI_500] = s_draco, }; static char amiga_model_name[13] = "Amiga "; @@ -85,17 +83,17 @@ extern char m68k_debug_device[]; static void amiga_sched_init(irq_handler_t handler); /* amiga specific irq functions */ -extern void amiga_init_IRQ (void); +extern void amiga_init_IRQ(void); static void amiga_get_model(char *model); static int amiga_get_hardware_list(char *buffer); /* amiga specific timer functions */ -static unsigned long amiga_gettimeoffset (void); -static int a3000_hwclk (int, struct rtc_time *); -static int a2000_hwclk (int, struct rtc_time *); -static int amiga_set_clock_mmss (unsigned long); -static unsigned int amiga_get_ss (void); -extern void amiga_mksound( unsigned int count, unsigned int ticks ); -static void amiga_reset (void); +static unsigned long amiga_gettimeoffset(void); +static int a3000_hwclk(int, struct rtc_time *); +static int a2000_hwclk(int, struct rtc_time *); +static int amiga_set_clock_mmss(unsigned long); +static unsigned int amiga_get_ss(void); +extern void amiga_mksound(unsigned int count, unsigned int ticks); +static void amiga_reset(void); extern void amiga_init_sound(void); static void amiga_savekmsg_init(void); static void amiga_mem_console_write(struct console *co, const char *b, @@ -108,9 +106,9 @@ static void amiga_heartbeat(int on); #endif static struct console amiga_console_driver = { - .name = "debug", - .flags = CON_PRINTBUFFER, - .index = -1, + .name = "debug", + .flags = CON_PRINTBUFFER, + .index = -1, }; @@ -119,24 +117,24 @@ static struct console amiga_console_driver = { */ static struct { - struct resource _ciab, _ciaa, _custom, _kickstart; + struct resource _ciab, _ciaa, _custom, _kickstart; } mb_resources = { - ._ciab = { - .name = "CIA B", .start = 0x00bfd000, .end = 0x00bfdfff - }, - ._ciaa = { - .name = "CIA A", .start = 0x00bfe000, .end = 0x00bfefff - }, - ._custom = { - .name = "Custom I/O", .start = 0x00dff000, .end = 0x00dfffff - }, - ._kickstart = { - .name = "Kickstart ROM", .start = 0x00f80000, .end = 0x00ffffff - } + ._ciab = { + .name = "CIA B", .start = 0x00bfd000, .end = 0x00bfdfff + }, + ._ciaa = { + .name = "CIA A", .start = 0x00bfe000, .end = 0x00bfefff + }, + ._custom = { + .name = "Custom I/O", .start = 0x00dff000, .end = 0x00dfffff + }, + ._kickstart = { + .name = "Kickstart ROM", .start = 0x00f80000, .end = 0x00ffffff + } }; static struct resource rtc_resource = { - .start = 0x00dc0000, .end = 0x00dcffff + .start = 0x00dc0000, .end = 0x00dcffff }; static struct resource ram_resource[NUM_MEMINFO]; @@ -148,57 +146,57 @@ static struct resource ram_resource[NUM_MEMINFO]; int amiga_parse_bootinfo(const struct bi_record *record) { - int unknown = 0; - const unsigned long *data = record->data; + int unknown = 0; + const unsigned long *data = record->data; - switch (record->tag) { + switch (record->tag) { case BI_AMIGA_MODEL: - amiga_model = *data; - break; + amiga_model = *data; + break; case BI_AMIGA_ECLOCK: - amiga_eclock = *data; - break; + amiga_eclock = *data; + break; case BI_AMIGA_CHIPSET: - amiga_chipset = *data; - break; + amiga_chipset = *data; + break; case BI_AMIGA_CHIP_SIZE: - amiga_chip_size = *(const int *)data; - break; + amiga_chip_size = *(const int *)data; + break; case BI_AMIGA_VBLANK: - amiga_vblank = *(const unsigned char *)data; - break; + amiga_vblank = *(const unsigned char *)data; + break; case BI_AMIGA_PSFREQ: - amiga_psfreq = *(const unsigned char *)data; - break; + amiga_psfreq = *(const unsigned char *)data; + break; case BI_AMIGA_AUTOCON: #ifdef CONFIG_ZORRO - if (zorro_num_autocon < ZORRO_NUM_AUTO) { - const struct ConfigDev *cd = (struct ConfigDev *)data; - struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++]; - dev->rom = cd->cd_Rom; - dev->slotaddr = cd->cd_SlotAddr; - dev->slotsize = cd->cd_SlotSize; - dev->resource.start = (unsigned long)cd->cd_BoardAddr; - dev->resource.end = dev->resource.start+cd->cd_BoardSize-1; - } else - printk("amiga_parse_bootinfo: too many AutoConfig devices\n"); + if (zorro_num_autocon < ZORRO_NUM_AUTO) { + const struct ConfigDev *cd = (struct ConfigDev *)data; + struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++]; + dev->rom = cd->cd_Rom; + dev->slotaddr = cd->cd_SlotAddr; + dev->slotsize = cd->cd_SlotSize; + dev->resource.start = (unsigned long)cd->cd_BoardAddr; + dev->resource.end = dev->resource.start + cd->cd_BoardSize - 1; + } else + printk("amiga_parse_bootinfo: too many AutoConfig devices\n"); #endif /* CONFIG_ZORRO */ - break; + break; case BI_AMIGA_SERPER: - /* serial port period: ignored here */ - break; + /* serial port period: ignored here */ + break; default: - unknown = 1; - } - return(unknown); + unknown = 1; + } + return unknown; } /* @@ -207,159 +205,159 @@ int amiga_parse_bootinfo(const struct bi_record *record) static void __init amiga_identify(void) { - /* Fill in some default values, if necessary */ - if (amiga_eclock == 0) - amiga_eclock = 709379; - - memset(&amiga_hw_present, 0, sizeof(amiga_hw_present)); - - printk("Amiga hardware found: "); - if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO) { - printk("[%s] ", amiga_models[amiga_model-AMI_500]); - strcat(amiga_model_name, amiga_models[amiga_model-AMI_500]); - } - - switch(amiga_model) { - case AMI_UNKNOWN: - goto Generic; - - case AMI_600: - case AMI_1200: - AMIGAHW_SET(A1200_IDE); - AMIGAHW_SET(PCMCIA); - case AMI_500: - case AMI_500PLUS: - case AMI_1000: - case AMI_2000: - case AMI_2500: - AMIGAHW_SET(A2000_CLK); /* Is this correct for all models? */ - goto Generic; - - case AMI_3000: - case AMI_3000T: - AMIGAHW_SET(AMBER_FF); - AMIGAHW_SET(MAGIC_REKICK); - /* fall through */ - case AMI_3000PLUS: - AMIGAHW_SET(A3000_SCSI); - AMIGAHW_SET(A3000_CLK); - AMIGAHW_SET(ZORRO3); - goto Generic; - - case AMI_4000T: - AMIGAHW_SET(A4000_SCSI); - /* fall through */ - case AMI_4000: - AMIGAHW_SET(A4000_IDE); - AMIGAHW_SET(A3000_CLK); - AMIGAHW_SET(ZORRO3); - goto Generic; - - case AMI_CDTV: - case AMI_CD32: - AMIGAHW_SET(CD_ROM); - AMIGAHW_SET(A2000_CLK); /* Is this correct? */ - goto Generic; - - Generic: - AMIGAHW_SET(AMI_VIDEO); - AMIGAHW_SET(AMI_BLITTER); - AMIGAHW_SET(AMI_AUDIO); - AMIGAHW_SET(AMI_FLOPPY); - AMIGAHW_SET(AMI_KEYBOARD); - AMIGAHW_SET(AMI_MOUSE); - AMIGAHW_SET(AMI_SERIAL); - AMIGAHW_SET(AMI_PARALLEL); - AMIGAHW_SET(CHIP_RAM); - AMIGAHW_SET(PAULA); - - switch(amiga_chipset) { - case CS_OCS: - case CS_ECS: - case CS_AGA: - switch (amiga_custom.deniseid & 0xf) { - case 0x0c: - AMIGAHW_SET(DENISE_HR); - break; - case 0x08: - AMIGAHW_SET(LISA); - break; - } - break; - default: - AMIGAHW_SET(DENISE); - break; - } - switch ((amiga_custom.vposr>>8) & 0x7f) { - case 0x00: - AMIGAHW_SET(AGNUS_PAL); - break; - case 0x10: - AMIGAHW_SET(AGNUS_NTSC); - break; - case 0x20: - case 0x21: - AMIGAHW_SET(AGNUS_HR_PAL); - break; - case 0x30: - case 0x31: - AMIGAHW_SET(AGNUS_HR_NTSC); - break; - case 0x22: - case 0x23: - AMIGAHW_SET(ALICE_PAL); - break; - case 0x32: - case 0x33: - AMIGAHW_SET(ALICE_NTSC); - break; - } - AMIGAHW_SET(ZORRO); - break; - - case AMI_DRACO: - panic("No support for Draco yet"); - - default: - panic("Unknown Amiga Model"); - } + /* Fill in some default values, if necessary */ + if (amiga_eclock == 0) + amiga_eclock = 709379; -#define AMIGAHW_ANNOUNCE(name, str) \ - if (AMIGAHW_PRESENT(name)) \ - printk(str) - - AMIGAHW_ANNOUNCE(AMI_VIDEO, "VIDEO "); - AMIGAHW_ANNOUNCE(AMI_BLITTER, "BLITTER "); - AMIGAHW_ANNOUNCE(AMBER_FF, "AMBER_FF "); - AMIGAHW_ANNOUNCE(AMI_AUDIO, "AUDIO "); - AMIGAHW_ANNOUNCE(AMI_FLOPPY, "FLOPPY "); - AMIGAHW_ANNOUNCE(A3000_SCSI, "A3000_SCSI "); - AMIGAHW_ANNOUNCE(A4000_SCSI, "A4000_SCSI "); - AMIGAHW_ANNOUNCE(A1200_IDE, "A1200_IDE "); - AMIGAHW_ANNOUNCE(A4000_IDE, "A4000_IDE "); - AMIGAHW_ANNOUNCE(CD_ROM, "CD_ROM "); - AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "KEYBOARD "); - AMIGAHW_ANNOUNCE(AMI_MOUSE, "MOUSE "); - AMIGAHW_ANNOUNCE(AMI_SERIAL, "SERIAL "); - AMIGAHW_ANNOUNCE(AMI_PARALLEL, "PARALLEL "); - AMIGAHW_ANNOUNCE(A2000_CLK, "A2000_CLK "); - AMIGAHW_ANNOUNCE(A3000_CLK, "A3000_CLK "); - AMIGAHW_ANNOUNCE(CHIP_RAM, "CHIP_RAM "); - AMIGAHW_ANNOUNCE(PAULA, "PAULA "); - AMIGAHW_ANNOUNCE(DENISE, "DENISE "); - AMIGAHW_ANNOUNCE(DENISE_HR, "DENISE_HR "); - AMIGAHW_ANNOUNCE(LISA, "LISA "); - AMIGAHW_ANNOUNCE(AGNUS_PAL, "AGNUS_PAL "); - AMIGAHW_ANNOUNCE(AGNUS_NTSC, "AGNUS_NTSC "); - AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "AGNUS_HR_PAL "); - AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "AGNUS_HR_NTSC "); - AMIGAHW_ANNOUNCE(ALICE_PAL, "ALICE_PAL "); - AMIGAHW_ANNOUNCE(ALICE_NTSC, "ALICE_NTSC "); - AMIGAHW_ANNOUNCE(MAGIC_REKICK, "MAGIC_REKICK "); - AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA "); - if (AMIGAHW_PRESENT(ZORRO)) - printk("ZORRO%s ", AMIGAHW_PRESENT(ZORRO3) ? "3" : ""); - printk("\n"); + memset(&amiga_hw_present, 0, sizeof(amiga_hw_present)); + + printk("Amiga hardware found: "); + if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO) { + printk("[%s] ", amiga_models[amiga_model-AMI_500]); + strcat(amiga_model_name, amiga_models[amiga_model-AMI_500]); + } + + switch (amiga_model) { + case AMI_UNKNOWN: + goto Generic; + + case AMI_600: + case AMI_1200: + AMIGAHW_SET(A1200_IDE); + AMIGAHW_SET(PCMCIA); + case AMI_500: + case AMI_500PLUS: + case AMI_1000: + case AMI_2000: + case AMI_2500: + AMIGAHW_SET(A2000_CLK); /* Is this correct for all models? */ + goto Generic; + + case AMI_3000: + case AMI_3000T: + AMIGAHW_SET(AMBER_FF); + AMIGAHW_SET(MAGIC_REKICK); + /* fall through */ + case AMI_3000PLUS: + AMIGAHW_SET(A3000_SCSI); + AMIGAHW_SET(A3000_CLK); + AMIGAHW_SET(ZORRO3); + goto Generic; + + case AMI_4000T: + AMIGAHW_SET(A4000_SCSI); + /* fall through */ + case AMI_4000: + AMIGAHW_SET(A4000_IDE); + AMIGAHW_SET(A3000_CLK); + AMIGAHW_SET(ZORRO3); + goto Generic; + + case AMI_CDTV: + case AMI_CD32: + AMIGAHW_SET(CD_ROM); + AMIGAHW_SET(A2000_CLK); /* Is this correct? */ + goto Generic; + + Generic: + AMIGAHW_SET(AMI_VIDEO); + AMIGAHW_SET(AMI_BLITTER); + AMIGAHW_SET(AMI_AUDIO); + AMIGAHW_SET(AMI_FLOPPY); + AMIGAHW_SET(AMI_KEYBOARD); + AMIGAHW_SET(AMI_MOUSE); + AMIGAHW_SET(AMI_SERIAL); + AMIGAHW_SET(AMI_PARALLEL); + AMIGAHW_SET(CHIP_RAM); + AMIGAHW_SET(PAULA); + + switch (amiga_chipset) { + case CS_OCS: + case CS_ECS: + case CS_AGA: + switch (amiga_custom.deniseid & 0xf) { + case 0x0c: + AMIGAHW_SET(DENISE_HR); + break; + case 0x08: + AMIGAHW_SET(LISA); + break; + } + break; + default: + AMIGAHW_SET(DENISE); + break; + } + switch ((amiga_custom.vposr>>8) & 0x7f) { + case 0x00: + AMIGAHW_SET(AGNUS_PAL); + break; + case 0x10: + AMIGAHW_SET(AGNUS_NTSC); + break; + case 0x20: + case 0x21: + AMIGAHW_SET(AGNUS_HR_PAL); + break; + case 0x30: + case 0x31: + AMIGAHW_SET(AGNUS_HR_NTSC); + break; + case 0x22: + case 0x23: + AMIGAHW_SET(ALICE_PAL); + break; + case 0x32: + case 0x33: + AMIGAHW_SET(ALICE_NTSC); + break; + } + AMIGAHW_SET(ZORRO); + break; + + case AMI_DRACO: + panic("No support for Draco yet"); + + default: + panic("Unknown Amiga Model"); + } + +#define AMIGAHW_ANNOUNCE(name, str) \ + if (AMIGAHW_PRESENT(name)) \ + printk(str) + + AMIGAHW_ANNOUNCE(AMI_VIDEO, "VIDEO "); + AMIGAHW_ANNOUNCE(AMI_BLITTER, "BLITTER "); + AMIGAHW_ANNOUNCE(AMBER_FF, "AMBER_FF "); + AMIGAHW_ANNOUNCE(AMI_AUDIO, "AUDIO "); + AMIGAHW_ANNOUNCE(AMI_FLOPPY, "FLOPPY "); + AMIGAHW_ANNOUNCE(A3000_SCSI, "A3000_SCSI "); + AMIGAHW_ANNOUNCE(A4000_SCSI, "A4000_SCSI "); + AMIGAHW_ANNOUNCE(A1200_IDE, "A1200_IDE "); + AMIGAHW_ANNOUNCE(A4000_IDE, "A4000_IDE "); + AMIGAHW_ANNOUNCE(CD_ROM, "CD_ROM "); + AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "KEYBOARD "); + AMIGAHW_ANNOUNCE(AMI_MOUSE, "MOUSE "); + AMIGAHW_ANNOUNCE(AMI_SERIAL, "SERIAL "); + AMIGAHW_ANNOUNCE(AMI_PARALLEL, "PARALLEL "); + AMIGAHW_ANNOUNCE(A2000_CLK, "A2000_CLK "); + AMIGAHW_ANNOUNCE(A3000_CLK, "A3000_CLK "); + AMIGAHW_ANNOUNCE(CHIP_RAM, "CHIP_RAM "); + AMIGAHW_ANNOUNCE(PAULA, "PAULA "); + AMIGAHW_ANNOUNCE(DENISE, "DENISE "); + AMIGAHW_ANNOUNCE(DENISE_HR, "DENISE_HR "); + AMIGAHW_ANNOUNCE(LISA, "LISA "); + AMIGAHW_ANNOUNCE(AGNUS_PAL, "AGNUS_PAL "); + AMIGAHW_ANNOUNCE(AGNUS_NTSC, "AGNUS_NTSC "); + AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "AGNUS_HR_PAL "); + AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "AGNUS_HR_NTSC "); + AMIGAHW_ANNOUNCE(ALICE_PAL, "ALICE_PAL "); + AMIGAHW_ANNOUNCE(ALICE_NTSC, "ALICE_NTSC "); + AMIGAHW_ANNOUNCE(MAGIC_REKICK, "MAGIC_REKICK "); + AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA "); + if (AMIGAHW_PRESENT(ZORRO)) + printk("ZORRO%s ", AMIGAHW_PRESENT(ZORRO3) ? "3" : ""); + printk("\n"); #undef AMIGAHW_ANNOUNCE } @@ -370,119 +368,117 @@ static void __init amiga_identify(void) void __init config_amiga(void) { - int i; - - amiga_debug_init(); - amiga_identify(); - - /* Yuk, we don't have PCI memory */ - iomem_resource.name = "Memory"; - for (i = 0; i < 4; i++) - request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]); - - mach_sched_init = amiga_sched_init; - mach_init_IRQ = amiga_init_IRQ; - mach_get_model = amiga_get_model; - mach_get_hardware_list = amiga_get_hardware_list; - mach_gettimeoffset = amiga_gettimeoffset; - if (AMIGAHW_PRESENT(A3000_CLK)){ - mach_hwclk = a3000_hwclk; - rtc_resource.name = "A3000 RTC"; - request_resource(&iomem_resource, &rtc_resource); - } - else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */ - mach_hwclk = a2000_hwclk; - rtc_resource.name = "A2000 RTC"; - request_resource(&iomem_resource, &rtc_resource); - } - - mach_max_dma_address = 0xffffffff; /* - * default MAX_DMA=0xffffffff - * on all machines. If we don't - * do so, the SCSI code will not - * be able to allocate any mem - * for transfers, unless we are - * dealing with a Z2 mem only - * system. /Jes - */ - - mach_set_clock_mmss = amiga_set_clock_mmss; - mach_get_ss = amiga_get_ss; - mach_reset = amiga_reset; + int i; + + amiga_debug_init(); + amiga_identify(); + + /* Yuk, we don't have PCI memory */ + iomem_resource.name = "Memory"; + for (i = 0; i < 4; i++) + request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]); + + mach_sched_init = amiga_sched_init; + mach_init_IRQ = amiga_init_IRQ; + mach_get_model = amiga_get_model; + mach_get_hardware_list = amiga_get_hardware_list; + mach_gettimeoffset = amiga_gettimeoffset; + if (AMIGAHW_PRESENT(A3000_CLK)) { + mach_hwclk = a3000_hwclk; + rtc_resource.name = "A3000 RTC"; + request_resource(&iomem_resource, &rtc_resource); + } else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ { + mach_hwclk = a2000_hwclk; + rtc_resource.name = "A2000 RTC"; + request_resource(&iomem_resource, &rtc_resource); + } + + /* + * default MAX_DMA=0xffffffff on all machines. If we don't do so, the SCSI + * code will not be able to allocate any mem for transfers, unless we are + * dealing with a Z2 mem only system. /Jes + */ + mach_max_dma_address = 0xffffffff; + + mach_set_clock_mmss = amiga_set_clock_mmss; + mach_get_ss = amiga_get_ss; + mach_reset = amiga_reset; #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) - mach_beep = amiga_mksound; + mach_beep = amiga_mksound; #endif #ifdef CONFIG_HEARTBEAT - mach_heartbeat = amiga_heartbeat; + mach_heartbeat = amiga_heartbeat; #endif - /* Fill in the clock values (based on the 700 kHz E-Clock) */ - amiga_masterclock = 40*amiga_eclock; /* 28 MHz */ - amiga_colorclock = 5*amiga_eclock; /* 3.5 MHz */ - - /* clear all DMA bits */ - amiga_custom.dmacon = DMAF_ALL; - /* ensure that the DMA master bit is set */ - amiga_custom.dmacon = DMAF_SETCLR | DMAF_MASTER; - - /* don't use Z2 RAM as system memory on Z3 capable machines */ - if (AMIGAHW_PRESENT(ZORRO3)) { - int i, j; - u32 disabled_z2mem = 0; - for (i = 0; i < m68k_num_memory; i++) - if (m68k_memory[i].addr < 16*1024*1024) { - if (i == 0) { - /* don't cut off the branch we're sitting on */ - printk("Warning: kernel runs in Zorro II memory\n"); - continue; + /* Fill in the clock values (based on the 700 kHz E-Clock) */ + amiga_masterclock = 40*amiga_eclock; /* 28 MHz */ + amiga_colorclock = 5*amiga_eclock; /* 3.5 MHz */ + + /* clear all DMA bits */ + amiga_custom.dmacon = DMAF_ALL; + /* ensure that the DMA master bit is set */ + amiga_custom.dmacon = DMAF_SETCLR | DMAF_MASTER; + + /* don't use Z2 RAM as system memory on Z3 capable machines */ + if (AMIGAHW_PRESENT(ZORRO3)) { + int i, j; + u32 disabled_z2mem = 0; + + for (i = 0; i < m68k_num_memory; i++) { + if (m68k_memory[i].addr < 16*1024*1024) { + if (i == 0) { + /* don't cut off the branch we're sitting on */ + printk("Warning: kernel runs in Zorro II memory\n"); + continue; + } + disabled_z2mem += m68k_memory[i].size; + m68k_num_memory--; + for (j = i; j < m68k_num_memory; j++) + m68k_memory[j] = m68k_memory[j+1]; + i--; + } + } + if (disabled_z2mem) + printk("%dK of Zorro II memory will not be used as system memory\n", + disabled_z2mem>>10); + } + + /* request all RAM */ + for (i = 0; i < m68k_num_memory; i++) { + ram_resource[i].name = + (m68k_memory[i].addr >= 0x01000000) ? "32-bit Fast RAM" : + (m68k_memory[i].addr < 0x00c00000) ? "16-bit Fast RAM" : + "16-bit Slow RAM"; + ram_resource[i].start = m68k_memory[i].addr; + ram_resource[i].end = m68k_memory[i].addr+m68k_memory[i].size-1; + request_resource(&iomem_resource, &ram_resource[i]); + } + + /* initialize chipram allocator */ + amiga_chip_init(); + + /* debugging using chipram */ + if (!strcmp(m68k_debug_device, "mem")) { + if (!AMIGAHW_PRESENT(CHIP_RAM)) + printk("Warning: no chipram present for debugging\n"); + else { + amiga_savekmsg_init(); + amiga_console_driver.write = amiga_mem_console_write; + register_console(&amiga_console_driver); + } } - disabled_z2mem += m68k_memory[i].size; - m68k_num_memory--; - for (j = i; j < m68k_num_memory; j++) - m68k_memory[j] = m68k_memory[j+1]; - i--; - } - if (disabled_z2mem) - printk("%dK of Zorro II memory will not be used as system memory\n", - disabled_z2mem>>10); - } - - /* request all RAM */ - for (i = 0; i < m68k_num_memory; i++) { - ram_resource[i].name = - (m68k_memory[i].addr >= 0x01000000) ? "32-bit Fast RAM" : - (m68k_memory[i].addr < 0x00c00000) ? "16-bit Fast RAM" : - "16-bit Slow RAM"; - ram_resource[i].start = m68k_memory[i].addr; - ram_resource[i].end = m68k_memory[i].addr+m68k_memory[i].size-1; - request_resource(&iomem_resource, &ram_resource[i]); - } - - /* initialize chipram allocator */ - amiga_chip_init (); - - /* debugging using chipram */ - if (!strcmp( m68k_debug_device, "mem" )){ - if (!AMIGAHW_PRESENT(CHIP_RAM)) - printk("Warning: no chipram present for debugging\n"); - else { - amiga_savekmsg_init(); - amiga_console_driver.write = amiga_mem_console_write; - register_console(&amiga_console_driver); - } - } - - /* our beloved beeper */ - if (AMIGAHW_PRESENT(AMI_AUDIO)) - amiga_init_sound(); - - /* - * if it is an A3000, set the magic bit that forces - * a hard rekick - */ - if (AMIGAHW_PRESENT(MAGIC_REKICK)) - *(unsigned char *)ZTWO_VADDR(0xde0002) |= 0x80; + + /* our beloved beeper */ + if (AMIGAHW_PRESENT(AMI_AUDIO)) + amiga_init_sound(); + + /* + * if it is an A3000, set the magic bit that forces + * a hard rekick + */ + if (AMIGAHW_PRESENT(MAGIC_REKICK)) + *(unsigned char *)ZTWO_VADDR(0xde0002) |= 0x80; } static unsigned short jiffy_ticks; @@ -490,12 +486,12 @@ static unsigned short jiffy_ticks; static void __init amiga_sched_init(irq_handler_t timer_routine) { static struct resource sched_res = { - .name = "timer", .start = 0x00bfd400, .end = 0x00bfd5ff, + .name = "timer", .start = 0x00bfd400, .end = 0x00bfd5ff, }; jiffy_ticks = (amiga_eclock+HZ/2)/HZ; if (request_resource(&mb_resources._ciab, &sched_res)) - printk("Cannot allocate ciab.ta{lo,hi}\n"); + printk("Cannot allocate ciab.ta{lo,hi}\n"); ciab.cra &= 0xC0; /* turn off timer A, continuous mode, from Eclk */ ciab.talo = jiffy_ticks % 256; ciab.tahi = jiffy_ticks / 256; @@ -513,7 +509,7 @@ static void __init amiga_sched_init(irq_handler_t timer_routine) #define TICK_SIZE 10000 /* This is always executed with interrupts disabled. */ -static unsigned long amiga_gettimeoffset (void) +static unsigned long amiga_gettimeoffset(void) { unsigned short hi, lo, hi2; unsigned long ticks, offset = 0; @@ -585,15 +581,15 @@ static int a2000_hwclk(int op, struct rtc_time *t) tod_2000.cntrl1 = TOD2000_CNTRL1_HOLD; - while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) - { - tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; - udelay(70); - tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; + while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) { + tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; + udelay(70); + tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; } if (!cnt) - printk(KERN_INFO "hwclk: timed out waiting for RTC (0x%x)\n", tod_2000.cntrl1); + printk(KERN_INFO "hwclk: timed out waiting for RTC (0x%x)\n", + tod_2000.cntrl1); if (!op) { /* read */ t->tm_sec = tod_2000.second1 * 10 + tod_2000.second2; @@ -606,7 +602,7 @@ static int a2000_hwclk(int op, struct rtc_time *t) if (t->tm_year <= 69) t->tm_year += 100; - if (!(tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE)){ + if (!(tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE)) { if (!(tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour == 12) t->tm_hour = 0; else if ((tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour != 12) @@ -642,7 +638,7 @@ static int a2000_hwclk(int op, struct rtc_time *t) return 0; } -static int amiga_set_clock_mmss (unsigned long nowtime) +static int amiga_set_clock_mmss(unsigned long nowtime) { short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; @@ -660,8 +656,7 @@ static int amiga_set_clock_mmss (unsigned long nowtime) tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; - while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) - { + while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) { tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; udelay(70); tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; @@ -681,7 +676,7 @@ static int amiga_set_clock_mmss (unsigned long nowtime) return 0; } -static unsigned int amiga_get_ss( void ) +static unsigned int amiga_get_ss(void) { unsigned int s; @@ -695,71 +690,72 @@ static unsigned int amiga_get_ss( void ) return s; } -static NORET_TYPE void amiga_reset( void ) +static NORET_TYPE void amiga_reset(void) ATTRIB_NORET; -static void amiga_reset (void) +static void amiga_reset(void) { - unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040); - unsigned long jmp_addr = virt_to_phys(&&jmp_addr_label); - - local_irq_disable(); - if (CPU_IS_040_OR_060) - /* Setup transparent translation registers for mapping - * of 16 MB kernel segment before disabling translation - */ - __asm__ __volatile__ - ("movel %0,%/d0\n\t" - "andl #0xff000000,%/d0\n\t" - "orw #0xe020,%/d0\n\t" /* map 16 MB, enable, cacheable */ - ".chip 68040\n\t" - "movec %%d0,%%itt0\n\t" - "movec %%d0,%%dtt0\n\t" - ".chip 68k\n\t" - "jmp %0@\n\t" - : /* no outputs */ - : "a" (jmp_addr040)); - else - /* for 680[23]0, just disable translation and jump to the physical - * address of the label - */ - __asm__ __volatile__ - ("pmove %/tc,%@\n\t" - "bclr #7,%@\n\t" - "pmove %@,%/tc\n\t" - "jmp %0@\n\t" - : /* no outputs */ - : "a" (jmp_addr)); - jmp_addr_label040: - /* disable translation on '040 now */ - __asm__ __volatile__ - ("moveq #0,%/d0\n\t" - ".chip 68040\n\t" - "movec %%d0,%%tc\n\t" /* disable MMU */ - ".chip 68k\n\t" - : /* no outputs */ - : /* no inputs */ - : "d0"); - - jmp_addr_label: - /* pickup reset address from AmigaOS ROM, reset devices and jump - * to reset address - */ - __asm__ __volatile__ - ("movew #0x2700,%/sr\n\t" - "leal 0x01000000,%/a0\n\t" - "subl %/a0@(-0x14),%/a0\n\t" - "movel %/a0@(4),%/a0\n\t" - "subql #2,%/a0\n\t" - "bra 1f\n\t" - /* align on a longword boundary */ - __ALIGN_STR "\n" - "1:\n\t" - "reset\n\t" - "jmp %/a0@" : /* Just that gcc scans it for % escapes */ ); - - for (;;); - + unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040); + unsigned long jmp_addr = virt_to_phys(&&jmp_addr_label); + + local_irq_disable(); + if (CPU_IS_040_OR_060) + /* Setup transparent translation registers for mapping + * of 16 MB kernel segment before disabling translation + */ + asm volatile ("\n" + " move.l %0,%%d0\n" + " and.l #0xff000000,%%d0\n" + " or.w #0xe020,%%d0\n" /* map 16 MB, enable, cacheable */ + " .chip 68040\n" + " movec %%d0,%%itt0\n" + " movec %%d0,%%dtt0\n" + " .chip 68k\n" + " jmp %0@\n" + : /* no outputs */ + : "a" (jmp_addr040) + : "d0"); + else + /* for 680[23]0, just disable translation and jump to the physical + * address of the label + */ + asm volatile ("\n" + " pmove %%tc,%@\n" + " bclr #7,%@\n" + " pmove %@,%%tc\n" + " jmp %0@\n" + : /* no outputs */ + : "a" (jmp_addr)); +jmp_addr_label040: + /* disable translation on '040 now */ + asm volatile ("\n" + " moveq #0,%%d0\n" + " .chip 68040\n" + " movec %%d0,%%tc\n" /* disable MMU */ + " .chip 68k\n" + : /* no outputs */ + : /* no inputs */ + : "d0"); + + jmp_addr_label: + /* pickup reset address from AmigaOS ROM, reset devices and jump + * to reset address + */ + asm volatile ("\n" + " move.w #0x2700,%sr\n" + " lea 0x01000000,%a0\n" + " sub.l %a0@(-0x14),%a0\n" + " move.l %a0@(4),%a0\n" + " subq.l #2,%a0\n" + " jra 1f\n" + /* align on a longword boundary */ + " " __ALIGN_STR "\n" + "1:\n" + " reset\n" + " jmp %a0@"); + + for (;;) + ; } @@ -773,11 +769,11 @@ static void amiga_reset (void) #define SAVEKMSG_MAGIC2 0x4B4D5347 /* 'KMSG' */ struct savekmsg { - unsigned long magic1; /* SAVEKMSG_MAGIC1 */ - unsigned long magic2; /* SAVEKMSG_MAGIC2 */ - unsigned long magicptr; /* address of magic1 */ - unsigned long size; - char data[0]; + unsigned long magic1; /* SAVEKMSG_MAGIC1 */ + unsigned long magic2; /* SAVEKMSG_MAGIC2 */ + unsigned long magicptr; /* address of magic1 */ + unsigned long size; + char data[0]; }; static struct savekmsg *savekmsg; @@ -785,100 +781,100 @@ static struct savekmsg *savekmsg; static void amiga_mem_console_write(struct console *co, const char *s, unsigned int count) { - if (savekmsg->size+count <= SAVEKMSG_MAXMEM-sizeof(struct savekmsg)) { - memcpy(savekmsg->data+savekmsg->size, s, count); - savekmsg->size += count; - } + if (savekmsg->size + count <= SAVEKMSG_MAXMEM-sizeof(struct savekmsg)) { + memcpy(savekmsg->data + savekmsg->size, s, count); + savekmsg->size += count; + } } static void amiga_savekmsg_init(void) { - static struct resource debug_res = { .name = "Debug" }; + static struct resource debug_res = { .name = "Debug" }; - savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res); - savekmsg->magic1 = SAVEKMSG_MAGIC1; - savekmsg->magic2 = SAVEKMSG_MAGIC2; - savekmsg->magicptr = ZTWO_PADDR(savekmsg); - savekmsg->size = 0; + savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res); + savekmsg->magic1 = SAVEKMSG_MAGIC1; + savekmsg->magic2 = SAVEKMSG_MAGIC2; + savekmsg->magicptr = ZTWO_PADDR(savekmsg); + savekmsg->size = 0; } static void amiga_serial_putc(char c) { - amiga_custom.serdat = (unsigned char)c | 0x100; - while (!(amiga_custom.serdatr & 0x2000)) - ; + amiga_custom.serdat = (unsigned char)c | 0x100; + while (!(amiga_custom.serdatr & 0x2000)) + ; } void amiga_serial_console_write(struct console *co, const char *s, - unsigned int count) + unsigned int count) { - while (count--) { - if (*s == '\n') - amiga_serial_putc('\r'); - amiga_serial_putc(*s++); - } + while (count--) { + if (*s == '\n') + amiga_serial_putc('\r'); + amiga_serial_putc(*s++); + } } #ifdef CONFIG_SERIAL_CONSOLE void amiga_serial_puts(const char *s) { - amiga_serial_console_write(NULL, s, strlen(s)); + amiga_serial_console_write(NULL, s, strlen(s)); } int amiga_serial_console_wait_key(struct console *co) { - int ch; - - while (!(amiga_custom.intreqr & IF_RBF)) - barrier(); - ch = amiga_custom.serdatr & 0xff; - /* clear the interrupt, so that another character can be read */ - amiga_custom.intreq = IF_RBF; - return ch; + int ch; + + while (!(amiga_custom.intreqr & IF_RBF)) + barrier(); + ch = amiga_custom.serdatr & 0xff; + /* clear the interrupt, so that another character can be read */ + amiga_custom.intreq = IF_RBF; + return ch; } void amiga_serial_gets(struct console *co, char *s, int len) { - int ch, cnt = 0; - - while (1) { - ch = amiga_serial_console_wait_key(co); - - /* Check for backspace. */ - if (ch == 8 || ch == 127) { - if (cnt == 0) { - amiga_serial_putc('\007'); - continue; - } - cnt--; - amiga_serial_puts("\010 \010"); - continue; - } + int ch, cnt = 0; + + while (1) { + ch = amiga_serial_console_wait_key(co); + + /* Check for backspace. */ + if (ch == 8 || ch == 127) { + if (cnt == 0) { + amiga_serial_putc('\007'); + continue; + } + cnt--; + amiga_serial_puts("\010 \010"); + continue; + } - /* Check for enter. */ - if (ch == 10 || ch == 13) - break; + /* Check for enter. */ + if (ch == 10 || ch == 13) + break; - /* See if line is too long. */ - if (cnt >= len + 1) { - amiga_serial_putc(7); - cnt--; - continue; - } + /* See if line is too long. */ + if (cnt >= len + 1) { + amiga_serial_putc(7); + cnt--; + continue; + } - /* Store and echo character. */ - s[cnt++] = ch; - amiga_serial_putc(ch); - } - /* Print enter. */ - amiga_serial_puts("\r\n"); - s[cnt] = 0; + /* Store and echo character. */ + s[cnt++] = ch; + amiga_serial_putc(ch); + } + /* Print enter. */ + amiga_serial_puts("\r\n"); + s[cnt] = 0; } #endif static void __init amiga_debug_init(void) { - if (!strcmp( m68k_debug_device, "ser" )) { + if (!strcmp(m68k_debug_device, "ser" )) { /* no initialization required (?) */ amiga_console_driver.write = amiga_serial_console_write; register_console(&amiga_console_driver); @@ -888,10 +884,10 @@ static void __init amiga_debug_init(void) #ifdef CONFIG_HEARTBEAT static void amiga_heartbeat(int on) { - if (on) - ciaa.pra &= ~2; - else - ciaa.pra |= 2; + if (on) + ciaa.pra &= ~2; + else + ciaa.pra |= 2; } #endif @@ -901,81 +897,81 @@ static void amiga_heartbeat(int on) static void amiga_get_model(char *model) { - strcpy(model, amiga_model_name); + strcpy(model, amiga_model_name); } static int amiga_get_hardware_list(char *buffer) { - int len = 0; - - if (AMIGAHW_PRESENT(CHIP_RAM)) - len += sprintf(buffer+len, "Chip RAM:\t%ldK\n", amiga_chip_size>>10); - len += sprintf(buffer+len, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n", - amiga_psfreq, amiga_eclock); - if (AMIGAHW_PRESENT(AMI_VIDEO)) { - char *type; - switch(amiga_chipset) { - case CS_OCS: - type = "OCS"; - break; - case CS_ECS: - type = "ECS"; - break; - case CS_AGA: - type = "AGA"; - break; - default: - type = "Old or Unknown"; - break; + int len = 0; + + if (AMIGAHW_PRESENT(CHIP_RAM)) + len += sprintf(buffer+len, "Chip RAM:\t%ldK\n", amiga_chip_size>>10); + len += sprintf(buffer+len, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n", + amiga_psfreq, amiga_eclock); + if (AMIGAHW_PRESENT(AMI_VIDEO)) { + char *type; + switch (amiga_chipset) { + case CS_OCS: + type = "OCS"; + break; + case CS_ECS: + type = "ECS"; + break; + case CS_AGA: + type = "AGA"; + break; + default: + type = "Old or Unknown"; + break; + } + len += sprintf(buffer+len, "Graphics:\t%s\n", type); } - len += sprintf(buffer+len, "Graphics:\t%s\n", type); - } #define AMIGAHW_ANNOUNCE(name, str) \ - if (AMIGAHW_PRESENT(name)) \ - len += sprintf (buffer+len, "\t%s\n", str) - - len += sprintf (buffer + len, "Detected hardware:\n"); - - AMIGAHW_ANNOUNCE(AMI_VIDEO, "Amiga Video"); - AMIGAHW_ANNOUNCE(AMI_BLITTER, "Blitter"); - AMIGAHW_ANNOUNCE(AMBER_FF, "Amber Flicker Fixer"); - AMIGAHW_ANNOUNCE(AMI_AUDIO, "Amiga Audio"); - AMIGAHW_ANNOUNCE(AMI_FLOPPY, "Floppy Controller"); - AMIGAHW_ANNOUNCE(A3000_SCSI, "SCSI Controller WD33C93 (A3000 style)"); - AMIGAHW_ANNOUNCE(A4000_SCSI, "SCSI Controller NCR53C710 (A4000T style)"); - AMIGAHW_ANNOUNCE(A1200_IDE, "IDE Interface (A1200 style)"); - AMIGAHW_ANNOUNCE(A4000_IDE, "IDE Interface (A4000 style)"); - AMIGAHW_ANNOUNCE(CD_ROM, "Internal CD ROM drive"); - AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "Keyboard"); - AMIGAHW_ANNOUNCE(AMI_MOUSE, "Mouse Port"); - AMIGAHW_ANNOUNCE(AMI_SERIAL, "Serial Port"); - AMIGAHW_ANNOUNCE(AMI_PARALLEL, "Parallel Port"); - AMIGAHW_ANNOUNCE(A2000_CLK, "Hardware Clock (A2000 style)"); - AMIGAHW_ANNOUNCE(A3000_CLK, "Hardware Clock (A3000 style)"); - AMIGAHW_ANNOUNCE(CHIP_RAM, "Chip RAM"); - AMIGAHW_ANNOUNCE(PAULA, "Paula 8364"); - AMIGAHW_ANNOUNCE(DENISE, "Denise 8362"); - AMIGAHW_ANNOUNCE(DENISE_HR, "Denise 8373"); - AMIGAHW_ANNOUNCE(LISA, "Lisa 8375"); - AMIGAHW_ANNOUNCE(AGNUS_PAL, "Normal/Fat PAL Agnus 8367/8371"); - AMIGAHW_ANNOUNCE(AGNUS_NTSC, "Normal/Fat NTSC Agnus 8361/8370"); - AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "Fat Hires PAL Agnus 8372"); - AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "Fat Hires NTSC Agnus 8372"); - AMIGAHW_ANNOUNCE(ALICE_PAL, "PAL Alice 8374"); - AMIGAHW_ANNOUNCE(ALICE_NTSC, "NTSC Alice 8374"); - AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick"); - AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot"); + if (AMIGAHW_PRESENT(name)) \ + len += sprintf (buffer+len, "\t%s\n", str) + + len += sprintf (buffer + len, "Detected hardware:\n"); + + AMIGAHW_ANNOUNCE(AMI_VIDEO, "Amiga Video"); + AMIGAHW_ANNOUNCE(AMI_BLITTER, "Blitter"); + AMIGAHW_ANNOUNCE(AMBER_FF, "Amber Flicker Fixer"); + AMIGAHW_ANNOUNCE(AMI_AUDIO, "Amiga Audio"); + AMIGAHW_ANNOUNCE(AMI_FLOPPY, "Floppy Controller"); + AMIGAHW_ANNOUNCE(A3000_SCSI, "SCSI Controller WD33C93 (A3000 style)"); + AMIGAHW_ANNOUNCE(A4000_SCSI, "SCSI Controller NCR53C710 (A4000T style)"); + AMIGAHW_ANNOUNCE(A1200_IDE, "IDE Interface (A1200 style)"); + AMIGAHW_ANNOUNCE(A4000_IDE, "IDE Interface (A4000 style)"); + AMIGAHW_ANNOUNCE(CD_ROM, "Internal CD ROM drive"); + AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "Keyboard"); + AMIGAHW_ANNOUNCE(AMI_MOUSE, "Mouse Port"); + AMIGAHW_ANNOUNCE(AMI_SERIAL, "Serial Port"); + AMIGAHW_ANNOUNCE(AMI_PARALLEL, "Parallel Port"); + AMIGAHW_ANNOUNCE(A2000_CLK, "Hardware Clock (A2000 style)"); + AMIGAHW_ANNOUNCE(A3000_CLK, "Hardware Clock (A3000 style)"); + AMIGAHW_ANNOUNCE(CHIP_RAM, "Chip RAM"); + AMIGAHW_ANNOUNCE(PAULA, "Paula 8364"); + AMIGAHW_ANNOUNCE(DENISE, "Denise 8362"); + AMIGAHW_ANNOUNCE(DENISE_HR, "Denise 8373"); + AMIGAHW_ANNOUNCE(LISA, "Lisa 8375"); + AMIGAHW_ANNOUNCE(AGNUS_PAL, "Normal/Fat PAL Agnus 8367/8371"); + AMIGAHW_ANNOUNCE(AGNUS_NTSC, "Normal/Fat NTSC Agnus 8361/8370"); + AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "Fat Hires PAL Agnus 8372"); + AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "Fat Hires NTSC Agnus 8372"); + AMIGAHW_ANNOUNCE(ALICE_PAL, "PAL Alice 8374"); + AMIGAHW_ANNOUNCE(ALICE_NTSC, "NTSC Alice 8374"); + AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick"); + AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot"); #ifdef CONFIG_ZORRO - if (AMIGAHW_PRESENT(ZORRO)) - len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion " - "Device%s\n", - AMIGAHW_PRESENT(ZORRO3) ? "I" : "", - zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s"); + if (AMIGAHW_PRESENT(ZORRO)) + len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion " + "Device%s\n", + AMIGAHW_PRESENT(ZORRO3) ? "I" : "", + zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s"); #endif /* CONFIG_ZORRO */ #undef AMIGAHW_ANNOUNCE - return(len); + return len; } diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c index ca5cd4344e3d..b10e7addae5c 100644 --- a/arch/m68k/atari/config.c +++ b/arch/m68k/atari/config.c @@ -50,19 +50,19 @@ int atari_dont_touch_floppy_select; int atari_rtc_year_offset; /* local function prototypes */ -static void atari_reset( void ); +static void atari_reset(void); static void atari_get_model(char *model); static int atari_get_hardware_list(char *buffer); /* atari specific irq functions */ extern void atari_init_IRQ (void); -extern void atari_mksound( unsigned int count, unsigned int ticks ); +extern void atari_mksound(unsigned int count, unsigned int ticks); #ifdef CONFIG_HEARTBEAT -static void atari_heartbeat( int on ); +static void atari_heartbeat(int on); #endif /* atari specific timer functions (in time.c) */ -extern void atari_sched_init(irq_handler_t ); +extern void atari_sched_init(irq_handler_t); extern unsigned long atari_gettimeoffset (void); extern int atari_mste_hwclk (int, struct rtc_time *); extern int atari_tt_hwclk (int, struct rtc_time *); @@ -73,48 +73,6 @@ extern int atari_tt_set_clock_mmss (unsigned long); extern void atari_debug_init(void); -/* I've moved hwreg_present() and hwreg_present_bywrite() out into - * mm/hwtest.c, to avoid having multiple copies of the same routine - * in the kernel [I wanted them in hp300 and they were already used - * in the nubus code. NB: I don't have an Atari so this might (just - * conceivably) break something. - * I've preserved the #if 0 version of hwreg_present_bywrite() here - * for posterity. - * -- Peter Maydell , 05/1998 - */ - -#if 0 -static int __init -hwreg_present_bywrite(volatile void *regp, unsigned char val) -{ - int ret; - long save_sp, save_vbr; - static long tmp_vectors[3] = { [2] = (long)&&after_test }; - - __asm__ __volatile__ - ( "movec %/vbr,%2\n\t" /* save vbr value */ - "movec %4,%/vbr\n\t" /* set up temporary vectors */ - "movel %/sp,%1\n\t" /* save sp */ - "moveq #0,%0\n\t" /* assume not present */ - "moveb %5,%3@\n\t" /* write the hardware reg */ - "cmpb %3@,%5\n\t" /* compare it */ - "seq %0" /* comes here only if reg */ - /* is present */ - : "=d&" (ret), "=r&" (save_sp), "=r&" (save_vbr) - : "a" (regp), "r" (tmp_vectors), "d" (val) - ); - after_test: - __asm__ __volatile__ - ( "movel %0,%/sp\n\t" /* restore sp */ - "movec %1,%/vbr" /* restore vbr */ - : : "r" (save_sp), "r" (save_vbr) : "sp" - ); - - return( ret ); -} -#endif - - /* ++roman: This is a more elaborate test for an SCC chip, since the plain * Medusa board generates DTACK at the SCC's standard addresses, but a SCC * board in the Medusa is possible. Also, the addresses where the ST_ESCC @@ -123,26 +81,34 @@ hwreg_present_bywrite(volatile void *regp, unsigned char val) * should be readable without trouble (from channel A!). */ -static int __init scc_test( volatile char *ctla ) +static int __init scc_test(volatile char *ctla) { - if (!hwreg_present( ctla )) - return( 0 ); + if (!hwreg_present(ctla)) + return 0; MFPDELAY(); - *ctla = 2; MFPDELAY(); - *ctla = 0x40; MFPDELAY(); + *ctla = 2; + MFPDELAY(); + *ctla = 0x40; + MFPDELAY(); - *ctla = 2; MFPDELAY(); - if (*ctla != 0x40) return( 0 ); + *ctla = 2; + MFPDELAY(); + if (*ctla != 0x40) + return 0; MFPDELAY(); - *ctla = 2; MFPDELAY(); - *ctla = 0x60; MFPDELAY(); + *ctla = 2; + MFPDELAY(); + *ctla = 0x60; + MFPDELAY(); - *ctla = 2; MFPDELAY(); - if (*ctla != 0x60) return( 0 ); + *ctla = 2; + MFPDELAY(); + if (*ctla != 0x60) + return 0; - return( 1 ); + return 1; } @@ -152,59 +118,58 @@ static int __init scc_test( volatile char *ctla ) int __init atari_parse_bootinfo(const struct bi_record *record) { - int unknown = 0; - const u_long *data = record->data; + int unknown = 0; + const u_long *data = record->data; - switch (record->tag) { + switch (record->tag) { case BI_ATARI_MCH_COOKIE: - atari_mch_cookie = *data; - break; + atari_mch_cookie = *data; + break; case BI_ATARI_MCH_TYPE: - atari_mch_type = *data; - break; + atari_mch_type = *data; + break; default: - unknown = 1; - } - return(unknown); + unknown = 1; + break; + } + return unknown; } /* Parse the Atari-specific switches= option. */ -void __init atari_switches_setup( const char *str, unsigned len ) +void __init atari_switches_setup(const char *str, unsigned len) { - char switches[len+1]; - char *p; - int ovsc_shift; - char *args = switches; - - /* copy string to local array, strsep works destructively... */ - strlcpy( switches, str, sizeof(switches) ); - atari_switches = 0; - - /* parse the options */ - while ((p = strsep(&args, ",")) != NULL) { - if (!*p) continue; - ovsc_shift = 0; - if (strncmp( p, "ov_", 3 ) == 0) { - p += 3; - ovsc_shift = ATARI_SWITCH_OVSC_SHIFT; - } - - if (strcmp( p, "ikbd" ) == 0) { - /* RTS line of IKBD ACIA */ - atari_switches |= ATARI_SWITCH_IKBD << ovsc_shift; - } - else if (strcmp( p, "midi" ) == 0) { - /* RTS line of MIDI ACIA */ - atari_switches |= ATARI_SWITCH_MIDI << ovsc_shift; + char switches[len+1]; + char *p; + int ovsc_shift; + char *args = switches; + + /* copy string to local array, strsep works destructively... */ + strlcpy(switches, str, sizeof(switches)); + atari_switches = 0; + + /* parse the options */ + while ((p = strsep(&args, ",")) != NULL) { + if (!*p) + continue; + ovsc_shift = 0; + if (strncmp(p, "ov_", 3) == 0) { + p += 3; + ovsc_shift = ATARI_SWITCH_OVSC_SHIFT; + } + + if (strcmp(p, "ikbd") == 0) { + /* RTS line of IKBD ACIA */ + atari_switches |= ATARI_SWITCH_IKBD << ovsc_shift; + } else if (strcmp(p, "midi") == 0) { + /* RTS line of MIDI ACIA */ + atari_switches |= ATARI_SWITCH_MIDI << ovsc_shift; + } else if (strcmp(p, "snd6") == 0) { + atari_switches |= ATARI_SWITCH_SND6 << ovsc_shift; + } else if (strcmp(p, "snd7") == 0) { + atari_switches |= ATARI_SWITCH_SND7 << ovsc_shift; + } } - else if (strcmp( p, "snd6" ) == 0) { - atari_switches |= ATARI_SWITCH_SND6 << ovsc_shift; - } - else if (strcmp( p, "snd7" ) == 0) { - atari_switches |= ATARI_SWITCH_SND7 << ovsc_shift; - } - } } @@ -214,284 +179,283 @@ void __init atari_switches_setup( const char *str, unsigned len ) void __init config_atari(void) { - unsigned short tos_version; + unsigned short tos_version; - memset(&atari_hw_present, 0, sizeof(atari_hw_present)); + memset(&atari_hw_present, 0, sizeof(atari_hw_present)); - atari_debug_init(); + atari_debug_init(); - ioport_resource.end = 0xFFFFFFFF; /* Change size of I/O space from 64KB - to 4GB. */ + /* Change size of I/O space from 64KB to 4GB. */ + ioport_resource.end = 0xFFFFFFFF; - mach_sched_init = atari_sched_init; - mach_init_IRQ = atari_init_IRQ; - mach_get_model = atari_get_model; - mach_get_hardware_list = atari_get_hardware_list; - mach_gettimeoffset = atari_gettimeoffset; - mach_reset = atari_reset; - mach_max_dma_address = 0xffffff; + mach_sched_init = atari_sched_init; + mach_init_IRQ = atari_init_IRQ; + mach_get_model = atari_get_model; + mach_get_hardware_list = atari_get_hardware_list; + mach_gettimeoffset = atari_gettimeoffset; + mach_reset = atari_reset; + mach_max_dma_address = 0xffffff; #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) - mach_beep = atari_mksound; + mach_beep = atari_mksound; #endif #ifdef CONFIG_HEARTBEAT - mach_heartbeat = atari_heartbeat; + mach_heartbeat = atari_heartbeat; #endif - /* Set switches as requested by the user */ - if (atari_switches & ATARI_SWITCH_IKBD) - acia.key_ctrl = ACIA_DIV64 | ACIA_D8N1S | ACIA_RHTID; - if (atari_switches & ATARI_SWITCH_MIDI) - acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RHTID; - if (atari_switches & (ATARI_SWITCH_SND6|ATARI_SWITCH_SND7)) { - sound_ym.rd_data_reg_sel = 14; - sound_ym.wd_data = sound_ym.rd_data_reg_sel | - ((atari_switches&ATARI_SWITCH_SND6) ? 0x40 : 0) | - ((atari_switches&ATARI_SWITCH_SND7) ? 0x80 : 0); - } - - /* ++bjoern: - * Determine hardware present - */ + /* Set switches as requested by the user */ + if (atari_switches & ATARI_SWITCH_IKBD) + acia.key_ctrl = ACIA_DIV64 | ACIA_D8N1S | ACIA_RHTID; + if (atari_switches & ATARI_SWITCH_MIDI) + acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RHTID; + if (atari_switches & (ATARI_SWITCH_SND6|ATARI_SWITCH_SND7)) { + sound_ym.rd_data_reg_sel = 14; + sound_ym.wd_data = sound_ym.rd_data_reg_sel | + ((atari_switches&ATARI_SWITCH_SND6) ? 0x40 : 0) | + ((atari_switches&ATARI_SWITCH_SND7) ? 0x80 : 0); + } - printk( "Atari hardware found: " ); - if (MACH_IS_MEDUSA || MACH_IS_HADES) { - /* There's no Atari video hardware on the Medusa, but all the - * addresses below generate a DTACK so no bus error occurs! */ - } - else if (hwreg_present( f030_xreg )) { - ATARIHW_SET(VIDEL_SHIFTER); - printk( "VIDEL " ); - /* This is a temporary hack: If there is Falcon video - * hardware, we assume that the ST-DMA serves SCSI instead of - * ACSI. In the future, there should be a better method for - * this... - */ - ATARIHW_SET(ST_SCSI); - printk( "STDMA-SCSI " ); - } - else if (hwreg_present( tt_palette )) { - ATARIHW_SET(TT_SHIFTER); - printk( "TT_SHIFTER " ); - } - else if (hwreg_present( &shifter.bas_hi )) { - if (hwreg_present( &shifter.bas_lo ) && - (shifter.bas_lo = 0x0aau, shifter.bas_lo == 0x0aau)) { - ATARIHW_SET(EXTD_SHIFTER); - printk( "EXTD_SHIFTER " ); - } - else { - ATARIHW_SET(STND_SHIFTER); - printk( "STND_SHIFTER " ); - } - } - if (hwreg_present( &mfp.par_dt_reg )) { - ATARIHW_SET(ST_MFP); - printk( "ST_MFP " ); - } - if (hwreg_present( &tt_mfp.par_dt_reg )) { - ATARIHW_SET(TT_MFP); - printk( "TT_MFP " ); - } - if (hwreg_present( &tt_scsi_dma.dma_addr_hi )) { - ATARIHW_SET(SCSI_DMA); - printk( "TT_SCSI_DMA " ); - } - if (!MACH_IS_HADES && hwreg_present( &st_dma.dma_hi )) { - ATARIHW_SET(STND_DMA); - printk( "STND_DMA " ); - } - if (MACH_IS_MEDUSA || /* The ST-DMA address registers aren't readable - * on all Medusas, so the test below may fail */ - (hwreg_present( &st_dma.dma_vhi ) && - (st_dma.dma_vhi = 0x55) && (st_dma.dma_hi = 0xaa) && - st_dma.dma_vhi == 0x55 && st_dma.dma_hi == 0xaa && - (st_dma.dma_vhi = 0xaa) && (st_dma.dma_hi = 0x55) && - st_dma.dma_vhi == 0xaa && st_dma.dma_hi == 0x55)) { - ATARIHW_SET(EXTD_DMA); - printk( "EXTD_DMA " ); - } - if (hwreg_present( &tt_scsi.scsi_data )) { - ATARIHW_SET(TT_SCSI); - printk( "TT_SCSI " ); - } - if (hwreg_present( &sound_ym.rd_data_reg_sel )) { - ATARIHW_SET(YM_2149); - printk( "YM2149 " ); - } - if (!MACH_IS_MEDUSA && !MACH_IS_HADES && - hwreg_present( &tt_dmasnd.ctrl )) { - ATARIHW_SET(PCM_8BIT); - printk( "PCM " ); - } - if (!MACH_IS_HADES && hwreg_present( &falcon_codec.unused5 )) { - ATARIHW_SET(CODEC); - printk( "CODEC " ); - } - if (hwreg_present( &dsp56k_host_interface.icr )) { - ATARIHW_SET(DSP56K); - printk( "DSP56K " ); - } - if (hwreg_present( &tt_scc_dma.dma_ctrl ) && + /* ++bjoern: + * Determine hardware present + */ + + printk("Atari hardware found: "); + if (MACH_IS_MEDUSA || MACH_IS_HADES) { + /* There's no Atari video hardware on the Medusa, but all the + * addresses below generate a DTACK so no bus error occurs! */ + } else if (hwreg_present(f030_xreg)) { + ATARIHW_SET(VIDEL_SHIFTER); + printk("VIDEL "); + /* This is a temporary hack: If there is Falcon video + * hardware, we assume that the ST-DMA serves SCSI instead of + * ACSI. In the future, there should be a better method for + * this... + */ + ATARIHW_SET(ST_SCSI); + printk("STDMA-SCSI "); + } else if (hwreg_present(tt_palette)) { + ATARIHW_SET(TT_SHIFTER); + printk("TT_SHIFTER "); + } else if (hwreg_present(&shifter.bas_hi)) { + if (hwreg_present(&shifter.bas_lo) && + (shifter.bas_lo = 0x0aau, shifter.bas_lo == 0x0aau)) { + ATARIHW_SET(EXTD_SHIFTER); + printk("EXTD_SHIFTER "); + } else { + ATARIHW_SET(STND_SHIFTER); + printk("STND_SHIFTER "); + } + } + if (hwreg_present(&mfp.par_dt_reg)) { + ATARIHW_SET(ST_MFP); + printk("ST_MFP "); + } + if (hwreg_present(&tt_mfp.par_dt_reg)) { + ATARIHW_SET(TT_MFP); + printk("TT_MFP "); + } + if (hwreg_present(&tt_scsi_dma.dma_addr_hi)) { + ATARIHW_SET(SCSI_DMA); + printk("TT_SCSI_DMA "); + } + if (!MACH_IS_HADES && hwreg_present(&st_dma.dma_hi)) { + ATARIHW_SET(STND_DMA); + printk("STND_DMA "); + } + /* + * The ST-DMA address registers aren't readable + * on all Medusas, so the test below may fail + */ + if (MACH_IS_MEDUSA || + (hwreg_present(&st_dma.dma_vhi) && + (st_dma.dma_vhi = 0x55) && (st_dma.dma_hi = 0xaa) && + st_dma.dma_vhi == 0x55 && st_dma.dma_hi == 0xaa && + (st_dma.dma_vhi = 0xaa) && (st_dma.dma_hi = 0x55) && + st_dma.dma_vhi == 0xaa && st_dma.dma_hi == 0x55)) { + ATARIHW_SET(EXTD_DMA); + printk("EXTD_DMA "); + } + if (hwreg_present(&tt_scsi.scsi_data)) { + ATARIHW_SET(TT_SCSI); + printk("TT_SCSI "); + } + if (hwreg_present(&sound_ym.rd_data_reg_sel)) { + ATARIHW_SET(YM_2149); + printk("YM2149 "); + } + if (!MACH_IS_MEDUSA && !MACH_IS_HADES && + hwreg_present(&tt_dmasnd.ctrl)) { + ATARIHW_SET(PCM_8BIT); + printk("PCM "); + } + if (!MACH_IS_HADES && hwreg_present(&falcon_codec.unused5)) { + ATARIHW_SET(CODEC); + printk("CODEC "); + } + if (hwreg_present(&dsp56k_host_interface.icr)) { + ATARIHW_SET(DSP56K); + printk("DSP56K "); + } + if (hwreg_present(&tt_scc_dma.dma_ctrl) && #if 0 - /* This test sucks! Who knows some better? */ - (tt_scc_dma.dma_ctrl = 0x01, (tt_scc_dma.dma_ctrl & 1) == 1) && - (tt_scc_dma.dma_ctrl = 0x00, (tt_scc_dma.dma_ctrl & 1) == 0) + /* This test sucks! Who knows some better? */ + (tt_scc_dma.dma_ctrl = 0x01, (tt_scc_dma.dma_ctrl & 1) == 1) && + (tt_scc_dma.dma_ctrl = 0x00, (tt_scc_dma.dma_ctrl & 1) == 0) #else - !MACH_IS_MEDUSA && !MACH_IS_HADES + !MACH_IS_MEDUSA && !MACH_IS_HADES #endif - ) { - ATARIHW_SET(SCC_DMA); - printk( "SCC_DMA " ); - } - if (scc_test( &scc.cha_a_ctrl )) { - ATARIHW_SET(SCC); - printk( "SCC " ); - } - if (scc_test( &st_escc.cha_b_ctrl )) { - ATARIHW_SET( ST_ESCC ); - printk( "ST_ESCC " ); - } - if (MACH_IS_HADES) - { - ATARIHW_SET( VME ); - printk( "VME " ); - } - else if (hwreg_present( &tt_scu.sys_mask )) { - ATARIHW_SET(SCU); - /* Assume a VME bus if there's a SCU */ - ATARIHW_SET( VME ); - printk( "VME SCU " ); - } - if (hwreg_present( (void *)(0xffff9210) )) { - ATARIHW_SET(ANALOG_JOY); - printk( "ANALOG_JOY " ); - } - if (!MACH_IS_HADES && hwreg_present( blitter.halftone )) { - ATARIHW_SET(BLITTER); - printk( "BLITTER " ); - } - if (hwreg_present((void *)0xfff00039)) { - ATARIHW_SET(IDE); - printk( "IDE " ); - } + ) { + ATARIHW_SET(SCC_DMA); + printk("SCC_DMA "); + } + if (scc_test(&scc.cha_a_ctrl)) { + ATARIHW_SET(SCC); + printk("SCC "); + } + if (scc_test(&st_escc.cha_b_ctrl)) { + ATARIHW_SET(ST_ESCC); + printk("ST_ESCC "); + } + if (MACH_IS_HADES) { + ATARIHW_SET(VME); + printk("VME "); + } else if (hwreg_present(&tt_scu.sys_mask)) { + ATARIHW_SET(SCU); + /* Assume a VME bus if there's a SCU */ + ATARIHW_SET(VME); + printk("VME SCU "); + } + if (hwreg_present((void *)(0xffff9210))) { + ATARIHW_SET(ANALOG_JOY); + printk("ANALOG_JOY "); + } + if (!MACH_IS_HADES && hwreg_present(blitter.halftone)) { + ATARIHW_SET(BLITTER); + printk("BLITTER "); + } + if (hwreg_present((void *)0xfff00039)) { + ATARIHW_SET(IDE); + printk("IDE "); + } #if 1 /* This maybe wrong */ - if (!MACH_IS_MEDUSA && !MACH_IS_HADES && - hwreg_present( &tt_microwire.data ) && - hwreg_present( &tt_microwire.mask ) && - (tt_microwire.mask = 0x7ff, - udelay(1), - tt_microwire.data = MW_LM1992_PSG_HIGH | MW_LM1992_ADDR, - udelay(1), - tt_microwire.data != 0)) { - ATARIHW_SET(MICROWIRE); - while (tt_microwire.mask != 0x7ff) ; - printk( "MICROWIRE " ); - } + if (!MACH_IS_MEDUSA && !MACH_IS_HADES && + hwreg_present(&tt_microwire.data) && + hwreg_present(&tt_microwire.mask) && + (tt_microwire.mask = 0x7ff, + udelay(1), + tt_microwire.data = MW_LM1992_PSG_HIGH | MW_LM1992_ADDR, + udelay(1), + tt_microwire.data != 0)) { + ATARIHW_SET(MICROWIRE); + while (tt_microwire.mask != 0x7ff) + ; + printk("MICROWIRE "); + } #endif - if (hwreg_present( &tt_rtc.regsel )) { - ATARIHW_SET(TT_CLK); - printk( "TT_CLK " ); - mach_hwclk = atari_tt_hwclk; - mach_set_clock_mmss = atari_tt_set_clock_mmss; - } - if (!MACH_IS_HADES && hwreg_present( &mste_rtc.sec_ones)) { - ATARIHW_SET(MSTE_CLK); - printk( "MSTE_CLK "); - mach_hwclk = atari_mste_hwclk; - mach_set_clock_mmss = atari_mste_set_clock_mmss; - } - if (!MACH_IS_MEDUSA && !MACH_IS_HADES && - hwreg_present( &dma_wd.fdc_speed ) && - hwreg_write( &dma_wd.fdc_speed, 0 )) { - ATARIHW_SET(FDCSPEED); - printk( "FDC_SPEED "); - } - if (!MACH_IS_HADES && !ATARIHW_PRESENT(ST_SCSI)) { - ATARIHW_SET(ACSI); - printk( "ACSI " ); - } - printk("\n"); - - if (CPU_IS_040_OR_060) - /* Now it seems to be safe to turn of the tt0 transparent - * translation (the one that must not be turned off in - * head.S...) - */ - __asm__ volatile ("moveq #0,%/d0\n\t" - ".chip 68040\n\t" - "movec %%d0,%%itt0\n\t" - "movec %%d0,%%dtt0\n\t" - ".chip 68k" - : /* no outputs */ - : /* no inputs */ - : "d0"); - - /* allocator for memory that must reside in st-ram */ - atari_stram_init (); - - /* Set up a mapping for the VMEbus address region: - * - * VME is either at phys. 0xfexxxxxx (TT) or 0xa00000..0xdfffff - * (MegaSTE) In both cases, the whole 16 MB chunk is mapped at - * 0xfe000000 virt., because this can be done with a single - * transparent translation. On the 68040, lots of often unused - * page tables would be needed otherwise. On a MegaSTE or similar, - * the highest byte is stripped off by hardware due to the 24 bit - * design of the bus. - */ + if (hwreg_present(&tt_rtc.regsel)) { + ATARIHW_SET(TT_CLK); + printk("TT_CLK "); + mach_hwclk = atari_tt_hwclk; + mach_set_clock_mmss = atari_tt_set_clock_mmss; + } + if (!MACH_IS_HADES && hwreg_present(&mste_rtc.sec_ones)) { + ATARIHW_SET(MSTE_CLK); + printk("MSTE_CLK "); + mach_hwclk = atari_mste_hwclk; + mach_set_clock_mmss = atari_mste_set_clock_mmss; + } + if (!MACH_IS_MEDUSA && !MACH_IS_HADES && + hwreg_present(&dma_wd.fdc_speed) && + hwreg_write(&dma_wd.fdc_speed, 0)) { + ATARIHW_SET(FDCSPEED); + printk("FDC_SPEED "); + } + if (!MACH_IS_HADES && !ATARIHW_PRESENT(ST_SCSI)) { + ATARIHW_SET(ACSI); + printk("ACSI "); + } + printk("\n"); + + if (CPU_IS_040_OR_060) + /* Now it seems to be safe to turn of the tt0 transparent + * translation (the one that must not be turned off in + * head.S...) + */ + asm volatile ("\n" + " moveq #0,%%d0\n" + " .chip 68040\n" + " movec %%d0,%%itt0\n" + " movec %%d0,%%dtt0\n" + " .chip 68k" + : /* no outputs */ + : /* no inputs */ + : "d0"); + + /* allocator for memory that must reside in st-ram */ + atari_stram_init(); + + /* Set up a mapping for the VMEbus address region: + * + * VME is either at phys. 0xfexxxxxx (TT) or 0xa00000..0xdfffff + * (MegaSTE) In both cases, the whole 16 MB chunk is mapped at + * 0xfe000000 virt., because this can be done with a single + * transparent translation. On the 68040, lots of often unused + * page tables would be needed otherwise. On a MegaSTE or similar, + * the highest byte is stripped off by hardware due to the 24 bit + * design of the bus. + */ + + if (CPU_IS_020_OR_030) { + unsigned long tt1_val; + tt1_val = 0xfe008543; /* Translate 0xfexxxxxx, enable, cache + * inhibit, read and write, FDC mask = 3, + * FDC val = 4 -> Supervisor only */ + asm volatile ("\n" + " .chip 68030\n" + " pmove %0@,%/tt1\n" + " .chip 68k" + : : "a" (&tt1_val)); + } else { + asm volatile ("\n" + " .chip 68040\n" + " movec %0,%%itt1\n" + " movec %0,%%dtt1\n" + " .chip 68k" + : + : "d" (0xfe00a040)); /* Translate 0xfexxxxxx, enable, + * supervisor only, non-cacheable/ + * serialized, writable */ + + } - if (CPU_IS_020_OR_030) { - unsigned long tt1_val; - tt1_val = 0xfe008543; /* Translate 0xfexxxxxx, enable, cache - * inhibit, read and write, FDC mask = 3, - * FDC val = 4 -> Supervisor only */ - __asm__ __volatile__ ( ".chip 68030\n\t" - "pmove %0@,%/tt1\n\t" - ".chip 68k" - : : "a" (&tt1_val) ); - } - else { - __asm__ __volatile__ - ( "movel %0,%/d0\n\t" - ".chip 68040\n\t" - "movec %%d0,%%itt1\n\t" - "movec %%d0,%%dtt1\n\t" - ".chip 68k" - : - : "g" (0xfe00a040) /* Translate 0xfexxxxxx, enable, - * supervisor only, non-cacheable/ - * serialized, writable */ - : "d0" ); - - } - - /* Fetch tos version at Physical 2 */ - /* We my not be able to access this address if the kernel is - loaded to st ram, since the first page is unmapped. On the - Medusa this is always the case and there is nothing we can do - about this, so we just assume the smaller offset. For the TT - we use the fact that in head.S we have set up a mapping - 0xFFxxxxxx -> 0x00xxxxxx, so that the first 16MB is accessible - in the last 16MB of the address space. */ - tos_version = (MACH_IS_MEDUSA || MACH_IS_HADES) ? - 0xfff : *(unsigned short *)0xff000002; - atari_rtc_year_offset = (tos_version < 0x306) ? 70 : 68; + /* Fetch tos version at Physical 2 */ + /* + * We my not be able to access this address if the kernel is + * loaded to st ram, since the first page is unmapped. On the + * Medusa this is always the case and there is nothing we can do + * about this, so we just assume the smaller offset. For the TT + * we use the fact that in head.S we have set up a mapping + * 0xFFxxxxxx -> 0x00xxxxxx, so that the first 16MB is accessible + * in the last 16MB of the address space. + */ + tos_version = (MACH_IS_MEDUSA || MACH_IS_HADES) ? + 0xfff : *(unsigned short *)0xff000002; + atari_rtc_year_offset = (tos_version < 0x306) ? 70 : 68; } #ifdef CONFIG_HEARTBEAT -static void atari_heartbeat( int on ) +static void atari_heartbeat(int on) { - unsigned char tmp; - unsigned long flags; + unsigned char tmp; + unsigned long flags; - if (atari_dont_touch_floppy_select) - return; + if (atari_dont_touch_floppy_select) + return; - local_irq_save(flags); - sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */ - tmp = sound_ym.rd_data_reg_sel; - sound_ym.wd_data = on ? (tmp & ~0x02) : (tmp | 0x02); - local_irq_restore(flags); + local_irq_save(flags); + sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */ + tmp = sound_ym.rd_data_reg_sel; + sound_ym.wd_data = on ? (tmp & ~0x02) : (tmp | 0x02); + local_irq_restore(flags); } #endif @@ -526,180 +490,171 @@ static void atari_heartbeat( int on ) /* ++andreas: no need for complicated code, just depend on prefetch */ -static void atari_reset (void) +static void atari_reset(void) { - long tc_val = 0; - long reset_addr; - - /* On the Medusa, phys. 0x4 may contain garbage because it's no - ROM. See above for explanation why we cannot use PTOV(4). */ - reset_addr = MACH_IS_HADES ? 0x7fe00030 : - MACH_IS_MEDUSA || MACH_IS_AB40 ? 0xe00030 : - *(unsigned long *) 0xff000004; - - /* reset ACIA for switch off OverScan, if it's active */ - if (atari_switches & ATARI_SWITCH_OVSC_IKBD) - acia.key_ctrl = ACIA_RESET; - if (atari_switches & ATARI_SWITCH_OVSC_MIDI) - acia.mid_ctrl = ACIA_RESET; - - /* processor independent: turn off interrupts and reset the VBR; - * the caches must be left enabled, else prefetching the final jump - * instruction doesn't work. */ - local_irq_disable(); - __asm__ __volatile__ - ("moveq #0,%/d0\n\t" - "movec %/d0,%/vbr" - : : : "d0" ); - - if (CPU_IS_040_OR_060) { - unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040); - if (CPU_IS_060) { - /* 68060: clear PCR to turn off superscalar operation */ - __asm__ __volatile__ - ("moveq #0,%/d0\n\t" - ".chip 68060\n\t" - "movec %%d0,%%pcr\n\t" - ".chip 68k" - : : : "d0" ); - } - - __asm__ __volatile__ - ("movel %0,%/d0\n\t" - "andl #0xff000000,%/d0\n\t" - "orw #0xe020,%/d0\n\t" /* map 16 MB, enable, cacheable */ - ".chip 68040\n\t" - "movec %%d0,%%itt0\n\t" - "movec %%d0,%%dtt0\n\t" - ".chip 68k\n\t" - "jmp %0@\n\t" - : /* no outputs */ - : "a" (jmp_addr040) - : "d0" ); - jmp_addr_label040: - __asm__ __volatile__ - ("moveq #0,%/d0\n\t" - "nop\n\t" - ".chip 68040\n\t" - "cinva %%bc\n\t" - "nop\n\t" - "pflusha\n\t" - "nop\n\t" - "movec %%d0,%%tc\n\t" - "nop\n\t" - /* the following setup of transparent translations is needed on the - * Afterburner040 to successfully reboot. Other machines shouldn't - * care about a different tt regs setup, they also didn't care in - * the past that the regs weren't turned off. */ - "movel #0xffc000,%%d0\n\t" /* whole insn space cacheable */ - "movec %%d0,%%itt0\n\t" - "movec %%d0,%%itt1\n\t" - "orw #0x40,%/d0\n\t" /* whole data space non-cacheable/ser. */ - "movec %%d0,%%dtt0\n\t" - "movec %%d0,%%dtt1\n\t" - ".chip 68k\n\t" - "jmp %0@" - : /* no outputs */ - : "a" (reset_addr) - : "d0"); - } - else - __asm__ __volatile__ - ("pmove %0@,%/tc\n\t" - "jmp %1@" - : /* no outputs */ - : "a" (&tc_val), "a" (reset_addr)); + long tc_val = 0; + long reset_addr; + + /* + * On the Medusa, phys. 0x4 may contain garbage because it's no + * ROM. See above for explanation why we cannot use PTOV(4). + */ + reset_addr = MACH_IS_HADES ? 0x7fe00030 : + MACH_IS_MEDUSA || MACH_IS_AB40 ? 0xe00030 : + *(unsigned long *) 0xff000004; + + /* reset ACIA for switch off OverScan, if it's active */ + if (atari_switches & ATARI_SWITCH_OVSC_IKBD) + acia.key_ctrl = ACIA_RESET; + if (atari_switches & ATARI_SWITCH_OVSC_MIDI) + acia.mid_ctrl = ACIA_RESET; + + /* processor independent: turn off interrupts and reset the VBR; + * the caches must be left enabled, else prefetching the final jump + * instruction doesn't work. + */ + local_irq_disable(); + asm volatile ("movec %0,%%vbr" + : : "d" (0)); + + if (CPU_IS_040_OR_060) { + unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040); + if (CPU_IS_060) { + /* 68060: clear PCR to turn off superscalar operation */ + asm volatile ("\n" + " .chip 68060\n" + " movec %0,%%pcr\n" + " .chip 68k" + : : "d" (0)); + } + + asm volatile ("\n" + " move.l %0,%%d0\n" + " and.l #0xff000000,%%d0\n" + " or.w #0xe020,%%d0\n" /* map 16 MB, enable, cacheable */ + " .chip 68040\n" + " movec %%d0,%%itt0\n" + " movec %%d0,%%dtt0\n" + " .chip 68k\n" + " jmp %0@" + : : "a" (jmp_addr040) + : "d0"); + jmp_addr_label040: + asm volatile ("\n" + " moveq #0,%%d0\n" + " nop\n" + " .chip 68040\n" + " cinva %%bc\n" + " nop\n" + " pflusha\n" + " nop\n" + " movec %%d0,%%tc\n" + " nop\n" + /* the following setup of transparent translations is needed on the + * Afterburner040 to successfully reboot. Other machines shouldn't + * care about a different tt regs setup, they also didn't care in + * the past that the regs weren't turned off. */ + " move.l #0xffc000,%%d0\n" /* whole insn space cacheable */ + " movec %%d0,%%itt0\n" + " movec %%d0,%%itt1\n" + " or.w #0x40,%/d0\n" /* whole data space non-cacheable/ser. */ + " movec %%d0,%%dtt0\n" + " movec %%d0,%%dtt1\n" + " .chip 68k\n" + " jmp %0@" + : /* no outputs */ + : "a" (reset_addr) + : "d0"); + } else + asm volatile ("\n" + " pmove %0@,%%tc\n" + " jmp %1@" + : /* no outputs */ + : "a" (&tc_val), "a" (reset_addr)); } static void atari_get_model(char *model) { - strcpy(model, "Atari "); - switch (atari_mch_cookie >> 16) { + strcpy(model, "Atari "); + switch (atari_mch_cookie >> 16) { case ATARI_MCH_ST: - if (ATARIHW_PRESENT(MSTE_CLK)) - strcat (model, "Mega ST"); - else - strcat (model, "ST"); - break; + if (ATARIHW_PRESENT(MSTE_CLK)) + strcat(model, "Mega ST"); + else + strcat(model, "ST"); + break; case ATARI_MCH_STE: - if (MACH_IS_MSTE) - strcat (model, "Mega STE"); - else - strcat (model, "STE"); - break; + if (MACH_IS_MSTE) + strcat(model, "Mega STE"); + else + strcat(model, "STE"); + break; case ATARI_MCH_TT: - if (MACH_IS_MEDUSA) - /* Medusa has TT _MCH cookie */ - strcat (model, "Medusa"); - else if (MACH_IS_HADES) - strcat(model, "Hades"); - else - strcat (model, "TT"); - break; + if (MACH_IS_MEDUSA) + /* Medusa has TT _MCH cookie */ + strcat(model, "Medusa"); + else if (MACH_IS_HADES) + strcat(model, "Hades"); + else + strcat(model, "TT"); + break; case ATARI_MCH_FALCON: - strcat (model, "Falcon"); - if (MACH_IS_AB40) - strcat (model, " (with Afterburner040)"); - break; + strcat(model, "Falcon"); + if (MACH_IS_AB40) + strcat(model, " (with Afterburner040)"); + break; default: - sprintf (model + strlen (model), "(unknown mach cookie 0x%lx)", - atari_mch_cookie); - break; - } + sprintf(model + strlen(model), "(unknown mach cookie 0x%lx)", + atari_mch_cookie); + break; + } } static int atari_get_hardware_list(char *buffer) { - int len = 0, i; - - for (i = 0; i < m68k_num_memory; i++) - len += sprintf (buffer+len, "\t%3ld MB at 0x%08lx (%s)\n", - m68k_memory[i].size >> 20, m68k_memory[i].addr, - (m68k_memory[i].addr & 0xff000000 ? - "alternate RAM" : "ST-RAM")); - -#define ATARIHW_ANNOUNCE(name,str) \ - if (ATARIHW_PRESENT(name)) \ - len += sprintf (buffer + len, "\t%s\n", str) - - len += sprintf (buffer + len, "Detected hardware:\n"); - ATARIHW_ANNOUNCE(STND_SHIFTER, "ST Shifter"); - ATARIHW_ANNOUNCE(EXTD_SHIFTER, "STe Shifter"); - ATARIHW_ANNOUNCE(TT_SHIFTER, "TT Shifter"); - ATARIHW_ANNOUNCE(VIDEL_SHIFTER, "Falcon Shifter"); - ATARIHW_ANNOUNCE(YM_2149, "Programmable Sound Generator"); - ATARIHW_ANNOUNCE(PCM_8BIT, "PCM 8 Bit Sound"); - ATARIHW_ANNOUNCE(CODEC, "CODEC Sound"); - ATARIHW_ANNOUNCE(TT_SCSI, "SCSI Controller NCR5380 (TT style)"); - ATARIHW_ANNOUNCE(ST_SCSI, "SCSI Controller NCR5380 (Falcon style)"); - ATARIHW_ANNOUNCE(ACSI, "ACSI Interface"); - ATARIHW_ANNOUNCE(IDE, "IDE Interface"); - ATARIHW_ANNOUNCE(FDCSPEED, "8/16 Mhz Switch for FDC"); - ATARIHW_ANNOUNCE(ST_MFP, "Multi Function Peripheral MFP 68901"); - ATARIHW_ANNOUNCE(TT_MFP, "Second Multi Function Peripheral MFP 68901"); - ATARIHW_ANNOUNCE(SCC, "Serial Communications Controller SCC 8530"); - ATARIHW_ANNOUNCE(ST_ESCC, "Extended Serial Communications Controller SCC 85230"); - ATARIHW_ANNOUNCE(ANALOG_JOY, "Paddle Interface"); - ATARIHW_ANNOUNCE(MICROWIRE, "MICROWIRE(tm) Interface"); - ATARIHW_ANNOUNCE(STND_DMA, "DMA Controller (24 bit)"); - ATARIHW_ANNOUNCE(EXTD_DMA, "DMA Controller (32 bit)"); - ATARIHW_ANNOUNCE(SCSI_DMA, "DMA Controller for NCR5380"); - ATARIHW_ANNOUNCE(SCC_DMA, "DMA Controller for SCC"); - ATARIHW_ANNOUNCE(TT_CLK, "Clock Chip MC146818A"); - ATARIHW_ANNOUNCE(MSTE_CLK, "Clock Chip RP5C15"); - ATARIHW_ANNOUNCE(SCU, "System Control Unit"); - ATARIHW_ANNOUNCE(BLITTER, "Blitter"); - ATARIHW_ANNOUNCE(VME, "VME Bus"); - ATARIHW_ANNOUNCE(DSP56K, "DSP56001 processor"); - - return(len); + int len = 0, i; + + for (i = 0; i < m68k_num_memory; i++) + len += sprintf(buffer+len, "\t%3ld MB at 0x%08lx (%s)\n", + m68k_memory[i].size >> 20, m68k_memory[i].addr, + (m68k_memory[i].addr & 0xff000000 ? + "alternate RAM" : "ST-RAM")); + +#define ATARIHW_ANNOUNCE(name, str) \ + if (ATARIHW_PRESENT(name)) \ + len += sprintf(buffer + len, "\t%s\n", str) + + len += sprintf(buffer + len, "Detected hardware:\n"); + ATARIHW_ANNOUNCE(STND_SHIFTER, "ST Shifter"); + ATARIHW_ANNOUNCE(EXTD_SHIFTER, "STe Shifter"); + ATARIHW_ANNOUNCE(TT_SHIFTER, "TT Shifter"); + ATARIHW_ANNOUNCE(VIDEL_SHIFTER, "Falcon Shifter"); + ATARIHW_ANNOUNCE(YM_2149, "Programmable Sound Generator"); + ATARIHW_ANNOUNCE(PCM_8BIT, "PCM 8 Bit Sound"); + ATARIHW_ANNOUNCE(CODEC, "CODEC Sound"); + ATARIHW_ANNOUNCE(TT_SCSI, "SCSI Controller NCR5380 (TT style)"); + ATARIHW_ANNOUNCE(ST_SCSI, "SCSI Controller NCR5380 (Falcon style)"); + ATARIHW_ANNOUNCE(ACSI, "ACSI Interface"); + ATARIHW_ANNOUNCE(IDE, "IDE Interface"); + ATARIHW_ANNOUNCE(FDCSPEED, "8/16 Mhz Switch for FDC"); + ATARIHW_ANNOUNCE(ST_MFP, "Multi Function Peripheral MFP 68901"); + ATARIHW_ANNOUNCE(TT_MFP, "Second Multi Function Peripheral MFP 68901"); + ATARIHW_ANNOUNCE(SCC, "Serial Communications Controller SCC 8530"); + ATARIHW_ANNOUNCE(ST_ESCC, "Extended Serial Communications Controller SCC 85230"); + ATARIHW_ANNOUNCE(ANALOG_JOY, "Paddle Interface"); + ATARIHW_ANNOUNCE(MICROWIRE, "MICROWIRE(tm) Interface"); + ATARIHW_ANNOUNCE(STND_DMA, "DMA Controller (24 bit)"); + ATARIHW_ANNOUNCE(EXTD_DMA, "DMA Controller (32 bit)"); + ATARIHW_ANNOUNCE(SCSI_DMA, "DMA Controller for NCR5380"); + ATARIHW_ANNOUNCE(SCC_DMA, "DMA Controller for SCC"); + ATARIHW_ANNOUNCE(TT_CLK, "Clock Chip MC146818A"); + ATARIHW_ANNOUNCE(MSTE_CLK, "Clock Chip RP5C15"); + ATARIHW_ANNOUNCE(SCU, "System Control Unit"); + ATARIHW_ANNOUNCE(BLITTER, "Blitter"); + ATARIHW_ANNOUNCE(VME, "VME Bus"); + ATARIHW_ANNOUNCE(DSP56K, "DSP56001 processor"); + + return len; } - -/* - * Local variables: - * c-indent-level: 4 - * tab-width: 8 - * End: - */ diff --git a/arch/m68k/atari/debug.c b/arch/m68k/atari/debug.c index 4ae01004d8dd..66983fe87509 100644 --- a/arch/m68k/atari/debug.c +++ b/arch/m68k/atari/debug.c @@ -30,317 +30,311 @@ int atari_SCC_init_done; int atari_SCC_reset_done; static struct console atari_console_driver = { - .name = "debug", - .flags = CON_PRINTBUFFER, - .index = -1, + .name = "debug", + .flags = CON_PRINTBUFFER, + .index = -1, }; -static inline void ata_mfp_out (char c) +static inline void ata_mfp_out(char c) { - while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */ - barrier (); - mfp.usart_dta = c; + while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */ + barrier(); + mfp.usart_dta = c; } -void atari_mfp_console_write (struct console *co, const char *str, - unsigned int count) +void atari_mfp_console_write(struct console *co, const char *str, + unsigned int count) { - while (count--) { - if (*str == '\n') - ata_mfp_out( '\r' ); - ata_mfp_out( *str++ ); - } + while (count--) { + if (*str == '\n') + ata_mfp_out('\r'); + ata_mfp_out(*str++); + } } -static inline void ata_scc_out (char c) +static inline void ata_scc_out(char c) { - do { + do { + MFPDELAY(); + } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ MFPDELAY(); - } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ - MFPDELAY(); - scc.cha_b_data = c; + scc.cha_b_data = c; } -void atari_scc_console_write (struct console *co, const char *str, - unsigned int count) +void atari_scc_console_write(struct console *co, const char *str, + unsigned int count) { - while (count--) { - if (*str == '\n') - ata_scc_out( '\r' ); - ata_scc_out( *str++ ); - } + while (count--) { + if (*str == '\n') + ata_scc_out('\r'); + ata_scc_out(*str++); + } } -static inline void ata_midi_out (char c) +static inline void ata_midi_out(char c) { - while (!(acia.mid_ctrl & ACIA_TDRE)) /* wait for tx buf empty */ - barrier (); - acia.mid_data = c; + while (!(acia.mid_ctrl & ACIA_TDRE)) /* wait for tx buf empty */ + barrier(); + acia.mid_data = c; } -void atari_midi_console_write (struct console *co, const char *str, - unsigned int count) +void atari_midi_console_write(struct console *co, const char *str, + unsigned int count) { - while (count--) { - if (*str == '\n') - ata_midi_out( '\r' ); - ata_midi_out( *str++ ); - } + while (count--) { + if (*str == '\n') + ata_midi_out('\r'); + ata_midi_out(*str++); + } } -static int ata_par_out (char c) +static int ata_par_out(char c) { - unsigned char tmp; - /* This a some-seconds timeout in case no printer is connected */ - unsigned long i = loops_per_jiffy > 1 ? loops_per_jiffy : 10000000/HZ; - - while( (mfp.par_dt_reg & 1) && --i ) /* wait for BUSY == L */ - ; - if (!i) return( 0 ); - - sound_ym.rd_data_reg_sel = 15; /* select port B */ - sound_ym.wd_data = c; /* put char onto port */ - sound_ym.rd_data_reg_sel = 14; /* select port A */ - tmp = sound_ym.rd_data_reg_sel; - sound_ym.wd_data = tmp & ~0x20; /* set strobe L */ - MFPDELAY(); /* wait a bit */ - sound_ym.wd_data = tmp | 0x20; /* set strobe H */ - return( 1 ); + unsigned char tmp; + /* This a some-seconds timeout in case no printer is connected */ + unsigned long i = loops_per_jiffy > 1 ? loops_per_jiffy : 10000000/HZ; + + while ((mfp.par_dt_reg & 1) && --i) /* wait for BUSY == L */ + ; + if (!i) + return 0; + + sound_ym.rd_data_reg_sel = 15; /* select port B */ + sound_ym.wd_data = c; /* put char onto port */ + sound_ym.rd_data_reg_sel = 14; /* select port A */ + tmp = sound_ym.rd_data_reg_sel; + sound_ym.wd_data = tmp & ~0x20; /* set strobe L */ + MFPDELAY(); /* wait a bit */ + sound_ym.wd_data = tmp | 0x20; /* set strobe H */ + return 1; } -static void atari_par_console_write (struct console *co, const char *str, - unsigned int count) +static void atari_par_console_write(struct console *co, const char *str, + unsigned int count) { - static int printer_present = 1; - - if (!printer_present) - return; + static int printer_present = 1; - while (count--) { - if (*str == '\n') - if (!ata_par_out( '\r' )) { - printer_present = 0; + if (!printer_present) return; - } - if (!ata_par_out( *str++ )) { - printer_present = 0; - return; + + while (count--) { + if (*str == '\n') { + if (!ata_par_out('\r')) { + printer_present = 0; + return; + } + } + if (!ata_par_out(*str++)) { + printer_present = 0; + return; + } } - } } #ifdef CONFIG_SERIAL_CONSOLE int atari_mfp_console_wait_key(struct console *co) { - while( !(mfp.rcv_stat & 0x80) ) /* wait for rx buf filled */ - barrier(); - return( mfp.usart_dta ); + while (!(mfp.rcv_stat & 0x80)) /* wait for rx buf filled */ + barrier(); + return mfp.usart_dta; } int atari_scc_console_wait_key(struct console *co) { - do { + do { + MFPDELAY(); + } while (!(scc.cha_b_ctrl & 0x01)); /* wait for rx buf filled */ MFPDELAY(); - } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */ - MFPDELAY(); - return( scc.cha_b_data ); + return scc.cha_b_data; } int atari_midi_console_wait_key(struct console *co) { - while( !(acia.mid_ctrl & ACIA_RDRF) ) /* wait for rx buf filled */ - barrier(); - return( acia.mid_data ); + while (!(acia.mid_ctrl & ACIA_RDRF)) /* wait for rx buf filled */ + barrier(); + return acia.mid_data; } #endif -/* The following two functions do a quick'n'dirty initialization of the MFP or +/* + * The following two functions do a quick'n'dirty initialization of the MFP or * SCC serial ports. They're used by the debugging interface, kgdb, and the - * serial console code. */ + * serial console code. + */ #ifndef CONFIG_SERIAL_CONSOLE -static void __init atari_init_mfp_port( int cflag ) +static void __init atari_init_mfp_port(int cflag) #else -void atari_init_mfp_port( int cflag ) +void atari_init_mfp_port(int cflag) #endif { - /* timer values for 1200...115200 bps; > 38400 select 110, 134, or 150 - * bps, resp., and work only correct if there's a RSVE or RSSPEED */ - static int baud_table[9] = { 16, 11, 8, 4, 2, 1, 175, 143, 128 }; - int baud = cflag & CBAUD; - int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x04 : 0x06) : 0; - int csize = ((cflag & CSIZE) == CS7) ? 0x20 : 0x00; - - if (cflag & CBAUDEX) - baud += B38400; - if (baud < B1200 || baud > B38400+2) - baud = B9600; /* use default 9600bps for non-implemented rates */ - baud -= B1200; /* baud_table[] starts at 1200bps */ - - mfp.trn_stat &= ~0x01; /* disable TX */ - mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */ - mfp.tim_ct_cd &= 0x70; /* stop timer D */ - mfp.tim_dt_d = baud_table[baud]; - mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ - mfp.trn_stat |= 0x01; /* enable TX */ - - atari_MFP_init_done = 1; + /* + * timer values for 1200...115200 bps; > 38400 select 110, 134, or 150 + * bps, resp., and work only correct if there's a RSVE or RSSPEED + */ + static int baud_table[9] = { 16, 11, 8, 4, 2, 1, 175, 143, 128 }; + int baud = cflag & CBAUD; + int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x04 : 0x06) : 0; + int csize = ((cflag & CSIZE) == CS7) ? 0x20 : 0x00; + + if (cflag & CBAUDEX) + baud += B38400; + if (baud < B1200 || baud > B38400+2) + baud = B9600; /* use default 9600bps for non-implemented rates */ + baud -= B1200; /* baud_table[] starts at 1200bps */ + + mfp.trn_stat &= ~0x01; /* disable TX */ + mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */ + mfp.tim_ct_cd &= 0x70; /* stop timer D */ + mfp.tim_dt_d = baud_table[baud]; + mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ + mfp.trn_stat |= 0x01; /* enable TX */ + + atari_MFP_init_done = 1; } -#define SCC_WRITE(reg,val) \ - do { \ - scc.cha_b_ctrl = (reg); \ - MFPDELAY(); \ - scc.cha_b_ctrl = (val); \ - MFPDELAY(); \ - } while(0) +#define SCC_WRITE(reg, val) \ + do { \ + scc.cha_b_ctrl = (reg); \ + MFPDELAY(); \ + scc.cha_b_ctrl = (val); \ + MFPDELAY(); \ + } while (0) /* loops_per_jiffy isn't initialized yet, so we can't use udelay(). This does a * delay of ~ 60us. */ -#define LONG_DELAY() \ - do { \ - int i; \ - for( i = 100; i > 0; --i ) \ - MFPDELAY(); \ - } while(0) +#define LONG_DELAY() \ + do { \ + int i; \ + for (i = 100; i > 0; --i) \ + MFPDELAY(); \ + } while (0) #ifndef CONFIG_SERIAL_CONSOLE -static void __init atari_init_scc_port( int cflag ) +static void __init atari_init_scc_port(int cflag) #else -void atari_init_scc_port( int cflag ) +void atari_init_scc_port(int cflag) #endif { - extern int atari_SCC_reset_done; - static int clksrc_table[9] = - /* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */ - { 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 }; - static int brgsrc_table[9] = - /* reg 14: 0 = RTxC, 2 = PCLK */ - { 2, 2, 2, 2, 2, 2, 0, 2, 2 }; - static int clkmode_table[9] = - /* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */ - { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 }; - static int div_table[9] = - /* reg12 (BRG low) */ - { 208, 138, 103, 50, 24, 11, 1, 0, 0 }; - - int baud = cflag & CBAUD; - int clksrc, clkmode, div, reg3, reg5; - - if (cflag & CBAUDEX) - baud += B38400; - if (baud < B1200 || baud > B38400+2) - baud = B9600; /* use default 9600bps for non-implemented rates */ - baud -= B1200; /* tables starts at 1200bps */ - - clksrc = clksrc_table[baud]; - clkmode = clkmode_table[baud]; - div = div_table[baud]; - if (ATARIHW_PRESENT(TT_MFP) && baud >= 6) { - /* special treatment for TT, where rates >= 38400 are done via TRxC */ - clksrc = 0x28; /* TRxC */ - clkmode = baud == 6 ? 0xc0 : - baud == 7 ? 0x80 : /* really 76800bps */ - 0x40; /* really 153600bps */ - div = 0; - } - - reg3 = (cflag & CSIZE) == CS8 ? 0xc0 : 0x40; - reg5 = (cflag & CSIZE) == CS8 ? 0x60 : 0x20 | 0x82 /* assert DTR/RTS */; - - (void)scc.cha_b_ctrl; /* reset reg pointer */ - SCC_WRITE( 9, 0xc0 ); /* reset */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCC_WRITE( 4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | - 0x04 /* 1 stopbit */ | - clkmode ); - SCC_WRITE( 3, reg3 ); - SCC_WRITE( 5, reg5 ); - SCC_WRITE( 9, 0 ); /* no interrupts */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCC_WRITE( 10, 0 ); /* NRZ mode */ - SCC_WRITE( 11, clksrc ); /* main clock source */ - SCC_WRITE( 12, div ); /* BRG value */ - SCC_WRITE( 13, 0 ); /* BRG high byte */ - SCC_WRITE( 14, brgsrc_table[baud] ); - SCC_WRITE( 14, brgsrc_table[baud] | (div ? 1 : 0) ); - SCC_WRITE( 3, reg3 | 1 ); - SCC_WRITE( 5, reg5 | 8 ); - - atari_SCC_reset_done = 1; - atari_SCC_init_done = 1; + extern int atari_SCC_reset_done; + static int clksrc_table[9] = + /* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */ + { 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 }; + static int brgsrc_table[9] = + /* reg 14: 0 = RTxC, 2 = PCLK */ + { 2, 2, 2, 2, 2, 2, 0, 2, 2 }; + static int clkmode_table[9] = + /* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */ + { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 }; + static int div_table[9] = + /* reg12 (BRG low) */ + { 208, 138, 103, 50, 24, 11, 1, 0, 0 }; + + int baud = cflag & CBAUD; + int clksrc, clkmode, div, reg3, reg5; + + if (cflag & CBAUDEX) + baud += B38400; + if (baud < B1200 || baud > B38400+2) + baud = B9600; /* use default 9600bps for non-implemented rates */ + baud -= B1200; /* tables starts at 1200bps */ + + clksrc = clksrc_table[baud]; + clkmode = clkmode_table[baud]; + div = div_table[baud]; + if (ATARIHW_PRESENT(TT_MFP) && baud >= 6) { + /* special treatment for TT, where rates >= 38400 are done via TRxC */ + clksrc = 0x28; /* TRxC */ + clkmode = baud == 6 ? 0xc0 : + baud == 7 ? 0x80 : /* really 76800bps */ + 0x40; /* really 153600bps */ + div = 0; + } + + reg3 = (cflag & CSIZE) == CS8 ? 0xc0 : 0x40; + reg5 = (cflag & CSIZE) == CS8 ? 0x60 : 0x20 | 0x82 /* assert DTR/RTS */; + + (void)scc.cha_b_ctrl; /* reset reg pointer */ + SCC_WRITE(9, 0xc0); /* reset */ + LONG_DELAY(); /* extra delay after WR9 access */ + SCC_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) + : 0 | 0x04 /* 1 stopbit */ | clkmode); + SCC_WRITE(3, reg3); + SCC_WRITE(5, reg5); + SCC_WRITE(9, 0); /* no interrupts */ + LONG_DELAY(); /* extra delay after WR9 access */ + SCC_WRITE(10, 0); /* NRZ mode */ + SCC_WRITE(11, clksrc); /* main clock source */ + SCC_WRITE(12, div); /* BRG value */ + SCC_WRITE(13, 0); /* BRG high byte */ + SCC_WRITE(14, brgsrc_table[baud]); + SCC_WRITE(14, brgsrc_table[baud] | (div ? 1 : 0)); + SCC_WRITE(3, reg3 | 1); + SCC_WRITE(5, reg5 | 8); + + atari_SCC_reset_done = 1; + atari_SCC_init_done = 1; } #ifndef CONFIG_SERIAL_CONSOLE -static void __init atari_init_midi_port( int cflag ) +static void __init atari_init_midi_port(int cflag) #else -void atari_init_midi_port( int cflag ) +void atari_init_midi_port(int cflag) #endif { - int baud = cflag & CBAUD; - int csize = ((cflag & CSIZE) == CS8) ? 0x10 : 0x00; - /* warning 7N1 isn't possible! (instead 7O2 is used...) */ - int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x0c : 0x08) : 0x04; - int div; - - /* 4800 selects 7812.5, 115200 selects 500000, all other (incl. 9600 as - * default) the standard MIDI speed 31250. */ - if (cflag & CBAUDEX) - baud += B38400; - if (baud == B4800) - div = ACIA_DIV64; /* really 7812.5 bps */ - else if (baud == B38400+2 /* 115200 */) - div = ACIA_DIV1; /* really 500 kbps (does that work??) */ - else - div = ACIA_DIV16; /* 31250 bps, standard for MIDI */ - - /* RTS low, ints disabled */ - acia.mid_ctrl = div | csize | parity | + int baud = cflag & CBAUD; + int csize = ((cflag & CSIZE) == CS8) ? 0x10 : 0x00; + /* warning 7N1 isn't possible! (instead 7O2 is used...) */ + int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x0c : 0x08) : 0x04; + int div; + + /* 4800 selects 7812.5, 115200 selects 500000, all other (incl. 9600 as + * default) the standard MIDI speed 31250. */ + if (cflag & CBAUDEX) + baud += B38400; + if (baud == B4800) + div = ACIA_DIV64; /* really 7812.5 bps */ + else if (baud == B38400+2 /* 115200 */) + div = ACIA_DIV1; /* really 500 kbps (does that work??) */ + else + div = ACIA_DIV16; /* 31250 bps, standard for MIDI */ + + /* RTS low, ints disabled */ + acia.mid_ctrl = div | csize | parity | ((atari_switches & ATARI_SWITCH_MIDI) ? ACIA_RHTID : ACIA_RLTID); } void __init atari_debug_init(void) { - if (!strcmp( m68k_debug_device, "ser" )) { - /* defaults to ser2 for a Falcon and ser1 otherwise */ - strcpy( m68k_debug_device, MACH_IS_FALCON ? "ser2" : "ser1" ); - - } - - if (!strcmp( m68k_debug_device, "ser1" )) { - /* ST-MFP Modem1 serial port */ - atari_init_mfp_port( B9600|CS8 ); - atari_console_driver.write = atari_mfp_console_write; - } - else if (!strcmp( m68k_debug_device, "ser2" )) { - /* SCC Modem2 serial port */ - atari_init_scc_port( B9600|CS8 ); - atari_console_driver.write = atari_scc_console_write; - } - else if (!strcmp( m68k_debug_device, "midi" )) { - /* MIDI port */ - atari_init_midi_port( B9600|CS8 ); - atari_console_driver.write = atari_midi_console_write; - } - else if (!strcmp( m68k_debug_device, "par" )) { - /* parallel printer */ - atari_turnoff_irq( IRQ_MFP_BUSY ); /* avoid ints */ - sound_ym.rd_data_reg_sel = 7; /* select mixer control */ - sound_ym.wd_data = 0xff; /* sound off, ports are output */ - sound_ym.rd_data_reg_sel = 15; /* select port B */ - sound_ym.wd_data = 0; /* no char */ - sound_ym.rd_data_reg_sel = 14; /* select port A */ - sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x20; /* strobe H */ - atari_console_driver.write = atari_par_console_write; - } - if (atari_console_driver.write) - register_console(&atari_console_driver); -} + if (!strcmp(m68k_debug_device, "ser")) { + /* defaults to ser2 for a Falcon and ser1 otherwise */ + strcpy(m68k_debug_device, MACH_IS_FALCON ? "ser2" : "ser1"); + } -/* - * Local variables: - * c-indent-level: 4 - * tab-width: 8 - * End: - */ + if (!strcmp(m68k_debug_device, "ser1")) { + /* ST-MFP Modem1 serial port */ + atari_init_mfp_port(B9600|CS8); + atari_console_driver.write = atari_mfp_console_write; + } else if (!strcmp(m68k_debug_device, "ser2")) { + /* SCC Modem2 serial port */ + atari_init_scc_port(B9600|CS8); + atari_console_driver.write = atari_scc_console_write; + } else if (!strcmp(m68k_debug_device, "midi")) { + /* MIDI port */ + atari_init_midi_port(B9600|CS8); + atari_console_driver.write = atari_midi_console_write; + } else if (!strcmp(m68k_debug_device, "par")) { + /* parallel printer */ + atari_turnoff_irq(IRQ_MFP_BUSY); /* avoid ints */ + sound_ym.rd_data_reg_sel = 7; /* select mixer control */ + sound_ym.wd_data = 0xff; /* sound off, ports are output */ + sound_ym.rd_data_reg_sel = 15; /* select port B */ + sound_ym.wd_data = 0; /* no char */ + sound_ym.rd_data_reg_sel = 14; /* select port A */ + sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x20; /* strobe H */ + atari_console_driver.write = atari_par_console_write; + } + if (atari_console_driver.write) + register_console(&atari_console_driver); +} diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 222ce4244564..e162ee685d20 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -692,7 +692,7 @@ sys_call_table: .long sys_tgkill /* 265 */ .long sys_utimes .long sys_fadvise64_64 - .long sys_mbind + .long sys_mbind .long sys_get_mempolicy .long sys_set_mempolicy /* 270 */ .long sys_mq_open diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S index 6739e87fe825..05741f233567 100644 --- a/arch/m68k/kernel/head.S +++ b/arch/m68k/kernel/head.S @@ -3195,7 +3195,7 @@ func_start serial_putc,%d0/%d1/%a0/%a1 jbra L(serial_putc_done) 3: #endif - + L(serial_putc_done): func_return serial_putc diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index 42b8fd09ea8f..852cefe7c800 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c @@ -133,78 +133,78 @@ extern void config_hp300(void); extern void config_q40(void); extern void config_sun3x(void); -extern void mac_debugging_short (int, short); -extern void mac_debugging_long (int, long); - #define MASK_256K 0xfffc0000 extern void paging_init(void); static void __init m68k_parse_bootinfo(const struct bi_record *record) { - while (record->tag != BI_LAST) { - int unknown = 0; - const unsigned long *data = record->data; - switch (record->tag) { - case BI_MACHTYPE: - case BI_CPUTYPE: - case BI_FPUTYPE: - case BI_MMUTYPE: - /* Already set up by head.S */ - break; - - case BI_MEMCHUNK: - if (m68k_num_memory < NUM_MEMINFO) { - m68k_memory[m68k_num_memory].addr = data[0]; - m68k_memory[m68k_num_memory].size = data[1]; - m68k_num_memory++; - } else - printk("m68k_parse_bootinfo: too many memory chunks\n"); - break; - - case BI_RAMDISK: - m68k_ramdisk.addr = data[0]; - m68k_ramdisk.size = data[1]; - break; - - case BI_COMMAND_LINE: - strlcpy(m68k_command_line, (const char *)data, sizeof(m68k_command_line)); - break; - - default: - if (MACH_IS_AMIGA) - unknown = amiga_parse_bootinfo(record); - else if (MACH_IS_ATARI) - unknown = atari_parse_bootinfo(record); - else if (MACH_IS_MAC) - unknown = mac_parse_bootinfo(record); - else if (MACH_IS_Q40) - unknown = q40_parse_bootinfo(record); - else if (MACH_IS_BVME6000) - unknown = bvme6000_parse_bootinfo(record); - else if (MACH_IS_MVME16x) - unknown = mvme16x_parse_bootinfo(record); - else if (MACH_IS_MVME147) - unknown = mvme147_parse_bootinfo(record); - else if (MACH_IS_HP300) - unknown = hp300_parse_bootinfo(record); - else - unknown = 1; + while (record->tag != BI_LAST) { + int unknown = 0; + const unsigned long *data = record->data; + + switch (record->tag) { + case BI_MACHTYPE: + case BI_CPUTYPE: + case BI_FPUTYPE: + case BI_MMUTYPE: + /* Already set up by head.S */ + break; + + case BI_MEMCHUNK: + if (m68k_num_memory < NUM_MEMINFO) { + m68k_memory[m68k_num_memory].addr = data[0]; + m68k_memory[m68k_num_memory].size = data[1]; + m68k_num_memory++; + } else + printk("m68k_parse_bootinfo: too many memory chunks\n"); + break; + + case BI_RAMDISK: + m68k_ramdisk.addr = data[0]; + m68k_ramdisk.size = data[1]; + break; + + case BI_COMMAND_LINE: + strlcpy(m68k_command_line, (const char *)data, + sizeof(m68k_command_line)); + break; + + default: + if (MACH_IS_AMIGA) + unknown = amiga_parse_bootinfo(record); + else if (MACH_IS_ATARI) + unknown = atari_parse_bootinfo(record); + else if (MACH_IS_MAC) + unknown = mac_parse_bootinfo(record); + else if (MACH_IS_Q40) + unknown = q40_parse_bootinfo(record); + else if (MACH_IS_BVME6000) + unknown = bvme6000_parse_bootinfo(record); + else if (MACH_IS_MVME16x) + unknown = mvme16x_parse_bootinfo(record); + else if (MACH_IS_MVME147) + unknown = mvme147_parse_bootinfo(record); + else if (MACH_IS_HP300) + unknown = hp300_parse_bootinfo(record); + else + unknown = 1; + } + if (unknown) + printk("m68k_parse_bootinfo: unknown tag 0x%04x ignored\n", + record->tag); + record = (struct bi_record *)((unsigned long)record + + record->size); } - if (unknown) - printk("m68k_parse_bootinfo: unknown tag 0x%04x ignored\n", - record->tag); - record = (struct bi_record *)((unsigned long)record+record->size); - } - m68k_realnum_memory = m68k_num_memory; + m68k_realnum_memory = m68k_num_memory; #ifdef CONFIG_SINGLE_MEMORY_CHUNK - if (m68k_num_memory > 1) { - printk("Ignoring last %i chunks of physical memory\n", - (m68k_num_memory - 1)); - m68k_num_memory = 1; - } - m68k_memoffset = m68k_memory[0].addr-PAGE_OFFSET; + if (m68k_num_memory > 1) { + printk("Ignoring last %i chunks of physical memory\n", + (m68k_num_memory - 1)); + m68k_num_memory = 1; + } + m68k_memoffset = m68k_memory[0].addr-PAGE_OFFSET; #endif } @@ -234,7 +234,7 @@ void __init setup_arch(char **cmdline_p) /* clear the fpu if we have one */ if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060)) { volatile int zero = 0; - asm __volatile__ ("frestore %0" : : "m" (zero)); + asm volatile ("frestore %0" : : "m" (zero)); } #endif @@ -262,32 +262,35 @@ void __init setup_arch(char **cmdline_p) * For the m68k, this is currently only "debug=xxx" to enable printing * certain kernel messages to some machine-specific device. */ - for( p = *cmdline_p; p && *p; ) { - i = 0; - if (!strncmp( p, "debug=", 6 )) { - strlcpy( m68k_debug_device, p+6, sizeof(m68k_debug_device) ); - if ((q = strchr( m68k_debug_device, ' ' ))) *q = 0; - i = 1; - } + for (p = *cmdline_p; p && *p;) { + i = 0; + if (!strncmp(p, "debug=", 6)) { + strlcpy(m68k_debug_device, p+6, sizeof(m68k_debug_device)); + q = strchr(m68k_debug_device, ' '); + if (q) + *q = 0; + i = 1; + } #ifdef CONFIG_ATARI - /* This option must be parsed very early */ - if (!strncmp( p, "switches=", 9 )) { - extern void atari_switches_setup( const char *, int ); - atari_switches_setup( p+9, (q = strchr( p+9, ' ' )) ? - (q - (p+9)) : strlen(p+9) ); - i = 1; - } + /* This option must be parsed very early */ + if (!strncmp(p, "switches=", 9)) { + extern void atari_switches_setup(const char *, int); + q = strchr(p + 9, ' '); + atari_switches_setup(p + 9, q ? (q - (p + 9)) : strlen(p + 9)); + i = 1; + } #endif - if (i) { - /* option processed, delete it */ - if ((q = strchr( p, ' ' ))) - strcpy( p, q+1 ); - else - *p = 0; - } else { - if ((p = strchr( p, ' ' ))) ++p; - } + if (i) { + /* option processed, delete it */ + if ((q = strchr(p, ' '))) + strcpy(p, q + 1); + else + *p = 0; + } else { + if ((p = strchr(p, ' '))) + ++p; + } } #ifdef CONFIG_DUMMY_CONSOLE @@ -296,62 +299,62 @@ void __init setup_arch(char **cmdline_p) switch (m68k_machtype) { #ifdef CONFIG_AMIGA - case MACH_AMIGA: + case MACH_AMIGA: config_amiga(); break; #endif #ifdef CONFIG_ATARI - case MACH_ATARI: + case MACH_ATARI: config_atari(); break; #endif #ifdef CONFIG_MAC - case MACH_MAC: + case MACH_MAC: config_mac(); break; #endif #ifdef CONFIG_SUN3 - case MACH_SUN3: + case MACH_SUN3: config_sun3(); break; #endif #ifdef CONFIG_APOLLO - case MACH_APOLLO: + case MACH_APOLLO: config_apollo(); break; #endif #ifdef CONFIG_MVME147 - case MACH_MVME147: + case MACH_MVME147: config_mvme147(); break; #endif #ifdef CONFIG_MVME16x - case MACH_MVME16x: + case MACH_MVME16x: config_mvme16x(); break; #endif #ifdef CONFIG_BVME6000 - case MACH_BVME6000: + case MACH_BVME6000: config_bvme6000(); break; #endif #ifdef CONFIG_HP300 - case MACH_HP300: + case MACH_HP300: config_hp300(); break; #endif #ifdef CONFIG_Q40 - case MACH_Q40: - config_q40(); + case MACH_Q40: + config_q40(); break; #endif #ifdef CONFIG_SUN3X - case MACH_SUN3X: + case MACH_SUN3X: config_sun3x(); break; #endif - default: - panic ("No configuration setup"); + default: + panic("No configuration setup"); } #ifndef CONFIG_SUN3 @@ -380,7 +383,7 @@ void __init setup_arch(char **cmdline_p) reserve_bootmem(m68k_ramdisk.addr, m68k_ramdisk.size); initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr); initrd_end = initrd_start + m68k_ramdisk.size; - printk ("initrd: %08lx - %08lx\n", initrd_start, initrd_end); + printk("initrd: %08lx - %08lx\n", initrd_start, initrd_end); } #endif @@ -402,18 +405,18 @@ void __init setup_arch(char **cmdline_p) #if defined(CONFIG_ISA) && defined(MULTI_ISA) #if defined(CONFIG_Q40) if (MACH_IS_Q40) { - isa_type = Q40_ISA; - isa_sex = 0; + isa_type = Q40_ISA; + isa_sex = 0; } #elif defined(CONFIG_GG2) - if (MACH_IS_AMIGA && AMIGAHW_PRESENT(GG2_ISA)){ - isa_type = GG2_ISA; - isa_sex = 0; + if (MACH_IS_AMIGA && AMIGAHW_PRESENT(GG2_ISA)) { + isa_type = GG2_ISA; + isa_sex = 0; } #elif defined(CONFIG_AMIGA_PCMCIA) - if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)){ - isa_type = AG_ISA; - isa_sex = 1; + if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)) { + isa_type = AG_ISA; + isa_sex = 1; } #endif #endif @@ -421,66 +424,66 @@ void __init setup_arch(char **cmdline_p) static int show_cpuinfo(struct seq_file *m, void *v) { - const char *cpu, *mmu, *fpu; - unsigned long clockfreq, clockfactor; + const char *cpu, *mmu, *fpu; + unsigned long clockfreq, clockfactor; #define LOOP_CYCLES_68020 (8) #define LOOP_CYCLES_68030 (8) #define LOOP_CYCLES_68040 (3) #define LOOP_CYCLES_68060 (1) - if (CPU_IS_020) { - cpu = "68020"; - clockfactor = LOOP_CYCLES_68020; - } else if (CPU_IS_030) { - cpu = "68030"; - clockfactor = LOOP_CYCLES_68030; - } else if (CPU_IS_040) { - cpu = "68040"; - clockfactor = LOOP_CYCLES_68040; - } else if (CPU_IS_060) { - cpu = "68060"; - clockfactor = LOOP_CYCLES_68060; - } else { - cpu = "680x0"; - clockfactor = 0; - } + if (CPU_IS_020) { + cpu = "68020"; + clockfactor = LOOP_CYCLES_68020; + } else if (CPU_IS_030) { + cpu = "68030"; + clockfactor = LOOP_CYCLES_68030; + } else if (CPU_IS_040) { + cpu = "68040"; + clockfactor = LOOP_CYCLES_68040; + } else if (CPU_IS_060) { + cpu = "68060"; + clockfactor = LOOP_CYCLES_68060; + } else { + cpu = "680x0"; + clockfactor = 0; + } #ifdef CONFIG_M68KFPU_EMU_ONLY - fpu="none(soft float)"; + fpu = "none(soft float)"; #else - if (m68k_fputype & FPU_68881) - fpu = "68881"; - else if (m68k_fputype & FPU_68882) - fpu = "68882"; - else if (m68k_fputype & FPU_68040) - fpu = "68040"; - else if (m68k_fputype & FPU_68060) - fpu = "68060"; - else if (m68k_fputype & FPU_SUNFPA) - fpu = "Sun FPA"; - else - fpu = "none"; + if (m68k_fputype & FPU_68881) + fpu = "68881"; + else if (m68k_fputype & FPU_68882) + fpu = "68882"; + else if (m68k_fputype & FPU_68040) + fpu = "68040"; + else if (m68k_fputype & FPU_68060) + fpu = "68060"; + else if (m68k_fputype & FPU_SUNFPA) + fpu = "Sun FPA"; + else + fpu = "none"; #endif - if (m68k_mmutype & MMU_68851) - mmu = "68851"; - else if (m68k_mmutype & MMU_68030) - mmu = "68030"; - else if (m68k_mmutype & MMU_68040) - mmu = "68040"; - else if (m68k_mmutype & MMU_68060) - mmu = "68060"; - else if (m68k_mmutype & MMU_SUN3) - mmu = "Sun-3"; - else if (m68k_mmutype & MMU_APOLLO) - mmu = "Apollo"; - else - mmu = "unknown"; - - clockfreq = loops_per_jiffy*HZ*clockfactor; - - seq_printf(m, "CPU:\t\t%s\n" + if (m68k_mmutype & MMU_68851) + mmu = "68851"; + else if (m68k_mmutype & MMU_68030) + mmu = "68030"; + else if (m68k_mmutype & MMU_68040) + mmu = "68040"; + else if (m68k_mmutype & MMU_68060) + mmu = "68060"; + else if (m68k_mmutype & MMU_SUN3) + mmu = "Sun-3"; + else if (m68k_mmutype & MMU_APOLLO) + mmu = "Apollo"; + else + mmu = "unknown"; + + clockfreq = loops_per_jiffy * HZ * clockfactor; + + seq_printf(m, "CPU:\t\t%s\n" "MMU:\t\t%s\n" "FPU:\t\t%s\n" "Clocking:\t%lu.%1luMHz\n" @@ -490,7 +493,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) clockfreq/1000000,(clockfreq/100000)%10, loops_per_jiffy/(500000/HZ),(loops_per_jiffy/(5000/HZ))%100, loops_per_jiffy); - return 0; + return 0; } static void *c_start(struct seq_file *m, loff_t *pos) @@ -506,44 +509,44 @@ static void c_stop(struct seq_file *m, void *v) { } struct seq_operations cpuinfo_op = { - .start = c_start, - .next = c_next, - .stop = c_stop, - .show = show_cpuinfo, + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, }; int get_hardware_list(char *buffer) { - int len = 0; - char model[80]; - unsigned long mem; - int i; + int len = 0; + char model[80]; + unsigned long mem; + int i; - if (mach_get_model) - mach_get_model(model); - else - strcpy(model, "Unknown m68k"); + if (mach_get_model) + mach_get_model(model); + else + strcpy(model, "Unknown m68k"); - len += sprintf(buffer+len, "Model:\t\t%s\n", model); - for (mem = 0, i = 0; i < m68k_num_memory; i++) - mem += m68k_memory[i].size; - len += sprintf(buffer+len, "System Memory:\t%ldK\n", mem>>10); + len += sprintf(buffer + len, "Model:\t\t%s\n", model); + for (mem = 0, i = 0; i < m68k_num_memory; i++) + mem += m68k_memory[i].size; + len += sprintf(buffer + len, "System Memory:\t%ldK\n", mem >> 10); - if (mach_get_hardware_list) - len += mach_get_hardware_list(buffer+len); + if (mach_get_hardware_list) + len += mach_get_hardware_list(buffer + len); - return(len); + return len; } void check_bugs(void) { #ifndef CONFIG_M68KFPU_EMU if (m68k_fputype == 0) { - printk( KERN_EMERG "*** YOU DO NOT HAVE A FLOATING POINT UNIT, " - "WHICH IS REQUIRED BY LINUX/M68K ***\n" ); - printk( KERN_EMERG "Upgrade your hardware or join the FPU " - "emulation project\n" ); - panic( "no FPU" ); + printk(KERN_EMERG "*** YOU DO NOT HAVE A FLOATING POINT UNIT, " + "WHICH IS REQUIRED BY LINUX/M68K ***\n"); + printk(KERN_EMERG "Upgrade your hardware or join the FPU " + "emulation project\n"); + panic("no FPU"); } #endif /* !CONFIG_M68KFPU_EMU */ } diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c index 562b38d00180..d2fbf436a1fb 100644 --- a/arch/m68k/mac/config.c +++ b/arch/m68k/mac/config.c @@ -59,15 +59,15 @@ extern struct mem_info m68k_ramdisk; extern char m68k_command_line[CL_SIZE]; -void *mac_env; /* Loaded by the boot asm */ +void *mac_env; /* Loaded by the boot asm */ /* The phys. video addr. - might be bogus on some machines */ unsigned long mac_orig_videoaddr; /* Mac specific timer functions */ -extern unsigned long mac_gettimeoffset (void); -extern int mac_hwclk (int, struct rtc_time *); -extern int mac_set_clock_mmss (unsigned long); +extern unsigned long mac_gettimeoffset(void); +extern int mac_hwclk(int, struct rtc_time *); +extern int mac_set_clock_mmss(unsigned long); extern int show_mac_interrupts(struct seq_file *, void *); extern void iop_preinit(void); extern void iop_init(void); @@ -99,51 +99,52 @@ static void mac_sched_init(irq_handler_t vector) int __init mac_parse_bootinfo(const struct bi_record *record) { - int unknown = 0; - const u_long *data = record->data; + int unknown = 0; + const u_long *data = record->data; - switch (record->tag) { + switch (record->tag) { case BI_MAC_MODEL: - mac_bi_data.id = *data; - break; + mac_bi_data.id = *data; + break; case BI_MAC_VADDR: - mac_bi_data.videoaddr = *data; - break; + mac_bi_data.videoaddr = *data; + break; case BI_MAC_VDEPTH: - mac_bi_data.videodepth = *data; - break; + mac_bi_data.videodepth = *data; + break; case BI_MAC_VROW: - mac_bi_data.videorow = *data; - break; + mac_bi_data.videorow = *data; + break; case BI_MAC_VDIM: - mac_bi_data.dimensions = *data; - break; + mac_bi_data.dimensions = *data; + break; case BI_MAC_VLOGICAL: - mac_bi_data.videological = VIDEOMEMBASE + (*data & ~VIDEOMEMMASK); - mac_orig_videoaddr = *data; - break; + mac_bi_data.videological = VIDEOMEMBASE + (*data & ~VIDEOMEMMASK); + mac_orig_videoaddr = *data; + break; case BI_MAC_SCCBASE: - mac_bi_data.sccbase = *data; - break; + mac_bi_data.sccbase = *data; + break; case BI_MAC_BTIME: - mac_bi_data.boottime = *data; - break; + mac_bi_data.boottime = *data; + break; case BI_MAC_GMTBIAS: - mac_bi_data.gmtbias = *data; - break; + mac_bi_data.gmtbias = *data; + break; case BI_MAC_MEMSIZE: - mac_bi_data.memsize = *data; - break; + mac_bi_data.memsize = *data; + break; case BI_MAC_CPUID: - mac_bi_data.cpuid = *data; - break; - case BI_MAC_ROMBASE: - mac_bi_data.rombase = *data; - break; + mac_bi_data.cpuid = *data; + break; + case BI_MAC_ROMBASE: + mac_bi_data.rombase = *data; + break; default: - unknown = 1; - } - return(unknown); + unknown = 1; + break; + } + return unknown; } /* @@ -155,6 +156,7 @@ int __init mac_parse_bootinfo(const struct bi_record *record) static void mac_cache_card_flush(int writeback) { unsigned long flags; + local_irq_save(flags); via_flush_cache(); local_irq_restore(flags); @@ -162,28 +164,27 @@ static void mac_cache_card_flush(int writeback) void __init config_mac(void) { - if (!MACH_IS_MAC) { - printk(KERN_ERR "ERROR: no Mac, but config_mac() called!! \n"); - } + if (!MACH_IS_MAC) + printk(KERN_ERR "ERROR: no Mac, but config_mac() called!! \n"); - mach_sched_init = mac_sched_init; - mach_init_IRQ = mac_init_IRQ; - mach_get_model = mac_get_model; - mach_gettimeoffset = mac_gettimeoffset; + mach_sched_init = mac_sched_init; + mach_init_IRQ = mac_init_IRQ; + mach_get_model = mac_get_model; + mach_gettimeoffset = mac_gettimeoffset; #warning move to adb/via init #if 0 - mach_hwclk = mac_hwclk; + mach_hwclk = mac_hwclk; #endif - mach_set_clock_mmss = mac_set_clock_mmss; - mach_reset = mac_reset; - mach_halt = mac_poweroff; - mach_power_off = mac_poweroff; + mach_set_clock_mmss = mac_set_clock_mmss; + mach_reset = mac_reset; + mach_halt = mac_poweroff; + mach_power_off = mac_poweroff; mach_max_dma_address = 0xffffffff; #if 0 - mach_debug_init = mac_debug_init; + mach_debug_init = mac_debug_init; #endif #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) - mach_beep = mac_mksound; + mach_beep = mac_mksound; #endif #ifdef CONFIG_HEARTBEAT #if 0 @@ -199,21 +200,22 @@ void __init config_mac(void) mac_identify(); mac_report_hardware(); - /* AFAIK only the IIci takes a cache card. The IIfx has onboard - cache ... someone needs to figure out how to tell if it's on or - not. */ + /* + * AFAIK only the IIci takes a cache card. The IIfx has onboard + * cache ... someone needs to figure out how to tell if it's on or + * not. + */ if (macintosh_config->ident == MAC_MODEL_IICI - || macintosh_config->ident == MAC_MODEL_IIFX) { + || macintosh_config->ident == MAC_MODEL_IIFX) mach_l2_flush = mac_cache_card_flush; - } /* * Check for machine specific fixups. */ #ifdef OLD_NUBUS_CODE - nubus_sweep_video(); + nubus_sweep_video(); #endif } @@ -233,8 +235,7 @@ void __init config_mac(void) struct mac_model *macintosh_config; EXPORT_SYMBOL(macintosh_config); -static struct mac_model mac_data_table[]= -{ +static struct mac_model mac_data_table[] = { /* * We'll pretend to be a Macintosh II, that's pretty safe. */ @@ -784,12 +785,12 @@ void mac_identify(void) if (!model) { /* no bootinfo model id -> NetBSD booter was used! */ /* XXX FIXME: breaks for model > 31 */ - model=(mac_bi_data.cpuid>>2)&63; - printk (KERN_WARNING "No bootinfo model ID, using cpuid instead (hey, use Penguin!)\n"); + model = (mac_bi_data.cpuid >> 2) & 63; + printk(KERN_WARNING "No bootinfo model ID, using cpuid instead (hey, use Penguin!)\n"); } macintosh_config = mac_data_table; - for (m = macintosh_config ; m->ident != -1 ; m++) { + for (m = macintosh_config; m->ident != -1; m++) { if (m->ident == model) { macintosh_config = m; break; @@ -803,25 +804,25 @@ void mac_identify(void) iop_preinit(); mac_debug_init(); - printk (KERN_INFO "Detected Macintosh model: %d \n", model); + printk(KERN_INFO "Detected Macintosh model: %d \n", model); /* * Report booter data: */ - printk (KERN_DEBUG " Penguin bootinfo data:\n"); - printk (KERN_DEBUG " Video: addr 0x%lx row 0x%lx depth %lx dimensions %ld x %ld\n", + printk(KERN_DEBUG " Penguin bootinfo data:\n"); + printk(KERN_DEBUG " Video: addr 0x%lx row 0x%lx depth %lx dimensions %ld x %ld\n", mac_bi_data.videoaddr, mac_bi_data.videorow, mac_bi_data.videodepth, mac_bi_data.dimensions & 0xFFFF, mac_bi_data.dimensions >> 16); - printk (KERN_DEBUG " Videological 0x%lx phys. 0x%lx, SCC at 0x%lx \n", + printk(KERN_DEBUG " Videological 0x%lx phys. 0x%lx, SCC at 0x%lx \n", mac_bi_data.videological, mac_orig_videoaddr, mac_bi_data.sccbase); - printk (KERN_DEBUG " Boottime: 0x%lx GMTBias: 0x%lx \n", + printk(KERN_DEBUG " Boottime: 0x%lx GMTBias: 0x%lx \n", mac_bi_data.boottime, mac_bi_data.gmtbias); - printk (KERN_DEBUG " Machine ID: %ld CPUid: 0x%lx memory size: 0x%lx \n", + printk(KERN_DEBUG " Machine ID: %ld CPUid: 0x%lx memory size: 0x%lx \n", mac_bi_data.id, mac_bi_data.cpuid, mac_bi_data.memsize); #if 0 - printk ("Ramdisk: addr 0x%lx size 0x%lx\n", + printk("Ramdisk: addr 0x%lx size 0x%lx\n", m68k_ramdisk.addr, m68k_ramdisk.size); #endif @@ -830,22 +831,22 @@ void mac_identify(void) */ switch (macintosh_config->scsi_type) { case MAC_SCSI_OLD: - MACHW_SET(MAC_SCSI_80); - break; + MACHW_SET(MAC_SCSI_80); + break; case MAC_SCSI_QUADRA: case MAC_SCSI_QUADRA2: case MAC_SCSI_QUADRA3: - MACHW_SET(MAC_SCSI_96); - if ((macintosh_config->ident == MAC_MODEL_Q900) || - (macintosh_config->ident == MAC_MODEL_Q950)) - MACHW_SET(MAC_SCSI_96_2); - break; + MACHW_SET(MAC_SCSI_96); + if ((macintosh_config->ident == MAC_MODEL_Q900) || + (macintosh_config->ident == MAC_MODEL_Q950)) + MACHW_SET(MAC_SCSI_96_2); + break; default: - printk(KERN_WARNING "config.c: wtf: unknown scsi, using 53c80\n"); - MACHW_SET(MAC_SCSI_80); - break; - + printk(KERN_WARNING "config.c: wtf: unknown scsi, using 53c80\n"); + MACHW_SET(MAC_SCSI_80); + break; } + iop_init(); via_init(); oss_init(); @@ -860,6 +861,6 @@ void mac_report_hardware(void) static void mac_get_model(char *str) { - strcpy(str,"Macintosh "); + strcpy(str, "Macintosh "); strcat(str, macintosh_config->name); } diff --git a/arch/m68k/mac/debug.c b/arch/m68k/mac/debug.c index 4eeb09dc0e8f..83990326099b 100644 --- a/arch/m68k/mac/debug.c +++ b/arch/m68k/mac/debug.c @@ -52,7 +52,7 @@ extern void mac_serial_print(const char *); */ #ifdef DEBUG_SCREEN -static int peng=0, line=0; +static int peng, line; #endif void mac_debugging_short(int pos, short num) @@ -74,15 +74,14 @@ void mac_debugging_short(int pos, short num) } /* calculate current offset */ - pengoffset=(unsigned char *)(mac_videobase+(150+line*2)*mac_rowbytes) - +80*peng; + pengoffset = (unsigned char *)mac_videobase + + (150+line*2) * mac_rowbytes) + 80 * peng; - pptr=pengoffset; + pptr = pengoffset; - for(i=0;i<8*sizeof(short);i++) /* # of bits */ - { + for (i = 0; i < 8 * sizeof(short); i++) { /* # of bits */ /* value mask for bit i, reverse order */ - *pptr++ = (num & ( 1 << (8*sizeof(short)-i-1) ) ? 0xFF : 0x00); + *pptr++ = (num & (1 << (8*sizeof(short)-i-1)) ? 0xFF : 0x00); } peng++; @@ -115,11 +114,10 @@ void mac_debugging_long(int pos, long addr) pengoffset=(unsigned char *)(mac_videobase+(150+line*2)*mac_rowbytes) +80*peng; - pptr=pengoffset; + pptr = pengoffset; - for(i=0;i<8*sizeof(long);i++) /* # of bits */ - { - *pptr++ = (addr & ( 1 << (8*sizeof(long)-i-1) ) ? 0xFF : 0x00); + for (i = 0; i < 8 * sizeof(long); i++) { /* # of bits */ + *pptr++ = (addr & (1 << (8*sizeof(long)-i-1)) ? 0xFF : 0x00); } peng++; @@ -136,16 +134,15 @@ void mac_debugging_long(int pos, long addr) * TODO: serial debug code */ -struct mac_SCC - { - u_char cha_b_ctrl; - u_char char_dummy1; - u_char cha_a_ctrl; - u_char char_dummy2; - u_char cha_b_data; - u_char char_dummy3; - u_char cha_a_data; - }; +struct mac_SCC { + u_char cha_b_ctrl; + u_char char_dummy1; + u_char cha_a_ctrl; + u_char char_dummy2; + u_char cha_b_data; + u_char char_dummy3; + u_char cha_a_data; +}; # define scc (*((volatile struct mac_SCC*)mac_bi_data.sccbase)) @@ -158,9 +155,9 @@ int mac_SCC_reset_done; static int scc_port = -1; static struct console mac_console_driver = { - .name = "debug", - .flags = CON_PRINTBUFFER, - .index = -1, + .name = "debug", + .flags = CON_PRINTBUFFER, + .index = -1, }; /* @@ -178,8 +175,8 @@ static struct console mac_console_driver = { * this driver if Mac. */ -void mac_debug_console_write (struct console *co, const char *str, - unsigned int count) +void mac_debug_console_write(struct console *co, const char *str, + unsigned int count) { mac_serial_print(str); } @@ -190,48 +187,50 @@ void mac_debug_console_write (struct console *co, const char *str, #define uSEC 1 -static inline void mac_sccb_out (char c) +static inline void mac_sccb_out(char c) { - int i; - do { - for( i = uSEC; i > 0; --i ) + int i; + + do { + for (i = uSEC; i > 0; --i) + barrier(); + } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ + for (i = uSEC; i > 0; --i) barrier(); - } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ - for( i = uSEC; i > 0; --i ) - barrier(); - scc.cha_b_data = c; + scc.cha_b_data = c; } -static inline void mac_scca_out (char c) +static inline void mac_scca_out(char c) { - int i; - do { - for( i = uSEC; i > 0; --i ) + int i; + + do { + for (i = uSEC; i > 0; --i) + barrier(); + } while (!(scc.cha_a_ctrl & 0x04)); /* wait for tx buf empty */ + for (i = uSEC; i > 0; --i) barrier(); - } while (!(scc.cha_a_ctrl & 0x04)); /* wait for tx buf empty */ - for( i = uSEC; i > 0; --i ) - barrier(); - scc.cha_a_data = c; + scc.cha_a_data = c; } -void mac_sccb_console_write (struct console *co, const char *str, - unsigned int count) +void mac_sccb_console_write(struct console *co, const char *str, + unsigned int count) { - while (count--) { - if (*str == '\n') - mac_sccb_out( '\r' ); - mac_sccb_out( *str++ ); - } + while (count--) { + if (*str == '\n') + mac_sccb_out('\r'); + mac_sccb_out(*str++); + } } -void mac_scca_console_write (struct console *co, const char *str, - unsigned int count) +void mac_scca_console_write(struct console *co, const char *str, + unsigned int count) { - while (count--) { - if (*str == '\n') - mac_scca_out( '\r' ); - mac_scca_out( *str++ ); - } + while (count--) { + if (*str == '\n') + mac_scca_out('\r'); + mac_scca_out(*str++); + } } @@ -239,41 +238,41 @@ void mac_scca_console_write (struct console *co, const char *str, * SCC serial ports. They're used by the debugging interface, kgdb, and the * serial console code. */ #define SCCB_WRITE(reg,val) \ - do { \ - int i; \ - scc.cha_b_ctrl = (reg); \ - for( i = uSEC; i > 0; --i ) \ - barrier(); \ - scc.cha_b_ctrl = (val); \ - for( i = uSEC; i > 0; --i ) \ - barrier(); \ - } while(0) + do { \ + int i; \ + scc.cha_b_ctrl = (reg); \ + for (i = uSEC; i > 0; --i) \ + barrier(); \ + scc.cha_b_ctrl = (val); \ + for (i = uSEC; i > 0; --i) \ + barrier(); \ + } while(0) #define SCCA_WRITE(reg,val) \ - do { \ - int i; \ - scc.cha_a_ctrl = (reg); \ - for( i = uSEC; i > 0; --i ) \ - barrier(); \ - scc.cha_a_ctrl = (val); \ - for( i = uSEC; i > 0; --i ) \ - barrier(); \ - } while(0) + do { \ + int i; \ + scc.cha_a_ctrl = (reg); \ + for (i = uSEC; i > 0; --i) \ + barrier(); \ + scc.cha_a_ctrl = (val); \ + for (i = uSEC; i > 0; --i) \ + barrier(); \ + } while(0) /* loops_per_jiffy isn't initialized yet, so we can't use udelay(). This does a * delay of ~ 60us. */ /* Mac: loops_per_jiffy min. 19000 ^= .5 us; MFPDELAY was 0.6 us*/ -#define LONG_DELAY() \ - do { \ - int i; \ - for( i = 60*uSEC; i > 0; --i ) \ - barrier(); \ - } while(0) +#define LONG_DELAY() \ + do { \ + int i; \ + for (i = 60*uSEC; i > 0; --i) \ + barrier(); \ + } while(0) #ifndef CONFIG_SERIAL_CONSOLE -static void __init mac_init_scc_port( int cflag, int port ) +static void __init mac_init_scc_port(int cflag, int port) #else -void mac_init_scc_port( int cflag, int port ) +void mac_init_scc_port(int cflag, int port) #endif { extern int mac_SCC_reset_done; @@ -292,71 +291,71 @@ void mac_init_scc_port( int cflag, int port ) /* reg12 (BRG low) */ { 94, 62, 46, 22, 10, 4, 1, 0, 0 }; - int baud = cflag & CBAUD; - int clksrc, clkmode, div, reg3, reg5; - - if (cflag & CBAUDEX) - baud += B38400; - if (baud < B1200 || baud > B38400+2) - baud = B9600; /* use default 9600bps for non-implemented rates */ - baud -= B1200; /* tables starts at 1200bps */ - - clksrc = clksrc_table[baud]; - clkmode = clkmode_table[baud]; - div = div_table[baud]; - - reg3 = (((cflag & CSIZE) == CS8) ? 0xc0 : 0x40); - reg5 = (((cflag & CSIZE) == CS8) ? 0x60 : 0x20) | 0x82 /* assert DTR/RTS */; - - if (port == 1) { - (void)scc.cha_b_ctrl; /* reset reg pointer */ - SCCB_WRITE( 9, 0xc0 ); /* reset */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCCB_WRITE( 4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | - 0x04 /* 1 stopbit */ | - clkmode ); - SCCB_WRITE( 3, reg3 ); - SCCB_WRITE( 5, reg5 ); - SCCB_WRITE( 9, 0 ); /* no interrupts */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCCB_WRITE( 10, 0 ); /* NRZ mode */ - SCCB_WRITE( 11, clksrc ); /* main clock source */ - SCCB_WRITE( 12, div ); /* BRG value */ - SCCB_WRITE( 13, 0 ); /* BRG high byte */ - SCCB_WRITE( 14, 1 ); - SCCB_WRITE( 3, reg3 | 1 ); - SCCB_WRITE( 5, reg5 | 8 ); - } else if (port == 0) { - (void)scc.cha_a_ctrl; /* reset reg pointer */ - SCCA_WRITE( 9, 0xc0 ); /* reset */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCCA_WRITE( 4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | + int baud = cflag & CBAUD; + int clksrc, clkmode, div, reg3, reg5; + + if (cflag & CBAUDEX) + baud += B38400; + if (baud < B1200 || baud > B38400+2) + baud = B9600; /* use default 9600bps for non-implemented rates */ + baud -= B1200; /* tables starts at 1200bps */ + + clksrc = clksrc_table[baud]; + clkmode = clkmode_table[baud]; + div = div_table[baud]; + + reg3 = (((cflag & CSIZE) == CS8) ? 0xc0 : 0x40); + reg5 = (((cflag & CSIZE) == CS8) ? 0x60 : 0x20) | 0x82 /* assert DTR/RTS */; + + if (port == 1) { + (void)scc.cha_b_ctrl; /* reset reg pointer */ + SCCB_WRITE(9, 0xc0); /* reset */ + LONG_DELAY(); /* extra delay after WR9 access */ + SCCB_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | + 0x04 /* 1 stopbit */ | + clkmode); + SCCB_WRITE(3, reg3); + SCCB_WRITE(5, reg5); + SCCB_WRITE(9, 0); /* no interrupts */ + LONG_DELAY(); /* extra delay after WR9 access */ + SCCB_WRITE(10, 0); /* NRZ mode */ + SCCB_WRITE(11, clksrc); /* main clock source */ + SCCB_WRITE(12, div); /* BRG value */ + SCCB_WRITE(13, 0); /* BRG high byte */ + SCCB_WRITE(14, 1); + SCCB_WRITE(3, reg3 | 1); + SCCB_WRITE(5, reg5 | 8); + } else if (port == 0) { + (void)scc.cha_a_ctrl; /* reset reg pointer */ + SCCA_WRITE(9, 0xc0); /* reset */ + LONG_DELAY(); /* extra delay after WR9 access */ + SCCA_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | 0x04 /* 1 stopbit */ | - clkmode ); - SCCA_WRITE( 3, reg3 ); - SCCA_WRITE( 5, reg5 ); - SCCA_WRITE( 9, 0 ); /* no interrupts */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCCA_WRITE( 10, 0 ); /* NRZ mode */ - SCCA_WRITE( 11, clksrc ); /* main clock source */ - SCCA_WRITE( 12, div ); /* BRG value */ - SCCA_WRITE( 13, 0 ); /* BRG high byte */ - SCCA_WRITE( 14, 1 ); - SCCA_WRITE( 3, reg3 | 1 ); - SCCA_WRITE( 5, reg5 | 8 ); - } - - mac_SCC_reset_done = 1; - mac_SCC_init_done = 1; + clkmode); + SCCA_WRITE(3, reg3); + SCCA_WRITE(5, reg5); + SCCA_WRITE(9, 0); /* no interrupts */ + LONG_DELAY(); /* extra delay after WR9 access */ + SCCA_WRITE(10, 0); /* NRZ mode */ + SCCA_WRITE(11, clksrc); /* main clock source */ + SCCA_WRITE(12, div); /* BRG value */ + SCCA_WRITE(13, 0); /* BRG high byte */ + SCCA_WRITE(14, 1); + SCCA_WRITE(3, reg3 | 1); + SCCA_WRITE(5, reg5 | 8); + } + + mac_SCC_reset_done = 1; + mac_SCC_init_done = 1; } #endif /* DEBUG_SERIAL */ -void mac_init_scca_port( int cflag ) +void mac_init_scca_port(int cflag) { mac_init_scc_port(cflag, 0); } -void mac_init_sccb_port( int cflag ) +void mac_init_sccb_port(int cflag) { mac_init_scc_port(cflag, 1); } @@ -364,34 +363,26 @@ void mac_init_sccb_port( int cflag ) void __init mac_debug_init(void) { #ifdef DEBUG_SERIAL - if ( !strcmp( m68k_debug_device, "ser" ) - || !strcmp( m68k_debug_device, "ser1" )) { - /* Mac modem port */ - mac_init_scc_port( B9600|CS8, 0 ); - mac_console_driver.write = mac_scca_console_write; - scc_port = 0; - } - else if (!strcmp( m68k_debug_device, "ser2" )) { - /* Mac printer port */ - mac_init_scc_port( B9600|CS8, 1 ); - mac_console_driver.write = mac_sccb_console_write; - scc_port = 1; - } + if (!strcmp(m68k_debug_device, "ser") || + !strcmp(m68k_debug_device, "ser1")) { + /* Mac modem port */ + mac_init_scc_port(B9600|CS8, 0); + mac_console_driver.write = mac_scca_console_write; + scc_port = 0; + } else if (!strcmp(m68k_debug_device, "ser2")) { + /* Mac printer port */ + mac_init_scc_port(B9600|CS8, 1); + mac_console_driver.write = mac_sccb_console_write; + scc_port = 1; + } #endif #ifdef DEBUG_HEADS - if ( !strcmp( m68k_debug_device, "scn" ) - || !strcmp( m68k_debug_device, "con" )) { - /* display, using head.S console routines */ - mac_console_driver.write = mac_debug_console_write; - } + if (!strcmp(m68k_debug_device, "scn") || + !strcmp(m68k_debug_device, "con")) { + /* display, using head.S console routines */ + mac_console_driver.write = mac_debug_console_write; + } #endif - if (mac_console_driver.write) - register_console(&mac_console_driver); + if (mac_console_driver.write) + register_console(&mac_console_driver); } - -/* - * Local variables: - * c-indent-level: 4 - * tab-width: 8 - * End: - */ diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index 92f873cc7060..4c5b9e4e98bc 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c @@ -35,35 +35,35 @@ #include #include -extern irqreturn_t q40_process_int (int level, struct pt_regs *regs); -extern void q40_init_IRQ (void); +extern irqreturn_t q40_process_int(int level, struct pt_regs *regs); +extern void q40_init_IRQ(void); static void q40_get_model(char *model); static int q40_get_hardware_list(char *buffer); extern void q40_sched_init(irq_handler_t handler); -extern unsigned long q40_gettimeoffset (void); -extern int q40_hwclk (int, struct rtc_time *); -extern unsigned int q40_get_ss (void); -extern int q40_set_clock_mmss (unsigned long); +extern unsigned long q40_gettimeoffset(void); +extern int q40_hwclk(int, struct rtc_time *); +extern unsigned int q40_get_ss(void); +extern int q40_set_clock_mmss(unsigned long); static int q40_get_rtc_pll(struct rtc_pll_info *pll); static int q40_set_rtc_pll(struct rtc_pll_info *pll); -extern void q40_reset (void); +extern void q40_reset(void); void q40_halt(void); extern void q40_waitbut(void); -void q40_set_vectors (void); +void q40_set_vectors(void); -extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/ ); +extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/); extern char m68k_debug_device[]; static void q40_mem_console_write(struct console *co, const char *b, - unsigned int count); + unsigned int count); extern int ql_ticks; static struct console q40_console_driver = { - .name = "debug", - .flags = CON_PRINTBUFFER, - .index = -1, + .name = "debug", + .flags = CON_PRINTBUFFER, + .index = -1, }; @@ -74,150 +74,157 @@ static int _cpleft; static void q40_mem_console_write(struct console *co, const char *s, unsigned int count) { - char *p=(char *)s; - - if (count<_cpleft) - while (count-- >0){ - *q40_mem_cptr=*p++; - q40_mem_cptr+=4; - _cpleft--; - } + const char *p = s; + + if (count < _cpleft) { + while (count-- > 0) { + *q40_mem_cptr = *p++; + q40_mem_cptr += 4; + _cpleft--; + } + } } + #if 0 void printq40(char *str) { - int l=strlen(str); - char *p=q40_mem_cptr; - - while (l-- >0 && _cpleft-- >0) - { - *p=*str++; - p+=4; - } - q40_mem_cptr=p; + int l = strlen(str); + char *p = q40_mem_cptr; + + while (l-- > 0 && _cpleft-- > 0) { + *p = *str++; + p += 4; + } + q40_mem_cptr = p; } #endif -static int halted=0; +static int halted; #ifdef CONFIG_HEARTBEAT static void q40_heartbeat(int on) { - if (halted) return; + if (halted) + return; - if (on) - Q40_LED_ON(); - else - Q40_LED_OFF(); + if (on) + Q40_LED_ON(); + else + Q40_LED_OFF(); } #endif void q40_reset(void) { - halted=1; - printk ("\n\n*******************************************\n" + halted = 1; + printk("\n\n*******************************************\n" "Called q40_reset : press the RESET button!! \n" "*******************************************\n"); Q40_LED_ON(); - while(1) ; + while (1) + ; } void q40_halt(void) { - halted=1; - printk ("\n\n*******************\n" - " Called q40_halt\n" - "*******************\n"); + halted = 1; + printk("\n\n*******************\n" + " Called q40_halt\n" + "*******************\n"); Q40_LED_ON(); - while(1) ; + while (1) + ; } static void q40_get_model(char *model) { - sprintf(model, "Q40"); + sprintf(model, "Q40"); } /* No hardware options on Q40? */ static int q40_get_hardware_list(char *buffer) { - *buffer = '\0'; - return 0; + *buffer = '\0'; + return 0; } -static unsigned int serports[]={0x3f8,0x2f8,0x3e8,0x2e8,0}; +static unsigned int serports[] = +{ + 0x3f8,0x2f8,0x3e8,0x2e8,0 +}; void q40_disable_irqs(void) { - unsigned i,j; + unsigned i, j; - j=0; - while((i=serports[j++])) outb(0,i+UART_IER); - master_outb(0,EXT_ENABLE_REG); - master_outb(0,KEY_IRQ_ENABLE_REG); + j = 0; + while ((i = serports[j++])) + outb(0, i + UART_IER); + master_outb(0, EXT_ENABLE_REG); + master_outb(0, KEY_IRQ_ENABLE_REG); } void __init config_q40(void) { - mach_sched_init = q40_sched_init; + mach_sched_init = q40_sched_init; - mach_init_IRQ = q40_init_IRQ; - mach_gettimeoffset = q40_gettimeoffset; - mach_hwclk = q40_hwclk; - mach_get_ss = q40_get_ss; - mach_get_rtc_pll = q40_get_rtc_pll; - mach_set_rtc_pll = q40_set_rtc_pll; - mach_set_clock_mmss = q40_set_clock_mmss; + mach_init_IRQ = q40_init_IRQ; + mach_gettimeoffset = q40_gettimeoffset; + mach_hwclk = q40_hwclk; + mach_get_ss = q40_get_ss; + mach_get_rtc_pll = q40_get_rtc_pll; + mach_set_rtc_pll = q40_set_rtc_pll; + mach_set_clock_mmss = q40_set_clock_mmss; - mach_reset = q40_reset; - mach_get_model = q40_get_model; - mach_get_hardware_list = q40_get_hardware_list; + mach_reset = q40_reset; + mach_get_model = q40_get_model; + mach_get_hardware_list = q40_get_hardware_list; #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) - mach_beep = q40_mksound; + mach_beep = q40_mksound; #endif #ifdef CONFIG_HEARTBEAT - mach_heartbeat = q40_heartbeat; + mach_heartbeat = q40_heartbeat; #endif - mach_halt = q40_halt; - - /* disable a few things that SMSQ might have left enabled */ - q40_disable_irqs(); - - /* no DMA at all, but ide-scsi requires it.. make sure - * all physical RAM fits into the boundary - otherwise - * allocator may play costly and useless tricks */ - mach_max_dma_address = 1024*1024*1024; - - /* useful for early debugging stages - writes kernel messages into SRAM */ - if (!strncmp( m68k_debug_device,"mem",3 )) - { - /*printk("using NVRAM debug, q40_mem_cptr=%p\n",q40_mem_cptr);*/ - _cpleft=2000-((long)q40_mem_cptr-0xff020000)/4; - q40_console_driver.write = q40_mem_console_write; - register_console(&q40_console_driver); - } + mach_halt = q40_halt; + + /* disable a few things that SMSQ might have left enabled */ + q40_disable_irqs(); + + /* no DMA at all, but ide-scsi requires it.. make sure + * all physical RAM fits into the boundary - otherwise + * allocator may play costly and useless tricks */ + mach_max_dma_address = 1024*1024*1024; + + /* useful for early debugging stages - writes kernel messages into SRAM */ + if (!strncmp( m68k_debug_device,"mem", 3)) { + /*printk("using NVRAM debug, q40_mem_cptr=%p\n",q40_mem_cptr);*/ + _cpleft = 2000 - ((long)q40_mem_cptr-0xff020000) / 4; + q40_console_driver.write = q40_mem_console_write; + register_console(&q40_console_driver); + } } int q40_parse_bootinfo(const struct bi_record *rec) { - return 1; + return 1; } -static inline unsigned char bcd2bin (unsigned char b) +static inline unsigned char bcd2bin(unsigned char b) { - return ((b>>4)*10 + (b&15)); + return (b >> 4) * 10 + (b & 15); } -static inline unsigned char bin2bcd (unsigned char b) +static inline unsigned char bin2bcd(unsigned char b) { - return (((b/10)*16) + (b%10)); + return (b / 10) * 16 + (b % 10); } -unsigned long q40_gettimeoffset (void) +unsigned long q40_gettimeoffset(void) { - return 5000*(ql_ticks!=0); + return 5000 * (ql_ticks != 0); } @@ -238,9 +245,9 @@ unsigned long q40_gettimeoffset (void) int q40_hwclk(int op, struct rtc_time *t) { - if (op) - { /* Write.... */ - Q40_RTC_CTRL |= Q40_RTC_WRITE; + if (op) { + /* Write.... */ + Q40_RTC_CTRL |= Q40_RTC_WRITE; Q40_RTC_SECS = bin2bcd(t->tm_sec); Q40_RTC_MINS = bin2bcd(t->tm_min); @@ -251,25 +258,23 @@ int q40_hwclk(int op, struct rtc_time *t) if (t->tm_wday >= 0) Q40_RTC_DOW = bin2bcd(t->tm_wday+1); - Q40_RTC_CTRL &= ~(Q40_RTC_WRITE); - } - else - { /* Read.... */ - Q40_RTC_CTRL |= Q40_RTC_READ; - - t->tm_year = bcd2bin (Q40_RTC_YEAR); - t->tm_mon = bcd2bin (Q40_RTC_MNTH)-1; - t->tm_mday = bcd2bin (Q40_RTC_DATE); - t->tm_hour = bcd2bin (Q40_RTC_HOUR); - t->tm_min = bcd2bin (Q40_RTC_MINS); - t->tm_sec = bcd2bin (Q40_RTC_SECS); - - Q40_RTC_CTRL &= ~(Q40_RTC_READ); - - if (t->tm_year < 70) - t->tm_year += 100; - t->tm_wday = bcd2bin(Q40_RTC_DOW)-1; - + Q40_RTC_CTRL &= ~(Q40_RTC_WRITE); + } else { + /* Read.... */ + Q40_RTC_CTRL |= Q40_RTC_READ; + + t->tm_year = bcd2bin (Q40_RTC_YEAR); + t->tm_mon = bcd2bin (Q40_RTC_MNTH)-1; + t->tm_mday = bcd2bin (Q40_RTC_DATE); + t->tm_hour = bcd2bin (Q40_RTC_HOUR); + t->tm_min = bcd2bin (Q40_RTC_MINS); + t->tm_sec = bcd2bin (Q40_RTC_SECS); + + Q40_RTC_CTRL &= ~(Q40_RTC_READ); + + if (t->tm_year < 70) + t->tm_year += 100; + t->tm_wday = bcd2bin(Q40_RTC_DOW)-1; } return 0; @@ -285,29 +290,25 @@ unsigned int q40_get_ss(void) * clock is out by > 30 minutes. Logic lifted from atari code. */ -int q40_set_clock_mmss (unsigned long nowtime) +int q40_set_clock_mmss(unsigned long nowtime) { int retval = 0; short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; int rtc_minutes; + rtc_minutes = bcd2bin(Q40_RTC_MINS); - rtc_minutes = bcd2bin (Q40_RTC_MINS); - - if ((rtc_minutes < real_minutes - ? real_minutes - rtc_minutes - : rtc_minutes - real_minutes) < 30) - { - Q40_RTC_CTRL |= Q40_RTC_WRITE; + if ((rtc_minutes < real_minutes ? + real_minutes - rtc_minutes : + rtc_minutes - real_minutes) < 30) { + Q40_RTC_CTRL |= Q40_RTC_WRITE; Q40_RTC_MINS = bin2bcd(real_minutes); Q40_RTC_SECS = bin2bcd(real_seconds); Q40_RTC_CTRL &= ~(Q40_RTC_WRITE); - } - else + } else retval = -1; - return retval; } @@ -318,21 +319,23 @@ int q40_set_clock_mmss (unsigned long nowtime) static int q40_get_rtc_pll(struct rtc_pll_info *pll) { - int tmp=Q40_RTC_CTRL; + int tmp = Q40_RTC_CTRL; + pll->pll_value = tmp & Q40_RTC_PLL_MASK; if (tmp & Q40_RTC_PLL_SIGN) pll->pll_value = -pll->pll_value; - pll->pll_max=31; - pll->pll_min=-31; - pll->pll_posmult=512; - pll->pll_negmult=256; - pll->pll_clock=125829120; + pll->pll_max = 31; + pll->pll_min = -31; + pll->pll_posmult = 512; + pll->pll_negmult = 256; + pll->pll_clock = 125829120; + return 0; } static int q40_set_rtc_pll(struct rtc_pll_info *pll) { - if (!pll->pll_ctrl){ + if (!pll->pll_ctrl) { /* the docs are a bit unclear so I am doublesetting */ /* RTC_WRITE here ... */ int tmp = (pll->pll_value & 31) | (pll->pll_value<0 ? 32 : 0) | diff --git a/arch/m68k/sun3x/prom.c b/arch/m68k/sun3x/prom.c index 574cf06df9e4..f23d4255a6fa 100644 --- a/arch/m68k/sun3x/prom.c +++ b/arch/m68k/sun3x/prom.c @@ -34,43 +34,43 @@ e_vector *sun3x_prom_vbr; /* Handle returning to the prom */ void sun3x_halt(void) { - unsigned long flags; + unsigned long flags; - /* Disable interrupts while we mess with things */ - local_irq_save(flags); + /* Disable interrupts while we mess with things */ + local_irq_save(flags); - /* Restore prom vbr */ - __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr)); + /* Restore prom vbr */ + asm volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr)); - /* Restore prom NMI clock */ -// sun3x_disable_intreg(5); - sun3_enable_irq(7); + /* Restore prom NMI clock */ +// sun3x_disable_intreg(5); + sun3_enable_irq(7); - /* Let 'er rip */ - __asm__ volatile ("trap #14" : : ); + /* Let 'er rip */ + asm volatile ("trap #14"); - /* Restore everything */ - sun3_disable_irq(7); - sun3_enable_irq(5); + /* Restore everything */ + sun3_disable_irq(7); + sun3_enable_irq(5); - __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors)); - local_irq_restore(flags); + asm volatile ("movec %0,%%vbr" : : "r" ((void*)vectors)); + local_irq_restore(flags); } void sun3x_reboot(void) { - /* This never returns, don't bother saving things */ - local_irq_disable(); + /* This never returns, don't bother saving things */ + local_irq_disable(); - /* Restore prom vbr */ - __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr)); + /* Restore prom vbr */ + asm volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr)); - /* Restore prom NMI clock */ - sun3_disable_irq(5); - sun3_enable_irq(7); + /* Restore prom NMI clock */ + sun3_disable_irq(5); + sun3_enable_irq(7); - /* Let 'er rip */ - (*romvec->pv_reboot)("vmlinux"); + /* Let 'er rip */ + (*romvec->pv_reboot)("vmlinux"); } extern char m68k_debug_device[]; @@ -78,54 +78,52 @@ extern char m68k_debug_device[]; static void sun3x_prom_write(struct console *co, const char *s, unsigned int count) { - while (count--) { - if (*s == '\n') - sun3x_putchar('\r'); - sun3x_putchar(*s++); - } + while (count--) { + if (*s == '\n') + sun3x_putchar('\r'); + sun3x_putchar(*s++); + } } /* debug console - write-only */ static struct console sun3x_debug = { - .name = "debug", - .write = sun3x_prom_write, - .flags = CON_PRINTBUFFER, - .index = -1, + .name = "debug", + .write = sun3x_prom_write, + .flags = CON_PRINTBUFFER, + .index = -1, }; void sun3x_prom_init(void) { - /* Read the vector table */ - - sun3x_putchar = *(void (**)(int)) (SUN3X_P_PUTCHAR); - sun3x_getchar = *(int (**)(void)) (SUN3X_P_GETCHAR); - sun3x_mayget = *(int (**)(void)) (SUN3X_P_MAYGET); - sun3x_mayput = *(int (**)(int)) (SUN3X_P_MAYPUT); - sun3x_prom_reboot = *(void (**)(void)) (SUN3X_P_REBOOT); - sun3x_prom_abort = *(e_vector *) (SUN3X_P_ABORT); - romvec = (struct linux_romvec *)SUN3X_PROM_BASE; - - idprom_init(); - - if(!((idprom->id_machtype & SM_ARCH_MASK) == SM_SUN3X)) { - printk("Warning: machine reports strange type %02x\n", - idprom->id_machtype); - printk("Pretending it's a 3/80, but very afraid...\n"); - idprom->id_machtype = SM_SUN3X | SM_3_80; - } - - /* point trap #14 at abort. - * XXX this is futile since we restore the vbr first - oops - */ - vectors[VEC_TRAP14] = sun3x_prom_abort; - - /* If debug=prom was specified, start the debug console */ - - if (!strcmp(m68k_debug_device, "prom")) - register_console(&sun3x_debug); - - + /* Read the vector table */ + + sun3x_putchar = *(void (**)(int)) (SUN3X_P_PUTCHAR); + sun3x_getchar = *(int (**)(void)) (SUN3X_P_GETCHAR); + sun3x_mayget = *(int (**)(void)) (SUN3X_P_MAYGET); + sun3x_mayput = *(int (**)(int)) (SUN3X_P_MAYPUT); + sun3x_prom_reboot = *(void (**)(void)) (SUN3X_P_REBOOT); + sun3x_prom_abort = *(e_vector *) (SUN3X_P_ABORT); + romvec = (struct linux_romvec *)SUN3X_PROM_BASE; + + idprom_init(); + + if (!((idprom->id_machtype & SM_ARCH_MASK) == SM_SUN3X)) { + printk("Warning: machine reports strange type %02x\n", + idprom->id_machtype); + printk("Pretending it's a 3/80, but very afraid...\n"); + idprom->id_machtype = SM_SUN3X | SM_3_80; + } + + /* point trap #14 at abort. + * XXX this is futile since we restore the vbr first - oops + */ + vectors[VEC_TRAP14] = sun3x_prom_abort; + + /* If debug=prom was specified, start the debug console */ + + if (!strcmp(m68k_debug_device, "prom")) + register_console(&sun3x_debug); } /* some prom functions to export */ @@ -141,7 +139,6 @@ int prom_getbool (int node, char *prop) void prom_printf(char *fmt, ...) { - } void prom_halt (void) @@ -159,7 +156,7 @@ prom_get_idprom(char *idbuf, int num_bytes) int i; /* make a copy of the idprom structure */ - for(i = 0; i < num_bytes; i++) + for (i = 0; i < num_bytes; i++) idbuf[i] = ((char *)SUN3X_IDPROM)[i]; return idbuf[0]; -- cgit v1.2.3-59-g8ed1b From d6713b4091a99fa2af2fabdcd2f3fb97f32ecf2e Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Tue, 1 May 2007 22:32:45 +0200 Subject: m68k: early parameter support Add early parameter support and convert current users to it. Signed-off-by: Roman Zippel Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/amiga/config.c | 41 ++++++++++++++++++++++------------------- arch/m68k/atari/config.c | 17 +++++++++-------- arch/m68k/atari/debug.c | 24 ++++++++++++++---------- arch/m68k/kernel/setup.c | 39 +-------------------------------------- arch/m68k/mac/config.c | 8 -------- arch/m68k/mac/debug.c | 20 ++++++++++---------- arch/m68k/q40/config.c | 23 ++++++++++++++--------- arch/m68k/sun3x/prom.c | 11 +++++++---- 8 files changed, 77 insertions(+), 106 deletions(-) (limited to 'arch') diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c index c3b69b1b0cef..35748531327d 100644 --- a/arch/m68k/amiga/config.c +++ b/arch/m68k/amiga/config.c @@ -79,8 +79,6 @@ static char *amiga_models[] __initdata = { static char amiga_model_name[13] = "Amiga "; -extern char m68k_debug_device[]; - static void amiga_sched_init(irq_handler_t handler); /* amiga specific irq functions */ extern void amiga_init_IRQ(void); @@ -95,12 +93,10 @@ static unsigned int amiga_get_ss(void); extern void amiga_mksound(unsigned int count, unsigned int ticks); static void amiga_reset(void); extern void amiga_init_sound(void); -static void amiga_savekmsg_init(void); static void amiga_mem_console_write(struct console *co, const char *b, unsigned int count); void amiga_serial_console_write(struct console *co, const char *s, unsigned int count); -static void amiga_debug_init(void); #ifdef CONFIG_HEARTBEAT static void amiga_heartbeat(int on); #endif @@ -370,7 +366,6 @@ void __init config_amiga(void) { int i; - amiga_debug_init(); amiga_identify(); /* Yuk, we don't have PCI memory */ @@ -458,17 +453,6 @@ void __init config_amiga(void) /* initialize chipram allocator */ amiga_chip_init(); - /* debugging using chipram */ - if (!strcmp(m68k_debug_device, "mem")) { - if (!AMIGAHW_PRESENT(CHIP_RAM)) - printk("Warning: no chipram present for debugging\n"); - else { - amiga_savekmsg_init(); - amiga_console_driver.write = amiga_mem_console_write; - register_console(&amiga_console_driver); - } - } - /* our beloved beeper */ if (AMIGAHW_PRESENT(AMI_AUDIO)) amiga_init_sound(); @@ -787,17 +771,33 @@ static void amiga_mem_console_write(struct console *co, const char *s, } } -static void amiga_savekmsg_init(void) +static int __init amiga_savekmsg_setup(char *arg) { static struct resource debug_res = { .name = "Debug" }; + if (!MACH_IS_AMIGA || strcmp(arg, "mem")) + goto done; + + if (!AMIGAHW_PRESENT(CHIP_RAM)) { + printk("Warning: no chipram present for debugging\n"); + goto done; + } + savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res); savekmsg->magic1 = SAVEKMSG_MAGIC1; savekmsg->magic2 = SAVEKMSG_MAGIC2; savekmsg->magicptr = ZTWO_PADDR(savekmsg); savekmsg->size = 0; + + amiga_console_driver.write = amiga_mem_console_write; + register_console(&amiga_console_driver); + +done: + return 0; } +early_param("debug", amiga_savekmsg_setup); + static void amiga_serial_putc(char c) { amiga_custom.serdat = (unsigned char)c | 0x100; @@ -872,15 +872,18 @@ void amiga_serial_gets(struct console *co, char *s, int len) } #endif -static void __init amiga_debug_init(void) +static int __init amiga_debug_setup(char *arg) { - if (!strcmp(m68k_debug_device, "ser" )) { + if (MACH_IS_AMIGA && !strcmp(arg, "ser")) { /* no initialization required (?) */ amiga_console_driver.write = amiga_serial_console_write; register_console(&amiga_console_driver); } + return 0; } +early_param("debug", amiga_debug_setup); + #ifdef CONFIG_HEARTBEAT static void amiga_heartbeat(int on) { diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c index b10e7addae5c..e40e5dcaa347 100644 --- a/arch/m68k/atari/config.c +++ b/arch/m68k/atari/config.c @@ -69,9 +69,6 @@ extern int atari_tt_hwclk (int, struct rtc_time *); extern int atari_mste_set_clock_mmss (unsigned long); extern int atari_tt_set_clock_mmss (unsigned long); -/* atari specific debug functions (in debug.c) */ -extern void atari_debug_init(void); - /* ++roman: This is a more elaborate test for an SCC chip, since the plain * Medusa board generates DTACK at the SCC's standard addresses, but a SCC @@ -137,15 +134,18 @@ int __init atari_parse_bootinfo(const struct bi_record *record) /* Parse the Atari-specific switches= option. */ -void __init atari_switches_setup(const char *str, unsigned len) +static int __init atari_switches_setup(char *str) { - char switches[len+1]; + char switches[strlen(str) + 1]; char *p; int ovsc_shift; char *args = switches; + if (!MACH_IS_ATARI) + return 0; + /* copy string to local array, strsep works destructively... */ - strlcpy(switches, str, sizeof(switches)); + strcpy(switches, str); atari_switches = 0; /* parse the options */ @@ -170,8 +170,11 @@ void __init atari_switches_setup(const char *str, unsigned len) atari_switches |= ATARI_SWITCH_SND7 << ovsc_shift; } } + return 0; } +early_param("switches", atari_switches_setup); + /* * Setup the Atari configuration info @@ -183,8 +186,6 @@ void __init config_atari(void) memset(&atari_hw_present, 0, sizeof(atari_hw_present)); - atari_debug_init(); - /* Change size of I/O space from 64KB to 4GB. */ ioport_resource.end = 0xFFFFFFFF; diff --git a/arch/m68k/atari/debug.c b/arch/m68k/atari/debug.c index 66983fe87509..fbeed8c8ecbc 100644 --- a/arch/m68k/atari/debug.c +++ b/arch/m68k/atari/debug.c @@ -19,8 +19,6 @@ #include #include -extern char m68k_debug_device[]; - /* Flag that Modem1 port is already initialized and used */ int atari_MFP_init_done; /* Flag that Modem1 port is already initialized and used */ @@ -305,26 +303,28 @@ void atari_init_midi_port(int cflag) ACIA_RHTID : ACIA_RLTID); } -void __init atari_debug_init(void) +static int __init atari_debug_setup(char *arg) { - if (!strcmp(m68k_debug_device, "ser")) { + if (!MACH_IS_ATARI) + return 0; + + if (!strcmp(arg, "ser")) /* defaults to ser2 for a Falcon and ser1 otherwise */ - strcpy(m68k_debug_device, MACH_IS_FALCON ? "ser2" : "ser1"); - } + arg = MACH_IS_FALCON ? "ser2" : "ser1"; - if (!strcmp(m68k_debug_device, "ser1")) { + if (!strcmp(arg, "ser1")) { /* ST-MFP Modem1 serial port */ atari_init_mfp_port(B9600|CS8); atari_console_driver.write = atari_mfp_console_write; - } else if (!strcmp(m68k_debug_device, "ser2")) { + } else if (!strcmp(arg, "ser2")) { /* SCC Modem2 serial port */ atari_init_scc_port(B9600|CS8); atari_console_driver.write = atari_scc_console_write; - } else if (!strcmp(m68k_debug_device, "midi")) { + } else if (!strcmp(arg, "midi")) { /* MIDI port */ atari_init_midi_port(B9600|CS8); atari_console_driver.write = atari_midi_console_write; - } else if (!strcmp(m68k_debug_device, "par")) { + } else if (!strcmp(arg, "par")) { /* parallel printer */ atari_turnoff_irq(IRQ_MFP_BUSY); /* avoid ints */ sound_ym.rd_data_reg_sel = 7; /* select mixer control */ @@ -337,4 +337,8 @@ void __init atari_debug_init(void) } if (atari_console_driver.write) register_console(&atari_console_driver); + + return 0; } + +early_param("debug", atari_debug_setup); diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index 852cefe7c800..9b307a5f4f22 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c @@ -71,9 +71,6 @@ static struct mem_info m68k_ramdisk; static char m68k_command_line[CL_SIZE]; -char m68k_debug_device[6] = ""; -EXPORT_SYMBOL(m68k_debug_device); - void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL; /* machine dependent irq functions */ void (*mach_init_IRQ) (void) __initdata = NULL; @@ -215,7 +212,6 @@ void __init setup_arch(char **cmdline_p) unsigned long endmem, startmem; #endif int i; - char *p, *q; /* The bootinfo is located right after the kernel bss */ m68k_parse_bootinfo((const struct bi_record *)&_end); @@ -258,40 +254,7 @@ void __init setup_arch(char **cmdline_p) *cmdline_p = m68k_command_line; memcpy(boot_command_line, *cmdline_p, CL_SIZE); - /* Parse the command line for arch-specific options. - * For the m68k, this is currently only "debug=xxx" to enable printing - * certain kernel messages to some machine-specific device. - */ - for (p = *cmdline_p; p && *p;) { - i = 0; - if (!strncmp(p, "debug=", 6)) { - strlcpy(m68k_debug_device, p+6, sizeof(m68k_debug_device)); - q = strchr(m68k_debug_device, ' '); - if (q) - *q = 0; - i = 1; - } -#ifdef CONFIG_ATARI - /* This option must be parsed very early */ - if (!strncmp(p, "switches=", 9)) { - extern void atari_switches_setup(const char *, int); - q = strchr(p + 9, ' '); - atari_switches_setup(p + 9, q ? (q - (p + 9)) : strlen(p + 9)); - i = 1; - } -#endif - - if (i) { - /* option processed, delete it */ - if ((q = strchr(p, ' '))) - strcpy(p, q + 1); - else - *p = 0; - } else { - if ((p = strchr(p, ' '))) - ++p; - } - } + parse_early_param(); #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c index d2fbf436a1fb..5fd413246f89 100644 --- a/arch/m68k/mac/config.c +++ b/arch/m68k/mac/config.c @@ -82,10 +82,6 @@ extern void mac_mksound(unsigned int, unsigned int); extern void nubus_sweep_video(void); -/* Mac specific debug functions (in debug.c) */ -extern void mac_debug_init(void); -extern void mac_debugging_long(int, long); - static void mac_get_model(char *str); static void mac_sched_init(irq_handler_t vector) @@ -180,9 +176,6 @@ void __init config_mac(void) mach_halt = mac_poweroff; mach_power_off = mac_poweroff; mach_max_dma_address = 0xffffffff; -#if 0 - mach_debug_init = mac_debug_init; -#endif #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) mach_beep = mac_mksound; #endif @@ -802,7 +795,6 @@ void mac_identify(void) /* the serial ports set to "Faster" mode in MacOS. */ iop_preinit(); - mac_debug_init(); printk(KERN_INFO "Detected Macintosh model: %d \n", model); diff --git a/arch/m68k/mac/debug.c b/arch/m68k/mac/debug.c index 83990326099b..7a5bed5bdc57 100644 --- a/arch/m68k/mac/debug.c +++ b/arch/m68k/mac/debug.c @@ -27,10 +27,6 @@ #include #include -extern char m68k_debug_device[]; - -extern struct compat_bootinfo compat_boot_info; - extern unsigned long mac_videobase; extern unsigned long mac_videodepth; extern unsigned long mac_rowbytes; @@ -360,16 +356,18 @@ void mac_init_sccb_port(int cflag) mac_init_scc_port(cflag, 1); } -void __init mac_debug_init(void) +static int __init mac_debug_setup(char *arg) { + if (!MACH_IS_MAC) + return 0; + #ifdef DEBUG_SERIAL - if (!strcmp(m68k_debug_device, "ser") || - !strcmp(m68k_debug_device, "ser1")) { + if (!strcmp(arg, "ser") || !strcmp(arg, "ser1")) { /* Mac modem port */ mac_init_scc_port(B9600|CS8, 0); mac_console_driver.write = mac_scca_console_write; scc_port = 0; - } else if (!strcmp(m68k_debug_device, "ser2")) { + } else if (!strcmp(arg, "ser2")) { /* Mac printer port */ mac_init_scc_port(B9600|CS8, 1); mac_console_driver.write = mac_sccb_console_write; @@ -377,12 +375,14 @@ void __init mac_debug_init(void) } #endif #ifdef DEBUG_HEADS - if (!strcmp(m68k_debug_device, "scn") || - !strcmp(m68k_debug_device, "con")) { + if (!strcmp(arg, "scn") || !strcmp(arg, "con")) { /* display, using head.S console routines */ mac_console_driver.write = mac_debug_console_write; } #endif if (mac_console_driver.write) register_console(&mac_console_driver); + return 0; } + +early_param("debug", mac_debug_setup); diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index 4c5b9e4e98bc..476e18eca758 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c @@ -54,7 +54,6 @@ void q40_set_vectors(void); extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/); -extern char m68k_debug_device[]; static void q40_mem_console_write(struct console *co, const char *b, unsigned int count); @@ -62,6 +61,7 @@ extern int ql_ticks; static struct console q40_console_driver = { .name = "debug", + .write = q40_mem_console_write, .flags = CON_PRINTBUFFER, .index = -1, }; @@ -85,6 +85,19 @@ static void q40_mem_console_write(struct console *co, const char *s, } } +static int __init q40_debug_setup(char *arg) +{ + /* useful for early debugging stages - writes kernel messages into SRAM */ + if (MACH_IS_Q40 && !strncmp(arg, "mem", 3)) { + /*printk("using NVRAM debug, q40_mem_cptr=%p\n",q40_mem_cptr);*/ + _cpleft = 2000 - ((long)q40_mem_cptr-0xff020000) / 4; + register_console(&q40_console_driver); + } + return 0; +} + +early_param("debug", q40_debug_setup); + #if 0 void printq40(char *str) { @@ -194,14 +207,6 @@ void __init config_q40(void) * all physical RAM fits into the boundary - otherwise * allocator may play costly and useless tricks */ mach_max_dma_address = 1024*1024*1024; - - /* useful for early debugging stages - writes kernel messages into SRAM */ - if (!strncmp( m68k_debug_device,"mem", 3)) { - /*printk("using NVRAM debug, q40_mem_cptr=%p\n",q40_mem_cptr);*/ - _cpleft = 2000 - ((long)q40_mem_cptr-0xff020000) / 4; - q40_console_driver.write = q40_mem_console_write; - register_console(&q40_console_driver); - } } diff --git a/arch/m68k/sun3x/prom.c b/arch/m68k/sun3x/prom.c index f23d4255a6fa..48f8eb7b1565 100644 --- a/arch/m68k/sun3x/prom.c +++ b/arch/m68k/sun3x/prom.c @@ -73,8 +73,6 @@ void sun3x_reboot(void) (*romvec->pv_reboot)("vmlinux"); } -extern char m68k_debug_device[]; - static void sun3x_prom_write(struct console *co, const char *s, unsigned int count) { @@ -119,13 +117,18 @@ void sun3x_prom_init(void) * XXX this is futile since we restore the vbr first - oops */ vectors[VEC_TRAP14] = sun3x_prom_abort; +} +static int __init sun3x_debug_setup(char *arg) +{ /* If debug=prom was specified, start the debug console */ - - if (!strcmp(m68k_debug_device, "prom")) + if (MACH_IS_SUN3X && !strcmp(arg, "prom")) register_console(&sun3x_debug); + return 0; } +early_param("debug", sun3x_debug_setup); + /* some prom functions to export */ int prom_getintdefault(int node, char *property, int deflt) { -- cgit v1.2.3-59-g8ed1b From 35bdd52d7401b1208552523d6fa28d4a37dbc74d Mon Sep 17 00:00:00 2001 From: Sam Creasey Date: Tue, 1 May 2007 22:32:47 +0200 Subject: m68k: Correct number of interrupts for Sun3 Only attempt to initialize the amount of interrupts a sun3 actually has... Signed-off-by: Sam Creasey Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/sun3/sun3ints.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c index baf74e8de8b5..4232a2c2fae9 100644 --- a/arch/m68k/sun3/sun3ints.c +++ b/arch/m68k/sun3/sun3ints.c @@ -103,7 +103,7 @@ void sun3_init_IRQ(void) m68k_setup_auto_interrupt(sun3_inthandle); m68k_setup_irq_controller(&sun3_irq_controller, IRQ_AUTO_1, 7); - m68k_setup_user_interrupt(VEC_USER, 192, NULL); + m68k_setup_user_interrupt(VEC_USER, 128, NULL); request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL); request_irq(IRQ_AUTO_7, sun3_int7, 0, "int7", NULL); -- cgit v1.2.3-59-g8ed1b From e10e5c4325b37e1a7dce9cd3d2cbcd8dd9536a7a Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Tue, 1 May 2007 22:32:52 +0200 Subject: m68k: Mac interrupt priorities Add some more machines that support A/UX interrupt priorities. There are probably others as well, but I've only tested these ones so far. Signed-off-by: Finn Thain Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/mac/via.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c index e27735be2924..2be7b9cc5b32 100644 --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c @@ -193,8 +193,14 @@ void __init via_init(void) /* that the IIfx emulates this alternate mapping using the OSS. */ switch(macintosh_config->ident) { + case MAC_MODEL_P475: + case MAC_MODEL_P475F: + case MAC_MODEL_P575: + case MAC_MODEL_Q605: + case MAC_MODEL_Q605_ACC: case MAC_MODEL_C610: case MAC_MODEL_Q610: + case MAC_MODEL_Q630: case MAC_MODEL_C650: case MAC_MODEL_Q650: case MAC_MODEL_Q700: -- cgit v1.2.3-59-g8ed1b From 647b804c8237aa35e19caf8e11ea8d5565107b0e Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Tue, 1 May 2007 22:32:55 +0200 Subject: m68k: reverse Mac IRQ damage Reverse the last of a monumental brown-paper-bag commit that went into the 2.3 kernel. Signed-off-by: Finn Thain Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/mac/baboon.c | 2 +- arch/m68k/mac/oss.c | 6 +++--- arch/m68k/mac/psc.c | 2 +- arch/m68k/mac/via.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c index a1c7ec706741..303a3b56c51c 100644 --- a/arch/m68k/mac/baboon.c +++ b/arch/m68k/mac/baboon.c @@ -81,9 +81,9 @@ irqreturn_t baboon_irq(int irq, void *dev_id) for (i = 0, irq_bit = 1 ; i < 3 ; i++, irq_bit <<= 1) { if (events & irq_bit/* & baboon_active*/) { baboon_active &= ~irq_bit; + baboon->mb_ifr &= ~irq_bit; m68k_handle_int(IRQ_BABOON_0 + i); baboon_active |= irq_bit; - baboon->mb_ifr &= ~irq_bit; } } #if 0 diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c index 63690819565a..603d5cb72891 100644 --- a/arch/m68k/mac/oss.c +++ b/arch/m68k/mac/oss.c @@ -109,12 +109,12 @@ irqreturn_t oss_irq(int irq, void *dev_id) /* FIXME: how do you clear a pending IRQ? */ if (events & OSS_IP_SOUND) { - /* FIXME: call sound handler */ oss->irq_pending &= ~OSS_IP_SOUND; + /* FIXME: call sound handler */ } else if (events & OSS_IP_SCSI) { oss->irq_level[OSS_SCSI] = OSS_IRQLEV_DISABLED; - m68k_handle_int(IRQ_MAC_SCSI); oss->irq_pending &= ~OSS_IP_SCSI; + m68k_handle_int(IRQ_MAC_SCSI); oss->irq_level[OSS_SCSI] = OSS_IRQLEV_SCSI; } else { /* FIXME: error check here? */ @@ -146,8 +146,8 @@ irqreturn_t oss_nubus_irq(int irq, void *dev_id) for (i = 0, irq_bit = 1 ; i < 6 ; i++, irq_bit <<= 1) { if (events & irq_bit) { oss->irq_level[i] = OSS_IRQLEV_DISABLED; - m68k_handle_int(NUBUS_SOURCE_BASE + i); oss->irq_pending &= ~irq_bit; + m68k_handle_int(NUBUS_SOURCE_BASE + i); oss->irq_level[i] = OSS_IRQLEV_NUBUS; } } diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c index 15378a5878c9..401147985a96 100644 --- a/arch/m68k/mac/psc.c +++ b/arch/m68k/mac/psc.c @@ -149,8 +149,8 @@ irqreturn_t psc_irq(int irq, void *dev_id) for (i = 0, irq_bit = 1 ; i < 4 ; i++, irq_bit <<= 1) { if (events & irq_bit) { psc_write_byte(pIER, irq_bit); - m68k_handle_int(base_irq + i); psc_write_byte(pIFR, irq_bit); + m68k_handle_int(base_irq + i); psc_write_byte(pIER, irq_bit | 0x80); } } diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c index 2be7b9cc5b32..21b03180d9f4 100644 --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c @@ -430,8 +430,8 @@ irqreturn_t via1_irq(int irq, void *dev_id) for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) if (events & irq_bit) { via1[vIER] = irq_bit; - m68k_handle_int(VIA1_SOURCE_BASE + i); via1[vIFR] = irq_bit; + m68k_handle_int(VIA1_SOURCE_BASE + i); via1[vIER] = irq_bit | 0x80; } -- cgit v1.2.3-59-g8ed1b From 67dfb153a352e57e71404d550be7eb60d15d7f2d Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Tue, 1 May 2007 22:32:56 +0200 Subject: m68k: Mac IRQ prep Make sure that there are no slot IRQs asserted before leaving the nubus handler. If there are and we don't then the nubus gets wedged because this prevents a CA1 transition, which means no more nubus IRQs. Make the interrupt dispatch loops terminate sooner. Explicitly initialise the VIA latches to make the code more easily understood. Also some cleanups. Signed-off-by: Finn Thain Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/mac/baboon.c | 12 +++-- arch/m68k/mac/oss.c | 8 ++- arch/m68k/mac/psc.c | 19 +++---- arch/m68k/mac/via.c | 141 ++++++++++++++++++++++++++++++------------------- 4 files changed, 111 insertions(+), 69 deletions(-) (limited to 'arch') diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c index 303a3b56c51c..8ea7498cec37 100644 --- a/arch/m68k/mac/baboon.c +++ b/arch/m68k/mac/baboon.c @@ -66,7 +66,7 @@ void __init baboon_register_interrupts(void) irqreturn_t baboon_irq(int irq, void *dev_id) { - int irq_bit,i; + int irq_bit, irq_num; unsigned char events; #ifdef DEBUG_IRQS @@ -78,14 +78,18 @@ irqreturn_t baboon_irq(int irq, void *dev_id) if (!(events = baboon->mb_ifr & 0x07)) return IRQ_NONE; - for (i = 0, irq_bit = 1 ; i < 3 ; i++, irq_bit <<= 1) { + irq_num = IRQ_BABOON_0; + irq_bit = 1; + do { if (events & irq_bit/* & baboon_active*/) { baboon_active &= ~irq_bit; baboon->mb_ifr &= ~irq_bit; - m68k_handle_int(IRQ_BABOON_0 + i); + m68k_handle_int(irq_num); baboon_active |= irq_bit; } - } + irq_bit <<= 1; + irq_num++; + } while(events >= irq_bit); #if 0 if (baboon->mb_ifr & 0x02) macide_ack_intr(NULL); /* for now we need to smash all interrupts */ diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c index 603d5cb72891..6399883ae742 100644 --- a/arch/m68k/mac/oss.c +++ b/arch/m68k/mac/oss.c @@ -143,14 +143,18 @@ irqreturn_t oss_nubus_irq(int irq, void *dev_id) #endif /* There are only six slots on the OSS, not seven */ - for (i = 0, irq_bit = 1 ; i < 6 ; i++, irq_bit <<= 1) { + i = 6; + irq_bit = 0x40; + do { + --i; + irq_bit >>= 1; if (events & irq_bit) { oss->irq_level[i] = OSS_IRQLEV_DISABLED; oss->irq_pending &= ~irq_bit; m68k_handle_int(NUBUS_SOURCE_BASE + i); oss->irq_level[i] = OSS_IRQLEV_NUBUS; } - } + } while(events & (irq_bit - 1)); return IRQ_HANDLED; } diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c index 401147985a96..1dba88247c6f 100644 --- a/arch/m68k/mac/psc.c +++ b/arch/m68k/mac/psc.c @@ -131,11 +131,8 @@ irqreturn_t psc_irq(int irq, void *dev_id) { int pIFR = pIFRbase + ((int) dev_id); int pIER = pIERbase + ((int) dev_id); - int base_irq; - int irq_bit,i; - unsigned char events; - - base_irq = irq << 3; + int irq_num; + unsigned char irq_bit, events; #ifdef DEBUG_IRQS printk("psc_irq: irq %d pIFR = 0x%02X pIER = 0x%02X\n", @@ -146,14 +143,18 @@ irqreturn_t psc_irq(int irq, void *dev_id) if (!events) return IRQ_NONE; - for (i = 0, irq_bit = 1 ; i < 4 ; i++, irq_bit <<= 1) { - if (events & irq_bit) { + irq_num = irq << 3; + irq_bit = 1; + do { + if (events & irq_bit) { psc_write_byte(pIER, irq_bit); psc_write_byte(pIFR, irq_bit); - m68k_handle_int(base_irq + i); + m68k_handle_int(irq_num); psc_write_byte(pIER, irq_bit | 0x80); } - } + irq_num++; + irq_bit <<= 1; + } while (events >= irq_bit); return IRQ_HANDLED; } diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c index 21b03180d9f4..0c1cc45c570d 100644 --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c @@ -13,6 +13,10 @@ * for info. A full-text web search on 6522 AND VIA will probably also * net some usefulness. 20apr1999 * + * Additional data is here (the SY6522 was used in the Mac II etc): + * http://www.6502.org/documents/datasheets/synertek/synertek_sy6522.pdf + * http://www.6502.org/documents/datasheets/synertek/synertek_sy6522_programming_reference.pdf + * * PRAM/RTC access algorithms are from the NetBSD RTC toolkit version 1.08b * by Erik Vogan and adapted to Linux by Joshua M. Thompson (funaho@jurai.org) * @@ -37,7 +41,7 @@ volatile __u8 *via1, *via2; /* See note in mac_via.h about how this is possibly not useful */ volatile long *via_memory_bogon=(long *)&via_memory_bogon; #endif -int rbv_present,via_alt_mapping; +int rbv_present, via_alt_mapping; __u8 rbv_clear; /* @@ -138,11 +142,11 @@ void __init via_init(void) printk(KERN_INFO "VIA2 at %p is ", via2); if (rbv_present) { - printk(KERN_INFO "an RBV\n"); + printk("an RBV\n"); } else if (oss_present) { - printk(KERN_INFO "an OSS\n"); + printk("an OSS\n"); } else { - printk(KERN_INFO "a 6522 or clone\n"); + printk("a 6522 or clone\n"); } #ifdef DEBUG_VIA @@ -163,6 +167,7 @@ void __init via_init(void) via1[vT2CL] = 0; via1[vT2CH] = 0; via1[vACR] &= 0x3F; + via1[vACR] &= ~0x03; /* disable port A & B latches */ /* * SE/30: disable video IRQ @@ -234,6 +239,22 @@ void __init via_init(void) via2[vT2CL] = 0; via2[vT2CH] = 0; via2[vACR] &= 0x3F; + via2[vACR] &= ~0x03; /* disable port A & B latches */ + } + + /* + * Set vPCR for SCSI interrupts (but not on RBV) + */ + if (!rbv_present) { + if (macintosh_config->scsi_type == MAC_SCSI_OLD) { + /* CB2 (IRQ) indep. input, positive edge */ + /* CA2 (DRQ) indep. input, positive edge */ + via2[vPCR] = 0x66; + } else { + /* CB2 (IRQ) indep. input, negative edge */ + /* CA2 (DRQ) indep. input, negative edge */ + via2[vPCR] = 0x22; + } } } @@ -367,19 +388,14 @@ void __init via_nubus_init(void) /* unlock nubus transactions */ - if (!rbv_present) { + if ((macintosh_config->adb_type != MAC_ADB_PB1) && + (macintosh_config->adb_type != MAC_ADB_PB2)) { /* set the line to be an output on non-RBV machines */ - if ((macintosh_config->adb_type != MAC_ADB_PB1) && - (macintosh_config->adb_type != MAC_ADB_PB2)) { + if (!rbv_present) via2[vDirB] |= 0x02; - } - } - - /* this seems to be an ADB bit on PMU machines */ - /* according to MkLinux. -- jmt */ - if ((macintosh_config->adb_type != MAC_ADB_PB1) && - (macintosh_config->adb_type != MAC_ADB_PB2)) { + /* this seems to be an ADB bit on PMU machines */ + /* according to MkLinux. -- jmt */ via2[gBufB] |= 0x02; } @@ -420,20 +436,25 @@ void __init via_nubus_init(void) irqreturn_t via1_irq(int irq, void *dev_id) { - int irq_bit, i; - unsigned char events, mask; + int irq_num; + unsigned char irq_bit, events; - mask = via1[vIER] & 0x7F; - if (!(events = via1[vIFR] & mask)) + events = via1[vIFR] & via1[vIER] & 0x7F; + if (!events) return IRQ_NONE; - for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) + irq_num = VIA1_SOURCE_BASE; + irq_bit = 1; + do { if (events & irq_bit) { via1[vIER] = irq_bit; via1[vIFR] = irq_bit; - m68k_handle_int(VIA1_SOURCE_BASE + i); + m68k_handle_int(irq_num); via1[vIER] = irq_bit | 0x80; } + ++irq_num; + irq_bit <<= 1; + } while (events >= irq_bit); #if 0 /* freakin' pmu is doing weird stuff */ if (!oss_present) { @@ -454,20 +475,25 @@ irqreturn_t via1_irq(int irq, void *dev_id) irqreturn_t via2_irq(int irq, void *dev_id) { - int irq_bit, i; - unsigned char events, mask; + int irq_num; + unsigned char irq_bit, events; - mask = via2[gIER] & 0x7F; - if (!(events = via2[gIFR] & mask)) + events = via2[gIFR] & via2[gIER] & 0x7F; + if (!events) return IRQ_NONE; - for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) + irq_num = VIA2_SOURCE_BASE; + irq_bit = 1; + do { if (events & irq_bit) { via2[gIER] = irq_bit; via2[gIFR] = irq_bit | rbv_clear; - m68k_handle_int(VIA2_SOURCE_BASE + i); + m68k_handle_int(irq_num); via2[gIER] = irq_bit | 0x80; } + ++irq_num; + irq_bit <<= 1; + } while (events >= irq_bit); return IRQ_HANDLED; } @@ -478,19 +504,37 @@ irqreturn_t via2_irq(int irq, void *dev_id) irqreturn_t via_nubus_irq(int irq, void *dev_id) { - int irq_bit, i; - unsigned char events; - - if (!(events = ~via2[gBufA] & nubus_active)) + int slot_irq; + unsigned char slot_bit, events; + + events = ~via2[gBufA] & 0x7F; + if (rbv_present) + events &= via2[rSIER]; + else + events &= nubus_active; + if (!events) return IRQ_NONE; - for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) { - if (events & irq_bit) { - via_irq_disable(NUBUS_SOURCE_BASE + i); - m68k_handle_int(NUBUS_SOURCE_BASE + i); - via_irq_enable(NUBUS_SOURCE_BASE + i); - } - } + do { + slot_irq = IRQ_NUBUS_F; + slot_bit = 0x40; + do { + if (events & slot_bit) { + events &= ~slot_bit; + m68k_handle_int(slot_irq); + } + --slot_irq; + slot_bit >>= 1; + } while (events); + + /* clear the CA1 interrupt and make certain there's no more. */ + via2[gIFR] = 0x02 | rbv_clear; + events = ~via2[gBufA] & 0x7F; + if (rbv_present) + events &= via2[rSIER]; + else + events &= nubus_active; + } while (events); return IRQ_HANDLED; } @@ -506,20 +550,6 @@ void via_irq_enable(int irq) { if (irq_src == 1) { via1[vIER] = irq_bit | 0x80; } else if (irq_src == 2) { - /* - * Set vPCR for SCSI interrupts (but not on RBV) - */ - if ((irq_idx == 0) && !rbv_present) { - if (macintosh_config->scsi_type == MAC_SCSI_OLD) { - /* CB2 (IRQ) indep. input, positive edge */ - /* CA2 (DRQ) indep. input, positive edge */ - via2[vPCR] = 0x66; - } else { - /* CB2 (IRQ) indep. input, negative edge */ - /* CA2 (DRQ) indep. input, negative edge */ - via2[vPCR] = 0x22; - } - } via2[gIER] = irq_bit | 0x80; } else if (irq_src == 7) { nubus_active |= irq_bit; @@ -557,9 +587,9 @@ void via_irq_disable(int irq) { #endif if (irq_src == 1) { - via1[vIER] = irq_bit; + via1[vIER] = irq_bit & 0x7F; } else if (irq_src == 2) { - via2[gIER] = irq_bit; + via2[gIER] = irq_bit & 0x7F; } else if (irq_src == 7) { if (rbv_present) { /* disable the slot interrupt. SIER works like IER. */ @@ -586,7 +616,9 @@ void via_irq_clear(int irq) { } else if (irq_src == 2) { via2[gIFR] = irq_bit | rbv_clear; } else if (irq_src == 7) { - /* FIXME: hmm.. */ + /* FIXME: There is no way to clear an individual nubus slot + * IRQ flag, other than getting the device to do it. + */ } } @@ -606,6 +638,7 @@ int via_irq_pending(int irq) } else if (irq_src == 2) { return via2[gIFR] & irq_bit; } else if (irq_src == 7) { + /* FIXME: this can't work while a slot irq is disabled! */ return ~via2[gBufA] & irq_bit; } return 0; -- cgit v1.2.3-59-g8ed1b From cd713ddc93bf2f612783aea8eff6d0df6107765e Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Tue, 1 May 2007 22:32:57 +0200 Subject: m68k: Mac nubus IRQ fixes (plan E) Some Macs lack a slot interrupt enable register. So the existing code makes disabled and unregistered slot IRQ lines outputs set high. This seems to work on quadras, but does not work on genuine VIAs (perhaps the card still succeeds in pulling the line low, or perhaps because this increases the settle time on the port A input, meaning that the CA1 IRQ could fire before the slot line reads active). Because of this, the nubus_active flags were used to mask IRQs, which is actually worse than the problem it tries to solve. Any interrupt masked by nubus_active will remain asserted and prevent further transitions on CA1. And so the nubus gets wedged regardless of hardware (emulated VIA ASIC, real VIA chip or RBV). The best solution to this hardware limitation of genuine VIAs is to disable the umbrella SLOTS IRQ when disabling a slot on those machines. Unfortunately, this means all slot IRQs get disabled when any slot IRQ is disabled. But it is only a problem when there's more than 1 device using nubus interrupts. Another potential problem for genuine VIAs is an unregistered nubus IRQ. Eventually it will be possible to enable the CA1 interrupt by installing its handler only _after_ all nubus drivers have loaded but _before_ the kernel needs them, at which time this last problem can be fixed. For now it can be worked around: - disable MacOS extensions - don't boot MacOS (use the Emile bootloader instead) - get the bootloaders to disable ROM drivers (Penguin does this for video cards already, don't know about Emile) - physically remove unsupported cards Signed-off-by: Finn Thain Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/mac/via.c | 141 +++++++++++++++++++++++++++++----------------------- 1 file changed, 80 insertions(+), 61 deletions(-) (limited to 'arch') diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c index 0c1cc45c570d..83a3bb0c0325 100644 --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c @@ -64,7 +64,19 @@ static int gIER,gIFR,gBufA,gBufB; #define MAC_CLOCK_LOW (MAC_CLOCK_TICK&0xFF) #define MAC_CLOCK_HIGH (MAC_CLOCK_TICK>>8) -static int nubus_active; +/* To disable a NuBus slot on Quadras we make the slot IRQ lines outputs, set + * high. On RBV we just use the slot interrupt enable register. On Macs with + * genuine VIA chips we must use nubus_disabled to keep track of disabled slot + * interrupts. When any slot IRQ is disabled we mask the (edge triggered) CA1 + * or "SLOTS" interrupt. When no slot is disabled, we unmask the CA1 interrupt. + * So, on genuine VIAs, having more than one NuBus IRQ can mean trouble, + * because closing one of those drivers can mask all of the NuBus interrupts. + * Also, since we can't mask the unregistered slot IRQs on genuine VIAs, it's + * possible to get interrupts from cards that MacOS or the ROM has configured + * but we have not. FWIW, "Designing Cards and Drivers for Macintosh II and + * Macintosh SE", page 9-8, says, a slot IRQ with no driver would crash MacOS. + */ +static u8 nubus_disabled; void via_debug_dump(void); irqreturn_t via1_irq(int, void *); @@ -383,9 +395,6 @@ int via_get_cache_disable(void) void __init via_nubus_init(void) { - /* don't set nubus_active = 0 here, it kills the Baboon */ - /* interrupt that we've already registered. */ - /* unlock nubus transactions */ if ((macintosh_config->adb_type != MAC_ADB_PB1) && @@ -399,28 +408,35 @@ void __init via_nubus_init(void) via2[gBufB] |= 0x02; } - /* disable nubus slot interrupts. */ - if (rbv_present) { + /* Disable all the slot interrupts (where possible). */ + + switch (macintosh_config->via_type) { + case MAC_VIA_II: + /* Just make the port A lines inputs. */ + switch(macintosh_config->ident) { + case MAC_MODEL_II: + case MAC_MODEL_IIX: + case MAC_MODEL_IICX: + case MAC_MODEL_SE30: + /* The top two bits are RAM size outputs. */ + via2[vDirA] &= 0xC0; + break; + default: + via2[vDirA] &= 0x80; + } + break; + case MAC_VIA_IIci: + /* RBV. Disable all the slot interrupts. SIER works like IER. */ via2[rSIER] = 0x7F; - via2[rSIER] = nubus_active | 0x80; - } else { - /* These are ADB bits on PMU */ + break; + case MAC_VIA_QUADRA: + /* Disable the inactive slot interrupts by making those lines outputs. */ if ((macintosh_config->adb_type != MAC_ADB_PB1) && - (macintosh_config->adb_type != MAC_ADB_PB2)) { - switch(macintosh_config->ident) - { - case MAC_MODEL_II: - case MAC_MODEL_IIX: - case MAC_MODEL_IICX: - case MAC_MODEL_SE30: - via2[vBufA] |= 0x3F; - via2[vDirA] = ~nubus_active | 0xc0; - break; - default: - via2[vBufA] = 0xFF; - via2[vDirA] = ~nubus_active; - } + (macintosh_config->adb_type != MAC_ADB_PB2)) { + via2[vBufA] |= 0x7F; + via2[vDirA] |= 0x7F; } + break; } } @@ -489,7 +505,8 @@ irqreturn_t via2_irq(int irq, void *dev_id) via2[gIER] = irq_bit; via2[gIFR] = irq_bit | rbv_clear; m68k_handle_int(irq_num); - via2[gIER] = irq_bit | 0x80; + if (irq_num != IRQ_MAC_NUBUS || nubus_disabled == 0) + via2[gIER] = irq_bit | 0x80; } ++irq_num; irq_bit <<= 1; @@ -511,7 +528,7 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id) if (rbv_present) events &= via2[rSIER]; else - events &= nubus_active; + events &= ~via2[vDirA]; if (!events) return IRQ_NONE; @@ -533,7 +550,7 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id) if (rbv_present) events &= via2[rSIER]; else - events &= nubus_active; + events &= ~via2[vDirA]; } while (events); return IRQ_HANDLED; } @@ -541,38 +558,38 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id) void via_irq_enable(int irq) { int irq_src = IRQ_SRC(irq); int irq_idx = IRQ_IDX(irq); - int irq_bit = 1 << irq_idx; #ifdef DEBUG_IRQUSE printk(KERN_DEBUG "via_irq_enable(%d)\n", irq); #endif if (irq_src == 1) { - via1[vIER] = irq_bit | 0x80; + via1[vIER] = IER_SET_BIT(irq_idx); } else if (irq_src == 2) { - via2[gIER] = irq_bit | 0x80; + if (irq != IRQ_MAC_NUBUS || nubus_disabled == 0) + via2[gIER] = IER_SET_BIT(irq_idx); } else if (irq_src == 7) { - nubus_active |= irq_bit; - if (rbv_present) { - /* enable the slot interrupt. SIER works like IER. */ + switch (macintosh_config->via_type) { + case MAC_VIA_II: + nubus_disabled &= ~(1 << irq_idx); + /* Enable the CA1 interrupt when no slot is disabled. */ + if (!nubus_disabled) + via2[gIER] = IER_SET_BIT(1); + break; + case MAC_VIA_IIci: + /* On RBV, enable the slot interrupt. + * SIER works like IER. + */ via2[rSIER] = IER_SET_BIT(irq_idx); - } else { - /* Make sure the bit is an input, to enable the irq */ - /* But not on PowerBooks, that's ADB... */ + break; + case MAC_VIA_QUADRA: + /* Make the port A line an input to enable the slot irq. + * But not on PowerBooks, that's ADB. + */ if ((macintosh_config->adb_type != MAC_ADB_PB1) && - (macintosh_config->adb_type != MAC_ADB_PB2)) { - switch(macintosh_config->ident) - { - case MAC_MODEL_II: - case MAC_MODEL_IIX: - case MAC_MODEL_IICX: - case MAC_MODEL_SE30: - via2[vDirA] &= (~irq_bit | 0xc0); - break; - default: - via2[vDirA] &= ~irq_bit; - } - } + (macintosh_config->adb_type != MAC_ADB_PB2)) + via2[vDirA] &= ~(1 << irq_idx); + break; } } } @@ -580,29 +597,31 @@ void via_irq_enable(int irq) { void via_irq_disable(int irq) { int irq_src = IRQ_SRC(irq); int irq_idx = IRQ_IDX(irq); - int irq_bit = 1 << irq_idx; #ifdef DEBUG_IRQUSE printk(KERN_DEBUG "via_irq_disable(%d)\n", irq); #endif if (irq_src == 1) { - via1[vIER] = irq_bit & 0x7F; + via1[vIER] = IER_CLR_BIT(irq_idx); } else if (irq_src == 2) { - via2[gIER] = irq_bit & 0x7F; + via2[gIER] = IER_CLR_BIT(irq_idx); } else if (irq_src == 7) { - if (rbv_present) { - /* disable the slot interrupt. SIER works like IER. */ + switch (macintosh_config->via_type) { + case MAC_VIA_II: + nubus_disabled |= 1 << irq_idx; + if (nubus_disabled) + via2[gIER] = IER_CLR_BIT(1); + break; + case MAC_VIA_IIci: via2[rSIER] = IER_CLR_BIT(irq_idx); - } else { - /* disable the nubus irq by changing dir to output */ - /* except on PMU */ + break; + case MAC_VIA_QUADRA: if ((macintosh_config->adb_type != MAC_ADB_PB1) && - (macintosh_config->adb_type != MAC_ADB_PB2)) { - via2[vDirA] |= irq_bit; - } + (macintosh_config->adb_type != MAC_ADB_PB2)) + via2[vDirA] |= 1 << irq_idx; + break; } - nubus_active &= ~irq_bit; } } @@ -638,7 +657,7 @@ int via_irq_pending(int irq) } else if (irq_src == 2) { return via2[gIFR] & irq_bit; } else if (irq_src == 7) { - /* FIXME: this can't work while a slot irq is disabled! */ + /* Always 0 for MAC_VIA_QUADRA if the slot irq is disabled. */ return ~via2[gBufA] & irq_bit; } return 0; -- cgit v1.2.3-59-g8ed1b From 217f6710c275118af1008bb1447d244be52d2dc3 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Tue, 1 May 2007 22:32:58 +0200 Subject: m68k: Mac IRQ cleanup There are no slow IRQs on Macs since Roman Zippel's IRQ reorganisation that went into 2.6.16 and removed mac_irq_list[] and the do_mac_irq_list() dispatcher. (They were implemented in do_mac_irq_list() by lowering the IPL.) Hence there's no more use for mutual exclusion in the Mac interrupt dispatchers. Remove it. Signed-off-by: Finn Thain Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/mac/baboon.c | 20 +++++++------------- arch/m68k/mac/oss.c | 4 ---- arch/m68k/mac/psc.c | 2 -- arch/m68k/mac/via.c | 10 ---------- 4 files changed, 7 insertions(+), 29 deletions(-) (limited to 'arch') diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c index 8ea7498cec37..673a1085984d 100644 --- a/arch/m68k/mac/baboon.c +++ b/arch/m68k/mac/baboon.c @@ -22,7 +22,7 @@ /* #define DEBUG_BABOON */ /* #define DEBUG_IRQS */ -int baboon_present,baboon_active; +int baboon_present; volatile struct baboon *baboon; irqreturn_t baboon_irq(int, void *); @@ -45,7 +45,6 @@ void __init baboon_init(void) baboon = (struct baboon *) BABOON_BASE; baboon_present = 1; - baboon_active = 0; printk("Baboon detected at %p\n", baboon); } @@ -70,9 +69,9 @@ irqreturn_t baboon_irq(int irq, void *dev_id) unsigned char events; #ifdef DEBUG_IRQS - printk("baboon_irq: mb_control %02X mb_ifr %02X mb_status %02X active %02X\n", + printk("baboon_irq: mb_control %02X mb_ifr %02X mb_status %02X\n", (uint) baboon->mb_control, (uint) baboon->mb_ifr, - (uint) baboon->mb_status, baboon_active); + (uint) baboon->mb_status); #endif if (!(events = baboon->mb_ifr & 0x07)) @@ -81,11 +80,9 @@ irqreturn_t baboon_irq(int irq, void *dev_id) irq_num = IRQ_BABOON_0; irq_bit = 1; do { - if (events & irq_bit/* & baboon_active*/) { - baboon_active &= ~irq_bit; + if (events & irq_bit) { baboon->mb_ifr &= ~irq_bit; m68k_handle_int(irq_num); - baboon_active |= irq_bit; } irq_bit <<= 1; irq_num++; @@ -99,21 +96,18 @@ irqreturn_t baboon_irq(int irq, void *dev_id) } void baboon_irq_enable(int irq) { - int irq_idx = IRQ_IDX(irq); - #ifdef DEBUG_IRQUSE printk("baboon_irq_enable(%d)\n", irq); #endif - baboon_active |= (1 << irq_idx); + /* FIXME: figure out how to mask and unmask baboon interrupt sources */ + enable_irq(IRQ_NUBUS_C); } void baboon_irq_disable(int irq) { - int irq_idx = IRQ_IDX(irq); - #ifdef DEBUG_IRQUSE printk("baboon_irq_disable(%d)\n", irq); #endif - baboon_active &= ~(1 << irq_idx); + disable_irq(IRQ_NUBUS_C); } void baboon_irq_clear(int irq) { diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c index 6399883ae742..d7be16917efd 100644 --- a/arch/m68k/mac/oss.c +++ b/arch/m68k/mac/oss.c @@ -112,10 +112,8 @@ irqreturn_t oss_irq(int irq, void *dev_id) oss->irq_pending &= ~OSS_IP_SOUND; /* FIXME: call sound handler */ } else if (events & OSS_IP_SCSI) { - oss->irq_level[OSS_SCSI] = OSS_IRQLEV_DISABLED; oss->irq_pending &= ~OSS_IP_SCSI; m68k_handle_int(IRQ_MAC_SCSI); - oss->irq_level[OSS_SCSI] = OSS_IRQLEV_SCSI; } else { /* FIXME: error check here? */ } @@ -149,10 +147,8 @@ irqreturn_t oss_nubus_irq(int irq, void *dev_id) --i; irq_bit >>= 1; if (events & irq_bit) { - oss->irq_level[i] = OSS_IRQLEV_DISABLED; oss->irq_pending &= ~irq_bit; m68k_handle_int(NUBUS_SOURCE_BASE + i); - oss->irq_level[i] = OSS_IRQLEV_NUBUS; } } while(events & (irq_bit - 1)); return IRQ_HANDLED; diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c index 1dba88247c6f..d66f723b17c3 100644 --- a/arch/m68k/mac/psc.c +++ b/arch/m68k/mac/psc.c @@ -147,10 +147,8 @@ irqreturn_t psc_irq(int irq, void *dev_id) irq_bit = 1; do { if (events & irq_bit) { - psc_write_byte(pIER, irq_bit); psc_write_byte(pIFR, irq_bit); m68k_handle_int(irq_num); - psc_write_byte(pIER, irq_bit | 0x80); } irq_num++; irq_bit <<= 1; diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c index 83a3bb0c0325..d5cac72eb3db 100644 --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c @@ -443,11 +443,6 @@ void __init via_nubus_init(void) /* * The generic VIA interrupt routines (shamelessly stolen from Alan Cox's * via6522.c :-), disable/pending masks added. - * - * The new interrupt architecture in macints.c takes care of a lot of the - * gruntwork for us, including tallying the interrupts and calling the - * handlers on the linked list. All we need to do here is basically generate - * the machspec interrupt number after clearing the interrupt. */ irqreturn_t via1_irq(int irq, void *dev_id) @@ -463,10 +458,8 @@ irqreturn_t via1_irq(int irq, void *dev_id) irq_bit = 1; do { if (events & irq_bit) { - via1[vIER] = irq_bit; via1[vIFR] = irq_bit; m68k_handle_int(irq_num); - via1[vIER] = irq_bit | 0x80; } ++irq_num; irq_bit <<= 1; @@ -502,11 +495,8 @@ irqreturn_t via2_irq(int irq, void *dev_id) irq_bit = 1; do { if (events & irq_bit) { - via2[gIER] = irq_bit; via2[gIFR] = irq_bit | rbv_clear; m68k_handle_int(irq_num); - if (irq_num != IRQ_MAC_NUBUS || nubus_disabled == 0) - via2[gIER] = irq_bit | 0x80; } ++irq_num; irq_bit <<= 1; -- cgit v1.2.3-59-g8ed1b From d95fd5fce88f05fd36004f2a0c317e665549e54c Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Tue, 1 May 2007 22:32:59 +0200 Subject: m68k: Mac II ADB fixes Fix a crash caused by requests placed in the queue with the completed flag already set. This lead to some ADB_SYNC requests returning early and their request structs being popped off the stack while still queued. Stack corruption ensued or an invalid request callback pointer was invoked or both. Eliminate macii_retransmit() and its buggy implementation of macii_write(). Have macii_queue_poll() fully initialise the request queues. Fix a bug in macii_queue_poll() where the last_req pointer was not being set. This caused some requests to leave the queue before being completed (and would also corrupt the stack under certain conditions). Fix a race in macii_start that could set the state machine to "reading" while current_req was null. No longer send poll commands with the ADBREQ_REPLY flag -- doing that caused the replies to be stored in the request buffer where they were forgotten about. Don't autopoll by continuously sending new Talk commands. Get the controller to do that for us. This reduces the ADB interrupt rate on an idle bus to about 5 per second. Only autopoll the devices that were probed. Explicitly clear the interrupt flag when polling. Use disable_irq rather than local_irq_save when polling. Remove excess local_irq_save/restore pairs. Improve bus timeout and service request detection. Remove unused code (last_reply, adb_dir etc) and unneeded code (prefix_len, first_byte etc). Change TIP and TACK to their correct names on this ADB controller (ST_EVEN and ST_ODD). Add some commentry. Add a generous quantity of sanity checks (BUG_ONs). Let m68k macs use the adb_sync boot param too. Tested on Mac II, Mac IIci, Quadra 650, Quadra 700 etc. Signed-off-by: Finn Thain Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/kernel/setup.c | 10 + drivers/macintosh/via-macii.c | 582 +++++++++++++++++------------------------- 2 files changed, 251 insertions(+), 341 deletions(-) (limited to 'arch') diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index 9b307a5f4f22..610319356691 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c @@ -513,3 +513,13 @@ void check_bugs(void) } #endif /* !CONFIG_M68KFPU_EMU */ } + +#ifdef CONFIG_ADB +static int __init adb_probe_sync_enable (char *str) { + extern int __adb_probe_sync; + __adb_probe_sync = 1; + return 1; +} + +__setup("adb_sync", adb_probe_sync_enable); +#endif /* CONFIG_ADB */ diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c index 1b3bad62a1be..01b8eca7ccd5 100644 --- a/drivers/macintosh/via-macii.c +++ b/drivers/macintosh/via-macii.c @@ -12,6 +12,15 @@ * 1999-08-02 (jmt) - Initial rewrite for Unified ADB. * 2000-03-29 Tony Mantler * - Big overhaul, should actually work now. + * 2006-12-31 Finn Thain - Another overhaul. + * + * Suggested reading: + * Inside Macintosh, ch. 5 ADB Manager + * Guide to the Macinstosh Family Hardware, ch. 8 Apple Desktop Bus + * Rockwell R6522 VIA datasheet + * + * Apple's "ADB Analyzer" bus sniffer is invaluable: + * ftp://ftp.apple.com/developer/Tool_Chest/Devices_-_Hardware/Apple_Desktop_Bus/ */ #include @@ -26,7 +35,6 @@ #include #include #include -#include #include static volatile unsigned char *via; @@ -51,9 +59,7 @@ static volatile unsigned char *via; #define ANH (15*RS) /* A-side data, no handshake */ /* Bits in B data register: all active low */ -#define TREQ 0x08 /* Transfer request (input) */ -#define TACK 0x10 /* Transfer acknowledge (output) */ -#define TIP 0x20 /* Transfer in progress (output) */ +#define CTLR_IRQ 0x08 /* Controller rcv status (input) */ #define ST_MASK 0x30 /* mask for selecting ADB state bits */ /* Bits in ACR */ @@ -65,8 +71,6 @@ static volatile unsigned char *via; #define IER_SET 0x80 /* set bits in IER */ #define IER_CLR 0 /* clear bits in IER */ #define SR_INT 0x04 /* Shift register full/empty */ -#define SR_DATA 0x08 /* Shift register data */ -#define SR_CLOCK 0x10 /* Shift register clock */ /* ADB transaction states according to GMHW */ #define ST_CMD 0x00 /* ADB state: command byte */ @@ -77,7 +81,6 @@ static volatile unsigned char *via; static int macii_init_via(void); static void macii_start(void); static irqreturn_t macii_interrupt(int irq, void *arg); -static void macii_retransmit(int); static void macii_queue_poll(void); static int macii_probe(void); @@ -103,29 +106,37 @@ static enum macii_state { sending, reading, read_done, - awaiting_reply } macii_state; -static int need_poll; -static int command_byte; -static int last_reply; -static int last_active; - -static struct adb_request *current_req; -static struct adb_request *last_req; -static struct adb_request *retry_req; -static unsigned char reply_buf[16]; -static unsigned char *reply_ptr; -static int reply_len; -static int reading_reply; -static int data_index; -static int first_byte; -static int prefix_len; -static int status = ST_IDLE|TREQ; -static int last_status; -static int driver_running; - -/* debug level 10 required for ADB logging (should be && debug_adb, ideally) */ +static struct adb_request *current_req; /* first request struct in the queue */ +static struct adb_request *last_req; /* last request struct in the queue */ +static unsigned char reply_buf[16]; /* storage for autopolled replies */ +static unsigned char *reply_ptr; /* next byte in req->data or reply_buf */ +static int reading_reply; /* store reply in reply_buf else req->reply */ +static int data_index; /* index of the next byte to send from req->data */ +static int reply_len; /* number of bytes received in reply_buf or req->reply */ +static int status; /* VIA's ADB status bits captured upon interrupt */ +static int last_status; /* status bits as at previous interrupt */ +static int srq_asserted; /* have to poll for the device that asserted it */ +static int command_byte; /* the most recent command byte transmitted */ +static int autopoll_devs; /* bits set are device addresses to be polled */ + +/* Sanity check for request queue. Doesn't check for cycles. */ +static int request_is_queued(struct adb_request *req) { + struct adb_request *cur; + unsigned long flags; + local_irq_save(flags); + cur = current_req; + while (cur) { + if (cur == req) { + local_irq_restore(flags); + return 1; + } + cur = cur->next; + } + local_irq_restore(flags); + return 0; +} /* Check for MacII style ADB */ static int macii_probe(void) @@ -147,15 +158,16 @@ int macii_init(void) local_irq_save(flags); err = macii_init_via(); - if (err) return err; + if (err) goto out; err = request_irq(IRQ_MAC_ADB, macii_interrupt, IRQ_FLG_LOCK, "ADB", macii_interrupt); - if (err) return err; + if (err) goto out; macii_state = idle; +out: local_irq_restore(flags); - return 0; + return err; } /* initialize the hardware */ @@ -163,12 +175,12 @@ static int macii_init_via(void) { unsigned char x; - /* Set the lines up. We want TREQ as input TACK|TIP as output */ - via[DIRB] = (via[DIRB] | TACK | TIP) & ~TREQ; + /* We want CTLR_IRQ as input and ST_EVEN | ST_ODD as output lines. */ + via[DIRB] = (via[DIRB] | ST_EVEN | ST_ODD) & ~CTLR_IRQ; /* Set up state: idle */ via[B] |= ST_IDLE; - last_status = via[B] & (ST_MASK|TREQ); + last_status = via[B] & (ST_MASK|CTLR_IRQ); /* Shift register on input */ via[ACR] = (via[ACR] & ~SR_CTRL) | SR_EXT; @@ -179,81 +191,72 @@ static int macii_init_via(void) return 0; } -/* Send an ADB poll (Talk Register 0 command, tagged on the front of the request queue) */ +/* Send an ADB poll (Talk Register 0 command prepended to the request queue) */ static void macii_queue_poll(void) { - static int device = 0; - static int in_poll=0; + /* No point polling the active device as it will never assert SRQ, so + * poll the next device in the autopoll list. This could leave us + * stuck in a polling loop if an unprobed device is asserting SRQ. + * In theory, that could only happen if a device was plugged in after + * probing started. Unplugging it again will break the cycle. + * (Simply polling the next higher device often ends up polling almost + * every device (after wrapping around), which takes too long.) + */ + int device_mask; + int next_device; static struct adb_request req; - unsigned long flags; - - if (in_poll) printk("macii_queue_poll: double poll!\n"); - - in_poll++; - if (++device > 15) device = 1; - - adb_request(&req, NULL, ADBREQ_REPLY|ADBREQ_NOSEND, 1, - ADB_READREG(device, 0)); - - local_irq_save(flags); - - req.next = current_req; - current_req = &req; - local_irq_restore(flags); - macii_start(); - in_poll--; -} + if (!autopoll_devs) return; -/* Send an ADB retransmit (Talk, appended to the request queue) */ -static void macii_retransmit(int device) -{ - static int in_retransmit = 0; - static struct adb_request rt; - unsigned long flags; - - if (in_retransmit) printk("macii_retransmit: double retransmit!\n"); + device_mask = (1 << (((command_byte & 0xF0) >> 4) + 1)) - 1; + if (autopoll_devs & ~device_mask) + next_device = ffs(autopoll_devs & ~device_mask) - 1; + else + next_device = ffs(autopoll_devs) - 1; - in_retransmit++; + BUG_ON(request_is_queued(&req)); - adb_request(&rt, NULL, ADBREQ_REPLY|ADBREQ_NOSEND, 1, - ADB_READREG(device, 0)); + adb_request(&req, NULL, ADBREQ_NOSEND, 1, + ADB_READREG(next_device, 0)); - local_irq_save(flags); + req.sent = 0; + req.complete = 0; + req.reply_len = 0; + req.next = current_req; if (current_req != NULL) { - last_req->next = &rt; - last_req = &rt; + current_req = &req; } else { - current_req = &rt; - last_req = &rt; + current_req = &req; + last_req = &req; } - - if (macii_state == idle) macii_start(); - - local_irq_restore(flags); - in_retransmit--; } /* Send an ADB request; if sync, poll out the reply 'till it's done */ static int macii_send_request(struct adb_request *req, int sync) { - int i; + int err; + unsigned long flags; - i = macii_write(req); - if (i) return i; + BUG_ON(request_is_queued(req)); - if (sync) { - while (!req->complete) macii_poll(); + local_irq_save(flags); + err = macii_write(req); + local_irq_restore(flags); + + if (!err && sync) { + while (!req->complete) { + macii_poll(); + } + BUG_ON(request_is_queued(req)); } - return 0; + + return err; } -/* Send an ADB request */ +/* Send an ADB request (append to request queue) */ static int macii_write(struct adb_request *req) { - unsigned long flags; - if (req->nbytes < 2 || req->data[0] != ADB_PACKET || req->nbytes > 15) { req->complete = 1; return -EINVAL; @@ -264,8 +267,6 @@ static int macii_write(struct adb_request *req) req->complete = 0; req->reply_len = 0; - local_irq_save(flags); - if (current_req != NULL) { last_req->next = req; last_req = req; @@ -274,28 +275,52 @@ static int macii_write(struct adb_request *req) last_req = req; if (macii_state == idle) macii_start(); } - - local_irq_restore(flags); return 0; } /* Start auto-polling */ static int macii_autopoll(int devs) { - /* Just ping a random default address */ - if (!(current_req || retry_req)) - macii_retransmit( (last_active < 16 && last_active > 0) ? last_active : 3); - return 0; + static struct adb_request req; + unsigned long flags; + int err = 0; + + /* bit 1 == device 1, and so on. */ + autopoll_devs = devs & 0xFFFE; + + if (!autopoll_devs) return 0; + + local_irq_save(flags); + + if (current_req == NULL) { + /* Send a Talk Reg 0. The controller will repeatedly transmit + * this as long as it is idle. + */ + adb_request(&req, NULL, ADBREQ_NOSEND, 1, + ADB_READREG(ffs(autopoll_devs) - 1, 0)); + err = macii_write(&req); + } + + local_irq_restore(flags); + return err; +} + +static inline int need_autopoll(void) { + /* Was the last command Talk Reg 0 + * and is the target on the autopoll list? + */ + if ((command_byte & 0x0F) == 0x0C && + ((1 << ((command_byte & 0xF0) >> 4)) & autopoll_devs)) + return 0; + return 1; } /* Prod the chip without interrupts */ static void macii_poll(void) { - unsigned long flags; - - local_irq_save(flags); - if (via[IFR] & SR_INT) macii_interrupt(0, NULL); - local_irq_restore(flags); + disable_irq(IRQ_MAC_ADB); + macii_interrupt(0, NULL); + enable_irq(IRQ_MAC_ADB); } /* Reset the bus */ @@ -303,73 +328,34 @@ static int macii_reset_bus(void) { static struct adb_request req; + if (request_is_queued(&req)) + return 0; + /* Command = 0, Address = ignored */ adb_request(&req, NULL, 0, 1, ADB_BUSRESET); + /* Don't want any more requests during the Global Reset low time. */ + udelay(3000); + return 0; } /* Start sending ADB packet */ static void macii_start(void) { - unsigned long flags; struct adb_request *req; req = current_req; - if (!req) return; - - /* assert macii_state == idle */ - if (macii_state != idle) { - printk("macii_start: called while driver busy (%p %x %x)!\n", - req, macii_state, (uint) via1[B] & (ST_MASK|TREQ)); - return; - } - local_irq_save(flags); - - /* - * IRQ signaled ?? (means ADB controller wants to send, or might - * be end of packet if we were reading) - */ -#if 0 /* FIXME: This is broke broke broke, for some reason */ - if ((via[B] & TREQ) == 0) { - printk("macii_start: weird poll stuff. huh?\n"); - /* - * FIXME - we need to restart this on a timer - * or a collision at boot hangs us. - * Never set macii_state to idle here, or macii_start - * won't be called again from send_request! - * (need to re-check other cases ...) - */ - /* - * if the interrupt handler set the need_poll - * flag, it's hopefully a SRQ poll or re-Talk - * so we try to send here anyway - */ - if (!need_poll) { - if (console_loglevel == 10) - printk("macii_start: device busy - retry %p state %d status %x!\n", - req, macii_state, - (uint) via[B] & (ST_MASK|TREQ)); - retry_req = req; - /* set ADB status here ? */ - local_irq_restore(flags); - return; - } else { - need_poll = 0; - } - } -#endif - /* - * Another retry pending? (sanity check) + BUG_ON(req == NULL); + + BUG_ON(macii_state != idle); + + /* Now send it. Be careful though, that first byte of the request + * is actually ADB_PACKET; the real data begins at index 1! + * And req->nbytes is the number of bytes of real data plus one. */ - if (retry_req) { - retry_req = NULL; - } - /* Now send it. Be careful though, that first byte of the request */ - /* is actually ADB_PACKET; the real data begins at index 1! */ - /* store command byte */ command_byte = req->data[1]; /* Output mode */ @@ -381,115 +367,97 @@ static void macii_start(void) macii_state = sending; data_index = 2; - - local_irq_restore(flags); } /* - * The notorious ADB interrupt handler - does all of the protocol handling, - * except for starting new send operations. Relies heavily on the ADB - * controller sending and receiving data, thereby generating SR interrupts - * for us. This means there has to be always activity on the ADB bus, otherwise - * the whole process dies and has to be re-kicked by sending TALK requests ... - * CUDA-based Macs seem to solve this with the autopoll option, for MacII-type - * ADB the problem isn't solved yet (retransmit of the latest active TALK seems - * a good choice; either on timeout or on a timer interrupt). + * The notorious ADB interrupt handler - does all of the protocol handling. + * Relies on the ADB controller sending and receiving data, thereby + * generating shift register interrupts (SR_INT) for us. This means there has + * to be activity on the ADB bus. The chip will poll to achieve this. * * The basic ADB state machine was left unchanged from the original MacII code * by Alan Cox, which was based on the CUDA driver for PowerMac. - * The syntax of the ADB status lines seems to be totally different on MacII, - * though. MacII uses the states Command -> Even -> Odd -> Even ->...-> Idle for - * sending, and Idle -> Even -> Odd -> Even ->...-> Idle for receiving. Start - * and end of a receive packet are signaled by asserting /IRQ on the interrupt - * line. Timeouts are signaled by a sequence of 4 0xFF, with /IRQ asserted on - * every other byte. SRQ is probably signaled by 3 or more 0xFF tacked on the - * end of a packet. (Thanks to Guido Koerber for eavesdropping on the ADB - * protocol with a logic analyzer!!) - * - * Note: As of 21/10/97, the MacII ADB part works including timeout detection - * and retransmit (Talk to the last active device). + * The syntax of the ADB status lines is totally different on MacII, + * though. MacII uses the states Command -> Even -> Odd -> Even ->...-> Idle + * for sending and Idle -> Even -> Odd -> Even ->...-> Idle for receiving. + * Start and end of a receive packet are signalled by asserting /IRQ on the + * interrupt line (/IRQ means the CTLR_IRQ bit in port B; not to be confused + * with the VIA shift register interrupt. /IRQ never actually interrupts the + * processor, it's just an ordinary input.) */ static irqreturn_t macii_interrupt(int irq, void *arg) { - int x, adbdir; - unsigned long flags; + int x; + static int entered; struct adb_request *req; - last_status = status; - - /* prevent races due to SCSI enabling ints */ - local_irq_save(flags); - - if (driver_running) { - local_irq_restore(flags); - return IRQ_NONE; + if (!arg) { + /* Clear the SR IRQ flag when polling. */ + if (via[IFR] & SR_INT) + via[IFR] = SR_INT; + else + return IRQ_NONE; } - driver_running = 1; - - status = via[B] & (ST_MASK|TREQ); - adbdir = via[ACR] & SR_OUT; + BUG_ON(entered++); + + last_status = status; + status = via[B] & (ST_MASK|CTLR_IRQ); switch (macii_state) { case idle: + if (reading_reply) { + reply_ptr = current_req->reply; + } else { + BUG_ON(current_req != NULL); + reply_ptr = reply_buf; + } + x = via[SR]; - first_byte = x; - /* set ADB state = even for first data byte */ - via[B] = (via[B] & ~ST_MASK) | ST_EVEN; - reply_buf[0] = first_byte; /* was command_byte?? */ - reply_ptr = reply_buf + 1; - reply_len = 1; - prefix_len = 1; - reading_reply = 0; - - macii_state = reading; - break; + if ((status & CTLR_IRQ) && (x == 0xFF)) { + /* Bus timeout without SRQ sequence: + * data is "FF" while CTLR_IRQ is "H" + */ + reply_len = 0; + srq_asserted = 0; + macii_state = read_done; + } else { + macii_state = reading; + *reply_ptr = x; + reply_len = 1; + } - case awaiting_reply: - /* handshake etc. for II ?? */ - x = via[SR]; - first_byte = x; /* set ADB state = even for first data byte */ via[B] = (via[B] & ~ST_MASK) | ST_EVEN; - - current_req->reply[0] = first_byte; - reply_ptr = current_req->reply + 1; - reply_len = 1; - prefix_len = 1; - reading_reply = 1; - - macii_state = reading; break; case sending: req = current_req; if (data_index >= req->nbytes) { - /* print an error message if a listen command has no data */ - if (((command_byte & 0x0C) == 0x08) - /* && (console_loglevel == 10) */ - && (data_index == 2)) - printk("MacII ADB: listen command with no data: %x!\n", - command_byte); - /* reset to shift in */ - via[ACR] &= ~SR_OUT; - x = via[SR]; - /* set ADB state idle - might get SRQ */ - via[B] = (via[B] & ~ST_MASK) | ST_IDLE; - req->sent = 1; + macii_state = idle; if (req->reply_expected) { - macii_state = awaiting_reply; + reading_reply = 1; } else { req->complete = 1; current_req = req->next; if (req->done) (*req->done)(req); - macii_state = idle; - if (current_req || retry_req) + + if (current_req) macii_start(); else - macii_retransmit((command_byte & 0xF0) >> 4); + if (need_autopoll()) + macii_autopoll(autopoll_devs); + } + + if (macii_state == idle) { + /* reset to shift in */ + via[ACR] &= ~SR_OUT; + x = via[SR]; + /* set ADB state idle - might get SRQ */ + via[B] = (via[B] & ~ST_MASK) | ST_IDLE; } } else { via[SR] = req->data[data_index++]; @@ -505,147 +473,79 @@ static irqreturn_t macii_interrupt(int irq, void *arg) break; case reading: + x = via[SR]; + BUG_ON((status & ST_MASK) == ST_CMD || + (status & ST_MASK) == ST_IDLE); + + /* Bus timeout with SRQ sequence: + * data is "XX FF" while CTLR_IRQ is "L L" + * End of packet without SRQ sequence: + * data is "XX...YY 00" while CTLR_IRQ is "L...H L" + * End of packet SRQ sequence: + * data is "XX...YY 00" while CTLR_IRQ is "L...L L" + * (where XX is the first response byte and + * YY is the last byte of valid response data.) + */ - /* timeout / SRQ handling for II hw */ - if( (first_byte == 0xFF && (reply_len-prefix_len)==2 - && memcmp(reply_ptr-2,"\xFF\xFF",2)==0) || - ((reply_len-prefix_len)==3 - && memcmp(reply_ptr-3,"\xFF\xFF\xFF",3)==0)) - { - /* - * possible timeout (in fact, most probably a - * timeout, since SRQ can't be signaled without - * transfer on the bus). - * The last three bytes seen were FF, together - * with the starting byte (in case we started - * on 'idle' or 'awaiting_reply') this probably - * makes four. So this is mostl likely #5! - * The timeout signal is a pattern 1 0 1 0 0.. - * on /INT, meaning we missed it :-( - */ - x = via[SR]; - if (x != 0xFF) printk("MacII ADB: mistaken timeout/SRQ!\n"); - - if ((status & TREQ) == (last_status & TREQ)) { - /* Not a timeout. Unsolicited SRQ? weird. */ - /* Terminate the SRQ packet and poll */ - need_poll = 1; + srq_asserted = 0; + if (!(status & CTLR_IRQ)) { + if (x == 0xFF) { + if (!(last_status & CTLR_IRQ)) { + macii_state = read_done; + reply_len = 0; + srq_asserted = 1; + } + } else if (x == 0x00) { + macii_state = read_done; + if (!(last_status & CTLR_IRQ)) + srq_asserted = 1; } - /* There's no packet to get, so reply is blank */ - via[B] ^= ST_MASK; - reply_ptr -= (reply_len-prefix_len); - reply_len = prefix_len; - macii_state = read_done; - break; - } /* end timeout / SRQ handling for II hw. */ - - if((reply_len-prefix_len)>3 - && memcmp(reply_ptr-3,"\xFF\xFF\xFF",3)==0) - { - /* SRQ tacked on data packet */ - /* Terminate the packet (SRQ never ends) */ - x = via[SR]; - macii_state = read_done; - reply_len -= 3; - reply_ptr -= 3; - need_poll = 1; - /* need to continue; next byte not seen else */ - } else { - /* Sanity check */ - if (reply_len > 15) reply_len = 0; - /* read byte */ - x = via[SR]; - *reply_ptr = x; + } + + if (macii_state == reading) { + BUG_ON(reply_len > 15); reply_ptr++; + *reply_ptr = x; reply_len++; } - /* The usual handshake ... */ - - /* - * NetBSD hints that the next to last byte - * is sent with IRQ !! - * Guido found out it's the last one (0x0), - * but IRQ should be asserted already. - * Problem with timeout detection: First - * transition to /IRQ might be second - * byte of timeout packet! - * Timeouts are signaled by 4x FF. - */ - if (((status & TREQ) == 0) && (x == 0x00)) { /* != 0xFF */ - /* invert state bits, toggle ODD/EVEN */ - via[B] ^= ST_MASK; - /* adjust packet length */ - reply_len--; - reply_ptr--; - macii_state = read_done; - } else { - /* not caught: ST_CMD */ - /* required for re-entry 'reading'! */ - if ((status & ST_MASK) == ST_IDLE) { - /* (in)sanity check - set even */ - via[B] = (via[B] & ~ST_MASK) | ST_EVEN; - } else { - /* invert state bits */ - via[B] ^= ST_MASK; - } - } + /* invert state bits, toggle ODD/EVEN */ + via[B] ^= ST_MASK; break; case read_done: x = via[SR]; + if (reading_reply) { + reading_reply = 0; req = current_req; - req->reply_len = reply_ptr - req->reply; + req->reply_len = reply_len; req->complete = 1; current_req = req->next; if (req->done) (*req->done)(req); - } else { - adb_input(reply_buf, reply_ptr - reply_buf, 0); - } + } else if (reply_len && autopoll_devs) + adb_input(reply_buf, reply_len, 0); - /* - * remember this device ID; it's the latest we got a - * reply from! - */ - last_reply = command_byte; - last_active = (command_byte & 0xF0) >> 4; + macii_state = idle; /* SRQ seen before, initiate poll now */ - if (need_poll) { - macii_state = idle; + if (srq_asserted) macii_queue_poll(); - need_poll = 0; - break; - } - - /* set ADB state to idle */ - via[B] = (via[B] & ~ST_MASK) | ST_IDLE; - - /* /IRQ seen, so the ADB controller has data for us */ - if ((via[B] & TREQ) != 0) { - macii_state = reading; - reply_buf[0] = command_byte; - reply_ptr = reply_buf + 1; - reply_len = 1; - prefix_len = 1; - reading_reply = 0; - } else { - /* no IRQ, send next packet or wait */ - macii_state = idle; - if (current_req) - macii_start(); - else - macii_retransmit(last_active); - } + if (current_req) + macii_start(); + else + if (need_autopoll()) + macii_autopoll(autopoll_devs); + + if (macii_state == idle) + via[B] = (via[B] & ~ST_MASK) | ST_IDLE; break; default: break; } - /* reset mutex and interrupts */ - driver_running = 0; - local_irq_restore(flags); + + entered--; return IRQ_HANDLED; } -- cgit v1.2.3-59-g8ed1b From f5456e040eaac7eb9545d49c38984af2047699be Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 1 May 2007 22:33:06 +0200 Subject: m68k: export csum_partial_copy_from_user net/rxrpc/af-rxrpc.ko needs csum_partial_copy_from_user Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/lib/checksum.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/m68k/lib/checksum.c b/arch/m68k/lib/checksum.c index aed3be29e06b..cf6bb51945a2 100644 --- a/arch/m68k/lib/checksum.c +++ b/arch/m68k/lib/checksum.c @@ -320,6 +320,9 @@ csum_partial_copy_from_user(const void __user *src, void *dst, return(sum); } +EXPORT_SYMBOL(csum_partial_copy_from_user); + + /* * copy from kernel space while checksumming, otherwise like csum_partial */ -- cgit v1.2.3-59-g8ed1b From 28bd3a0dcce11bea6f99a351cc64053dff00196e Mon Sep 17 00:00:00 2001 From: Michael-Luke Jones Date: Sat, 28 Apr 2007 08:31:40 +0100 Subject: [ARM] 4318/2: DSM-G600 Board Support This patch adds support for the D-Link DSM-G600 Rev A. This is an ARM XScale IXP4xx system relatively similar to the NSLU2 and NAS-100D already supported by mainline. An important difference is Gigabit Ethernet support using the Via Velocity chipset. This patch is the combined work of Michael Westerhof and Alessandro Zummo, with contributions from Michael-Luke Jones. This version addresses review comments from rmk and Deepak Saxena. Signed-off-by: Michael-Luke Jones Signed-off-by: Alessandro Zummo Signed-off-by: Michael Westerhof Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-ixp4xx/Kconfig | 9 ++ arch/arm/mach-ixp4xx/Makefile | 2 + arch/arm/mach-ixp4xx/dsmg600-pci.c | 74 ++++++++++++++ arch/arm/mach-ixp4xx/dsmg600-power.c | 125 +++++++++++++++++++++++ arch/arm/mach-ixp4xx/dsmg600-setup.c | 175 +++++++++++++++++++++++++++++++++ include/asm-arm/arch-ixp4xx/dsmg600.h | 57 +++++++++++ include/asm-arm/arch-ixp4xx/hardware.h | 1 + include/asm-arm/arch-ixp4xx/irqs.h | 10 ++ 8 files changed, 453 insertions(+) create mode 100644 arch/arm/mach-ixp4xx/dsmg600-pci.c create mode 100644 arch/arm/mach-ixp4xx/dsmg600-power.c create mode 100644 arch/arm/mach-ixp4xx/dsmg600-setup.c create mode 100644 include/asm-arm/arch-ixp4xx/dsmg600.h (limited to 'arch') diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index dd0fb7239a80..9715ef506c24 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig @@ -95,6 +95,15 @@ config MACH_NAS100D NAS 100d device. For more information on this platform, see http://www.nslu2-linux.org/wiki/NAS100d/HomePage +config MACH_DSMG600 + bool + prompt "D-Link DSM-G600 RevA" + select PCI + help + Say 'Y' here if you want your kernel to support D-Link's + DSM-G600 RevA device. For more information on this platform, + see http://www.nslu2-linux.org/wiki/DSMG600/HomePage + # # Avila and IXDP share the same source for now. Will change in future # diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile index 746e297284ed..3b87c47e06cf 100644 --- a/arch/arm/mach-ixp4xx/Makefile +++ b/arch/arm/mach-ixp4xx/Makefile @@ -12,6 +12,7 @@ obj-pci-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o obj-pci-$(CONFIG_MACH_NSLU2) += nslu2-pci.o obj-pci-$(CONFIG_MACH_NAS100D) += nas100d-pci.o +obj-pci-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o obj-y += common.o @@ -22,5 +23,6 @@ obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-setup.o obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o obj-$(CONFIG_MACH_NSLU2) += nslu2-setup.o nslu2-power.o obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o nas100d-power.o +obj-$(CONFIG_MACH_DSMG600) += dsmg600-setup.o dsmg600-power.o obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o diff --git a/arch/arm/mach-ixp4xx/dsmg600-pci.c b/arch/arm/mach-ixp4xx/dsmg600-pci.c new file mode 100644 index 000000000000..9db7e1f42011 --- /dev/null +++ b/arch/arm/mach-ixp4xx/dsmg600-pci.c @@ -0,0 +1,74 @@ +/* + * DSM-G600 board-level PCI initialization + * + * Copyright (C) 2006 Tower Technologies + * Author: Alessandro Zummo + * + * based on ixdp425-pci.c: + * Copyright (C) 2002 Intel Corporation. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * Maintainer: http://www.nslu2-linux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include + +#include +#include + +void __init dsmg600_pci_preinit(void) +{ + set_irq_type(IRQ_DSMG600_PCI_INTA, IRQT_LOW); + set_irq_type(IRQ_DSMG600_PCI_INTB, IRQT_LOW); + set_irq_type(IRQ_DSMG600_PCI_INTC, IRQT_LOW); + set_irq_type(IRQ_DSMG600_PCI_INTD, IRQT_LOW); + set_irq_type(IRQ_DSMG600_PCI_INTE, IRQT_LOW); + set_irq_type(IRQ_DSMG600_PCI_INTF, IRQT_LOW); + + ixp4xx_pci_preinit(); +} + +static int __init dsmg600_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + static int pci_irq_table[DSMG600_PCI_MAX_DEV][DSMG600_PCI_IRQ_LINES] = + { + { IRQ_DSMG600_PCI_INTE, -1, -1 }, + { IRQ_DSMG600_PCI_INTA, -1, -1 }, + { IRQ_DSMG600_PCI_INTB, IRQ_DSMG600_PCI_INTC, IRQ_DSMG600_PCI_INTD }, + { IRQ_DSMG600_PCI_INTF, -1, -1 }, + }; + + int irq = -1; + + if (slot >= 1 && slot <= DSMG600_PCI_MAX_DEV && + pin >= 1 && pin <= DSMG600_PCI_IRQ_LINES) + irq = pci_irq_table[slot-1][pin-1]; + + return irq; +} + +struct hw_pci __initdata dsmg600_pci = { + .nr_controllers = 1, + .preinit = dsmg600_pci_preinit, + .swizzle = pci_std_swizzle, + .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, + .map_irq = dsmg600_map_irq, +}; + +int __init dsmg600_pci_init(void) +{ + if (machine_is_dsmg600()) + pci_common_init(&dsmg600_pci); + + return 0; +} + +subsys_initcall(dsmg600_pci_init); diff --git a/arch/arm/mach-ixp4xx/dsmg600-power.c b/arch/arm/mach-ixp4xx/dsmg600-power.c new file mode 100644 index 000000000000..34717872d076 --- /dev/null +++ b/arch/arm/mach-ixp4xx/dsmg600-power.c @@ -0,0 +1,125 @@ +/* + * arch/arm/mach-ixp4xx/dsmg600-power.c + * + * DSM-G600 Power/Reset driver + * Author: Michael Westerhof + * + * Based on nslu2-power.c + * Copyright (C) 2005 Tower Technologies + * Author: Alessandro Zummo + * + * which was based on nslu2-io.c + * Copyright (C) 2004 Karen Spearel + * + * Maintainers: http://www.nslu2-linux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include + +#include + +extern void ctrl_alt_del(void); + +/* This is used to make sure the power-button pusher is serious. The button + * must be held until the value of this counter reaches zero. + */ +static volatile int power_button_countdown; + +/* Must hold the button down for at least this many counts to be processed */ +#define PBUTTON_HOLDDOWN_COUNT 4 /* 2 secs */ + +static void dsmg600_power_handler(unsigned long data); +static DEFINE_TIMER(dsmg600_power_timer, dsmg600_power_handler, 0, 0); + +static void dsmg600_power_handler(unsigned long data) +{ + /* This routine is called twice per second to check the + * state of the power button. + */ + + if (*IXP4XX_GPIO_GPINR & DSMG600_PB_BM) { + + /* IO Pin is 1 (button pushed) */ + if (power_button_countdown == 0) { + /* Signal init to do the ctrlaltdel action, this will bypass + * init if it hasn't started and do a kernel_restart. + */ + ctrl_alt_del(); + + /* Change the state of the power LED to "blink" */ + gpio_line_set(DSMG600_LED_PWR_GPIO, IXP4XX_GPIO_LOW); + } + power_button_countdown--; + + } else { + power_button_countdown = PBUTTON_HOLDDOWN_COUNT; + } + + mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500)); +} + +static irqreturn_t dsmg600_reset_handler(int irq, void *dev_id) +{ + /* This is the paper-clip reset, it shuts the machine down directly. */ + machine_power_off(); + + return IRQ_HANDLED; +} + +static int __init dsmg600_power_init(void) +{ + if (!(machine_is_dsmg600())) + return 0; + + if (request_irq(DSMG600_RB_IRQ, &dsmg600_reset_handler, + IRQF_DISABLED | IRQF_TRIGGER_LOW, "DSM-G600 reset button", + NULL) < 0) { + + printk(KERN_DEBUG "Reset Button IRQ %d not available\n", + DSMG600_RB_IRQ); + + return -EIO; + } + + /* The power button on the D-Link DSM-G600 is on GPIO 15, but + * it cannot handle interrupts on that GPIO line. So we'll + * have to poll it with a kernel timer. + */ + + /* Make sure that the power button GPIO is set up as an input */ + gpio_line_config(DSMG600_PB_GPIO, IXP4XX_GPIO_IN); + + /* Set the initial value for the power button IRQ handler */ + power_button_countdown = PBUTTON_HOLDDOWN_COUNT; + + mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500)); + + return 0; +} + +static void __exit dsmg600_power_exit(void) +{ + if (!(machine_is_dsmg600())) + return; + + del_timer_sync(&dsmg600_power_timer); + + free_irq(DSMG600_RB_IRQ, NULL); +} + +module_init(dsmg600_power_init); +module_exit(dsmg600_power_exit); + +MODULE_AUTHOR("Michael Westerhof "); +MODULE_DESCRIPTION("DSM-G600 Power/Reset driver"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c new file mode 100644 index 000000000000..1caff65e22cc --- /dev/null +++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c @@ -0,0 +1,175 @@ +/* + * DSM-G600 board-setup + * + * Copyright (C) 2006 Tower Technologies + * Author: Alessandro Zummo + * + * based ixdp425-setup.c: + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * Author: Alessandro Zummo + * Maintainers: http://www.nslu2-linux.org/ + */ + +#include +#include +#include + +#include +#include +#include + +static struct flash_platform_data dsmg600_flash_data = { + .map_name = "cfi_probe", + .width = 2, +}; + +static struct resource dsmg600_flash_resource = { + .flags = IORESOURCE_MEM, +}; + +static struct platform_device dsmg600_flash = { + .name = "IXP4XX-Flash", + .id = 0, + .dev.platform_data = &dsmg600_flash_data, + .num_resources = 1, + .resource = &dsmg600_flash_resource, +}; + +static struct ixp4xx_i2c_pins dsmg600_i2c_gpio_pins = { + .sda_pin = DSMG600_SDA_PIN, + .scl_pin = DSMG600_SCL_PIN, +}; + +static struct platform_device dsmg600_i2c_controller = { + .name = "IXP4XX-I2C", + .id = 0, + .dev.platform_data = &dsmg600_i2c_gpio_pins, +}; + +#ifdef CONFIG_LEDS_CLASS +static struct resource dsmg600_led_resources[] = { + { + .name = "power", + .start = DSMG600_LED_PWR_GPIO, + .end = DSMG600_LED_PWR_GPIO, + .flags = IXP4XX_GPIO_HIGH, + }, + { + .name = "wlan", + .start = DSMG600_LED_WLAN_GPIO, + .end = DSMG600_LED_WLAN_GPIO, + .flags = IXP4XX_GPIO_LOW, + }, +}; + +static struct platform_device dsmg600_leds = { + .name = "IXP4XX-GPIO-LED", + .id = -1, + .num_resources = ARRAY_SIZE(dsmg600_led_resources), + .resource = dsmg600_led_resources, +}; +#endif + +static struct resource dsmg600_uart_resources[] = { + { + .start = IXP4XX_UART1_BASE_PHYS, + .end = IXP4XX_UART1_BASE_PHYS + 0x0fff, + .flags = IORESOURCE_MEM, + }, + { + .start = IXP4XX_UART2_BASE_PHYS, + .end = IXP4XX_UART2_BASE_PHYS + 0x0fff, + .flags = IORESOURCE_MEM, + } +}; + +static struct plat_serial8250_port dsmg600_uart_data[] = { + { + .mapbase = IXP4XX_UART1_BASE_PHYS, + .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, + .irq = IRQ_IXP4XX_UART1, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP4XX_UART_XTAL, + }, + { + .mapbase = IXP4XX_UART2_BASE_PHYS, + .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, + .irq = IRQ_IXP4XX_UART2, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP4XX_UART_XTAL, + }, + { } +}; + +static struct platform_device dsmg600_uart = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev.platform_data = dsmg600_uart_data, + .num_resources = ARRAY_SIZE(dsmg600_uart_resources), + .resource = dsmg600_uart_resources, +}; + +static struct platform_device *dsmg600_devices[] __initdata = { + &dsmg600_i2c_controller, + &dsmg600_flash, +}; + +static void dsmg600_power_off(void) +{ + /* enable the pwr cntl gpio */ + gpio_line_config(DSMG600_PO_GPIO, IXP4XX_GPIO_OUT); + + /* poweroff */ + gpio_line_set(DSMG600_PO_GPIO, IXP4XX_GPIO_HIGH); +} + +static void __init dsmg600_init(void) +{ + ixp4xx_sys_init(); + + /* Make sure that GPIO14 and GPIO15 are not used as clocks */ + *IXP4XX_GPIO_GPCLKR = 0; + + dsmg600_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); + dsmg600_flash_resource.end = + IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; + + pm_power_off = dsmg600_power_off; + + /* The UART is required on the DSM-G600 (Redboot cannot use the + * NIC) -- do it here so that it does *not* get removed if + * platform_add_devices fails! + */ + (void)platform_device_register(&dsmg600_uart); + + platform_add_devices(dsmg600_devices, ARRAY_SIZE(dsmg600_devices)); + +#ifdef CONFIG_LEDS_CLASS + /* We don't care whether or not this works. */ + (void)platform_device_register(&dsmg600_leds); +#endif +} + +static void __init dsmg600_fixup(struct machine_desc *desc, + struct tag *tags, char **cmdline, struct meminfo *mi) +{ + /* The xtal on this machine is non-standard. */ + ixp4xx_timer_freq = DSMG600_FREQ; +} + +MACHINE_START(DSMG600, "D-Link DSM-G600 RevA") + /* Maintainer: www.nslu2-linux.org */ + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC, + .boot_params = 0x00000100, + .fixup = dsmg600_fixup, + .map_io = ixp4xx_map_io, + .init_irq = ixp4xx_init_irq, + .timer = &ixp4xx_timer, + .init_machine = dsmg600_init, +MACHINE_END diff --git a/include/asm-arm/arch-ixp4xx/dsmg600.h b/include/asm-arm/arch-ixp4xx/dsmg600.h new file mode 100644 index 000000000000..a19605ad240d --- /dev/null +++ b/include/asm-arm/arch-ixp4xx/dsmg600.h @@ -0,0 +1,57 @@ +/* + * DSM-G600 platform specific definitions + * + * Copyright (C) 2006 Tower Technologies + * Author: Alessandro Zummo + * + * based on ixdp425.h: + * Copyright 2004 (C) MontaVista, Software, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __ASM_ARCH_HARDWARE_H__ +#error "Do not include this directly, instead #include " +#endif + +#define DSMG600_SDA_PIN 5 +#define DSMG600_SCL_PIN 4 + +/* + * DSMG600 PCI IRQs + */ +#define DSMG600_PCI_MAX_DEV 4 +#define DSMG600_PCI_IRQ_LINES 3 + + +/* PCI controller GPIO to IRQ pin mappings */ +#define DSMG600_PCI_INTA_PIN 11 +#define DSMG600_PCI_INTB_PIN 10 +#define DSMG600_PCI_INTC_PIN 9 +#define DSMG600_PCI_INTD_PIN 8 +#define DSMG600_PCI_INTE_PIN 7 +#define DSMG600_PCI_INTF_PIN 6 + +/* DSM-G600 Timer Setting */ +#define DSMG600_FREQ 66000000 + +/* Buttons */ + +#define DSMG600_PB_GPIO 15 /* power button */ +#define DSMG600_PB_BM (1L << DSMG600_PB_GPIO) + +#define DSMG600_RB_GPIO 3 /* reset button */ + +#define DSMG600_RB_IRQ IRQ_IXP4XX_GPIO3 + +#define DSMG600_PO_GPIO 2 /* power off */ + +/* LEDs */ + +#define DSMG600_LED_PWR_GPIO 0 +#define DSMG600_LED_PWR_BM (1L << DSMG600_LED_PWR_GPIO) + +#define DSMG600_LED_WLAN_GPIO 14 +#define DSMG600_LED_WLAN_BM (1L << DSMG600_LED_WLAN_GPIO) diff --git a/include/asm-arm/arch-ixp4xx/hardware.h b/include/asm-arm/arch-ixp4xx/hardware.h index a0acde3b8862..297ceda08b61 100644 --- a/include/asm-arm/arch-ixp4xx/hardware.h +++ b/include/asm-arm/arch-ixp4xx/hardware.h @@ -44,5 +44,6 @@ #include "prpmc1100.h" #include "nslu2.h" #include "nas100d.h" +#include "dsmg600.h" #endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/include/asm-arm/arch-ixp4xx/irqs.h b/include/asm-arm/arch-ixp4xx/irqs.h index 73a9aa583745..11801605047b 100644 --- a/include/asm-arm/arch-ixp4xx/irqs.h +++ b/include/asm-arm/arch-ixp4xx/irqs.h @@ -118,4 +118,14 @@ #define IRQ_NAS100D_PCI_INTD IRQ_IXP4XX_GPIO8 #define IRQ_NAS100D_PCI_INTE IRQ_IXP4XX_GPIO7 +/* + * D-Link DSM-G600 RevA board IRQs + */ +#define IRQ_DSMG600_PCI_INTA IRQ_IXP4XX_GPIO11 +#define IRQ_DSMG600_PCI_INTB IRQ_IXP4XX_GPIO10 +#define IRQ_DSMG600_PCI_INTC IRQ_IXP4XX_GPIO9 +#define IRQ_DSMG600_PCI_INTD IRQ_IXP4XX_GPIO8 +#define IRQ_DSMG600_PCI_INTE IRQ_IXP4XX_GPIO7 +#define IRQ_DSMG600_PCI_INTF IRQ_IXP4XX_GPIO6 + #endif -- cgit v1.2.3-59-g8ed1b From 14f1c3bf51b78d916a6aff9c9b5e6689e3e006e7 Mon Sep 17 00:00:00 2001 From: Juha Yrjola Date: Wed, 6 Dec 2006 17:13:48 -0800 Subject: ARM: OMAP: Enable 24xx GPIO autoidling Enable 24xx GPIO autoidling Signed-off-by: Juha Yrjola Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/plat-omap/gpio.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 8bedc8f9b6e5..037a4930ec61 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -1082,6 +1082,10 @@ static int __init _omap_gpio_init(void) if (bank->method == METHOD_GPIO_24XX) { __raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1); __raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1); + __raw_writew(0x0015, bank->base + OMAP24XX_GPIO_SYSCONFIG); + + /* Initialize interface clock ungated, module enabled */ + __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL); gpio_count = 32; } @@ -1104,6 +1108,12 @@ static int __init _omap_gpio_init(void) if (cpu_is_omap16xx()) omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL); +#ifdef CONFIG_ARCH_OMAP24XX + /* Enable autoidle for the OCP interface */ + if (cpu_is_omap24xx()) + omap_writel(1 << 0, 0x48019010); +#endif + return 0; } -- cgit v1.2.3-59-g8ed1b From 3ac4fa99291a60329e9c9424ac3e67bb4f9564f5 Mon Sep 17 00:00:00 2001 From: Juha Yrjola Date: Wed, 6 Dec 2006 17:13:52 -0800 Subject: ARM: OMAP: Implement workaround for GPIO wakeup bug in OMAP2420 silicon Some GPIOs on OMAP2420 do not have wakeup capabilities. If these GPIOs are configured as IRQ sources, spurious interrupts will be generated each time the core domain enters retention. Signed-off-by: Juha Yrjola Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/plat-omap/gpio.c | 154 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 136 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 037a4930ec61..ec0e2f18fdea 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -117,8 +117,18 @@ struct gpio_bank { u16 virtual_irq_start; int method; u32 reserved_map; +#if defined (CONFIG_ARCH_OMAP16XX) || defined (CONFIG_ARCH_OMAP24XX) u32 suspend_wakeup; u32 saved_wakeup; +#endif +#ifdef CONFIG_ARCH_OMAP24XX + u32 non_wakeup_gpios; + u32 enabled_non_wakeup_gpios; + + u32 saved_datain; + u32 saved_fallingdetect; + u32 saved_risingdetect; +#endif spinlock_t lock; }; @@ -397,8 +407,10 @@ do { \ __raw_writel(l, base + reg); \ } while(0) -static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int trigger) +#ifdef CONFIG_ARCH_OMAP24XX +static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) { + void __iomem *base = bank->base; u32 gpio_bit = 1 << gpio; MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, @@ -409,9 +421,21 @@ static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int tr trigger & __IRQT_RISEDGE); MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, trigger & __IRQT_FALEDGE); + if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { + if (trigger != 0) + __raw_writel(1 << gpio, bank->base + OMAP24XX_GPIO_SETWKUENA); + else + __raw_writel(1 << gpio, bank->base + OMAP24XX_GPIO_CLEARWKUENA); + } else { + if (trigger != 0) + bank->enabled_non_wakeup_gpios |= gpio_bit; + else + bank->enabled_non_wakeup_gpios &= ~gpio_bit; + } /* FIXME: Possibly do 'set_irq_handler(j, handle_level_irq)' if only level * triggering requested. */ } +#endif static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) { @@ -439,6 +463,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) else goto bad; break; +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: if (gpio & 0x08) reg += OMAP1610_GPIO_EDGE_CTRL2; @@ -454,7 +479,14 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) l |= 2 << (gpio << 1); if (trigger & __IRQT_FALEDGE) l |= 1 << (gpio << 1); + if (trigger) + /* Enable wake-up during idle for dynamic tick */ + __raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_SET_WAKEUPENA); + else + __raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA); break; +#endif +#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_CONTROL; l = __raw_readl(reg); @@ -465,9 +497,12 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) else goto bad; break; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: - set_24xx_gpio_triggering(reg, gpio, trigger); + set_24xx_gpio_triggering(bank, gpio, trigger); break; +#endif default: BUG(); goto bad; @@ -651,8 +686,8 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) { switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: - case METHOD_GPIO_24XX: spin_lock(&bank->lock); if (enable) bank->suspend_wakeup |= (1 << gpio); @@ -660,6 +695,24 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) bank->suspend_wakeup &= ~(1 << gpio); spin_unlock(&bank->lock); return 0; +#endif +#ifdef CONFIG_ARCH_OMAP24XX + case METHOD_GPIO_24XX: + spin_lock(&bank->lock); + if (enable) { + if (bank->non_wakeup_gpios & (1 << gpio)) { + printk(KERN_ERR "Unable to enable wakeup on" + "non-wakeup GPIO%d\n", + (bank - gpio_bank) * 32 + gpio); + spin_unlock(&bank->lock); + return -EINVAL; + } + bank->suspend_wakeup |= (1 << gpio); + } else + bank->suspend_wakeup &= ~(1 << gpio); + spin_unlock(&bank->lock); + return 0; +#endif default: printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n", bank->method); @@ -720,20 +773,6 @@ int omap_request_gpio(int gpio) reg = bank->base + OMAP1510_GPIO_PIN_CONTROL; __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg); } -#endif -#ifdef CONFIG_ARCH_OMAP16XX - if (bank->method == METHOD_GPIO_1610) { - /* Enable wake-up during idle for dynamic tick */ - void __iomem *reg = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; - __raw_writel(1 << get_gpio_index(gpio), reg); - } -#endif -#ifdef CONFIG_ARCH_OMAP24XX - if (bank->method == METHOD_GPIO_24XX) { - /* Enable wake-up during idle for dynamic tick */ - void __iomem *reg = bank->base + OMAP24XX_GPIO_SETWKUENA; - __raw_writel(1 << get_gpio_index(gpio), reg); - } #endif spin_unlock(&bank->lock); @@ -1080,13 +1119,18 @@ static int __init _omap_gpio_init(void) #endif #ifdef CONFIG_ARCH_OMAP24XX if (bank->method == METHOD_GPIO_24XX) { + static const u32 non_wakeup_gpios[] = { + 0xe203ffc0, 0x08700040 + }; + __raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1); __raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1); __raw_writew(0x0015, bank->base + OMAP24XX_GPIO_SYSCONFIG); /* Initialize interface clock ungated, module enabled */ __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL); - + if (i < ARRAY_SIZE(non_wakeup_gpios)) + bank->non_wakeup_gpios = non_wakeup_gpios[i]; gpio_count = 32; } #endif @@ -1200,6 +1244,80 @@ static struct sys_device omap_gpio_device = { .id = 0, .cls = &omap_gpio_sysclass, }; + +#endif + +#ifdef CONFIG_ARCH_OMAP24XX + +static int workaround_enabled; + +void omap2_gpio_prepare_for_retention(void) +{ + int i, c = 0; + + /* Remove triggering for all non-wakeup GPIOs. Otherwise spurious + * IRQs will be generated. See OMAP2420 Errata item 1.101. */ + for (i = 0; i < gpio_bank_count; i++) { + struct gpio_bank *bank = &gpio_bank[i]; + u32 l1, l2; + + if (!(bank->enabled_non_wakeup_gpios)) + continue; + bank->saved_datain = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN); + l1 = __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT); + l2 = __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT); + bank->saved_fallingdetect = l1; + bank->saved_risingdetect = l2; + l1 &= ~bank->enabled_non_wakeup_gpios; + l2 &= ~bank->enabled_non_wakeup_gpios; + __raw_writel(l1, bank->base + OMAP24XX_GPIO_FALLINGDETECT); + __raw_writel(l2, bank->base + OMAP24XX_GPIO_RISINGDETECT); + c++; + } + if (!c) { + workaround_enabled = 0; + return; + } + workaround_enabled = 1; +} + +void omap2_gpio_resume_after_retention(void) +{ + int i; + + if (!workaround_enabled) + return; + for (i = 0; i < gpio_bank_count; i++) { + struct gpio_bank *bank = &gpio_bank[i]; + u32 l; + + if (!(bank->enabled_non_wakeup_gpios)) + continue; + __raw_writel(bank->saved_fallingdetect, + bank->base + OMAP24XX_GPIO_FALLINGDETECT); + __raw_writel(bank->saved_risingdetect, + bank->base + OMAP24XX_GPIO_RISINGDETECT); + /* Check if any of the non-wakeup interrupt GPIOs have changed + * state. If so, generate an IRQ by software. This is + * horribly racy, but it's the best we can do to work around + * this silicon bug. */ + l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN); + l ^= bank->saved_datain; + l &= bank->non_wakeup_gpios; + if (l) { + u32 old0, old1; + + old0 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0); + old1 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); + __raw_writel(old0 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT0); + __raw_writel(old1 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT1); + __raw_writel(old0, bank->base + OMAP24XX_GPIO_LEVELDETECT0); + __raw_writel(old1, bank->base + OMAP24XX_GPIO_LEVELDETECT1); + } + } + +} + #endif /* -- cgit v1.2.3-59-g8ed1b From b9772a220a0d1b1d83b770ed131fa8b090af3681 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 6 Dec 2006 17:13:53 -0800 Subject: ARM: OMAP: /sys/kernel/debug/omap_gpio Add some GPIO debug support: /sys/kernel/debug/omap_gpio dumps the state of all GPIOs that have been claimed, including basic IRQ info if relevant. Tested on 24xx, 16xx. Includes minor bugfixes: recording IRQ trigger mode (this should probably be a genirq patch), adding missing space to non-wakeup warning Signed-off-by: David Brownell Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/plat-omap/gpio.c | 130 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index ec0e2f18fdea..0059f19185a7 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -535,6 +535,10 @@ static int gpio_irq_type(unsigned irq, unsigned type) bank = get_gpio_bank(gpio); spin_lock(&bank->lock); retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type); + if (retval == 0) { + irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK; + irq_desc[irq].status |= type; + } spin_unlock(&bank->lock); return retval; } @@ -701,7 +705,7 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) spin_lock(&bank->lock); if (enable) { if (bank->non_wakeup_gpios & (1 << gpio)) { - printk(KERN_ERR "Unable to enable wakeup on" + printk(KERN_ERR "Unable to enable wakeup on " "non-wakeup GPIO%d\n", (bank - gpio_bank) * 32 + gpio); spin_unlock(&bank->lock); @@ -1359,3 +1363,127 @@ EXPORT_SYMBOL(omap_set_gpio_dataout); EXPORT_SYMBOL(omap_get_gpio_datain); arch_initcall(omap_gpio_sysinit); + + +#ifdef CONFIG_DEBUG_FS + +#include +#include + +static int gpio_is_input(struct gpio_bank *bank, int mask) +{ + void __iomem *reg = bank->base; + + switch (bank->method) { + case METHOD_MPUIO: + reg += OMAP_MPUIO_IO_CNTL; + break; + case METHOD_GPIO_1510: + reg += OMAP1510_GPIO_DIR_CONTROL; + break; + case METHOD_GPIO_1610: + reg += OMAP1610_GPIO_DIRECTION; + break; + case METHOD_GPIO_730: + reg += OMAP730_GPIO_DIR_CONTROL; + break; + case METHOD_GPIO_24XX: + reg += OMAP24XX_GPIO_OE; + break; + } + return __raw_readl(reg) & mask; +} + + +static int dbg_gpio_show(struct seq_file *s, void *unused) +{ + unsigned i, j, gpio; + + for (i = 0, gpio = 0; i < gpio_bank_count; i++) { + struct gpio_bank *bank = gpio_bank + i; + unsigned bankwidth = 16; + u32 mask = 1; + + if (!cpu_is_omap24xx() && bank->method == METHOD_MPUIO) + gpio = OMAP_MPUIO(0); + else if (cpu_is_omap24xx() || cpu_is_omap730()) + bankwidth = 32; + + for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) { + unsigned irq, value, is_in, irqstat; + + if (!(bank->reserved_map & mask)) + continue; + + irq = bank->virtual_irq_start + j; + value = omap_get_gpio_datain(gpio); + is_in = gpio_is_input(bank, mask); + + if (!cpu_is_omap24xx() && bank->method == METHOD_MPUIO) + seq_printf(s, "MPUIO %2d: ", j); + else + seq_printf(s, "GPIO %3d: ", gpio); + seq_printf(s, "%s %s", + is_in ? "in " : "out", + value ? "hi" : "lo"); + + irqstat = irq_desc[irq].status; + if (is_in && ((bank->suspend_wakeup & mask) + || irqstat & IRQ_TYPE_SENSE_MASK)) { + char *trigger = NULL; + + switch (irqstat & IRQ_TYPE_SENSE_MASK) { + case IRQ_TYPE_EDGE_FALLING: + trigger = "falling"; + break; + case IRQ_TYPE_EDGE_RISING: + trigger = "rising"; + break; + case IRQ_TYPE_EDGE_BOTH: + trigger = "bothedge"; + break; + case IRQ_TYPE_LEVEL_LOW: + trigger = "low"; + break; + case IRQ_TYPE_LEVEL_HIGH: + trigger = "high"; + break; + case IRQ_TYPE_NONE: + trigger = "(unspecified)"; + break; + } + seq_printf(s, ", irq-%d %s%s", + irq, trigger, + (bank->suspend_wakeup & mask) + ? " wakeup" : ""); + } + seq_printf(s, "\n"); + } + + if (!cpu_is_omap24xx() && bank->method == METHOD_MPUIO) { + seq_printf(s, "\n"); + gpio = 0; + } + } + return 0; +} + +static int dbg_gpio_open(struct inode *inode, struct file *file) +{ + return single_open(file, dbg_gpio_show, inode->u.generic_ip/*i_private*/); +} + +static const struct file_operations debug_fops = { + .open = dbg_gpio_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init omap_gpio_debuginit(void) +{ + (void) debugfs_create_file("omap_gpio", S_IRUGO, NULL, NULL, &debug_fops); + return 0; +} +late_initcall(omap_gpio_debuginit); +#endif -- cgit v1.2.3-59-g8ed1b From e5c56ed3c9caa6ba717af0a5c23e2c7bf5c97a1f Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 6 Dec 2006 17:13:59 -0800 Subject: ARM: OMAP: gpio object shrinkage, cleanup More GPIO/IRQ cleanup: - compile-time removal of much useless code * mpuio support on non-OMAP1. * 15xx/730/24xx gpio support on 1610 * 15xx/730/16xx gpio support on 24xx * etc - remove all BUG() calls, which are always bad news ... replaced some with normal fault reports for that call, others with WARN_ON(1). - small mpuio bugfix: add missing set_type() method Oh, and fix a minor merge issue: inode->u.generic_ip is now gone. Signed-off-by: David Brownell Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/plat-omap/gpio.c | 166 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 130 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 0059f19185a7..f0a882b8ab3a 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -267,21 +267,34 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) u32 l; switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO: reg += OMAP_MPUIO_IO_CNTL; break; +#endif +#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510: reg += OMAP1510_GPIO_DIR_CONTROL; break; +#endif +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: reg += OMAP1610_GPIO_DIRECTION; break; +#endif +#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730: reg += OMAP730_GPIO_DIR_CONTROL; break; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: reg += OMAP24XX_GPIO_OE; break; +#endif + default: + WARN_ON(1); + return; } l = __raw_readl(reg); if (is_input) @@ -309,6 +322,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) u32 l = 0; switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO: reg += OMAP_MPUIO_OUTPUT; l = __raw_readl(reg); @@ -317,6 +331,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) else l &= ~(1 << gpio); break; +#endif +#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510: reg += OMAP1510_GPIO_DATA_OUTPUT; l = __raw_readl(reg); @@ -325,6 +341,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) else l &= ~(1 << gpio); break; +#endif +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: if (enable) reg += OMAP1610_GPIO_SET_DATAOUT; @@ -332,6 +350,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) reg += OMAP1610_GPIO_CLEAR_DATAOUT; l = 1 << gpio; break; +#endif +#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730: reg += OMAP730_GPIO_DATA_OUTPUT; l = __raw_readl(reg); @@ -340,6 +360,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) else l &= ~(1 << gpio); break; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: if (enable) reg += OMAP24XX_GPIO_SETDATAOUT; @@ -347,8 +369,9 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) reg += OMAP24XX_GPIO_CLEARDATAOUT; l = 1 << gpio; break; +#endif default: - BUG(); + WARN_ON(1); return; } __raw_writel(l, reg); @@ -372,28 +395,37 @@ int omap_get_gpio_datain(int gpio) void __iomem *reg; if (check_gpio(gpio) < 0) - return -1; + return -EINVAL; bank = get_gpio_bank(gpio); reg = bank->base; switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO: reg += OMAP_MPUIO_INPUT_LATCH; break; +#endif +#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510: reg += OMAP1510_GPIO_DATA_INPUT; break; +#endif +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: reg += OMAP1610_GPIO_DATAIN; break; +#endif +#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730: reg += OMAP730_GPIO_DATA_INPUT; break; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: reg += OMAP24XX_GPIO_DATAIN; break; +#endif default: - BUG(); - return -1; + return -EINVAL; } return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; @@ -443,6 +475,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) u32 l = 0; switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO: reg += OMAP_MPUIO_GPIO_INT_EDGE; l = __raw_readl(reg); @@ -453,6 +486,8 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) else goto bad; break; +#endif +#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_CONTROL; l = __raw_readl(reg); @@ -463,6 +498,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) else goto bad; break; +#endif #ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: if (gpio & 0x08) @@ -470,9 +506,6 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) else reg += OMAP1610_GPIO_EDGE_CTRL1; gpio &= 0x07; - /* We allow only edge triggering, i.e. two lowest bits */ - if (trigger & (__IRQT_LOWLVL | __IRQT_HIGHLVL)) - BUG(); l = __raw_readl(reg); l &= ~(3 << (gpio << 1)); if (trigger & __IRQT_RISEDGE) @@ -504,7 +537,6 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) break; #endif default: - BUG(); goto bad; } __raw_writel(l, reg); @@ -519,7 +551,7 @@ static int gpio_irq_type(unsigned irq, unsigned type) unsigned gpio; int retval; - if (irq > IH_MPUIO_BASE) + if (!cpu_is_omap24xx() && irq > IH_MPUIO_BASE) gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE); else gpio = irq - IH_GPIO_BASE; @@ -527,9 +559,12 @@ static int gpio_irq_type(unsigned irq, unsigned type) if (check_gpio(gpio) < 0) return -EINVAL; - if (type & IRQT_PROBE) + if (type & ~IRQ_TYPE_SENSE_MASK) return -EINVAL; - if (!cpu_is_omap24xx() && (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL))) + + /* OMAP1 allows only only edge triggering */ + if (!cpu_is_omap24xx() + && (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))) return -EINVAL; bank = get_gpio_bank(gpio); @@ -548,24 +583,34 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) void __iomem *reg = bank->base; switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO: /* MPUIO irqstatus is reset by reading the status register, * so do nothing here */ return; +#endif +#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_STATUS; break; +#endif +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: reg += OMAP1610_GPIO_IRQSTATUS1; break; +#endif +#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_STATUS; break; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: reg += OMAP24XX_GPIO_IRQSTATUS1; break; +#endif default: - BUG(); + WARN_ON(1); return; } __raw_writel(gpio_mask, reg); @@ -588,31 +633,41 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) u32 mask; switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO: reg += OMAP_MPUIO_GPIO_MASKIT; mask = 0xffff; inv = 1; break; +#endif +#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_MASK; mask = 0xffff; inv = 1; break; +#endif +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: reg += OMAP1610_GPIO_IRQENABLE1; mask = 0xffff; break; +#endif +#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_MASK; mask = 0xffffffff; inv = 1; break; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: reg += OMAP24XX_GPIO_IRQENABLE1; mask = 0xffffffff; break; +#endif default: - BUG(); + WARN_ON(1); return 0; } @@ -629,6 +684,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab u32 l; switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO: reg += OMAP_MPUIO_GPIO_MASKIT; l = __raw_readl(reg); @@ -637,6 +693,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab else l |= gpio_mask; break; +#endif +#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_MASK; l = __raw_readl(reg); @@ -645,6 +703,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab else l |= gpio_mask; break; +#endif +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: if (enable) reg += OMAP1610_GPIO_SET_IRQENABLE1; @@ -652,6 +712,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab reg += OMAP1610_GPIO_CLEAR_IRQENABLE1; l = gpio_mask; break; +#endif +#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_MASK; l = __raw_readl(reg); @@ -660,6 +722,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab else l |= gpio_mask; break; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: if (enable) reg += OMAP24XX_GPIO_SETIRQENABLE1; @@ -667,8 +731,9 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab reg += OMAP24XX_GPIO_CLEARIRQENABLE1; l = gpio_mask; break; +#endif default: - BUG(); + WARN_ON(1); return; } __raw_writel(l, reg); @@ -837,8 +902,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) desc->chip->ack(irq); bank = get_irq_data(irq); +#ifdef CONFIG_ARCH_OMAP1 if (bank->method == METHOD_MPUIO) isr_reg = bank->base + OMAP_MPUIO_GPIO_INT; +#endif #ifdef CONFIG_ARCH_OMAP15XX if (bank->method == METHOD_GPIO_1510) isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS; @@ -984,6 +1051,22 @@ static void gpio_unmask_irq(unsigned int irq) _set_gpio_irqenable(bank, gpio_idx, 1); } +static struct irq_chip gpio_irq_chip = { + .name = "GPIO", + .shutdown = gpio_irq_shutdown, + .ack = gpio_ack_irq, + .mask = gpio_mask_irq, + .unmask = gpio_unmask_irq, + .set_type = gpio_irq_type, + .set_wake = gpio_wake_enable, +}; + +/*---------------------------------------------------------------------*/ + +#ifdef CONFIG_ARCH_OMAP1 + +/* MPUIO uses the always-on 32k clock */ + static void mpuio_ack_irq(unsigned int irq) { /* The ISR is reset automatically, so do nothing here. */ @@ -1005,23 +1088,26 @@ static void mpuio_unmask_irq(unsigned int irq) _set_gpio_irqenable(bank, gpio, 1); } -static struct irq_chip gpio_irq_chip = { - .name = "GPIO", - .shutdown = gpio_irq_shutdown, - .ack = gpio_ack_irq, - .mask = gpio_mask_irq, - .unmask = gpio_unmask_irq, +static struct irq_chip mpuio_irq_chip = { + .name = "MPUIO", + .ack = mpuio_ack_irq, + .mask = mpuio_mask_irq, + .unmask = mpuio_unmask_irq, .set_type = gpio_irq_type, - .set_wake = gpio_wake_enable, }; -static struct irq_chip mpuio_irq_chip = { - .name = "MPUIO", - .ack = mpuio_ack_irq, - .mask = mpuio_mask_irq, - .unmask = mpuio_unmask_irq, - .set_type = gpio_irq_type, -}; + +#define bank_is_mpuio(bank) ((bank)->method == METHOD_MPUIO) + +#else + +extern struct irq_chip mpuio_irq_chip; + +#define bank_is_mpuio(bank) 0 + +#endif + +/*---------------------------------------------------------------------*/ static int initialized; static struct clk * gpio_ick; @@ -1097,9 +1183,8 @@ static int __init _omap_gpio_init(void) bank->reserved_map = 0; bank->base = IO_ADDRESS(bank->base); spin_lock_init(&bank->lock); - if (bank->method == METHOD_MPUIO) { + if (bank_is_mpuio(bank)) omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT); - } #ifdef CONFIG_ARCH_OMAP15XX if (bank->method == METHOD_GPIO_1510) { __raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK); @@ -1140,7 +1225,7 @@ static int __init _omap_gpio_init(void) #endif for (j = bank->virtual_irq_start; j < bank->virtual_irq_start + gpio_count; j++) { - if (bank->method == METHOD_MPUIO) + if (bank_is_mpuio(bank)) set_irq_chip(j, &mpuio_irq_chip); else set_irq_chip(j, &gpio_irq_chip); @@ -1180,16 +1265,20 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg) void __iomem *wake_set; switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE; wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; break; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: wake_status = bank->base + OMAP24XX_GPIO_SETWKUENA; wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; break; +#endif default: continue; } @@ -1217,14 +1306,18 @@ static int omap_gpio_resume(struct sys_device *dev) void __iomem *wake_set; switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; break; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; break; +#endif default: continue; } @@ -1404,7 +1497,7 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) unsigned bankwidth = 16; u32 mask = 1; - if (!cpu_is_omap24xx() && bank->method == METHOD_MPUIO) + if (bank_is_mpuio(bank)) gpio = OMAP_MPUIO(0); else if (cpu_is_omap24xx() || cpu_is_omap730()) bankwidth = 32; @@ -1419,7 +1512,7 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) value = omap_get_gpio_datain(gpio); is_in = gpio_is_input(bank, mask); - if (!cpu_is_omap24xx() && bank->method == METHOD_MPUIO) + if (bank_is_mpuio(bank)) seq_printf(s, "MPUIO %2d: ", j); else seq_printf(s, "GPIO %3d: ", gpio); @@ -1460,7 +1553,7 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) seq_printf(s, "\n"); } - if (!cpu_is_omap24xx() && bank->method == METHOD_MPUIO) { + if (bank_is_mpuio(bank)) { seq_printf(s, "\n"); gpio = 0; } @@ -1470,7 +1563,7 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) static int dbg_gpio_open(struct inode *inode, struct file *file) { - return single_open(file, dbg_gpio_show, inode->u.generic_ip/*i_private*/); + return single_open(file, dbg_gpio_show, &inode->i_private); } static const struct file_operations debug_fops = { @@ -1482,7 +1575,8 @@ static const struct file_operations debug_fops = { static int __init omap_gpio_debuginit(void) { - (void) debugfs_create_file("omap_gpio", S_IRUGO, NULL, NULL, &debug_fops); + (void) debugfs_create_file("omap_gpio", S_IRUGO, + NULL, NULL, &debug_fops); return 0; } late_initcall(omap_gpio_debuginit); -- cgit v1.2.3-59-g8ed1b From 56a2564185db752d83bbc78be9b1e257bf103444 Mon Sep 17 00:00:00 2001 From: Syed Mohammed Khasim Date: Wed, 6 Dec 2006 17:14:08 -0800 Subject: ARM: OMAP: plat-omap changes for 2430 SDP This patch adds minimal OMAP2430 support to plat-omap files to get the kernel booting on 2430SDP. Signed-off-by: Syed Mohammed Khasim Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/plat-omap/devices.c | 6 +++- arch/arm/plat-omap/dmtimer.c | 2 ++ arch/arm/plat-omap/gpio.c | 76 ++++++++++++++++++++++++++++++++++++-------- arch/arm/plat-omap/mcbsp.c | 15 ++++++--- 4 files changed, 80 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index dbc3f44e07a6..eeb33fed6f7c 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c @@ -429,6 +429,10 @@ static inline void omap_init_rng(void) {} */ static int __init omap_init_devices(void) { +/* + * Need to enable relevant once for 2430 SDP + */ +#ifndef CONFIG_MACH_OMAP_2430SDP /* please keep these calls, and their implementations above, * in alphabetical order so they're easier to sort through. */ @@ -438,7 +442,7 @@ static int __init omap_init_devices(void) omap_init_uwire(); omap_init_wdt(); omap_init_rng(); - +#endif return 0; } arch_initcall(omap_init_devices); diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 45f0439bffba..659619f235ca 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -506,6 +506,8 @@ int omap_dm_timer_init(void) BUG_ON(dm_source_clocks[i] == NULL); } #endif + if (cpu_is_omap243x()) + dm_timers[0].phys_base = 0x49018000; for (i = 0; i < dm_timer_count; i++) { #ifdef CONFIG_ARCH_OMAP2 diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index f0a882b8ab3a..1da7a5d1ddd9 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -85,10 +85,17 @@ /* * omap24xx specific GPIO registers */ -#define OMAP24XX_GPIO1_BASE (void __iomem *)0x48018000 -#define OMAP24XX_GPIO2_BASE (void __iomem *)0x4801a000 -#define OMAP24XX_GPIO3_BASE (void __iomem *)0x4801c000 -#define OMAP24XX_GPIO4_BASE (void __iomem *)0x4801e000 +#define OMAP242X_GPIO1_BASE (void __iomem *)0x48018000 +#define OMAP242X_GPIO2_BASE (void __iomem *)0x4801a000 +#define OMAP242X_GPIO3_BASE (void __iomem *)0x4801c000 +#define OMAP242X_GPIO4_BASE (void __iomem *)0x4801e000 + +#define OMAP243X_GPIO1_BASE (void __iomem *)0x4900C000 +#define OMAP243X_GPIO2_BASE (void __iomem *)0x4900E000 +#define OMAP243X_GPIO3_BASE (void __iomem *)0x49010000 +#define OMAP243X_GPIO4_BASE (void __iomem *)0x49012000 +#define OMAP243X_GPIO5_BASE (void __iomem *)0x480B6000 + #define OMAP24XX_GPIO_REVISION 0x0000 #define OMAP24XX_GPIO_SYSCONFIG 0x0010 #define OMAP24XX_GPIO_SYSSTATUS 0x0014 @@ -168,12 +175,22 @@ static struct gpio_bank gpio_bank_730[7] = { #endif #ifdef CONFIG_ARCH_OMAP24XX -static struct gpio_bank gpio_bank_24xx[4] = { - { OMAP24XX_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_24XX }, - { OMAP24XX_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_24XX }, - { OMAP24XX_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_24XX }, - { OMAP24XX_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96, METHOD_GPIO_24XX }, + +static struct gpio_bank gpio_bank_242x[4] = { + { OMAP242X_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_24XX }, + { OMAP242X_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_24XX }, + { OMAP242X_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_24XX }, + { OMAP242X_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96, METHOD_GPIO_24XX }, }; + +static struct gpio_bank gpio_bank_243x[5] = { + { OMAP243X_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_24XX }, + { OMAP243X_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_24XX }, + { OMAP243X_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_24XX }, + { OMAP243X_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96, METHOD_GPIO_24XX }, + { OMAP243X_GPIO5_BASE, INT_24XX_GPIO_BANK5, IH_GPIO_BASE + 128, METHOD_GPIO_24XX }, +}; + #endif static struct gpio_bank *gpio_bank; @@ -1113,6 +1130,11 @@ static int initialized; static struct clk * gpio_ick; static struct clk * gpio_fck; +#ifdef CONFIG_ARCH_OMAP2430 +static struct clk * gpio5_ick; +static struct clk * gpio5_fck; +#endif + static int __init _omap_gpio_init(void) { int i; @@ -1138,7 +1160,25 @@ static int __init _omap_gpio_init(void) printk("Could not get gpios_fck\n"); else clk_enable(gpio_fck); - } + + /* + * On 2430 GPIO 5 uses CORE L4 ICLK + */ +#ifdef CONFIG_ARCH_OMAP2430 + if (cpu_is_omap2430()) { + gpio5_ick = clk_get(NULL, "gpio5_ick"); + if (IS_ERR(gpio5_ick)) + printk("Could not get gpio5_ick\n"); + else + clk_enable(gpio5_ick); + gpio5_fck = clk_get(NULL, "gpio5_fck"); + if (IS_ERR(gpio5_fck)) + printk("Could not get gpio5_fck\n"); + else + clk_enable(gpio5_fck); + } +#endif +} #ifdef CONFIG_ARCH_OMAP15XX if (cpu_is_omap15xx()) { @@ -1165,14 +1205,24 @@ static int __init _omap_gpio_init(void) gpio_bank = gpio_bank_730; } #endif + #ifdef CONFIG_ARCH_OMAP24XX - if (cpu_is_omap24xx()) { + if (cpu_is_omap242x()) { int rev; gpio_bank_count = 4; - gpio_bank = gpio_bank_24xx; + gpio_bank = gpio_bank_242x; + rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION); + printk(KERN_INFO "OMAP242x GPIO hardware version %d.%d\n", + (rev >> 4) & 0x0f, rev & 0x0f); + } + if (cpu_is_omap243x()) { + int rev; + + gpio_bank_count = 5; + gpio_bank = gpio_bank_243x; rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION); - printk(KERN_INFO "OMAP24xx GPIO hardware version %d.%d\n", + printk(KERN_INFO "OMAP243x GPIO hardware version %d.%d\n", (rev >> 4) & 0x0f, rev & 0x0f); } #endif diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index b8d6f17ff58f..f7b9ccdaacbc 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -225,11 +225,16 @@ static void omap_mcbsp_dsp_free(void) #ifdef CONFIG_ARCH_OMAP2 static void omap2_mcbsp2_mux_setup(void) { - omap_cfg_reg(Y15_24XX_MCBSP2_CLKX); - omap_cfg_reg(R14_24XX_MCBSP2_FSX); - omap_cfg_reg(W15_24XX_MCBSP2_DR); - omap_cfg_reg(V15_24XX_MCBSP2_DX); - omap_cfg_reg(V14_24XX_GPIO117); + if (cpu_is_omap2420()) { + omap_cfg_reg(Y15_24XX_MCBSP2_CLKX); + omap_cfg_reg(R14_24XX_MCBSP2_FSX); + omap_cfg_reg(W15_24XX_MCBSP2_DR); + omap_cfg_reg(V15_24XX_MCBSP2_DX); + omap_cfg_reg(V14_24XX_GPIO117); + } + /* + * Need to add MUX settings for OMAP 2430 SDP + */ } #endif -- cgit v1.2.3-59-g8ed1b From 58781016c3637caf314ca7f579ce0acd1b0378dc Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 6 Dec 2006 17:14:10 -0800 Subject: ARM: OMAP: speed up gpio irq handling Speedup and shrink GPIO irq handling code, by using a pointer that's available in the irq_chip structure instead of calling the get_gpio_bank() function. On OMAP1 this saves 44 words, most of which were in IRQ critical path methods. Hey, every few instructions help. Signed-off-by: David Brownell Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/plat-omap/gpio.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 1da7a5d1ddd9..14a3f7118c73 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -584,7 +584,7 @@ static int gpio_irq_type(unsigned irq, unsigned type) && (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))) return -EINVAL; - bank = get_gpio_bank(gpio); + bank = get_irq_chip_data(irq); spin_lock(&bank->lock); retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type); if (retval == 0) { @@ -823,7 +823,7 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable) if (check_gpio(gpio) < 0) return -ENODEV; - bank = get_gpio_bank(gpio); + bank = get_irq_chip_data(irq); retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable); return retval; @@ -1038,7 +1038,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) static void gpio_irq_shutdown(unsigned int irq) { unsigned int gpio = irq - IH_GPIO_BASE; - struct gpio_bank *bank = get_gpio_bank(gpio); + struct gpio_bank *bank = get_irq_chip_data(irq); _reset_gpio(bank, gpio); } @@ -1046,7 +1046,7 @@ static void gpio_irq_shutdown(unsigned int irq) static void gpio_ack_irq(unsigned int irq) { unsigned int gpio = irq - IH_GPIO_BASE; - struct gpio_bank *bank = get_gpio_bank(gpio); + struct gpio_bank *bank = get_irq_chip_data(irq); _clear_gpio_irqstatus(bank, gpio); } @@ -1054,7 +1054,7 @@ static void gpio_ack_irq(unsigned int irq) static void gpio_mask_irq(unsigned int irq) { unsigned int gpio = irq - IH_GPIO_BASE; - struct gpio_bank *bank = get_gpio_bank(gpio); + struct gpio_bank *bank = get_irq_chip_data(irq); _set_gpio_irqenable(bank, gpio, 0); } @@ -1063,7 +1063,7 @@ static void gpio_unmask_irq(unsigned int irq) { unsigned int gpio = irq - IH_GPIO_BASE; unsigned int gpio_idx = get_gpio_index(gpio); - struct gpio_bank *bank = get_gpio_bank(gpio); + struct gpio_bank *bank = get_irq_chip_data(irq); _set_gpio_irqenable(bank, gpio_idx, 1); } @@ -1092,7 +1092,7 @@ static void mpuio_ack_irq(unsigned int irq) static void mpuio_mask_irq(unsigned int irq) { unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE); - struct gpio_bank *bank = get_gpio_bank(gpio); + struct gpio_bank *bank = get_irq_chip_data(irq); _set_gpio_irqenable(bank, gpio, 0); } @@ -1100,7 +1100,7 @@ static void mpuio_mask_irq(unsigned int irq) static void mpuio_unmask_irq(unsigned int irq) { unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE); - struct gpio_bank *bank = get_gpio_bank(gpio); + struct gpio_bank *bank = get_irq_chip_data(irq); _set_gpio_irqenable(bank, gpio, 1); } @@ -1275,6 +1275,7 @@ static int __init _omap_gpio_init(void) #endif for (j = bank->virtual_irq_start; j < bank->virtual_irq_start + gpio_count; j++) { + set_irq_chip_data(j, bank); if (bank_is_mpuio(bank)) set_irq_chip(j, &mpuio_irq_chip); else -- cgit v1.2.3-59-g8ed1b From 11a78b7944963a8b052be46108d07a3ced9e2762 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 6 Dec 2006 17:14:11 -0800 Subject: ARM: OMAP: MPUIO wake updates GPIO and MPUIO wake updates: - Hook MPUIOs into the irq wakeup framework too. This uses a platform device to update irq enables during system sleep states, instead of a sys_device, since the latter is no longer needed for such things. - Also forward enable/disable irq wake requests to the relevant GPIO controller, so the top level IRQ dispatcher can (eventually) handle these wakeup events automatically if more than one GPIO pin needs to be a wakeup event source. - Minor tweak to the 24xx non-wakeup gpio stuff: no need to check such read-only data under the spinlock. This assumes (maybe wrongly?) that only 16xx can do GPIO wakeup; without a 15xx I can't test such stuff. Also this expects the top level IRQ dispatcher to properly handle requests to enable/disable irq wake, which is currently known to be wrong: omap1 saves the flags but ignores them, omap2 doesn't even save it. (Wakeup events are, wrongly, hardwired in the relevant mach-omapX/pm.c file ...) So MPUIO irqs won't yet trigger system wakeup. Signed-off-by: David Brownell Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/plat-omap/gpio.c | 93 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 83 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 14a3f7118c73..df0ff0fd881a 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -773,29 +773,35 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) { switch (bank->method) { #ifdef CONFIG_ARCH_OMAP16XX + case METHOD_MPUIO: case METHOD_GPIO_1610: spin_lock(&bank->lock); - if (enable) + if (enable) { bank->suspend_wakeup |= (1 << gpio); - else + enable_irq_wake(bank->irq); + } else { + disable_irq_wake(bank->irq); bank->suspend_wakeup &= ~(1 << gpio); + } spin_unlock(&bank->lock); return 0; #endif #ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: + if (bank->non_wakeup_gpios & (1 << gpio)) { + printk(KERN_ERR "Unable to modify wakeup on " + "non-wakeup GPIO%d\n", + (bank - gpio_bank) * 32 + gpio); + return -EINVAL; + } spin_lock(&bank->lock); if (enable) { - if (bank->non_wakeup_gpios & (1 << gpio)) { - printk(KERN_ERR "Unable to enable wakeup on " - "non-wakeup GPIO%d\n", - (bank - gpio_bank) * 32 + gpio); - spin_unlock(&bank->lock); - return -EINVAL; - } bank->suspend_wakeup |= (1 << gpio); - } else + enable_irq_wake(bank->irq); + } else { + disable_irq_wake(bank->irq); bank->suspend_wakeup &= ~(1 << gpio); + } spin_unlock(&bank->lock); return 0; #endif @@ -1111,16 +1117,81 @@ static struct irq_chip mpuio_irq_chip = { .mask = mpuio_mask_irq, .unmask = mpuio_unmask_irq, .set_type = gpio_irq_type, +#ifdef CONFIG_ARCH_OMAP16XX + /* REVISIT: assuming only 16xx supports MPUIO wake events */ + .set_wake = gpio_wake_enable, +#endif }; #define bank_is_mpuio(bank) ((bank)->method == METHOD_MPUIO) + +#ifdef CONFIG_ARCH_OMAP16XX + +#include + +static int omap_mpuio_suspend_late(struct platform_device *pdev, pm_message_t mesg) +{ + struct gpio_bank *bank = platform_get_drvdata(pdev); + void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT; + + spin_lock(&bank->lock); + bank->saved_wakeup = __raw_readl(mask_reg); + __raw_writel(0xffff & ~bank->suspend_wakeup, mask_reg); + spin_unlock(&bank->lock); + + return 0; +} + +static int omap_mpuio_resume_early(struct platform_device *pdev) +{ + struct gpio_bank *bank = platform_get_drvdata(pdev); + void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT; + + spin_lock(&bank->lock); + __raw_writel(bank->saved_wakeup, mask_reg); + spin_unlock(&bank->lock); + + return 0; +} + +/* use platform_driver for this, now that there's no longer any + * point to sys_device (other than not disturbing old code). + */ +static struct platform_driver omap_mpuio_driver = { + .suspend_late = omap_mpuio_suspend_late, + .resume_early = omap_mpuio_resume_early, + .driver = { + .name = "mpuio", + }, +}; + +static struct platform_device omap_mpuio_device = { + .name = "mpuio", + .id = -1, + .dev = { + .driver = &omap_mpuio_driver.driver, + } + /* could list the /proc/iomem resources */ +}; + +static inline void mpuio_init(void) +{ + if (platform_driver_register(&omap_mpuio_driver) == 0) + (void) platform_device_register(&omap_mpuio_device); +} + +#else +static inline void mpuio_init(void) {} +#endif /* 16xx */ + #else extern struct irq_chip mpuio_irq_chip; #define bank_is_mpuio(bank) 0 +static inline void mpuio_init(void) {} #endif @@ -1487,6 +1558,8 @@ static int __init omap_gpio_sysinit(void) if (!initialized) ret = _omap_gpio_init(); + mpuio_init(); + #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) if (cpu_is_omap16xx() || cpu_is_omap24xx()) { if (ret == 0) { -- cgit v1.2.3-59-g8ed1b From fcf126d847c41461d4f034b11541296f3e15d0b2 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 2 Apr 2007 12:46:47 -0700 Subject: ARM: OMAP: fix OMAP1 mpuio suspend/resume oops Fix oops in omap16xx mpuio suspend/resume code; field wasn't initialized Signed-off-by: David Brownell Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/plat-omap/gpio.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index df0ff0fd881a..9dc6d3617bdb 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -1178,6 +1178,8 @@ static struct platform_device omap_mpuio_device = { static inline void mpuio_init(void) { + platform_set_drvdata(&omap_mpuio_device, &gpio_bank_1610[0]); + if (platform_driver_register(&omap_mpuio_driver) == 0) (void) platform_device_register(&omap_mpuio_device); } -- cgit v1.2.3-59-g8ed1b From 9ef7963503abd3287943125681c2dc17879e8d4e Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 5 May 2007 20:03:35 +0100 Subject: [ARM] mm 8: define mem_types table L1 bit 4 to be for ARMv6 Change the memory types table to define the L1 descriptor bit 4 to be in terms of the ARMv6 definition - execute never. Signed-off-by: Russell King --- arch/arm/mm/mmu.c | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 360405515bbd..44f385a3eb3f 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -181,16 +181,16 @@ static struct mem_type mem_types[] = { .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE, .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED | + .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_UNCACHED | PMD_SECT_AP_WRITE, .domain = DOMAIN_IO, }, [MT_CACHECLEAN] = { - .prot_sect = PMD_TYPE_SECT | PMD_BIT4, + .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN, .domain = DOMAIN_KERNEL, }, [MT_MINICLEAN] = { - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_MINICACHE, + .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_MINICACHE, .domain = DOMAIN_KERNEL, }, [MT_LOW_VECTORS] = { @@ -206,25 +206,25 @@ static struct mem_type mem_types[] = { .domain = DOMAIN_USER, }, [MT_MEMORY] = { - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_AP_WRITE, + .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, .domain = DOMAIN_KERNEL, }, [MT_ROM] = { - .prot_sect = PMD_TYPE_SECT | PMD_BIT4, + .prot_sect = PMD_TYPE_SECT, .domain = DOMAIN_KERNEL, }, [MT_IXP2000_DEVICE] = { /* IXP2400 requires XCB=101 for on-chip I/O */ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE, .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED | + .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_UNCACHED | PMD_SECT_AP_WRITE | PMD_SECT_BUFFERABLE | PMD_SECT_TEX(1), .domain = DOMAIN_IO, }, [MT_NONSHARED_DEVICE] = { .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_NONSHARED_DEV | + .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_NONSHARED_DEV | PMD_SECT_AP_WRITE, .domain = DOMAIN_IO, } @@ -260,20 +260,23 @@ static void __init build_mem_type_table(void) } /* - * Xscale must not have PMD bit 4 set for section mappings. + * ARMv5 and lower, bit 4 must be set for page tables. + * (was: cache "update-able on write" bit on ARM610) + * However, Xscale cores require this bit to be cleared. */ - if (cpu_is_xscale()) - for (i = 0; i < ARRAY_SIZE(mem_types); i++) + if (cpu_is_xscale()) { + for (i = 0; i < ARRAY_SIZE(mem_types); i++) { mem_types[i].prot_sect &= ~PMD_BIT4; - - /* - * ARMv5 and lower, excluding Xscale, bit 4 must be set for - * page tables. - */ - if (cpu_arch < CPU_ARCH_ARMv6 && !cpu_is_xscale()) - for (i = 0; i < ARRAY_SIZE(mem_types); i++) + mem_types[i].prot_l1 &= ~PMD_BIT4; + } + } else if (cpu_arch < CPU_ARCH_ARMv6) { + for (i = 0; i < ARRAY_SIZE(mem_types); i++) { if (mem_types[i].prot_l1) mem_types[i].prot_l1 |= PMD_BIT4; + if (mem_types[i].prot_sect) + mem_types[i].prot_sect |= PMD_BIT4; + } + } cp = &cache_policies[cachepolicy]; kern_pgprot = user_pgprot = cp->pte; @@ -293,13 +296,6 @@ static void __init build_mem_type_table(void) * ARMv6 and above have extended page tables. */ if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { - /* - * bit 4 becomes XN which we must clear for the - * kernel memory mapping. - */ - mem_types[MT_MEMORY].prot_sect &= ~PMD_SECT_XN; - mem_types[MT_ROM].prot_sect &= ~PMD_SECT_XN; - /* * Mark cache clean areas and XIP ROM read only * from SVC mode and no access from userspace. -- cgit v1.2.3-59-g8ed1b From 0af92befeb4b330c46cce6b520b2cc775cd6931f Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 5 May 2007 20:28:16 +0100 Subject: [ARM] mm 9: add additional device memory types Add cached device type for ioremap_cached(). Group all device memory types together, and ensure that they all have a "MT_DEVICE" prefix. Signed-off-by: Russell King --- arch/arm/mach-ixp2000/core.c | 22 +++++++++--------- arch/arm/mach-ixp2000/enp2611.c | 6 ++--- arch/arm/mm/mmu.c | 50 +++++++++++++++++++++++------------------ include/asm-arm/mach/map.h | 20 ++++++++++------- 4 files changed, 54 insertions(+), 44 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index 27b7480f4afe..9cf2498dc99e 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c @@ -84,59 +84,59 @@ static struct map_desc ixp2000_io_desc[] __initdata = { .virtual = IXP2000_CAP_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE), .length = IXP2000_CAP_SIZE, - .type = MT_IXP2000_DEVICE, + .type = MT_DEVICE_IXP2000, }, { .virtual = IXP2000_INTCTL_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE), .length = IXP2000_INTCTL_SIZE, - .type = MT_IXP2000_DEVICE, + .type = MT_DEVICE_IXP2000, }, { .virtual = IXP2000_PCI_CREG_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE), .length = IXP2000_PCI_CREG_SIZE, - .type = MT_IXP2000_DEVICE, + .type = MT_DEVICE_IXP2000, }, { .virtual = IXP2000_PCI_CSR_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE), .length = IXP2000_PCI_CSR_SIZE, - .type = MT_IXP2000_DEVICE, + .type = MT_DEVICE_IXP2000, }, { .virtual = IXP2000_MSF_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE), .length = IXP2000_MSF_SIZE, - .type = MT_IXP2000_DEVICE, + .type = MT_DEVICE_IXP2000, }, { .virtual = IXP2000_SCRATCH_RING_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_SCRATCH_RING_PHYS_BASE), .length = IXP2000_SCRATCH_RING_SIZE, - .type = MT_IXP2000_DEVICE, + .type = MT_DEVICE_IXP2000, }, { .virtual = IXP2000_SRAM0_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_SRAM0_PHYS_BASE), .length = IXP2000_SRAM0_SIZE, - .type = MT_IXP2000_DEVICE, + .type = MT_DEVICE_IXP2000, }, { .virtual = IXP2000_PCI_IO_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE), .length = IXP2000_PCI_IO_SIZE, - .type = MT_IXP2000_DEVICE, + .type = MT_DEVICE_IXP2000, }, { .virtual = IXP2000_PCI_CFG0_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE), .length = IXP2000_PCI_CFG0_SIZE, - .type = MT_IXP2000_DEVICE, + .type = MT_DEVICE_IXP2000, }, { .virtual = IXP2000_PCI_CFG1_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE), .length = IXP2000_PCI_CFG1_SIZE, - .type = MT_IXP2000_DEVICE, + .type = MT_DEVICE_IXP2000, } }; void __init ixp2000_map_io(void) { /* - * On IXP2400 CPUs we need to use MT_IXP2000_DEVICE so that + * On IXP2400 CPUs we need to use MT_DEVICE_IXP2000 so that * XCB=101 (to avoid triggering erratum #66), and given that * this mode speeds up I/O accesses and we have write buffer * flushes in the right places anyway, it doesn't hurt to use diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c index ac29298c5d3f..500e997ba7a4 100644 --- a/arch/arm/mach-ixp2000/enp2611.c +++ b/arch/arm/mach-ixp2000/enp2611.c @@ -70,17 +70,17 @@ static struct map_desc enp2611_io_desc[] __initdata = { .virtual = ENP2611_CALEB_VIRT_BASE, .pfn = __phys_to_pfn(ENP2611_CALEB_PHYS_BASE), .length = ENP2611_CALEB_SIZE, - .type = MT_IXP2000_DEVICE, + .type = MT_DEVICE_IXP2000, }, { .virtual = ENP2611_PM3386_0_VIRT_BASE, .pfn = __phys_to_pfn(ENP2611_PM3386_0_PHYS_BASE), .length = ENP2611_PM3386_0_SIZE, - .type = MT_IXP2000_DEVICE, + .type = MT_DEVICE_IXP2000, }, { .virtual = ENP2611_PM3386_1_VIRT_BASE, .pfn = __phys_to_pfn(ENP2611_PM3386_1_PHYS_BASE), .length = ENP2611_PM3386_1_SIZE, - .type = MT_IXP2000_DEVICE, + .type = MT_DEVICE_IXP2000, } }; diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 44f385a3eb3f..2ba1530d1ce1 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -176,14 +176,35 @@ void adjust_cr(unsigned long mask, unsigned long set) } #endif +#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_WRITE +#define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_XN|PMD_SECT_AP_WRITE + static struct mem_type mem_types[] = { - [MT_DEVICE] = { - .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_WRITE, - .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_UNCACHED | - PMD_SECT_AP_WRITE, - .domain = DOMAIN_IO, + [MT_DEVICE] = { /* Strongly ordered / ARMv6 shared device */ + .prot_pte = PROT_PTE_DEVICE, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PROT_SECT_DEVICE | PMD_SECT_UNCACHED, + .domain = DOMAIN_IO, + }, + [MT_DEVICE_NONSHARED] = { /* ARMv6 non-shared device */ + .prot_pte = PROT_PTE_DEVICE, + .prot_pte_ext = PTE_EXT_TEX(2), + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PROT_SECT_DEVICE | PMD_SECT_TEX(2), + .domain = DOMAIN_IO, + }, + [MT_DEVICE_CACHED] = { /* ioremap_cached */ + .prot_pte = PROT_PTE_DEVICE | L_PTE_CACHEABLE | L_PTE_BUFFERABLE, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PROT_SECT_DEVICE | PMD_SECT_WB, + .domain = DOMAIN_IO, + }, + [MT_DEVICE_IXP2000] = { /* IXP2400 requires XCB=101 for on-chip I/O */ + .prot_pte = PROT_PTE_DEVICE, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PROT_SECT_DEVICE | PMD_SECT_BUFFERABLE | + PMD_SECT_TEX(1), + .domain = DOMAIN_IO, }, [MT_CACHECLEAN] = { .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN, @@ -213,21 +234,6 @@ static struct mem_type mem_types[] = { .prot_sect = PMD_TYPE_SECT, .domain = DOMAIN_KERNEL, }, - [MT_IXP2000_DEVICE] = { /* IXP2400 requires XCB=101 for on-chip I/O */ - .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_WRITE, - .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_UNCACHED | - PMD_SECT_AP_WRITE | PMD_SECT_BUFFERABLE | - PMD_SECT_TEX(1), - .domain = DOMAIN_IO, - }, - [MT_NONSHARED_DEVICE] = { - .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_NONSHARED_DEV | - PMD_SECT_AP_WRITE, - .domain = DOMAIN_IO, - } }; const struct mem_type *get_mem_type(unsigned int type) diff --git a/include/asm-arm/mach/map.h b/include/asm-arm/mach/map.h index cef5364ed5fe..8afef40730af 100644 --- a/include/asm-arm/mach/map.h +++ b/include/asm-arm/mach/map.h @@ -17,14 +17,18 @@ struct map_desc { }; #define MT_DEVICE 0 -#define MT_CACHECLEAN 1 -#define MT_MINICLEAN 2 -#define MT_LOW_VECTORS 3 -#define MT_HIGH_VECTORS 4 -#define MT_MEMORY 5 -#define MT_ROM 6 -#define MT_IXP2000_DEVICE 7 -#define MT_NONSHARED_DEVICE 8 +#define MT_DEVICE_NONSHARED 1 +#define MT_DEVICE_CACHED 2 +#define MT_DEVICE_IXP2000 3 +#define MT_CACHECLEAN 4 +#define MT_MINICLEAN 5 +#define MT_LOW_VECTORS 6 +#define MT_HIGH_VECTORS 7 +#define MT_MEMORY 8 +#define MT_ROM 9 + +#define MT_NONSHARED_DEVICE MT_DEVICE_NONSHARED +#define MT_IXP2000_DEVICE MT_DEVICE_IXP2000 #ifdef CONFIG_MMU extern void iotable_init(struct map_desc *, int); -- cgit v1.2.3-59-g8ed1b From 3603ab2b62ad8372fc93816b080b370dd55d7cec Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 5 May 2007 20:59:27 +0100 Subject: [ARM] mm 10: allow memory type to be specified with ioremap __ioremap() took a set of page table flags (specifically the cacheable and bufferable bits) to control the mapping type. However, with the advent of ARMv6, this is far too limited. Replace the page table flags with a memory type index, so that the desired attributes can be selected from the mem_type table. Finally, to prevent silent miscompilation due to the differing arguments, rename the __ioremap() and __ioremap_pfn() functions. Signed-off-by: Russell King --- arch/arm/mach-iop13xx/io.c | 10 +++++----- arch/arm/mach-iop13xx/pci.c | 8 ++++---- arch/arm/mm/ioremap.c | 20 +++++++++----------- arch/arm/mm/nommu.c | 12 ++++++------ arch/arm/plat-iop/io.c | 4 ++-- include/asm-arm/arch-ixp23xx/io.h | 4 ++-- include/asm-arm/arch-ixp4xx/io.h | 4 ++-- include/asm-arm/io.h | 33 +++++++++++++++++++++------------ include/asm-arm/mach/map.h | 7 +++---- 9 files changed, 54 insertions(+), 48 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-iop13xx/io.c b/arch/arm/mach-iop13xx/io.c index e79a1b62600f..5b22fdeca52c 100644 --- a/arch/arm/mach-iop13xx/io.c +++ b/arch/arm/mach-iop13xx/io.c @@ -41,7 +41,7 @@ void * __iomem __iop13xx_io(unsigned long io_addr) EXPORT_SYMBOL(__iop13xx_io); void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size, - unsigned long flags) + unsigned int mtype) { void __iomem * retval; @@ -61,9 +61,9 @@ void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size, (cookie - IOP13XX_PCIE_LOWER_MEM_RA)); break; case IOP13XX_PBI_LOWER_MEM_RA ... IOP13XX_PBI_UPPER_MEM_RA: - retval = __ioremap(IOP13XX_PBI_LOWER_MEM_PA + - (cookie - IOP13XX_PBI_LOWER_MEM_RA), - size, flags); + retval = __arm_ioremap(IOP13XX_PBI_LOWER_MEM_PA + + (cookie - IOP13XX_PBI_LOWER_MEM_RA), + size, mtype); break; case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA: retval = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(cookie); @@ -75,7 +75,7 @@ void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size, retval = (void *) IOP13XX_PMMR_PHYS_TO_VIRT(cookie); break; default: - retval = __ioremap(cookie, size, flags); + retval = __arm_ioremap(cookie, size, mtype); } return retval; diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c index 89ec70ea3187..d85b88fcb7e8 100644 --- a/arch/arm/mach-iop13xx/pci.c +++ b/arch/arm/mach-iop13xx/pci.c @@ -88,9 +88,9 @@ void iop13xx_map_pci_memory(void) if (end) { iop13xx_atux_mem_base = - (u32) __ioremap_pfn( + (u32) __arm_ioremap_pfn( __phys_to_pfn(IOP13XX_PCIX_LOWER_MEM_PA) - , 0, iop13xx_atux_mem_size, 0); + , 0, iop13xx_atux_mem_size, MT_DEVICE); if (!iop13xx_atux_mem_base) { printk("%s: atux allocation " "failed\n", __FUNCTION__); @@ -114,9 +114,9 @@ void iop13xx_map_pci_memory(void) if (end) { iop13xx_atue_mem_base = - (u32) __ioremap_pfn( + (u32) __arm_ioremap_pfn( __phys_to_pfn(IOP13XX_PCIE_LOWER_MEM_PA) - , 0, iop13xx_atue_mem_size, 0); + , 0, iop13xx_atue_mem_size, MT_DEVICE); if (!iop13xx_atue_mem_base) { printk("%s: atue allocation " "failed\n", __FUNCTION__); diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index 216623eece35..d6167ad4e011 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -262,11 +262,10 @@ remap_area_supersections(unsigned long virt, unsigned long pfn, * mapping. See include/asm-arm/proc-armv/pgtable.h for more information. */ void __iomem * -__ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, - unsigned long flags) +__arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, + unsigned int mtype) { const struct mem_type *type; - struct mem_type t; int err; unsigned long addr; struct vm_struct * area; @@ -277,10 +276,9 @@ __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, if (pfn >= 0x100000 && (__pfn_to_phys(pfn) & ~SUPERSECTION_MASK)) return NULL; - t = *get_mem_type(MT_DEVICE); - t.prot_sect |= flags; - t.prot_pte |= flags; - type = &t; + type = get_mem_type(mtype); + if (!type) + return NULL; size = PAGE_ALIGN(size); @@ -311,10 +309,10 @@ __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, flush_cache_vmap(addr, addr + size); return (void __iomem *) (offset + addr); } -EXPORT_SYMBOL(__ioremap_pfn); +EXPORT_SYMBOL(__arm_ioremap_pfn); void __iomem * -__ioremap(unsigned long phys_addr, size_t size, unsigned long flags) +__arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) { unsigned long last_addr; unsigned long offset = phys_addr & ~PAGE_MASK; @@ -332,9 +330,9 @@ __ioremap(unsigned long phys_addr, size_t size, unsigned long flags) */ size = PAGE_ALIGN(last_addr + 1) - phys_addr; - return __ioremap_pfn(pfn, offset, size, flags); + return __arm_ioremap_pfn(pfn, offset, size, mtype); } -EXPORT_SYMBOL(__ioremap); +EXPORT_SYMBOL(__arm_ioremap); void __iounmap(volatile void __iomem *addr) { diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 05818fc0c705..8cd3a60954f0 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -62,21 +62,21 @@ void flush_dcache_page(struct page *page) } EXPORT_SYMBOL(flush_dcache_page); -void __iomem *__ioremap_pfn(unsigned long pfn, unsigned long offset, - size_t size, unsigned long flags) +void __iomem *__arm_ioremap_pfn(unsigned long pfn, unsigned long offset, + size_t size, unsigned int mtype) { if (pfn >= (0x100000000ULL >> PAGE_SHIFT)) return NULL; return (void __iomem *) (offset + (pfn << PAGE_SHIFT)); } -EXPORT_SYMBOL(__ioremap_pfn); +EXPORT_SYMBOL(__arm_ioremap_pfn); -void __iomem *__ioremap(unsigned long phys_addr, size_t size, - unsigned long flags) +void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size, + unsigned int mtype) { return (void __iomem *)phys_addr; } -EXPORT_SYMBOL(__ioremap); +EXPORT_SYMBOL(__arm_ioremap); void __iounmap(volatile void __iomem *addr) { diff --git a/arch/arm/plat-iop/io.c b/arch/arm/plat-iop/io.c index f7eccecf2e47..498675d028d0 100644 --- a/arch/arm/plat-iop/io.c +++ b/arch/arm/plat-iop/io.c @@ -22,7 +22,7 @@ #include void * __iomem __iop3xx_ioremap(unsigned long cookie, size_t size, - unsigned long flags) + unsigned int mtype) { void __iomem * retval; @@ -34,7 +34,7 @@ void * __iomem __iop3xx_ioremap(unsigned long cookie, size_t size, retval = (void *) IOP3XX_PMMR_PHYS_TO_VIRT(cookie); break; default: - retval = __ioremap(cookie, size, flags); + retval = __arm_ioremap(cookie, size, mtype); } return retval; diff --git a/include/asm-arm/arch-ixp23xx/io.h b/include/asm-arm/arch-ixp23xx/io.h index 18415a81ac74..66f5bafc315c 100644 --- a/include/asm-arm/arch-ixp23xx/io.h +++ b/include/asm-arm/arch-ixp23xx/io.h @@ -23,7 +23,7 @@ #include /* For BUG */ static inline void __iomem * -ixp23xx_ioremap(unsigned long addr, unsigned long size, unsigned long flags) +ixp23xx_ioremap(unsigned long addr, unsigned long size, unsigned int mtype) { if (addr >= IXP23XX_PCI_MEM_START && addr <= IXP23XX_PCI_MEM_START + IXP23XX_PCI_MEM_SIZE) { @@ -34,7 +34,7 @@ ixp23xx_ioremap(unsigned long addr, unsigned long size, unsigned long flags) ((addr - IXP23XX_PCI_MEM_START) + IXP23XX_PCI_MEM_VIRT); } - return __ioremap(addr, size, flags); + return __arm_ioremap(addr, size, mtype); } static inline void diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h index a41ba229c564..b27c910adf9d 100644 --- a/include/asm-arm/arch-ixp4xx/io.h +++ b/include/asm-arm/arch-ixp4xx/io.h @@ -59,10 +59,10 @@ extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data); * fallback to the default. */ static inline void __iomem * -__ixp4xx_ioremap(unsigned long addr, size_t size, unsigned long flags) +__ixp4xx_ioremap(unsigned long addr, size_t size, unsigned int mtype) { if((addr < 0x48000000) || (addr > 0x4fffffff)) - return __ioremap(addr, size, flags); + return __arm_ioremap(addr, size, mtype); return (void *)addr; } diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h index 5f60b4220906..8261ff9e7955 100644 --- a/include/asm-arm/io.h +++ b/include/asm-arm/io.h @@ -56,13 +56,22 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); /* * Architecture ioremap implementation. - * - * __ioremap takes CPU physical address. - * - * __ioremap_pfn takes a Page Frame Number and an offset into that page */ -extern void __iomem * __ioremap_pfn(unsigned long, unsigned long, size_t, unsigned long); -extern void __iomem * __ioremap(unsigned long, size_t, unsigned long); +#define MT_DEVICE 0 +#define MT_DEVICE_NONSHARED 1 +#define MT_DEVICE_CACHED 2 +#define MT_DEVICE_IXP2000 3 +/* + * types 4 onwards can be found in asm/mach/map.h and are undefined + * for ioremap + */ + +/* + * __arm_ioremap takes CPU physical address. + * __arm_ioremap_pfn takes a Page Frame Number and an offset into that page + */ +extern void __iomem * __arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int); +extern void __iomem * __arm_ioremap(unsigned long, size_t, unsigned int); extern void __iounmap(volatile void __iomem *addr); /* @@ -203,14 +212,14 @@ extern void _memset_io(volatile void __iomem *, int, size_t); * */ #ifndef __arch_ioremap -#define ioremap(cookie,size) __ioremap(cookie,size,0) -#define ioremap_nocache(cookie,size) __ioremap(cookie,size,0) -#define ioremap_cached(cookie,size) __ioremap(cookie,size,L_PTE_CACHEABLE) +#define ioremap(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE) +#define ioremap_nocache(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE) +#define ioremap_cached(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE_CACHED) #define iounmap(cookie) __iounmap(cookie) #else -#define ioremap(cookie,size) __arch_ioremap((cookie),(size),0) -#define ioremap_nocache(cookie,size) __arch_ioremap((cookie),(size),0) -#define ioremap_cached(cookie,size) __arch_ioremap((cookie),(size),L_PTE_CACHEABLE) +#define ioremap(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE) +#define ioremap_nocache(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE) +#define ioremap_cached(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_CACHED) #define iounmap(cookie) __arch_iounmap(cookie) #endif diff --git a/include/asm-arm/mach/map.h b/include/asm-arm/mach/map.h index 8afef40730af..7ef3c8390180 100644 --- a/include/asm-arm/mach/map.h +++ b/include/asm-arm/mach/map.h @@ -9,6 +9,8 @@ * * Page table mapping constructs and function prototypes */ +#include + struct map_desc { unsigned long virtual; unsigned long pfn; @@ -16,10 +18,7 @@ struct map_desc { unsigned int type; }; -#define MT_DEVICE 0 -#define MT_DEVICE_NONSHARED 1 -#define MT_DEVICE_CACHED 2 -#define MT_DEVICE_IXP2000 3 +/* types 0-3 are defined in asm/io.h */ #define MT_CACHECLEAN 4 #define MT_MINICLEAN 5 #define MT_LOW_VECTORS 6 -- cgit v1.2.3-59-g8ed1b From c4b5bd4b101a8da1fb24a072adde276547462b43 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Sat, 5 May 2007 15:12:17 +0100 Subject: [ARM] 4358/1: S3C24XX: mach-qt2410.c: remove linux/mmc/protocol.h header linux/mmc/protocol.h header is gone, thus breaking the build of the mach-qt2410.c file. As this header is not used, I'm removing it. The right headers may still be added later if needed. Signed-off-by: Arnaud Patard Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/mach-qt2410.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c index caf6778472d3..9cc4253d7bbc 100644 --- a/arch/arm/mach-s3c2410/mach-qt2410.c +++ b/arch/arm/mach-s3c2410/mach-qt2410.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3-59-g8ed1b From 5ba6d3febd4978f31b2c523d64d381603923a709 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 6 May 2007 13:56:26 +0100 Subject: [ARM] Move syscall saving out of the way of utrace utrace removes the ptrace_message field in task_struct. Move our use of this field into a new member in thread_info called "syscall" Signed-off-by: Russell King --- arch/arm/kernel/ptrace.c | 6 +++--- include/asm-arm/thread_info.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index e594b84cca83..13af4006a40f 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -779,8 +779,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; case PTRACE_SET_SYSCALL: + task_thread_info(child)->syscall = data; ret = 0; - child->ptrace_message = data; break; #ifdef CONFIG_CRUNCH @@ -817,7 +817,7 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) ip = regs->ARM_ip; regs->ARM_ip = why; - current->ptrace_message = scno; + current_thread_info()->syscall = scno; /* the 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */ @@ -834,5 +834,5 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) } regs->ARM_ip = ip; - return current->ptrace_message; + return current_thread_info()->syscall; } diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h index 5014794f9eb3..eae85b09db2e 100644 --- a/include/asm-arm/thread_info.h +++ b/include/asm-arm/thread_info.h @@ -57,6 +57,7 @@ struct thread_info { __u32 cpu; /* cpu */ __u32 cpu_domain; /* cpu domain */ struct cpu_context_save cpu_context; /* cpu context */ + __u32 syscall; /* syscall number */ __u8 used_cp[16]; /* thread used copro */ unsigned long tp_value; struct crunch_state crunchstate; -- cgit v1.2.3-59-g8ed1b From fa5da2f7bdcf885efe65a37df13907c7d72296f6 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 8 Mar 2007 17:27:37 +0900 Subject: sh: Bring kgdb back from the dead. This code has suffered quite a bit of bitrot, do some basic tidying to get it to a reasonably functional state again. This gets the basic support and the console working again. Signed-off-by: Paul Mundt --- arch/sh/Kconfig.debug | 15 ++--- arch/sh/Makefile | 1 - arch/sh/boards/se/7751/setup.c | 148 ----------------------------------------- arch/sh/kernel/kgdb_stub.c | 106 ++++++++++++++--------------- arch/sh/kernel/setup.c | 94 +------------------------- drivers/serial/sh-sci.c | 53 +++++++++------ include/asm-sh/kgdb.h | 51 ++------------ include/asm-sh/se7751.h | 2 + 8 files changed, 101 insertions(+), 369 deletions(-) (limited to 'arch') diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 87902e0298e2..6be2385c1ad2 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -77,16 +77,17 @@ config 4KSTACKS on the VM subsystem for higher order allocations. This option will also use IRQ stacks to compensate for the reduced stackspace. -config KGDB +config SH_KGDB bool "Include KGDB kernel debugger" select FRAME_POINTER + select DEBUG_INFO help Include in-kernel hooks for kgdb, the Linux kernel source level debugger. See for more information. Unless you are intending to debug the kernel, say N here. menu "KGDB configuration options" - depends on KGDB + depends on SH_KGDB config MORE_COMPILE_OPTIONS bool "Add any additional compile options" @@ -109,16 +110,14 @@ config KGDB_THREAD config SH_KGDB_CONSOLE bool "Console messages through GDB" + depends on !SERIAL_SH_SCI_CONSOLE + select SERIAL_CORE_CONSOLE default n config KGDB_SYSRQ bool "Allow SysRq 'G' to enter KGDB" default y -config KGDB_KERNEL_ASSERTS - bool "Include KGDB kernel assertions" - default n - comment "Serial port setup" config KGDB_DEFPORT @@ -131,7 +130,7 @@ config KGDB_DEFBAUD choice prompt "Parity" - depends on KGDB + depends on SH_KGDB default KGDB_DEFPARITY_N config KGDB_DEFPARITY_N @@ -147,7 +146,7 @@ endchoice choice prompt "Data bits" - depends on KGDB + depends on SH_KGDB default KGDB_DEFBITS_8 config KGDB_DEFBITS_8 diff --git a/arch/sh/Makefile b/arch/sh/Makefile index bd9b1729f8b8..0fadde283368 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -47,7 +47,6 @@ cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -ffreestanding cflags-$(CONFIG_SH_DSP) += -Wa,-dsp -cflags-$(CONFIG_SH_KGDB) += -g cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \ $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g') diff --git a/arch/sh/boards/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c index e3feae6ec0bf..770defed9c4a 100644 --- a/arch/sh/boards/se/7751/setup.c +++ b/arch/sh/boards/se/7751/setup.c @@ -14,153 +14,6 @@ #include #include -void init_7751se_IRQ(void); - -#ifdef CONFIG_SH_KGDB -#include -static int kgdb_uart_setup(void); -static struct kgdb_sermap kgdb_uart_sermap = -{ "ttyS", 0, kgdb_uart_setup, NULL }; -#endif - -/* - * Initialize the board - */ -static void __init sh7751se_setup(char **cmdline_p) -{ - /* Call init_smsc() replacement to set up SuperIO. */ - /* XXX: RTC setting comes here */ -#ifdef CONFIG_SH_KGDB - kgdb_register_sermap(&kgdb_uart_sermap); -#endif -} - -/********************************************************************* - * Currently a hack (e.g. does not interact well w/serial.c, lots of * - * hardcoded stuff) but may be useful if SCI/F needs debugging. * - * Mostly copied from x86 code (see files asm-i386/kgdb_local.h and * - * arch/i386/lib/kgdb_serial.c). * - *********************************************************************/ - -#ifdef CONFIG_SH_KGDB -#include -#include -#include -#include - -#define COM1_PORT 0x3f8 /* Base I/O address */ -#define COM1_IRQ 4 /* IRQ not used yet */ -#define COM2_PORT 0x2f8 /* Base I/O address */ -#define COM2_IRQ 3 /* IRQ not used yet */ - -#define SB_CLOCK 1843200 /* Serial baud clock */ -#define SB_BASE (SB_CLOCK/16) -#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS - -struct uart_port { - int base; -}; -#define UART_NPORTS 2 -struct uart_port uart_ports[] = { - { COM1_PORT }, - { COM2_PORT }, -}; -struct uart_port *kgdb_uart_port; - -#define UART_IN(reg) inb_p(kgdb_uart_port->base + reg) -#define UART_OUT(reg,v) outb_p((v), kgdb_uart_port->base + reg) - -/* Basic read/write functions for the UART */ -#define UART_LSR_RXCERR (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE) -static int kgdb_uart_getchar(void) -{ - int lsr; - int c = -1; - - while (c == -1) { - lsr = UART_IN(UART_LSR); - if (lsr & UART_LSR_DR) - c = UART_IN(UART_RX); - if ((lsr & UART_LSR_RXCERR)) - c = -1; - } - return c; -} - -static void kgdb_uart_putchar(int c) -{ - while ((UART_IN(UART_LSR) & UART_LSR_THRE) == 0) - ; - UART_OUT(UART_TX, c); -} - -/* - * Initialize UART to configured/requested values. - * (But we don't interrupts yet, or interact w/serial.c) - */ -static int kgdb_uart_setup(void) -{ - int port; - int lcr = 0; - int bdiv = 0; - - if (kgdb_portnum >= UART_NPORTS) { - KGDB_PRINTK("uart port %d invalid.\n", kgdb_portnum); - return -1; - } - - kgdb_uart_port = &uart_ports[kgdb_portnum]; - - /* Init sequence from gdb_hook_interrupt */ - UART_IN(UART_RX); - UART_OUT(UART_IER, 0); - - UART_IN(UART_RX); /* Serial driver comments say */ - UART_IN(UART_IIR); /* this clears interrupt regs */ - UART_IN(UART_MSR); - - /* Figure basic LCR values */ - switch (kgdb_bits) { - case '7': - lcr |= UART_LCR_WLEN7; - break; - default: case '8': - lcr |= UART_LCR_WLEN8; - break; - } - switch (kgdb_parity) { - case 'O': - lcr |= UART_LCR_PARITY; - break; - case 'E': - lcr |= (UART_LCR_PARITY | UART_LCR_EPAR); - break; - default: break; - } - - /* Figure the baud rate divisor */ - bdiv = (SB_BASE/kgdb_baud); - - /* Set the baud rate and LCR values */ - UART_OUT(UART_LCR, (lcr | UART_LCR_DLAB)); - UART_OUT(UART_DLL, (bdiv & 0xff)); - UART_OUT(UART_DLM, ((bdiv >> 8) & 0xff)); - UART_OUT(UART_LCR, lcr); - - /* Set the MCR */ - UART_OUT(UART_MCR, SB_MCR); - - /* Turn off FIFOs for now */ - UART_OUT(UART_FCR, 0); - - /* Setup complete: initialize function pointers */ - kgdb_getchar = kgdb_uart_getchar; - kgdb_putchar = kgdb_uart_putchar; - - return 0; -} -#endif /* CONFIG_SH_KGDB */ - static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; static struct resource heartbeat_resources[] = { @@ -197,7 +50,6 @@ __initcall(se7751_devices_setup); */ struct sh_machine_vector mv_7751se __initmv = { .mv_name = "7751 SolutionEngine", - .mv_setup = sh7751se_setup, .mv_nr_irqs = 72, .mv_inb = sh7751se_inb, diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c index d8927d85492e..737eadc8ce0f 100644 --- a/arch/sh/kernel/kgdb_stub.c +++ b/arch/sh/kernel/kgdb_stub.c @@ -6,11 +6,11 @@ * David Grothe , Tigran Aivazian , * Amit S. Kale , William Gatliff , * Ben Lee, Steve Chamberlain and Benoit Miller . - * + * * This version by Henry Bell * Minor modifications by Jeremy Siegel - * - * Contains low-level support for remote debug using GDB. + * + * Contains low-level support for remote debug using GDB. * * To enable debugger support, two things need to happen. A call to * set_debug_traps() is necessary in order to allow any breakpoints @@ -48,7 +48,7 @@ * k kill (Detach GDB) * * d Toggle debug flag - * D Detach GDB + * D Detach GDB * * Hct Set thread t for operations, OK or ENN * c = 'c' (step, cont), c = 'g' (other @@ -58,7 +58,7 @@ * qfThreadInfo Get list of current threads (first) m * qsThreadInfo " " " " " (subsequent) * qOffsets Get section offsets Text=x;Data=y;Bss=z - * + * * TXX Find if thread XX is alive OK or ENN * ? What was the last sigval ? SNN (signal NN) * O Output to GDB console @@ -74,7 +74,7 @@ * '$' or '#'. If starts with two characters followed by * ':', then the existing stubs interpret this as a sequence number. * - * CSUM1 and CSUM2 are ascii hex representation of an 8-bit + * CSUM1 and CSUM2 are ascii hex representation of an 8-bit * checksum of , the most significant nibble is sent first. * the hex digits 0-9,a-f are used. * @@ -86,8 +86,8 @@ * Responses can be run-length encoded to save space. A '*' means that * the next character is an ASCII encoding giving a repeat count which * stands for that many repititions of the character preceding the '*'. - * The encoding is n+29, yielding a printable character where n >=3 - * (which is where RLE starts to win). Don't use an n > 126. + * The encoding is n+29, yielding a printable character where n >=3 + * (which is where RLE starts to win). Don't use an n > 126. * * So "0* " means the same as "0000". */ @@ -100,12 +100,10 @@ #include #include #include - -#ifdef CONFIG_SH_KGDB_CONSOLE #include -#endif - +#include #include +#include #include #include #include @@ -153,7 +151,6 @@ char kgdb_in_gdb_mode; char in_nmi; /* Set during NMI to prevent reentry */ int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */ int kgdb_enabled = 1; /* Default to enabled, cmdline can disable */ -int kgdb_halt; /* Exposed for user access */ struct task_struct *kgdb_current; @@ -328,7 +325,7 @@ static int hex_to_int(char **ptr, int *int_value) } /* Copy the binary array pointed to by buf into mem. Fix $, #, - and 0x7d escaped with 0x7d. Return a pointer to the character + and 0x7d escaped with 0x7d. Return a pointer to the character after the last byte written. */ static char *ebin_to_mem(const char *buf, char *mem, int count) { @@ -452,7 +449,7 @@ static void get_packet(char *buffer, int buflen) /* Ack successful transfer */ put_debug_char('+'); - /* If a sequence char is present, reply + /* If a sequence char is present, reply the sequence ID */ if (buffer[2] == ':') { put_debug_char(buffer[0]); @@ -759,7 +756,7 @@ static short *get_step_address(void) return (short *) addr; } -/* Set up a single-step. Replace the instruction immediately after the +/* Set up a single-step. Replace the instruction immediately after the current instruction (i.e. next in the expected flow of control) with a trap instruction, so that returning will cause only a single instruction to be executed. Note that this model is slightly broken for instructions @@ -1002,10 +999,8 @@ void set_thread_msg(void) char *ptr; switch (in_buffer[1]) { - - /* To select which thread for gG etc messages, i.e. supported */ + /* To select which thread for gG etc messages, i.e. supported */ case 'g': - ptr = &in_buffer[2]; hex_to_int(&ptr, &threadid); thread = get_thread(threadid); @@ -1173,6 +1168,7 @@ static void query_msg(void) } #endif /* CONFIG_KGDB_THREAD */ +#ifdef CONFIG_SH_KGDB_CONSOLE /* * Bring up the ports.. */ @@ -1185,6 +1181,9 @@ static int kgdb_serial_setup(void) return 0; } +#else +#define kgdb_serial_setup() 0 +#endif /* The command loop, read and act on requests */ static void kgdb_command_loop(const int excep_code, const int trapa_value) @@ -1193,7 +1192,7 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value) if (excep_code == NMI_VEC) { #ifndef CONFIG_KGDB_NMI - KGDB_PRINTK("Ignoring unexpected NMI?\n"); + printk(KERN_NOTICE "KGDB: Ignoring unexpected NMI?\n"); return; #else /* CONFIG_KGDB_NMI */ if (!kgdb_enabled) { @@ -1216,10 +1215,7 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value) /* Enter GDB mode (e.g. after detach) */ if (!kgdb_in_gdb_mode) { /* Do serial setup, notify user, issue preemptive ack */ - kgdb_serial_setup(); - KGDB_PRINTK("Waiting for GDB (on %s%d at %d baud)\n", - (kgdb_porttype ? kgdb_porttype->name : ""), - kgdb_portnum, kgdb_baud); + printk(KERN_NOTICE "KGDB: Waiting for GDB\n"); kgdb_in_gdb_mode = 1; put_debug_char('+'); } @@ -1233,21 +1229,18 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value) will later be replaced by its original one. Do NOT do this for trap 0xff, since that indicates a compiled-in breakpoint which will not be replaced (and we would retake the trap forever) */ - if ((excep_code == TRAP_VEC) && (trapa_value != (0xff << 2))) { + if ((excep_code == TRAP_VEC) && (trapa_value != (0x3c << 2))) trap_registers.pc -= 2; - } /* Undo any stepping we may have done */ undo_single_step(); while (1) { - out_buffer[0] = 0; get_packet(in_buffer, BUFMAX); /* Examine first char of buffer to see what we need to do */ switch (in_buffer[0]) { - case '?': /* Send which signal we've received */ send_signal_msg(sigval); break; @@ -1323,11 +1316,8 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value) } /* There has been an exception, most likely a breakpoint. */ -asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) +static void handle_exception(struct pt_regs *regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); int excep_code, vbr_val; int count; int trapa_value = ctrl_inl(TRA); @@ -1355,7 +1345,7 @@ asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5, kgdb_trapa_val = trapa_value; /* Act on the exception */ - kgdb_command_loop(excep_code >> 5, trapa_value); + kgdb_command_loop(excep_code, trapa_value); kgdb_current = NULL; @@ -1373,14 +1363,12 @@ asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5, asm("ldc %0, vbr": :"r"(vbr_val)); } -/* Trigger a breakpoint by function */ -void breakpoint(void) +asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs __regs) { - if (!kgdb_enabled) { - kgdb_enabled = 1; - kgdb_init(); - } - BREAKPOINT(); + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); + handle_exception(regs); } /* Initialise the KGDB data structures and serial configuration */ @@ -1395,24 +1383,16 @@ int kgdb_init(void) kgdb_in_gdb_mode = 0; if (kgdb_serial_setup() != 0) { - KGDB_PRINTK("serial setup error\n"); + printk(KERN_NOTICE "KGDB: serial setup error\n"); return -1; } /* Init ptr to exception handler */ - kgdb_debug_hook = kgdb_handle_exception; + kgdb_debug_hook = handle_exception; kgdb_bus_err_hook = kgdb_handle_bus_error; /* Enter kgdb now if requested, or just report init done */ - if (kgdb_halt) { - kgdb_in_gdb_mode = 1; - put_debug_char('+'); - breakpoint(); - } - else - { - KGDB_PRINTK("stub is initialized.\n"); - } + printk(KERN_NOTICE "KGDB: stub is initialized.\n"); return 0; } @@ -1437,7 +1417,7 @@ static void kgdb_msg_write(const char *s, unsigned count) /* Calculate how many this time */ wcount = (count > MAXOUT) ? MAXOUT : count; - + /* Pack in hex chars */ for (i = 0; i < wcount; i++) bufptr = pack_hex_byte(bufptr, s[i]); @@ -1467,3 +1447,25 @@ void kgdb_console_write(struct console *co, const char *s, unsigned count) kgdb_msg_write(s, count); } #endif + +#ifdef CONFIG_KGDB_SYSRQ +static void sysrq_handle_gdb(int key, struct tty_struct *tty) +{ + printk("Entering GDB stub\n"); + breakpoint(); +} + +static struct sysrq_key_op sysrq_gdb_op = { + .handler = sysrq_handle_gdb, + .help_msg = "Gdb", + .action_msg = "GDB", +}; + +static int gdb_register_sysrq(void) +{ + printk("Registering GDB sysrq handler\n"); + register_sysrq_key('g', &sysrq_gdb_op); + return 0; +} +module_init(gdb_register_sysrq); +#endif diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 98802ab28211..f96490419768 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -25,11 +25,8 @@ #include #include -#ifdef CONFIG_SH_KGDB -#include -static int kgdb_parse_options(char *options); -#endif extern void * __rd_start, * __rd_end; + /* * Machine setup.. */ @@ -499,92 +496,3 @@ struct seq_operations cpuinfo_op = { .show = show_cpuinfo, }; #endif /* CONFIG_PROC_FS */ - -#ifdef CONFIG_SH_KGDB -/* - * Parse command-line kgdb options. By default KGDB is enabled, - * entered on error (or other action) using default serial info. - * The command-line option can include a serial port specification - * and an action to override default or configured behavior. - */ -struct kgdb_sermap kgdb_sci_sermap = -{ "ttySC", 5, kgdb_sci_setup, NULL }; - -struct kgdb_sermap *kgdb_serlist = &kgdb_sci_sermap; -struct kgdb_sermap *kgdb_porttype = &kgdb_sci_sermap; - -void kgdb_register_sermap(struct kgdb_sermap *map) -{ - struct kgdb_sermap *last; - - for (last = kgdb_serlist; last->next; last = last->next) - ; - last->next = map; - if (!map->namelen) { - map->namelen = strlen(map->name); - } -} - -static int __init kgdb_parse_options(char *options) -{ - char c; - int baud; - - /* Check for port spec (or use default) */ - - /* Determine port type and instance */ - if (!memcmp(options, "tty", 3)) { - struct kgdb_sermap *map = kgdb_serlist; - - while (map && memcmp(options, map->name, map->namelen)) - map = map->next; - - if (!map) { - KGDB_PRINTK("unknown port spec in %s\n", options); - return -1; - } - - kgdb_porttype = map; - kgdb_serial_setup = map->setup_fn; - kgdb_portnum = options[map->namelen] - '0'; - options += map->namelen + 1; - - options = (*options == ',') ? options+1 : options; - - /* Read optional parameters (baud/parity/bits) */ - baud = simple_strtoul(options, &options, 10); - if (baud != 0) { - kgdb_baud = baud; - - c = toupper(*options); - if (c == 'E' || c == 'O' || c == 'N') { - kgdb_parity = c; - options++; - } - - c = *options; - if (c == '7' || c == '8') { - kgdb_bits = c; - options++; - } - options = (*options == ',') ? options+1 : options; - } - } - - /* Check for action specification */ - if (!memcmp(options, "halt", 4)) { - kgdb_halt = 1; - options += 4; - } else if (!memcmp(options, "disabled", 8)) { - kgdb_enabled = 0; - options += 8; - } - - if (*options) { - KGDB_PRINTK("ignored unknown options: %s\n", options); - return 0; - } - return 1; -} -__setup("kgdb=", kgdb_parse_options); -#endif /* CONFIG_SH_KGDB */ diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 46c40bbc4bc6..4b17f845f5cd 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -46,6 +46,7 @@ #endif #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) +#include #include #include #include @@ -163,7 +164,7 @@ static void put_string(struct sci_port *sci_port, const char *buffer, int count) usegdb |= sh_bios_in_gdb_mode(); #endif #ifdef CONFIG_SH_KGDB - usegdb |= (kgdb_in_gdb_mode && (port == kgdb_sci_port)); + usegdb |= (kgdb_in_gdb_mode && (sci_port == kgdb_sci_port)); #endif if (usegdb) { @@ -204,7 +205,7 @@ static int kgdb_sci_getchar(void) int c; /* Keep trying to read a character, this could be neater */ - while ((c = get_char(kgdb_sci_port)) < 0) + while ((c = get_char(&kgdb_sci_port->port)) < 0) cpu_relax(); return c; @@ -212,7 +213,7 @@ static int kgdb_sci_getchar(void) static inline void kgdb_sci_putchar(int c) { - put_char(kgdb_sci_port, c); + put_char(&kgdb_sci_port->port, c); } #endif /* CONFIG_SH_KGDB */ @@ -738,7 +739,7 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr) #ifdef CONFIG_SH_KGDB /* Break into the debugger if a break is detected */ - BREAKPOINT(); + breakpoint(); #endif sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port)); @@ -971,7 +972,6 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, { struct sci_port *s = &sci_ports[port->line]; unsigned int status, baud, smr_val; - unsigned long flags; int t; baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); @@ -989,12 +989,10 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, #else t = SCBRR_VALUE(baud); #endif - } break; + } } - spin_lock_irqsave(&port->lock, flags); - do { status = sci_in(port, SCxSR); } while (!(status & SCxSR_TEND(port))); @@ -1038,8 +1036,6 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, if ((termios->c_cflag & CREAD) != 0) sci_start_rx(port,0); - - spin_unlock_irqrestore(&port->lock, flags); } static const char *sci_type(struct uart_port *port) @@ -1220,8 +1216,6 @@ static int __init serial_console_setup(struct console *co, char *options) if (!port->membase || !port->mapbase) return -ENODEV; - spin_lock_init(&port->lock); - port->type = serial_console_port->type; if (port->flags & UPF_IOREMAP) @@ -1247,7 +1241,7 @@ static struct console serial_console = { .device = uart_console_device, .write = serial_console_write, .setup = serial_console_setup, - .flags = CON_PRINTBUFFER, + .flags = CON_PRINTBUFFER, .index = -1, .data = &sci_uart_driver, }; @@ -1292,11 +1286,23 @@ int __init kgdb_console_setup(struct console *co, char *options) int parity = 'n'; int flow = 'n'; - spin_lock_init(&port->lock); - if (co->index != kgdb_portnum) co->index = kgdb_portnum; + kgdb_sci_port = &sci_ports[co->index]; + port = &kgdb_sci_port->port; + + /* + * Also need to check port->type, we don't actually have any + * UPIO_PORT ports, but uart_report_port() handily misreports + * it anyways if we don't have a port available by the time this is + * called. + */ + if (!port->type) + return -ENODEV; + if (!port->membase || !port->mapbase) + return -ENODEV; + if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); else @@ -1311,11 +1317,12 @@ int __init kgdb_console_setup(struct console *co, char *options) #ifdef CONFIG_SH_KGDB_CONSOLE static struct console kgdb_console = { - .name = "ttySC", - .write = kgdb_console_write, - .setup = kgdb_console_setup, - .flags = CON_PRINTBUFFER | CON_ENABLED, - .index = -1, + .name = "ttySC", + .device = uart_console_device, + .write = kgdb_console_write, + .setup = kgdb_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, .data = &sci_uart_driver, }; @@ -1386,6 +1393,12 @@ static int __devinit sci_probe(struct platform_device *dev) uart_add_one_port(&sci_uart_driver, &sciport->port); } +#if defined(CONFIG_SH_KGDB) && !defined(CONFIG_SH_KGDB_CONSOLE) + kgdb_sci_port = &sci_ports[kgdb_portnum]; + kgdb_getchar = kgdb_sci_getchar; + kgdb_putchar = kgdb_sci_putchar; +#endif + #ifdef CONFIG_CPU_FREQ cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); dev_info(&dev->dev, "sci: CPU frequency notifier registered\n"); diff --git a/include/asm-sh/kgdb.h b/include/asm-sh/kgdb.h index 0095c665d272..74bd0953e5ce 100644 --- a/include/asm-sh/kgdb.h +++ b/include/asm-sh/kgdb.h @@ -17,6 +17,7 @@ #define __KGDB_H #include +#include struct console; @@ -45,35 +46,21 @@ extern int kgdb_portnum; extern int kgdb_baud; extern char kgdb_parity; extern char kgdb_bits; -extern int kgdb_console_setup(struct console *, char *); /* Init and interface stuff */ extern int kgdb_init(void); -extern int (*kgdb_serial_setup)(void); extern int (*kgdb_getchar)(void); extern void (*kgdb_putchar)(int); -struct kgdb_sermap { - char *name; - int namelen; - int (*setup_fn)(struct console *, char *); - struct kgdb_sermap *next; -}; -extern void kgdb_register_sermap(struct kgdb_sermap *map); -extern struct kgdb_sermap *kgdb_porttype; - /* Trap functions */ -typedef void (kgdb_debug_hook_t)(struct pt_regs *regs); +typedef void (kgdb_debug_hook_t)(struct pt_regs *regs); typedef void (kgdb_bus_error_hook_t)(void); extern kgdb_debug_hook_t *kgdb_debug_hook; extern kgdb_bus_error_hook_t *kgdb_bus_err_hook; -extern void breakpoint(void); - /* Console */ -struct console; void kgdb_console_write(struct console *co, const char *s, unsigned count); -void kgdb_console_init(void); +extern int kgdb_console_setup(struct console *, char *); /* Prototypes for jmp fns */ #define _JBLEN 9 @@ -81,11 +68,8 @@ typedef int jmp_buf[_JBLEN]; extern void longjmp(jmp_buf __jmpb, int __retval); extern int setjmp(jmp_buf __jmpb); -/* Variadic macro to print our own message to the console */ -#define KGDB_PRINTK(...) printk("KGDB: " __VA_ARGS__) - /* Forced breakpoint */ -#define BREAKPOINT() \ +#define breakpoint() \ do { \ if (kgdb_enabled) \ __asm__ __volatile__("trapa #0x3c"); \ @@ -95,7 +79,6 @@ do { \ #if defined(CONFIG_CPU_SH4) #define kgdb_flush_icache_range(start, end) \ { \ - extern void __flush_purge_region(void *, int); \ __flush_purge_region((void*)(start), (int)(end) - (int)(start));\ flush_icache_range((start), (end)); \ } @@ -103,31 +86,6 @@ do { \ #define kgdb_flush_icache_range(start, end) do { } while (0) #endif -/* Kernel assert macros */ -#ifdef CONFIG_KGDB_KERNEL_ASSERTS - -/* Predefined conditions */ -#define KA_VALID_ERRNO(errno) ((errno) > 0 && (errno) <= EMEDIUMTYPE) -#define KA_VALID_PTR_ERR(ptr) KA_VALID_ERRNO(-PTR_ERR(ptr)) -#define KA_VALID_KPTR(ptr) (!(ptr) || \ - ((void *)(ptr) >= (void *)PAGE_OFFSET && \ - (void *)(ptr) < ERR_PTR(-EMEDIUMTYPE))) -#define KA_VALID_PTRORERR(errptr) \ - (KA_VALID_KPTR(errptr) || KA_VALID_PTR_ERR(errptr)) -#define KA_HELD_GKL() (current->lock_depth >= 0) - -/* The actual assert */ -#define KGDB_ASSERT(condition, message) do { \ - if (!(condition) && (kgdb_enabled)) { \ - KGDB_PRINTK("Assertion failed at %s:%d: %s\n", \ - __FILE__, __LINE__, message);\ - BREAKPOINT(); \ - } \ -} while (0) -#else -#define KGDB_ASSERT(condition, message) -#endif - /* Taken from sh-stub.c of GDB 4.18 */ static const char hexchars[] = "0123456789abcdef"; @@ -142,5 +100,4 @@ static inline char lowhex(const int x) { return hexchars[x & 0xf]; } - #endif diff --git a/include/asm-sh/se7751.h b/include/asm-sh/se7751.h index 88cd379d9084..02ca9347f043 100644 --- a/include/asm-sh/se7751.h +++ b/include/asm-sh/se7751.h @@ -65,6 +65,8 @@ #define IRQ_79C973 13 +void init_7751se_IRQ(void); + #define __IO_PREFIX sh7751se #include -- cgit v1.2.3-59-g8ed1b From fc31b80957a14a60513d953cc67a55519a2b09c7 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 8 Mar 2007 17:33:24 +0900 Subject: sh: Rip out broken kgdb thread support. The kgdb thread support is woefully out of date (it predates the pidhash), and needs a complete rewrite before it's useful again. Just rip it out entirely. Updating the unified kgdb stub is a more worthwhile endeavour for anyone that happens to be interested in this, at present it's just limping along. Signed-off-by: Paul Mundt --- arch/sh/Kconfig.debug | 4 - arch/sh/kernel/kgdb_stub.c | 386 +-------------------------------------------- 2 files changed, 4 insertions(+), 386 deletions(-) (limited to 'arch') diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 6be2385c1ad2..931c620dbc24 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -104,10 +104,6 @@ config KGDB_NMI bool "Enter KGDB on NMI" default n -config KGDB_THREAD - bool "Include KGDB thread support" - default y - config SH_KGDB_CONSOLE bool "Console messages through GDB" depends on !SERIAL_SH_SCI_CONSOLE diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c index 737eadc8ce0f..a5323364cbca 100644 --- a/arch/sh/kernel/kgdb_stub.c +++ b/arch/sh/kernel/kgdb_stub.c @@ -243,14 +243,6 @@ static char out_buffer[OUTBUFMAX]; static void kgdb_to_gdb(const char *s); -#ifdef CONFIG_KGDB_THREAD -static struct task_struct *trapped_thread; -static struct task_struct *current_thread; -typedef unsigned char threadref[8]; -#define BUF_THREAD_ID_SIZE 16 -#endif - - /* Convert ch to hex */ static int hex(const char ch) { @@ -346,66 +338,6 @@ static char *pack_hex_byte(char *pkt, int byte) return pkt; } -#ifdef CONFIG_KGDB_THREAD - -/* Pack a thread ID */ -static char *pack_threadid(char *pkt, threadref * id) -{ - char *limit; - unsigned char *altid; - - altid = (unsigned char *) id; - - limit = pkt + BUF_THREAD_ID_SIZE; - while (pkt < limit) - pkt = pack_hex_byte(pkt, *altid++); - return pkt; -} - -/* Convert an integer into our threadref */ -static void int_to_threadref(threadref * id, const int value) -{ - unsigned char *scan = (unsigned char *) id; - int i = 4; - - while (i--) - *scan++ = 0; - - *scan++ = (value >> 24) & 0xff; - *scan++ = (value >> 16) & 0xff; - *scan++ = (value >> 8) & 0xff; - *scan++ = (value & 0xff); -} - -/* Return a task structure ptr for a particular pid */ -static struct task_struct *get_thread(int pid) -{ - struct task_struct *thread; - - /* Use PID_MAX w/gdb for pid 0 */ - if (pid == PID_MAX) pid = 0; - - /* First check via PID */ - thread = find_task_by_pid(pid); - - if (thread) - return thread; - - /* Start at the start */ - thread = init_tasks[0]; - - /* Walk along the linked list of tasks */ - do { - if (thread->pid == pid) - return thread; - thread = thread->next_task; - } while (thread != init_tasks[0]); - - return NULL; -} - -#endif /* CONFIG_KGDB_THREAD */ - /* Scan for the start char '$', read the packet and check the checksum */ static void get_packet(char *buffer, int buflen) { @@ -608,74 +540,6 @@ static void gdb_regs_to_kgdb_regs(const int *gdb_regs, regs->vbr = gdb_regs[VBR]; } -#ifdef CONFIG_KGDB_THREAD -/* Make a local copy of registers from the specified thread */ -asmlinkage void ret_from_fork(void); -static void thread_regs_to_gdb_regs(const struct task_struct *thread, - int *gdb_regs) -{ - int regno; - int *tregs; - - /* Initialize to zero */ - for (regno = 0; regno < MAXREG; regno++) - gdb_regs[regno] = 0; - - /* Just making sure... */ - if (thread == NULL) - return; - - /* A new fork has pt_regs on the stack from a fork() call */ - if (thread->thread.pc == (unsigned long)ret_from_fork) { - - int vbr_val; - struct pt_regs *kregs; - kregs = (struct pt_regs*)thread->thread.sp; - - gdb_regs[R0] = kregs->regs[R0]; - gdb_regs[R1] = kregs->regs[R1]; - gdb_regs[R2] = kregs->regs[R2]; - gdb_regs[R3] = kregs->regs[R3]; - gdb_regs[R4] = kregs->regs[R4]; - gdb_regs[R5] = kregs->regs[R5]; - gdb_regs[R6] = kregs->regs[R6]; - gdb_regs[R7] = kregs->regs[R7]; - gdb_regs[R8] = kregs->regs[R8]; - gdb_regs[R9] = kregs->regs[R9]; - gdb_regs[R10] = kregs->regs[R10]; - gdb_regs[R11] = kregs->regs[R11]; - gdb_regs[R12] = kregs->regs[R12]; - gdb_regs[R13] = kregs->regs[R13]; - gdb_regs[R14] = kregs->regs[R14]; - gdb_regs[R15] = kregs->regs[R15]; - gdb_regs[PC] = kregs->pc; - gdb_regs[PR] = kregs->pr; - gdb_regs[GBR] = kregs->gbr; - gdb_regs[MACH] = kregs->mach; - gdb_regs[MACL] = kregs->macl; - gdb_regs[SR] = kregs->sr; - - asm("stc vbr, %0":"=r"(vbr_val)); - gdb_regs[VBR] = vbr_val; - return; - } - - /* Otherwise, we have only some registers from switch_to() */ - tregs = (int *)thread->thread.sp; - gdb_regs[R15] = (int)tregs; - gdb_regs[R14] = *tregs++; - gdb_regs[R13] = *tregs++; - gdb_regs[R12] = *tregs++; - gdb_regs[R11] = *tregs++; - gdb_regs[R10] = *tregs++; - gdb_regs[R9] = *tregs++; - gdb_regs[R8] = *tregs++; - gdb_regs[PR] = *tregs++; - gdb_regs[GBR] = *tregs++; - gdb_regs[PC] = thread->thread.pc; -} -#endif /* CONFIG_KGDB_THREAD */ - /* Calculate the new address for after a step */ static short *get_step_address(void) { @@ -794,37 +658,11 @@ static void undo_single_step(void) /* Send a signal message */ static void send_signal_msg(const int signum) { -#ifndef CONFIG_KGDB_THREAD out_buffer[0] = 'S'; out_buffer[1] = highhex(signum); out_buffer[2] = lowhex(signum); out_buffer[3] = 0; put_packet(out_buffer); -#else /* CONFIG_KGDB_THREAD */ - int threadid; - threadref thref; - char *out = out_buffer; - const char *tstring = "thread"; - - *out++ = 'T'; - *out++ = highhex(signum); - *out++ = lowhex(signum); - - while (*tstring) { - *out++ = *tstring++; - } - *out++ = ':'; - - threadid = trapped_thread->pid; - if (threadid == 0) threadid = PID_MAX; - int_to_threadref(&thref, threadid); - pack_threadid(out, &thref); - out += BUF_THREAD_ID_SIZE; - *out++ = ';'; - - *out = 0; - put_packet(out_buffer); -#endif /* CONFIG_KGDB_THREAD */ } /* Reply that all was well */ @@ -959,15 +797,7 @@ static void step_with_sig_msg(void) /* Send register contents */ static void send_regs_msg(void) { -#ifdef CONFIG_KGDB_THREAD - if (!current_thread) - kgdb_regs_to_gdb_regs(&trap_registers, registers); - else - thread_regs_to_gdb_regs(current_thread, registers); -#else kgdb_regs_to_gdb_regs(&trap_registers, registers); -#endif - mem_to_hex((char *) registers, out_buffer, NUMREGBYTES); put_packet(out_buffer); } @@ -975,198 +805,11 @@ static void send_regs_msg(void) /* Set register contents - currently can't set other thread's registers */ static void set_regs_msg(void) { -#ifdef CONFIG_KGDB_THREAD - if (!current_thread) { -#endif - kgdb_regs_to_gdb_regs(&trap_registers, registers); - hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES); - gdb_regs_to_kgdb_regs(registers, &trap_registers); - send_ok_msg(); -#ifdef CONFIG_KGDB_THREAD - } else - send_err_msg(); -#endif -} - - -#ifdef CONFIG_KGDB_THREAD - -/* Set the status for a thread */ -void set_thread_msg(void) -{ - int threadid; - struct task_struct *thread = NULL; - char *ptr; - - switch (in_buffer[1]) { - /* To select which thread for gG etc messages, i.e. supported */ - case 'g': - ptr = &in_buffer[2]; - hex_to_int(&ptr, &threadid); - thread = get_thread(threadid); - - /* If we haven't found it */ - if (!thread) { - send_err_msg(); - break; - } - - /* Set current_thread (or not) */ - if (thread == trapped_thread) - current_thread = NULL; - else - current_thread = thread; - send_ok_msg(); - break; - - /* To select which thread for cCsS messages, i.e. unsupported */ - case 'c': - send_ok_msg(); - break; - - default: - send_empty_msg(); - break; - } -} - -/* Is a thread alive? */ -static void thread_status_msg(void) -{ - char *ptr; - int threadid; - struct task_struct *thread = NULL; - - ptr = &in_buffer[1]; - hex_to_int(&ptr, &threadid); - thread = get_thread(threadid); - if (thread) - send_ok_msg(); - else - send_err_msg(); -} -/* Send the current thread ID */ -static void thread_id_msg(void) -{ - int threadid; - threadref thref; - - out_buffer[0] = 'Q'; - out_buffer[1] = 'C'; - - if (current_thread) - threadid = current_thread->pid; - else if (trapped_thread) - threadid = trapped_thread->pid; - else /* Impossible, but just in case! */ - { - send_err_msg(); - return; - } - - /* Translate pid 0 to PID_MAX for gdb */ - if (threadid == 0) threadid = PID_MAX; - - int_to_threadref(&thref, threadid); - pack_threadid(out_buffer + 2, &thref); - out_buffer[2 + BUF_THREAD_ID_SIZE] = '\0'; - put_packet(out_buffer); -} - -/* Send thread info */ -static void thread_info_msg(void) -{ - struct task_struct *thread = NULL; - int threadid; - char *pos; - threadref thref; - - /* Start with 'm' */ - out_buffer[0] = 'm'; - pos = &out_buffer[1]; - - /* For all possible thread IDs - this will overrun if > 44 threads! */ - /* Start at 1 and include PID_MAX (since GDB won't use pid 0...) */ - for (threadid = 1; threadid <= PID_MAX; threadid++) { - - read_lock(&tasklist_lock); - thread = get_thread(threadid); - read_unlock(&tasklist_lock); - - /* If it's a valid thread */ - if (thread) { - int_to_threadref(&thref, threadid); - pack_threadid(pos, &thref); - pos += BUF_THREAD_ID_SIZE; - *pos++ = ','; - } - } - *--pos = 0; /* Lose final comma */ - put_packet(out_buffer); - -} - -/* Return printable info for gdb's 'info threads' command */ -static void thread_extra_info_msg(void) -{ - int threadid; - struct task_struct *thread = NULL; - char buffer[20], *ptr; - int i; - - /* Extract thread ID */ - ptr = &in_buffer[17]; - hex_to_int(&ptr, &threadid); - thread = get_thread(threadid); - - /* If we don't recognise it, say so */ - if (thread == NULL) - strcpy(buffer, "(unknown)"); - else - strcpy(buffer, thread->comm); - - /* Construct packet */ - for (i = 0, ptr = out_buffer; buffer[i]; i++) - ptr = pack_hex_byte(ptr, buffer[i]); - - if (thread->thread.pc == (unsigned long)ret_from_fork) { - strcpy(buffer, ""); - for (i = 0; buffer[i]; i++) - ptr = pack_hex_byte(ptr, buffer[i]); - } - - *ptr = '\0'; - put_packet(out_buffer); -} - -/* Handle all qFooBarBaz messages - have to use an if statement as - opposed to a switch because q messages can have > 1 char id. */ -static void query_msg(void) -{ - const char *q_start = &in_buffer[1]; - - /* qC = return current thread ID */ - if (strncmp(q_start, "C", 1) == 0) - thread_id_msg(); - - /* qfThreadInfo = query all threads (first) */ - else if (strncmp(q_start, "fThreadInfo", 11) == 0) - thread_info_msg(); - - /* qsThreadInfo = query all threads (subsequent). We know we have sent - them all after the qfThreadInfo message, so there are no to send */ - else if (strncmp(q_start, "sThreadInfo", 11) == 0) - put_packet("l"); /* el = last */ - - /* qThreadExtraInfo = supply printable information per thread */ - else if (strncmp(q_start, "ThreadExtraInfo", 15) == 0) - thread_extra_info_msg(); - - /* Unsupported - empty message as per spec */ - else - send_empty_msg(); + kgdb_regs_to_gdb_regs(&trap_registers, registers); + hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES); + gdb_regs_to_kgdb_regs(registers, &trap_registers); + send_ok_msg(); } -#endif /* CONFIG_KGDB_THREAD */ #ifdef CONFIG_SH_KGDB_CONSOLE /* @@ -1206,12 +849,6 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value) if (!kgdb_enabled) return; -#ifdef CONFIG_KGDB_THREAD - /* Until GDB specifies a thread */ - current_thread = NULL; - trapped_thread = current; -#endif - /* Enter GDB mode (e.g. after detach) */ if (!kgdb_in_gdb_mode) { /* Do serial setup, notify user, issue preemptive ack */ @@ -1284,21 +921,6 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value) step_msg(); return; -#ifdef CONFIG_KGDB_THREAD - - case 'H': /* Task related */ - set_thread_msg(); - break; - - case 'T': /* Query thread status */ - thread_status_msg(); - break; - - case 'q': /* Handle query - currently thread-related */ - query_msg(); - break; -#endif - case 'k': /* 'Kill the program' with a kernel ? */ break; -- cgit v1.2.3-59-g8ed1b From 45ed285b54930767937deb0eaf718b1d08c3c475 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 8 Mar 2007 18:12:17 +0900 Subject: sh: speculative execution support for SH7780. SH7780 has a speculative execution mode where it can speculatively perform an instruction fetch for subroutine returns, this allows it to be enabled. There are some various pitfalls associated with this mode, so it's left as depending on CONFIG_EXPERIMENTAL and not enabled by default. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 10 ++++++++++ arch/sh/kernel/cpu/init.c | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 4d16d8917074..2715834f72be 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -366,6 +366,16 @@ config SH_STORE_QUEUES Selecting this option will enable an in-kernel API for manipulating the store queues integrated in the SH-4 processors. +config SPECULATIVE_EXECUTION + bool "Speculative subroutine return" + depends on CPU_SUBTYPE_SH7780 && EXPERIMENTAL + help + This enables support for a speculative instruction fetch for + subroutine return. There are various pitfalls associated with + this, as outlined in the SH7780 hardware manual. + + If unsure, say N. + config CPU_HAS_INTEVT bool diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index 726acfcb9b77..6451ad630174 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -41,6 +41,23 @@ __setup("no" __stringify(x), x##_setup); onchip_setup(fpu); onchip_setup(dsp); +#ifdef CONFIG_SPECULATIVE_EXECUTION +#define CPUOPM 0xff2f0000 +#define CPUOPM_RABD (1 << 5) + +static void __init speculative_execution_init(void) +{ + /* Clear RABD */ + ctrl_outl(ctrl_inl(CPUOPM) & ~CPUOPM_RABD, CPUOPM); + + /* Flush the update */ + (void)ctrl_inl(CPUOPM); + ctrl_barrier(); +} +#else +#define speculative_execution_init() do { } while (0) +#endif + /* * Generic first-level cache init */ @@ -261,4 +278,6 @@ asmlinkage void __init sh_cpu_init(void) */ ubc_wakeup(); #endif + + speculative_execution_init(); } -- cgit v1.2.3-59-g8ed1b From fa69151173b1fc6fa3ced0edd5c2ea83b5d32bc1 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 8 Mar 2007 19:41:21 +0900 Subject: sh: generic BUG() support. Wire up GENERIC_BUG for SH. This moves off of the special bug frame and on to the generic struct bug_entry. Roughly the same semantics are retained, and we can kill off some of the verbose BUG() reporting code. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 4 ++ arch/sh/kernel/traps.c | 54 ++++++++++---------------- arch/sh/kernel/vmlinux.lds.S | 47 +++++----------------- include/asm-sh/bug.h | 92 +++++++++++++++++++++++++++++--------------- 4 files changed, 95 insertions(+), 102 deletions(-) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 2715834f72be..51d9d0ab39c6 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -22,6 +22,10 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool +config GENERIC_BUG + def_bool y + depends on BUG + config GENERIC_FIND_NEXT_BIT bool default y diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index e9f168f60f95..77107838271f 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -130,40 +131,6 @@ static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err) return -EFAULT; } -#ifdef CONFIG_BUG -#ifdef CONFIG_DEBUG_BUGVERBOSE -static inline void do_bug_verbose(struct pt_regs *regs) -{ - struct bug_frame f; - long len; - - if (__copy_from_user(&f, (const void __user *)regs->pc, - sizeof(struct bug_frame))) - return; - - len = __strnlen_user(f.file, PATH_MAX) - 1; - if (unlikely(len < 0 || len >= PATH_MAX)) - f.file = ""; - len = __strnlen_user(f.func, PATH_MAX) - 1; - if (unlikely(len < 0 || len >= PATH_MAX)) - f.func = ""; - - printk(KERN_ALERT "kernel BUG in %s() at %s:%d!\n", - f.func, f.file, f.line); -} -#else -static inline void do_bug_verbose(struct pt_regs *regs) -{ -} -#endif /* CONFIG_DEBUG_BUGVERBOSE */ - -void handle_BUG(struct pt_regs *regs) -{ - do_bug_verbose(regs); - die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff); -} -#endif /* CONFIG_BUG */ - /* * handle an instruction that does an unaligned memory access by emulating the * desired behaviour @@ -888,6 +855,25 @@ void __init trap_init(void) per_cpu_trap_init(); } +#ifdef CONFIG_BUG +void handle_BUG(struct pt_regs *regs) +{ + enum bug_trap_type tt; + tt = report_bug(regs->pc); + if (tt == BUG_TRAP_TYPE_WARN) { + regs->pc += 2; + return; + } + + die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff); +} + +int is_valid_bugaddr(unsigned long addr) +{ + return addr >= PAGE_OFFSET; +} +#endif + void show_trace(struct task_struct *tsk, unsigned long *sp, struct pt_regs *regs) { diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 2f606d0ce1f6..d83143cc5ca9 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -34,9 +34,11 @@ SECTIONS __ex_table : { *(__ex_table) } __stop___ex_table = .; + _etext = .; /* End of text section */ + RODATA - _etext = .; /* End of text section */ + BUG_TABLE .data : { /* Data */ *(.data) @@ -53,6 +55,10 @@ SECTIONS . = ALIGN(PAGE_SIZE); .data.page_aligned : { *(.data.page_aligned) } + __nosave_begin = .; + .data_nosave : { *(.data.nosave) } + . = ALIGN(PAGE_SIZE); + __nosave_end = .; . = ALIGN(PAGE_SIZE); __per_cpu_start = .; @@ -110,43 +116,10 @@ SECTIONS * it's a module. */ /DISCARD/ : { - *(.exit.text) - *(.exit.data) *(.exitcall.exit) } - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging section are relative to the beginning - of the section so we begin .debug at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* These must appear regardless of . */ + STABS_DEBUG + + DWARF_DEBUG } diff --git a/include/asm-sh/bug.h b/include/asm-sh/bug.h index 2f89dd06d0cd..794c36daf06d 100644 --- a/include/asm-sh/bug.h +++ b/include/asm-sh/bug.h @@ -2,50 +2,80 @@ #define __ASM_SH_BUG_H #ifdef CONFIG_BUG - -struct bug_frame { - unsigned short opcode; - unsigned short line; - const char *file; - const char *func; -}; - -struct pt_regs; - -extern void handle_BUG(struct pt_regs *); +#define HAVE_ARCH_BUG +#define HAVE_ARCH_WARN_ON #define TRAPA_BUG_OPCODE 0xc33e /* trapa #0x3e */ +/** + * _EMIT_BUG_ENTRY + * %1 - __FILE__ + * %2 - __LINE__ + * %3 - trap type + * %4 - sizeof(struct bug_entry) + * + * The trapa opcode itself sits in %0. + * The %O notation is used to avoid # generation. + * + * The offending file and line are encoded in the __bug_table section. + */ #ifdef CONFIG_DEBUG_BUGVERBOSE +#define _EMIT_BUG_ENTRY \ + "\t.pushsection __bug_table,\"a\"\n" \ + "2:\t.long 1b, %O1\n" \ + "\t.short %O2, %O3\n" \ + "\t.org 2b+%O4\n" \ + "\t.popsection\n" +#else +#define _EMIT_BUG_ENTRY \ + "\t.pushsection __bug_table,\"a\"\n" \ + "2:\t.long 1b\n" \ + "\t.short %O3\n" \ + "\t.org 2b+%O4\n" \ + "\t.popsection\n" +#endif #define BUG() \ do { \ __asm__ __volatile__ ( \ - ".align 2\n\t" \ - ".short %O0\n\t" \ - ".short %O1\n\t" \ - ".long %O2\n\t" \ - ".long %O3\n\t" \ - : \ - : "n" (TRAPA_BUG_OPCODE), \ - "i" (__LINE__), "X" (__FILE__), \ - "X" (__FUNCTION__)); \ + "1:\t.short %O0\n" \ + _EMIT_BUG_ENTRY \ + : \ + : "n" (TRAPA_BUG_OPCODE), \ + "i" (__FILE__), \ + "i" (__LINE__), "i" (0), \ + "i" (sizeof(struct bug_entry))); \ } while (0) -#else - -#define BUG() \ -do { \ - __asm__ __volatile__ ( \ - ".align 2\n\t" \ - ".short %O0\n\t" \ - : \ - : "n" (TRAPA_BUG_OPCODE)); \ +#define __WARN() \ +do { \ + __asm__ __volatile__ ( \ + "1:\t.short %O0\n" \ + _EMIT_BUG_ENTRY \ + : \ + : "n" (TRAPA_BUG_OPCODE), \ + "i" (__FILE__), \ + "i" (__LINE__), \ + "i" (BUGFLAG_WARNING), \ + "i" (sizeof(struct bug_entry))); \ } while (0) -#endif /* CONFIG_DEBUG_BUGVERBOSE */ +#define WARN_ON(x) ({ \ + typeof(x) __ret_warn_on = (x); \ + if (__builtin_constant_p(__ret_warn_on)) { \ + if (__ret_warn_on) \ + __WARN(); \ + } else { \ + if (unlikely(__ret_warn_on)) \ + __WARN(); \ + } \ + unlikely(__ret_warn_on); \ +}) -#define HAVE_ARCH_BUG +struct pt_regs; + +/* arch/sh/kernel/traps.c */ +void handle_BUG(struct pt_regs *); #endif /* CONFIG_BUG */ -- cgit v1.2.3-59-g8ed1b From be782df54c51b50dd4dbc363a5a5afa04565fc60 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 12 Mar 2007 14:09:35 +0900 Subject: sh: NR_IRQS consolidation. Each board sets the total number of IRQs that it's interested in via the machvec. Previously we cared about the off vs on-chip IRQ range, but any code relying on that is long dead. Set NR_IRQS to something sensible given the vector range, and allow boards to cap it if they really care. Signed-off-by: Paul Mundt --- arch/sh/kernel/irq.c | 5 +-- include/asm-sh/irq.h | 91 +++------------------------------------------------- 2 files changed, 8 insertions(+), 88 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 9bdd8a00cd4a..27b923c45b3d 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -44,7 +45,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); } - if (i < NR_IRQS) { + if (i < sh_mv.mv_nr_irqs) { spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) @@ -61,7 +62,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); unlock: spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == NR_IRQS) + } else if (i == sh_mv.mv_nr_irqs) seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count)); return 0; diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h index afe188f0ad5f..e81bf21c801e 100644 --- a/include/asm-sh/irq.h +++ b/include/asm-sh/irq.h @@ -2,94 +2,13 @@ #define __ASM_SH_IRQ_H #include -#include /* for pt_regs */ -/* NR_IRQS is made from three components: - * 1. ONCHIP_NR_IRQS - number of IRLS + on-chip peripherial modules - * 2. PINT_NR_IRQS - number of PINT interrupts - * 3. OFFCHIP_NR_IRQS - numbe of IRQs from off-chip peripherial modules +/* + * A sane default based on a reasonable vector table size, platforms are + * advised to cap this at the hard limit that they're interested in + * through the machvec. */ - -/* 1. ONCHIP_NR_IRQS */ -#if defined(CONFIG_CPU_SUBTYPE_SH7604) -# define ONCHIP_NR_IRQS 24 // Actually 21 -#elif defined(CONFIG_CPU_SUBTYPE_SH7707) -# define ONCHIP_NR_IRQS 64 -# define PINT_NR_IRQS 16 -#elif defined(CONFIG_CPU_SUBTYPE_SH7708) -# define ONCHIP_NR_IRQS 32 -#elif defined(CONFIG_CPU_SUBTYPE_SH7709) || \ - defined(CONFIG_CPU_SUBTYPE_SH7706) || \ - defined(CONFIG_CPU_SUBTYPE_SH7705) -# define ONCHIP_NR_IRQS 64 // Actually 61 -# define PINT_NR_IRQS 16 -#elif defined(CONFIG_CPU_SUBTYPE_SH7710) -# define ONCHIP_NR_IRQS 104 -#elif defined(CONFIG_CPU_SUBTYPE_SH7750) -# define ONCHIP_NR_IRQS 48 // Actually 44 -#elif defined(CONFIG_CPU_SUBTYPE_SH7751) -# define ONCHIP_NR_IRQS 72 -#elif defined(CONFIG_CPU_SUBTYPE_SH7760) -# define ONCHIP_NR_IRQS 112 /* XXX */ -#elif defined(CONFIG_CPU_SUBTYPE_SH4_202) -# define ONCHIP_NR_IRQS 72 -#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1) -# define ONCHIP_NR_IRQS 144 -#elif defined(CONFIG_CPU_SUBTYPE_SH7300) || \ - defined(CONFIG_CPU_SUBTYPE_SH73180) || \ - defined(CONFIG_CPU_SUBTYPE_SH7343) || \ - defined(CONFIG_CPU_SUBTYPE_SH7722) -# define ONCHIP_NR_IRQS 109 -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) -# define ONCHIP_NR_IRQS 111 -#elif defined(CONFIG_CPU_SUBTYPE_SH7206) -# define ONCHIP_NR_IRQS 256 -#elif defined(CONFIG_CPU_SUBTYPE_SH7619) -# define ONCHIP_NR_IRQS 128 -#elif defined(CONFIG_SH_UNKNOWN) /* Most be last */ -# define ONCHIP_NR_IRQS 144 -#endif - -/* 2. PINT_NR_IRQS */ -#ifdef CONFIG_SH_UNKNOWN -# define PINT_NR_IRQS 16 -#else -# ifndef PINT_NR_IRQS -# define PINT_NR_IRQS 0 -# endif -#endif - -#if PINT_NR_IRQS > 0 -# define PINT_IRQ_BASE ONCHIP_NR_IRQS -#endif - -/* 3. OFFCHIP_NR_IRQS */ -#if defined(CONFIG_HD64461) -# define OFFCHIP_NR_IRQS 18 -#elif defined(CONFIG_HD64465) -# define OFFCHIP_NR_IRQS 16 -#elif defined (CONFIG_SH_DREAMCAST) -# define OFFCHIP_NR_IRQS 96 -#elif defined (CONFIG_SH_TITAN) -# define OFFCHIP_NR_IRQS 4 -#elif defined(CONFIG_SH_R7780RP) -# define OFFCHIP_NR_IRQS 16 -#elif defined(CONFIG_SH_7343_SOLUTION_ENGINE) -# define OFFCHIP_NR_IRQS 12 -#elif defined(CONFIG_SH_7722_SOLUTION_ENGINE) -# define OFFCHIP_NR_IRQS 14 -#elif defined(CONFIG_SH_UNKNOWN) -# define OFFCHIP_NR_IRQS 16 /* Must also be last */ -#else -# define OFFCHIP_NR_IRQS 0 -#endif - -#if OFFCHIP_NR_IRQS > 0 -# define OFFCHIP_IRQ_BASE (ONCHIP_NR_IRQS + PINT_NR_IRQS) -#endif - -/* NR_IRQS. 1+2+3 */ -#define NR_IRQS (ONCHIP_NR_IRQS + PINT_NR_IRQS + OFFCHIP_NR_IRQS) +#define NR_IRQS 256 /* * Convert back and forth between INTEVT and IRQ values. -- cgit v1.2.3-59-g8ed1b From 32351a28a7e1f2c68afbe559dd35e1ad0301be6d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 12 Mar 2007 14:38:59 +0900 Subject: sh: Add SH7785 Highlander board support (R7785RP). This adds preliminary support for the SH7785-based Highlander board. Some of the Highlander support code is reordered so that most of it can be reused directly. This also plugs in missing SH7785 checks in the places that need it, as this is the first board to support the CPU. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 47 +- arch/sh/Makefile | 2 +- arch/sh/boards/renesas/r7780rp/Kconfig | 18 +- arch/sh/boards/renesas/r7780rp/Makefile | 6 +- arch/sh/boards/renesas/r7780rp/irq-r7780rp.c | 21 + arch/sh/boards/renesas/r7780rp/irq-r7785rp.c | 29 + arch/sh/boards/renesas/r7780rp/irq.c | 25 +- arch/sh/boards/renesas/r7780rp/setup.c | 74 +- arch/sh/configs/r7785rp_defconfig | 1334 ++++++++++++++++++++++++++ arch/sh/drivers/Kconfig | 10 + arch/sh/drivers/pci/Makefile | 3 +- arch/sh/drivers/pci/ops-r7780rp.c | 37 +- arch/sh/drivers/pci/pci-sh4.h | 2 +- arch/sh/drivers/pci/pci-sh7780.c | 17 +- arch/sh/drivers/pci/pci-sh7780.h | 3 +- arch/sh/kernel/cpu/irq/intc2.c | 3 +- arch/sh/kernel/cpu/sh4/probe.c | 8 + arch/sh/kernel/cpu/sh4a/Makefile | 2 + arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 162 ++++ arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 98 ++ arch/sh/kernel/timers/timer-tmu.c | 4 +- arch/sh/tools/mach-types | 1 + drivers/serial/sh-sci.c | 20 +- drivers/serial/sh-sci.h | 40 +- include/asm-sh/cpu-sh4/freq.h | 4 + include/asm-sh/pci.h | 2 +- include/asm-sh/r7780rp.h | 68 +- 27 files changed, 1896 insertions(+), 144 deletions(-) create mode 100644 arch/sh/boards/renesas/r7780rp/irq-r7780rp.c create mode 100644 arch/sh/boards/renesas/r7780rp/irq-r7785rp.c create mode 100644 arch/sh/configs/r7785rp_defconfig create mode 100644 arch/sh/kernel/cpu/sh4a/clock-sh7785.c create mode 100644 arch/sh/kernel/cpu/sh4a/setup-sh7785.c (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 51d9d0ab39c6..9932d1aa8494 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -197,12 +197,8 @@ config SH_RTS7751R2D Select RTS7751R2D if configuring for a Renesas Technology Sales SH-Graphics board. -config SH_R7780RP - bool "R7780RP-1" - select CPU_SUBTYPE_SH7780 - help - Select R7780RP-1 if configuring for a Renesas Solutions - HIGHLANDER board. +config SH_HIGHLANDER + bool "Highlander" config SH_EDOSK7705 bool "EDOSK7705" @@ -262,6 +258,10 @@ config SH_UNKNOWN endchoice +source "arch/sh/boards/renesas/hs7751rvoip/Kconfig" +source "arch/sh/boards/renesas/rts7751r2d/Kconfig" +source "arch/sh/boards/renesas/r7780rp/Kconfig" + source "arch/sh/mm/Kconfig" config CF_ENABLER @@ -412,8 +412,9 @@ config CPU_HAS_PTEA endmenu -menu "Timer support" -depends on !GENERIC_TIME +menu "Timer and clock configuration" + +if !GENERIC_TIME config SH_TMU bool "TMU timer support" @@ -436,17 +437,11 @@ config SH_MTU2 help This enables the use of the MTU2 as the system timer. -endmenu - -source "arch/sh/boards/renesas/hs7751rvoip/Kconfig" - -source "arch/sh/boards/renesas/rts7751r2d/Kconfig" - -source "arch/sh/boards/renesas/r7780rp/Kconfig" +endif config SH_TIMER_IRQ int - default "28" if CPU_SUBTYPE_SH7780 + default "28" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 default "86" if CPU_SUBTYPE_SH7619 default "140" if CPU_SUBTYPE_SH7206 default "16" @@ -476,7 +471,8 @@ config SH_PCLK_FREQ default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \ CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 || \ CPU_SUBTYPE_SH7206 - default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780 + default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780 || \ + CPU_SUBTYPE_SH7785 default "60000000" if CPU_SUBTYPE_SH7751 default "66000000" if CPU_SUBTYPE_SH4_202 help @@ -491,6 +487,8 @@ config SH_CLK_MD help MD2 - MD0 pin setting. +endmenu + menu "CPU Frequency scaling" source "drivers/cpufreq/Kconfig" @@ -509,21 +507,6 @@ config SH_CPU_FREQ endmenu -source "arch/sh/drivers/dma/Kconfig" - -source "arch/sh/cchips/Kconfig" - -config HEARTBEAT - bool "Heartbeat LED" - depends on SH_MPC1211 || SH_SH03 || \ - SOLUTION_ENGINE || \ - SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_LANDISK || \ - SH_R7780RP - help - Use the power-on LED on your machine as a load meter. The exact - behavior is platform-dependent, but normally the flash frequency is - a hyperbolic function of the 5-minute load average. - source "arch/sh/drivers/Kconfig" endmenu diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 0fadde283368..7eef74b1cb7b 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -102,7 +102,7 @@ machdir-$(CONFIG_SH_HS7751RVOIP) := renesas/hs7751rvoip machdir-$(CONFIG_SH_RTS7751R2D) := renesas/rts7751r2d machdir-$(CONFIG_SH_7751_SYSTEMH) := renesas/systemh machdir-$(CONFIG_SH_EDOSK7705) := renesas/edosk7705 -machdir-$(CONFIG_SH_R7780RP) := renesas/r7780rp +machdir-$(CONFIG_SH_HIGHLANDER) := renesas/r7780rp machdir-$(CONFIG_SH_7710VOIPGW) := renesas/sh7710voipgw machdir-$(CONFIG_SH_SH4202_MICRODEV) := superh/microdev machdir-$(CONFIG_SH_LANDISK) := landisk diff --git a/arch/sh/boards/renesas/r7780rp/Kconfig b/arch/sh/boards/renesas/r7780rp/Kconfig index c26d9813d239..9fb11641fe13 100644 --- a/arch/sh/boards/renesas/r7780rp/Kconfig +++ b/arch/sh/boards/renesas/r7780rp/Kconfig @@ -1,14 +1,24 @@ -if SH_R7780RP +if SH_HIGHLANDER -menu "R7780RP options" +choice + prompt "Highlander options" + default SH_R7780MP + +config SH_R7780RP + bool "R7780RP-1 board support" + select CPU_SUBTYPE_SH7780 config SH_R7780MP bool "R7780MP board support" - default y + select CPU_SUBTYPE_SH7780 help Selecting this option will enable support for the mass-production version of the R7780RP. If in doubt, say Y. -endmenu +config SH_R7785RP + bool "R7785RP board support" + select CPU_SUBTYPE_SH7785 + +endchoice endif diff --git a/arch/sh/boards/renesas/r7780rp/Makefile b/arch/sh/boards/renesas/r7780rp/Makefile index ed5f5a9a3b3e..609e5d50dde8 100644 --- a/arch/sh/boards/renesas/r7780rp/Makefile +++ b/arch/sh/boards/renesas/r7780rp/Makefile @@ -1,7 +1,7 @@ # # Makefile for the R7780RP-1 specific parts of the kernel # - -obj-y := setup.o irq.o - +irqinit-y := irq-r7780rp.o +irqinit-$(CONFIG_SH_R7785RP) := irq-r7785rp.o obj-$(CONFIG_PUSH_SWITCH) += psw.o +obj-y := setup.o irq.o $(irqinit-y) diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c b/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c new file mode 100644 index 000000000000..f5f358746c9e --- /dev/null +++ b/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c @@ -0,0 +1,21 @@ +/* + * Renesas Solutions Highlander R7780RP-1 Support. + * + * Copyright (C) 2002 Atom Create Engineering Co., Ltd. + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include + +void __init highlander_init_irq(void) +{ + int i; + + for (i = 0; i < 15; i++) + make_r7780rp_irq(i); +} diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c b/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c new file mode 100644 index 000000000000..dd6ec4ce44dc --- /dev/null +++ b/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c @@ -0,0 +1,29 @@ +/* + * Renesas Solutions Highlander R7780RP-1 Support. + * + * Copyright (C) 2002 Atom Create Engineering Co., Ltd. + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include + +void __init highlander_init_irq(void) +{ + ctrl_outw(0x0000, PA_IRLSSR1); /* FPGA IRLSSR1(CF_CD clear) */ + + /* Setup the FPGA IRL */ + ctrl_outw(0x0000, PA_IRLPRA); /* FPGA IRLA */ + ctrl_outw(0xe598, PA_IRLPRB); /* FPGA IRLB */ + ctrl_outw(0x7060, PA_IRLPRC); /* FPGA IRLC */ + ctrl_outw(0x0000, PA_IRLPRD); /* FPGA IRLD */ + ctrl_outw(0x4321, PA_IRLPRE); /* FPGA IRLE */ + ctrl_outw(0x0000, PA_IRLPRF); /* FPGA IRLF */ + + make_r7780rp_irq(1); /* CF card */ + make_r7780rp_irq(10); /* On-board ethernet */ +} diff --git a/arch/sh/boards/renesas/r7780rp/irq.c b/arch/sh/boards/renesas/r7780rp/irq.c index cc381e197783..e0b8eb52f376 100644 --- a/arch/sh/boards/renesas/r7780rp/irq.c +++ b/arch/sh/boards/renesas/r7780rp/irq.c @@ -14,10 +14,12 @@ #include #include -#ifdef CONFIG_SH_R7780MP -static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0}; -#else +#ifdef CONFIG_SH_R7780RP static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0}; +#elif defined(CONFIG_SH_R7780MP) +static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0}; +#elif defined(CONFIG_SH_R7785RP) +static int mask_pos[] = {2, 11, 2, 2, 2, 2, 9, 8, 7, 5, 10, 2, 2, 2, 2, 2}; #endif static void enable_r7780rp_irq(unsigned int irq) @@ -40,17 +42,10 @@ static struct irq_chip r7780rp_irq_chip __read_mostly = { .mask_ack = disable_r7780rp_irq, }; -/* - * Initialize IRQ setting - */ -void __init init_r7780rp_IRQ(void) +void make_r7780rp_irq(unsigned int irq) { - int i; - - for (i = 0; i < 15; i++) { - disable_irq_nosync(i); - set_irq_chip_and_handler_name(i, &r7780rp_irq_chip, - handle_level_irq, "level"); - enable_r7780rp_irq(i); - } + disable_irq_nosync(irq); + set_irq_chip_and_handler_name(irq, &r7780rp_irq_chip, + handle_level_irq, "level"); + enable_r7780rp_irq(irq); } diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c index 2faba6679e64..6af0cc35ceb7 100644 --- a/arch/sh/boards/renesas/r7780rp/setup.c +++ b/arch/sh/boards/renesas/r7780rp/setup.c @@ -1,10 +1,13 @@ /* * arch/sh/boards/renesas/r7780rp/setup.c * + * Renesas Solutions Highlander Support. + * * Copyright (C) 2002 Atom Create Engineering Co., Ltd. * Copyright (C) 2005 - 2007 Paul Mundt * - * Renesas Solutions Highlander R7780RP-1 Support. + * This contains support for the R7780RP-1, R7780MP, and R7785RP + * Highlander modules. * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -18,32 +21,6 @@ #include #include -extern void init_r7780rp_IRQ(void); - -static struct resource m66596_usb_host_resources[] = { - [0] = { - .start = 0xa4800000, - .end = 0xa4ffffff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 6, /* irq number */ - .end = 6, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device m66596_usb_host_device = { - .name = "m66596-hcd", - .id = 0, - .dev = { - .dma_mask = NULL, /* don't use dma */ - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(m66596_usb_host_resources), - .resource = m66596_usb_host_resources, -}; - static struct resource cf_ide_resources[] = { [0] = { .start = PA_AREA5_IO + 0x1000, @@ -56,10 +33,10 @@ static struct resource cf_ide_resources[] = { .flags = IORESOURCE_MEM, }, [2] = { -#ifdef CONFIG_SH_R7780MP - .start = 1, -#else +#ifdef CONFIG_SH_R7780RP .start = 4, +#else + .start = 1, #endif .flags = IORESOURCE_IRQ, }, @@ -92,15 +69,18 @@ static struct resource heartbeat_resources[] = { static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, + + /* R7785RP has a slightly more sensible FPGA.. */ +#ifndef CONFIG_SH_R7785RP .dev = { .platform_data = heartbeat_bit_pos, }, +#endif .num_resources = ARRAY_SIZE(heartbeat_resources), .resource = heartbeat_resources, }; static struct platform_device *r7780rp_devices[] __initdata = { - &m66596_usb_host_device, &cf_ide_device, &heartbeat_device, }; @@ -110,6 +90,7 @@ static int __init r7780rp_devices_setup(void) return platform_add_devices(r7780rp_devices, ARRAY_SIZE(r7780rp_devices)); } +device_initcall(r7780rp_devices_setup); /* * Platform specific clocks @@ -140,22 +121,22 @@ static struct clk *r7780rp_clocks[] = { static void r7780rp_power_off(void) { -#ifdef CONFIG_SH_R7780MP - ctrl_outw(0x0001, PA_POFF); -#endif + if (mach_is_r7780mp() || mach_is_r7785rp()) + ctrl_outw(0x0001, PA_POFF); } /* * Initialize the board */ -static void __init r7780rp_setup(char **cmdline_p) +static void __init highlander_setup(char **cmdline_p) { u16 ver = ctrl_inw(PA_VERREG); int i; - device_initcall(r7780rp_devices_setup); - - printk(KERN_INFO "Renesas Solutions Highlander R7780RP-1 support.\n"); + printk(KERN_INFO "Renesas Solutions Highlander %s support.\n", + mach_is_r7780rp() ? "R7780RP-1" : + mach_is_r7780mp() ? "R7780MP" : + "R7785RP"); printk(KERN_INFO "Board version: %d (revision %d), " "FPGA version: %d (revision %d)\n", @@ -173,9 +154,10 @@ static void __init r7780rp_setup(char **cmdline_p) } ctrl_outw(0x0000, PA_OBLED); /* Clear LED. */ -#ifndef CONFIG_SH_R7780MP - ctrl_outw(0x0001, PA_SDPOW); /* SD Power ON */ -#endif + + if (mach_is_r7780rp()) + ctrl_outw(0x0001, PA_SDPOW); /* SD Power ON */ + ctrl_outw(ctrl_inw(PA_IVDRCTL) | 0x01, PA_IVDRCTL); /* Si13112 */ pm_power_off = r7780rp_power_off; @@ -184,10 +166,10 @@ static void __init r7780rp_setup(char **cmdline_p) /* * The Machine Vector */ -struct sh_machine_vector mv_r7780rp __initmv = { - .mv_name = "Highlander R7780RP-1", - .mv_setup = r7780rp_setup, +struct sh_machine_vector mv_highlander __initmv = { + .mv_name = "Highlander", .mv_nr_irqs = 109, - .mv_init_irq = init_r7780rp_IRQ, + .mv_setup = highlander_setup, + .mv_init_irq = highlander_init_irq, }; -ALIAS_MV(r7780rp) +ALIAS_MV(highlander) diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig new file mode 100644 index 000000000000..0f5ec649daf8 --- /dev/null +++ b/arch/sh/configs/r7785rp_defconfig @@ -0,0 +1,1334 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.21-rc3 +# Mon Mar 12 14:26:33 2007 +# +CONFIG_SUPERH=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME is not set +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RELAY is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +# CONFIG_FUTEX is not set +# CONFIG_EPOLL is not set +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" + +# +# System type +# +# CONFIG_SH_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SOLUTION_ENGINE is not set +# CONFIG_SH_7300_SOLUTION_ENGINE is not set +# CONFIG_SH_7343_SOLUTION_ENGINE is not set +# CONFIG_SH_73180_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SYSTEMH is not set +# CONFIG_SH_HP6XX is not set +# CONFIG_SH_SATURN is not set +# CONFIG_SH_DREAMCAST is not set +# CONFIG_SH_MPC1211 is not set +# CONFIG_SH_SH03 is not set +# CONFIG_SH_SECUREEDGE5410 is not set +# CONFIG_SH_HS7751RVOIP is not set +# CONFIG_SH_7710VOIPGW is not set +# CONFIG_SH_RTS7751R2D is not set +CONFIG_SH_HIGHLANDER=y +# CONFIG_SH_EDOSK7705 is not set +# CONFIG_SH_SH4202_MICRODEV is not set +# CONFIG_SH_LANDISK is not set +# CONFIG_SH_TITAN is not set +# CONFIG_SH_SHMIN is not set +# CONFIG_SH_7206_SOLUTION_ENGINE is not set +# CONFIG_SH_7619_SOLUTION_ENGINE is not set +# CONFIG_SH_UNKNOWN is not set +# CONFIG_SH_R7780RP is not set +# CONFIG_SH_R7780MP is not set +CONFIG_SH_R7785RP=y + +# +# Processor selection +# +CONFIG_CPU_SH4=y +CONFIG_CPU_SH4A=y +CONFIG_CPU_SHX2=y + +# +# SH-2 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7604 is not set +# CONFIG_CPU_SUBTYPE_SH7619 is not set + +# +# SH-2A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7206 is not set + +# +# SH-3 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7300 is not set +# CONFIG_CPU_SUBTYPE_SH7705 is not set +# CONFIG_CPU_SUBTYPE_SH7706 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7710 is not set + +# +# SH-4 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7750 is not set +# CONFIG_CPU_SUBTYPE_SH7091 is not set +# CONFIG_CPU_SUBTYPE_SH7750R is not set +# CONFIG_CPU_SUBTYPE_SH7750S is not set +# CONFIG_CPU_SUBTYPE_SH7751 is not set +# CONFIG_CPU_SUBTYPE_SH7751R is not set +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_SH4_202 is not set + +# +# ST40 Processor Support +# +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +# CONFIG_CPU_SUBTYPE_ST40GX1 is not set + +# +# SH-4A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7770 is not set +# CONFIG_CPU_SUBTYPE_SH7780 is not set +CONFIG_CPU_SUBTYPE_SH7785=y + +# +# SH4AL-DSP Processor Support +# +# CONFIG_CPU_SUBTYPE_SH73180 is not set +# CONFIG_CPU_SUBTYPE_SH7343 is not set +# CONFIG_CPU_SUBTYPE_SH7722 is not set + +# +# Memory management options +# +CONFIG_MMU=y +CONFIG_PAGE_OFFSET=0x80000000 +CONFIG_MEMORY_START=0x08000000 +CONFIG_MEMORY_SIZE=0x08000000 +CONFIG_32BIT=y +# CONFIG_X2TLB is not set +CONFIG_VSYSCALL=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +# CONFIG_HUGETLB_PAGE_SIZE_64K is not set +# CONFIG_HUGETLB_PAGE_SIZE_256K is not set +CONFIG_HUGETLB_PAGE_SIZE_1MB=y +# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 + +# +# Cache configuration +# +# CONFIG_SH_DIRECT_MAPPED is not set +# CONFIG_SH_WRITETHROUGH is not set +# CONFIG_SH_OCRAM is not set + +# +# Processor features +# +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_SH_FPU=y +# CONFIG_SH_DSP is not set +CONFIG_SH_STORE_QUEUES=y +CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_INTC2_IRQ=y +CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_PTEA=y + +# +# Timer and clock configuration +# +CONFIG_SH_TMU=y +CONFIG_SH_TIMER_IRQ=28 +CONFIG_NO_IDLE_HZ=y +CONFIG_SH_PCLK_FREQ=50000000 + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# DMA support +# +# CONFIG_SH_DMA is not set + +# +# Companion Chips +# +# CONFIG_HD6446X_SERIES is not set + +# +# Additional SuperH Device Drivers +# +CONFIG_HEARTBEAT=y +CONFIG_PUSH_SWITCH=y + +# +# Kernel features +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_KEXEC=y +# CONFIG_SMP is not set +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y + +# +# Boot options +# +CONFIG_ZERO_PAGE_OFFSET=0x00001000 +CONFIG_BOOT_LINK_OFFSET=0x00800000 +# CONFIG_UBC_WAKEUP is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1" + +# +# Bus options +# +CONFIG_PCI=y +CONFIG_SH_PCIDMA_NONCOHERENT=y +CONFIG_PCI_AUTO=y +CONFIG_PCI_AUTO_UPDATE_RESOURCES=y +# CONFIG_PCI_DEBUG is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_FLAT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options (EXPERIMENTAL) +# +# CONFIG_PM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_MULTIPLE_TABLES is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_BRIDGE=m +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set +CONFIG_WIRELESS_EXT=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# Misc devices +# +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +CONFIG_SATA_SIL=y +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +CONFIG_PATA_PLATFORM=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_STNIC is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_R8169=y +# CONFIG_R8169_NAPI is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_NET_WIRELESS_RTNETLINK is not set + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_HERMES is not set +# CONFIG_ATMEL is not set + +# +# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support +# +# CONFIG_PRISM54 is not set +# CONFIG_HOSTAP is not set +CONFIG_NET_WIRELESS=y + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=6 +CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frambuffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_EPSON1355 is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=m +# CONFIG_OBSOLETE_OSS is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set + +# +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set + +# +# RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +CONFIG_RTC_DRV_SH=y +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# Auxiliary Display support +# + +# +# Virtualization +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=m + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=y +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_RAMFS=y +CONFIG_CONFIGFS_FS=m + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_CODEPAGE_932=y +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=m + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_PREEMPT is not set +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_LOCK_ALLOC=y +# CONFIG_PROVE_LOCKING is not set +CONFIG_LOCKDEP=y +# CONFIG_DEBUG_LOCKDEP is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +CONFIG_DEBUG_LOCKING_API_SELFTESTS=y +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +CONFIG_FORCED_INLINING=y +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_SH_STANDARD_BIOS=y +# CONFIG_EARLY_SCIF_CONSOLE is not set +CONFIG_EARLY_PRINTK=y +CONFIG_DEBUG_STACKOVERFLOW=y +CONFIG_DEBUG_STACK_USAGE=y +# CONFIG_4KSTACKS is not set +# CONFIG_SH_KGDB is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y diff --git a/arch/sh/drivers/Kconfig b/arch/sh/drivers/Kconfig index c54c758e6243..420c6b2f33a5 100644 --- a/arch/sh/drivers/Kconfig +++ b/arch/sh/drivers/Kconfig @@ -1,5 +1,15 @@ +source "arch/sh/drivers/dma/Kconfig" +source "arch/sh/cchips/Kconfig" + menu "Additional SuperH Device Drivers" +config HEARTBEAT + bool "Heartbeat LED" + help + Use the power-on LED on your machine as a load meter. The exact + behavior is platform-dependent, but normally the flash frequency is + a hyperbolic function of the 5-minute load average. + config PUSH_SWITCH tristate "Push switch support" help diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index cc8d0d0b1427..8a7e70651939 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -8,12 +8,13 @@ obj-$(CONFIG_PCI_AUTO) += pci-auto.o obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o +obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ dma-dreamcast.o obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o -obj-$(CONFIG_SH_R7780RP) += ops-r7780rp.o fixups-r7780rp.o +obj-$(CONFIG_SH_HIGHLANDER) += ops-r7780rp.o fixups-r7780rp.o obj-$(CONFIG_SH_TITAN) += ops-titan.o obj-$(CONFIG_SH_LANDISK) += ops-landisk.o diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c index eeea1577e112..6f4fb38bafa2 100644 --- a/arch/sh/drivers/pci/ops-r7780rp.c +++ b/arch/sh/drivers/pci/ops-r7780rp.c @@ -17,18 +17,35 @@ #include #include "pci-sh4.h" +static char r7780rp_irq_tab[] __initdata = { + 0, 1, 2, 3, +}; + +static char r7780mp_irq_tab[] __initdata = { + 65, 66, 67, 68, +}; + +static char r7785rp_irq_tab[][4] __initdata = { + { 65, 66, 67, 68 }, /* INT ABCD */ + { 66, 67, 68, 65 }, /* INT BCDA */ + { 67, 68, 65, 66 }, /* INT CDAB */ + { 68, 65, 66, 67 }, /* INT DABC */ + { 64, 64, 64, 64 }, /* PCI Host */ +}; + int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { - switch (slot) { - case 0: return IRQ_PCISLOT1; /* PCI Interrupt #1 */ - case 1: return IRQ_PCISLOT2; /* PCI Interrupt #2 */ - case 2: return IRQ_PCISLOT3; /* PCI Interrupt #3 */ - case 3: return IRQ_PCISLOT4; /* PCI Interrupt E4 */ - default: - printk(KERN_ERR "PCI: Bad IRQ mapping " - "request for slot %d, func %d\n", slot, pin-1); - return -1; - } + if (mach_is_r7780rp()) + return r7780rp_irq_tab[slot]; + if (mach_is_r7780mp()) + return r7780mp_irq_tab[slot]; + if (mach_is_r7785rp()) + return r7785rp_irq_tab[slot][pin]; + + printk(KERN_ERR "PCI: Bad IRQ mapping " + "request for slot %d, func %d\n", slot, pin-1); + + return -1; } static struct resource sh7780_io_resource = { diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h index 5a61d6041f2c..1901c33cde6a 100644 --- a/arch/sh/drivers/pci/pci-sh4.h +++ b/arch/sh/drivers/pci/pci-sh4.h @@ -1,7 +1,7 @@ #ifndef __PCI_SH4_H #define __PCI_SH4_H -#ifdef CONFIG_CPU_SUBTYPE_SH7780 +#if defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785) #include "pci-sh7780.h" #else #include "pci-sh7751.h" diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 602b644c35ad..16b30a9e94bb 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -48,7 +48,7 @@ static int __init sh7780_pci_init(void) { unsigned int id; - int ret; + int ret, match = 0; pr_debug("PCI: Starting intialization.\n"); @@ -56,8 +56,17 @@ static int __init sh7780_pci_init(void) /* check for SH7780/SH7780R hardware */ id = pci_read_reg(SH7780_PCIVID); - if ((id != ((SH7780_DEVICE_ID << 16) | SH7780_VENDOR_ID)) && - (id != ((SH7781_DEVICE_ID << 16) | SH7780_VENDOR_ID))) { + if ((id & 0xffff) == SH7780_VENDOR_ID) { + switch ((id >> 16) & 0xffff) { + case SH7780_DEVICE_ID: + case SH7781_DEVICE_ID: + case SH7785_DEVICE_ID: + match = 1; + break; + } + } + + if (unlikely(!match)) { printk(KERN_ERR "PCI: This is not an SH7780 (%x)\n", id); return -ENODEV; } @@ -138,7 +147,7 @@ int __init sh7780_pcic_init(struct sh4_pci_address_map *map) * DMA interrupts... */ -#ifdef CONFIG_SH_R7780RP +#ifdef CONFIG_SH_HIGHLANDER pci_fixup_pcic(); #endif diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h index f02d2180a4bc..bd44255509e6 100644 --- a/arch/sh/drivers/pci/pci-sh7780.h +++ b/arch/sh/drivers/pci/pci-sh7780.h @@ -14,8 +14,9 @@ /* Platform Specific Values */ #define SH7780_VENDOR_ID 0x1912 -#define SH7780_DEVICE_ID 0x0002 #define SH7781_DEVICE_ID 0x0001 +#define SH7780_DEVICE_ID 0x0002 +#define SH7785_DEVICE_ID 0x0007 /* SH7780 Control Registers */ #define SH7780_PCI_VCR0 0xFE000000 diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c index 74defe76a058..d8e22f4ff0f0 100644 --- a/arch/sh/kernel/cpu/irq/intc2.c +++ b/arch/sh/kernel/cpu/irq/intc2.c @@ -18,7 +18,8 @@ #define INTC2_BASE 0xfe080000 #define INTC2_INTMSK (INTC2_BASE + 0x40) #define INTC2_INTMSKCLR (INTC2_BASE + 0x60) -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) +#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || \ + defined(CONFIG_CPU_SUBTYPE_SH7785) #define INTC2_BASE 0xffd40000 #define INTC2_INTMSK (INTC2_BASE + 0x38) #define INTC2_INTMSKCLR (INTC2_BASE + 0x3c) diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index 58950de2696d..8cd04904c77a 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -124,6 +124,14 @@ int __init detect_cpu_and_cache_system(void) current_cpu_data.dcache.ways = 4; current_cpu_data.flags |= CPU_HAS_LLSC; break; + case 0x3004: + case 0x3007: + current_cpu_data.type = CPU_SH7785; + current_cpu_data.icache.ways = 4; + current_cpu_data.dcache.ways = 4; + current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | + CPU_HAS_LLSC; + break; case 0x3008: if (prr == 0xa0) { current_cpu_data.type = CPU_SH7722; diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile index a8f493f2f21f..1efeda0e1829 100644 --- a/arch/sh/kernel/cpu/sh4a/Makefile +++ b/arch/sh/kernel/cpu/sh4a/Makefile @@ -5,6 +5,7 @@ # CPU subtype setup obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o +obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o @@ -13,6 +14,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o +clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7343.o diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c new file mode 100644 index 000000000000..805535aa505e --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -0,0 +1,162 @@ +/* + * arch/sh/kernel/cpu/sh4a/clock-sh7785.c + * + * SH7785 support for the clock framework + * + * Copyright (C) 2007 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include + +static int ifc_divisors[] = { 1, 2, 4, 6 }; +static int ufc_divisors[] = { 1, 1, 4, 6 }; +static int sfc_divisors[] = { 1, 1, 4, 6 }; +static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 18, + 24, 32, 36, 48, 1, 1, 1, 1 }; +static int mfc_divisors[] = { 1, 1, 4, 6 }; +static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18, + 24, 32, 36, 48, 1, 1, 1, 1 }; + +static void master_clk_init(struct clk *clk) +{ + clk->rate *= 36; +} + +static struct clk_ops sh7785_master_clk_ops = { + .init = master_clk_init, +}; + +static void module_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQMR1) & 0x000f); + clk->rate = clk->parent->rate / pfc_divisors[idx]; +} + +static struct clk_ops sh7785_module_clk_ops = { + .recalc = module_clk_recalc, +}; + +static void bus_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQMR1) >> 16) & 0x000f); + clk->rate = clk->parent->rate / bfc_divisors[idx]; +} + +static struct clk_ops sh7785_bus_clk_ops = { + .recalc = bus_clk_recalc, +}; + +static void cpu_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQMR1) >> 28) & 0x0003); + clk->rate = clk->parent->rate / ifc_divisors[idx]; +} + +static struct clk_ops sh7785_cpu_clk_ops = { + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *sh7785_clk_ops[] = { + &sh7785_master_clk_ops, + &sh7785_module_clk_ops, + &sh7785_bus_clk_ops, + &sh7785_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(sh7785_clk_ops)) + *ops = sh7785_clk_ops[idx]; +} + +static void shyway_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQMR1) >> 20) & 0x0003); + clk->rate = clk->parent->rate / sfc_divisors[idx]; +} + +static struct clk_ops sh7785_shyway_clk_ops = { + .recalc = shyway_clk_recalc, +}; + +static struct clk sh7785_shyway_clk = { + .name = "shyway_clk", + .flags = CLK_ALWAYS_ENABLED, + .ops = &sh7785_shyway_clk_ops, +}; + +static void ddr_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQMR1) >> 12) & 0x0003); + clk->rate = clk->parent->rate / mfc_divisors[idx]; +} + +static struct clk_ops sh7785_ddr_clk_ops = { + .recalc = ddr_clk_recalc, +}; + +static struct clk sh7785_ddr_clk = { + .name = "ddr_clk", + .flags = CLK_ALWAYS_ENABLED, + .ops = &sh7785_ddr_clk_ops, +}; + +static void ram_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQMR1) >> 24) & 0x0003); + clk->rate = clk->parent->rate / ufc_divisors[idx]; +} + +static struct clk_ops sh7785_ram_clk_ops = { + .recalc = ram_clk_recalc, +}; + +static struct clk sh7785_ram_clk = { + .name = "ram_clk", + .flags = CLK_ALWAYS_ENABLED, + .ops = &sh7785_ram_clk_ops, +}; + +/* + * Additional SH7785-specific on-chip clocks that aren't already part of the + * clock framework + */ +static struct clk *sh7785_onchip_clocks[] = { + &sh7785_shyway_clk, + &sh7785_ddr_clk, + &sh7785_ram_clk, +}; + +static int __init sh7785_clk_init(void) +{ + struct clk *clk = clk_get(NULL, "master_clk"); + int i; + + for (i = 0; i < ARRAY_SIZE(sh7785_onchip_clocks); i++) { + struct clk *clkp = sh7785_onchip_clocks[i]; + + clkp->parent = clk; + clk_register(clkp); + clk_enable(clkp); + } + + /* + * Now that we have the rest of the clocks registered, we need to + * force the parent clock to propagate so that these clocks will + * automatically figure out their rate. We cheat by handing the + * parent clock its current rate and forcing child propagation. + */ + clk_set_rate(clk, clk_get_rate(clk)); + + clk_put(clk); + + return 0; +} +arch_initcall(sh7785_clk_init); diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c new file mode 100644 index 000000000000..c9ae6592f098 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -0,0 +1,98 @@ +/* + * SH7785 Setup + * + * Copyright (C) 2007 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xffea0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 40, 41, 43, 42 }, + }, { + .mapbase = 0xffeb0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 44, 45, 47, 46 }, + }, + + /* + * The rest of these all have multiplexed IRQs + */ + { + .mapbase = 0xffec0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 60, 60, 60, 60 }, + }, { + .mapbase = 0xffed0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 61, 61, 61, 61 }, + }, { + .mapbase = 0xffee0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 62, 62, 62, 62 }, + }, { + .mapbase = 0xffef0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 63, 63, 63, 63 }, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh7785_devices[] __initdata = { + &sci_device, +}; + +static int __init sh7785_devices_setup(void) +{ + return platform_add_devices(sh7785_devices, + ARRAY_SIZE(sh7785_devices)); +} +__initcall(sh7785_devices_setup); + +static struct intc2_data intc2_irq_table[] = { + { 28, 0, 24, 0, 0, 2 }, /* TMU0 */ + + { 40, 8, 24, 0, 3, 3 }, /* SCIF0 ERI */ + { 41, 8, 24, 0, 3, 3 }, /* SCIF0 RXI */ + { 42, 8, 24, 0, 3, 3 }, /* SCIF0 BRI */ + { 43, 8, 24, 0, 3, 3 }, /* SCIF0 TXI */ + + { 76, 8, 16, 0, 4, 3 }, /* SCIF1 ERI */ + { 77, 8, 16, 0, 4, 3 }, /* SCIF1 RXI */ + { 78, 8, 16, 0, 4, 3 }, /* SCIF1 BRI */ + { 79, 8, 16, 0, 4, 3 }, /* SCIF1 TXI */ + + { 64, 0x14, 8, 0, 14, 2 }, /* PCIC0 */ + { 65, 0x14, 0, 0, 15, 2 }, /* PCIC1 */ + { 66, 0x18, 24, 0, 16, 2 }, /* PCIC2 */ + { 67, 0x18, 16, 0, 17, 2 }, /* PCIC3 */ + { 68, 0x18, 8, 0, 18, 2 }, /* PCIC4 */ +}; + +void __init init_IRQ_intc2(void) +{ + make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); +} diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c index e060e71d0785..ad1ede52fc9c 100644 --- a/arch/sh/kernel/timers/timer-tmu.c +++ b/arch/sh/kernel/timers/timer-tmu.c @@ -148,7 +148,9 @@ static int tmu_timer_init(void) /* Start TMU0 */ tmu_timer_stop(); -#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760) +#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && \ + !defined(CONFIG_CPU_SUBTYPE_SH7760) && \ + !defined(CONFIG_CPU_SUBTYPE_SH7785) ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); #endif diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index 4fe0f94cbf42..5b1236c2cfec 100644 --- a/arch/sh/tools/mach-types +++ b/arch/sh/tools/mach-types @@ -26,6 +26,7 @@ SH03 SH_SH03 LANDISK SH_LANDISK R7780RP SH_R7780RP R7780MP SH_R7780MP +R7785RP SH_R7785RP TITAN SH_TITAN SHMIN SH_SHMIN 7710VOIPGW SH_7710VOIPGW diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 4b17f845f5cd..94deebda6da0 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -62,7 +62,7 @@ struct sci_port { unsigned int type; /* Port IRQs: ERI, RXI, TXI, BRI (optional) */ - unsigned int irqs[SCIx_NR_IRQS]; + unsigned int irqs[SCIx_NR_IRQS]; /* Port pin configuration */ void (*init_pins)(struct uart_port *port, @@ -351,7 +351,7 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) } else { #ifdef CONFIG_CPU_SUBTYPE_SH7343 /* Nothing */ -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) +#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785) ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */ #else ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */ @@ -361,7 +361,9 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) } #endif -#if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780) +#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \ + defined(CONFIG_CPU_SUBTYPE_SH7780) || \ + defined(CONFIG_CPU_SUBTYPE_SH7785) static inline int scif_txroom(struct uart_port *port) { return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0x7f); @@ -1368,9 +1370,19 @@ static int __devinit sci_probe(struct platform_device *dev) struct plat_sci_port *p = dev->dev.platform_data; int i; - for (i = 0; p && p->flags != 0 && i < SCI_NPORTS; p++, i++) { + for (i = 0; p && p->flags != 0; p++, i++) { struct sci_port *sciport = &sci_ports[i]; + /* Sanity check */ + if (unlikely(i == SCI_NPORTS)) { + dev_notice(&dev->dev, "Attempting to register port " + "%d when only %d are available.\n", + i+1, SCI_NPORTS); + dev_notice(&dev->dev, "Consider bumping " + "CONFIG_SERIAL_SH_SCI_NR_UARTS!\n"); + break; + } + sciport->port.mapbase = p->mapbase; /* diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 77f7d6351ab1..854153a1d60a 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -140,6 +140,16 @@ # define SCIF_ORER 0x0001 /* Overrun error bit */ # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ # define SCIF_ONLY +#elif defined(CONFIG_CPU_SUBTYPE_SH7785) +# define SCSPTR0 0xffea0024 /* 16 bit SCIF */ +# define SCSPTR1 0xffeb0024 /* 16 bit SCIF */ +# define SCSPTR2 0xffec0024 /* 16 bit SCIF */ +# define SCSPTR3 0xffed0024 /* 16 bit SCIF */ +# define SCSPTR4 0xffee0024 /* 16 bit SCIF */ +# define SCSPTR5 0xffef0024 /* 16 bit SCIF */ +# define SCIF_OPER 0x0001 /* Overrun error bit */ +# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ +# define SCIF_ONLY #elif defined(CONFIG_CPU_SUBTYPE_SH7206) # define SCSPTR0 0xfffe8020 /* 16 bit SCIF */ # define SCSPTR1 0xfffe8820 /* 16 bit SCIF */ @@ -163,7 +173,10 @@ #define SCI_CTRL_FLAGS_RIE 0x40 /* all */ #define SCI_CTRL_FLAGS_TE 0x20 /* all */ #define SCI_CTRL_FLAGS_RE 0x10 /* all */ -#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH7780) +#if defined(CONFIG_CPU_SUBTYPE_SH7750) || \ + defined(CONFIG_CPU_SUBTYPE_SH7751) || \ + defined(CONFIG_CPU_SUBTYPE_SH7780) || \ + defined(CONFIG_CPU_SUBTYPE_SH7785) #define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */ #else #define SCI_CTRL_FLAGS_REIE 0 @@ -385,7 +398,9 @@ SCIx_FNS(SCxTDR, 0x06, 8, 0x0c, 8, 0x06, 8, 0x0C, 8, 0x03, 8) SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16, 0x04, 8) SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8) SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16) -#if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780) +#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \ + defined(CONFIG_CPU_SUBTYPE_SH7780) || \ + defined(CONFIG_CPU_SUBTYPE_SH7785) SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16) SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) @@ -576,6 +591,23 @@ static inline int sci_rxd_in(struct uart_port *port) return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ return 1; } +#elif defined(CONFIG_CPU_SUBTYPE_SH7785) +static inline int sci_rxd_in(struct uart_port *port) +{ + if (port->mapbase == 0xffea0000) + return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ + if (port->mapbase == 0xffeb0000) + return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ + if (port->mapbase == 0xffec0000) + return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ + if (port->mapbase == 0xffed0000) + return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ + if (port->mapbase == 0xffee0000) + return ctrl_inw(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF */ + if (port->mapbase == 0xffef0000) + return ctrl_inw(SCSPTR5) & 0x0001 ? 1 : 0; /* SCIF */ + return 1; +} #elif defined(CONFIG_CPU_SUBTYPE_SH7206) static inline int sci_rxd_in(struct uart_port *port) { @@ -634,7 +666,9 @@ static inline int sci_rxd_in(struct uart_port *port) * -- Mitch Davis - 15 Jul 2000 */ -#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7780) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) || \ + defined(CONFIG_CPU_SUBTYPE_SH7780) || \ + defined(CONFIG_CPU_SUBTYPE_SH7785) #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1) #elif defined(CONFIG_CPU_SUBTYPE_SH7705) #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) diff --git a/include/asm-sh/cpu-sh4/freq.h b/include/asm-sh/cpu-sh4/freq.h index 602d061ca2dc..99402547ed06 100644 --- a/include/asm-sh/cpu-sh4/freq.h +++ b/include/asm-sh/cpu-sh4/freq.h @@ -14,6 +14,10 @@ #define FRQCR 0xa4150000 #elif defined(CONFIG_CPU_SUBTYPE_SH7780) #define FRQCR 0xffc80000 +#elif defined(CONFIG_CPU_SUBTYPE_SH7785) +#define FRQCR0 0xffc80000 +#define FRQCR1 0xffc80004 +#define FRQMR1 0xffc80014 #else #define FRQCR 0xffc00000 #endif diff --git a/include/asm-sh/pci.h b/include/asm-sh/pci.h index 6ccc948fe216..b1f9a9e0231e 100644 --- a/include/asm-sh/pci.h +++ b/include/asm-sh/pci.h @@ -35,7 +35,7 @@ extern struct pci_channel board_pci_channels[]; /* * I/O routine helpers */ -#ifdef CONFIG_CPU_SUBTYPE_SH7780 +#if defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785) #define PCI_IO_AREA 0xFE400000 #define PCI_IO_SIZE 0x00400000 #else diff --git a/include/asm-sh/r7780rp.h b/include/asm-sh/r7780rp.h index c18f648a7995..8c0721965a5e 100644 --- a/include/asm-sh/r7780rp.h +++ b/include/asm-sh/r7780rp.h @@ -1,17 +1,11 @@ #ifndef __ASM_SH_RENESAS_R7780RP_H #define __ASM_SH_RENESAS_R7780RP_H -/* - * linux/include/asm-sh/r7780rp.h - * - * Copyright (C) 2000 Atom Create Engineering Co., Ltd. - * - * Renesas Solutions Highlander R7780RP support - */ - /* Box specific addresses. */ #if defined(CONFIG_SH_R7780MP) #define PA_BCR 0xa4000000 /* FPGA */ +#define PA_SDPOW (-1) + #define PA_IRLMSK (PA_BCR+0x0000) /* Interrupt Mask control */ #define PA_IRLMON (PA_BCR+0x0002) /* Interrupt Status control */ #define PA_IRLPRI1 (PA_BCR+0x0004) /* Interrupt Priorty 1 */ @@ -70,18 +64,12 @@ #define PA_POFF (PA_BCR+0x0800) /* System Power Off control */ #define PA_PMR (PA_BCR+0x0900) /* */ -#define PA_AX88796L 0xa4100400 /* AX88796L Area */ -#define PA_SC1602BSLB 0xa6000000 /* SC1602BSLB Area */ -#define PA_IDE_OFFSET 0x1f0 /* CF IDE Offset */ -#define AX88796L_IO_BASE 0x1000 /* AX88796L IO Base Address */ - #define IRLCNTR1 (PA_BCR + 0) /* Interrupt Control Register1 */ #define IRQ_PCISLOT1 65 /* PCI Slot #1 IRQ */ #define IRQ_PCISLOT2 66 /* PCI Slot #2 IRQ */ #define IRQ_PCISLOT3 67 /* PCI Slot #3 IRQ */ #define IRQ_PCISLOT4 68 /* PCI Slot #4 IRQ */ -// #define IRQ_CFINST 0 /* CF Card Insert IRQ */ #define IRQ_TP 2 /* Touch Panel IRQ */ #define IRQ_SCI1 3 /* SCI1 IRQ */ #define IRQ_SCI0 4 /* SCI0 IRQ */ @@ -95,7 +83,7 @@ #define IRQ_ONETH 13 /* On board Ethernet IRQ */ #define IRQ_PSW 14 /* Push Switch IRQ */ -#else /* R7780RP */ +#elif defined(CONFIG_SH_R7780RP) #define PA_BCR 0xa5000000 /* FPGA */ #define PA_IRLMSK (PA_BCR+0x0000) /* Interrupt Mask control */ @@ -163,7 +151,55 @@ #define IRQ_PSW 13 /* Push Switch IRQ */ #define IRQ_ZIGBEE 14 /* Ziggbee IO IRQ */ -#endif /* CONFIG_SH_R7780MP */ +#elif defined(CONFIG_SH_R7785RP) +#define PA_BCR 0xa4000000 /* FPGA */ +#define PA_SDPOW (-1) + +#define PA_PCISCR (PA_BCR+0x0000) +#define PA_IRLPRA (PA_BCR+0x0002) +#define PA_IRLPRB (PA_BCR+0x0004) +#define PA_IRLPRC (PA_BCR+0x0006) +#define PA_IRLPRD (PA_BCR+0x0008) +#define IRLCNTR1 (PA_BCR+0x0010) +#define PA_IRLPRE (PA_BCR+0x000a) +#define PA_IRLPRF (PA_BCR+0x000c) +#define PA_EXIRLCR (PA_BCR+0x000e) +#define PA_IRLMCR1 (PA_BCR+0x0010) +#define PA_IRLMCR2 (PA_BCR+0x0012) +#define PA_IRLSSR1 (PA_BCR+0x0014) +#define PA_IRLSSR2 (PA_BCR+0x0016) +#define PA_CFTCR (PA_BCR+0x0100) +#define PA_CFPCR (PA_BCR+0x0102) +#define PA_PCICR (PA_BCR+0x0110) +#define PA_IVDRCTL (PA_BCR+0x0112) +#define PA_IVDRSR (PA_BCR+0x0114) +#define PA_PDRSTCR (PA_BCR+0x0116) +#define PA_POFF (PA_BCR+0x0120) +#define PA_LCDCR (PA_BCR+0x0130) +#define PA_TPCR (PA_BCR+0x0140) +#define PA_TPCKCR (PA_BCR+0x0142) +#define PA_TPRSTR (PA_BCR+0x0144) +#define PA_TPXPDR (PA_BCR+0x0146) +#define PA_TPYPDR (PA_BCR+0x0148) +#define PA_GPIOPFR (PA_BCR+0x0150) +#define PA_GPIODR (PA_BCR+0x0152) +#define PA_OBLED (PA_BCR+0x0154) +#define PA_SWSR (PA_BCR+0x0156) +#define PA_VERREG (PA_BCR+0x0158) +#define PA_SMCR (PA_BCR+0x0200) +#define PA_SMSMADR (PA_BCR+0x0202) +#define PA_SMMR (PA_BCR+0x0204) +#define PA_SMSADR1 (PA_BCR+0x0206) +#define PA_SMSADR32 (PA_BCR+0x0244) +#define PA_SMTRDR1 (PA_BCR+0x0246) +#define PA_SMTRDR16 (PA_BCR+0x0264) +#define PA_CU3MDR (PA_BCR+0x0300) +#define PA_CU5MDR (PA_BCR+0x0302) +#define PA_MMSR (PA_BCR+0x0400) +#endif + +void make_r7780rp_irq(unsigned int irq); +void highlander_init_irq(void); #define __IO_PREFIX r7780rp #include -- cgit v1.2.3-59-g8ed1b From f987fc880d191bf2ef66ac17e9d524aee6afa02e Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Mon, 12 Mar 2007 15:12:27 +0900 Subject: sh: pata_platform pcmcia support for SolutionEngine boards. This enables pata_platform support for the PCMCIA slot on the SolutionEngine. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt --- arch/sh/boards/se/770x/setup.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'arch') diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c index 45cbc36b9fb7..dab5510699a0 100644 --- a/arch/sh/boards/se/770x/setup.c +++ b/arch/sh/boards/se/770x/setup.c @@ -63,6 +63,31 @@ static void __init smsc_setup(char **cmdline_p) outb_p(CONFIG_EXIT, CONFIG_PORT); } + +static struct resource cf_ide_resources[] = { + [0] = { + .start = PA_MRSHPC_IO + 0x1f0, + .end = PA_MRSHPC_IO + 0x1f0 + 8, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PA_MRSHPC_IO + 0x1f0 + 0x206, + .end = PA_MRSHPC_IO + 0x1f0 +8 + 0x206 + 8, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = 7, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cf_ide_device = { + .name = "pata_platform", + .id = -1, + .num_resources = ARRAY_SIZE(cf_ide_resources), + .resource = cf_ide_resources, +}; + static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; static struct resource heartbeat_resources[] = { @@ -85,6 +110,7 @@ static struct platform_device heartbeat_device = { static struct platform_device *se_devices[] __initdata = { &heartbeat_device, + &cf_ide_device, }; static int __init se_devices_setup(void) -- cgit v1.2.3-59-g8ed1b From f6072896e3f4c577db7e3a06105ebdfd52d7e7c9 Mon Sep 17 00:00:00 2001 From: Takashi YOSHII Date: Mon, 12 Mar 2007 15:33:22 +0900 Subject: sh: heartbeat double 0 fix. This implements stricter and more compliant knightrider strobing in the heartbeat handler. While there still seems to be some debate as to whether the double 0 is "more" correct or not, this updated version appears to have general consensus. Fixes a long-term "bug". Signed-off-by: Takashi YOSHII Signed-off-by: Paul Mundt --- arch/sh/drivers/heartbeat.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c index bc59cb6cd78b..23dd6080422f 100644 --- a/arch/sh/drivers/heartbeat.c +++ b/arch/sh/drivers/heartbeat.c @@ -40,16 +40,9 @@ static void heartbeat_timer(unsigned long data) static unsigned bit = 0, up = 1; ctrl_outw(1 << hd->bit_pos[bit], (unsigned long)hd->base); - if (up) - if (bit == (ARRAY_SIZE(hd->bit_pos) - 1)) { - bit--; - up = 0; - } else - bit++; - else if (bit == 0) - up = 1; - else - bit--; + bit += up; + if ((bit == 0) || (bit == ARRAY_SIZE(hd->bit_pos)-1)) + up = -up; mod_timer(&hd->timer, jiffies + (110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT))))); -- cgit v1.2.3-59-g8ed1b From 00e8c494a1603eac0a2cae9836e624a752ad45b1 Mon Sep 17 00:00:00 2001 From: kogiidena Date: Mon, 19 Mar 2007 16:24:12 +0900 Subject: sh: landisk updates. Updates for the landisk board: - The push_switch framework was used. - landisk_pwb.c was divided into psw.c and gio.c. - pata_platform was supported in USL-5P. - irq.c was rewritten. - io.c was replaced with generic I/O routines. Signed-off-by: kogiidena Signed-off-by: Paul Mundt --- arch/sh/boards/landisk/Makefile | 2 +- arch/sh/boards/landisk/gio.c | 167 +++++++++++++++++ arch/sh/boards/landisk/io.c | 250 ------------------------- arch/sh/boards/landisk/irq.c | 83 +++------ arch/sh/boards/landisk/landisk_pwb.c | 346 ----------------------------------- arch/sh/boards/landisk/psw.c | 143 +++++++++++++++ arch/sh/boards/landisk/rtc.c | 91 --------- arch/sh/boards/landisk/setup.c | 163 +++++------------ arch/sh/drivers/pci/ops-landisk.c | 4 +- 9 files changed, 377 insertions(+), 872 deletions(-) create mode 100644 arch/sh/boards/landisk/gio.c delete mode 100644 arch/sh/boards/landisk/io.c delete mode 100644 arch/sh/boards/landisk/landisk_pwb.c create mode 100644 arch/sh/boards/landisk/psw.c delete mode 100644 arch/sh/boards/landisk/rtc.c (limited to 'arch') diff --git a/arch/sh/boards/landisk/Makefile b/arch/sh/boards/landisk/Makefile index 89e4beb2ad47..a696b4277fa9 100644 --- a/arch/sh/boards/landisk/Makefile +++ b/arch/sh/boards/landisk/Makefile @@ -2,4 +2,4 @@ # Makefile for I-O DATA DEVICE, INC. "LANDISK Series" # -obj-y := setup.o io.o irq.o rtc.o landisk_pwb.o +obj-y := setup.o irq.o psw.o gio.o diff --git a/arch/sh/boards/landisk/gio.c b/arch/sh/boards/landisk/gio.c new file mode 100644 index 000000000000..50d38be62f01 --- /dev/null +++ b/arch/sh/boards/landisk/gio.c @@ -0,0 +1,167 @@ +/* + * arch/sh/boards/landisk/gio.c - driver for landisk + * + * This driver will also support the I-O DATA Device, Inc. LANDISK Board. + * LANDISK and USL-5P Button, LED and GIO driver drive function. + * + * Copylight (C) 2006 kogiidena + * Copylight (C) 2002 Atom Create Engineering Co., Ltd. * + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEVCOUNT 4 +#define GIO_MINOR 2 /* GIO minor no. */ + +static dev_t dev; +static struct cdev *cdev_p; +static int openCnt; + +static int gio_open(struct inode *inode, struct file *filp) +{ + int minor; + + minor = MINOR(inode->i_rdev); + if (minor < DEVCOUNT) { + if (openCnt > 0) { + return -EALREADY; + } else { + openCnt++; + return 0; + } + } + return -ENOENT; +} + +static int gio_close(struct inode *inode, struct file *filp) +{ + int minor; + + minor = MINOR(inode->i_rdev); + if (minor < DEVCOUNT) { + openCnt--; + } + return 0; +} + +static int gio_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + unsigned int data; + static unsigned int addr = 0; + + if (cmd & 0x01) { /* write */ + if (copy_from_user(&data, (int *)arg, sizeof(int))) { + return -EFAULT; + } + } + + switch (cmd) { + case GIODRV_IOCSGIOSETADDR: /* addres set */ + addr = data; + break; + + case GIODRV_IOCSGIODATA1: /* write byte */ + ctrl_outb((unsigned char)(0x0ff & data), addr); + break; + + case GIODRV_IOCSGIODATA2: /* write word */ + if (addr & 0x01) { + return -EFAULT; + } + ctrl_outw((unsigned short int)(0x0ffff & data), addr); + break; + + case GIODRV_IOCSGIODATA4: /* write long */ + if (addr & 0x03) { + return -EFAULT; + } + ctrl_outl(data, addr); + break; + + case GIODRV_IOCGGIODATA1: /* read byte */ + data = ctrl_inb(addr); + break; + + case GIODRV_IOCGGIODATA2: /* read word */ + if (addr & 0x01) { + return -EFAULT; + } + data = ctrl_inw(addr); + break; + + case GIODRV_IOCGGIODATA4: /* read long */ + if (addr & 0x03) { + return -EFAULT; + } + data = ctrl_inl(addr); + break; + default: + return -EFAULT; + break; + } + + if ((cmd & 0x01) == 0) { /* read */ + if (copy_to_user((int *)arg, &data, sizeof(int))) { + return -EFAULT; + } + } + return 0; +} + +static struct file_operations gio_fops = { + .owner = THIS_MODULE, + .open = gio_open, /* open */ + .release = gio_close, /* release */ + .ioctl = gio_ioctl, /* ioctl */ +}; + +static int __init gio_init(void) +{ + int error; + + printk(KERN_INFO "gio: driver initialized\n"); + + openCnt = 0; + + if ((error = alloc_chrdev_region(&dev, 0, DEVCOUNT, "gio")) < 0) { + printk(KERN_ERR + "gio: Couldn't alloc_chrdev_region, error=%d\n", + error); + return 1; + } + + cdev_p = cdev_alloc(); + cdev_p->ops = &gio_fops; + error = cdev_add(cdev_p, dev, DEVCOUNT); + if (error) { + printk(KERN_ERR + "gio: Couldn't cdev_add, error=%d\n", error); + return 1; + } + + return 0; +} + +static void __exit gio_exit(void) +{ + cdev_del(cdev_p); + unregister_chrdev_region(dev, DEVCOUNT); +} + +module_init(gio_init); +module_exit(gio_exit); + +MODULE_LICENSE("GPL"); diff --git a/arch/sh/boards/landisk/io.c b/arch/sh/boards/landisk/io.c deleted file mode 100644 index 92498b4947d5..000000000000 --- a/arch/sh/boards/landisk/io.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * arch/sh/boards/landisk/io.c - * - * Copyright (C) 2001 Ian da Silva, Jeremy Siegel - * Based largely on io_se.c. - * - * I/O routine for I-O Data Device, Inc. LANDISK. - * - * Initial version only to support LAN access; some - * placeholder code from io_landisk.c left in with the - * expectation of later SuperIO and PCMCIA access. - */ -/* - * modifed by kogiidena - * 2005.03.03 - */ -#include -#include -#include -#include -#include -#include - -extern void *area5_io_base; /* Area 5 I/O Base address */ -extern void *area6_io_base; /* Area 6 I/O Base address */ - -static inline unsigned long port2adr(unsigned int port) -{ - if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) - if (port == 0x3f6) - return ((unsigned long)area5_io_base + 0x2c); - else - return ((unsigned long)area5_io_base + PA_PIDE_OFFSET + - ((port - 0x1f0) << 1)); - else if ((0x170 <= port && port < 0x178) || port == 0x376) - if (port == 0x376) - return ((unsigned long)area6_io_base + 0x2c); - else - return ((unsigned long)area6_io_base + PA_SIDE_OFFSET + - ((port - 0x170) << 1)); - else - maybebadio((unsigned long)port); - - return port; -} - -/* - * General outline: remap really low stuff [eventually] to SuperIO, - * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) - * is mapped through the PCI IO window. Stuff with high bits (PXSEG) - * should be way beyond the window, and is used w/o translation for - * compatibility. - */ -u8 landisk_inb(unsigned long port) -{ - if (PXSEG(port)) - return ctrl_inb(port); - else if (is_pci_ioaddr(port)) - return ctrl_inb(pci_ioaddr(port)); - - return ctrl_inw(port2adr(port)) & 0xff; -} - -u8 landisk_inb_p(unsigned long port) -{ - u8 v; - - if (PXSEG(port)) - v = ctrl_inb(port); - else if (is_pci_ioaddr(port)) - v = ctrl_inb(pci_ioaddr(port)); - else - v = ctrl_inw(port2adr(port)) & 0xff; - - ctrl_delay(); - - return v; -} - -u16 landisk_inw(unsigned long port) -{ - if (PXSEG(port)) - return ctrl_inw(port); - else if (is_pci_ioaddr(port)) - return ctrl_inw(pci_ioaddr(port)); - else - maybebadio(port); - - return 0; -} - -u32 landisk_inl(unsigned long port) -{ - if (PXSEG(port)) - return ctrl_inl(port); - else if (is_pci_ioaddr(port)) - return ctrl_inl(pci_ioaddr(port)); - else - maybebadio(port); - - return 0; -} - -void landisk_outb(u8 value, unsigned long port) -{ - if (PXSEG(port)) - ctrl_outb(value, port); - else if (is_pci_ioaddr(port)) - ctrl_outb(value, pci_ioaddr(port)); - else - ctrl_outw(value, port2adr(port)); -} - -void landisk_outb_p(u8 value, unsigned long port) -{ - if (PXSEG(port)) - ctrl_outb(value, port); - else if (is_pci_ioaddr(port)) - ctrl_outb(value, pci_ioaddr(port)); - else - ctrl_outw(value, port2adr(port)); - ctrl_delay(); -} - -void landisk_outw(u16 value, unsigned long port) -{ - if (PXSEG(port)) - ctrl_outw(value, port); - else if (is_pci_ioaddr(port)) - ctrl_outw(value, pci_ioaddr(port)); - else - maybebadio(port); -} - -void landisk_outl(u32 value, unsigned long port) -{ - if (PXSEG(port)) - ctrl_outl(value, port); - else if (is_pci_ioaddr(port)) - ctrl_outl(value, pci_ioaddr(port)); - else - maybebadio(port); -} - -void landisk_insb(unsigned long port, void *dst, unsigned long count) -{ - volatile u16 *p; - u8 *buf = dst; - - if (PXSEG(port)) { - while (count--) - *buf++ = *(volatile u8 *)port; - } else if (is_pci_ioaddr(port)) { - volatile u8 *bp = (volatile u8 *)pci_ioaddr(port); - - while (count--) - *buf++ = *bp; - } else { - p = (volatile u16 *)port2adr(port); - while (count--) - *buf++ = *p & 0xff; - } -} - -void landisk_insw(unsigned long port, void *dst, unsigned long count) -{ - volatile u16 *p; - u16 *buf = dst; - - if (PXSEG(port)) - p = (volatile u16 *)port; - else if (is_pci_ioaddr(port)) - p = (volatile u16 *)pci_ioaddr(port); - else - p = (volatile u16 *)port2adr(port); - while (count--) - *buf++ = *p; -} - -void landisk_insl(unsigned long port, void *dst, unsigned long count) -{ - u32 *buf = dst; - - if (is_pci_ioaddr(port)) { - volatile u32 *p = (volatile u32 *)pci_ioaddr(port); - - while (count--) - *buf++ = *p; - } else - maybebadio(port); -} - -void landisk_outsb(unsigned long port, const void *src, unsigned long count) -{ - volatile u16 *p; - const u8 *buf = src; - - if (PXSEG(port)) - while (count--) - ctrl_outb(*buf++, port); - else if (is_pci_ioaddr(port)) { - volatile u8 *bp = (volatile u8 *)pci_ioaddr(port); - - while (count--) - *bp = *buf++; - } else { - p = (volatile u16 *)port2adr(port); - while (count--) - *p = *buf++; - } -} - -void landisk_outsw(unsigned long port, const void *src, unsigned long count) -{ - volatile u16 *p; - const u16 *buf = src; - - if (PXSEG(port)) - p = (volatile u16 *)port; - else if (is_pci_ioaddr(port)) - p = (volatile u16 *)pci_ioaddr(port); - else - p = (volatile u16 *)port2adr(port); - - while (count--) - *p = *buf++; -} - -void landisk_outsl(unsigned long port, const void *src, unsigned long count) -{ - const u32 *buf = src; - - if (is_pci_ioaddr(port)) { - volatile u32 *p = (volatile u32 *)pci_ioaddr(port); - - while (count--) - *p = *buf++; - } else - maybebadio(port); -} - -void __iomem *landisk_ioport_map(unsigned long port, unsigned int size) -{ - if (PXSEG(port)) - return (void __iomem *)port; - else if (is_pci_ioaddr(port)) - return (void __iomem *)pci_ioaddr(port); - - return (void __iomem *)port2adr(port); -} diff --git a/arch/sh/boards/landisk/irq.c b/arch/sh/boards/landisk/irq.c index 3eba6d086d7f..258649491d44 100644 --- a/arch/sh/boards/landisk/irq.c +++ b/arch/sh/boards/landisk/irq.c @@ -1,18 +1,16 @@ /* * arch/sh/boards/landisk/irq.c * + * I-O DATA Device, Inc. LANDISK Support + * + * Copyright (C) 2005-2007 kogiidena + * * Copyright (C) 2001 Ian da Silva, Jeremy Siegel * Based largely on io_se.c. * - * I/O routine for I-O Data Device, Inc. LANDISK. - * - * Initial version only to support LAN access; some - * placeholder code from io_landisk.c left in with the - * expectation of later SuperIO and PCMCIA access. - */ -/* - * modified by kogiidena - * 2005.03.03 + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. */ #include #include @@ -20,71 +18,27 @@ #include #include -static void enable_landisk_irq(unsigned int irq); -static void disable_landisk_irq(unsigned int irq); - -/* shutdown is same as "disable" */ -#define shutdown_landisk_irq disable_landisk_irq - -static void ack_landisk_irq(unsigned int irq); -static void end_landisk_irq(unsigned int irq); - -static unsigned int startup_landisk_irq(unsigned int irq) -{ - enable_landisk_irq(irq); - return 0; /* never anything pending */ -} - static void disable_landisk_irq(unsigned int irq) { - unsigned char val; unsigned char mask = 0xff ^ (0x01 << (irq - 5)); - /* Set the priority in IPR to 0 */ - val = ctrl_inb(PA_IMASK); - val &= mask; - ctrl_outb(val, PA_IMASK); + ctrl_outb(ctrl_inb(PA_IMASK) & mask, PA_IMASK); } static void enable_landisk_irq(unsigned int irq) { - unsigned char val; unsigned char value = (0x01 << (irq - 5)); - /* Set priority in IPR back to original value */ - val = ctrl_inb(PA_IMASK); - val |= value; - ctrl_outb(val, PA_IMASK); -} - -static void ack_landisk_irq(unsigned int irq) -{ - disable_landisk_irq(irq); -} - -static void end_landisk_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - enable_landisk_irq(irq); + ctrl_outb(ctrl_inb(PA_IMASK) | value, PA_IMASK); } -static struct hw_interrupt_type landisk_irq_type = { - .typename = "LANDISK IRQ", - .startup = startup_landisk_irq, - .shutdown = shutdown_landisk_irq, - .enable = enable_landisk_irq, - .disable = disable_landisk_irq, - .ack = ack_landisk_irq, - .end = end_landisk_irq +static struct irq_chip landisk_irq_chip __read_mostly = { + .name = "LANDISK", + .mask = disable_landisk_irq, + .unmask = enable_landisk_irq, + .mask_ack = disable_landisk_irq, }; -static void make_landisk_irq(unsigned int irq) -{ - disable_irq_nosync(irq); - irq_desc[irq].chip = &landisk_irq_type; - disable_landisk_irq(irq); -} - /* * Initialize IRQ setting */ @@ -92,6 +46,11 @@ void __init init_landisk_IRQ(void) { int i; - for (i = 5; i < 14; i++) - make_landisk_irq(i); + for (i = 5; i < 14; i++) { + disable_irq_nosync(i); + set_irq_chip_and_handler_name(i, &landisk_irq_chip, + handle_level_irq, "level"); + enable_landisk_irq(i); + } + ctrl_outb(0x00, PA_PWRINT_CLR); } diff --git a/arch/sh/boards/landisk/landisk_pwb.c b/arch/sh/boards/landisk/landisk_pwb.c deleted file mode 100644 index 47a63c6617ed..000000000000 --- a/arch/sh/boards/landisk/landisk_pwb.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * arch/sh/boards/landisk/landisk_pwb.c -- driver for the Power control switch. - * - * This driver will also support the I-O DATA Device, Inc. LANDISK Board. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copylight (C) 2002 Atom Create Engineering Co., Ltd. - * - * LED control drive function added by kogiidena - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define SHUTDOWN_BTN_MINOR 1 /* Shutdown button device minor no. */ -#define LED_MINOR 21 /* LED minor no. */ -#define BTN_MINOR 22 /* BUTTON minor no. */ -#define GIO_MINOR 40 /* GIO minor no. */ - -static int openCnt; -static int openCntLED; -static int openCntGio; -static int openCntBtn; -static int landisk_btn; -static int landisk_btnctrlpid; -/* - * Functions prototypes - */ - -static int gio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg); - -static int swdrv_open(struct inode *inode, struct file *filp) -{ - int minor; - - minor = MINOR(inode->i_rdev); - filp->private_data = (void *)minor; - - if (minor == SHUTDOWN_BTN_MINOR) { - if (openCnt > 0) { - return -EALREADY; - } else { - openCnt++; - return 0; - } - } else if (minor == LED_MINOR) { - if (openCntLED > 0) { - return -EALREADY; - } else { - openCntLED++; - return 0; - } - } else if (minor == BTN_MINOR) { - if (openCntBtn > 0) { - return -EALREADY; - } else { - openCntBtn++; - return 0; - } - } else if (minor == GIO_MINOR) { - if (openCntGio > 0) { - return -EALREADY; - } else { - openCntGio++; - return 0; - } - } - return -ENOENT; - -} - -static int swdrv_close(struct inode *inode, struct file *filp) -{ - int minor; - - minor = MINOR(inode->i_rdev); - if (minor == SHUTDOWN_BTN_MINOR) { - openCnt--; - } else if (minor == LED_MINOR) { - openCntLED--; - } else if (minor == BTN_MINOR) { - openCntBtn--; - } else if (minor == GIO_MINOR) { - openCntGio--; - } - return 0; -} - -static int swdrv_read(struct file *filp, char *buff, size_t count, - loff_t * ppos) -{ - int minor; - minor = (int)(filp->private_data); - - if (!access_ok(VERIFY_WRITE, (void *)buff, count)) - return -EFAULT; - - if (minor == SHUTDOWN_BTN_MINOR) { - if (landisk_btn & 0x10) { - put_user(1, buff); - return 1; - } else { - return 0; - } - } - return 0; -} - -static int swdrv_write(struct file *filp, const char *buff, size_t count, - loff_t * ppos) -{ - int minor; - minor = (int)(filp->private_data); - - if (minor == SHUTDOWN_BTN_MINOR) { - return count; - } - return count; -} - -static irqreturn_t sw_interrupt(int irq, void *dev_id) -{ - landisk_btn = (0x0ff & (~ctrl_inb(PA_STATUS))); - disable_irq(IRQ_BUTTON); - disable_irq(IRQ_POWER); - ctrl_outb(0x00, PA_PWRINT_CLR); - - if (landisk_btnctrlpid != 0) { - kill_proc(landisk_btnctrlpid, SIGUSR1, 1); - landisk_btnctrlpid = 0; - } - - return IRQ_HANDLED; -} - -static const struct file_operations swdrv_fops = { - .read = swdrv_read, /* read */ - .write = swdrv_write, /* write */ - .open = swdrv_open, /* open */ - .release = swdrv_close, /* release */ - .ioctl = gio_ioctl, /* ioctl */ - -}; - -static char banner[] __initdata = - KERN_INFO "LANDISK and USL-5P Button, LED and GIO driver initialized\n"; - -int __init swdrv_init(void) -{ - int error; - - printk("%s", banner); - - openCnt = 0; - openCntLED = 0; - openCntBtn = 0; - openCntGio = 0; - landisk_btn = 0; - landisk_btnctrlpid = 0; - - if ((error = register_chrdev(SHUTDOWN_BTN_MAJOR, "swdrv", &swdrv_fops))) { - printk(KERN_ERR - "Button, LED and GIO driver:Couldn't register driver, error=%d\n", - error); - return 1; - } - - if (request_irq(IRQ_POWER, sw_interrupt, 0, "SHUTDOWNSWITCH", NULL)) { - printk(KERN_ERR "Unable to get IRQ 11.\n"); - return 1; - } - if (request_irq(IRQ_BUTTON, sw_interrupt, 0, "USL-5P BUTTON", NULL)) { - printk(KERN_ERR "Unable to get IRQ 12.\n"); - return 1; - } - ctrl_outb(0x00, PA_PWRINT_CLR); - - return 0; -} - -module_init(swdrv_init); - -/* - * gio driver - * - */ - -#include - -static int gio_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - int minor; - unsigned int data, mask; - static unsigned int addr = 0; - - minor = (int)(filp->private_data); - - /* access control */ - if (minor == GIO_MINOR) { - ; - } else if (minor == LED_MINOR) { - if (((cmd & 0x0ff) >= 9) && ((cmd & 0x0ff) < 20)) { - ; - } else { - return -EINVAL; - } - } else if (minor == BTN_MINOR) { - if (((cmd & 0x0ff) >= 20) && ((cmd & 0x0ff) < 30)) { - ; - } else { - return -EINVAL; - } - } else { - return -EINVAL; - } - - if (cmd & 0x01) { /* write */ - if (copy_from_user(&data, (int *)arg, sizeof(int))) { - return -EFAULT; - } - } - - switch (cmd) { - case GIODRV_IOCSGIOSETADDR: /* addres set */ - addr = data; - break; - - case GIODRV_IOCSGIODATA1: /* write byte */ - ctrl_outb((unsigned char)(0x0ff & data), addr); - break; - - case GIODRV_IOCSGIODATA2: /* write word */ - if (addr & 0x01) { - return -EFAULT; - } - ctrl_outw((unsigned short int)(0x0ffff & data), addr); - break; - - case GIODRV_IOCSGIODATA4: /* write long */ - if (addr & 0x03) { - return -EFAULT; - } - ctrl_outl(data, addr); - break; - - case GIODRV_IOCGGIODATA1: /* read byte */ - data = ctrl_inb(addr); - break; - - case GIODRV_IOCGGIODATA2: /* read word */ - if (addr & 0x01) { - return -EFAULT; - } - data = ctrl_inw(addr); - break; - - case GIODRV_IOCGGIODATA4: /* read long */ - if (addr & 0x03) { - return -EFAULT; - } - data = ctrl_inl(addr); - break; - case GIODRV_IOCSGIO_LED: /* write */ - mask = ((data & 0x00ffffff) << 8) - | ((data & 0x0000ffff) << 16) - | ((data & 0x000000ff) << 24); - landisk_ledparam = data & (~mask); - if (landisk_arch == 0) { /* arch == landisk */ - landisk_ledparam &= 0x03030303; - mask = (~(landisk_ledparam >> 22)) & 0x000c; - landisk_ledparam |= mask; - } else { /* arch == usl-5p */ - mask = (landisk_ledparam >> 24) & 0x0001; - landisk_ledparam |= mask; - landisk_ledparam &= 0x007f7f7f; - } - landisk_ledparam |= 0x80; - break; - case GIODRV_IOCGGIO_LED: /* read */ - data = landisk_ledparam; - if (landisk_arch == 0) { /* arch == landisk */ - data &= 0x03030303; - } else { /* arch == usl-5p */ - ; - } - data &= (~0x080); - break; - case GIODRV_IOCSGIO_BUZZER: /* write */ - landisk_buzzerparam = data; - landisk_ledparam |= 0x80; - break; - case GIODRV_IOCGGIO_LANDISK: /* read */ - data = landisk_arch & 0x01; - break; - case GIODRV_IOCGGIO_BTN: /* read */ - data = (0x0ff & ctrl_inb(PA_PWRINT_CLR)); - data <<= 8; - data |= (0x0ff & ctrl_inb(PA_IMASK)); - data <<= 8; - data |= (0x0ff & landisk_btn); - data <<= 8; - data |= (0x0ff & (~ctrl_inb(PA_STATUS))); - break; - case GIODRV_IOCSGIO_BTNPID: /* write */ - landisk_btnctrlpid = data; - landisk_btn = 0; - if (irq_desc[IRQ_BUTTON].depth) { - enable_irq(IRQ_BUTTON); - } - if (irq_desc[IRQ_POWER].depth) { - enable_irq(IRQ_POWER); - } - break; - case GIODRV_IOCGGIO_BTNPID: /* read */ - data = landisk_btnctrlpid; - break; - default: - return -EFAULT; - break; - } - - if ((cmd & 0x01) == 0) { /* read */ - if (copy_to_user((int *)arg, &data, sizeof(int))) { - return -EFAULT; - } - } - return 0; -} diff --git a/arch/sh/boards/landisk/psw.c b/arch/sh/boards/landisk/psw.c new file mode 100644 index 000000000000..5a9b70b5decb --- /dev/null +++ b/arch/sh/boards/landisk/psw.c @@ -0,0 +1,143 @@ +/* + * arch/sh/boards/landisk/psw.c + * + * push switch support for LANDISK and USL-5P + * + * Copyright (C) 2006-2007 Paul Mundt + * Copyright (C) 2007 kogiidena + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include + +static irqreturn_t psw_irq_handler(int irq, void *arg) +{ + struct platform_device *pdev = arg; + struct push_switch *psw = platform_get_drvdata(pdev); + struct push_switch_platform_info *psw_info = pdev->dev.platform_data; + unsigned int sw_value; + int ret = 0; + + sw_value = (0x0ff & (~ctrl_inb(PA_STATUS))); + + /* Nothing to do if there's no state change */ + if (psw->state) { + ret = 1; + goto out; + } + + /* Figure out who raised it */ + if (sw_value & (1 << psw_info->bit)) { + psw->state = 1; + mod_timer(&psw->debounce, jiffies + 50); + ret = 1; + } + +out: + /* Clear the switch IRQs */ + ctrl_outb(0x00, PA_PWRINT_CLR); + + return IRQ_RETVAL(ret); +} + +static struct resource psw_power_resources[] = { + [0] = { + .start = IRQ_POWER, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource psw_usl5p_resources[] = { + [0] = { + .start = IRQ_BUTTON, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct push_switch_platform_info psw_power_platform_data = { + .name = "psw_power", + .bit = 4, + .irq_flags = IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct push_switch_platform_info psw1_platform_data = { + .name = "psw1", + .bit = 0, + .irq_flags = IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct push_switch_platform_info psw2_platform_data = { + .name = "psw2", + .bit = 2, + .irq_flags = IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct push_switch_platform_info psw3_platform_data = { + .name = "psw3", + .bit = 1, + .irq_flags = IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct platform_device psw_power_switch_device = { + .name = "push-switch", + .id = 0, + .num_resources = ARRAY_SIZE(psw_power_resources), + .resource = psw_power_resources, + .dev = { + .platform_data = &psw_power_platform_data, + }, +}; + +static struct platform_device psw1_switch_device = { + .name = "push-switch", + .id = 1, + .num_resources = ARRAY_SIZE(psw_usl5p_resources), + .resource = psw_usl5p_resources, + .dev = { + .platform_data = &psw1_platform_data, + }, +}; + +static struct platform_device psw2_switch_device = { + .name = "push-switch", + .id = 2, + .num_resources = ARRAY_SIZE(psw_usl5p_resources), + .resource = psw_usl5p_resources, + .dev = { + .platform_data = &psw2_platform_data, + }, +}; + +static struct platform_device psw3_switch_device = { + .name = "push-switch", + .id = 3, + .num_resources = ARRAY_SIZE(psw_usl5p_resources), + .resource = psw_usl5p_resources, + .dev = { + .platform_data = &psw3_platform_data, + }, +}; + +static struct platform_device *psw_devices[] = { + &psw_power_switch_device, + &psw1_switch_device, + &psw2_switch_device, + &psw3_switch_device, +}; + +static int __init psw_init(void) +{ + return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices)); +} +module_init(psw_init); diff --git a/arch/sh/boards/landisk/rtc.c b/arch/sh/boards/landisk/rtc.c deleted file mode 100644 index 0a9a2a2ad05b..000000000000 --- a/arch/sh/boards/landisk/rtc.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * arch/sh/boards/landisk/rtc.c -- RTC support - * - * Copyright (C) 2000 Philipp Rumpf - * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka - */ -/* - * modifed by kogiidena - * 2005.09.16 - */ -#include -#include -#include -#include -#include -#include -#include -#include - -extern spinlock_t rtc_lock; - -extern void -rs5c313_set_cmos_time(unsigned int BCD_yr, unsigned int BCD_mon, - unsigned int BCD_day, unsigned int BCD_hr, - unsigned int BCD_min, unsigned int BCD_sec); - -extern unsigned long -rs5c313_get_cmos_time(unsigned int *BCD_yr, unsigned int *BCD_mon, - unsigned int *BCD_day, unsigned int *BCD_hr, - unsigned int *BCD_min, unsigned int *BCD_sec); - -void landisk_rtc_gettimeofday(struct timespec *tv) -{ - unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec; - unsigned long flags; - - spin_lock_irqsave(&rtc_lock, flags); - tv->tv_sec = rs5c313_get_cmos_time - (&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec); - tv->tv_nsec = 0; - spin_unlock_irqrestore(&rtc_lock, flags); -} - -int landisk_rtc_settimeofday(const time_t secs) -{ - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; - unsigned long flags; - unsigned long nowtime = secs; - unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec; - - spin_lock_irqsave(&rtc_lock, flags); - - rs5c313_get_cmos_time - (&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec); - cmos_minutes = BCD_min; - BCD_TO_BIN(cmos_minutes); - - /* - * since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; - - if (abs(real_minutes - cmos_minutes) < 30) { - BIN_TO_BCD(real_seconds); - BIN_TO_BCD(real_minutes); - rs5c313_set_cmos_time(BCD_yr, BCD_mon, BCD_day, BCD_hr, - real_minutes, real_seconds); - } else { - printk(KERN_WARNING - "set_rtc_time: can't update from %d to %d\n", - cmos_minutes, real_minutes); - retval = -1; - } - - spin_unlock_irqrestore(&rtc_lock, flags); - return retval; -} - -void landisk_time_init(void) -{ - rtc_sh_get_time = landisk_rtc_gettimeofday; - rtc_sh_set_time = landisk_rtc_settimeofday; -} diff --git a/arch/sh/boards/landisk/setup.c b/arch/sh/boards/landisk/setup.c index 122d69962637..a83a5d9587bb 100644 --- a/arch/sh/boards/landisk/setup.c +++ b/arch/sh/boards/landisk/setup.c @@ -1,144 +1,90 @@ /* * arch/sh/boards/landisk/setup.c * - * Copyright (C) 2000 Kazumoto Kojima - * Copyright (C) 2002 Paul Mundt - * * I-O DATA Device, Inc. LANDISK Support. * - * Modified for LANDISK by - * Atom Create Engineering Co., Ltd. 2002. - * - * modifed by kogiidena - * 2005.09.16 + * Copyright (C) 2000 Kazumoto Kojima + * Copyright (C) 2002 Paul Mundt + * Copylight (C) 2002 Atom Create Engineering Co., Ltd. + * Copyright (C) 2005-2007 kogiidena * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. */ #include +#include +#include #include #include #include -#include #include #include -void landisk_time_init(void); void init_landisk_IRQ(void); -int landisk_ledparam; -int landisk_buzzerparam; -int landisk_arch; - -/* cycle the led's in the clasic knightrider/sun pattern */ -static void heartbeat_landisk(void) -{ - static unsigned int cnt = 0, blink = 0x00, period = 25; - volatile u8 *p = (volatile u8 *)PA_LED; - char data; - - if ((landisk_ledparam & 0x080) == 0) - return; - - cnt += 1; - - if (cnt < period) - return; - - cnt = 0; - blink++; - - data = (blink & 0x01) ? (landisk_ledparam >> 16) : 0; - data |= (blink & 0x02) ? (landisk_ledparam >> 8) : 0; - data |= landisk_ledparam; - - /* buzzer */ - if (landisk_buzzerparam & 0x1) { - data |= 0x80; - } else { - data &= 0x7f; - } - *p = data; - - if (((landisk_ledparam & 0x007f7f00) == 0) && - (landisk_buzzerparam == 0)) - landisk_ledparam &= (~0x0080); - - landisk_buzzerparam >>= 1; -} - static void landisk_power_off(void) { ctrl_outb(0x01, PA_SHUTDOWN); } -static void check_usl5p(void) -{ - volatile u8 *p = (volatile u8 *)PA_LED; - u8 tmp1, tmp2; +static struct resource cf_ide_resources[3]; - tmp1 = *p; - *p = 0x40; - tmp2 = *p; - *p = tmp1; +static struct pata_platform_info pata_info = { + .ioport_shift = 1, +}; - landisk_arch = (tmp2 == 0x40); - if (landisk_arch == 1) { - /* arch == usl-5p */ - landisk_ledparam = 0x00000380; - landisk_ledparam |= (tmp1 & 0x07c); - } else { - /* arch == landisk */ - landisk_ledparam = 0x02000180; - landisk_ledparam |= 0x04; - } -} +static struct platform_device cf_ide_device = { + .name = "pata_platform", + .id = -1, + .num_resources = ARRAY_SIZE(cf_ide_resources), + .resource = cf_ide_resources, + .dev = { + .platform_data = &pata_info, + }, +}; -void *area5_io_base; -void *area6_io_base; +static struct platform_device *landisk_devices[] __initdata = { + &cf_ide_device, +}; -static int __init landisk_cf_init(void) +static int __init landisk_devices_setup(void) { pgprot_t prot; - unsigned long paddrbase, psize; + unsigned long paddrbase; + void *cf_ide_base; /* open I/O area window */ paddrbase = virt_to_phys((void *)PA_AREA5_IO); - psize = PAGE_SIZE; prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16); - area5_io_base = p3_ioremap(paddrbase, psize, prot.pgprot); - if (!area5_io_base) { + cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot); + if (!cf_ide_base) { printk("allocate_cf_area : can't open CF I/O window!\n"); return -ENOMEM; } - paddrbase = virt_to_phys((void *)PA_AREA6_IO); - psize = PAGE_SIZE; - prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16); - area6_io_base = p3_ioremap(paddrbase, psize, prot.pgprot); - if (!area6_io_base) { - printk("allocate_cf_area : can't open HDD I/O window!\n"); - return -ENOMEM; - } - - printk(KERN_INFO "Allocate Area5/6 success.\n"); - - /* XXX : do we need attribute and common-memory area also? */ - - return 0; + /* IDE cmd address : 0x1f0-0x1f7 and 0x3f6 */ + cf_ide_resources[0].start = (unsigned long)cf_ide_base + 0x40; + cf_ide_resources[0].end = (unsigned long)cf_ide_base + 0x40 + 0x0f; + cf_ide_resources[0].flags = IORESOURCE_IO; + cf_ide_resources[1].start = (unsigned long)cf_ide_base + 0x2c; + cf_ide_resources[1].end = (unsigned long)cf_ide_base + 0x2c + 0x03; + cf_ide_resources[1].flags = IORESOURCE_IO; + cf_ide_resources[2].start = IRQ_FATA; + cf_ide_resources[2].flags = IORESOURCE_IRQ; + + return platform_add_devices(landisk_devices, + ARRAY_SIZE(landisk_devices)); } +__initcall(landisk_devices_setup); + static void __init landisk_setup(char **cmdline_p) { - device_initcall(landisk_cf_init); - - landisk_buzzerparam = 0; - check_usl5p(); + /* LED ON */ + ctrl_outb(ctrl_inb(PA_LED) | 0x03, PA_LED); printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n"); - - board_time_init = landisk_time_init; pm_power_off = landisk_power_off; } @@ -148,29 +94,6 @@ static void __init landisk_setup(char **cmdline_p) struct sh_machine_vector mv_landisk __initmv = { .mv_name = "LANDISK", .mv_setup = landisk_setup, - .mv_nr_irqs = 72, - .mv_inb = landisk_inb, - .mv_inw = landisk_inw, - .mv_inl = landisk_inl, - .mv_outb = landisk_outb, - .mv_outw = landisk_outw, - .mv_outl = landisk_outl, - .mv_inb_p = landisk_inb_p, - .mv_inw_p = landisk_inw, - .mv_inl_p = landisk_inl, - .mv_outb_p = landisk_outb_p, - .mv_outw_p = landisk_outw, - .mv_outl_p = landisk_outl, - .mv_insb = landisk_insb, - .mv_insw = landisk_insw, - .mv_insl = landisk_insl, - .mv_outsb = landisk_outsb, - .mv_outsw = landisk_outsw, - .mv_outsl = landisk_outsl, - .mv_ioport_map = landisk_ioport_map, .mv_init_irq = init_landisk_IRQ, -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_landisk, -#endif }; ALIAS_MV(landisk) diff --git a/arch/sh/drivers/pci/ops-landisk.c b/arch/sh/drivers/pci/ops-landisk.c index d06030815a96..bff09ecf3419 100644 --- a/arch/sh/drivers/pci/ops-landisk.c +++ b/arch/sh/drivers/pci/ops-landisk.c @@ -17,8 +17,8 @@ static struct resource sh7751_io_resource = { .name = "SH7751 IO", - .start = 0x4000, - .end = 0x4000 + SH7751_PCI_IO_SIZE - 1, + .start = SH7751_PCI_IO_BASE, + .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, .flags = IORESOURCE_IO }; -- cgit v1.2.3-59-g8ed1b From c86c5a910451dd5a30e62a9e36d8e9b3c7a0c1d1 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Mon, 26 Mar 2007 14:27:43 +0900 Subject: sh: L-BOX RE2 support. This adds support for the L-BOX RE2 router. http://www.nttcom.co.jp/l-box/ L-BOX RE2 is a SH7751R-based router. It has CF, Cardbus, serial, and LAN x2. This is one of the very few SH boards that a general person can obtain now. The L-BOX shipped with a 2.4.28 kernel, this is a rewritten patch adding it to current git. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 6 + arch/sh/Makefile | 1 + arch/sh/boards/lboxre2/Makefile | 5 + arch/sh/boards/lboxre2/irq.c | 31 + arch/sh/boards/lboxre2/setup.c | 84 +++ arch/sh/configs/lboxre2_defconfig | 1271 ++++++++++++++++++++++++++++++++++ arch/sh/drivers/pci/Makefile | 1 + arch/sh/drivers/pci/fixups-lboxre2.c | 41 ++ arch/sh/drivers/pci/ops-lboxre2.c | 63 ++ arch/sh/drivers/pci/pci-sh7751.c | 2 +- include/asm-sh/lboxre2.h | 32 + 11 files changed, 1536 insertions(+), 1 deletion(-) create mode 100644 arch/sh/boards/lboxre2/Makefile create mode 100644 arch/sh/boards/lboxre2/irq.c create mode 100644 arch/sh/boards/lboxre2/setup.c create mode 100644 arch/sh/configs/lboxre2_defconfig create mode 100644 arch/sh/drivers/pci/fixups-lboxre2.c create mode 100644 arch/sh/drivers/pci/ops-lboxre2.c create mode 100644 include/asm-sh/lboxre2.h (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 9932d1aa8494..4b6948f41d3f 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -243,6 +243,12 @@ config SH_7619_SOLUTION_ENGINE help Select 7619 SolutionEngine if configuring for a Hitachi SH7619 evaluation board. + +config SH_LBOX_RE2 + bool "L-BOX RE2" + select CPU_SUBTYPE_SH7751R + help + Select L-BOX RE2 if configuring for the NTT COMWARE L-BOX RE2. config SH_UNKNOWN bool "BareCPU" diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 7eef74b1cb7b..b00ed904aa00 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -110,6 +110,7 @@ machdir-$(CONFIG_SH_TITAN) := titan machdir-$(CONFIG_SH_SHMIN) := shmin machdir-$(CONFIG_SH_7206_SOLUTION_ENGINE) := se/7206 machdir-$(CONFIG_SH_7619_SOLUTION_ENGINE) := se/7619 +machdir-$(CONFIG_SH_LBOX_RE2) := lboxre2 machdir-$(CONFIG_SH_UNKNOWN) := unknown incdir-y := $(notdir $(machdir-y)) diff --git a/arch/sh/boards/lboxre2/Makefile b/arch/sh/boards/lboxre2/Makefile new file mode 100644 index 000000000000..e9ed140c06f6 --- /dev/null +++ b/arch/sh/boards/lboxre2/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the L-BOX RE2 specific parts of the kernel +# Copyright (c) 2007 Nobuhiro Iwamatsu + +obj-y := setup.o irq.o diff --git a/arch/sh/boards/lboxre2/irq.c b/arch/sh/boards/lboxre2/irq.c new file mode 100644 index 000000000000..5a1c3bbe7b50 --- /dev/null +++ b/arch/sh/boards/lboxre2/irq.c @@ -0,0 +1,31 @@ +/* + * linux/arch/sh/boards/lboxre2/irq.c + * + * Copyright (C) 2007 Nobuhiro Iwamatsu + * + * NTT COMWARE L-BOX RE2 Support. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ +#include +#include +#include +#include +#include +#include + +/* + * Initialize IRQ setting + */ +void __init init_lboxre2_IRQ(void) +{ + make_imask_irq(IRQ_CF1); + make_imask_irq(IRQ_CF0); + make_imask_irq(IRQ_INTD); + make_imask_irq(IRQ_ETH1); + make_imask_irq(IRQ_ETH0); + make_imask_irq(IRQ_INTA); +} diff --git a/arch/sh/boards/lboxre2/setup.c b/arch/sh/boards/lboxre2/setup.c new file mode 100644 index 000000000000..fc3cba3f0606 --- /dev/null +++ b/arch/sh/boards/lboxre2/setup.c @@ -0,0 +1,84 @@ +/* + * linux/arch/sh/boards/lbox/setup.c + * + * Copyright (C) 2007 Nobuhiro Iwamatsu + * + * NTT COMWARE L-BOX RE2 Support + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ + +#include +#include +#include +#include +#include +#include + +static struct resource cf_ide_resources[] = { + [0] = { + .start = 0x1f0, + .end = 0x1f0 + 8 , + .flags = IORESOURCE_IO, + }, + [1] = { + .start = 0x1f0 + 0x206, + .end = 0x1f0 +8 + 0x206 + 8, + .flags = IORESOURCE_IO, + }, + [2] = { + .start = IRQ_CF0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cf_ide_device = { + .name = "pata_platform", + .id = -1, + .num_resources = ARRAY_SIZE(cf_ide_resources), + .resource = cf_ide_resources, +}; + +static struct platform_device *lboxre2_devices[] __initdata = { + &cf_ide_device, +}; + +static int __init lboxre2_devices_setup(void) +{ + u32 cf0_io_base; /* Boot CF base address */ + pgprot_t prot; + unsigned long paddrbase, psize; + + /* open I/O area window */ + paddrbase = virt_to_phys((void*)CONFIG_CF0_BASE_ADDR); + psize = PAGE_SIZE; + prot = PAGE_KERNEL_PCC( 1 , _PAGE_PCC_IO16); + cf0_io_base = (u32)p3_ioremap(paddrbase, psize, prot.pgprot); + if (!cf0_io_base) { + printk(KERN_ERR "%s : can't open CF I/O window!\n" , __func__ ); + return -ENOMEM; + } + + cf_ide_resources[0].start += cf0_io_base ; + cf_ide_resources[0].end += cf0_io_base ; + cf_ide_resources[1].start += cf0_io_base ; + cf_ide_resources[1].end += cf0_io_base ; + + return platform_add_devices(lboxre2_devices, + ARRAY_SIZE(lboxre2_devices)); + +} +device_initcall(lboxre2_devices_setup); + +/* + * The Machine Vector + */ +struct sh_machine_vector mv_lboxre2 __initmv = { + .mv_name = "L-BOX RE2", + .mv_nr_irqs = 72, + .mv_init_irq = init_lboxre2_IRQ, +}; +ALIAS_MV(lboxre2) diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig new file mode 100644 index 000000000000..be86414dcc87 --- /dev/null +++ b/arch/sh/configs/lboxre2_defconfig @@ -0,0 +1,1271 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.21-rc4 +# Sat Mar 24 22:04:27 2007 +# +CONFIG_SUPERH=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME is not set +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System type +# +# CONFIG_SH_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SOLUTION_ENGINE is not set +# CONFIG_SH_7300_SOLUTION_ENGINE is not set +# CONFIG_SH_7343_SOLUTION_ENGINE is not set +# CONFIG_SH_73180_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SYSTEMH is not set +# CONFIG_SH_HP6XX is not set +# CONFIG_SH_SATURN is not set +# CONFIG_SH_DREAMCAST is not set +# CONFIG_SH_MPC1211 is not set +# CONFIG_SH_SH03 is not set +# CONFIG_SH_SECUREEDGE5410 is not set +# CONFIG_SH_HS7751RVOIP is not set +# CONFIG_SH_7710VOIPGW is not set +# CONFIG_SH_RTS7751R2D is not set +# CONFIG_SH_HIGHLANDER is not set +# CONFIG_SH_EDOSK7705 is not set +# CONFIG_SH_SH4202_MICRODEV is not set +# CONFIG_SH_LANDISK is not set +# CONFIG_SH_TITAN is not set +# CONFIG_SH_SHMIN is not set +# CONFIG_SH_7206_SOLUTION_ENGINE is not set +# CONFIG_SH_7619_SOLUTION_ENGINE is not set +CONFIG_SH_LBOX_RE2=y +# CONFIG_SH_UNKNOWN is not set + +# +# Processor selection +# +CONFIG_CPU_SH4=y + +# +# SH-2 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7604 is not set +# CONFIG_CPU_SUBTYPE_SH7619 is not set + +# +# SH-2A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7206 is not set + +# +# SH-3 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7300 is not set +# CONFIG_CPU_SUBTYPE_SH7705 is not set +# CONFIG_CPU_SUBTYPE_SH7706 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7710 is not set + +# +# SH-4 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7750 is not set +# CONFIG_CPU_SUBTYPE_SH7091 is not set +# CONFIG_CPU_SUBTYPE_SH7750R is not set +# CONFIG_CPU_SUBTYPE_SH7750S is not set +CONFIG_CPU_SUBTYPE_SH7751=y +CONFIG_CPU_SUBTYPE_SH7751R=y +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_SH4_202 is not set + +# +# ST40 Processor Support +# +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +# CONFIG_CPU_SUBTYPE_ST40GX1 is not set + +# +# SH-4A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7770 is not set +# CONFIG_CPU_SUBTYPE_SH7780 is not set +# CONFIG_CPU_SUBTYPE_SH7785 is not set + +# +# SH4AL-DSP Processor Support +# +# CONFIG_CPU_SUBTYPE_SH73180 is not set +# CONFIG_CPU_SUBTYPE_SH7343 is not set +# CONFIG_CPU_SUBTYPE_SH7722 is not set + +# +# Memory management options +# +CONFIG_MMU=y +CONFIG_PAGE_OFFSET=0x80000000 +CONFIG_MEMORY_START=0x0c000000 +CONFIG_MEMORY_SIZE=0x04000000 +CONFIG_VSYSCALL=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 + +# +# Cache configuration +# +# CONFIG_SH_DIRECT_MAPPED is not set +# CONFIG_SH_WRITETHROUGH is not set +# CONFIG_SH_OCRAM is not set + +# +# Processor features +# +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_SH_FPU=y +# CONFIG_SH_DSP is not set +# CONFIG_SH_STORE_QUEUES is not set +CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_IPR_IRQ=y +CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_PTEA=y + +# +# Timer and clock configuration +# +CONFIG_SH_TMU=y +CONFIG_SH_TIMER_IRQ=16 +# CONFIG_NO_IDLE_HZ is not set +CONFIG_SH_PCLK_FREQ=40000000 + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# DMA support +# +# CONFIG_SH_DMA is not set + +# +# Companion Chips +# +# CONFIG_HD6446X_SERIES is not set + +# +# Additional SuperH Device Drivers +# +# CONFIG_HEARTBEAT is not set +# CONFIG_PUSH_SWITCH is not set + +# +# Kernel features +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_KEXEC=y +# CONFIG_SMP is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set + +# +# Boot options +# +CONFIG_ZERO_PAGE_OFFSET=0x00001000 +CONFIG_BOOT_LINK_OFFSET=0x00800000 +# CONFIG_UBC_WAKEUP is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttySC1,115200 root=/dev/sda1" + +# +# Bus options +# +CONFIG_ISA=y +CONFIG_PCI=y +CONFIG_SH_PCIDMA_NONCOHERENT=y +CONFIG_PCI_AUTO=y +CONFIG_PCI_AUTO_UPDATE_RESOURCES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=y +CONFIG_PCMCIA_DEBUG=y +CONFIG_PCMCIA=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_IOCTL=y +CONFIG_CARDBUS=y + +# +# PC-card bridges +# +CONFIG_YENTA=y +CONFIG_YENTA_O2=y +# CONFIG_YENTA_RICOH is not set +# CONFIG_YENTA_TI is not set +# CONFIG_YENTA_TOSHIBA is not set +# CONFIG_PD6729 is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +CONFIG_PCMCIA_PROBE=y +CONFIG_PCCARD_NONSTATIC=y + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_FLAT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options (EXPERIMENTAL) +# +# CONFIG_PM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_MULTIPLE_TABLES is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_NETLINK is not set +# CONFIG_NF_CONNTRACK_ENABLED is not set +# CONFIG_NETFILTER_XTABLES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set +# CONFIG_PNPACPI is not set + +# +# Block devices +# +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# Misc devices +# +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set + +# +# PCMCIA SCSI adapter support +# +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_FDOMAIN is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_PCMCIA_SYM53C500 is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PCMCIA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_QDI is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +# CONFIG_PATA_WINBOND_VLB is not set +CONFIG_PATA_PLATFORM=y + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_STNIC is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +CONFIG_NE2K_PCI=y +# CONFIG_8139CP is not set +CONFIG_8139TOO=y +CONFIG_8139TOO_PIO=y +CONFIG_8139TOO_TUNE_TWISTER=y +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_SC92031 is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +CONFIG_PCMCIA_PCNET=y +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_AXNET is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=2 +CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set + +# +# RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_SH is not set +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# Auxiliary Display support +# + +# +# Virtualization +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_SH_STANDARD_BIOS=y +# CONFIG_EARLY_SCIF_CONSOLE is not set +# CONFIG_EARLY_PRINTK is not set +# CONFIG_SH_KGDB is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index 8a7e70651939..b1391cb080d1 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -18,3 +18,4 @@ obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o obj-$(CONFIG_SH_HIGHLANDER) += ops-r7780rp.o fixups-r7780rp.o obj-$(CONFIG_SH_TITAN) += ops-titan.o obj-$(CONFIG_SH_LANDISK) += ops-landisk.o +obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-lboxre2.o diff --git a/arch/sh/drivers/pci/fixups-lboxre2.c b/arch/sh/drivers/pci/fixups-lboxre2.c new file mode 100644 index 000000000000..40b19bdfb891 --- /dev/null +++ b/arch/sh/drivers/pci/fixups-lboxre2.c @@ -0,0 +1,41 @@ +/* + * arch/sh/drivers/pci/fixups-lboxre2.c + * + * L-BOX RE2 PCI fixups + * + * Copyright (C) 2007 Nobuhiro Iwamatsu + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include "pci-sh4.h" + +#define PCIMCR_MRSET_OFF 0xBFFFFFFF +#define PCIMCR_RFSH_OFF 0xFFFFFFFB + +int pci_fixup_pcic(void) +{ + unsigned long bcr1, mcr; + + bcr1 = inl(SH7751_BCR1); + bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ + pci_write_reg(bcr1, SH4_PCIBCR1); + + /* Enable all interrupts, so we known what to fix */ + pci_write_reg(0x0000c3ff, SH4_PCIINTM); + pci_write_reg(0x0000380f, SH4_PCIAINTM); + pci_write_reg(0xfb900047, SH7751_PCICONF1); + pci_write_reg(0xab000001, SH7751_PCICONF4); + + mcr = inl(SH7751_MCR); + mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; + pci_write_reg(mcr, SH4_PCIMCR); + + pci_write_reg(0x0c000000, SH7751_PCICONF5); + pci_write_reg(0xd0000000, SH7751_PCICONF6); + pci_write_reg(0x0c000000, SH4_PCILAR0); + pci_write_reg(0x00000000, SH4_PCILAR1); + + return 0; +} diff --git a/arch/sh/drivers/pci/ops-lboxre2.c b/arch/sh/drivers/pci/ops-lboxre2.c new file mode 100644 index 000000000000..a13cb764b0b9 --- /dev/null +++ b/arch/sh/drivers/pci/ops-lboxre2.c @@ -0,0 +1,63 @@ +/* + * linux/arch/sh/drivers/pci/ops-lboxre2.c + * + * Copyright (C) 2007 Nobuhiro Iwamatsu + * + * PCI initialization for the NTT COMWARE L-BOX RE2 + */ +#include +#include +#include +#include +#include +#include +#include "pci-sh4.h" + +static char lboxre2_irq_tab[] __initdata = { + IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD, +}; + +int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +{ + return lboxre2_irq_tab[slot]; +} + +static struct resource sh7751_io_resource = { + .name = "SH7751_IO", + .start = SH7751_PCI_IO_BASE , + .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, + .flags = IORESOURCE_IO +}; + +static struct resource sh7751_mem_resource = { + .name = "SH7751_mem", + .start = SH7751_PCI_MEMORY_BASE, + .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM +}; + +extern struct pci_ops sh7751_pci_ops; + +struct pci_channel board_pci_channels[] = { + { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, + { NULL, NULL, NULL, 0, 0 }, +}; + +EXPORT_SYMBOL(board_pci_channels); + +static struct sh4_pci_address_map sh7751_pci_map = { + .window0 = { + .base = SH7751_CS3_BASE_ADDR, + .size = 0x04000000, + }, + .window1 = { + .base = 0x00000000, /* Unused */ + .size = 0x00000000, /* Unused */ + }, + .flags = SH4_PCIC_NO_RESET, +}; + +int __init pcibios_init_platform(void) +{ + return sh7751_pcic_init(&sh7751_pci_map); +} diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 9ddff760d3c6..f3ead58a9519 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -194,7 +194,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) * DMA interrupts... */ -#ifdef CONFIG_SH_RTS7751R2D +#if defined(CONFIG_SH_RTS7751R2D) || defined(CONFIG_SH_LBOX_RE2) pci_fixup_pcic(); #endif diff --git a/include/asm-sh/lboxre2.h b/include/asm-sh/lboxre2.h new file mode 100644 index 000000000000..65775668df93 --- /dev/null +++ b/include/asm-sh/lboxre2.h @@ -0,0 +1,32 @@ +#ifndef __ASM_SH_LBOXRE2_H +#define __ASM_SH_LBOXRE2_H + +/* + * linux/include/asm-sh/lbox.h + * + * Copyright (C) 2007 Nobuhiro Iwamatsu + * + * NTT COMWARE L-BOX RE2 support + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ + +#define CONFIG_CF0_BASE_ADDR 0xb4000000 /* Boot only */ +#define CONFIG_CF1_BASE_ADDR 0xb8000000 + +#define IRQ_CF1 9 /* CF1 */ +#define IRQ_CF0 10 /* CF0 */ +#define IRQ_INTD 11 /* INTD */ +#define IRQ_ETH1 12 /* Ether1 */ +#define IRQ_ETH0 13 /* Ether0 */ +#define IRQ_INTA 14 /* INTA */ + +void init_lboxre2_IRQ(void); + +#define __IO_PREFIX lboxre2 +#include + +#endif /* __ASM_SH_LBOXRE2_H */ -- cgit v1.2.3-59-g8ed1b From 9465a54fa4a9da628091c372baa84120f8304587 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Tue, 27 Mar 2007 18:13:51 +0900 Subject: sh: MS7712SE01 board support. Support the SH7712 (SH3-DSP) Solution Engine reference board. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt --- arch/sh/Kconfig.debug | 1 + arch/sh/boards/se/770x/io.c | 2 ++ arch/sh/boards/se/770x/irq.c | 27 ++++++++-------- arch/sh/boards/se/770x/setup.c | 4 ++- arch/sh/kernel/cpu/sh3/Makefile | 1 + arch/sh/kernel/cpu/sh3/probe.c | 3 ++ arch/sh/kernel/cpu/sh3/setup-sh7710.c | 60 +++++++++++++++++++++++++++++++++++ arch/sh/kernel/process.c | 3 +- arch/sh/kernel/setup.c | 1 + arch/sh/mm/Kconfig | 8 +++++ drivers/serial/sh-sci.c | 13 +++++++- drivers/serial/sh-sci.h | 43 ++++++++++++++++++------- include/asm-sh/cpu-sh3/mmu_context.h | 1 + include/asm-sh/processor.h | 2 +- include/asm-sh/se.h | 1 + 15 files changed, 142 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 931c620dbc24..be60def6f306 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -33,6 +33,7 @@ config EARLY_SCIF_CONSOLE_PORT default "0xffe00000" if CPU_SUBTYPE_SH7780 default "0xfffe9800" if CPU_SUBTYPE_SH7206 default "0xf8420000" if CPU_SUBTYPE_SH7619 + default "0xa4400000" if CPU_SUBTYPE_SH7712 default "0xffe80000" if CPU_SH4 config EARLY_PRINTK diff --git a/arch/sh/boards/se/770x/io.c b/arch/sh/boards/se/770x/io.c index 9941949331ab..c4550473d4c3 100644 --- a/arch/sh/boards/se/770x/io.c +++ b/arch/sh/boards/se/770x/io.c @@ -27,6 +27,8 @@ int sh_pcic_io_dummy; static inline volatile __u16 * port2adr(unsigned int port) { + if (port & 0xff000000) + return ( volatile __u16 *) port; if (port >= 0x2000) return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); else if (port >= 0x1000) diff --git a/arch/sh/boards/se/770x/irq.c b/arch/sh/boards/se/770x/irq.c index 307ca5da6232..59cdffa13964 100644 --- a/arch/sh/boards/se/770x/irq.c +++ b/arch/sh/boards/se/770x/irq.c @@ -55,6 +55,17 @@ void make_se770x_irq(struct ipr_data *table, unsigned int nr_irqs) } static struct ipr_data se770x_ipr_map[] = { + /* + * Super I/O (Just mimic PC): + * 1: keyboard + * 3: serial 0 + * 4: serial 1 + * 5: printer + * 6: floppy + * 8: rtc + * 12: mouse + * 14: ide0 + */ #if defined(CONFIG_CPU_SUBTYPE_SH7705) /* This is default value */ { 0xf-0x2, 0, 8, 0x2 , BCR_ILCRA}, @@ -81,8 +92,10 @@ static struct ipr_data se770x_ipr_map[] = { { 4, 0, 4, 0x0f- 4 ,BCR_ILCRC}, { 3, 0, 0, 0x0f- 3 ,BCR_ILCRC}, { 1, 0, 12, 0x0f- 1 ,BCR_ILCRD}, +#if defined(CONFIG_STNIC) /* ST NIC */ { 10, 0, 4, 0x0f-10 ,BCR_ILCRD}, /* LAN */ +#endif /* MRSHPC IRQs setting */ { 0, 0, 12, 0x0f- 0 ,BCR_ILCRE}, /* PCIRQ3 */ { 11, 0, 8, 0x0f-11 ,BCR_ILCRE}, /* PCIRQ2 */ @@ -100,18 +113,6 @@ static struct ipr_data se770x_ipr_map[] = { */ void __init init_se_IRQ(void) { - /* - * Super I/O (Just mimic PC): - * 1: keyboard - * 3: serial 0 - * 4: serial 1 - * 5: printer - * 6: floppy - * 8: rtc - * 12: mouse - * 14: ide0 - */ -#if defined(CONFIG_CPU_SUBTYPE_SH7705) /* Disable all interrupts */ ctrl_outw(0, BCR_ILCRA); ctrl_outw(0, BCR_ILCRB); @@ -120,6 +121,6 @@ void __init init_se_IRQ(void) ctrl_outw(0, BCR_ILCRE); ctrl_outw(0, BCR_ILCRF); ctrl_outw(0, BCR_ILCRG); -#endif + make_se770x_irq(se770x_ipr_map, ARRAY_SIZE(se770x_ipr_map)); } diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c index dab5510699a0..f1c7c8d9fdd2 100644 --- a/arch/sh/boards/se/770x/setup.c +++ b/arch/sh/boards/se/770x/setup.c @@ -117,7 +117,7 @@ static int __init se_devices_setup(void) { return platform_add_devices(se_devices, ARRAY_SIZE(se_devices)); } -__initcall(se_devices_setup); +device_initcall(se_devices_setup); /* * The Machine Vector @@ -133,6 +133,8 @@ struct sh_machine_vector mv_se __initmv = { .mv_nr_irqs = 61, #elif defined(CONFIG_CPU_SUBTYPE_SH7705) .mv_nr_irqs = 86, +#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) + .mv_nr_irqs = 104, #endif .mv_inb = se_inb, diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile index 83905e4e4387..09faa056cd43 100644 --- a/arch/sh/kernel/cpu/sh3/Makefile +++ b/arch/sh/kernel/cpu/sh3/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh7708.o obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh7709.o obj-$(CONFIG_CPU_SUBTYPE_SH7300) += setup-sh7300.o obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o +obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o # Primary on-chip clocks (common) clock-$(CONFIG_CPU_SH3) := clock-sh3.o diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c index 821b0ab7b528..647623b22edc 100644 --- a/arch/sh/kernel/cpu/sh3/probe.c +++ b/arch/sh/kernel/cpu/sh3/probe.c @@ -78,6 +78,9 @@ int __init detect_cpu_and_cache_system(void) #if defined(CONFIG_CPU_SUBTYPE_SH7710) current_cpu_data.type = CPU_SH7710; #endif +#if defined(CONFIG_CPU_SUBTYPE_SH7712) + current_cpu_data.type = CPU_SH7712; +#endif #if defined(CONFIG_CPU_SUBTYPE_SH7705) current_cpu_data.type = CPU_SH7705; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 895f99ee6a95..51760a7e7f1c 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -2,6 +2,7 @@ * SH7710 Setup * * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2007 Nobuhiro Iwamatsu * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -19,6 +20,12 @@ static struct plat_sci_port sci_platform_data[] = { .type = PORT_SCIF, .irqs = { 52, 53, 55, 54 }, }, { + .mapbase = 0xa4420000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 56, 57, 59, 58 }, + }, { + .flags = 0, } }; @@ -41,3 +48,56 @@ static int __init sh7710_devices_setup(void) ARRAY_SIZE(sh7710_devices)); } __initcall(sh7710_devices_setup); + +static struct ipr_data sh7710_ipr_map[] = { + /* IRQ, IPR-idx, shift, priority */ + { 16, 0, 12, 2 }, /* TMU0 TUNI*/ + { 17, 0, 8, 2 }, /* TMU1 TUNI */ + { 18, 0, 4, 2 }, /* TMU2 TUNI */ + { 27, 1, 12, 2 }, /* WDT ITI */ + { 20, 0, 0, 2 }, /* RTC ATI (alarm) */ + { 21, 0, 0, 2 }, /* RTC PRI (period) */ + { 22, 0, 0, 2 }, /* RTC CUI (carry) */ + { 48, 4, 12, 7 }, /* DMAC DMTE0 */ + { 49, 4, 12, 7 }, /* DMAC DMTE1 */ + { 50, 4, 12, 7 }, /* DMAC DMTE2 */ + { 51, 4, 12, 7 }, /* DMAC DMTE3 */ + { 52, 4, 8, 3 }, /* SCIF0 ERI */ + { 53, 4, 8, 3 }, /* SCIF0 RXI */ + { 54, 4, 8, 3 }, /* SCIF0 BRI */ + { 55, 4, 8, 3 }, /* SCIF0 TXI */ + { 56, 4, 4, 3 }, /* SCIF1 ERI */ + { 57, 4, 4, 3 }, /* SCIF1 RXI */ + { 58, 4, 4, 3 }, /* SCIF1 BRI */ + { 59, 4, 4, 3 }, /* SCIF1 TXI */ + { 76, 5, 8, 7 }, /* DMAC DMTE4 */ + { 77, 5, 8, 7 }, /* DMAC DMTE5 */ + { 80, 6, 12, 5 }, /* EDMAC EINT0 */ + { 81, 6, 8, 5 }, /* EDMAC EINT1 */ + { 82, 6, 4, 5 }, /* EDMAC EINT2 */ +}; + +static unsigned long ipr_offsets[] = { + 0xA414FEE2 /* 0: IPRA */ +, 0xA414FEE4 /* 1: IPRB */ +, 0xA4140016 /* 2: IPRC */ +, 0xA4140018 /* 3: IPRD */ +, 0xA414001A /* 4: IPRE */ +, 0xA4080000 /* 5: IPRF */ +, 0xA4080002 /* 6: IPRG */ +, 0xA4080004 /* 7: IPRH */ +, 0xA4080006 /* 8: IPRI */ +}; + +/* given the IPR index return the address of the IPR register */ +unsigned int map_ipridx_to_addr(int idx) +{ + if (idx >= ARRAY_SIZE(ipr_offsets)) + return 0; + return ipr_offsets[idx]; +} + +void __init init_IRQ_ipr() +{ + make_ipr_irq(sh7710_ipr_map, ARRAY_SIZE(sh7710_ipr_map)); +} diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index e7607366ac4e..286c80388bf5 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -299,7 +299,8 @@ static void ubc_set_tracing(int asid, unsigned long pc) ctrl_outl(0, UBC_BAMRA); if (current_cpu_data.type == CPU_SH7729 || - current_cpu_data.type == CPU_SH7710) { + current_cpu_data.type == CPU_SH7710 || + current_cpu_data.type == CPU_SH7712 ) { ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA); ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR); } else { diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index f96490419768..4d6d89115194 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -377,6 +377,7 @@ static const char *cpu_name[] = { [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706", [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708", [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710", + [CPU_SH7712] = "SH7712", [CPU_SH7729] = "SH7729", [CPU_SH7750] = "SH7750", [CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R", [CPU_SH7751] = "SH7751", [CPU_SH7751R] = "SH7751R", diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 6b0d28ac9241..3cac22f50e15 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -101,9 +101,17 @@ config CPU_SUBTYPE_SH7709 config CPU_SUBTYPE_SH7710 bool "Support SH7710 processor" select CPU_SH3 + select CPU_HAS_IPR_IRQ help Select SH7710 if you have a SH3-DSP SH7710 CPU. +config CPU_SUBTYPE_SH7712 + bool "Support SH7712 processor" + select CPU_SH3 + select CPU_HAS_IPR_IRQ + help + Select SH7712 if you have a SH3-DSP SH7712 CPU. + comment "SH-4 Processor Support" config CPU_SUBTYPE_SH7750 diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 8f387219287f..0a34fa9e0733 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -284,12 +284,23 @@ static void sci_init_pins_irda(struct uart_port *port, unsigned int cflag) #endif #if defined(SCIF_ONLY) || defined(SCI_AND_SCIF) -#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7710) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) /* SH7300 doesn't use RTS/CTS */ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) { sci_out(port, SCFCR, 0); } +#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) +static void sci_init_pins_scif(struct uart_port* port, unsigned int cflag) +{ + unsigned int fcr_val = 0; + + set_sh771x_scif_pfc(port); + if (cflag & CRTSCTS) { + fcr_val |= SCFCR_MCE; + } + sci_out(port, SCFCR, fcr_val); +} #elif defined(CONFIG_CPU_SH3) /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 854153a1d60a..fb04fb5f9843 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -73,9 +73,13 @@ # define SCPDR 0xA4050136 /* 16 bit SCIF */ # define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ # define SCIF_ONLY -#elif defined(CONFIG_CPU_SUBTYPE_SH7710) +#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) # define SCSPTR0 0xA4400000 /* 16 bit SCIF */ -# define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ +# define SCI_NPORTS 2 +# define SCIF_ORER 0x0001 /* overrun error bit */ +# define PACR 0xa4050100 +# define PBCR 0xa4050102 +# define SCSCR_INIT(port) 0x3B # define SCIF_ONLY #elif defined(CONFIG_CPU_SUBTYPE_SH73180) # define SCPDR 0xA4050138 /* 16 bit SCIF */ @@ -346,9 +350,15 @@ } #ifdef CONFIG_CPU_SH3 -#if defined(CONFIG_CPU_SUBTYPE_SH7300) || \ - defined(CONFIG_CPU_SUBTYPE_SH7705) || \ - defined(CONFIG_CPU_SUBTYPE_SH7710) +#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) +#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ + sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ + h8_sci_offset, h8_sci_size) \ + CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size) +#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ + CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) +#elif defined(CONFIG_CPU_SUBTYPE_SH7300) || \ + defined(CONFIG_CPU_SUBTYPE_SH7705) #define SCIF_FNS(name, scif_offset, scif_size) \ CPU_SCIF_FNS(name, scif_offset, scif_size) #else @@ -375,8 +385,8 @@ #endif #if defined(CONFIG_CPU_SUBTYPE_SH7300) || \ - defined(CONFIG_CPU_SUBTYPE_SH7705) || \ - defined(CONFIG_CPU_SUBTYPE_SH7710) + defined(CONFIG_CPU_SUBTYPE_SH7705) + SCIF_FNS(SCSMR, 0x00, 16) SCIF_FNS(SCBRR, 0x04, 8) SCIF_FNS(SCSCR, 0x08, 16) @@ -486,13 +496,24 @@ static inline int sci_rxd_in(struct uart_port *port) return ctrl_inb(SCPDR)&0x10 ? 1 : 0; /* SCIF */ return 1; } -#elif defined(CONFIG_CPU_SUBTYPE_SH7710) +#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) static inline int sci_rxd_in(struct uart_port *port) { - if (port->mapbase == SCSPTR0) - return ctrl_inw(SCSPTR0 + 0x10) & 0x01 ? 1 : 0; - return 1; + return sci_in(port,SCxSR)&0x0010 ? 1 : 0; +} +static inline void set_sh771x_scif_pfc(struct uart_port *port) +{ + if (port->mapbase == 0xA4400000){ + ctrl_outw(ctrl_inw(PACR)&0xffc0,PACR); + ctrl_outw(ctrl_inw(PBCR)&0x0fff,PBCR); + return; + } + if (port->mapbase == 0xA4410000){ + ctrl_outw(ctrl_inw(PBCR)&0xf003,PBCR); + return; + } } + #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ defined(CONFIG_CPU_SUBTYPE_SH7751) || \ defined(CONFIG_CPU_SUBTYPE_SH4_202) diff --git a/include/asm-sh/cpu-sh3/mmu_context.h b/include/asm-sh/cpu-sh3/mmu_context.h index bccb7ddb438b..4704e86dff5b 100644 --- a/include/asm-sh/cpu-sh3/mmu_context.h +++ b/include/asm-sh/cpu-sh3/mmu_context.h @@ -32,6 +32,7 @@ defined(CONFIG_CPU_SUBTYPE_SH7706) || \ defined(CONFIG_CPU_SUBTYPE_SH7300) || \ defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7712) || \ defined(CONFIG_CPU_SUBTYPE_SH7710) #define INTEVT 0xa4000000 /* INTEVTE2(0xa4000000) */ #else diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index 3e46a7afe764..d42f68e724fa 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h @@ -44,7 +44,7 @@ enum cpu_type { /* SH-3 types */ CPU_SH7705, CPU_SH7706, CPU_SH7707, CPU_SH7708, CPU_SH7708S, CPU_SH7708R, - CPU_SH7709, CPU_SH7709A, CPU_SH7710, + CPU_SH7709, CPU_SH7709A, CPU_SH7710, CPU_SH7712, CPU_SH7729, CPU_SH7300, /* SH-4 types */ diff --git a/include/asm-sh/se.h b/include/asm-sh/se.h index a1832154a3aa..eeaf5c9124cc 100644 --- a/include/asm-sh/se.h +++ b/include/asm-sh/se.h @@ -73,6 +73,7 @@ #else #define IRQ_STNIC 10 #endif +#define IRQ_CFCARD 7 #define __IO_PREFIX se #include -- cgit v1.2.3-59-g8ed1b From 759ab068c4d4216c4ad247bfa851601dfb6500dc Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Wed, 28 Mar 2007 15:04:05 +0900 Subject: sh: Add defconfig for se7712. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt --- arch/sh/configs/se7712_defconfig | 1088 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 1088 insertions(+) create mode 100644 arch/sh/configs/se7712_defconfig (limited to 'arch') diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig new file mode 100644 index 000000000000..a5e37dbc5353 --- /dev/null +++ b/arch/sh/configs/se7712_defconfig @@ -0,0 +1,1088 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.21-rc4 +# Wed Mar 28 10:19:02 2007 +# +CONFIG_SUPERH=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME is not set +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +# CONFIG_BUG is not set +CONFIG_ELF_CORE=y +# CONFIG_BASE_FULL is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y +# CONFIG_SHMEM is not set +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=1 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" + +# +# System type +# +CONFIG_SOLUTION_ENGINE=y +CONFIG_SH_SOLUTION_ENGINE=y +# CONFIG_SH_7751_SOLUTION_ENGINE is not set +# CONFIG_SH_7300_SOLUTION_ENGINE is not set +# CONFIG_SH_7343_SOLUTION_ENGINE is not set +# CONFIG_SH_73180_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SYSTEMH is not set +# CONFIG_SH_HP6XX is not set +# CONFIG_SH_SATURN is not set +# CONFIG_SH_DREAMCAST is not set +# CONFIG_SH_MPC1211 is not set +# CONFIG_SH_SH03 is not set +# CONFIG_SH_SECUREEDGE5410 is not set +# CONFIG_SH_HS7751RVOIP is not set +# CONFIG_SH_7710VOIPGW is not set +# CONFIG_SH_RTS7751R2D is not set +# CONFIG_SH_HIGHLANDER is not set +# CONFIG_SH_EDOSK7705 is not set +# CONFIG_SH_SH4202_MICRODEV is not set +# CONFIG_SH_LANDISK is not set +# CONFIG_SH_TITAN is not set +# CONFIG_SH_SHMIN is not set +# CONFIG_SH_7206_SOLUTION_ENGINE is not set +# CONFIG_SH_7619_SOLUTION_ENGINE is not set +# CONFIG_SH_LBOX_RE2 is not set +# CONFIG_SH_UNKNOWN is not set + +# +# Processor selection +# +CONFIG_CPU_SH3=y + +# +# SH-2 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7604 is not set +# CONFIG_CPU_SUBTYPE_SH7619 is not set + +# +# SH-2A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7206 is not set + +# +# SH-3 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7300 is not set +# CONFIG_CPU_SUBTYPE_SH7705 is not set +# CONFIG_CPU_SUBTYPE_SH7706 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7710 is not set +CONFIG_CPU_SUBTYPE_SH7712=y + +# +# SH-4 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7750 is not set +# CONFIG_CPU_SUBTYPE_SH7091 is not set +# CONFIG_CPU_SUBTYPE_SH7750R is not set +# CONFIG_CPU_SUBTYPE_SH7750S is not set +# CONFIG_CPU_SUBTYPE_SH7751 is not set +# CONFIG_CPU_SUBTYPE_SH7751R is not set +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_SH4_202 is not set + +# +# ST40 Processor Support +# +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +# CONFIG_CPU_SUBTYPE_ST40GX1 is not set + +# +# SH-4A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7770 is not set +# CONFIG_CPU_SUBTYPE_SH7780 is not set +# CONFIG_CPU_SUBTYPE_SH7785 is not set + +# +# SH4AL-DSP Processor Support +# +# CONFIG_CPU_SUBTYPE_SH73180 is not set +# CONFIG_CPU_SUBTYPE_SH7343 is not set +# CONFIG_CPU_SUBTYPE_SH7722 is not set + +# +# Memory management options +# +CONFIG_MMU=y +CONFIG_PAGE_OFFSET=0x80000000 +CONFIG_MEMORY_START=0x0c000000 +CONFIG_MEMORY_SIZE=0x02000000 +CONFIG_VSYSCALL=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 + +# +# Cache configuration +# +# CONFIG_SH_DIRECT_MAPPED is not set +# CONFIG_SH_WRITETHROUGH is not set +# CONFIG_SH_OCRAM is not set +CONFIG_CF_ENABLER=y +# CONFIG_CF_AREA5 is not set +CONFIG_CF_AREA6=y +CONFIG_CF_BASE_ADDR=0xb8000000 + +# +# Processor features +# +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set +# CONFIG_SH_FPU_EMU is not set +# CONFIG_SH_DSP is not set +# CONFIG_SH_ADC is not set +CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_IPR_IRQ=y +CONFIG_CPU_HAS_SR_RB=y + +# +# Timer and clock configuration +# +CONFIG_SH_TMU=y +CONFIG_SH_TIMER_IRQ=16 +# CONFIG_NO_IDLE_HZ is not set +CONFIG_SH_PCLK_FREQ=33333333 + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# DMA support +# +# CONFIG_SH_DMA is not set + +# +# Companion Chips +# +# CONFIG_HD6446X_SERIES is not set + +# +# Additional SuperH Device Drivers +# +CONFIG_HEARTBEAT=y +# CONFIG_PUSH_SWITCH is not set + +# +# Kernel features +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +# CONFIG_KEXEC is not set +# CONFIG_SMP is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set + +# +# Boot options +# +CONFIG_ZERO_PAGE_OFFSET=0x00001000 +CONFIG_BOOT_LINK_OFFSET=0x00800000 +# CONFIG_UBC_WAKEUP is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1" + +# +# Bus options +# +# CONFIG_PCI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_FLAT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options (EXPERIMENTAL) +# +# CONFIG_PM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +CONFIG_INET_XFRM_TUNNEL=y +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_CLK_JIFFIES=y +# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set +# CONFIG_NET_SCH_CLK_CPU is not set + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=y +CONFIG_NET_SCH_HTB=y +CONFIG_NET_SCH_HFSC=y +CONFIG_NET_SCH_PRIO=y +CONFIG_NET_SCH_RED=y +CONFIG_NET_SCH_SFQ=y +CONFIG_NET_SCH_TEQL=y +CONFIG_NET_SCH_TBF=y +CONFIG_NET_SCH_GRED=y +CONFIG_NET_SCH_DSMARK=y +CONFIG_NET_SCH_NETEM=y +CONFIG_NET_SCH_INGRESS=y + +# +# Classification +# +CONFIG_NET_CLS=y +# CONFIG_NET_CLS_BASIC is not set +CONFIG_NET_CLS_TCINDEX=y +CONFIG_NET_CLS_ROUTE4=y +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=y +# CONFIG_NET_CLS_U32 is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +# CONFIG_NET_CLS_POLICE is not set +CONFIG_NET_CLS_IND=y +CONFIG_NET_ESTIMATOR=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set +CONFIG_FIB_RULES=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# Misc devices +# + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_PATA_PLATFORM=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=2 +CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=m +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_TIMER is not set +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set + +# +# InfiniBand support +# + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# Auxiliary Display support +# + +# +# Virtualization +# + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +# CONFIG_FORCED_INLINING is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_SH_STANDARD_BIOS is not set +# CONFIG_EARLY_SCIF_CONSOLE is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_4KSTACKS is not set +# CONFIG_SH_KGDB is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y -- cgit v1.2.3-59-g8ed1b From 01066625e9ae39742c92e21163f7f2a818e02762 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 28 Mar 2007 16:38:13 +0900 Subject: sh: bootmem tidying for discontig/sparsemem preparation. This reworks some of the node 0 bootmem initialization in preparation for discontigmem and sparsemem support. ARCH_POPULATES_NODE_MAP is switched to as a result of this. Signed-off-by: Paul Mundt --- arch/sh/kernel/setup.c | 164 ++++++++++++++++++++--------------- arch/sh/mm/Kconfig | 11 +++ arch/sh/mm/init.c | 197 ++++++++++++++++++++----------------------- include/asm-sh/mmu_context.h | 6 +- include/asm-sh/page.h | 10 +-- 5 files changed, 207 insertions(+), 181 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 4d6d89115194..60cc2161438f 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -4,7 +4,7 @@ * This file handles the architecture-dependent parts of initialization * * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2002 - 2006 Paul Mundt + * Copyright (C) 2002 - 2007 Paul Mundt */ #include #include @@ -15,15 +15,18 @@ #include #include #include +#include #include #include #include +#include #include #include #include #include #include #include +#include extern void * __rd_start, * __rd_end; @@ -202,53 +205,33 @@ static int __init sh_mv_setup(char **cmdline_p) return 0; } -void __init setup_arch(char **cmdline_p) +/* + * Register fully available low RAM pages with the bootmem allocator. + */ +static void __init register_bootmem_low_pages(void) { - unsigned long bootmap_size; - unsigned long start_pfn, max_pfn, max_low_pfn; - -#ifdef CONFIG_CMDLINE_BOOL - strcpy(COMMAND_LINE, CONFIG_CMDLINE); -#endif - - ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); - -#ifdef CONFIG_BLK_DEV_RAM - rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; - rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0); - rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0); -#endif - - if (!MOUNT_ROOT_RDONLY) - root_mountflags &= ~MS_RDONLY; - init_mm.start_code = (unsigned long) _text; - init_mm.end_code = (unsigned long) _etext; - init_mm.end_data = (unsigned long) _edata; - init_mm.brk = (unsigned long) _end; - - code_resource.start = (unsigned long)virt_to_phys(_text); - code_resource.end = (unsigned long)virt_to_phys(_etext)-1; - data_resource.start = (unsigned long)virt_to_phys(_etext); - data_resource.end = (unsigned long)virt_to_phys(_edata)-1; - - sh_mv_setup(cmdline_p); - + unsigned long curr_pfn, last_pfn, pages; /* - * Find the highest page frame number we have available + * We are rounding up the start address of usable memory: */ - max_pfn = PFN_DOWN(__pa(memory_end)); + curr_pfn = PFN_UP(__MEMORY_START); /* - * Determine low and high memory ranges: + * ... and at the end of the usable range downwards: */ - max_low_pfn = max_pfn; + last_pfn = PFN_DOWN(__pa(memory_end)); - /* - * Partially used pages are not usable - thus - * we are rounding upwards: - */ - start_pfn = PFN_UP(__pa(_end)); + if (last_pfn > max_low_pfn) + last_pfn = max_low_pfn; + + pages = last_pfn - curr_pfn; + free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages)); +} + +void __init setup_bootmem_allocator(unsigned long start_pfn) +{ + unsigned long bootmap_size; /* * Find a proper area for the bootmem bitmap. After this @@ -256,31 +239,11 @@ void __init setup_arch(char **cmdline_p) * is intact) must be done via bootmem_alloc(). */ bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, - __MEMORY_START>>PAGE_SHIFT, - max_low_pfn); - /* - * Register fully available low RAM pages with the bootmem allocator. - */ - { - unsigned long curr_pfn, last_pfn, pages; - - /* - * We are rounding up the start address of usable memory: - */ - curr_pfn = PFN_UP(__MEMORY_START); - /* - * ... and at the end of the usable range downwards: - */ - last_pfn = PFN_DOWN(__pa(memory_end)); + min_low_pfn, max_low_pfn); - if (last_pfn > max_low_pfn) - last_pfn = max_low_pfn; - - pages = last_pfn - curr_pfn; - free_bootmem_node(NODE_DATA(0), PFN_PHYS(curr_pfn), - PFN_PHYS(pages)); - } + register_bootmem_low_pages(); + node_set_online(0); /* * Reserve the kernel text and @@ -289,14 +252,14 @@ void __init setup_arch(char **cmdline_p) * case of us accidentally initializing the bootmem allocator with * an invalid RAM area. */ - reserve_bootmem_node(NODE_DATA(0), __MEMORY_START+PAGE_SIZE, + reserve_bootmem(__MEMORY_START+PAGE_SIZE, (PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START); /* * reserve physical page 0 - it's a special BIOS page on many boxes, * enabling clean reboots, SMP operation, laptop functions. */ - reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE); + reserve_bootmem(__MEMORY_START, PAGE_SIZE); #ifdef CONFIG_BLK_DEV_INITRD ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); @@ -310,8 +273,8 @@ void __init setup_arch(char **cmdline_p) if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { - reserve_bootmem_node(NODE_DATA(0), INITRD_START + - __MEMORY_START, INITRD_SIZE); + reserve_bootmem(INITRD_START + __MEMORY_START, + INITRD_SIZE); initrd_start = INITRD_START + PAGE_OFFSET + __MEMORY_START; initrd_end = initrd_start + INITRD_SIZE; @@ -324,6 +287,71 @@ void __init setup_arch(char **cmdline_p) } } #endif +} + +#ifndef CONFIG_NEED_MULTIPLE_NODES +static void __init setup_memory(void) +{ + unsigned long start_pfn; + + /* + * Partially used pages are not usable - thus + * we are rounding upwards: + */ + start_pfn = PFN_UP(__pa(_end)); + setup_bootmem_allocator(start_pfn); +} +#else +extern void __init setup_memory(void); +#endif + +void __init setup_arch(char **cmdline_p) +{ + enable_mmu(); + +#ifdef CONFIG_CMDLINE_BOOL + strcpy(COMMAND_LINE, CONFIG_CMDLINE); +#endif + + ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); + +#ifdef CONFIG_BLK_DEV_RAM + rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; + rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0); + rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0); +#endif + + if (!MOUNT_ROOT_RDONLY) + root_mountflags &= ~MS_RDONLY; + init_mm.start_code = (unsigned long) _text; + init_mm.end_code = (unsigned long) _etext; + init_mm.end_data = (unsigned long) _edata; + init_mm.brk = (unsigned long) _end; + + code_resource.start = virt_to_phys(_text); + code_resource.end = virt_to_phys(_etext)-1; + data_resource.start = virt_to_phys(_etext); + data_resource.end = virt_to_phys(_edata)-1; + + parse_early_param(); + + sh_mv_setup(cmdline_p); + + /* + * Find the highest page frame number we have available + */ + max_pfn = PFN_DOWN(__pa(memory_end)); + + /* + * Determine low and high memory ranges: + */ + max_low_pfn = max_pfn; + min_low_pfn = __MEMORY_START >> PAGE_SHIFT; + + nodes_clear(node_online_map); + setup_memory(); + paging_init(); + sparse_init(); #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; @@ -332,8 +360,6 @@ void __init setup_arch(char **cmdline_p) /* Perform the machine specific initialisation */ if (likely(sh_mv.mv_setup)) sh_mv.mv_setup(cmdline_p); - - paging_init(); } struct sh_machine_vector* __init get_mv_byname(const char* name) diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 3cac22f50e15..5359f3dff93c 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -291,6 +291,17 @@ config VSYSCALL For systems with an MMU that can afford to give up a page, (the default value) say Y. +config NODES_SHIFT + int + default "1" + depends on NEED_MULTIPLE_NODES + +config ARCH_FLATMEM_ENABLE + def_bool y + +config ARCH_POPULATES_NODE_MAP + def_bool y + choice prompt "Kernel page size" default PAGE_SIZE_4KB diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index ae957a932375..4d030988b368 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -1,37 +1,20 @@ -/* $Id: init.c,v 1.19 2004/02/21 04:42:16 kkojima Exp $ - * - * linux/arch/sh/mm/init.c +/* + * linux/arch/sh/mm/init.c * * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2002, 2004 Paul Mundt + * Copyright (C) 2002 - 2007 Paul Mundt * * Based on linux/arch/i386/mm/init.c: * Copyright (C) 1995 Linus Torvalds */ - -#include -#include -#include -#include -#include -#include -#include -#include #include #include -#include #include -#include #include -#include #include -#include -#include -#include -#include -#include +#include +#include #include -#include #include #include #include @@ -39,37 +22,51 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); pgd_t swapper_pg_dir[PTRS_PER_PGD]; -#ifdef CONFIG_MMU -/* It'd be good if these lines were in the standard header file. */ -#define START_PFN (NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT) -#define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn) -#endif - void (*copy_page)(void *from, void *to); void (*clear_page)(void *to); void show_mem(void) { - int i, total = 0, reserved = 0; - int shared = 0, cached = 0; + int total = 0, reserved = 0, free = 0; + int shared = 0, cached = 0, slab = 0; + pg_data_t *pgdat; printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); - i = max_mapnr; - while (i-- > 0) { - total++; - if (PageReserved(mem_map+i)) - reserved++; - else if (PageSwapCache(mem_map+i)) - cached++; - else if (page_count(mem_map+i)) - shared += page_count(mem_map+i) - 1; + + for_each_online_pgdat(pgdat) { + struct page *page, *end; + unsigned long flags; + + pgdat_resize_lock(pgdat, &flags); + page = pgdat->node_mem_map; + end = page + pgdat->node_spanned_pages; + + do { + total++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (PageSlab(page)) + slab++; + else if (!page_count(page)) + free++; + else + shared += page_count(page) - 1; + page++; + } while (page < end); + + pgdat_resize_unlock(pgdat, &flags); } - printk("%d pages of RAM\n",total); - printk("%d reserved pages\n",reserved); - printk("%d pages shared\n",shared); - printk("%d pages swap cached\n",cached); + + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + printk("%d pages of RAM\n", total); + printk("%d free pages\n", free); + printk("%d reserved pages\n", reserved); + printk("%d slab pages\n", slab); + printk("%d pages shared\n", shared); + printk("%d pages swap cached\n", cached); } #ifdef CONFIG_MMU @@ -147,52 +144,38 @@ extern char __init_begin, __init_end; */ void __init paging_init(void) { - unsigned long zones_size[MAX_NR_ZONES] = { 0, }; + int nid; - /* - * Setup some defaults for the zone sizes.. these should be safe - * regardless of distcontiguous memory or MMU settings. - */ - zones_size[ZONE_NORMAL] = __MEMORY_SIZE >> PAGE_SHIFT; -#ifdef CONFIG_HIGHMEM - zones_size[ZONE_HIGHMEM] = 0 >> PAGE_SHIFT; -#endif - -#ifdef CONFIG_MMU - /* - * If we have an MMU, and want to be using it .. we need to adjust - * the zone sizes accordingly, in addition to turning it on. - */ - { - /* We don't need to map the kernel through the TLB, as - * it is permanatly mapped using P1. So clear the - * entire pgd. */ - memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir)); - - /* Turn on the MMU */ - enable_mmu(); - zones_size[ZONE_NORMAL] = MAX_LOW_PFN - START_PFN; - } + /* We don't need to map the kernel through the TLB, as + * it is permanatly mapped using P1. So clear the + * entire pgd. */ + memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir)); /* Set an initial value for the MMU.TTB so we don't have to * check for a null value. */ set_TTB(swapper_pg_dir); -#elif defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4) - /* - * If we don't have CONFIG_MMU set and the processor in question - * still has an MMU, care needs to be taken to make sure it doesn't - * stay on.. Since the boot loader could have potentially already - * turned it on, and we clearly don't want it, we simply turn it off. - * - * We don't need to do anything special for the zone sizes, since the - * default values that were already configured up above should be - * satisfactory. - */ - disable_mmu(); -#endif - NODE_DATA(0)->node_mem_map = NULL; - free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0); + for_each_online_node(nid) { + pg_data_t *pgdat = NODE_DATA(nid); + unsigned long max_zone_pfns[MAX_NR_ZONES]; + unsigned long low, start_pfn; + + memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); + + start_pfn = pgdat->bdata->node_boot_start >> PAGE_SHIFT; + low = pgdat->bdata->node_low_pfn; + + max_zone_pfns[ZONE_NORMAL] = low; + add_active_range(nid, start_pfn, low); + + printk("Node %u: start_pfn = 0x%lx, low = 0x%lx\n", + nid, start_pfn, low); + + free_area_init_nodes(max_zone_pfns); + + printk("Node %u: mem_map starts at %p\n", + pgdat->node_id, pgdat->node_mem_map); + } } static struct kcore_list kcore_mem, kcore_vmalloc; @@ -200,18 +183,33 @@ static struct kcore_list kcore_mem, kcore_vmalloc; void __init mem_init(void) { int codesize, reservedpages, datasize, initsize; - int tmp; - extern unsigned long memory_start; + int nid; -#ifdef CONFIG_MMU - high_memory = (void *)__va(MAX_LOW_PFN * PAGE_SIZE); -#else - extern unsigned long memory_end; + reservedpages = 0; - high_memory = (void *)(memory_end & PAGE_MASK); -#endif + for_each_online_node(nid) { + pg_data_t *pgdat = NODE_DATA(nid); + unsigned long node_pages = 0; + void *node_high_memory; + int i; + + num_physpages += pgdat->node_present_pages; + + if (pgdat->node_spanned_pages) + node_pages = free_all_bootmem_node(pgdat); + + totalram_pages += node_pages; - max_mapnr = num_physpages = MAP_NR(high_memory) - MAP_NR(memory_start); + for (i = 0; i < node_pages; i++) + if (PageReserved(pgdat->node_mem_map + i)) + reservedpages++; + + node_high_memory = (void *)((pgdat->node_start_pfn + + pgdat->node_spanned_pages) << + PAGE_SHIFT); + if (node_high_memory > high_memory) + high_memory = node_high_memory; + } /* clear the zero-page */ memset(empty_zero_page, 0, PAGE_SIZE); @@ -229,16 +227,6 @@ void __init mem_init(void) clear_page = clear_page_nommu; #endif - /* this will put all low memory onto the freelists */ - totalram_pages += free_all_bootmem_node(NODE_DATA(0)); - reservedpages = 0; - for (tmp = 0; tmp < num_physpages; tmp++) - /* - * Only count reserved RAM pages - */ - if (PageReserved(mem_map+tmp)) - reservedpages++; - codesize = (unsigned long) &_etext - (unsigned long) &_text; datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; @@ -250,7 +238,7 @@ void __init mem_init(void) printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, " "%dk reserved, %dk data, %dk init)\n", (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), - max_mapnr << (PAGE_SHIFT-10), + totalram_pages << (PAGE_SHIFT-10), codesize >> 10, reservedpages << (PAGE_SHIFT-10), datasize >> 10, @@ -289,4 +277,3 @@ void free_initrd_mem(unsigned long start, unsigned long end) printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); } #endif - diff --git a/include/asm-sh/mmu_context.h b/include/asm-sh/mmu_context.h index 01acaaae9751..199662bb35c6 100644 --- a/include/asm-sh/mmu_context.h +++ b/include/asm-sh/mmu_context.h @@ -169,6 +169,8 @@ enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) #define destroy_context(mm) do { } while (0) #define set_asid(asid) do { } while (0) #define get_asid() (0) +#define set_TTB(pgd) do { } while (0) +#define get_TTB() (0) #define activate_context(mm,cpu) do { } while (0) #define switch_mm(prev,next,tsk) do { } while (0) #define deactivate_mm(tsk,mm) do { } while (0) @@ -211,8 +213,8 @@ static inline void disable_mmu(void) * MMU control handlers for processors lacking memory * management hardware. */ -#define enable_mmu() do { BUG(); } while (0) -#define disable_mmu() do { BUG(); } while (0) +#define enable_mmu() do { } while (0) +#define disable_mmu() do { } while (0) #endif #endif /* __KERNEL__ */ diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h index ac4b4677f28c..7464de4ba07d 100644 --- a/include/asm-sh/page.h +++ b/include/asm-sh/page.h @@ -59,6 +59,7 @@ extern void (*clear_page)(void *to); extern void (*copy_page)(void *to, void *from); extern unsigned long shm_align_mask; +extern unsigned long max_low_pfn, min_low_pfn; #ifdef CONFIG_MMU extern void clear_page_slow(void *to); @@ -124,17 +125,16 @@ typedef struct { unsigned long pgd; } pgd_t; #define PAGE_OFFSET CONFIG_PAGE_OFFSET #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) +#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) -#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT) - -#define phys_to_page(phys) (mem_map + (((phys)-__MEMORY_START) >> PAGE_SHIFT)) -#define page_to_phys(page) (((page - mem_map) << PAGE_SHIFT) + __MEMORY_START) +#define phys_to_page(phys) (pfn_to_page(phys >> PAGE_SHIFT)) +#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) /* PFN start number, because of __MEMORY_START */ #define PFN_START (__MEMORY_START >> PAGE_SHIFT) #define ARCH_PFN_OFFSET (PFN_START) #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) -#define pfn_valid(pfn) (((pfn) - PFN_START) < max_mapnr) +#define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) < max_low_pfn) #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ -- cgit v1.2.3-59-g8ed1b From cdf50b23bf83624708d0abbb381a1c1694e42e19 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 28 Mar 2007 17:14:45 +0900 Subject: sh: Kill off udivdi3 div64_32 wrapping. Previously we've been handling udivdi3 references and wrapping them in to div64_32() automatically. This doesn't get a lot of use, however, and as akpm noted in the recent thread on l-k: http://lkml.org/lkml/2007/2/27/241 we're better off simply ripping it out and going the do_div() route if there happen to be any places that need it. Signed-off-by: Paul Mundt --- arch/sh/kernel/sh_ksyms.c | 1 - arch/sh/lib/Makefile | 4 +--- arch/sh/lib/udivdi3.c | 16 ---------------- 3 files changed, 1 insertion(+), 20 deletions(-) delete mode 100644 arch/sh/lib/udivdi3.c (limited to 'arch') diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index 6e0d10fac4a8..17f0b50c5678 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c @@ -65,7 +65,6 @@ EXPORT_SYMBOL(__div64_32); /* These symbols are generated by the compiler itself */ DECLARE_EXPORT(__udivsi3); -DECLARE_EXPORT(__udivdi3); DECLARE_EXPORT(__sdivsi3); DECLARE_EXPORT(__ashrdi3); DECLARE_EXPORT(__ashldi3); diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile index 0b9cca5c7cb4..e23dd1a3fccd 100644 --- a/arch/sh/lib/Makefile +++ b/arch/sh/lib/Makefile @@ -3,11 +3,9 @@ # lib-y = delay.o memset.o memmove.o memchr.o \ - checksum.o strlen.o div64.o udivdi3.o \ - div64-generic.o + checksum.o strlen.o div64.o div64-generic.o memcpy-y := memcpy.o memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o lib-y += $(memcpy-y) - diff --git a/arch/sh/lib/udivdi3.c b/arch/sh/lib/udivdi3.c deleted file mode 100644 index 68f038bf3c50..000000000000 --- a/arch/sh/lib/udivdi3.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Simple __udivdi3 function which doesn't use FPU. - */ - -#include - -extern u64 __xdiv64_32(u64 n, u32 d); -extern void panic(const char * fmt, ...); - -u64 __udivdi3(u64 n, u64 d) -{ - if (d & ~0xffffffff) - panic("Need true 64-bit/64-bit division"); - return __xdiv64_32(n, (u32)d); -} - -- cgit v1.2.3-59-g8ed1b From 652b9672cfc4000382f0f3f41907d9d32e5bd327 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 28 Mar 2007 17:20:47 +0900 Subject: sh: Add defconfig for se7722. Signed-off-by: Paul Mundt --- arch/sh/configs/se7722_defconfig | 945 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 945 insertions(+) create mode 100644 arch/sh/configs/se7722_defconfig (limited to 'arch') diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig new file mode 100644 index 000000000000..6a55ccbc934e --- /dev/null +++ b/arch/sh/configs/se7722_defconfig @@ -0,0 +1,945 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.21-rc4 +# Wed Mar 28 16:22:40 2007 +# +CONFIG_SUPERH=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME is not set +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_UTS_NS is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" + +# +# System type +# +# CONFIG_SH_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SOLUTION_ENGINE is not set +# CONFIG_SH_7300_SOLUTION_ENGINE is not set +# CONFIG_SH_7343_SOLUTION_ENGINE is not set +# CONFIG_SH_73180_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SYSTEMH is not set +# CONFIG_SH_HP6XX is not set +# CONFIG_SH_SATURN is not set +# CONFIG_SH_DREAMCAST is not set +# CONFIG_SH_MPC1211 is not set +# CONFIG_SH_SH03 is not set +# CONFIG_SH_SECUREEDGE5410 is not set +# CONFIG_SH_HS7751RVOIP is not set +# CONFIG_SH_7710VOIPGW is not set +# CONFIG_SH_RTS7751R2D is not set +# CONFIG_SH_HIGHLANDER is not set +# CONFIG_SH_EDOSK7705 is not set +# CONFIG_SH_SH4202_MICRODEV is not set +# CONFIG_SH_LANDISK is not set +# CONFIG_SH_TITAN is not set +# CONFIG_SH_SHMIN is not set +# CONFIG_SH_7206_SOLUTION_ENGINE is not set +# CONFIG_SH_7619_SOLUTION_ENGINE is not set +# CONFIG_SH_LBOX_RE2 is not set +CONFIG_SH_UNKNOWN=y + +# +# Processor selection +# +CONFIG_CPU_SH4=y +CONFIG_CPU_SH4A=y +CONFIG_CPU_SH4AL_DSP=y +CONFIG_CPU_SHX2=y + +# +# SH-2 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7604 is not set +# CONFIG_CPU_SUBTYPE_SH7619 is not set + +# +# SH-2A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7206 is not set + +# +# SH-3 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7300 is not set +# CONFIG_CPU_SUBTYPE_SH7705 is not set +# CONFIG_CPU_SUBTYPE_SH7706 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7710 is not set +# CONFIG_CPU_SUBTYPE_SH7712 is not set + +# +# SH-4 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7750 is not set +# CONFIG_CPU_SUBTYPE_SH7091 is not set +# CONFIG_CPU_SUBTYPE_SH7750R is not set +# CONFIG_CPU_SUBTYPE_SH7750S is not set +# CONFIG_CPU_SUBTYPE_SH7751 is not set +# CONFIG_CPU_SUBTYPE_SH7751R is not set +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_SH4_202 is not set + +# +# ST40 Processor Support +# +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +# CONFIG_CPU_SUBTYPE_ST40GX1 is not set + +# +# SH-4A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7770 is not set +# CONFIG_CPU_SUBTYPE_SH7780 is not set +# CONFIG_CPU_SUBTYPE_SH7785 is not set + +# +# SH4AL-DSP Processor Support +# +# CONFIG_CPU_SUBTYPE_SH73180 is not set +# CONFIG_CPU_SUBTYPE_SH7343 is not set +CONFIG_CPU_SUBTYPE_SH7722=y + +# +# Memory management options +# +CONFIG_MMU=y +CONFIG_PAGE_OFFSET=0x80000000 +CONFIG_MEMORY_START=0x0c000000 +CONFIG_MEMORY_SIZE=0x04000000 +# CONFIG_32BIT is not set +# CONFIG_X2TLB is not set +CONFIG_VSYSCALL=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_HUGETLB_PAGE_SIZE_64K=y +# CONFIG_HUGETLB_PAGE_SIZE_256K is not set +# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 + +# +# Cache configuration +# +# CONFIG_SH_DIRECT_MAPPED is not set +# CONFIG_SH_WRITETHROUGH is not set +# CONFIG_SH_OCRAM is not set +# CONFIG_CF_ENABLER is not set + +# +# Processor features +# +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set +# CONFIG_SH_FPU is not set +# CONFIG_SH_FPU_EMU is not set +CONFIG_SH_DSP=y +CONFIG_SH_STORE_QUEUES=y +CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_IPR_IRQ=y +CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_PTEA=y + +# +# Timer and clock configuration +# +CONFIG_SH_TMU=y +CONFIG_SH_TIMER_IRQ=16 +CONFIG_NO_IDLE_HZ=y +CONFIG_SH_PCLK_FREQ=32000000 + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# DMA support +# +# CONFIG_SH_DMA is not set + +# +# Companion Chips +# +# CONFIG_HD6446X_SERIES is not set + +# +# Additional SuperH Device Drivers +# +# CONFIG_HEARTBEAT is not set +CONFIG_PUSH_SWITCH=y + +# +# Kernel features +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_KEXEC=y +# CONFIG_SMP is not set +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y + +# +# Boot options +# +CONFIG_ZERO_PAGE_OFFSET=0x00001000 +CONFIG_BOOT_LINK_OFFSET=0x00800000 +# CONFIG_UBC_WAKEUP is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttySC0,115200" + +# +# Bus options +# +# CONFIG_PCI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_FLAT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options (EXPERIMENTAL) +# +# CONFIG_PM is not set + +# +# Networking +# +# CONFIG_NET is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set + +# +# Misc devices +# + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_DEBUG is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_PATA_PLATFORM=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# ISDN subsystem +# + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=2 +CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# + +# +# Graphics support +# +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_FB is not set + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=m +# CONFIG_OBSOLETE_OSS is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set + +# +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set + +# +# RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +CONFIG_RTC_DRV_SH=y +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# Auxiliary Display support +# + +# +# Virtualization +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=m + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=y +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_RAMFS=y +CONFIG_CONFIGFS_FS=m + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_CODEPAGE_932=y +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=m + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +CONFIG_DEBUG_SLAB=y +# CONFIG_DEBUG_SLAB_LEAK is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_VM=y +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +CONFIG_FORCED_INLINING=y +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_SH_STANDARD_BIOS=y +# CONFIG_EARLY_SCIF_CONSOLE is not set +CONFIG_EARLY_PRINTK=y +CONFIG_DEBUG_STACKOVERFLOW=y +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_4KSTACKS is not set +# CONFIG_SH_KGDB is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y -- cgit v1.2.3-59-g8ed1b From 0264f1603904dbee3196abc748a53fb0b23b8046 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 28 Mar 2007 23:36:03 +0900 Subject: sh: Tidy up L-BOX area5 addresses. L-BOX can use the normal PA_AREA5_IO, there's no reason for it to reproduce it. Signed-off-by: Paul Mundt --- arch/sh/boards/lboxre2/setup.c | 3 ++- include/asm-sh/lboxre2.h | 9 ++------- 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/lboxre2/setup.c b/arch/sh/boards/lboxre2/setup.c index fc3cba3f0606..4e20f7c63bf3 100644 --- a/arch/sh/boards/lboxre2/setup.c +++ b/arch/sh/boards/lboxre2/setup.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -53,7 +54,7 @@ static int __init lboxre2_devices_setup(void) unsigned long paddrbase, psize; /* open I/O area window */ - paddrbase = virt_to_phys((void*)CONFIG_CF0_BASE_ADDR); + paddrbase = virt_to_phys((void*)PA_AREA5_IO); psize = PAGE_SIZE; prot = PAGE_KERNEL_PCC( 1 , _PAGE_PCC_IO16); cf0_io_base = (u32)p3_ioremap(paddrbase, psize, prot.pgprot); diff --git a/include/asm-sh/lboxre2.h b/include/asm-sh/lboxre2.h index 65775668df93..e6d160504923 100644 --- a/include/asm-sh/lboxre2.h +++ b/include/asm-sh/lboxre2.h @@ -2,8 +2,6 @@ #define __ASM_SH_LBOXRE2_H /* - * linux/include/asm-sh/lbox.h - * * Copyright (C) 2007 Nobuhiro Iwamatsu * * NTT COMWARE L-BOX RE2 support @@ -14,11 +12,8 @@ * */ -#define CONFIG_CF0_BASE_ADDR 0xb4000000 /* Boot only */ -#define CONFIG_CF1_BASE_ADDR 0xb8000000 - -#define IRQ_CF1 9 /* CF1 */ -#define IRQ_CF0 10 /* CF0 */ +#define IRQ_CF1 9 /* CF1 */ +#define IRQ_CF0 10 /* CF0 */ #define IRQ_INTD 11 /* INTD */ #define IRQ_ETH1 12 /* Ether1 */ #define IRQ_ETH0 13 /* Ether0 */ -- cgit v1.2.3-59-g8ed1b From cd6c7ea234dc8a8607283e056d8010b2bd3c6369 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 29 Mar 2007 00:04:39 +0900 Subject: sh: Add a dummy SH-4 PCIC fixup. By default we don't have anything to fix up for the SH-4 PCIC, boards can overload this as necessary. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/ops-sh4.c | 6 ++++++ arch/sh/drivers/pci/pci-sh7751.c | 15 ++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c index 2d4371009a5e..54232f13e406 100644 --- a/arch/sh/drivers/pci/ops-sh4.c +++ b/arch/sh/drivers/pci/ops-sh4.c @@ -162,3 +162,9 @@ char * __init pcibios_setup(char *str) return str; } + +int __attribute__((weak)) pci_fixup_pcic(void) +{ + /* Nothing to do. */ + return 0; +} diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index f3ead58a9519..1aca7fe5783b 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -12,7 +12,6 @@ * License. See linux/COPYING for more information. * */ - #undef DEBUG #include @@ -28,7 +27,7 @@ * Initialization. Try all known PCI access methods. Note that we support * using both PCI BIOS and direct access: in such cases, we use I/O ports * to access config space. - * + * * Note that the platform specific initialization (BSC registers, and memory * space mapping) will be called via the platform defined function * pcibios_init_platform(). @@ -115,7 +114,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) * Wait Cycle Control + Parity Enable + Bus Master + * Mem space enable */ - word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | + word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES; pci_write_reg(word, SH7751_PCICONF1); @@ -123,10 +122,10 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) word = PCI_BASE_CLASS_BRIDGE << 24; pci_write_reg(word, SH7751_PCICONF2); - /* Set IO and Mem windows to local address - * Make PCI and local address the same for easy 1 to 1 mapping + /* Set IO and Mem windows to local address + * Make PCI and local address the same for easy 1 to 1 mapping * Window0 = map->window0.size @ non-cached area base = SDRAM - * Window1 = map->window1.size @ cached area base = SDRAM + * Window1 = map->window1.size @ cached area base = SDRAM */ word = map->window0.size - 1; pci_write_reg(word, SH4_PCILSR0); @@ -175,7 +174,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) case SH7751_CS5_BASE_ADDR: word = __area_sdram_check(5); break; case SH7751_CS6_BASE_ADDR: word = __area_sdram_check(6); break; } - + if (!word) return 0; @@ -194,9 +193,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) * DMA interrupts... */ -#if defined(CONFIG_SH_RTS7751R2D) || defined(CONFIG_SH_LBOX_RE2) pci_fixup_pcic(); -#endif /* SH7751 init done, set central function init complete */ /* use round robin mode to stop a device starving/overruning */ -- cgit v1.2.3-59-g8ed1b From b75762302e144b73f12b72c59b99401d036680aa Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Thu, 29 Mar 2007 00:07:35 +0900 Subject: sh: SH7780 Solution Engine board support. This adds support for the SH7780-based Solution Engine reference board. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 8 + arch/sh/Makefile | 1 + arch/sh/boards/se/7780/Makefile | 10 + arch/sh/boards/se/7780/irq.c | 89 +++ arch/sh/boards/se/7780/setup.c | 122 ++++ arch/sh/configs/se7780_defconfig | 1309 ++++++++++++++++++++++++++++++++++++++ arch/sh/drivers/pci/pci-sh7780.c | 30 +- arch/sh/drivers/pci/pci-sh7780.h | 16 + arch/sh/tools/mach-types | 1 + include/asm-sh/se7780.h | 108 ++++ 10 files changed, 1686 insertions(+), 8 deletions(-) create mode 100644 arch/sh/boards/se/7780/Makefile create mode 100644 arch/sh/boards/se/7780/irq.c create mode 100644 arch/sh/boards/se/7780/setup.c create mode 100644 arch/sh/configs/se7780_defconfig create mode 100644 include/asm-sh/se7780.h (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 4b6948f41d3f..0b465d622cfc 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -99,6 +99,14 @@ config SH_7751_SOLUTION_ENGINE help Select 7751 SolutionEngine if configuring for a Hitachi SH7751 evaluation board. + +config SH_7780_SOLUTION_ENGINE + bool "SolutionEngine7780" + select SOLUTION_ENGINE + select CPU_SUBTYPE_SH7780 + help + Select 7780 SolutionEngine if configuring for a Renesas SH7780 + evaluation board. config SH_7300_SOLUTION_ENGINE bool "SolutionEngine7300" diff --git a/arch/sh/Makefile b/arch/sh/Makefile index b00ed904aa00..d7c12053160b 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -89,6 +89,7 @@ core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/ # Boards machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751 +machdir-$(CONFIG_SH_7780_SOLUTION_ENGINE) := se/7780 machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300 machdir-$(CONFIG_SH_7343_SOLUTION_ENGINE) := se/7343 machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se/73180 diff --git a/arch/sh/boards/se/7780/Makefile b/arch/sh/boards/se/7780/Makefile new file mode 100644 index 000000000000..6b88adae3ecc --- /dev/null +++ b/arch/sh/boards/se/7780/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the HITACHI UL SolutionEngine 7780 specific parts of the kernel +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# + +obj-y := setup.o irq.o diff --git a/arch/sh/boards/se/7780/irq.c b/arch/sh/boards/se/7780/irq.c new file mode 100644 index 000000000000..3d0625c2d07b --- /dev/null +++ b/arch/sh/boards/se/7780/irq.c @@ -0,0 +1,89 @@ +/* + * linux/arch/sh/boards/se/7780/irq.c + * + * Copyright (C) 2006,2007 Nobuhiro Iwamatsu + * + * Hitachi UL SolutionEngine 7780 Support. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include + +#define INTC_INTMSK0 0xFFD00044 +#define INTC_INTMSKCLR0 0xFFD00064 + +static void disable_se7780_irq(unsigned int irq) +{ + struct intc2_data *p = get_irq_chip_data(irq); + ctrl_outl(1 << p->msk_shift, INTC_INTMSK0 + p->msk_offset); +} + +static void enable_se7780_irq(unsigned int irq) +{ + struct intc2_data *p = get_irq_chip_data(irq); + ctrl_outl(1 << p->msk_shift, INTC_INTMSKCLR0 + p->msk_offset); +} + +static struct irq_chip se7780_irq_chip __read_mostly = { + .name = "SE7780", + .mask = disable_se7780_irq, + .unmask = enable_se7780_irq, + .mask_ack = disable_se7780_irq, +}; + +static struct intc2_data intc2_irq_table[] = { + { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT1 */ + { 4, 0, 30, 0, 30, 3 }, /* daughter board EXTINT2 */ + { 6, 0, 29, 0, 29, 3 }, /* daughter board EXTINT3 */ + { 8, 0, 28, 0, 28, 3 }, /* SMC 91C111 (LAN) */ + { 10, 0, 27, 0, 27, 3 }, /* daughter board EXTINT4 */ + { 4, 0, 30, 0, 30, 3 }, /* daughter board EXTINT5 */ + { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT6 */ + { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT7 */ + { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT8 */ + { 0 , 0, 24, 0, 24, 3 }, /* SM501 */ +}; + +/* + * Initialize IRQ setting + */ +void __init init_se7780_IRQ(void) +{ + int i ; + + /* enable all interrupt at FPGA */ + ctrl_outw(0, FPGA_INTMSK1); + /* mask SM501 interrupt */ + ctrl_outw((ctrl_inw(FPGA_INTMSK1) | 0x0002), FPGA_INTMSK1); + /* enable all interrupt at FPGA */ + ctrl_outw(0, FPGA_INTMSK2); + + /* set FPGA INTSEL register */ + /* FPGA + 0x06 */ + ctrl_outw( ((IRQPIN_SM501 << IRQPOS_SM501) | + (IRQPIN_SMC91CX << IRQPOS_SMC91CX)), FPGA_INTSEL1); + + /* FPGA + 0x08 */ + ctrl_outw(((IRQPIN_EXTINT4 << IRQPOS_EXTINT4) | + (IRQPIN_EXTINT3 << IRQPOS_EXTINT3) | + (IRQPIN_EXTINT2 << IRQPOS_EXTINT2) | + (IRQPIN_EXTINT1 << IRQPOS_EXTINT1)), FPGA_INTSEL2); + + /* FPGA + 0x0A */ + ctrl_outw((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3); + + for (i = 0; i < ARRAY_SIZE(intc2_irq_table); i++) { + disable_irq_nosync(intc2_irq_table[i].irq); + set_irq_chip_and_handler_name( intc2_irq_table[i].irq, &se7780_irq_chip, + handle_level_irq, "level"); + set_irq_chip_data( intc2_irq_table[i].irq, &intc2_irq_table[i] ); + disable_se7780_irq(intc2_irq_table[i].irq); + } +} diff --git a/arch/sh/boards/se/7780/setup.c b/arch/sh/boards/se/7780/setup.c new file mode 100644 index 000000000000..df7d08a24c9f --- /dev/null +++ b/arch/sh/boards/se/7780/setup.c @@ -0,0 +1,122 @@ +/* + * linux/arch/sh/boards/se/7780/setup.c + * + * Copyright (C) 2006,2007 Nobuhiro Iwamatsu + * + * Hitachi UL SolutionEngine 7780 Support. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include + +/* Heartbeat */ +static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + +static struct resource heartbeat_resources[] = { + [0] = { + .start = PA_LED, + .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + .dev = { + .platform_data = heartbeat_bit_pos, + }, + .num_resources = ARRAY_SIZE(heartbeat_resources), + .resource = heartbeat_resources, +}; + +/* SMC91x */ +static struct resource smc91x_eth_resources[] = { + [0] = { + .name = "smc91x-regs" , + .start = PA_LAN + 0x300, + .end = PA_LAN + 0x300 + 0x10 , + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = SMC_IRQ, + .end = SMC_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_eth_device = { + .name = "smc91x", + .id = 0, + .dev = { + .dma_mask = NULL, /* don't use dma */ + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(smc91x_eth_resources), + .resource = smc91x_eth_resources, +}; + +static struct platform_device *se7780_devices[] __initdata = { + &heartbeat_device, + &smc91x_eth_device, +}; + +static int __init se7780_devices_setup(void) +{ + return platform_add_devices(se7780_devices, + ARRAY_SIZE(se7780_devices)); +} +device_initcall(se7780_devices_setup); + +#define GPIO_PHCR 0xFFEA000E +#define GPIO_PMSELR 0xFFEA0080 +#define GPIO_PECR 0xFFEA0008 + +static void __init se7780_setup(char **cmdline_p) +{ + /* "SH-Linux" on LED Display */ + ctrl_outw( 'S' , PA_LED_DISP + (DISP_SEL0_ADDR << 1) ); + ctrl_outw( 'H' , PA_LED_DISP + (DISP_SEL1_ADDR << 1) ); + ctrl_outw( '-' , PA_LED_DISP + (DISP_SEL2_ADDR << 1) ); + ctrl_outw( 'L' , PA_LED_DISP + (DISP_SEL3_ADDR << 1) ); + ctrl_outw( 'i' , PA_LED_DISP + (DISP_SEL4_ADDR << 1) ); + ctrl_outw( 'n' , PA_LED_DISP + (DISP_SEL5_ADDR << 1) ); + ctrl_outw( 'u' , PA_LED_DISP + (DISP_SEL6_ADDR << 1) ); + ctrl_outw( 'x' , PA_LED_DISP + (DISP_SEL7_ADDR << 1) ); + + printk(KERN_INFO "Hitachi UL Solutions Engine 7780SE03 support.\n"); + + /* + * PCI REQ/GNT setting + * REQ0/GNT0 -> USB + * REQ1/GNT1 -> PC Card + * REQ2/GNT2 -> Serial ATA + * REQ3/GNT3 -> PCI slot + */ + ctrl_outw(0x0213, FPGA_REQSEL); + + /* GPIO setting */ + ctrl_outw(0x0000, GPIO_PECR); + ctrl_outw(ctrl_inw(GPIO_PHCR)&0xfff3, GPIO_PHCR); + ctrl_outw(0x0c00, GPIO_PMSELR); + + /* iVDR Power ON */ + ctrl_outw(0x0001, FPGA_IVDRPW); +} + +/* + * The Machine Vector + */ +struct sh_machine_vector mv_se7780 __initmv = { + .mv_name = "Solution Engine 7780" , + .mv_setup = se7780_setup , + .mv_nr_irqs = 111 , + .mv_init_irq = init_se7780_IRQ, +}; +ALIAS_MV(se7780) diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig new file mode 100644 index 000000000000..538661e98793 --- /dev/null +++ b/arch/sh/configs/se7780_defconfig @@ -0,0 +1,1309 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.21-rc3 +# Thu Mar 15 14:06:20 2007 +# +CONFIG_SUPERH=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME is not set +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +# CONFIG_EXPERIMENTAL is not set +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +# CONFIG_KALLSYMS is not set +# CONFIG_HOTPLUG is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +# CONFIG_EPOLL is not set +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +CONFIG_IOSCHED_DEADLINE=y +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +CONFIG_DEFAULT_DEADLINE=y +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="deadline" + +# +# System type +# +CONFIG_SOLUTION_ENGINE=y +# CONFIG_SH_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SOLUTION_ENGINE is not set +CONFIG_SH_7780_SOLUTION_ENGINE=y +# CONFIG_SH_7300_SOLUTION_ENGINE is not set +# CONFIG_SH_7343_SOLUTION_ENGINE is not set +# CONFIG_SH_73180_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SYSTEMH is not set +# CONFIG_SH_HP6XX is not set +# CONFIG_SH_SATURN is not set +# CONFIG_SH_DREAMCAST is not set +# CONFIG_SH_MPC1211 is not set +# CONFIG_SH_SH03 is not set +# CONFIG_SH_SECUREEDGE5410 is not set +# CONFIG_SH_HS7751RVOIP is not set +# CONFIG_SH_7710VOIPGW is not set +# CONFIG_SH_RTS7751R2D is not set +# CONFIG_SH_HIGHLANDER is not set +# CONFIG_SH_EDOSK7705 is not set +# CONFIG_SH_SH4202_MICRODEV is not set +# CONFIG_SH_LANDISK is not set +# CONFIG_SH_TITAN is not set +# CONFIG_SH_SHMIN is not set +# CONFIG_SH_7206_SOLUTION_ENGINE is not set +# CONFIG_SH_7619_SOLUTION_ENGINE is not set +# CONFIG_SH_UNKNOWN is not set + +# +# Processor selection +# +CONFIG_CPU_SH4=y +CONFIG_CPU_SH4A=y + +# +# SH-2 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7604 is not set +# CONFIG_CPU_SUBTYPE_SH7619 is not set + +# +# SH-2A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7206 is not set + +# +# SH-3 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7300 is not set +# CONFIG_CPU_SUBTYPE_SH7705 is not set +# CONFIG_CPU_SUBTYPE_SH7706 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7710 is not set + +# +# SH-4 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7750 is not set +# CONFIG_CPU_SUBTYPE_SH7091 is not set +# CONFIG_CPU_SUBTYPE_SH7750R is not set +# CONFIG_CPU_SUBTYPE_SH7750S is not set +# CONFIG_CPU_SUBTYPE_SH7751 is not set +# CONFIG_CPU_SUBTYPE_SH7751R is not set +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_SH4_202 is not set + +# +# ST40 Processor Support +# +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +# CONFIG_CPU_SUBTYPE_ST40GX1 is not set + +# +# SH-4A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7770 is not set +CONFIG_CPU_SUBTYPE_SH7780=y +# CONFIG_CPU_SUBTYPE_SH7785 is not set + +# +# SH4AL-DSP Processor Support +# +# CONFIG_CPU_SUBTYPE_SH73180 is not set +# CONFIG_CPU_SUBTYPE_SH7343 is not set +# CONFIG_CPU_SUBTYPE_SH7722 is not set + +# +# Memory management options +# +CONFIG_MMU=y +CONFIG_PAGE_OFFSET=0x80000000 +CONFIG_MEMORY_START=0x08000000 +CONFIG_MEMORY_SIZE=0x08000000 +CONFIG_32BIT=y +CONFIG_VSYSCALL=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 + +# +# Cache configuration +# +# CONFIG_SH_DIRECT_MAPPED is not set +# CONFIG_SH_WRITETHROUGH is not set +# CONFIG_SH_OCRAM is not set + +# +# Processor features +# +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_SH_FPU=y +# CONFIG_SH_DSP is not set +# CONFIG_SH_STORE_QUEUES is not set +CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_INTC2_IRQ=y +CONFIG_CPU_HAS_SR_RB=y + +# +# Timer and clock configuration +# +CONFIG_SH_TMU=y +CONFIG_SH_TIMER_IRQ=28 +# CONFIG_NO_IDLE_HZ is not set +CONFIG_SH_PCLK_FREQ=33333333 + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# DMA support +# +# CONFIG_SH_DMA is not set + +# +# Companion Chips +# +# CONFIG_HD6446X_SERIES is not set + +# +# Additional SuperH Device Drivers +# +CONFIG_HEARTBEAT=y +# CONFIG_PUSH_SWITCH is not set + +# +# Kernel features +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +# CONFIG_SMP is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set + +# +# Boot options +# +CONFIG_ZERO_PAGE_OFFSET=0x00001000 +CONFIG_BOOT_LINK_OFFSET=0x00810000 +# CONFIG_UBC_WAKEUP is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Bus options +# +CONFIG_PCI=y +CONFIG_SH_PCIDMA_NONCOHERENT=y +CONFIG_PCI_AUTO=y +CONFIG_PCI_AUTO_UPDATE_RESOURCES=y + +# +# PCCARD (PCMCIA/CardBus) support +# + +# +# PCI Hotplug Support +# + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_FLAT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_IPV6=y +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set +# CONFIG_IPV6_SIT is not set +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +# CONFIG_MTD_CFI_I1 is not set +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +CONFIG_MTD_ROM=y +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# Misc devices +# +# CONFIG_SGI_IOC4 is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +CONFIG_SATA_SIL=y +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +# CONFIG_PATA_PLATFORM is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +CONFIG_SMSC_PHY=y +# CONFIG_BROADCOM_PHY is not set +# CONFIG_FIXED_PHY is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_STNIC is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +CONFIG_SMC91X=y + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=2 +CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB_DDC is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frambuffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_EPSON1355 is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_LOGO_SUPERH_MONO is not set +# CONFIG_LOGO_SUPERH_VGA16 is not set +CONFIG_LOGO_SUPERH_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +# CONFIG_OBSOLETE_OSS is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set + +# +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +CONFIG_USB_DEBUG=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_APPLETOUCH is not set +# CONFIG_USB_GTCO is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# Auxiliary Display support +# + +# +# Virtualization +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +# CONFIG_SYSFS is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_HFSPLUS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_SH_STANDARD_BIOS is not set +# CONFIG_EARLY_SCIF_CONSOLE is not set +# CONFIG_SH_KGDB is not set + +# +# Security options +# +# CONFIG_KEYS is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 16b30a9e94bb..5508e45d4838 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -72,12 +72,27 @@ static int __init sh7780_pci_init(void) } /* Setup the INTC */ - ctrl_outl(0x00200000, INTC_ICR0); /* INTC SH-4 Mode */ - ctrl_outl(0x00078000, INTC_INT2MSKCR); /* enable PCIINTA - PCIINTD */ - ctrl_outl(0x40000000, INTC_INTMSK1); /* disable IRL4-7 Interrupt */ - ctrl_outl(0x0000fffe, INTC_INTMSK2); /* disable IRL4-7 Interrupt */ - ctrl_outl(0x80000000, INTC_INTMSKCLR1); /* enable IRL0-3 Interrupt */ - ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); /* enable IRL0-3 Interrupt */ + if (mach_is_7780se()) { + /* ICR0: IRL=use separately */ + ctrl_outl(0x00C00020, INTC_ICR0); + /* ICR1: detect low level(for 2ndcut) */ + ctrl_outl(0xAAAA0000, INTC_ICR1); + /* INTPRI: priority=3(all) */ + ctrl_outl(0x33333333, INTC_INTPRI); + } else { + /* INTC SH-4 Mode */ + ctrl_outl(0x00200000, INTC_ICR0); + /* enable PCIINTA - PCIINTD */ + ctrl_outl(0x00078000, INTC_INT2MSKCR); + /* disable IRL4-7 Interrupt */ + ctrl_outl(0x40000000, INTC_INTMSK1); + /* disable IRL4-7 Interrupt */ + ctrl_outl(0x0000fffe, INTC_INTMSK2); + /* enable IRL0-3 Interrupt */ + ctrl_outl(0x80000000, INTC_INTMSKCLR1); + /* enable IRL0-3 Interrupt */ + ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); + } if ((ret = sh4_pci_check_direct()) != 0) return ret; @@ -147,9 +162,8 @@ int __init sh7780_pcic_init(struct sh4_pci_address_map *map) * DMA interrupts... */ -#ifdef CONFIG_SH_HIGHLANDER + /* Apply any last-minute PCIC fixups */ pci_fixup_pcic(); -#endif /* SH7780 init done, set central function init complete */ /* use round robin mode to stop a device starving/overruning */ diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h index bd44255509e6..00d12d0f8c1f 100644 --- a/arch/sh/drivers/pci/pci-sh7780.h +++ b/arch/sh/drivers/pci/pci-sh7780.h @@ -66,6 +66,22 @@ #define SH7780_PCIPMCSR_BSE 0x046 #define SH7780_PCICDD 0x047 +#define SH7780_PCICR 0x100 /* PCI Control Register */ +#define SH7780_PCILSR 0x104 /* PCI Local Space Register0 */ +#define SH7780_PCILSR1 0x108 /* PCI Local Space Register1 */ +#define SH7780_PCILAR0 0x10C /* PCI Local Address Register1 */ +#define SH7780_PCILAR1 0x110 /* PCI Local Address Register1 */ +#define SH7780_PCIIR 0x114 /* PCI Interrupt Register */ +#define SH7780_PCIIMR 0x118 /* PCI Interrupt Mask Register */ +#define SH7780_PCIAIR 0x11C /* Error Address Register */ +#define SH7780_PCICIR 0x120 /* Error Command/Data Register */ +#define SH7780_PCIAINT 0x130 /* Arbiter Interrupt Register */ +#define SH7780_PCIAINTM 0x134 /* Arbiter Int. Mask Register */ +#define SH7780_PCIBMIR 0x138 /* Error Bus Master Register */ +#define SH7780_PCIPAR 0x1C0 /* PIO Address Register */ +#define SH7780_PCIPINT 0x1CC /* Power Mgmnt Int. Register */ +#define SH7780_PCIPINTM 0x1D0 /* Power Mgmnt Mask Register */ + #define SH7780_PCIMBR0 0x1E0 #define SH7780_PCIMBMR0 0x1E4 #define SH7780_PCIMBR2 0x1F0 diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index 5b1236c2cfec..554f801db67b 100644 --- a/arch/sh/tools/mach-types +++ b/arch/sh/tools/mach-types @@ -9,6 +9,7 @@ SE SH_SOLUTION_ENGINE 7751SE SH_7751_SOLUTION_ENGINE 7300SE SH_7300_SOLUTION_ENGINE 7343SE SH_7343_SOLUTION_ENGINE +7780SE SH_7780_SOLUTION_ENGINE 73180SE SH_73180_SOLUTION_ENGINE 7751SYSTEMH SH_7751_SYSTEMH HP6XX SH_HP6XX diff --git a/include/asm-sh/se7780.h b/include/asm-sh/se7780.h new file mode 100644 index 000000000000..40e9b41458cd --- /dev/null +++ b/include/asm-sh/se7780.h @@ -0,0 +1,108 @@ +#ifndef __ASM_SH_SE7780_H +#define __ASM_SH_SE7780_H + +/* + * linux/include/asm-sh/se7780.h + * + * Copyright (C) 2006,2007 Nobuhiro Iwamatsu + * + * Hitachi UL SolutionEngine 7780 Support. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include + +/* Box specific addresses. */ +#define SE_AREA0_WIDTH 4 /* Area0: 32bit */ +#define PA_ROM 0xa0000000 /* EPROM */ +#define PA_ROM_SIZE 0x00400000 /* EPROM size 4M byte */ +#define PA_FROM 0xa1000000 /* Flash-ROM */ +#define PA_FROM_SIZE 0x01000000 /* Flash-ROM size 16M byte */ +#define PA_EXT1 0xa4000000 +#define PA_EXT1_SIZE 0x04000000 +#define PA_SM501 PA_EXT1 /* Graphic IC (SM501) */ +#define PA_SM501_SIZE PA_EXT1_SIZE /* Graphic IC (SM501) */ +#define PA_SDRAM 0xa8000000 /* DDR-SDRAM(Area2/3) 128MB */ +#define PA_SDRAM_SIZE 0x08000000 + +#define PA_EXT4 0xb0000000 +#define PA_EXT4_SIZE 0x04000000 +#define PA_EXT_FLASH PA_EXT4 /* Expansion Flash-ROM */ + +#define PA_PERIPHERAL PA_AREA6_IO /* SW6-6=ON */ + +#define PA_LAN (PA_PERIPHERAL + 0) /* SMC LAN91C111 */ +#define PA_LED_DISP (PA_PERIPHERAL + 0x02000000) /* 8words LED Display */ +#define DISP_CHAR_RAM (7 << 3) +#define DISP_SEL0_ADDR (DISP_CHAR_RAM + 0) +#define DISP_SEL1_ADDR (DISP_CHAR_RAM + 1) +#define DISP_SEL2_ADDR (DISP_CHAR_RAM + 2) +#define DISP_SEL3_ADDR (DISP_CHAR_RAM + 3) +#define DISP_SEL4_ADDR (DISP_CHAR_RAM + 4) +#define DISP_SEL5_ADDR (DISP_CHAR_RAM + 5) +#define DISP_SEL6_ADDR (DISP_CHAR_RAM + 6) +#define DISP_SEL7_ADDR (DISP_CHAR_RAM + 7) + +#define DISP_UDC_RAM (5 << 3) +#define PA_FPGA (PA_PERIPHERAL + 0x03000000) /* FPGA base address */ + +/* FPGA register address and bit */ +#define FPGA_SFTRST (PA_FPGA + 0) /* Soft reset register */ +#define FPGA_INTMSK1 (PA_FPGA + 2) /* Interrupt Mask register 1 */ +#define FPGA_INTMSK2 (PA_FPGA + 4) /* Interrupt Mask register 2 */ +#define FPGA_INTSEL1 (PA_FPGA + 6) /* Interrupt select register 1 */ +#define FPGA_INTSEL2 (PA_FPGA + 8) /* Interrupt select register 2 */ +#define FPGA_INTSEL3 (PA_FPGA + 10) /* Interrupt select register 3 */ +#define FPGA_PCI_INTSEL1 (PA_FPGA + 12) /* PCI Interrupt select register 1 */ +#define FPGA_PCI_INTSEL2 (PA_FPGA + 14) /* PCI Interrupt select register 2 */ +#define FPGA_INTSET (PA_FPGA + 16) /* IRQ/IRL select register */ +#define FPGA_INTSTS1 (PA_FPGA + 18) /* Interrupt status register 1 */ +#define FPGA_INTSTS2 (PA_FPGA + 20) /* Interrupt status register 2 */ +#define FPGA_REQSEL (PA_FPGA + 22) /* REQ/GNT select register */ +#define FPGA_DBG_LED (PA_FPGA + 32) /* Debug LED(D-LED[8:1] */ +#define PA_LED FPGA_DBG_LED +#define FPGA_IVDRID (PA_FPGA + 36) /* iVDR ID Register */ +#define FPGA_IVDRPW (PA_FPGA + 38) /* iVDR Power ON Register */ +#define FPGA_MMCID (PA_FPGA + 40) /* MMC ID Register */ + +/* FPGA INTSEL position */ +/* INTSEL1 */ +#define IRQPOS_SMC91CX (0 * 4) +#define IRQPOS_SM501 (1 * 4) +/* INTSEL2 */ +#define IRQPOS_EXTINT1 (0 * 4) +#define IRQPOS_EXTINT2 (1 * 4) +#define IRQPOS_EXTINT3 (2 * 4) +#define IRQPOS_EXTINT4 (3 * 4) +/* INTSEL3 */ +#define IRQPOS_PCCPW (0 * 4) + +/* IDE interrupt */ +#define IRQ_IDE0 67 /* iVDR */ + +/* SMC interrupt */ +#define SMC_IRQ 8 + +/* SM501 interrupt */ +#define SM501_IRQ 0 + +/* interrupt pin */ +#define IRQPIN_EXTINT1 0 /* IRQ0 pin */ +#define IRQPIN_EXTINT2 1 /* IRQ1 pin */ +#define IRQPIN_EXTINT3 2 /* IRQ2 pin */ +#define IRQPIN_SMC91CX 3 /* IRQ3 pin */ +#define IRQPIN_EXTINT4 4 /* IRQ4 pin */ +#define IRQPIN_PCC0 5 /* IRQ5 pin */ +#define IRQPIN_PCC2 6 /* IRQ6 pin */ +#define IRQPIN_SM501 7 /* IRQ7 pin */ +#define IRQPIN_PCCPW 7 /* IRQ7 pin */ + +/* arch/sh/boards/se/7780/irq.c */ +void init_se7780_IRQ(void); + +#define __IO_PREFIX se7780 +#include + +#endif /* __ASM_SH_SE7780_H */ -- cgit v1.2.3-59-g8ed1b From b7aee517c8302d651ff057fdcebee3c1f53c3b2e Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 30 Mar 2007 14:49:21 +0900 Subject: sh: se7780 PCI support. Add support for the SH7780 PCIC on the Solution Engine 7780, missing from the previous board-support patch. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Makefile | 1 + arch/sh/drivers/pci/fixups-se7780.c | 60 +++++++++++++++++++++++ arch/sh/drivers/pci/ops-se7780.c | 96 +++++++++++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+) create mode 100644 arch/sh/drivers/pci/fixups-se7780.c create mode 100644 arch/sh/drivers/pci/ops-se7780.c (limited to 'arch') diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index b1391cb080d1..0e9b532b9fbc 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -19,3 +19,4 @@ obj-$(CONFIG_SH_HIGHLANDER) += ops-r7780rp.o fixups-r7780rp.o obj-$(CONFIG_SH_TITAN) += ops-titan.o obj-$(CONFIG_SH_LANDISK) += ops-landisk.o obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-lboxre2.o +obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += ops-se7780.o fixups-se7780.o diff --git a/arch/sh/drivers/pci/fixups-se7780.c b/arch/sh/drivers/pci/fixups-se7780.c new file mode 100644 index 000000000000..880cea1c0d89 --- /dev/null +++ b/arch/sh/drivers/pci/fixups-se7780.c @@ -0,0 +1,60 @@ +/* + * arch/sh/drivers/pci/fixups-se7780.c + * + * HITACHI UL Solution Engine 7780 PCI fixups + * + * Copyright (C) 2003 Lineo uSolutions, Inc. + * Copyright (C) 2004 - 2006 Paul Mundt + * Copyright (C) 2006 Nobuhiro Iwamatsu + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include "pci-sh4.h" +#include + +int pci_fixup_pcic(void) +{ + ctrl_outl(0x00000001, SH7780_PCI_VCR2); + + /* Enable all interrupts, so we know what to fix */ + pci_write_reg(0x0000C3FF, SH7780_PCIIMR); + pci_write_reg(0x0000380F, SH7780_PCIAINTM); + + /* Set up standard PCI config registers */ + ctrl_outw(0xFB00, PCI_REG(SH7780_PCISTATUS)); + ctrl_outw(0x0047, PCI_REG(SH7780_PCICMD)); + ctrl_outb( 0x00, PCI_REG(SH7780_PCIPIF)); + ctrl_outb( 0x00, PCI_REG(SH7780_PCISUB)); + ctrl_outb( 0x06, PCI_REG(SH7780_PCIBCC)); + ctrl_outw(0x1912, PCI_REG(SH7780_PCISVID)); + ctrl_outw(0x0001, PCI_REG(SH7780_PCISID)); + + pci_write_reg(0x08000000, SH7780_PCIMBAR0); /* PCI */ + pci_write_reg(0x08000000, SH7780_PCILAR0); /* SHwy */ + pci_write_reg(0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */ + + pci_write_reg(0x00000000, SH7780_PCIMBAR1); + pci_write_reg(0x00000000, SH7780_PCILAR1); + pci_write_reg(0x00000000, SH7780_PCILSR1); + + pci_write_reg(0xAB000801, SH7780_PCIIBAR); + + /* + * Set the MBR so PCI address is one-to-one with window, + * meaning all calls go straight through... use ifdef to + * catch erroneous assumption. + */ + pci_write_reg(0xFD000000 , SH7780_PCIMBR0); + pci_write_reg(0x00FC0000 , SH7780_PCIMBMR0); /* 16M */ + + /* Set IOBR for window containing area specified in pci.h */ + pci_write_reg(PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR); + pci_write_reg((SH7780_PCI_IO_SIZE-1) & (7 << 18), SH7780_PCIIOBMR); + + pci_write_reg(0xA5000C01, SH7780_PCICR); + + return 0; +} diff --git a/arch/sh/drivers/pci/ops-se7780.c b/arch/sh/drivers/pci/ops-se7780.c new file mode 100644 index 000000000000..212674df5e13 --- /dev/null +++ b/arch/sh/drivers/pci/ops-se7780.c @@ -0,0 +1,96 @@ +/* + * linux/arch/sh/drivers/pci/ops-se7780.c + * + * Copyright (C) 2006 Nobuhiro Iwamatsu + * + * PCI initialization for the Hitachi UL Solution Engine 7780SE03 + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + */ +#include +#include +#include +#include +#include +#include +#include +#include "pci-sh4.h" + +/* + * IDSEL = AD16 PCI slot + * IDSEL = AD17 PCI slot + * IDSEL = AD18 Serial ATA Controller (Silicon Image SiL3512A) + * IDSEL = AD19 USB Host Controller (NEC uPD7210100A) + */ + +/* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */ +static char se7780_irq_tab[4][16] __initdata = { + /* INTA */ + { 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, + /* INTB */ + { 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, + /* INTC */ + { 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, + /* INTD */ + { 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +}; + +int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +{ + return se7780_irq_tab[pin-1][slot]; +} + +static struct resource se7780_io_resource = { + .name = "SH7780_IO", + .start = 0x2000, + .end = 0x2000 + SH7780_PCI_IO_SIZE - 1, + .flags = IORESOURCE_IO +}; + +static struct resource se7780_mem_resource = { + .name = "SH7780_mem", + .start = SH7780_PCI_MEMORY_BASE, + .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM +}; + +extern struct pci_ops se7780_pci_ops; + +struct pci_channel board_pci_channels[] = { + { &sh4_pci_ops, &se7780_io_resource, &se7780_mem_resource, 0, 0xff }, + { NULL, NULL, NULL, 0, 0 }, +}; +EXPORT_SYMBOL(board_pci_channels); + +static struct sh4_pci_address_map se7780_pci_map = { + .window0 = { + .base = SH7780_CS2_BASE_ADDR, + .size = 0x04000000, + }, + .flags = SH4_PCIC_NO_RESET, +}; + +int __init pcibios_init_platform(void) +{ + printk("SH7780 PCI: Finished initialization of the PCI controller\n"); + + /* + * FPGA PCISEL register initialize + * + * CPU || SLOT1 | SLOT2 | S-ATA | USB + * ------------------------------------- + * INTA || INTA | INTD | -- | INTB + * ------------------------------------- + * INTB || INTB | INTA | -- | INTC + * ------------------------------------- + * INTC || INTC | INTB | INTA | -- + * ------------------------------------- + * INTD || INTD | INTC | -- | INTA + * ------------------------------------- + */ + ctrl_outw(0x0013, FPGA_PCI_INTSEL1); + ctrl_outw(0xE402, FPGA_PCI_INTSEL2); + + return sh7780_pcic_init(&se7780_pci_map); +} -- cgit v1.2.3-59-g8ed1b From 34a780a0afeb8f99c9ca9934f4cc0822541769c6 Mon Sep 17 00:00:00 2001 From: Kristoffer Ericson Date: Tue, 10 Apr 2007 07:45:08 +0900 Subject: sh: hp6xx pata_platform support. Drop the hd64461 I/O ops and wire up pata_platform for MMIO. Signed-off-by: Kristoffer Ericson Signed-off-by: Paul Mundt --- arch/sh/boards/hp6xx/setup.c | 67 ++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/hp6xx/setup.c b/arch/sh/boards/hp6xx/setup.c index b5a96649ed26..6aeee85c9785 100644 --- a/arch/sh/boards/hp6xx/setup.c +++ b/arch/sh/boards/hp6xx/setup.c @@ -2,6 +2,7 @@ * linux/arch/sh/boards/hp6xx/setup.c * * Copyright (C) 2002 Andriy Skulysh + * Copyright (C) 2007 Kristoffer Ericson * * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. @@ -10,6 +11,7 @@ */ #include #include +#include #include #include #include @@ -19,6 +21,40 @@ #define SCPCR 0xa4000116 #define SCPDR 0xa4000136 +/* CF Slot */ +static struct resource cf_ide_resources[] = { + [0] = { + .start = 0x15000000 + 0x1f0, + .end = 0x15000000 + 0x1f0 + 0x08 - 0x01, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 0x15000000 + 0x1fe, + .end = 0x15000000 + 0x1fe + 0x01, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = 93, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cf_ide_device = { + .name = "pata_platform", + .id = -1, + .num_resources = ARRAY_SIZE(cf_ide_resources), + .resource = cf_ide_resources, +}; + +static struct platform_device *hp6xx_devices[] __initdata = { + &cf_ide_device, +}; + +static int __init hp6xx_devices_setup(void) +{ + return platform_add_devices(hp6xx_devices, ARRAY_SIZE(hp6xx_devices)); +} + static void __init hp6xx_setup(char **cmdline_p) { u8 v8; @@ -60,41 +96,12 @@ static void __init hp6xx_setup(char **cmdline_p) v |= SCPCR_TS_ENABLE; ctrl_outw(v, SCPCR); } +device_initcall(hp6xx_devices_setup); -/* - * XXX: This is stupid, we should have a generic machine vector for the cchips - * and just wrap the platform setup code in to this, as it's the only thing - * that ends up being different. - */ struct sh_machine_vector mv_hp6xx __initmv = { .mv_name = "hp6xx", .mv_setup = hp6xx_setup, .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM, - - .mv_inb = hd64461_inb, - .mv_inw = hd64461_inw, - .mv_inl = hd64461_inl, - .mv_outb = hd64461_outb, - .mv_outw = hd64461_outw, - .mv_outl = hd64461_outl, - - .mv_inb_p = hd64461_inb_p, - .mv_inw_p = hd64461_inw, - .mv_inl_p = hd64461_inl, - .mv_outb_p = hd64461_outb_p, - .mv_outw_p = hd64461_outw, - .mv_outl_p = hd64461_outl, - - .mv_insb = hd64461_insb, - .mv_insw = hd64461_insw, - .mv_insl = hd64461_insl, - .mv_outsb = hd64461_outsb, - .mv_outsw = hd64461_outsw, - .mv_outsl = hd64461_outsl, - - .mv_readw = hd64461_readw, - .mv_writew = hd64461_writew, - .mv_irq_demux = hd64461_irq_demux, }; ALIAS_MV(hp6xx) -- cgit v1.2.3-59-g8ed1b From 1929cb340b74904c130fdf3de3fe5bbedb68a5aa Mon Sep 17 00:00:00 2001 From: dmitry pervushin Date: Tue, 24 Apr 2007 13:39:09 +0900 Subject: sh: SH7722 clock framework support. This adds support for the SH7722 (MobileR) to the clock framework. Signed-off-by: dmitry pervushin Signed-off-by: Paul Mundt --- Documentation/sh/clk.txt | 32 ++ arch/sh/kernel/cpu/clock.c | 28 +- arch/sh/kernel/cpu/sh4/clock-sh4-202.c | 3 +- arch/sh/kernel/cpu/sh4a/Makefile | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 600 +++++++++++++++++++++++++++++++++ include/asm-sh/clock.h | 32 +- include/asm-sh/cpu-sh4/freq.h | 4 + 7 files changed, 694 insertions(+), 7 deletions(-) create mode 100644 Documentation/sh/clk.txt create mode 100644 arch/sh/kernel/cpu/sh4a/clock-sh7722.c (limited to 'arch') diff --git a/Documentation/sh/clk.txt b/Documentation/sh/clk.txt new file mode 100644 index 000000000000..9aef710e9a4b --- /dev/null +++ b/Documentation/sh/clk.txt @@ -0,0 +1,32 @@ +Clock framework on SuperH architecture + +The framework on SH extends existing API by the function clk_set_rate_ex, +which prototype is as follows: + + clk_set_rate_ex (struct clk *clk, unsigned long rate, int algo_id) + +The algo_id parameter is used to specify algorithm used to recalculate clocks, +adjanced to clock, specified as first argument. It is assumed that algo_id==0 +means no changes to adjanced clock + +Internally, the clk_set_rate_ex forwards request to clk->ops->set_rate method, +if it is present in ops structure. The method should set the clock rate and adjust +all needed clocks according to the passed algo_id. +Exact values for algo_id are machine-dependend. For the sh7722, the following +values are defined: + + NO_CHANGE = 0, + IUS_N1_N1, /* I:U = N:1, U:Sh = N:1 */ + IUS_322, /* I:U:Sh = 3:2:2 */ + IUS_522, /* I:U:Sh = 5:2:2 */ + IUS_N11, /* I:U:Sh = N:1:1 */ + SB_N1, /* Sh:B = N:1 */ + SB3_N1, /* Sh:B3 = N:1 */ + SB3_32, /* Sh:B3 = 3:2 */ + SB3_43, /* Sh:B3 = 4:3 */ + SB3_54, /* Sh:B3 = 5:4 */ + BP_N1, /* B:P = N:1 */ + IP_N1 /* I:P = N:1 */ + +Each of these constants means relation between clocks that can be set via the FRQCR +register diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index abb586b12565..2075f90d76c7 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -98,13 +98,14 @@ int __clk_enable(struct clk *clk) if (clk->ops && clk->ops->init) clk->ops->init(clk); + kref_get(&clk->kref); + if (clk->flags & CLK_ALWAYS_ENABLED) return 0; if (likely(clk->ops && clk->ops->enable)) clk->ops->enable(clk); - kref_get(&clk->kref); return 0; } @@ -127,10 +128,15 @@ static void clk_kref_release(struct kref *kref) void __clk_disable(struct clk *clk) { + int count = kref_put(&clk->kref, clk_kref_release); + if (clk->flags & CLK_ALWAYS_ENABLED) return; - kref_put(&clk->kref, clk_kref_release); + if (!count) { /* count reaches zero, disable the clock */ + if (likely(clk->ops && clk->ops->disable)) + clk->ops->disable(clk); + } } void clk_disable(struct clk *clk) @@ -151,6 +157,15 @@ int clk_register(struct clk *clk) mutex_unlock(&clock_list_sem); + if (clk->flags & CLK_ALWAYS_ENABLED) { + pr_debug( "Clock '%s' is ALWAYS_ENABLED\n", clk->name); + if (clk->ops && clk->ops->init) + clk->ops->init(clk); + if (clk->ops && clk->ops->enable) + clk->ops->enable(clk); + pr_debug( "Enabled."); + } + return 0; } @@ -167,6 +182,11 @@ inline unsigned long clk_get_rate(struct clk *clk) } int clk_set_rate(struct clk *clk, unsigned long rate) +{ + return clk_set_rate_ex(clk, rate, 0); +} + +int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) { int ret = -EOPNOTSUPP; @@ -174,7 +194,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) unsigned long flags; spin_lock_irqsave(&clock_lock, flags); - ret = clk->ops->set_rate(clk, rate); + ret = clk->ops->set_rate(clk, rate, algo_id); spin_unlock_irqrestore(&clock_lock, flags); } @@ -256,7 +276,6 @@ int __init clk_init(void) arch_init_clk_ops(&clk->ops, i); ret |= clk_register(clk); - clk_enable(clk); } /* Kick the child clocks.. */ @@ -298,3 +317,4 @@ EXPORT_SYMBOL_GPL(__clk_disable); EXPORT_SYMBOL_GPL(clk_get_rate); EXPORT_SYMBOL_GPL(clk_set_rate); EXPORT_SYMBOL_GPL(clk_recalc_rate); +EXPORT_SYMBOL_GPL(clk_set_rate_ex); diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index fa2019aabd74..fcb2c41bc34e 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c @@ -82,7 +82,8 @@ static void shoc_clk_init(struct clk *clk) for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) { int divisor = frqcr3_divisors[i]; - if (clk->ops->set_rate(clk, clk->parent->rate / divisor) == 0) + if (clk->ops->set_rate(clk, clk->parent->rate / + divisor, 0) == 0) break; } diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile index 1efeda0e1829..ab7422f8f820 100644 --- a/arch/sh/kernel/cpu/sh4a/Makefile +++ b/arch/sh/kernel/cpu/sh4a/Makefile @@ -16,6 +16,6 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o -clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7343.o +clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o obj-y += $(clock-y) diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c new file mode 100644 index 000000000000..29090035bc5b --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -0,0 +1,600 @@ +/* + * arch/sh/kernel/cpu/sh4a/clock-sh7722.c + * + * SH7722 support for the clock framework + * + * Copyright (c) 2006-2007 Nomad Global Solutions Inc + * Based on code for sh7343 by Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include + +#define SH7722_PLL_FREQ (32000000/8) +#define N (-1) +#define NM (-2) +#define ROUND_NEAREST 0 +#define ROUND_DOWN -1 +#define ROUND_UP +1 + +static int adjust_algos[][3] = { + {}, /* NO_CHANGE */ + { NM, N, 1 }, /* N:1, N:1 */ + { 3, 2, 2 }, /* 3:2:2 */ + { 5, 2, 2 }, /* 5:2:2 */ + { N, 1, 1 }, /* N:1:1 */ + + { N, 1 }, /* N:1 */ + + { N, 1 }, /* N:1 */ + { 3, 2 }, + { 4, 3 }, + { 5, 4 }, + + { N, 1 } +}; + +static unsigned long adjust_pair_of_clocks(unsigned long r1, unsigned long r2, + int m1, int m2, int round_flag) +{ + unsigned long rem, div; + int the_one = 0; + + pr_debug( "Actual values: r1 = %ld\n", r1); + pr_debug( "...............r2 = %ld\n", r2); + + if (m1 == m2) { + r2 = r1; + pr_debug( "setting equal rates: r2 now %ld\n", r2); + } else if ((m2 == N && m1 == 1) || + (m2 == NM && m1 == N)) { /* N:1 or NM:N */ + pr_debug( "Setting rates as 1:N (N:N*M)\n"); + rem = r2 % r1; + pr_debug( "...remainder = %ld\n", rem); + if (rem) { + div = r2 / r1; + pr_debug( "...div = %ld\n", div); + switch (round_flag) { + case ROUND_NEAREST: + the_one = rem >= r1/2 ? 1 : 0; break; + case ROUND_UP: + the_one = 1; break; + case ROUND_DOWN: + the_one = 0; break; + } + + r2 = r1 * (div + the_one); + pr_debug( "...setting r2 to %ld\n", r2); + } + } else if ((m2 == 1 && m1 == N) || + (m2 == N && m1 == NM)) { /* 1:N or N:NM */ + pr_debug( "Setting rates as N:1 (N*M:N)\n"); + rem = r1 % r2; + pr_debug( "...remainder = %ld\n", rem); + if (rem) { + div = r1 / r2; + pr_debug( "...div = %ld\n", div); + switch (round_flag) { + case ROUND_NEAREST: + the_one = rem > r2/2 ? 1 : 0; break; + case ROUND_UP: + the_one = 0; break; + case ROUND_DOWN: + the_one = 1; break; + } + + r2 = r1 / (div + the_one); + pr_debug( "...setting r2 to %ld\n", r2); + } + } else { /* value:value */ + pr_debug( "Setting rates as %d:%d\n", m1, m2); + div = r1 / m1; + r2 = div * m2; + pr_debug( "...div = %ld\n", div); + pr_debug( "...setting r2 to %ld\n", r2); + } + + return r2; +} + +static void adjust_clocks(int originate, int *l, unsigned long v[], + int n_in_line) +{ + int x; + + pr_debug( "Go down from %d...\n", originate); + /* go up recalculation clocks */ + for (x = originate; x>0; x -- ) + v[x-1] = adjust_pair_of_clocks(v[x], v[x-1], + l[x], l[x-1], + ROUND_UP); + + pr_debug( "Go up from %d...\n", originate); + /* go down recalculation clocks */ + for (x = originate; xrate = CONFIG_SH_PCLK_FREQ * (1 + (frqcr >> 24 & 0xF)); +} + +static int master_clk_setrate(struct clk *clk, unsigned long rate, int id) +{ + int div = rate / SH7722_PLL_FREQ; + int master_divs[] = { 2, 3, 4, 6, 8, 16 }; + int index; + unsigned long frqcr; + + if (rate < SH7722_PLL_FREQ * 2) + return -EINVAL; + + for (index = 1; index < ARRAY_SIZE(master_divs); index++) + if (div >= master_divs[index - 1] && div < master_divs[index]) + break; + + if (index >= ARRAY_SIZE(master_divs)) + index = ARRAY_SIZE(master_divs); + div = master_divs[index - 1]; + + frqcr = ctrl_inl(FRQCR); + frqcr &= ~(0xF << 24); + frqcr |= ( (div-1) << 24); + ctrl_outl(frqcr, FRQCR); + + return 0; +} + +static struct clk_ops sh7722_master_clk_ops = { + .init = master_clk_init, + .recalc = master_clk_recalc, + .set_rate = master_clk_setrate, +}; + +struct frqcr_context { + unsigned mask; + unsigned shift; +}; + +struct frqcr_context sh7722_get_clk_context(const char *name) +{ + struct frqcr_context ctx = { 0, }; + + if (!strcmp(name, "peripheral_clk")) { + ctx.shift = 0; + ctx.mask = 0xF; + } else if (!strcmp(name, "sdram_clk")) { + ctx.shift = 4; + ctx.mask = 0xF; + } else if (!strcmp(name, "bus_clk")) { + ctx.shift = 8; + ctx.mask = 0xF; + } else if (!strcmp(name, "sh_clk")) { + ctx.shift = 12; + ctx.mask = 0xF; + } else if (!strcmp(name, "umem_clk")) { + ctx.shift = 16; + ctx.mask = 0xF; + } else if (!strcmp(name, "cpu_clk")) { + ctx.shift = 20; + ctx.mask = 7; + } + return ctx; +} + +/** + * sh7722_find_divisors - find divisor for setting rate + * + * All sh7722 clocks use the same set of multipliers/divisors. This function + * chooses correct divisor to set the rate of clock with parent clock that + * generates frequency of 'parent_rate' + * + * @parent_rate: rate of parent clock + * @rate: requested rate to be set + */ +static int sh7722_find_divisors(unsigned long parent_rate, unsigned rate) +{ + unsigned div2 = parent_rate * 2 / rate; + int index; + + if (rate > parent_rate) + return -EINVAL; + + for (index = 1; index < ARRAY_SIZE(divisors2); index++) { + if (div2 > divisors2[index] && div2 <= divisors2[index]) + break; + } + if (index >= ARRAY_SIZE(divisors2)) + index = ARRAY_SIZE(divisors2) - 1; + return divisors2[index]; +} + +static void sh7722_frqcr_recalc(struct clk *clk) +{ + struct frqcr_context ctx = sh7722_get_clk_context(clk->name); + unsigned long frqcr = ctrl_inl(FRQCR); + int index; + + index = (frqcr >> ctx.shift) & ctx.mask; + clk->rate = clk->parent->rate * 2 / divisors2[index]; +} + +static int sh7722_frqcr_set_rate(struct clk *clk, unsigned long rate, + int algo_id) +{ + struct frqcr_context ctx = sh7722_get_clk_context(clk->name); + unsigned long parent_rate = clk->parent->rate; + int div; + unsigned long frqcr; + int err = 0; + + /* pretty invalid */ + if (parent_rate < rate) + return -EINVAL; + + /* look for multiplier/divisor pair */ + div = sh7722_find_divisors(parent_rate, rate); + if (div<0) + return div; + + /* calculate new value of clock rate */ + clk->rate = parent_rate * 2 / div; + frqcr = ctrl_inl(FRQCR); + + /* FIXME: adjust as algo_id specifies */ + if (algo_id != NO_CHANGE) { + int originator; + char *algo_group_1[] = { "cpu_clk", "umem_clk", "sh_clk" }; + char *algo_group_2[] = { "sh_clk", "bus_clk" }; + char *algo_group_3[] = { "sh_clk", "sdram_clk" }; + char *algo_group_4[] = { "bus_clk", "peripheral_clk" }; + char *algo_group_5[] = { "cpu_clk", "peripheral_clk" }; + char **algo_current = NULL; + /* 3 is the maximum number of clocks in relation */ + struct clk *ck[3]; + unsigned long values[3]; /* the same comment as above */ + int part_length = -1; + int i; + + /* + * all the steps below only required if adjustion was + * requested + */ + if (algo_id == IUS_N1_N1 || + algo_id == IUS_322 || + algo_id == IUS_522 || + algo_id == IUS_N11) { + algo_current = algo_group_1; + part_length = 3; + } + if (algo_id == SB_N1) { + algo_current = algo_group_2; + part_length = 2; + } + if (algo_id == SB3_N1 || + algo_id == SB3_32 || + algo_id == SB3_43 || + algo_id == SB3_54) { + algo_current = algo_group_3; + part_length = 2; + } + if (algo_id == BP_N1) { + algo_current = algo_group_4; + part_length = 2; + } + if (algo_id == IP_N1) { + algo_current = algo_group_5; + part_length = 2; + } + if (!algo_current) + goto incorrect_algo_id; + + originator = -1; + for (i = 0; i < part_length; i ++ ) { + if (originator >= 0 && !strcmp(clk->name, + algo_current[i])) + originator = i; + ck[i] = clk_get(NULL, algo_current[i]); + values[i] = clk_get_rate(ck[i]); + } + + if (originator >= 0) + adjust_clocks(originator, adjust_algos[algo_id], + values, part_length); + + for (i = 0; i < part_length; i ++ ) { + struct frqcr_context part_ctx; + int part_div; + + if (likely(!err)) { + part_div = sh7722_find_divisors(parent_rate, + rate); + if (part_div > 0) { + part_ctx = sh7722_get_clk_context( + ck[i]->name); + frqcr &= ~(part_ctx.mask << + part_ctx.shift); + frqcr |= part_div << part_ctx.shift; + } else + err = part_div; + } + + ck[i]->ops->recalc(ck[i]); + clk_put(ck[i]); + } + } + + /* was there any error during recalculation ? If so, bail out.. */ + if (unlikely(err!=0)) + goto out_err; + + /* clear FRQCR bits */ + frqcr &= ~(ctx.mask << ctx.shift); + frqcr |= div << ctx.shift; + + /* ...and perform actual change */ + ctrl_outl(frqcr, FRQCR); + return 0; + +incorrect_algo_id: + return -EINVAL; +out_err: + return err; +} + +static struct clk_ops sh7722_frqcr_clk_ops = { + .recalc = sh7722_frqcr_recalc, + .set_rate = sh7722_frqcr_set_rate, +}; + +/* + * clock ops methods for SIU A/B and IrDA clock + * + */ +static int sh7722_siu_which(struct clk *clk) +{ + if (!strcmp(clk->name, "siu_a_clk")) + return 0; + if (!strcmp(clk->name, "siu_b_clk")) + return 1; + if (!strcmp(clk->name, "irda_clk")) + return 2; + return -EINVAL; +} + +static unsigned long sh7722_siu_regs[] = { + [0] = SCLKACR, + [1] = SCLKBCR, + [2] = IrDACLKCR, +}; + +static int sh7722_siu_start_stop(struct clk *clk, int enable) +{ + int siu = sh7722_siu_which(clk); + unsigned long r; + + if (siu < 0) + return siu; + BUG_ON(siu > 2); + r = ctrl_inl(sh7722_siu_regs[siu]); + if (enable) + ctrl_outl(r & ~(1 << 8), sh7722_siu_regs[siu]); + else + ctrl_outl(r | (1 << 8), sh7722_siu_regs[siu]); + return 0; +} + +static void sh7722_siu_enable(struct clk *clk) +{ + sh7722_siu_start_stop(clk, 1); +} + +static void sh7722_siu_disable(struct clk *clk) +{ + sh7722_siu_start_stop(clk, 0); +} + +static void sh7722_video_enable(struct clk *clk) +{ + unsigned long r; + + r = ctrl_inl(VCLKCR); + ctrl_outl( r & ~(1<<8), VCLKCR); +} + +static void sh7722_video_disable(struct clk *clk) +{ + unsigned long r; + + r = ctrl_inl(VCLKCR); + ctrl_outl( r | (1<<8), VCLKCR); +} + +static int sh7722_video_set_rate(struct clk *clk, unsigned long rate, + int algo_id) +{ + unsigned long r; + + r = ctrl_inl(VCLKCR); + r &= ~0x3F; + r |= ((clk->parent->rate / rate - 1) & 0x3F); + ctrl_outl(r, VCLKCR); + return 0; +} + +static void sh7722_video_recalc(struct clk *clk) +{ + unsigned long r; + + r = ctrl_inl(VCLKCR); + clk->rate = clk->parent->rate / ((r & 0x3F) + 1); +} + +static int sh7722_siu_set_rate(struct clk *clk, unsigned long rate, int algo_id) +{ + int siu = sh7722_siu_which(clk); + unsigned long r; + int div; + + if (siu < 0) + return siu; + BUG_ON(siu > 2); + r = ctrl_inl(sh7722_siu_regs[siu]); + div = sh7722_find_divisors(clk->parent->rate, rate); + if (div < 0) + return div; + r = (r & ~0xF) | div; + ctrl_outl(r, sh7722_siu_regs[siu]); + return 0; +} + +static void sh7722_siu_recalc(struct clk *clk) +{ + int siu = sh7722_siu_which(clk); + unsigned long r; + + if (siu < 0) + return /* siu */ ; + BUG_ON(siu > 1); + r = ctrl_inl(sh7722_siu_regs[siu]); + clk->rate = clk->parent->rate * 2 / divisors2[r & 0xF]; +} + +static struct clk_ops sh7722_siu_clk_ops = { + .recalc = sh7722_siu_recalc, + .set_rate = sh7722_siu_set_rate, + .enable = sh7722_siu_enable, + .disable = sh7722_siu_disable, +}; + +static struct clk_ops sh7722_video_clk_ops = { + .recalc = sh7722_video_recalc, + .set_rate = sh7722_video_set_rate, + .enable = sh7722_video_enable, + .disable = sh7722_video_disable, +}; +/* + * and at last, clock definitions themselves + */ +static struct clk sh7722_umem_clock = { + .name = "umem_clk", + .ops = &sh7722_frqcr_clk_ops, +}; + +static struct clk sh7722_sh_clock = { + .name = "sh_clk", + .ops = &sh7722_frqcr_clk_ops, +}; + +static struct clk sh7722_peripheral_clock = { + .name = "peripheral_clk", + .ops = &sh7722_frqcr_clk_ops, +}; + +static struct clk sh7722_sdram_clock = { + .name = "sdram_clk", + .ops = &sh7722_frqcr_clk_ops, +}; + +/* + * these three clocks - SIU A, SIU B, IrDA - share the same clk_ops + * methods of clk_ops determine which register they should access by + * examining clk->name field + */ +static struct clk sh7722_siu_a_clock = { + .name = "siu_a_clk", + .ops = &sh7722_siu_clk_ops, +}; + +static struct clk sh7722_siu_b_clock = { + .name = "siu_b_clk", + .ops = &sh7722_siu_clk_ops, +}; + +static struct clk sh7722_irda_clock = { + .name = "irda_clk", + .ops = &sh7722_siu_clk_ops, +}; + +static struct clk sh7722_video_clock = { + .name = "video_clk", + .ops = &sh7722_video_clk_ops, +}; + +static struct clk *sh7722_clocks[] = { + &sh7722_umem_clock, + &sh7722_sh_clock, + &sh7722_peripheral_clock, + &sh7722_sdram_clock, + &sh7722_siu_a_clock, + &sh7722_siu_b_clock, + &sh7722_irda_clock, + &sh7722_video_clock, +}; + +/* + * init in order: master, module, bus, cpu + */ +struct clk_ops *onchip_ops[] = { + &sh7722_master_clk_ops, + &sh7722_frqcr_clk_ops, + &sh7722_frqcr_clk_ops, + &sh7722_frqcr_clk_ops, +}; + +void __init +arch_init_clk_ops(struct clk_ops **ops, int type) +{ + BUG_ON(type < 0 || type > ARRAY_SIZE(onchip_ops)); + *ops = onchip_ops[type]; +} + +int __init sh7722_clock_init(void) +{ + struct clk *master; + int i; + + master = clk_get(NULL, "master_clk"); + for (i = 0; i < ARRAY_SIZE(sh7722_clocks); i++) { + pr_debug( "Registering clock '%s'\n", sh7722_clocks[i]->name); + sh7722_clocks[i]->parent = master; + clk_register(sh7722_clocks[i]); + } + clk_put(master); + return 0; +} +arch_initcall(sh7722_clock_init); diff --git a/include/asm-sh/clock.h b/include/asm-sh/clock.h index 1df92807f8c5..a5d629f090d4 100644 --- a/include/asm-sh/clock.h +++ b/include/asm-sh/clock.h @@ -13,7 +13,7 @@ struct clk_ops { void (*enable)(struct clk *clk); void (*disable)(struct clk *clk); void (*recalc)(struct clk *clk); - int (*set_rate)(struct clk *clk, unsigned long rate); + int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id); }; struct clk { @@ -50,4 +50,34 @@ void clk_unregister(struct clk *); int show_clocks(struct seq_file *m); +/* the exported API, in addition to clk_set_rate */ +/** + * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter + * @clk: clock source + * @rate: desired clock rate in Hz + * @algo_id: algorithm id to be passed down to ops->set_rate + * + * Returns success (0) or negative errno. + */ +int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id); + +enum clk_sh_algo_id { + NO_CHANGE = 0, + + IUS_N1_N1, + IUS_322, + IUS_522, + IUS_N11, + + SB_N1, + + SB3_N1, + SB3_32, + SB3_43, + SB3_54, + + BP_N1, + + IP_N1, +}; #endif /* __ASM_SH_CLOCK_H */ diff --git a/include/asm-sh/cpu-sh4/freq.h b/include/asm-sh/cpu-sh4/freq.h index 99402547ed06..86564e7a26ae 100644 --- a/include/asm-sh/cpu-sh4/freq.h +++ b/include/asm-sh/cpu-sh4/freq.h @@ -12,6 +12,10 @@ #if defined(CONFIG_CPU_SUBTYPE_SH73180) || defined(CONFIG_CPU_SUBTYPE_SH7722) #define FRQCR 0xa4150000 +#define VCLKCR 0xa4150004 +#define SCLKACR 0xa4150008 +#define SCLKBCR 0xa415000c +#define IrDACLKCR 0xa4150010 #elif defined(CONFIG_CPU_SUBTYPE_SH7780) #define FRQCR 0xffc80000 #elif defined(CONFIG_CPU_SUBTYPE_SH7785) -- cgit v1.2.3-59-g8ed1b From 2a8ff4596cde3ec2a51980288ebb28a0d196d19a Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Thu, 26 Apr 2007 11:51:00 +0900 Subject: sh: Solution Engine SH7705 board and CPU updates. This fixes up SH7705 CPU support and the SE7705 board for some of the recent changes. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt --- arch/sh/Kconfig.debug | 2 +- arch/sh/boards/se/770x/irq.c | 32 +++++----- arch/sh/boards/se/770x/setup.c | 2 +- arch/sh/configs/se7705_defconfig | 106 ++++++++++++++++++++++++++++------ arch/sh/kernel/cpu/irq/Makefile | 2 +- arch/sh/kernel/cpu/irq/pint.c | 56 +++++++++++++++++- arch/sh/kernel/cpu/sh3/setup-sh7705.c | 54 +++++++++++++++-- arch/sh/mm/Kconfig | 1 + include/asm-sh/se.h | 5 +- 9 files changed, 215 insertions(+), 45 deletions(-) (limited to 'arch') diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index be60def6f306..b56307294b67 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -33,7 +33,7 @@ config EARLY_SCIF_CONSOLE_PORT default "0xffe00000" if CPU_SUBTYPE_SH7780 default "0xfffe9800" if CPU_SUBTYPE_SH7206 default "0xf8420000" if CPU_SUBTYPE_SH7619 - default "0xa4400000" if CPU_SUBTYPE_SH7712 + default "0xa4400000" if CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7705 default "0xffe80000" if CPU_SH4 config EARLY_PRINTK diff --git a/arch/sh/boards/se/770x/irq.c b/arch/sh/boards/se/770x/irq.c index 59cdffa13964..c8eccff77a04 100644 --- a/arch/sh/boards/se/770x/irq.c +++ b/arch/sh/boards/se/770x/irq.c @@ -65,24 +65,24 @@ static struct ipr_data se770x_ipr_map[] = { * 8: rtc * 12: mouse * 14: ide0 - */ + */ #if defined(CONFIG_CPU_SUBTYPE_SH7705) /* This is default value */ - { 0xf-0x2, 0, 8, 0x2 , BCR_ILCRA}, - { 0xf-0xa, 0, 4, 0xa , BCR_ILCRA}, - { 0xf-0x5, 0, 0, 0x5 , BCR_ILCRB}, - { 0xf-0x8, 0, 4, 0x8 , BCR_ILCRC}, - { 0xf-0xc, 0, 0, 0xc , BCR_ILCRC}, - { 0xf-0xe, 0, 12, 0xe , BCR_ILCRD}, - { 0xf-0x3, 0, 4, 0x3 , BCR_ILCRD}, /* LAN */ - { 0xf-0xd, 0, 8, 0xd , BCR_ILCRE}, - { 0xf-0x9, 0, 4, 0x9 , BCR_ILCRE}, - { 0xf-0x1, 0, 0, 0x1 , BCR_ILCRE}, - { 0xf-0xf, 0, 12, 0xf , BCR_ILCRF}, - { 0xf-0xb, 0, 4, 0xb , BCR_ILCRF}, - { 0xf-0x7, 0, 12, 0x7 , BCR_ILCRG}, - { 0xf-0x6, 0, 8, 0x6 , BCR_ILCRG}, - { 0xf-0x4, 0, 4, 0x4 , BCR_ILCRG}, + { 13, 0, 8, 0x0f-13 ,BCR_ILCRA}, + { 5 , 0, 4, 0x0f- 5 ,BCR_ILCRA}, + { 10, 0, 0, 0x0f-10, BCR_ILCRB}, + { 7 , 0, 4, 0x0f- 7, BCR_ILCRC}, + { 3 , 0, 0, 0x0f- 3, BCR_ILCRC}, + { 1 , 0, 12, 0x0f- 1, BCR_ILCRD}, + { 12, 0, 4, 0x0f-12, BCR_ILCRD}, /* LAN */ + { 2 , 0, 8, 0x0f- 2, BCR_ILCRE}, /* PCIRQ2 */ + { 6 , 0, 4, 0x0f- 6, BCR_ILCRE}, /* PCIRQ1 */ + { 14, 0, 0, 0x0f-14, BCR_ILCRE}, /* PCIRQ0 */ + { 0 , 0, 12, 0x0f , BCR_ILCRF}, + { 4 , 0, 4, 0x0f- 4, BCR_ILCRF}, + { 8 , 0, 12, 0x0f- 8, BCR_ILCRG}, + { 9 , 0, 8, 0x0f- 9, BCR_ILCRG}, + { 11, 0, 4, 0x0f-11, BCR_ILCRG}, #else { 14, 0, 8, 0x0f-14 ,BCR_ILCRA}, { 12, 0, 4, 0x0f-12 ,BCR_ILCRA}, diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c index f1c7c8d9fdd2..17a2631de3ba 100644 --- a/arch/sh/boards/se/770x/setup.c +++ b/arch/sh/boards/se/770x/setup.c @@ -76,7 +76,7 @@ static struct resource cf_ide_resources[] = { .flags = IORESOURCE_MEM, }, [2] = { - .start = 7, + .start = IRQ_CFCARD, .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig index 06ebd6ec0cdb..87ae5c1f8629 100644 --- a/arch/sh/configs/se7705_defconfig +++ b/arch/sh/configs/se7705_defconfig @@ -1,15 +1,21 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18 -# Tue Oct 3 12:03:04 2006 +# Linux kernel version: 2.6.21-rc5 +# Thu Apr 26 09:16:31 2007 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_BUG=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME is not set +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -33,7 +39,9 @@ CONFIG_LOCALVERSION_AUTO=y # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -91,27 +99,30 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_SOLUTION_ENGINE=y CONFIG_SH_SOLUTION_ENGINE=y # CONFIG_SH_7751_SOLUTION_ENGINE is not set +# CONFIG_SH_7780_SOLUTION_ENGINE is not set # CONFIG_SH_7300_SOLUTION_ENGINE is not set # CONFIG_SH_7343_SOLUTION_ENGINE is not set # CONFIG_SH_73180_SOLUTION_ENGINE is not set +# CONFIG_SH_7722_SOLUTION_ENGINE is not set # CONFIG_SH_7751_SYSTEMH is not set # CONFIG_SH_HP6XX is not set -# CONFIG_SH_EC3104 is not set # CONFIG_SH_SATURN is not set # CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_BIGSUR is not set # CONFIG_SH_MPC1211 is not set # CONFIG_SH_SH03 is not set # CONFIG_SH_SECUREEDGE5410 is not set # CONFIG_SH_HS7751RVOIP is not set # CONFIG_SH_7710VOIPGW is not set # CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_R7780RP is not set +# CONFIG_SH_HIGHLANDER is not set # CONFIG_SH_EDOSK7705 is not set # CONFIG_SH_SH4202_MICRODEV is not set # CONFIG_SH_LANDISK is not set # CONFIG_SH_TITAN is not set # CONFIG_SH_SHMIN is not set +# CONFIG_SH_7206_SOLUTION_ENGINE is not set +# CONFIG_SH_7619_SOLUTION_ENGINE is not set +# CONFIG_SH_LBOX_RE2 is not set # CONFIG_SH_UNKNOWN is not set # @@ -123,6 +134,12 @@ CONFIG_CPU_SH3=y # SH-2 Processor Support # # CONFIG_CPU_SUBTYPE_SH7604 is not set +# CONFIG_CPU_SUBTYPE_SH7619 is not set + +# +# SH-2A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7206 is not set # # SH-3 Processor Support @@ -134,6 +151,7 @@ CONFIG_CPU_SUBTYPE_SH7705=y # CONFIG_CPU_SUBTYPE_SH7708 is not set # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7710 is not set +# CONFIG_CPU_SUBTYPE_SH7712 is not set # # SH-4 Processor Support @@ -158,12 +176,14 @@ CONFIG_CPU_SUBTYPE_SH7705=y # # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set +# CONFIG_CPU_SUBTYPE_SH7785 is not set # # SH4AL-DSP Processor Support # # CONFIG_CPU_SUBTYPE_SH73180 is not set # CONFIG_CPU_SUBTYPE_SH7343 is not set +# CONFIG_CPU_SUBTYPE_SH7722 is not set # # Memory management options @@ -173,6 +193,11 @@ CONFIG_PAGE_OFFSET=0x80000000 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x02000000 CONFIG_VSYSCALL=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -182,6 +207,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 # # Cache configuration @@ -190,23 +216,31 @@ CONFIG_SH7705_CACHE_32KB=y # CONFIG_SH_DIRECT_MAPPED is not set # CONFIG_SH_WRITETHROUGH is not set # CONFIG_SH_OCRAM is not set -# CONFIG_CF_ENABLER is not set +CONFIG_CF_ENABLER=y +# CONFIG_CF_AREA5 is not set +CONFIG_CF_AREA6=y +# CONFIG_CF_AREA4 is not set +CONFIG_CF_BASE_ADDR=0xb8000000 # # Processor features # CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set # CONFIG_SH_FPU_EMU is not set # CONFIG_SH_DSP is not set # CONFIG_SH_ADC is not set CONFIG_CPU_HAS_INTEVT=y CONFIG_CPU_HAS_PINT_IRQ=y +CONFIG_CPU_HAS_IPR_IRQ=y CONFIG_CPU_HAS_SR_RB=y # -# Timer support +# Timer and clock configuration # CONFIG_SH_TMU=y +CONFIG_SH_TIMER_IRQ=16 +# CONFIG_NO_IDLE_HZ is not set CONFIG_SH_PCLK_FREQ=33333333 # @@ -223,13 +257,19 @@ CONFIG_SH_PCLK_FREQ=33333333 # Companion Chips # # CONFIG_HD6446X_SERIES is not set + +# +# Additional SuperH Device Drivers +# CONFIG_HEARTBEAT=y +# CONFIG_PUSH_SWITCH is not set # # Kernel features # # CONFIG_HZ_100 is not set CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 # CONFIG_KEXEC is not set @@ -287,6 +327,7 @@ CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -307,11 +348,13 @@ CONFIG_IP_PNP_RARP=y # CONFIG_INET_TUNNEL is not set CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set @@ -388,6 +431,7 @@ CONFIG_MTD_PARTITIONS=y # User Modules And Translation Layers # CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set @@ -461,6 +505,7 @@ CONFIG_MTD_CFI_UTIL=y # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -472,10 +517,13 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set +# +# Misc devices +# + # # ATA/ATAPI/MFM/RLL support # @@ -649,17 +697,12 @@ CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# # CONFIG_RAW_DRIVER is not set # # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support @@ -675,6 +718,7 @@ CONFIG_HW_RANDOM=y # # Dallas's 1-wire bus # +# CONFIG_W1 is not set # # Hardware Monitoring support @@ -683,18 +727,19 @@ CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_HWMON_DEBUG_CHIP is not set # -# Misc devices +# Multifunction device drivers # +# CONFIG_MFD_SM501 is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -704,7 +749,7 @@ CONFIG_VIDEO_V4L2=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # CONFIG_FB is not set # @@ -712,6 +757,12 @@ CONFIG_FIRMWARE_EDID=y # # CONFIG_SOUND is not set +# +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + # # USB support # @@ -772,6 +823,14 @@ CONFIG_FIRMWARE_EDID=y # DMA Devices # +# +# Auxiliary Display support +# + +# +# Virtualization +# + # # File systems # @@ -779,10 +838,12 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y @@ -828,7 +889,6 @@ CONFIG_RAMFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y @@ -877,6 +937,10 @@ CONFIG_MSDOS_PARTITION=y # # CONFIG_NLS is not set +# +# Distributed Lock Manager +# + # # Profiling support # @@ -885,15 +949,18 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_KGDB is not set +# CONFIG_EARLY_SCIF_CONSOLE is not set +# CONFIG_SH_KGDB is not set # # Security options @@ -908,6 +975,7 @@ CONFIG_LOG_BUF_SHIFT=14 # # Library routines # +CONFIG_BITREVERSE=y CONFIG_CRC_CCITT=y # CONFIG_CRC16 is not set CONFIG_CRC32=y @@ -915,3 +983,5 @@ CONFIG_CRC32=y CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y diff --git a/arch/sh/kernel/cpu/irq/Makefile b/arch/sh/kernel/cpu/irq/Makefile index 0049d217561a..1c23308cfc25 100644 --- a/arch/sh/kernel/cpu/irq/Makefile +++ b/arch/sh/kernel/cpu/irq/Makefile @@ -4,6 +4,6 @@ obj-y += imask.o obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o -obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o +obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o diff --git a/arch/sh/kernel/cpu/irq/pint.c b/arch/sh/kernel/cpu/irq/pint.c index f60007783a21..67602685df1a 100644 --- a/arch/sh/kernel/cpu/irq/pint.c +++ b/arch/sh/kernel/cpu/irq/pint.c @@ -18,6 +18,58 @@ #include #include +#if defined(CONFIG_CPU_SUBTYPE_SH7705) +#define INTC_INTER 0xA4000014UL +#define INTC_IPRD 0xA4000018UL +#define INTC_ICR2 0xA4000012UL + +/* PFC */ +#define PORT_PACR 0xA4000100UL +#define PORT_PBCR 0xA4000102UL +#define PORT_PCCR 0xA4000104UL +#define PORT_PDCR 0xA4000106UL +#define PORT_PECR 0xA4000108UL +#define PORT_PFCR 0xA400010AUL +#define PORT_PGCR 0xA400010CUL +#define PORT_PHCR 0xA400010EUL +#define PORT_PJCR 0xA4000110UL +#define PORT_PKCR 0xA4000112UL +#define PORT_PLCR 0xA4000114UL +#define PORT_PMCR 0xA4000118UL +#define PORT_PNCR 0xA400011AUL +#define PORT_PECR2 0xA4050148UL +#define PORT_PFCR2 0xA405014AUL +#define PORT_PNCR2 0xA405015AUL + +/* I/O port */ +#define PORT_PADR 0xA4000120UL +#define PORT_PBDR 0xA4000122UL +#define PORT_PCDR 0xA4000124UL +#define PORT_PDDR 0xA4000126UL +#define PORT_PEDR 0xA4000128UL +#define PORT_PFDR 0xA400012AUL +#define PORT_PGDR 0xA400012CUL +#define PORT_PHDR 0xA400012EUL +#define PORT_PJDR 0xA4000130UL +#define PORT_PKDR 0xA4000132UL +#define PORT_PLDR 0xA4000134UL +#define PORT_PMDR 0xA4000138UL +#define PORT_PNDR 0xA400013AUL + +#define PINT0_IRQ 40 +#define PINT8_IRQ 41 +#define PINT_IRQ_BASE 86 + +#define PINT0_IPR_ADDR INTC_IPRD +#define PINT0_IPR_POS 3 +#define PINT0_PRIORITY 2 + +#define PINT8_IPR_ADDR INTC_IPRD +#define PINT8_IPR_POS 2 +#define PINT8_PRIORITY 2 + +#endif /* CONFIG_CPU_SUBTYPE_SH7705 */ + static unsigned char pint_map[256]; static unsigned long portcr_mask; @@ -126,7 +178,7 @@ int ipr_irq_demux(int irq) unsigned long creg, dreg, d, sav; if (irq == PINT0_IRQ) { -#if defined(CONFIG_CPU_SUBTYPE_SH7707) +#if defined(CONFIG_CPU_SUBTYPE_SH7705) || defined(CONFIG_CPU_SUBTYPE_SH7707) creg = PORT_PACR; dreg = PORT_PADR; #else @@ -144,7 +196,7 @@ int ipr_irq_demux(int irq) return PINT_IRQ_BASE + pint_map[d]; } else if (irq == PINT8_IRQ) { -#if defined(CONFIG_CPU_SUBTYPE_SH7707) +#if defined(CONFIG_CPU_SUBTYPE_SH7705) || defined(CONFIG_CPU_SUBTYPE_SH7707) creg = PORT_PBCR; dreg = PORT_PBDR; #else diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index a8e41c5241fa..1983fb7ad6ea 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -2,6 +2,7 @@ * SH7705 Setup * * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2007 Nobuhiro Iwamatsu * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -14,15 +15,15 @@ static struct plat_sci_port sci_platform_data[] = { { - .mapbase = 0xa4400000, + .mapbase = 0xa4410000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 52, 53, 55, 54 }, + .irqs = { 56, 57, 59 }, }, { - .mapbase = 0xa4410000, + .mapbase = 0xa4400000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 56, 57, 59, 58 }, + .irqs = { 52, 53, 55 }, }, { .flags = 0, } @@ -46,3 +47,48 @@ static int __init sh7705_devices_setup(void) ARRAY_SIZE(sh7705_devices)); } __initcall(sh7705_devices_setup); + +static struct ipr_data sh7705_ipr_map[] = { + /* IRQ, IPR-idx, shift, priority */ + { 16, 0, 12, 2 }, /* TMU0 TUNI*/ + { 17, 0, 8, 2 }, /* TMU1 TUNI */ + { 18, 0, 4, 2 }, /* TMU2 TUNI */ + { 27, 1, 12, 2 }, /* WDT ITI */ + { 20, 0, 0, 2 }, /* RTC ATI (alarm) */ + { 21, 0, 0, 2 }, /* RTC PRI (period) */ + { 22, 0, 0, 2 }, /* RTC CUI (carry) */ + { 48, 4, 12, 7 }, /* DMAC DMTE0 */ + { 49, 4, 12, 7 }, /* DMAC DMTE1 */ + { 50, 4, 12, 7 }, /* DMAC DMTE2 */ + { 51, 4, 12, 7 }, /* DMAC DMTE3 */ + { 52, 4, 8, 3 }, /* SCIF0 ERI */ + { 53, 4, 8, 3 }, /* SCIF0 RXI */ + { 55, 4, 8, 3 }, /* SCIF0 TXI */ + { 56, 4, 4, 3 }, /* SCIF1 ERI */ + { 57, 4, 4, 3 }, /* SCIF1 RXI */ + { 59, 4, 4, 3 }, /* SCIF1 TXI */ +}; + +static unsigned long ipr_offsets[] = { + 0xFFFFFEE2 /* 0: IPRA */ +, 0xFFFFFEE4 /* 1: IPRB */ +, 0xA4000016 /* 2: IPRC */ +, 0xA4000018 /* 3: IPRD */ +, 0xA400001A /* 4: IPRE */ +, 0xA4080000 /* 5: IPRF */ +, 0xA4080002 /* 6: IPRG */ +, 0xA4080004 /* 7: IPRH */ +}; + +/* given the IPR index return the address of the IPR register */ +unsigned int map_ipridx_to_addr(int idx) +{ + if (idx >= ARRAY_SIZE(ipr_offsets)) + return 0; + return ipr_offsets[idx]; +} + +void __init init_IRQ_ipr() +{ + make_ipr_irq(sh7705_ipr_map, ARRAY_SIZE(sh7705_ipr_map)); +} diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 5359f3dff93c..12f3d394dc28 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -67,6 +67,7 @@ config CPU_SUBTYPE_SH7300 config CPU_SUBTYPE_SH7705 bool "Support SH7705 processor" select CPU_SH3 + select CPU_HAS_IPR_IRQ select CPU_HAS_PINT_IRQ config CPU_SUBTYPE_SH7706 diff --git a/include/asm-sh/se.h b/include/asm-sh/se.h index eeaf5c9124cc..bd2596c014a9 100644 --- a/include/asm-sh/se.h +++ b/include/asm-sh/se.h @@ -69,11 +69,12 @@ #define BCR_ILCRG (PA_BCR + 12) #if defined(CONFIG_CPU_SUBTYPE_SH7705) -#define IRQ_STNIC 12 +#define IRQ_STNIC 12 +#define IRQ_CFCARD 14 #else #define IRQ_STNIC 10 +#define IRQ_CFCARD 7 #endif -#define IRQ_CFCARD 7 #define __IO_PREFIX se #include -- cgit v1.2.3-59-g8ed1b From db62e5bd297d1f325811c5495ad23de36db0fdd4 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 26 Apr 2007 12:17:20 +0900 Subject: sh: Move clock reporting to its own proc entry. Previously this was done in cpuinfo, but with the number of clocks growing, it makes more sense to place this in a different proc entry. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock.c | 76 +++++++++++++++++++++++++++------------------- arch/sh/kernel/setup.c | 2 +- include/asm-sh/clock.h | 2 -- 3 files changed, 46 insertions(+), 34 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 2075f90d76c7..014f318f5a05 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -1,7 +1,7 @@ /* * arch/sh/kernel/cpu/clock.c - SuperH clock framework * - * Copyright (C) 2005, 2006 Paul Mundt + * Copyright (C) 2005, 2006, 2007 Paul Mundt * * This clock framework is derived from the OMAP version by: * @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -108,6 +109,7 @@ int __clk_enable(struct clk *clk) return 0; } +EXPORT_SYMBOL_GPL(__clk_enable); int clk_enable(struct clk *clk) { @@ -120,6 +122,7 @@ int clk_enable(struct clk *clk) return ret; } +EXPORT_SYMBOL_GPL(clk_enable); static void clk_kref_release(struct kref *kref) { @@ -138,6 +141,7 @@ void __clk_disable(struct clk *clk) clk->ops->disable(clk); } } +EXPORT_SYMBOL_GPL(__clk_disable); void clk_disable(struct clk *clk) { @@ -147,6 +151,7 @@ void clk_disable(struct clk *clk) __clk_disable(clk); spin_unlock_irqrestore(&clock_lock, flags); } +EXPORT_SYMBOL_GPL(clk_disable); int clk_register(struct clk *clk) { @@ -168,6 +173,7 @@ int clk_register(struct clk *clk) return 0; } +EXPORT_SYMBOL_GPL(clk_register); void clk_unregister(struct clk *clk) { @@ -175,16 +181,19 @@ void clk_unregister(struct clk *clk) list_del(&clk->node); mutex_unlock(&clock_list_sem); } +EXPORT_SYMBOL_GPL(clk_unregister); -inline unsigned long clk_get_rate(struct clk *clk) +unsigned long clk_get_rate(struct clk *clk) { return clk->rate; } +EXPORT_SYMBOL_GPL(clk_get_rate); int clk_set_rate(struct clk *clk, unsigned long rate) { return clk_set_rate_ex(clk, rate, 0); } +EXPORT_SYMBOL_GPL(clk_set_rate); int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) { @@ -203,6 +212,7 @@ int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) return ret; } +EXPORT_SYMBOL_GPL(clk_set_rate_ex); void clk_recalc_rate(struct clk *clk) { @@ -217,6 +227,7 @@ void clk_recalc_rate(struct clk *clk) if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) propagate_rate(clk); } +EXPORT_SYMBOL_GPL(clk_recalc_rate); /* * Returns a clock. Note that we first try to use device id on the bus @@ -253,18 +264,43 @@ found: return clk; } +EXPORT_SYMBOL_GPL(clk_get); void clk_put(struct clk *clk) { if (clk && !IS_ERR(clk)) module_put(clk->owner); } +EXPORT_SYMBOL_GPL(clk_put); void __init __attribute__ ((weak)) arch_init_clk_ops(struct clk_ops **ops, int type) { } +static int show_clocks(char *buf, char **start, off_t off, + int len, int *eof, void *data) +{ + struct clk *clk; + char *p = buf; + + list_for_each_entry_reverse(clk, &clock_list, node) { + unsigned long rate = clk_get_rate(clk); + + /* + * Don't bother listing dummy clocks with no ancestry + * that only support enable and disable ops. + */ + if (unlikely(!rate && !clk->parent)) + continue; + + p += sprintf(p, "%-12s\t: %ld.%02ldMHz\n", clk->name, + rate / 1000000, (rate % 1000000) / 10000); + } + + return p - buf; +} + int __init clk_init(void) { int i, ret = 0; @@ -285,36 +321,14 @@ int __init clk_init(void) return ret; } -int show_clocks(struct seq_file *m) +static int __init clk_proc_init(void) { - struct clk *clk; - - list_for_each_entry_reverse(clk, &clock_list, node) { - unsigned long rate = clk_get_rate(clk); - - /* - * Don't bother listing dummy clocks with no ancestry - * that only support enable and disable ops. - */ - if (unlikely(!rate && !clk->parent)) - continue; - - seq_printf(m, "%-12s\t: %ld.%02ldMHz\n", clk->name, - rate / 1000000, (rate % 1000000) / 10000); - } + struct proc_dir_entry *p; + p = create_proc_read_entry("clocks", S_IRUSR, NULL, + show_clocks, NULL); + if (unlikely(!p)) + return -EINVAL; return 0; } - -EXPORT_SYMBOL_GPL(clk_register); -EXPORT_SYMBOL_GPL(clk_unregister); -EXPORT_SYMBOL_GPL(clk_get); -EXPORT_SYMBOL_GPL(clk_put); -EXPORT_SYMBOL_GPL(clk_enable); -EXPORT_SYMBOL_GPL(clk_disable); -EXPORT_SYMBOL_GPL(__clk_enable); -EXPORT_SYMBOL_GPL(__clk_disable); -EXPORT_SYMBOL_GPL(clk_get_rate); -EXPORT_SYMBOL_GPL(clk_set_rate); -EXPORT_SYMBOL_GPL(clk_recalc_rate); -EXPORT_SYMBOL_GPL(clk_set_rate_ex); +subsys_initcall(clk_proc_init); diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 60cc2161438f..cab91a7665da 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -501,7 +501,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) c->loops_per_jiffy/(500000/HZ), (c->loops_per_jiffy/(5000/HZ)) % 100); - return show_clocks(m); + return 0; } static void *c_start(struct seq_file *m, loff_t *pos) diff --git a/include/asm-sh/clock.h b/include/asm-sh/clock.h index a5d629f090d4..386d797d86b7 100644 --- a/include/asm-sh/clock.h +++ b/include/asm-sh/clock.h @@ -48,8 +48,6 @@ void clk_recalc_rate(struct clk *); int clk_register(struct clk *); void clk_unregister(struct clk *); -int show_clocks(struct seq_file *m); - /* the exported API, in addition to clk_set_rate */ /** * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter -- cgit v1.2.3-59-g8ed1b From 4d5ade5b29c618e97a8988efb6967cb4dd0e2183 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 27 Apr 2007 11:25:57 +0900 Subject: sh: kdump support. This adds support for kexec based crash dumps. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 14 +++++++++++++ arch/sh/kernel/Makefile | 1 + arch/sh/kernel/crash_dump.c | 46 ++++++++++++++++++++++++++++++++++++++++++ arch/sh/kernel/machine_kexec.c | 29 ++++++++++++++++++++++---- arch/sh/kernel/setup.c | 6 ++++++ include/asm-sh/kexec.h | 42 +++++++++++++++++++++++++++++++++----- 6 files changed, 129 insertions(+), 9 deletions(-) create mode 100644 arch/sh/kernel/crash_dump.c (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 0b465d622cfc..dfdfaae6772f 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -551,6 +551,20 @@ config KEXEC support. As of this writing the exact hardware interface is strongly in flux, so no good recommendation can be made. +config CRASH_DUMP + bool "kernel crash dumps (EXPERIMENTAL)" + depends on EXPERIMENTAL + help + Generate crash dump after being started by kexec. + This should be normally only set in special crash dump kernels + which are loaded in the main kernel with kexec-tools into + a specially reserved region and then later executed after + a crash by kdump/kexec. The crash dump kernel must be compiled + to a memory address not used by the main kernel using + MEMORY_START. + + For more details see Documentation/kdump/kdump.txt + config SMP bool "Symmetric multi-processing support" ---help--- diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index ff30d7f58043..9104b6257644 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -20,5 +20,6 @@ obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o +obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_STACKTRACE) += stacktrace.o diff --git a/arch/sh/kernel/crash_dump.c b/arch/sh/kernel/crash_dump.c new file mode 100644 index 000000000000..4a2ecbe27d8e --- /dev/null +++ b/arch/sh/kernel/crash_dump.c @@ -0,0 +1,46 @@ +/* + * crash_dump.c - Memory preserving reboot related code. + * + * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) + * Copyright (C) IBM Corporation, 2004. All rights reserved + */ + +#include +#include +#include +#include + +/** + * copy_oldmem_page - copy one page from "oldmem" + * @pfn: page frame number to be copied + * @buf: target memory address for the copy; this can be in kernel address + * space or user address space (see @userbuf) + * @csize: number of bytes to copy + * @offset: offset in bytes into the page (based on pfn) to begin the copy + * @userbuf: if set, @buf is in user address space, use copy_to_user(), + * otherwise @buf is in kernel address space, use memcpy(). + * + * Copy a page from "oldmem". For this page, there is no pte mapped + * in the current kernel. We stitch up a pte, similar to kmap_atomic. + */ +ssize_t copy_oldmem_page(unsigned long pfn, char *buf, + size_t csize, unsigned long offset, int userbuf) +{ + void *vaddr; + + if (!csize) + return 0; + + vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE); + + if (userbuf) { + if (copy_to_user(buf, (vaddr + offset), csize)) { + iounmap(vaddr); + return -EFAULT; + } + } else + memcpy(buf, (vaddr + offset), csize); + + iounmap(vaddr); + return csize; +} diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c index 08587cdb64d6..790ed69b8666 100644 --- a/arch/sh/kernel/machine_kexec.c +++ b/arch/sh/kernel/machine_kexec.c @@ -59,13 +59,13 @@ static void kexec_info(struct kimage *image) printk(" segment[%d]: 0x%08x - 0x%08x (0x%08x)\n", i, (unsigned int)image->segment[i].mem, - (unsigned int)image->segment[i].mem + image->segment[i].memsz, + (unsigned int)image->segment[i].mem + + image->segment[i].memsz, (unsigned int)image->segment[i].memsz); - } + } printk(" start : 0x%08x\n\n", (unsigned int)image->start); } - /* * Do not allocate memory (or fail in any way) in machine_kexec(). * We are past the point of no return, committed to rebooting now. @@ -101,6 +101,27 @@ NORET_TYPE void machine_kexec(struct kimage *image) /* now call it */ rnk = (relocate_new_kernel_t) reboot_code_buffer; - (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg); + (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg); } +/* crashkernel=size@addr specifies the location to reserve for + * a crash kernel. By reserving this memory we guarantee + * that linux never sets it up as a DMA target. + * Useful for holding code to do something appropriate + * after a kernel panic. + */ +static int __init parse_crashkernel(char *arg) +{ + unsigned long size, base; + size = memparse(arg, &arg); + if (*arg == '@') { + base = memparse(arg+1, &arg); + /* FIXME: Do I want a sanity check + * to validate the memory range? + */ + crashk_res.start = base; + crashk_res.end = base + size - 1; + } + return 0; +} +early_param("crashkernel", parse_crashkernel); diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index cab91a7665da..477d2a854fc4 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -287,6 +288,11 @@ void __init setup_bootmem_allocator(unsigned long start_pfn) } } #endif +#ifdef CONFIG_KEXEC + if (crashk_res.start != crashk_res.end) + reserve_bootmem(crashk_res.start, + crashk_res.end - crashk_res.start + 1); +#endif } #ifndef CONFIG_NEED_MULTIPLE_NODES diff --git a/include/asm-sh/kexec.h b/include/asm-sh/kexec.h index 9d235af20cdd..da36a7548601 100644 --- a/include/asm-sh/kexec.h +++ b/include/asm-sh/kexec.h @@ -1,5 +1,8 @@ -#ifndef _SH_KEXEC_H -#define _SH_KEXEC_H +#ifndef __ASM_SH_KEXEC_H +#define __ASM_SH_KEXEC_H + +#include +#include /* * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return. @@ -25,8 +28,37 @@ #define MAX_NOTE_BYTES 1024 -/* Provide a dummy definition to avoid build failures. */ static inline void crash_setup_regs(struct pt_regs *newregs, - struct pt_regs *oldregs) { } + struct pt_regs *oldregs) +{ + if (oldregs) + memcpy(newregs, oldregs, sizeof(*newregs)); + else { + __asm__ __volatile__ ("mov r0, %0" : "=r" (newregs->regs[0])); + __asm__ __volatile__ ("mov r1, %0" : "=r" (newregs->regs[1])); + __asm__ __volatile__ ("mov r2, %0" : "=r" (newregs->regs[2])); + __asm__ __volatile__ ("mov r3, %0" : "=r" (newregs->regs[3])); + __asm__ __volatile__ ("mov r4, %0" : "=r" (newregs->regs[4])); + __asm__ __volatile__ ("mov r5, %0" : "=r" (newregs->regs[5])); + __asm__ __volatile__ ("mov r6, %0" : "=r" (newregs->regs[6])); + __asm__ __volatile__ ("mov r7, %0" : "=r" (newregs->regs[7])); + __asm__ __volatile__ ("mov r8, %0" : "=r" (newregs->regs[8])); + __asm__ __volatile__ ("mov r9, %0" : "=r" (newregs->regs[9])); + __asm__ __volatile__ ("mov r10, %0" : "=r" (newregs->regs[10])); + __asm__ __volatile__ ("mov r11, %0" : "=r" (newregs->regs[11])); + __asm__ __volatile__ ("mov r12, %0" : "=r" (newregs->regs[12])); + __asm__ __volatile__ ("mov r13, %0" : "=r" (newregs->regs[13])); + __asm__ __volatile__ ("mov r14, %0" : "=r" (newregs->regs[14])); + __asm__ __volatile__ ("mov r15, %0" : "=r" (newregs->regs[15])); + + __asm__ __volatile__ ("sts pr, %0" : "=r" (newregs->pr)); + __asm__ __volatile__ ("sts macl, %0" : "=r" (newregs->macl)); + __asm__ __volatile__ ("sts mach, %0" : "=r" (newregs->mach)); + + __asm__ __volatile__ ("stc gbr, %0" : "=r" (newregs->gbr)); + __asm__ __volatile__ ("stc sr, %0" : "=r" (newregs->sr)); -#endif /* _SH_KEXEC_H */ + newregs->pc = (unsigned long)current_text_addr(); + } +} +#endif /* __ASM_SH_KEXEC_H */ -- cgit v1.2.3-59-g8ed1b From 6865f0ea6ad91fec3ae7831c49d48b5a7db4b428 Mon Sep 17 00:00:00 2001 From: Ryusuke Sakato Date: Tue, 1 May 2007 09:45:29 +0900 Subject: sh: Solution Engine 7722 board support. This adds more full-featured support for the SH7722 Solution Engine. Previously this was using the generic board, and lacked most of the peripheral support. Signed-off-by: Ryusuke Sakato Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 8 + arch/sh/Makefile | 1 + arch/sh/boards/se/7722/Makefile | 10 ++ arch/sh/boards/se/7722/irq.c | 101 +++++++++++ arch/sh/boards/se/7722/setup.c | 148 +++++++++++++++++ arch/sh/configs/se7722_defconfig | 351 +++++++++++++++++++++------------------ arch/sh/kernel/cf-enabler.c | 28 +++- include/asm-sh/se7722.h | 118 +++++++++++++ 8 files changed, 598 insertions(+), 167 deletions(-) create mode 100644 arch/sh/boards/se/7722/Makefile create mode 100644 arch/sh/boards/se/7722/irq.c create mode 100644 arch/sh/boards/se/7722/setup.c create mode 100644 include/asm-sh/se7722.h (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index dfdfaae6772f..d74eb120a9c6 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -92,6 +92,14 @@ config SH_SOLUTION_ENGINE Select SolutionEngine if configuring for a Hitachi SH7709 or SH7750 evaluation board. +config SH_7722_SOLUTION_ENGINE + bool "SolutionEngine7722" + select SOLUTION_ENGINE + select CPU_SUBTYPE_SH7722 + help + Select 7722 SolutionEngine if configuring for a Hitachi SH772 + evaluation board. + config SH_7751_SOLUTION_ENGINE bool "SolutionEngine7751" select SOLUTION_ENGINE diff --git a/arch/sh/Makefile b/arch/sh/Makefile index d7c12053160b..7b1122417050 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -88,6 +88,7 @@ core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/ # Boards machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x +machdir-$(CONFIG_SH_7722_SOLUTION_ENGINE) := se/7722 machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751 machdir-$(CONFIG_SH_7780_SOLUTION_ENGINE) := se/7780 machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300 diff --git a/arch/sh/boards/se/7722/Makefile b/arch/sh/boards/se/7722/Makefile new file mode 100644 index 000000000000..8694373389e5 --- /dev/null +++ b/arch/sh/boards/se/7722/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the HITACHI UL SolutionEngine 7722 specific parts of the kernel +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# + +obj-y := setup.o irq.o diff --git a/arch/sh/boards/se/7722/irq.c b/arch/sh/boards/se/7722/irq.c new file mode 100644 index 000000000000..099e5deb77f8 --- /dev/null +++ b/arch/sh/boards/se/7722/irq.c @@ -0,0 +1,101 @@ +/* + * linux/arch/sh/boards/se/7722/irq.c + * + * Copyright (C) 2007 Nobuhiro Iwamatsu + * + * Hitachi UL SolutionEngine 7722 Support. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include + +#define INTC_INTMSK0 0xFFD00044 +#define INTC_INTMSKCLR0 0xFFD00064 + +static void disable_se7722_irq(unsigned int irq) +{ + struct ipr_data *p = get_irq_chip_data(irq); + ctrl_outw( ctrl_inw( p->addr ) | p->priority , p->addr ); +} + +static void enable_se7722_irq(unsigned int irq) +{ + struct ipr_data *p = get_irq_chip_data(irq); + ctrl_outw( ctrl_inw( p->addr ) & ~p->priority , p->addr ); +} + +static struct irq_chip se7722_irq_chip __read_mostly = { + .name = "SE7722", + .mask = disable_se7722_irq, + .unmask = enable_se7722_irq, + .mask_ack = disable_se7722_irq, +}; + +static struct ipr_data ipr_irq_table[] = { + /* irq ,idx,sft, priority , addr */ + { MRSHPC_IRQ0 , 0 , 0 , MRSHPC_BIT0 , IRQ01_MASK } , + { MRSHPC_IRQ1 , 0 , 0 , MRSHPC_BIT1 , IRQ01_MASK } , + { MRSHPC_IRQ2 , 0 , 0 , MRSHPC_BIT2 , IRQ01_MASK } , + { MRSHPC_IRQ3 , 0 , 0 , MRSHPC_BIT3 , IRQ01_MASK } , + { SMC_IRQ , 0 , 0 , SMC_BIT , IRQ01_MASK } , + { EXT_IRQ , 0 , 0 , EXT_BIT , IRQ01_MASK } , +}; + +int se7722_irq_demux(int irq) +{ + + if ((irq == IRQ0_IRQ)||(irq == IRQ1_IRQ)) { + volatile unsigned short intv = + *(volatile unsigned short *)IRQ01_STS; + if (irq == IRQ0_IRQ){ + if(intv & SMC_BIT ) { + return SMC_IRQ; + } else if(intv & USB_BIT) { + return USB_IRQ; + } else { + printk("intv =%04x\n", intv); + return SMC_IRQ; + } + } else if(irq == IRQ1_IRQ){ + if(intv & MRSHPC_BIT0) { + return MRSHPC_IRQ0; + } else if(intv & MRSHPC_BIT1) { + return MRSHPC_IRQ1; + } else if(intv & MRSHPC_BIT2) { + return MRSHPC_IRQ2; + } else if(intv & MRSHPC_BIT3) { + return MRSHPC_IRQ3; + } else { + printk("BIT_EXTENTION =%04x\n", intv); + return EXT_IRQ; + } + } + } + return irq; + +} +/* + * Initialize IRQ setting + */ +void __init init_se7722_IRQ(void) +{ + int i = 0; + ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ + ctrl_outl((3 << ((7 - 0) * 4))|(3 << ((7 - 1) * 4)), INTC_INTPRI0); /* irq0 pri=3,irq1,pri=3 */ + ctrl_outw((2 << ((7 - 0) * 2))|(2 << ((7 - 1) * 2)), INTC_ICR1); /* irq0,1 low-level irq */ + + for (i = 0; i < ARRAY_SIZE(ipr_irq_table); i++) { + disable_irq_nosync(ipr_irq_table[i].irq); + set_irq_chip_and_handler_name( ipr_irq_table[i].irq, &se7722_irq_chip, + handle_level_irq, "level"); + set_irq_chip_data( ipr_irq_table[i].irq, &ipr_irq_table[i] ); + disable_se7722_irq(ipr_irq_table[i].irq); + } +} diff --git a/arch/sh/boards/se/7722/setup.c b/arch/sh/boards/se/7722/setup.c new file mode 100644 index 000000000000..636ca6c987e0 --- /dev/null +++ b/arch/sh/boards/se/7722/setup.c @@ -0,0 +1,148 @@ +/* + * linux/arch/sh/boards/se/7722/setup.c + * + * Copyright (C) 2007 Nobuhiro Iwamatsu + * + * Hitachi UL SolutionEngine 7722 Support. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ +#include +#include +#include +#include +#include +#include + +/* Heartbeat */ +static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + +static struct resource heartbeat_resources[] = { + [0] = { + .start = PA_LED, + .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + .dev = { + .platform_data = heartbeat_bit_pos, + }, + .num_resources = ARRAY_SIZE(heartbeat_resources), + .resource = heartbeat_resources, +}; + +/* SMC91x */ +static struct resource smc91x_eth_resources[] = { + [0] = { + .name = "smc91x-regs" , + .start = PA_LAN + 0x300, + .end = PA_LAN + 0x300 + 0x10 , + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = SMC_IRQ, + .end = SMC_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_eth_device = { + .name = "smc91x", + .id = 0, + .dev = { + .dma_mask = NULL, /* don't use dma */ + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(smc91x_eth_resources), + .resource = smc91x_eth_resources, +}; + +static struct resource cf_ide_resources[] = { + [0] = { + .start = PA_MRSHPC_IO + 0x1f0, + .end = PA_MRSHPC_IO + 0x1f0 + 8 , + .flags = IORESOURCE_IO, + }, + [1] = { + .start = PA_MRSHPC_IO + 0x1f0 + 0x206, + .end = PA_MRSHPC_IO + 0x1f0 +8 + 0x206 + 8, + .flags = IORESOURCE_IO, + }, + [2] = { + .start = MRSHPC_IRQ0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cf_ide_device = { + .name = "pata_platform", + .id = -1, + .num_resources = ARRAY_SIZE(cf_ide_resources), + .resource = cf_ide_resources, +}; + +static struct platform_device *se7722_devices[] __initdata = { + &heartbeat_device, + &smc91x_eth_device, + &cf_ide_device, +}; + +static int __init se7722_devices_setup(void) +{ + return platform_add_devices(se7722_devices, + ARRAY_SIZE(se7722_devices)); +} +device_initcall(se7722_devices_setup); + +static void __init se7722_setup(char **cmdline_p) +{ + ctrl_outw(0x010D, FPGA_OUT); /* FPGA */ + + ctrl_outl(0x00051001, MSTPCR0); + ctrl_outl(0x00000000, MSTPCR1); + /* KEYSC, VOU, BEU, CEU, VEU, VPU, LCDC */ + ctrl_outl(0xffffbfC0, MSTPCR2); + + ctrl_outw(0x0000, PORT_PECR); /* PORT E 1 = IRQ5 ,E 0 = BS */ + ctrl_outw(0x1000, PORT_PJCR); /* PORT J 1 = IRQ1,J 0 =IRQ0 */ + + /* LCDC I/O */ + ctrl_outw(0x0020, PORT_PSELD); + + /* SIOF1*/ + ctrl_outw(0x0003, PORT_PSELB); + ctrl_outw(0xe000, PORT_PSELC); + ctrl_outw(0x0000, PORT_PKCR); + + /* LCDC */ + ctrl_outw(0x4020, PORT_PHCR); + ctrl_outw(0x0000, PORT_PLCR); + ctrl_outw(0x0000, PORT_PMCR); + ctrl_outw(0x0002, PORT_PRCR); + ctrl_outw(0x0000, PORT_PXCR); /* LCDC,CS6A */ + + /* KEYSC */ + ctrl_outw(0x0A10, PORT_PSELA); /* BS,SHHID2 */ + ctrl_outw(0x0000, PORT_PYCR); + ctrl_outw(0x0000, PORT_PZCR); +} + +/* + * The Machine Vector + */ +struct sh_machine_vector mv_se7722 __initmv = { + .mv_name = "Solution Engine 7722" , + .mv_setup = se7722_setup , + .mv_nr_irqs = 109 , + .mv_init_irq = init_se7722_IRQ, + .mv_irq_demux = se7722_irq_demux, + +}; +ALIAS_MV(se7722) diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig index 6a55ccbc934e..ca4c663dfa37 100644 --- a/arch/sh/configs/se7722_defconfig +++ b/arch/sh/configs/se7722_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc4 -# Wed Mar 28 16:22:40 2007 +# Linux kernel version: 2.6.21-rc7 +# Fri Apr 27 16:30:30 2007 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -35,24 +35,24 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_SYSFS_DEPRECATED is not set # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" -CONFIG_INITRAMFS_ROOT_UID=0 -CONFIG_INITRAMFS_ROOT_GID=0 CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_EMBEDDED=y CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y @@ -103,8 +103,11 @@ CONFIG_DEFAULT_IOSCHED="noop" # # System type # +CONFIG_SOLUTION_ENGINE=y # CONFIG_SH_SOLUTION_ENGINE is not set +CONFIG_SH_7722_SOLUTION_ENGINE=y # CONFIG_SH_7751_SOLUTION_ENGINE is not set +# CONFIG_SH_7780_SOLUTION_ENGINE is not set # CONFIG_SH_7300_SOLUTION_ENGINE is not set # CONFIG_SH_7343_SOLUTION_ENGINE is not set # CONFIG_SH_73180_SOLUTION_ENGINE is not set @@ -127,7 +130,7 @@ CONFIG_DEFAULT_IOSCHED="noop" # CONFIG_SH_7206_SOLUTION_ENGINE is not set # CONFIG_SH_7619_SOLUTION_ENGINE is not set # CONFIG_SH_LBOX_RE2 is not set -CONFIG_SH_UNKNOWN=y +# CONFIG_SH_UNKNOWN is not set # # Processor selection @@ -229,7 +232,10 @@ CONFIG_ZONE_DMA_FLAG=0 # CONFIG_SH_DIRECT_MAPPED is not set # CONFIG_SH_WRITETHROUGH is not set # CONFIG_SH_OCRAM is not set -# CONFIG_CF_ENABLER is not set +CONFIG_CF_ENABLER=y +# CONFIG_CF_AREA5 is not set +CONFIG_CF_AREA6=y +CONFIG_CF_BASE_ADDR=0xb8000000 # # Processor features @@ -251,7 +257,7 @@ CONFIG_CPU_HAS_PTEA=y CONFIG_SH_TMU=y CONFIG_SH_TIMER_IRQ=16 CONFIG_NO_IDLE_HZ=y -CONFIG_SH_PCLK_FREQ=32000000 +CONFIG_SH_PCLK_FREQ=33333333 # # CPU Frequency scaling @@ -271,8 +277,8 @@ CONFIG_SH_PCLK_FREQ=32000000 # # Additional SuperH Device Drivers # -# CONFIG_HEARTBEAT is not set -CONFIG_PUSH_SWITCH=y +CONFIG_HEARTBEAT=y +# CONFIG_PUSH_SWITCH is not set # # Kernel features @@ -283,6 +289,7 @@ CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set CONFIG_HZ=250 CONFIG_KEXEC=y +# CONFIG_CRASH_DUMP is not set # CONFIG_SMP is not set # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set @@ -295,8 +302,7 @@ CONFIG_PREEMPT_BKL=y CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 # CONFIG_UBC_WAKEUP is not set -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=ttySC0,115200" +# CONFIG_CMDLINE_BOOL is not set # # Bus options @@ -327,7 +333,88 @@ CONFIG_BINFMT_ELF=y # # Networking # -# CONFIG_NET is not set +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set # # Device Drivers @@ -338,14 +425,13 @@ CONFIG_BINFMT_ELF=y # CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=m -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set +# CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker # +# CONFIG_CONNECTOR is not set # # Memory Technology Devices (MTD) @@ -367,11 +453,13 @@ CONFIG_FW_LOADER=m # # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set # # Misc devices @@ -398,7 +486,7 @@ CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set -CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SG is not set # CONFIG_CHR_DEV_SCH is not set # @@ -414,12 +502,14 @@ CONFIG_CHR_DEV_SG=m # # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set # CONFIG_SCSI_SAS_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set # # SCSI low-level drivers # +# CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_DEBUG is not set # @@ -447,9 +537,60 @@ CONFIG_PATA_PLATFORM=y # I2O device support # +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_STNIC is not set +CONFIG_SMC91X=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + # # ISDN subsystem # +# CONFIG_ISDN is not set # # Telephony Support @@ -582,6 +723,7 @@ CONFIG_HWMON=y # # Digital Video Broadcasting Devices # +# CONFIG_DVB is not set # # Graphics support @@ -592,20 +734,7 @@ CONFIG_HWMON=y # # Sound # -CONFIG_SOUND=m - -# -# Advanced Linux Sound Architecture -# -# CONFIG_SND is not set - -# -# Open Sound System -# -CONFIG_SOUND_PRIME=m -# CONFIG_OBSOLETE_OSS is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND is not set # # HID Devices @@ -722,7 +851,8 @@ CONFIG_FS_MBCACHE=y # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set -CONFIG_MINIX_FS=y +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -730,7 +860,7 @@ CONFIG_INOTIFY_USER=y CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -CONFIG_FUSE_FS=m +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -741,14 +871,9 @@ CONFIG_FUSE_FS=m # # DOS/FAT/NT Filesystems # -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -CONFIG_NTFS_FS=y -# CONFIG_NTFS_DEBUG is not set -CONFIG_NTFS_RW=y +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set # # Pseudo filesystems @@ -762,7 +887,7 @@ CONFIG_TMPFS=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y -CONFIG_CONFIGFS_FS=m +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -781,6 +906,18 @@ CONFIG_CONFIGFS_FS=m # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + # # Partition Types # @@ -790,95 +927,33 @@ CONFIG_MSDOS_PARTITION=y # # Native Language Support # -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -CONFIG_NLS_CODEPAGE_932=y -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set +# CONFIG_NLS is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set # # Profiling support # -CONFIG_PROFILING=y -CONFIG_OPROFILE=m +# CONFIG_PROFILING is not set # # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_MAGIC_SYSRQ=y +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -CONFIG_DEBUG_SLAB=y -# CONFIG_DEBUG_SLAB_LEAK is not set -CONFIG_DEBUG_PREEMPT=y -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -CONFIG_DEBUG_SPINLOCK=y -CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_VM=y -# CONFIG_DEBUG_LIST is not set -CONFIG_FRAME_POINTER=y -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_FAULT_INJECTION is not set -CONFIG_SH_STANDARD_BIOS=y +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_SH_STANDARD_BIOS is not set # CONFIG_EARLY_SCIF_CONSOLE is not set -CONFIG_EARLY_PRINTK=y -CONFIG_DEBUG_STACKOVERFLOW=y -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_4KSTACKS is not set # CONFIG_SH_KGDB is not set # @@ -890,47 +965,7 @@ CONFIG_DEBUG_STACKOVERFLOW=y # # Cryptographic options # -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_GF128MUL is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# +# CONFIG_CRYPTO is not set # # Library routines diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c index 3e5fa1e24df0..0758d48147a0 100644 --- a/arch/sh/kernel/cf-enabler.c +++ b/arch/sh/kernel/cf-enabler.c @@ -29,7 +29,7 @@ * 0xB8001000 : Common Memory * 0xBA000000 : I/O */ -#if defined(CONFIG_IDE) && defined(CONFIG_CPU_SH4) +#if defined(CONFIG_CPU_SH4) /* SH4 can't access PCMCIA interface through P2 area. * we must remap it with appropreate attribute bit of the page set. * this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */ @@ -71,7 +71,7 @@ static int __init cf_init_default(void) /* You must have enabled the card, and set the level interrupt * before reaching this point. Possibly in boot ROM or boot loader. */ -#if defined(CONFIG_IDE) && defined(CONFIG_CPU_SH4) +#if defined(CONFIG_CPU_SH4) allocate_cf_area(); #endif #if defined(CONFIG_SH_UNKNOWN) @@ -84,15 +84,25 @@ static int __init cf_init_default(void) #if defined(CONFIG_SH_SOLUTION_ENGINE) #include +#elif defined(CONFIG_SH_7722_SOLUTION_ENGINE) +#include +#endif /* - * SolutionEngine + * SolutionEngine Seriese * + * about MS770xSE * 0xB8400000 : Common Memory * 0xB8500000 : Attribute * 0xB8600000 : I/O + * + * about MS7722SE + * 0xB0400000 : Common Memory + * 0xB0500000 : Attribute + * 0xB0600000 : I/O */ +#if defined(CONFIG_SH_SOLUTION_ENGINE) || defined(CONFIG_SH_7722_SOLUTION_ENGINE) static int __init cf_init_se(void) { if ((ctrl_inw(MRSHPC_CSR) & 0x000c) != 0) @@ -109,7 +119,7 @@ static int __init cf_init_se(void) * flag == COMMON/ATTRIBUTE/IO */ /* common window open */ - ctrl_outw(0x8a84, MRSHPC_MW0CR1);/* window 0xb8400000 */ + ctrl_outw(0x8a84, MRSHPC_MW0CR1); if((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0) /* common mode & bus width 16bit SWAP = 1*/ ctrl_outw(0x0b00, MRSHPC_MW0CR2); @@ -118,7 +128,7 @@ static int __init cf_init_se(void) ctrl_outw(0x0300, MRSHPC_MW0CR2); /* attribute window open */ - ctrl_outw(0x8a85, MRSHPC_MW1CR1);/* window 0xb8500000 */ + ctrl_outw(0x8a85, MRSHPC_MW1CR1); if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0) /* attribute mode & bus width 16bit SWAP = 1*/ ctrl_outw(0x0a00, MRSHPC_MW1CR2); @@ -127,7 +137,7 @@ static int __init cf_init_se(void) ctrl_outw(0x0200, MRSHPC_MW1CR2); /* I/O window open */ - ctrl_outw(0x8a86, MRSHPC_IOWCR1);/* I/O window 0xb8600000 */ + ctrl_outw(0x8a86, MRSHPC_IOWCR1); ctrl_outw(0x0008, MRSHPC_CDCR); /* I/O card mode */ if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0) ctrl_outw(0x0a00, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 1*/ @@ -143,10 +153,10 @@ static int __init cf_init_se(void) int __init cf_init(void) { -#if defined(CONFIG_SH_SOLUTION_ENGINE) - if (MACH_SE) + if( mach_is_se() || mach_is_7722se() ){ return cf_init_se(); -#endif + } + return cf_init_default(); } diff --git a/include/asm-sh/se7722.h b/include/asm-sh/se7722.h new file mode 100644 index 000000000000..b3b31e4725c6 --- /dev/null +++ b/include/asm-sh/se7722.h @@ -0,0 +1,118 @@ +#ifndef __ASM_SH_SE7722_H +#define __ASM_SH_SE7722_H + +/* + * linux/include/asm-sh/se7722.h + * + * Copyright (C) 2007 Nobuhiro Iwamatsu + * + * Hitachi UL SolutionEngine 7722 Support. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ +#include + +/* Box specific addresses. */ +#define SE_AREA0_WIDTH 4 /* Area0: 32bit */ +#define PA_ROM 0xa0000000 /* EPROM */ +#define PA_ROM_SIZE 0x00200000 /* EPROM size 2M byte */ +#define PA_FROM 0xa1000000 /* Flash-ROM */ +#define PA_FROM_SIZE 0x01000000 /* Flash-ROM size 16M byte */ +#define PA_EXT1 0xa4000000 +#define PA_EXT1_SIZE 0x04000000 +#define PA_SDRAM 0xaC000000 /* DDR-SDRAM(Area3) 64MB */ +#define PA_SDRAM_SIZE 0x04000000 + +#define PA_EXT4 0xb0000000 +#define PA_EXT4_SIZE 0x04000000 + +#define PA_PERIPHERAL 0xB0000000 + +#define PA_PCIC PA_PERIPHERAL /* MR-SHPC-01 PCMCIA */ +#define PA_MRSHPC (PA_PERIPHERAL + 0x003fffe0) /* MR-SHPC-01 PCMCIA controller */ +#define PA_MRSHPC_MW1 (PA_PERIPHERAL + 0x00400000) /* MR-SHPC-01 memory window base */ +#define PA_MRSHPC_MW2 (PA_PERIPHERAL + 0x00500000) /* MR-SHPC-01 attribute window base */ +#define PA_MRSHPC_IO (PA_PERIPHERAL + 0x00600000) /* MR-SHPC-01 I/O window base */ +#define MRSHPC_OPTION (PA_MRSHPC + 6) +#define MRSHPC_CSR (PA_MRSHPC + 8) +#define MRSHPC_ISR (PA_MRSHPC + 10) +#define MRSHPC_ICR (PA_MRSHPC + 12) +#define MRSHPC_CPWCR (PA_MRSHPC + 14) +#define MRSHPC_MW0CR1 (PA_MRSHPC + 16) +#define MRSHPC_MW1CR1 (PA_MRSHPC + 18) +#define MRSHPC_IOWCR1 (PA_MRSHPC + 20) +#define MRSHPC_MW0CR2 (PA_MRSHPC + 22) +#define MRSHPC_MW1CR2 (PA_MRSHPC + 24) +#define MRSHPC_IOWCR2 (PA_MRSHPC + 26) +#define MRSHPC_CDCR (PA_MRSHPC + 28) +#define MRSHPC_PCIC_INFO (PA_MRSHPC + 30) + +#define PA_LED (PA_PERIPHERAL + 0x00800000) /* 8bit LED */ +#define PA_FPGA (PA_PERIPHERAL + 0x01800000) /* FPGA base address */ + +#define PA_LAN (PA_AREA6_IO + 0) /* SMC LAN91C111 */ +/* GPIO */ +#define MSTPCR0 0xA4150030UL +#define MSTPCR1 0xA4150034UL +#define MSTPCR2 0xA4150038UL + +#define FPGA_IN 0xb1840000UL +#define FPGA_OUT 0xb1840004UL + +#define PORT_PECR 0xA4050108UL +#define PORT_PJCR 0xA4050110UL +#define PORT_PSELD 0xA4050154UL +#define PORT_PSELB 0xA4050150UL + +#define PORT_PSELC 0xA4050152UL +#define PORT_PKCR 0xA4050112UL +#define PORT_PHCR 0xA405010EUL +#define PORT_PLCR 0xA4050114UL +#define PORT_PMCR 0xA4050116UL +#define PORT_PRCR 0xA405011CUL +#define PORT_PXCR 0xA4050148UL +#define PORT_PSELA 0xA405014EUL +#define PORT_PYCR 0xA405014AUL +#define PORT_PZCR 0xA405014CUL + +/* IRQ */ +#define IRQ0_IRQ 32 +#define IRQ1_IRQ 33 +#define INTC_ICR0 0xA4140000UL +#define INTC_ICR1 0xA414001CUL + +#define INTMSK0 0xa4140044 +#define INTMSKCLR0 0xa4140064 +#define INTC_INTPRI0 0xa4140010 + +#define IRQ01_MODE 0xb1800000 +#define IRQ01_STS 0xb1800004 +#define IRQ01_MASK 0xb1800008 +#define EXT_BIT (0x3fc0) /* SH IRQ1 */ +#define MRSHPC_BIT0 (0x0004) /* SH IRQ1 */ +#define MRSHPC_BIT1 (0x0008) /* SH IRQ1 */ +#define MRSHPC_BIT2 (0x0010) /* SH IRQ1 */ +#define MRSHPC_BIT3 (0x0020) /* SH IRQ1 */ +#define SMC_BIT (0x0002) /* SH IRQ0 */ +#define USB_BIT (0x0001) /* SH IRQ0 */ + +#define MRSHPC_IRQ3 11 +#define MRSHPC_IRQ2 12 +#define MRSHPC_IRQ1 13 +#define MRSHPC_IRQ0 14 +#define SMC_IRQ 10 +#define EXT_IRQ 5 +#define USB_IRQ 6 + + +/* arch/sh/boards/se/7722/irq.c */ +void init_se7722_IRQ(void); +int se7722_irq_demux(int); + +#define __IO_PREFIX se7722 +#include + +#endif /* __ASM_SH_SE7722_H */ -- cgit v1.2.3-59-g8ed1b From 70fe4d87bf72053f78cf3d2e6cefa5d51a2c30af Mon Sep 17 00:00:00 2001 From: Takashi YOSHII Date: Tue, 1 May 2007 12:19:33 +0900 Subject: sh: Wire up more IRQs for SH7709. hp6xx requires some additional IRQs that aren't currently enabled in the SH7709 setup code. Wire them up. Signed-off-by: Takashi YOSHII Signed-off-by: Kristoffer Ericson Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh3/setup-sh7709.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7709.c b/arch/sh/kernel/cpu/sh3/setup-sh7709.c index dc9b211cf87f..c7d7c35fc834 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7709.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7709.c @@ -48,24 +48,33 @@ static struct platform_device *sh7709_devices[] __initdata = { static int __init sh7709_devices_setup(void) { return platform_add_devices(sh7709_devices, - ARRAY_SIZE(sh7709_devices)); + ARRAY_SIZE(sh7709_devices)); } __initcall(sh7709_devices_setup); -#define IPRx(A,N) .addr=A, .shift=0*N*-1 +#define IPRx(A,N) .addr=A, .shift=N #define IPRA(N) IPRx(0xfffffee2UL,N) #define IPRB(N) IPRx(0xfffffee4UL,N) +#define IPRC(N) IPRx(0xa4000016UL,N) +#define IPRD(N) IPRx(0xa4000018UL,N) #define IPRE(N) IPRx(0xa400001aUL,N) static struct ipr_data sh7709_ipr_map[] = { - [16] = { IPRA(15-12), 2 }, /* TMU TUNI0 */ - [17] = { IPRA(11-8), 4 }, /* TMU TUNI1 */ - [22] = { IPRA(3-0), 2 }, /* RTC CUI */ - [23 ... 26] = { IPRB(7-4), 3 }, /* SCI */ - [27] = { IPRB(15-12), 2 }, /* WDT ITI */ - [48 ... 51] = { IPRE(15-12), 7 }, /* DMA */ - [52 ... 55] = { IPRE(11-8), 3 }, /* IRDA */ - [56 ... 59] = { IPRE(7-4), 3 }, /* SCIF */ + [16] = { IPRA(12), 2 }, /* TMU TUNI0 */ + [17] = { IPRA(8), 4 }, /* TMU TUNI1 */ + [18 ... 19] = { IPRA(4), 1 }, /* TMU TUNI1 */ + [20 ... 22] = { IPRA(0), 2 }, /* RTC CUI */ + [23 ... 26] = { IPRB(4), 3 }, /* SCI */ + [27] = { IPRB(12), 2 }, /* WDT ITI */ + [32] = { IPRC(0), 1 }, /* IRQ 0 */ + [33] = { IPRC(4), 1 }, /* IRQ 1 */ + [34] = { IPRC(8), 1 }, /* IRQ 2 APM */ + [35] = { IPRC(12), 1 }, /* IRQ 3 TOUCHSCREEN */ + [36] = { IPRD(0), 1 }, /* IRQ 4 */ + [37] = { IPRD(4), 1 }, /* IRQ 5 */ + [48 ... 51] = { IPRE(12), 7 }, /* DMA */ + [52 ... 55] = { IPRE(8), 3 }, /* IRDA */ + [56 ... 59] = { IPRE(4), 3 }, /* SCIF */ }; void __init init_IRQ_ipr() -- cgit v1.2.3-59-g8ed1b From 3dde7a3c74bcc25c6fc31b836fec8c91fb0b2b8f Mon Sep 17 00:00:00 2001 From: Kristoffer Ericson Date: Tue, 1 May 2007 12:21:26 +0900 Subject: sh: Fix APM emulation on hp6xx. With the shared APM emulation code being introduced, hp6xx was missed in the conversion. Get it building again. Signed-off-by: Kristoffer Ericson Signed-off-by: Paul Mundt --- arch/sh/boards/hp6xx/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/hp6xx/Makefile b/arch/sh/boards/hp6xx/Makefile index ff1b7f5b4e91..b3124278247c 100644 --- a/arch/sh/boards/hp6xx/Makefile +++ b/arch/sh/boards/hp6xx/Makefile @@ -2,6 +2,6 @@ # Makefile for the HP6xx specific parts of the kernel # -obj-y := setup.o +obj-y := setup.o obj-$(CONFIG_PM) += pm.o pm_wakeup.o -obj-$(CONFIG_APM) += hp6xx_apm.o +obj-$(CONFIG_APM_EMULATION) += hp6xx_apm.o -- cgit v1.2.3-59-g8ed1b From 3a2e117e220f000f95187ea1e1bbe83b0ed5fdfb Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 1 May 2007 16:33:10 +0900 Subject: sh: Add die chain notifiers. Add the atomic die chains in, kprobes needs these. Signed-off-by: Paul Mundt --- arch/sh/kernel/process.c | 15 ++++++++++++--- arch/sh/kernel/traps.c | 19 +++++++++++++++++-- arch/sh/mm/fault.c | 39 +++++++++++++++++++++++++++++++++++++-- include/asm-sh/kdebug.h | 35 +++++++++++++++++++++++++++++++++++ include/asm-sh/system.h | 3 +++ 5 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 include/asm-sh/kdebug.h (limited to 'arch') diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 286c80388bf5..329b3f3051de 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -7,7 +7,7 @@ * * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima * Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC - * Copyright (C) 2002 - 2006 Paul Mundt + * Copyright (C) 2002 - 2007 Paul Mundt */ #include #include @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -299,8 +300,8 @@ static void ubc_set_tracing(int asid, unsigned long pc) ctrl_outl(0, UBC_BAMRA); if (current_cpu_data.type == CPU_SH7729 || - current_cpu_data.type == CPU_SH7710 || - current_cpu_data.type == CPU_SH7712 ) { + current_cpu_data.type == CPU_SH7710 || + current_cpu_data.type == CPU_SH7712) { ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA); ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR); } else { @@ -496,6 +497,10 @@ asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5, /* Rewind */ regs->pc -= 2; + if (notify_die(DIE_TRAP, regs, regs->tra & 0xff, + SIGTRAP) == NOTIFY_STOP) + return; + force_sig(SIGTRAP, current); } @@ -511,6 +516,10 @@ asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5, /* Rewind */ regs->pc -= 2; + if (notify_die(DIE_TRAP, regs, TRAPA_BUG_OPCODE & 0xff, + SIGTRAP) == NOTIFY_STOP) + return; + #ifdef CONFIG_BUG if (__kernel_text_address(instruction_pointer(regs))) { u16 insn = *(u16 *)instruction_pointer(regs); diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index 77107838271f..7b40f0ff3dfc 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -5,7 +5,7 @@ * SuperH version: Copyright (C) 1999 Niibe Yutaka * Copyright (C) 2000 Philipp Rumpf * Copyright (C) 2000 David Howells - * Copyright (C) 2002 - 2006 Paul Mundt + * Copyright (C) 2002 - 2007 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef CONFIG_SH_KGDB #include @@ -75,7 +76,21 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top) } } -DEFINE_SPINLOCK(die_lock); +ATOMIC_NOTIFIER_HEAD(shdie_chain); + +int register_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&shdie_chain, nb); +} +EXPORT_SYMBOL(register_die_notifier); + +int unregister_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&shdie_chain, nb); +} +EXPORT_SYMBOL(unregister_die_notifier); + +static DEFINE_SPINLOCK(die_lock); void die(const char * str, struct pt_regs * regs, long err) { diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index fa5d7f0b9f18..0ecc117cade4 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c @@ -2,7 +2,7 @@ * Page fault handler for SH with an MMU. * * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2003 Paul Mundt + * Copyright (C) 2003 - 2007 Paul Mundt * * Based on linux/arch/i386/mm/fault.c: * Copyright (C) 1995 Linus Torvalds @@ -15,12 +15,42 @@ #include #include #include +#include #include #include #include #include -extern void die(const char *,struct pt_regs *,long); +#ifdef CONFIG_KPROBES +ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); + +/* Hook to register for page fault notifications */ +int register_page_fault_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); +} + +int unregister_page_fault_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); +} + +static inline int notify_page_fault(enum die_val val, struct pt_regs *regs, + int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .trapnr = trap, + }; + return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); +} +#else +static inline int notify_page_fault(enum die_val val, struct pt_regs *regs, + int trap, int sig) +{ + return NOTIFY_DONE; +} +#endif /* * This routine handles page faults. It determines the address, @@ -39,6 +69,11 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, siginfo_t info; trace_hardirqs_on(); + + if (notify_page_fault(DIE_PAGE_FAULT, regs, + writeaccess, SIGSEGV) == NOTIFY_STOP) + return; + local_irq_enable(); #ifdef CONFIG_SH_KGDB diff --git a/include/asm-sh/kdebug.h b/include/asm-sh/kdebug.h new file mode 100644 index 000000000000..ef009baf5a11 --- /dev/null +++ b/include/asm-sh/kdebug.h @@ -0,0 +1,35 @@ +#ifndef __ASM_SH_KDEBUG_H +#define __ASM_SH_KDEBUG_H + +#include + +struct pt_regs; + +struct die_args { + struct pt_regs *regs; + int trapnr; +}; + +int register_die_notifier(struct notifier_block *nb); +int unregister_die_notifier(struct notifier_block *nb); +int register_page_fault_notifier(struct notifier_block *nb); +int unregister_page_fault_notifier(struct notifier_block *nb); +extern struct atomic_notifier_head shdie_chain; + +/* Grossly misnamed. */ +enum die_val { + DIE_TRAP, + DIE_PAGE_FAULT, +}; + +static inline int notify_die(enum die_val val, struct pt_regs *regs, + int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .trapnr = trap, + }; + + return atomic_notifier_call_chain(&shdie_chain, val, &args); +} +#endif /* __ASM_SH_KDEBUG_H */ diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h index 4a6a19f4f8a4..127af304865f 100644 --- a/include/asm-sh/system.h +++ b/include/asm-sh/system.h @@ -9,6 +9,7 @@ #include #include #include +#include /* * switch_to() should switch tasks to task nr n, first @@ -255,6 +256,8 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old, (unsigned long)_n_, sizeof(*(ptr))); \ }) +extern void die(const char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn)); + extern void *set_exception_table_vec(unsigned int vec, void *handler); static inline void *set_exception_table_evt(unsigned int evt, void *handler) -- cgit v1.2.3-59-g8ed1b From 9c37dc633016e9ebdc39adba0737b390e0de1507 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 1 May 2007 16:35:05 +0900 Subject: sh: Update r7780rp defconfig. Signed-off-by: Paul Mundt --- arch/sh/configs/r7780rp_defconfig | 108 +++++++++++++++++++++++++++++--------- 1 file changed, 82 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/sh/configs/r7780rp_defconfig b/arch/sh/configs/r7780rp_defconfig index 2b75b4896ba5..48c6a2194c98 100644 --- a/arch/sh/configs/r7780rp_defconfig +++ b/arch/sh/configs/r7780rp_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19 -# Wed Dec 6 11:59:38 2006 +# Linux kernel version: 2.6.21-rc7 +# Tue May 1 12:28:39 2007 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_BUG=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y @@ -13,6 +14,8 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y # CONFIG_GENERIC_TIME is not set CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -31,6 +34,7 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set @@ -41,7 +45,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_SYSFS_DEPRECATED is not set # CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" +# CONFIG_BLK_DEV_INITRD is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_EMBEDDED=y @@ -99,23 +103,23 @@ CONFIG_DEFAULT_IOSCHED="noop" # System type # # CONFIG_SH_SOLUTION_ENGINE is not set +# CONFIG_SH_7722_SOLUTION_ENGINE is not set # CONFIG_SH_7751_SOLUTION_ENGINE is not set +# CONFIG_SH_7780_SOLUTION_ENGINE is not set # CONFIG_SH_7300_SOLUTION_ENGINE is not set # CONFIG_SH_7343_SOLUTION_ENGINE is not set # CONFIG_SH_73180_SOLUTION_ENGINE is not set # CONFIG_SH_7751_SYSTEMH is not set # CONFIG_SH_HP6XX is not set -# CONFIG_SH_EC3104 is not set # CONFIG_SH_SATURN is not set # CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_BIGSUR is not set # CONFIG_SH_MPC1211 is not set # CONFIG_SH_SH03 is not set # CONFIG_SH_SECUREEDGE5410 is not set # CONFIG_SH_HS7751RVOIP is not set # CONFIG_SH_7710VOIPGW is not set # CONFIG_SH_RTS7751R2D is not set -CONFIG_SH_R7780RP=y +CONFIG_SH_HIGHLANDER=y # CONFIG_SH_EDOSK7705 is not set # CONFIG_SH_SH4202_MICRODEV is not set # CONFIG_SH_LANDISK is not set @@ -123,7 +127,11 @@ CONFIG_SH_R7780RP=y # CONFIG_SH_SHMIN is not set # CONFIG_SH_7206_SOLUTION_ENGINE is not set # CONFIG_SH_7619_SOLUTION_ENGINE is not set +# CONFIG_SH_LBOX_RE2 is not set # CONFIG_SH_UNKNOWN is not set +CONFIG_SH_R7780RP=y +# CONFIG_SH_R7780MP is not set +# CONFIG_SH_R7785RP is not set # # Processor selection @@ -152,6 +160,7 @@ CONFIG_CPU_SH4A=y # CONFIG_CPU_SUBTYPE_SH7708 is not set # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7710 is not set +# CONFIG_CPU_SUBTYPE_SH7712 is not set # # SH-4 Processor Support @@ -183,6 +192,7 @@ CONFIG_CPU_SUBTYPE_SH7780=y # # CONFIG_CPU_SUBTYPE_SH73180 is not set # CONFIG_CPU_SUBTYPE_SH7343 is not set +# CONFIG_CPU_SUBTYPE_SH7722 is not set # # Memory management options @@ -193,6 +203,8 @@ CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 # CONFIG_32BIT is not set CONFIG_VSYSCALL=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_64KB is not set @@ -210,6 +222,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 # # Cache configuration @@ -226,20 +239,15 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_SH_FPU=y # CONFIG_SH_DSP is not set CONFIG_SH_STORE_QUEUES=y +CONFIG_SPECULATIVE_EXECUTION=y CONFIG_CPU_HAS_INTEVT=y CONFIG_CPU_HAS_INTC2_IRQ=y CONFIG_CPU_HAS_SR_RB=y -CONFIG_CPU_HAS_PTEA=y # -# Timer support +# Timer and clock configuration # CONFIG_SH_TMU=y - -# -# R7780RP options -# -CONFIG_SH_R7780MP=y CONFIG_SH_TIMER_IRQ=28 CONFIG_NO_IDLE_HZ=y CONFIG_SH_PCLK_FREQ=32000000 @@ -262,6 +270,7 @@ CONFIG_SH_PCLK_FREQ=32000000 # # Additional SuperH Device Drivers # +# CONFIG_HEARTBEAT is not set CONFIG_PUSH_SWITCH=y # @@ -269,9 +278,11 @@ CONFIG_PUSH_SWITCH=y # # CONFIG_HZ_100 is not set CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 CONFIG_KEXEC=y +# CONFIG_CRASH_DUMP is not set # CONFIG_SMP is not set # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set @@ -294,7 +305,6 @@ CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y CONFIG_PCI_AUTO=y CONFIG_PCI_AUTO_UPDATE_RESOURCES=y -# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set # @@ -334,6 +344,7 @@ CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -425,6 +436,7 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=m # CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # @@ -445,6 +457,7 @@ CONFIG_FW_LOADER=m # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -461,7 +474,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -481,6 +493,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y @@ -500,6 +513,7 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_MULTI_LUN is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set # # SCSI Transports @@ -544,11 +558,13 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set # # Serial ATA (prod) and Parallel ATA (experimental) drivers # CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set # CONFIG_SATA_AHCI is not set # CONFIG_SATA_SVW is not set # CONFIG_ATA_PIIX is not set @@ -564,6 +580,7 @@ CONFIG_SATA_SIL=y # CONFIG_SATA_ULI is not set # CONFIG_SATA_VIA is not set # CONFIG_SATA_VITESSE is not set +# CONFIG_SATA_INIC162X is not set # CONFIG_PATA_ALI is not set # CONFIG_PATA_AMD is not set # CONFIG_PATA_ARTOP is not set @@ -579,6 +596,7 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_HPT3X2N is not set # CONFIG_PATA_HPT3X3 is not set # CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set @@ -685,6 +703,7 @@ CONFIG_8139TOO_8129=y CONFIG_VIA_RHINE=m CONFIG_VIA_RHINE_MMIO=y # CONFIG_VIA_RHINE_NAPI is not set +# CONFIG_SC92031 is not set # # Ethernet (1000 Mbit) @@ -707,11 +726,13 @@ CONFIG_R8169=y # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set # CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set # # Ethernet (10000 Mbit) # # CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set @@ -889,9 +910,15 @@ CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + # # Multimedia devices # @@ -905,9 +932,8 @@ CONFIG_HWMON=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y -# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_FB is not set # # Sound @@ -923,15 +949,20 @@ CONFIG_SOUND=m # Open Sound System # CONFIG_SOUND_PRIME=m -# CONFIG_OSS_OBSOLETE_DRIVER is not set +# CONFIG_OBSOLETE_OSS is not set # CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_ES1371 is not set # CONFIG_SOUND_ICH is not set # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set # CONFIG_SOUND_VIA82CXXX is not set +# +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + # # USB support # @@ -1016,6 +1047,14 @@ CONFIG_RTC_DRV_SH=y # DMA Devices # +# +# Auxiliary Display support +# + +# +# Virtualization +# + # # File systems # @@ -1174,6 +1213,11 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + # # Profiling support # @@ -1184,19 +1228,22 @@ CONFIG_OPROFILE=m # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_PRINTK_TIME=y +# CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_PREEMPT is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_LOCK_ALLOC is not set # CONFIG_PROVE_LOCKING is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set @@ -1204,19 +1251,19 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set -CONFIG_FRAME_POINTER=y +# CONFIG_FRAME_POINTER is not set CONFIG_FORCED_INLINING=y -# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_SH_STANDARD_BIOS is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_SH_STANDARD_BIOS=y # CONFIG_EARLY_SCIF_CONSOLE is not set +CONFIG_EARLY_PRINTK=y CONFIG_DEBUG_STACKOVERFLOW=y # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_4KSTACKS is not set -# CONFIG_KGDB is not set +# CONFIG_SH_KGDB is not set # # Security options @@ -1233,6 +1280,7 @@ CONFIG_CRYPTO_BLKCIPHER=y CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=y @@ -1241,9 +1289,13 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_LRW is not set CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set # CONFIG_CRYPTO_SERPENT is not set @@ -1257,6 +1309,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_TEST is not set # @@ -1266,7 +1319,10 @@ CONFIG_CRYPTO_DES=y # # Library routines # +CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y -- cgit v1.2.3-59-g8ed1b From 39374aadcd0159b4744ab456f4efa100bea84bd4 Mon Sep 17 00:00:00 2001 From: Ryusuke Sakato Date: Mon, 7 May 2007 10:48:56 +0900 Subject: sh: R7785RP board updates. Some fixups for the R7785RP board. Gets iVDR working. Signed-off-by: Ryusuke Sakato Signed-off-by: Paul Mundt --- arch/sh/boards/renesas/r7780rp/setup.c | 4 ++-- arch/sh/drivers/pci/ops-r7780rp.c | 12 +----------- arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 21 +++++++++++++-------- include/asm-sh/r7780rp.h | 7 +++++++ 4 files changed, 23 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c index 6af0cc35ceb7..0727ef92f2b3 100644 --- a/arch/sh/boards/renesas/r7780rp/setup.c +++ b/arch/sh/boards/renesas/r7780rp/setup.c @@ -97,12 +97,12 @@ device_initcall(r7780rp_devices_setup); */ static void ivdr_clk_enable(struct clk *clk) { - ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << 8), PA_IVDRCTL); + ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << IVDR_CK_ON), PA_IVDRCTL); } static void ivdr_clk_disable(struct clk *clk) { - ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << 8), PA_IVDRCTL); + ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << IVDR_CK_ON), PA_IVDRCTL); } static struct clk_ops ivdr_clk_ops = { diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c index 6f4fb38bafa2..f2216081ab85 100644 --- a/arch/sh/drivers/pci/ops-r7780rp.c +++ b/arch/sh/drivers/pci/ops-r7780rp.c @@ -25,22 +25,12 @@ static char r7780mp_irq_tab[] __initdata = { 65, 66, 67, 68, }; -static char r7785rp_irq_tab[][4] __initdata = { - { 65, 66, 67, 68 }, /* INT ABCD */ - { 66, 67, 68, 65 }, /* INT BCDA */ - { 67, 68, 65, 66 }, /* INT CDAB */ - { 68, 65, 66, 67 }, /* INT DABC */ - { 64, 64, 64, 64 }, /* PCI Host */ -}; - int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { if (mach_is_r7780rp()) return r7780rp_irq_tab[slot]; - if (mach_is_r7780mp()) + if (mach_is_r7780mp() || mach_is_r7785rp()) return r7780mp_irq_tab[slot]; - if (mach_is_r7785rp()) - return r7785rp_irq_tab[slot][pin]; printk(KERN_ERR "PCI: Bad IRQ mapping " "request for slot %d, func %d\n", slot, pin-1); diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index c9ae6592f098..07b0de82cfe6 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -75,21 +75,26 @@ __initcall(sh7785_devices_setup); static struct intc2_data intc2_irq_table[] = { { 28, 0, 24, 0, 0, 2 }, /* TMU0 */ - { 40, 8, 24, 0, 3, 3 }, /* SCIF0 ERI */ - { 41, 8, 24, 0, 3, 3 }, /* SCIF0 RXI */ - { 42, 8, 24, 0, 3, 3 }, /* SCIF0 BRI */ - { 43, 8, 24, 0, 3, 3 }, /* SCIF0 TXI */ + { 40, 8, 24, 0, 2, 3 }, /* SCIF0 ERI */ + { 41, 8, 24, 0, 2, 3 }, /* SCIF0 RXI */ + { 42, 8, 24, 0, 2, 3 }, /* SCIF0 BRI */ + { 43, 8, 24, 0, 2, 3 }, /* SCIF0 TXI */ - { 76, 8, 16, 0, 4, 3 }, /* SCIF1 ERI */ - { 77, 8, 16, 0, 4, 3 }, /* SCIF1 RXI */ - { 78, 8, 16, 0, 4, 3 }, /* SCIF1 BRI */ - { 79, 8, 16, 0, 4, 3 }, /* SCIF1 TXI */ + { 44, 8, 16, 0, 3, 3 }, /* SCIF1 ERI */ + { 45, 8, 16, 0, 3, 3 }, /* SCIF1 RXI */ + { 46, 8, 16, 0, 3, 3 }, /* SCIF1 BRI */ + { 47, 8, 16, 0, 3, 3 }, /* SCIF1 TXI */ { 64, 0x14, 8, 0, 14, 2 }, /* PCIC0 */ { 65, 0x14, 0, 0, 15, 2 }, /* PCIC1 */ { 66, 0x18, 24, 0, 16, 2 }, /* PCIC2 */ { 67, 0x18, 16, 0, 17, 2 }, /* PCIC3 */ { 68, 0x18, 8, 0, 18, 2 }, /* PCIC4 */ + + { 60, 8, 8, 0, 4, 3 }, /* SCIF2 ERI, RXI, BRI, TXI */ + { 60, 8, 0, 0, 5, 3 }, /* SCIF3 ERI, RXI, BRI, TXI */ + { 60, 12, 24, 0, 6, 3 }, /* SCIF4 ERI, RXI, BRI, TXI */ + { 60, 12, 16, 0, 7, 3 }, /* SCIF5 ERI, RXI, BRI, TXI */ }; void __init init_IRQ_intc2(void) diff --git a/include/asm-sh/r7780rp.h b/include/asm-sh/r7780rp.h index bb391e0979e6..4083b5949928 100644 --- a/include/asm-sh/r7780rp.h +++ b/include/asm-sh/r7780rp.h @@ -83,6 +83,8 @@ #define IRQ_ONETH 13 /* On board Ethernet IRQ */ #define IRQ_PSW 14 /* Push Switch IRQ */ +#define IVDR_CK_ON 8 /* iVDR Clock ON */ + #elif defined(CONFIG_SH_R7780RP) #define PA_POFF (-1) @@ -152,6 +154,8 @@ #define IRQ_PSW 13 /* Push Switch IRQ */ #define IRQ_ZIGBEE 14 /* Ziggbee IO IRQ */ +#define IVDR_CK_ON 8 /* iVDR Clock ON */ + #elif defined(CONFIG_SH_R7785RP) #define PA_BCR 0xa4000000 /* FPGA */ #define PA_SDPOW (-1) @@ -197,6 +201,9 @@ #define PA_CU3MDR (PA_BCR+0x0300) #define PA_CU5MDR (PA_BCR+0x0302) #define PA_MMSR (PA_BCR+0x0400) + +#define IVDR_CK_ON 4 /* iVDR Clock ON */ + #endif void make_r7780rp_irq(unsigned int irq); -- cgit v1.2.3-59-g8ed1b From 4cad69174f385c183b2bcb369fb4304d8624ab96 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 30 Apr 2007 17:59:50 -0700 Subject: [SPARC]: Fix comment typo in smp4m_blackbox_current(). Signed-off-by: David S. Miller --- arch/sparc/kernel/sun4m_smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c index e2d9c018bd56..4e07bdbbfb5d 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c @@ -405,7 +405,7 @@ void __init smp4m_blackbox_current(unsigned *addr) addr[0] = 0x81580000 | rd; /* rd %tbr, reg */ addr[2] = 0x8130200a | rd | rs1; /* srl reg, 0xa, reg */ - addr[4] = 0x8008200c | rd | rs1; /* and reg, 3, reg */ + addr[4] = 0x8008200c | rd | rs1; /* and reg, 0xc, reg */ } void __init sun4m_init_smp(void) -- cgit v1.2.3-59-g8ed1b From 861fe90656b8e20d750d73c57088dc52d316ce7b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 2 May 2007 17:31:36 -0700 Subject: [SPARC64]: SUN4U PCI-E controller support. Some minor refactoring in the generic code was necessary for this: 1) This controller requires 8-byte access to the interrupt map and clear register. They are 64-bits on all the other SBUS and PCI controllers anyways, so this was easy to cure. 2) The IMAP register has a different layout and some bits that we need to preserve, so use a read/modify/write when making changes to the IMAP register in generic code. 3) Flushing the entire IOMMU TLB is best done with a single write to a register on this PCI controller, add a iommu->iommu_flushinv for this. Still lacks MSI support, that will come later. Signed-off-by: David S. Miller --- arch/sparc64/kernel/Makefile | 2 +- arch/sparc64/kernel/irq.c | 16 +- arch/sparc64/kernel/pci.c | 9 + arch/sparc64/kernel/pci_fire.c | 418 ++++++++++++++++++++++++++++++++++++++++ arch/sparc64/kernel/pci_iommu.c | 22 ++- arch/sparc64/kernel/prom.c | 89 ++++++++- include/asm-sparc64/iommu.h | 1 + 7 files changed, 535 insertions(+), 22 deletions(-) create mode 100644 arch/sparc64/kernel/pci_fire.c (limited to 'arch') diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index eff0c01d3579..6bf6fb65bc20 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -17,7 +17,7 @@ obj-y := process.o setup.o cpu.o idprom.o \ obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ pci_psycho.o pci_sabre.o pci_schizo.o \ - pci_sun4v.o pci_sun4v_asm.o + pci_sun4v.o pci_sun4v_asm.o pci_fire.o obj-$(CONFIG_SMP) += smp.o trampoline.o obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 6241e3dbbd57..3edc18e1b818 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -279,7 +279,7 @@ static void sun4u_irq_enable(unsigned int virt_irq) struct irq_handler_data *data = get_irq_chip_data(virt_irq); if (likely(data)) { - unsigned long cpuid, imap; + unsigned long cpuid, imap, val; unsigned int tid; cpuid = irq_choose_cpu(virt_irq); @@ -287,7 +287,11 @@ static void sun4u_irq_enable(unsigned int virt_irq) tid = sun4u_compute_tid(imap, cpuid); - upa_writel(tid | IMAP_VALID, imap); + val = upa_readq(imap); + val &= ~(IMAP_TID_UPA | IMAP_TID_JBUS | + IMAP_AID_SAFARI | IMAP_NID_SAFARI); + val |= tid | IMAP_VALID; + upa_writeq(val, imap); } } @@ -297,10 +301,10 @@ static void sun4u_irq_disable(unsigned int virt_irq) if (likely(data)) { unsigned long imap = data->imap; - u32 tmp = upa_readl(imap); + u32 tmp = upa_readq(imap); tmp &= ~IMAP_VALID; - upa_writel(tmp, imap); + upa_writeq(tmp, imap); } } @@ -309,7 +313,7 @@ static void sun4u_irq_end(unsigned int virt_irq) struct irq_handler_data *data = get_irq_chip_data(virt_irq); if (likely(data)) - upa_writel(ICLR_IDLE, data->iclr); + upa_writeq(ICLR_IDLE, data->iclr); } static void sun4v_irq_enable(unsigned int virt_irq) @@ -465,7 +469,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) BUG_ON(tlb_type == hypervisor); - ino = (upa_readl(imap) & (IMAP_IGN | IMAP_INO)) + inofixup; + ino = (upa_readq(imap) & (IMAP_IGN | IMAP_INO)) + inofixup; bucket = &ivector_table[ino]; if (!bucket->virt_irq) { bucket->virt_irq = virt_irq_alloc(__irq(bucket)); diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 9a549547cb2b..a72a3c312d33 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -190,6 +190,7 @@ extern void schizo_init(struct device_node *, const char *); extern void schizo_plus_init(struct device_node *, const char *); extern void tomatillo_init(struct device_node *, const char *); extern void sun4v_pci_init(struct device_node *, const char *); +extern void fire_pci_init(struct device_node *, const char *); static struct { char *model_name; @@ -207,6 +208,7 @@ static struct { { "SUNW,tomatillo", tomatillo_init }, { "pci108e,a801", tomatillo_init }, { "SUNW,sun4v-pci", sun4v_pci_init }, + { "pciex108e,80f0", fire_pci_init }, }; #define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \ sizeof(pci_controller_table[0])) @@ -436,6 +438,13 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, printk(" class: 0x%x device name: %s\n", dev->class, pci_name(dev)); + /* I have seen IDE devices which will not respond to + * the bmdma simplex check reads if bus mastering is + * disabled. + */ + if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) + pci_set_master(dev); + dev->current_state = 4; /* unknown power state */ dev->error_state = pci_channel_io_normal; diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c new file mode 100644 index 000000000000..0fe626631e12 --- /dev/null +++ b/arch/sparc64/kernel/pci_fire.c @@ -0,0 +1,418 @@ +/* pci_fire.c: Sun4u platform PCI-E controller support. + * + * Copyright (C) 2007 David S. Miller (davem@davemloft.net) + */ +#include +#include +#include +#include + +#include +#include +#include + +#include "pci_impl.h" + +#define fire_read(__reg) \ +({ u64 __ret; \ + __asm__ __volatile__("ldxa [%1] %2, %0" \ + : "=r" (__ret) \ + : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \ + : "memory"); \ + __ret; \ +}) +#define fire_write(__reg, __val) \ + __asm__ __volatile__("stxa %0, [%1] %2" \ + : /* no outputs */ \ + : "r" (__val), "r" (__reg), \ + "i" (ASI_PHYS_BYPASS_EC_E) \ + : "memory") + +/* Fire config space address format is nearly identical to + * that of SCHIZO and PSYCHO, except that in order to accomodate + * PCI-E extended config space the encoding can handle 12 bits + * of register address: + * + * 32 28 27 20 19 15 14 12 11 2 1 0 + * ------------------------------------------------- + * |0 0 0 0 0| bus | device | function | reg | 0 0 | + * ------------------------------------------------- + */ +#define FIRE_CONFIG_BASE(PBM) ((PBM)->config_space) +#define FIRE_CONFIG_ENCODE(BUS, DEVFN, REG) \ + (((unsigned long)(BUS) << 20) | \ + ((unsigned long)(DEVFN) << 12) | \ + ((unsigned long)(REG))) + +static void *fire_pci_config_mkaddr(struct pci_pbm_info *pbm, + unsigned char bus, + unsigned int devfn, + int where) +{ + if (!pbm) + return NULL; + return (void *) + (FIRE_CONFIG_BASE(pbm) | + FIRE_CONFIG_ENCODE(bus, devfn, where)); +} + +/* FIRE PCI configuration space accessors. */ + +static int fire_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, + int where, int size, u32 *value) +{ + struct pci_pbm_info *pbm = bus_dev->sysdata; + unsigned char bus = bus_dev->number; + u32 *addr; + u16 tmp16; + u8 tmp8; + + if (bus_dev == pbm->pci_bus && devfn == 0x00) + return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, + size, value); + switch (size) { + case 1: + *value = 0xff; + break; + case 2: + *value = 0xffff; + break; + case 4: + *value = 0xffffffff; + break; + } + + addr = fire_pci_config_mkaddr(pbm, bus, devfn, where); + if (!addr) + return PCIBIOS_SUCCESSFUL; + + switch (size) { + case 1: + pci_config_read8((u8 *)addr, &tmp8); + *value = tmp8; + break; + + case 2: + if (where & 0x01) { + printk("pci_read_config_word: misaligned reg [%x]\n", + where); + return PCIBIOS_SUCCESSFUL; + } + pci_config_read16((u16 *)addr, &tmp16); + *value = tmp16; + break; + + case 4: + if (where & 0x03) { + printk("pci_read_config_dword: misaligned reg [%x]\n", + where); + return PCIBIOS_SUCCESSFUL; + } + + pci_config_read32(addr, value); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static int fire_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, + int where, int size, u32 value) +{ + struct pci_pbm_info *pbm = bus_dev->sysdata; + unsigned char bus = bus_dev->number; + u32 *addr; + + if (bus_dev == pbm->pci_bus && devfn == 0x00) + return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, + size, value); + addr = fire_pci_config_mkaddr(pbm, bus, devfn, where); + if (!addr) + return PCIBIOS_SUCCESSFUL; + + switch (size) { + case 1: + pci_config_write8((u8 *)addr, value); + break; + + case 2: + if (where & 0x01) { + printk("pci_write_config_word: misaligned reg [%x]\n", + where); + return PCIBIOS_SUCCESSFUL; + } + pci_config_write16((u16 *)addr, value); + break; + + case 4: + if (where & 0x03) { + printk("pci_write_config_dword: misaligned reg [%x]\n", + where); + return PCIBIOS_SUCCESSFUL; + } + + pci_config_write32(addr, value); + } + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops pci_fire_ops = { + .read = fire_read_pci_cfg, + .write = fire_write_pci_cfg, +}; + +static void pbm_scan_bus(struct pci_controller_info *p, + struct pci_pbm_info *pbm) +{ + pbm->pci_bus = pci_scan_one_pbm(pbm); +} + +static void pci_fire_scan_bus(struct pci_controller_info *p) +{ + struct device_node *dp; + + if ((dp = p->pbm_A.prom_node) != NULL) + pbm_scan_bus(p, &p->pbm_A); + + if ((dp = p->pbm_B.prom_node) != NULL) + pbm_scan_bus(p, &p->pbm_B); + + /* XXX register error interrupt handlers XXX */ +} + +#define FIRE_IOMMU_CONTROL 0x40000UL +#define FIRE_IOMMU_TSBBASE 0x40008UL +#define FIRE_IOMMU_FLUSH 0x40100UL +#define FIRE_IOMMU_FLUSHINV 0x40100UL + +static void pci_fire_pbm_iommu_init(struct pci_pbm_info *pbm) +{ + struct iommu *iommu = pbm->iommu; + u32 vdma[2], dma_mask; + u64 control; + int tsbsize; + + /* No virtual-dma property on these guys, use largest size. */ + vdma[0] = 0xc0000000; /* base */ + vdma[1] = 0x40000000; /* size */ + dma_mask = 0xffffffff; + tsbsize = 128; + + /* Register addresses. */ + iommu->iommu_control = pbm->pbm_regs + FIRE_IOMMU_CONTROL; + iommu->iommu_tsbbase = pbm->pbm_regs + FIRE_IOMMU_TSBBASE; + iommu->iommu_flush = pbm->pbm_regs + FIRE_IOMMU_FLUSH; + iommu->iommu_flushinv = pbm->pbm_regs + FIRE_IOMMU_FLUSHINV; + + /* We use the main control/status register of FIRE as the write + * completion register. + */ + iommu->write_complete_reg = pbm->controller_regs + 0x410000UL; + + /* + * Invalidate TLB Entries. + */ + fire_write(iommu->iommu_flushinv, ~(u64)0); + + pci_iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask); + + fire_write(iommu->iommu_tsbbase, __pa(iommu->page_table) | 0x7UL); + + control = fire_read(iommu->iommu_control); + control |= (0x00000400 /* TSB cache snoop enable */ | + 0x00000300 /* Cache mode */ | + 0x00000002 /* Bypass enable */ | + 0x00000001 /* Translation enable */); + fire_write(iommu->iommu_control, control); +} + +/* Based at pbm->controller_regs */ +#define FIRE_PARITY_CONTROL 0x470010UL +#define FIRE_PARITY_ENAB 0x8000000000000000UL +#define FIRE_FATAL_RESET_CTL 0x471028UL +#define FIRE_FATAL_RESET_SPARE 0x0000000004000000UL +#define FIRE_FATAL_RESET_MB 0x0000000002000000UL +#define FIRE_FATAL_RESET_CPE 0x0000000000008000UL +#define FIRE_FATAL_RESET_APE 0x0000000000004000UL +#define FIRE_FATAL_RESET_PIO 0x0000000000000040UL +#define FIRE_FATAL_RESET_JW 0x0000000000000004UL +#define FIRE_FATAL_RESET_JI 0x0000000000000002UL +#define FIRE_FATAL_RESET_JR 0x0000000000000001UL +#define FIRE_CORE_INTR_ENABLE 0x471800UL + +/* Based at pbm->pbm_regs */ +#define FIRE_TLU_CTRL 0x80000UL +#define FIRE_TLU_CTRL_TIM 0x00000000da000000UL +#define FIRE_TLU_CTRL_QDET 0x0000000000000100UL +#define FIRE_TLU_CTRL_CFG 0x0000000000000001UL +#define FIRE_TLU_DEV_CTRL 0x90008UL +#define FIRE_TLU_LINK_CTRL 0x90020UL +#define FIRE_TLU_LINK_CTRL_CLK 0x0000000000000040UL +#define FIRE_LPU_RESET 0xe2008UL +#define FIRE_LPU_LLCFG 0xe2200UL +#define FIRE_LPU_LLCFG_VC0 0x0000000000000100UL +#define FIRE_LPU_FCTRL_UCTRL 0xe2240UL +#define FIRE_LPU_FCTRL_UCTRL_N 0x0000000000000002UL +#define FIRE_LPU_FCTRL_UCTRL_P 0x0000000000000001UL +#define FIRE_LPU_TXL_FIFOP 0xe2430UL +#define FIRE_LPU_LTSSM_CFG2 0xe2788UL +#define FIRE_LPU_LTSSM_CFG3 0xe2790UL +#define FIRE_LPU_LTSSM_CFG4 0xe2798UL +#define FIRE_LPU_LTSSM_CFG5 0xe27a0UL +#define FIRE_DMC_IENAB 0x31800UL +#define FIRE_DMC_DBG_SEL_A 0x53000UL +#define FIRE_DMC_DBG_SEL_B 0x53008UL +#define FIRE_PEC_IENAB 0x51800UL + +static void pci_fire_hw_init(struct pci_pbm_info *pbm) +{ + u64 val; + + fire_write(pbm->controller_regs + FIRE_PARITY_CONTROL, + FIRE_PARITY_ENAB); + + fire_write(pbm->controller_regs + FIRE_FATAL_RESET_CTL, + (FIRE_FATAL_RESET_SPARE | + FIRE_FATAL_RESET_MB | + FIRE_FATAL_RESET_CPE | + FIRE_FATAL_RESET_APE | + FIRE_FATAL_RESET_PIO | + FIRE_FATAL_RESET_JW | + FIRE_FATAL_RESET_JI | + FIRE_FATAL_RESET_JR)); + + fire_write(pbm->controller_regs + FIRE_CORE_INTR_ENABLE, ~(u64)0); + + val = fire_read(pbm->pbm_regs + FIRE_TLU_CTRL); + val |= (FIRE_TLU_CTRL_TIM | + FIRE_TLU_CTRL_QDET | + FIRE_TLU_CTRL_CFG); + fire_write(pbm->pbm_regs + FIRE_TLU_CTRL, val); + fire_write(pbm->pbm_regs + FIRE_TLU_DEV_CTRL, 0); + fire_write(pbm->pbm_regs + FIRE_TLU_LINK_CTRL, + FIRE_TLU_LINK_CTRL_CLK); + + fire_write(pbm->pbm_regs + FIRE_LPU_RESET, 0); + fire_write(pbm->pbm_regs + FIRE_LPU_LLCFG, + FIRE_LPU_LLCFG_VC0); + fire_write(pbm->pbm_regs + FIRE_LPU_FCTRL_UCTRL, + (FIRE_LPU_FCTRL_UCTRL_N | + FIRE_LPU_FCTRL_UCTRL_P)); + fire_write(pbm->pbm_regs + FIRE_LPU_TXL_FIFOP, + ((0xffff << 16) | (0x0000 << 0))); + fire_write(pbm->pbm_regs + FIRE_LPU_LTSSM_CFG2, 3000000); + fire_write(pbm->pbm_regs + FIRE_LPU_LTSSM_CFG3, 500000); + fire_write(pbm->pbm_regs + FIRE_LPU_LTSSM_CFG4, + (2 << 16) | (140 << 8)); + fire_write(pbm->pbm_regs + FIRE_LPU_LTSSM_CFG5, 0); + + fire_write(pbm->pbm_regs + FIRE_DMC_IENAB, ~(u64)0); + fire_write(pbm->pbm_regs + FIRE_DMC_DBG_SEL_A, 0); + fire_write(pbm->pbm_regs + FIRE_DMC_DBG_SEL_B, 0); + + fire_write(pbm->pbm_regs + FIRE_PEC_IENAB, ~(u64)0); +} + +static void pci_fire_pbm_init(struct pci_controller_info *p, + struct device_node *dp, u32 portid) +{ + const struct linux_prom64_registers *regs; + struct pci_pbm_info *pbm; + const u32 *ino_bitmap; + const unsigned int *busrange; + + if ((portid & 1) == 0) + pbm = &p->pbm_A; + else + pbm = &p->pbm_B; + + pbm->portid = portid; + pbm->parent = p; + pbm->prom_node = dp; + pbm->name = dp->full_name; + + regs = of_get_property(dp, "reg", NULL); + pbm->pbm_regs = regs[0].phys_addr; + pbm->controller_regs = regs[1].phys_addr - 0x410000UL; + + printk("%s: SUN4U PCIE Bus Module\n", pbm->name); + + pci_determine_mem_io_space(pbm); + + ino_bitmap = of_get_property(dp, "ino-bitmap", NULL); + pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) | + ((u64)ino_bitmap[0] << 0UL)); + + busrange = of_get_property(dp, "bus-range", NULL); + pbm->pci_first_busno = busrange[0]; + pbm->pci_last_busno = busrange[1]; + + pci_fire_hw_init(pbm); + pci_fire_pbm_iommu_init(pbm); +} + +static inline int portid_compare(u32 x, u32 y) +{ + if (x == (y ^ 1)) + return 1; + return 0; +} + +void fire_pci_init(struct device_node *dp, const char *model_name) +{ + struct pci_controller_info *p; + u32 portid = of_getintprop_default(dp, "portid", 0xff); + struct iommu *iommu; + + for (p = pci_controller_root; p; p = p->next) { + struct pci_pbm_info *pbm; + + if (p->pbm_A.prom_node && p->pbm_B.prom_node) + continue; + + pbm = (p->pbm_A.prom_node ? + &p->pbm_A : + &p->pbm_B); + + if (portid_compare(pbm->portid, portid)) { + pci_fire_pbm_init(p, dp, portid); + return; + } + } + + p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); + if (!p) + goto fatal_memory_error; + + iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); + if (!iommu) + goto fatal_memory_error; + + p->pbm_A.iommu = iommu; + + iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); + if (!iommu) + goto fatal_memory_error; + + p->pbm_B.iommu = iommu; + + p->next = pci_controller_root; + pci_controller_root = p; + + p->index = pci_num_controllers++; + + p->scan_bus = pci_fire_scan_bus; + /* XXX MSI support XXX */ + p->pci_ops = &pci_fire_ops; + + /* Like PSYCHO and SCHIZO we have a 2GB aligned area + * for memory space. + */ + pci_memspace_mask = 0x7fffffffUL; + + pci_fire_pbm_init(p, dp, portid); + return; + +fatal_memory_error: + prom_printf("PCI_FIRE: Fatal memory allocation error.\n"); + prom_halt(); +} diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c index 66712772f494..9e405cbbcb0d 100644 --- a/arch/sparc64/kernel/pci_iommu.c +++ b/arch/sparc64/kernel/pci_iommu.c @@ -37,17 +37,21 @@ /* Must be invoked under the IOMMU lock. */ static void __iommu_flushall(struct iommu *iommu) { - unsigned long tag; - int entry; + if (iommu->iommu_flushinv) { + pci_iommu_write(iommu->iommu_flushinv, ~(u64)0); + } else { + unsigned long tag; + int entry; - tag = iommu->iommu_flush + (0xa580UL - 0x0210UL); - for (entry = 0; entry < 16; entry++) { - pci_iommu_write(tag, 0); - tag += 8; - } + tag = iommu->iommu_flush + (0xa580UL - 0x0210UL); + for (entry = 0; entry < 16; entry++) { + pci_iommu_write(tag, 0); + tag += 8; + } - /* Ensure completion of previous PIO writes. */ - (void) pci_iommu_read(iommu->write_complete_reg); + /* Ensure completion of previous PIO writes. */ + (void) pci_iommu_read(iommu->write_complete_reg); + } } #define IOPTE_CONSISTENT(CTX) \ diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index 5e1fcd05160d..6625ac8d15fe 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -386,11 +386,9 @@ static unsigned int psycho_irq_build(struct device_node *dp, /* Now build the IRQ bucket. */ imap = controller_regs + imap_off; - imap += 4; iclr_off = psycho_iclr_offset(ino); iclr = controller_regs + iclr_off; - iclr += 4; if ((ino & 0x20) == 0) inofixup = ino & 0x03; @@ -613,11 +611,9 @@ static unsigned int sabre_irq_build(struct device_node *dp, /* Now build the IRQ bucket. */ imap = controller_regs + imap_off; - imap += 4; iclr_off = sabre_iclr_offset(ino); iclr = controller_regs + iclr_off; - iclr += 4; if ((ino & 0x20) == 0) inofixup = ino & 0x03; @@ -679,13 +675,14 @@ static unsigned long schizo_iclr_offset(unsigned long ino) static unsigned long schizo_ino_to_iclr(unsigned long pbm_regs, unsigned int ino) { - return pbm_regs + schizo_iclr_offset(ino) + 4; + + return pbm_regs + schizo_iclr_offset(ino); } static unsigned long schizo_ino_to_imap(unsigned long pbm_regs, unsigned int ino) { - return pbm_regs + schizo_imap_offset(ino) + 4; + return pbm_regs + schizo_imap_offset(ino); } #define schizo_read(__reg) \ @@ -848,6 +845,85 @@ static void pci_sun4v_irq_trans_init(struct device_node *dp) dp->irq_trans->data = (void *) (unsigned long) ((regs->phys_addr >> 32UL) & 0x0fffffff); } + +struct fire_irq_data { + unsigned long pbm_regs; + u32 portid; +}; + +#define FIRE_IMAP_BASE 0x001000 +#define FIRE_ICLR_BASE 0x001400 + +static unsigned long fire_imap_offset(unsigned long ino) +{ + return FIRE_IMAP_BASE + (ino * 8UL); +} + +static unsigned long fire_iclr_offset(unsigned long ino) +{ + return FIRE_ICLR_BASE + (ino * 8UL); +} + +static unsigned long fire_ino_to_iclr(unsigned long pbm_regs, + unsigned int ino) +{ + return pbm_regs + fire_iclr_offset(ino); +} + +static unsigned long fire_ino_to_imap(unsigned long pbm_regs, + unsigned int ino) +{ + return pbm_regs + fire_imap_offset(ino); +} + +static unsigned int fire_irq_build(struct device_node *dp, + unsigned int ino, + void *_data) +{ + struct fire_irq_data *irq_data = _data; + unsigned long pbm_regs = irq_data->pbm_regs; + unsigned long imap, iclr; + unsigned long int_ctrlr; + + ino &= 0x3f; + + /* Now build the IRQ bucket. */ + imap = fire_ino_to_imap(pbm_regs, ino); + iclr = fire_ino_to_iclr(pbm_regs, ino); + + /* Set the interrupt controller number. */ + int_ctrlr = 1 << 6; + upa_writeq(int_ctrlr, imap); + + /* The interrupt map registers do not have an INO field + * like other chips do. They return zero in the INO + * field, and the interrupt controller number is controlled + * in bits 6 thru 9. So in order for build_irq() to get + * the INO right we pass it in as part of the fixup + * which will get added to the map register zero value + * read by build_irq(). + */ + ino |= (irq_data->portid << 6); + ino -= int_ctrlr; + return build_irq(ino, iclr, imap); +} + +static void fire_irq_trans_init(struct device_node *dp) +{ + const struct linux_prom64_registers *regs; + struct fire_irq_data *irq_data; + + dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); + dp->irq_trans->irq_build = fire_irq_build; + + irq_data = prom_early_alloc(sizeof(struct fire_irq_data)); + + regs = of_get_property(dp, "reg", NULL); + dp->irq_trans->data = irq_data; + + irq_data->pbm_regs = regs[0].phys_addr; + irq_data->portid = of_getintprop_default(dp, "portid", 0); +} #endif /* CONFIG_PCI */ #ifdef CONFIG_SBUS @@ -1069,6 +1145,7 @@ static struct irq_trans pci_irq_trans_table[] = { { "SUNW,tomatillo", tomatillo_irq_trans_init }, { "pci108e,a801", tomatillo_irq_trans_init }, { "SUNW,sun4v-pci", pci_sun4v_irq_trans_init }, + { "pciex108e,80f0", fire_irq_trans_init }, }; #endif diff --git a/include/asm-sparc64/iommu.h b/include/asm-sparc64/iommu.h index e199594a1e9b..0b1813f41045 100644 --- a/include/asm-sparc64/iommu.h +++ b/include/asm-sparc64/iommu.h @@ -32,6 +32,7 @@ struct iommu { unsigned long iommu_control; unsigned long iommu_tsbbase; unsigned long iommu_flush; + unsigned long iommu_flushinv; unsigned long iommu_ctxflush; unsigned long write_complete_reg; unsigned long dummy_page; -- cgit v1.2.3-59-g8ed1b From 7db00552d937e4c0825895734ba5fe257dfe8ced Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 6 May 2007 22:47:14 -0700 Subject: [SPARC64]: Update defconfig. Signed-off-by: David S. Miller --- arch/sparc64/defconfig | 71 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 120c9c33b7a6..37c2d3695658 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -1,15 +1,16 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc4 -# Sat Mar 17 14:18:44 2007 +# Linux kernel version: 2.6.21 +# Sun May 6 22:46:54 2007 # CONFIG_SPARC=y CONFIG_SPARC64=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_64BIT=y CONFIG_MMU=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y -CONFIG_TIME_INTERPOLATION=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set @@ -108,6 +109,9 @@ CONFIG_GENERIC_HARDIRQS=y # # General machine setup # +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y # CONFIG_SMP is not set CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_TABLE=m @@ -140,8 +144,7 @@ CONFIG_SELECT_MEMORY_MODEL=y CONFIG_SPARSEMEM_MANUAL=y CONFIG_SPARSEMEM=y CONFIG_HAVE_MEMORY_PRESENT=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_STATIC=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_RESOURCES_64BIT=y CONFIG_ZONE_DMA_FLAG=0 @@ -151,6 +154,7 @@ CONFIG_SUN_AUXIO=y CONFIG_SUN_IO=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y +CONFIG_ARCH_SUPPORTS_MSI=y CONFIG_PCI_MSI=y # CONFIG_PCI_DEBUG is not set CONFIG_SUN_OPENPROMFS=m @@ -178,7 +182,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -219,6 +222,7 @@ CONFIG_IPV6=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m @@ -292,6 +296,14 @@ CONFIG_NET_TCPPROBE=m # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # @@ -312,10 +324,6 @@ CONFIG_FW_LOADER=y # Connector - unified userspace <-> kernelspace linker # CONFIG_CONNECTOR=m - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -383,7 +391,6 @@ CONFIG_BLK_DEV_IDEPCI=y # CONFIG_BLK_DEV_OPTI621 is not set CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y CONFIG_IDEDMA_ONLYDISK=y # CONFIG_BLK_DEV_AEC62XX is not set CONFIG_BLK_DEV_ALI15X3=y @@ -413,7 +420,6 @@ CONFIG_BLK_DEV_ALI15X3=y # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y # CONFIG_BLK_DEV_HD is not set # @@ -443,6 +449,7 @@ CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports @@ -485,6 +492,7 @@ CONFIG_ISCSI_TCP=m # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_ESP_CORE is not set # CONFIG_SCSI_SUNESP is not set # CONFIG_SCSI_SRP is not set @@ -628,9 +636,10 @@ CONFIG_BNX2=m # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) +# Wireless LAN # -# CONFIG_NET_RADIO is not set +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # # Wan interfaces @@ -695,6 +704,12 @@ CONFIG_KEYBOARD_LKKBD=m # CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set CONFIG_MOUSE_SERIAL=y # CONFIG_MOUSE_VSXXXAA is not set # CONFIG_INPUT_JOYSTICK is not set @@ -702,6 +717,7 @@ CONFIG_MOUSE_SERIAL=y CONFIG_INPUT_MISC=y CONFIG_INPUT_SPARCSPKR=y # CONFIG_INPUT_UINPUT is not set +# CONFIG_INPUT_POLLDEV is not set # # Hardware I/O ports @@ -763,11 +779,8 @@ CONFIG_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y # CONFIG_I2C_CHARDEV is not set # @@ -791,17 +804,17 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PASEMI is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set # CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set # CONFIG_I2C_VIA is not set # CONFIG_I2C_VIAPRO is not set # CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set # # Miscellaneous I2C Chip support @@ -912,7 +925,7 @@ CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y # -# Frambuffer hardware drivers +# Frame buffer hardware drivers # # CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set @@ -937,6 +950,8 @@ CONFIG_FB_RADEON_I2C=y # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_XVR500 is not set +# CONFIG_FB_XVR2500 is not set # CONFIG_FB_PCI is not set # CONFIG_FB_VIRTUAL is not set @@ -1093,6 +1108,14 @@ CONFIG_AC97_BUS=m CONFIG_HID=y # CONFIG_HID_DEBUG is not set +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y + # # USB support # @@ -1106,6 +1129,7 @@ CONFIG_USB=y # Miscellaneous USB options # CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set @@ -1156,10 +1180,6 @@ CONFIG_USB_STORAGE=m # # USB Input Devices # -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -CONFIG_USB_HIDDEV=y # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set # CONFIG_USB_ACECAD is not set @@ -1524,6 +1544,7 @@ CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_LRW=m +# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_BLOWFISH=m -- cgit v1.2.3-59-g8ed1b From 23abc9ec6a4fbcb3da5475f9f4c25415c466de08 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 May 2007 00:00:37 -0700 Subject: [SPARC64]: Fix section mismatch warnings in arch/sparc64/kernel/console.c probe_other_fhcs() and central_probe() should be __init Signed-off-by: David S. Miller --- arch/sparc64/kernel/central.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/central.c b/arch/sparc64/kernel/central.c index c65b2f9c98d8..8230099f0d8a 100644 --- a/arch/sparc64/kernel/central.c +++ b/arch/sparc64/kernel/central.c @@ -98,7 +98,7 @@ void apply_central_ranges(struct linux_central *central, central->num_central_ranges); } -void * __init central_alloc_bootmem(unsigned long size) +static void * __init central_alloc_bootmem(unsigned long size) { void *ret; @@ -116,7 +116,7 @@ static unsigned long prom_reg_to_paddr(struct linux_prom_registers *r) return ret | (unsigned long) r->phys_addr; } -static void probe_other_fhcs(void) +static void __init probe_other_fhcs(void) { struct device_node *dp; const struct linux_prom64_registers *fpregs; @@ -298,7 +298,7 @@ static void init_all_fhc_hw(void) } -void central_probe(void) +void __init central_probe(void) { struct linux_prom_registers fpregs[6]; const struct linux_prom_registers *pr; -- cgit v1.2.3-59-g8ed1b From a6009dda97776d50166e7f1e378cf553a1c20309 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 May 2007 00:01:38 -0700 Subject: [SPARC64]: Fix section mismatch warnings in arch/sparc64/kernel/pci.c apb_calc_first_last(), apb_fake_ranges(), pci_of_scan_bus(), of_scan_pci_bridge(), pci_of_scan_bus(), and pci_scan_one_pbm() should all be __devinit. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index a72a3c312d33..af2c7ff01eeb 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -477,7 +477,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, return dev; } -static void __init apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p) +static void __devinit apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p) { u32 idx, first, last; @@ -506,9 +506,9 @@ static void __init pci_resource_adjust(struct resource *res, /* Cook up fake bus resources for SUNW,simba PCI bridges which lack * a proper 'ranges' property. */ -static void __init apb_fake_ranges(struct pci_dev *dev, - struct pci_bus *bus, - struct pci_pbm_info *pbm) +static void __devinit apb_fake_ranges(struct pci_dev *dev, + struct pci_bus *bus, + struct pci_pbm_info *pbm) { struct resource *res; u32 first, last; @@ -531,15 +531,15 @@ static void __init apb_fake_ranges(struct pci_dev *dev, pci_resource_adjust(res, &pbm->mem_space); } -static void __init pci_of_scan_bus(struct pci_pbm_info *pbm, - struct device_node *node, - struct pci_bus *bus); +static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, + struct device_node *node, + struct pci_bus *bus); #define GET_64BIT(prop, i) ((((u64) (prop)[(i)]) << 32) | (prop)[(i)+1]) -void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, - struct device_node *node, - struct pci_dev *dev) +static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, + struct device_node *node, + struct pci_dev *dev) { struct pci_bus *bus; const u32 *busrange, *ranges; @@ -638,9 +638,9 @@ simba_cont: pci_of_scan_bus(pbm, node, bus); } -static void __init pci_of_scan_bus(struct pci_pbm_info *pbm, - struct device_node *node, - struct pci_bus *bus) +static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, + struct device_node *node, + struct pci_bus *bus) { struct device_node *child; const u32 *reg; @@ -742,7 +742,7 @@ int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, return PCIBIOS_SUCCESSFUL; } -struct pci_bus * __init pci_scan_one_pbm(struct pci_pbm_info *pbm) +struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) { struct pci_controller_info *p = pbm->parent; struct device_node *node = pbm->prom_node; -- cgit v1.2.3-59-g8ed1b From c35a376d6089ab0ece2913959c8363aad76eb820 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 May 2007 00:02:24 -0700 Subject: [SPARC64]: Fix section mismatch warnings in arch/sparc64/kernel/prom.c The IRQ translation init routines should all be __init. Signed-off-by: David S. Miller --- arch/sparc64/kernel/prom.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index 6625ac8d15fe..c54d4d8af014 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -396,7 +396,7 @@ static unsigned int psycho_irq_build(struct device_node *dp, return build_irq(inofixup, iclr, imap); } -static void psycho_irq_trans_init(struct device_node *dp) +static void __init psycho_irq_trans_init(struct device_node *dp) { const struct linux_prom64_registers *regs; @@ -636,7 +636,7 @@ static unsigned int sabre_irq_build(struct device_node *dp, return virt_irq; } -static void sabre_irq_trans_init(struct device_node *dp) +static void __init sabre_irq_trans_init(struct device_node *dp) { const struct linux_prom64_registers *regs; struct sabre_irq_data *irq_data; @@ -793,7 +793,8 @@ static unsigned int schizo_irq_build(struct device_node *dp, return virt_irq; } -static void __schizo_irq_trans_init(struct device_node *dp, int is_tomatillo) +static void __init __schizo_irq_trans_init(struct device_node *dp, + int is_tomatillo) { const struct linux_prom64_registers *regs; struct schizo_irq_data *irq_data; @@ -815,12 +816,12 @@ static void __schizo_irq_trans_init(struct device_node *dp, int is_tomatillo) irq_data->chip_version = of_getintprop_default(dp, "version#", 0); } -static void schizo_irq_trans_init(struct device_node *dp) +static void __init schizo_irq_trans_init(struct device_node *dp) { __schizo_irq_trans_init(dp, 0); } -static void tomatillo_irq_trans_init(struct device_node *dp) +static void __init tomatillo_irq_trans_init(struct device_node *dp) { __schizo_irq_trans_init(dp, 1); } @@ -834,7 +835,7 @@ static unsigned int pci_sun4v_irq_build(struct device_node *dp, return sun4v_build_irq(devhandle, devino); } -static void pci_sun4v_irq_trans_init(struct device_node *dp) +static void __init pci_sun4v_irq_trans_init(struct device_node *dp) { const struct linux_prom64_registers *regs; @@ -908,7 +909,7 @@ static unsigned int fire_irq_build(struct device_node *dp, return build_irq(ino, iclr, imap); } -static void fire_irq_trans_init(struct device_node *dp) +static void __init fire_irq_trans_init(struct device_node *dp) { const struct linux_prom64_registers *regs; struct fire_irq_data *irq_data; @@ -1071,7 +1072,7 @@ static unsigned int sbus_of_build_irq(struct device_node *dp, return build_irq(sbus_level, iclr, imap); } -static void sbus_irq_trans_init(struct device_node *dp) +static void __init sbus_irq_trans_init(struct device_node *dp) { const struct linux_prom64_registers *regs; @@ -1118,7 +1119,7 @@ static unsigned int central_build_irq(struct device_node *dp, return build_irq(0, iclr, imap); } -static void central_irq_trans_init(struct device_node *dp) +static void __init central_irq_trans_init(struct device_node *dp) { dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); dp->irq_trans->irq_build = central_build_irq; @@ -1132,7 +1133,7 @@ struct irq_trans { }; #ifdef CONFIG_PCI -static struct irq_trans pci_irq_trans_table[] = { +static struct irq_trans __initdata pci_irq_trans_table[] = { { "SUNW,sabre", sabre_irq_trans_init }, { "pci108e,a000", sabre_irq_trans_init }, { "pci108e,a001", sabre_irq_trans_init }, @@ -1158,7 +1159,7 @@ static unsigned int sun4v_vdev_irq_build(struct device_node *dp, return sun4v_build_irq(devhandle, devino); } -static void sun4v_vdev_irq_trans_init(struct device_node *dp) +static void __init sun4v_vdev_irq_trans_init(struct device_node *dp) { const struct linux_prom64_registers *regs; @@ -1170,7 +1171,7 @@ static void sun4v_vdev_irq_trans_init(struct device_node *dp) ((regs->phys_addr >> 32UL) & 0x0fffffff); } -static void irq_trans_init(struct device_node *dp) +static void __init irq_trans_init(struct device_node *dp) { #ifdef CONFIG_PCI const char *model; -- cgit v1.2.3-59-g8ed1b From e7f11aeed02767541020984f72f823757c58e48e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 May 2007 00:02:46 -0700 Subject: [SPARC64]: pgtable_cache_init() should be __init. Signed-off-by: David S. Miller --- arch/sparc64/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index cafadcbcdf38..8c7af7e13ff9 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -173,7 +173,7 @@ static void zero_ctor(void *addr, struct kmem_cache *cache, unsigned long flags) extern void tsb_cache_init(void); -void pgtable_cache_init(void) +void __init pgtable_cache_init(void) { pgtable_cache = kmem_cache_create("pgtable_cache", PAGE_SIZE, PAGE_SIZE, -- cgit v1.2.3-59-g8ed1b From e3ebadd95cb621e2c7436f3d3646447ac9d5c16d Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 7 May 2007 08:44:24 -0700 Subject: Revert "[PATCH] x86: __pa and __pa_symbol address space separation" This was broken. It adds complexity, for no good reason. Rather than separate __pa() and __pa_symbol(), we should deprecate __pa_symbol(), and preferably __pa() too - and just use "virt_to_phys()" instead, which is more readable and has nicer semantics. However, right now, just undo the separation, and make __pa_symbol() be the exact same as __pa(). That fixes the bugs this patch introduced, and we can do the fairly obvious cleanups later. Do the new __phys_addr() function (which is now the actual workhorse for the unified __pa()/__pa_symbol()) as a real external function, that way all the potential issues with compile/link-time optimizations of constant symbol addresses go away, and we can also, if we choose to, add more sanity-checking of the argument. Cc: Eric W. Biederman Cc: Vivek Goyal Cc: Andi Kleen Cc: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/alternative.c | 4 ++-- arch/i386/mm/init.c | 15 +++++++-------- arch/x86_64/kernel/machine_kexec.c | 16 ++++++++-------- arch/x86_64/kernel/setup.c | 9 ++++----- arch/x86_64/kernel/smp.c | 2 +- arch/x86_64/mm/init.c | 31 ++++++++++++++++++------------- arch/x86_64/mm/ioremap.c | 9 +++++++++ arch/x86_64/mm/pageattr.c | 16 ++++++++-------- include/asm-x86_64/page.h | 18 +++++++----------- include/asm-x86_64/pgtable.h | 4 ++-- 10 files changed, 66 insertions(+), 58 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index e5cec6685cc5..d8cda14fff8b 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -390,8 +390,8 @@ void __init alternative_instructions(void) _text, _etext); } free_init_pages("SMP alternatives", - __pa_symbol(&__smp_locks), - __pa_symbol(&__smp_locks_end)); + (unsigned long)__smp_locks, + (unsigned long)__smp_locks_end); } else { alternatives_smp_module_add(NULL, "core kernel", __smp_locks, __smp_locks_end, diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index dbe16f63a566..1a7197e89eb4 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -843,11 +843,10 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) unsigned long addr; for (addr = begin; addr < end; addr += PAGE_SIZE) { - struct page *page = pfn_to_page(addr >> PAGE_SHIFT); - ClearPageReserved(page); - init_page_count(page); - memset(page_address(page), POISON_FREE_INITMEM, PAGE_SIZE); - __free_page(page); + ClearPageReserved(virt_to_page(addr)); + init_page_count(virt_to_page(addr)); + memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); + free_page(addr); totalram_pages++; } printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10); @@ -856,14 +855,14 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) void free_initmem(void) { free_init_pages("unused kernel memory", - __pa_symbol(&__init_begin), - __pa_symbol(&__init_end)); + (unsigned long)(&__init_begin), + (unsigned long)(&__init_end)); } #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { - free_init_pages("initrd memory", __pa(start), __pa(end)); + free_init_pages("initrd memory", start, end); } #endif diff --git a/arch/x86_64/kernel/machine_kexec.c b/arch/x86_64/kernel/machine_kexec.c index a8bb33c1a8f2..c3a554703672 100644 --- a/arch/x86_64/kernel/machine_kexec.c +++ b/arch/x86_64/kernel/machine_kexec.c @@ -189,21 +189,21 @@ NORET_TYPE void machine_kexec(struct kimage *image) control_page = page_address(image->control_code_page) + PAGE_SIZE; memcpy(control_page, relocate_kernel, PAGE_SIZE); - page_list[PA_CONTROL_PAGE] = __pa(control_page); + page_list[PA_CONTROL_PAGE] = virt_to_phys(control_page); page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel; - page_list[PA_PGD] = __pa_symbol(&kexec_pgd); + page_list[PA_PGD] = virt_to_phys(&kexec_pgd); page_list[VA_PGD] = (unsigned long)kexec_pgd; - page_list[PA_PUD_0] = __pa_symbol(&kexec_pud0); + page_list[PA_PUD_0] = virt_to_phys(&kexec_pud0); page_list[VA_PUD_0] = (unsigned long)kexec_pud0; - page_list[PA_PMD_0] = __pa_symbol(&kexec_pmd0); + page_list[PA_PMD_0] = virt_to_phys(&kexec_pmd0); page_list[VA_PMD_0] = (unsigned long)kexec_pmd0; - page_list[PA_PTE_0] = __pa_symbol(&kexec_pte0); + page_list[PA_PTE_0] = virt_to_phys(&kexec_pte0); page_list[VA_PTE_0] = (unsigned long)kexec_pte0; - page_list[PA_PUD_1] = __pa_symbol(&kexec_pud1); + page_list[PA_PUD_1] = virt_to_phys(&kexec_pud1); page_list[VA_PUD_1] = (unsigned long)kexec_pud1; - page_list[PA_PMD_1] = __pa_symbol(&kexec_pmd1); + page_list[PA_PMD_1] = virt_to_phys(&kexec_pmd1); page_list[VA_PMD_1] = (unsigned long)kexec_pmd1; - page_list[PA_PTE_1] = __pa_symbol(&kexec_pte1); + page_list[PA_PTE_1] = virt_to_phys(&kexec_pte1); page_list[VA_PTE_1] = (unsigned long)kexec_pte1; page_list[PA_TABLE_PAGE] = diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index db30b5bcef61..db51577bda32 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -245,12 +245,11 @@ void __init setup_arch(char **cmdline_p) init_mm.end_code = (unsigned long) &_etext; init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) &_end; - init_mm.pgd = __va(__pa_symbol(&init_level4_pgt)); - code_resource.start = __pa_symbol(&_text); - code_resource.end = __pa_symbol(&_etext)-1; - data_resource.start = __pa_symbol(&_etext); - data_resource.end = __pa_symbol(&_edata)-1; + code_resource.start = virt_to_phys(&_text); + code_resource.end = virt_to_phys(&_etext)-1; + data_resource.start = virt_to_phys(&_etext); + data_resource.end = virt_to_phys(&_edata)-1; early_identify_cpu(&boot_cpu_data); diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c index 22abae4e9f39..bd1d123947ce 100644 --- a/arch/x86_64/kernel/smp.c +++ b/arch/x86_64/kernel/smp.c @@ -76,7 +76,7 @@ static inline void leave_mm(int cpu) if (read_pda(mmu_state) == TLBSTATE_OK) BUG(); cpu_clear(cpu, read_pda(active_mm)->cpu_vm_mask); - load_cr3(init_mm.pgd); + load_cr3(swapper_pg_dir); } /* diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 282b0a8f00ad..c0822683b916 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -572,13 +572,13 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10); for (addr = begin; addr < end; addr += PAGE_SIZE) { - struct page *page = pfn_to_page(addr >> PAGE_SHIFT); - ClearPageReserved(page); - init_page_count(page); - memset(page_address(page), POISON_FREE_INITMEM, PAGE_SIZE); + ClearPageReserved(virt_to_page(addr)); + init_page_count(virt_to_page(addr)); + memset((void *)(addr & ~(PAGE_SIZE-1)), + POISON_FREE_INITMEM, PAGE_SIZE); if (addr >= __START_KERNEL_map) change_page_attr_addr(addr, 1, __pgprot(0)); - __free_page(page); + free_page(addr); totalram_pages++; } if (addr > __START_KERNEL_map) @@ -588,26 +588,31 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) void free_initmem(void) { free_init_pages("unused kernel memory", - __pa_symbol(&__init_begin), - __pa_symbol(&__init_end)); + (unsigned long)(&__init_begin), + (unsigned long)(&__init_end)); } #ifdef CONFIG_DEBUG_RODATA void mark_rodata_ro(void) { - unsigned long start = PFN_ALIGN(__va(__pa_symbol(&_stext))), size; + unsigned long start = (unsigned long)_stext, end; #ifdef CONFIG_HOTPLUG_CPU /* It must still be possible to apply SMP alternatives. */ if (num_possible_cpus() > 1) - start = PFN_ALIGN(__va(__pa_symbol(&_etext))); + start = (unsigned long)_etext; #endif - size = (unsigned long)__va(__pa_symbol(&__end_rodata)) - start; - change_page_attr_addr(start, size >> PAGE_SHIFT, PAGE_KERNEL_RO); + end = (unsigned long)__end_rodata; + start = (start + PAGE_SIZE - 1) & PAGE_MASK; + end &= PAGE_MASK; + if (end <= start) + return; + + change_page_attr_addr(start, (end - start) >> PAGE_SHIFT, PAGE_KERNEL_RO); printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", - size >> 10); + (end - start) >> 10); /* * change_page_attr_addr() requires a global_flush_tlb() call after it. @@ -622,7 +627,7 @@ void mark_rodata_ro(void) #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { - free_init_pages("initrd memory", __pa(start), __pa(end)); + free_init_pages("initrd memory", start, end); } #endif diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c index c6e5e8d401a4..6cac90aa5032 100644 --- a/arch/x86_64/mm/ioremap.c +++ b/arch/x86_64/mm/ioremap.c @@ -13,12 +13,21 @@ #include #include #include + #include #include #include #include #include +unsigned long __phys_addr(unsigned long x) +{ + if (x >= __START_KERNEL_map) + return x - __START_KERNEL_map + phys_base; + return x - PAGE_OFFSET; +} +EXPORT_SYMBOL(__phys_addr); + #define ISA_START_ADDRESS 0xa0000 #define ISA_END_ADDRESS 0x100000 diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c index bf4aa8dd4254..d653d0bf3df6 100644 --- a/arch/x86_64/mm/pageattr.c +++ b/arch/x86_64/mm/pageattr.c @@ -51,6 +51,7 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot, SetPagePrivate(base); page_private(base) = 0; + address = __pa(address); addr = address & LARGE_PAGE_MASK; pbase = (pte_t *)page_address(base); for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) { @@ -100,12 +101,13 @@ static inline void save_page(struct page *fpage) * No more special protections in this 2/4MB area - revert to a * large page again. */ -static void revert_page(unsigned long address, unsigned long pfn, pgprot_t ref_prot) +static void revert_page(unsigned long address, pgprot_t ref_prot) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t large_pte; + unsigned long pfn; pgd = pgd_offset_k(address); BUG_ON(pgd_none(*pgd)); @@ -113,6 +115,7 @@ static void revert_page(unsigned long address, unsigned long pfn, pgprot_t ref_p BUG_ON(pud_none(*pud)); pmd = pmd_offset(pud, address); BUG_ON(pmd_val(*pmd) & _PAGE_PSE); + pfn = (__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT; large_pte = pfn_pte(pfn, ref_prot); large_pte = pte_mkhuge(large_pte); set_pte((pte_t *)pmd, large_pte); @@ -138,8 +141,7 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot, */ struct page *split; ref_prot2 = pte_pgprot(pte_clrhuge(*kpte)); - split = split_large_page(pfn << PAGE_SHIFT, prot, - ref_prot2); + split = split_large_page(address, prot, ref_prot2); if (!split) return -ENOMEM; set_pte(kpte, mk_pte(split, ref_prot2)); @@ -158,7 +160,7 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot, if (page_private(kpte_page) == 0) { save_page(kpte_page); - revert_page(address, pfn, ref_prot); + revert_page(address, ref_prot); } return 0; } @@ -178,7 +180,6 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot, */ int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot) { - unsigned long phys_base_pfn = __pa_symbol(__START_KERNEL_map) >> PAGE_SHIFT; int err = 0, kernel_map = 0; int i; @@ -199,11 +200,10 @@ int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot) } /* Handle kernel mapping too which aliases part of the * lowmem */ - if ((pfn >= phys_base_pfn) && - ((pfn - phys_base_pfn) < (KERNEL_TEXT_SIZE >> PAGE_SHIFT))) { + if (__pa(address) < KERNEL_TEXT_SIZE) { unsigned long addr2; pgprot_t prot2; - addr2 = __START_KERNEL_map + ((pfn - phys_base_pfn) << PAGE_SHIFT); + addr2 = __START_KERNEL_map + __pa(address); /* Make sure the kernel mappings stay executable */ prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot))); err = __change_page_attr(addr2, pfn, prot2, diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h index b17fc16ec2eb..4d04e2479569 100644 --- a/include/asm-x86_64/page.h +++ b/include/asm-x86_64/page.h @@ -94,26 +94,22 @@ extern unsigned long phys_base; #define KERNEL_TEXT_SIZE (40*1024*1024) #define KERNEL_TEXT_START 0xffffffff80000000 +#define PAGE_OFFSET __PAGE_OFFSET #ifndef __ASSEMBLY__ #include -#endif /* __ASSEMBLY__ */ +extern unsigned long __phys_addr(unsigned long); -#define PAGE_OFFSET __PAGE_OFFSET +#endif /* __ASSEMBLY__ */ -/* Note: __pa(&symbol_visible_to_c) should be always replaced with __pa_symbol. - Otherwise you risk miscompilation. */ -#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET) -/* __pa_symbol should be used for C visible symbols. - This seems to be the official gcc blessed way to do such arithmetic. */ -#define __pa_symbol(x) \ - ({unsigned long v; \ - asm("" : "=r" (v) : "0" (x)); \ - ((v - __START_KERNEL_map) + phys_base); }) +#define __pa(x) __phys_addr((unsigned long)(x)) +#define __pa_symbol(x) __phys_addr((unsigned long)(x)) #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) +#define __boot_va(x) __va(x) +#define __boot_pa(x) __pa(x) #ifdef CONFIG_FLATMEM #define pfn_valid(pfn) ((pfn) < end_pfn) #endif diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h index 599993f6ba84..da3390faaea6 100644 --- a/include/asm-x86_64/pgtable.h +++ b/include/asm-x86_64/pgtable.h @@ -19,7 +19,7 @@ extern pmd_t level2_kernel_pgt[512]; extern pgd_t init_level4_pgt[]; extern unsigned long __supported_pte_mask; -#define swapper_pg_dir ((pgd_t *)NULL) +#define swapper_pg_dir init_level4_pgt extern void paging_init(void); extern void clear_kernel_mapping(unsigned long addr, unsigned long size); @@ -29,7 +29,7 @@ extern void clear_kernel_mapping(unsigned long addr, unsigned long size); * for zero-mapped memory areas etc.. */ extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)]; -#define ZERO_PAGE(vaddr) (pfn_to_page(__pa_symbol(&empty_zero_page) >> PAGE_SHIFT)) +#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) #endif /* !__ASSEMBLY__ */ -- cgit v1.2.3-59-g8ed1b From beab697ab4b2962e3d741b476abe443baad0933d Mon Sep 17 00:00:00 2001 From: Marc St-Jean Date: Sun, 6 May 2007 14:48:45 -0700 Subject: serial driver PMC MSP71xx Serial driver patch for the PMC-Sierra MSP71xx devices. There are three different fixes: 1 Fix for DesignWare APB THRE errata: In brief, this is a non-standard 16550 in that the THRE interrupt will not re-assert itself simply by disabling and re-enabling the THRI bit in the IER, it is only re-enabled if a character is actually sent out. It appears that the "8250-uart-backup-timer.patch" in the "mm" tree also fixes it so we have dropped our initial workaround. This patch now needs to be applied on top of that "mm" patch. 2 Fix for Busy Detect on LCR write: The DesignWare APB UART has a feature which causes a new Busy Detect interrupt to be generated if it's busy when the LCR is written. This fix saves the value of the LCR and rewrites it after clearing the interrupt. 3 Workaround for interrupt/data concurrency issue: The SoC needs to ensure that writes that can cause interrupts to be cleared reach the UART before returning from the ISR. This fix reads a non-destructive register on the UART so the read transaction completion ensures the previously queued write transaction has also completed. Signed-off-by: Marc St-Jean Cc: Russell King Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/pmc-sierra/msp71xx/msp_serial.c | 165 ++++++++++++++++++++++++++++++ drivers/serial/8250.c | 31 ++++++ drivers/serial/serial_core.c | 2 + include/linux/serial_core.h | 2 + include/linux/serial_reg.h | 2 + 5 files changed, 202 insertions(+) create mode 100644 arch/mips/pmc-sierra/msp71xx/msp_serial.c (limited to 'arch') diff --git a/arch/mips/pmc-sierra/msp71xx/msp_serial.c b/arch/mips/pmc-sierra/msp71xx/msp_serial.c new file mode 100644 index 000000000000..c41b53faa8f6 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_serial.c @@ -0,0 +1,165 @@ +/* + * The setup file for serial related hardware on PMC-Sierra MSP processors. + * + * Copyright 2005 PMC-Sierra, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_KGDB +/* + * kgdb uses serial port 1 so the console can remain on port 0. + * To use port 0 change the definition to read as follows: + * #define DEBUG_PORT_BASE KSEG1ADDR(MSP_UART0_BASE) + */ +#define DEBUG_PORT_BASE KSEG1ADDR(MSP_UART1_BASE) + +int putDebugChar(char c) +{ + volatile uint32_t *uart = (volatile uint32_t *)DEBUG_PORT_BASE; + uint32_t val = (uint32_t)c; + + local_irq_disable(); + while( !(uart[5] & 0x20) ); /* Wait for TXRDY */ + uart[0] = val; + while( !(uart[5] & 0x20) ); /* Wait for TXRDY */ + local_irq_enable(); + + return 1; +} + +char getDebugChar(void) +{ + volatile uint32_t *uart = (volatile uint32_t *)DEBUG_PORT_BASE; + uint32_t val; + + while( !(uart[5] & 0x01) ); /* Wait for RXRDY */ + val = uart[0]; + + return (char)val; +} + +void initDebugPort(unsigned int uartclk, unsigned int baudrate) +{ + unsigned int baud_divisor = (uartclk + 8 * baudrate)/(16 * baudrate); + + /* Enable FIFOs */ + writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | + UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_4, + (char *)DEBUG_PORT_BASE + (UART_FCR * 4)); + + /* Select brtc divisor */ + writeb(UART_LCR_DLAB, (char *)DEBUG_PORT_BASE + (UART_LCR * 4)); + + /* Store divisor lsb */ + writeb(baud_divisor, (char *)DEBUG_PORT_BASE + (UART_TX * 4)); + + /* Store divisor msb */ + writeb(baud_divisor >> 8, (char *)DEBUG_PORT_BASE + (UART_IER * 4)); + + /* Set 8N1 mode */ + writeb(UART_LCR_WLEN8, (char *)DEBUG_PORT_BASE + (UART_LCR * 4)); + + /* Disable flow control */ + writeb(0, (char *)DEBUG_PORT_BASE + (UART_MCR * 4)); + + /* Disable receive interrupt(!) */ + writeb(0, (char *)DEBUG_PORT_BASE + (UART_IER * 4)); +} +#endif + +void __init msp_serial_setup(void) +{ + char *s; + char *endp; + struct uart_port up; + unsigned int uartclk; + + memset(&up, 0, sizeof(up)); + + /* Check if clock was specified in environment */ + s = prom_getenv("uartfreqhz"); + if(!(s && *s && (uartclk = simple_strtoul(s, &endp, 10)) && *endp == 0)) + uartclk = MSP_BASE_BAUD; + ppfinit("UART clock set to %d\n", uartclk); + + /* Initialize first serial port */ + up.mapbase = MSP_UART0_BASE; + up.membase = ioremap_nocache(up.mapbase,MSP_UART_REG_LEN); + up.irq = MSP_INT_UART0; + up.uartclk = uartclk; + up.regshift = 2; + up.iotype = UPIO_DWAPB; /* UPIO_MEM like */ + up.flags = STD_COM_FLAGS; + up.type = PORT_16550A; + up.line = 0; + up.private_data = (void*)UART0_STATUS_REG; + if (early_serial_setup(&up)) + printk(KERN_ERR "Early serial init of port 0 failed\n"); + + /* Initialize the second serial port, if one exists */ + switch (mips_machtype) { + case MACH_MSP4200_EVAL: + case MACH_MSP4200_GW: + case MACH_MSP4200_FPGA: + case MACH_MSP7120_EVAL: + case MACH_MSP7120_GW: + case MACH_MSP7120_FPGA: + /* Enable UART1 on MSP4200 and MSP7120 */ + *GPIO_CFG2_REG = 0x00002299; + +#ifdef CONFIG_KGDB + /* Initialize UART1 for kgdb since PMON doesn't */ + if( DEBUG_PORT_BASE == KSEG1ADDR(MSP_UART1_BASE) ) { + if( mips_machtype == MACH_MSP4200_FPGA + || mips_machtype == MACH_MSP7120_FPGA ) + initDebugPort(uartclk,19200); + else + initDebugPort(uartclk,57600); + } +#endif + break; + + default: + return; /* No second serial port, good-bye. */ + } + + up.mapbase = MSP_UART1_BASE; + up.membase = ioremap_nocache(up.mapbase,MSP_UART_REG_LEN); + up.irq = MSP_INT_UART1; + up.line = 1; + up.private_data = (void*)UART1_STATUS_REG; + if (early_serial_setup(&up)) + printk(KERN_ERR "Early serial init of port 1 failed\n"); +} diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 90621c3312bc..194362d9f5a3 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -308,6 +308,7 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset) return inb(up->port.iobase + 1); case UPIO_MEM: + case UPIO_DWAPB: return readb(up->port.membase + offset); case UPIO_MEM32: @@ -333,6 +334,8 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset) static void serial_out(struct uart_8250_port *up, int offset, int value) { + /* Save the offset before it's remapped */ + int save_offset = offset; offset = map_8250_out_reg(up, offset) << up->port.regshift; switch (up->port.iotype) { @@ -359,6 +362,18 @@ serial_out(struct uart_8250_port *up, int offset, int value) writeb(value, up->port.membase + offset); break; + case UPIO_DWAPB: + /* Save the LCR value so it can be re-written when a + * Busy Detect interrupt occurs. */ + if (save_offset == UART_LCR) + up->lcr = value; + writeb(value, up->port.membase + offset); + /* Read the IER to ensure any interrupt is cleared before + * returning from ISR. */ + if (save_offset == UART_TX || save_offset == UART_IER) + value = serial_in(up, UART_IER); + break; + default: outb(value, up->port.iobase + offset); } @@ -373,6 +388,7 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value) #ifdef CONFIG_SERIAL_8250_AU1X00 case UPIO_AU: #endif + case UPIO_DWAPB: serial_out(up, offset, value); serial_in(up, UART_LCR); /* safe, no side-effects */ break; @@ -1388,6 +1404,19 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) handled = 1; + end = NULL; + } else if (up->port.iotype == UPIO_DWAPB && + (iir & UART_IIR_BUSY) == UART_IIR_BUSY) { + /* The DesignWare APB UART has an Busy Detect (0x07) + * interrupt meaning an LCR write attempt occured while the + * UART was busy. The interrupt must be cleared by reading + * the UART status register (USR) and the LCR re-written. */ + unsigned int status; + status = *(volatile u32 *)up->port.private_data; + serial_out(up, UART_LCR, up->lcr); + + handled = 1; + end = NULL; } else if (end == NULL) end = l; @@ -2090,6 +2119,7 @@ static int serial8250_request_std_resource(struct uart_8250_port *up) case UPIO_TSI: case UPIO_MEM32: case UPIO_MEM: + case UPIO_DWAPB: if (!up->port.mapbase) break; @@ -2127,6 +2157,7 @@ static void serial8250_release_std_resource(struct uart_8250_port *up) case UPIO_TSI: case UPIO_MEM32: case UPIO_MEM: + case UPIO_DWAPB: if (!up->port.mapbase) break; diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 0422c0f1f852..a677133ab2d4 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -2064,6 +2064,7 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) case UPIO_MEM32: case UPIO_AU: case UPIO_TSI: + case UPIO_DWAPB: snprintf(address, sizeof(address), "MMIO 0x%lx", port->mapbase); break; @@ -2409,6 +2410,7 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2) case UPIO_MEM32: case UPIO_AU: case UPIO_TSI: + case UPIO_DWAPB: return (port1->mapbase == port2->mapbase); } return 0; diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 586aaba91720..8b5592e6aca4 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -230,6 +230,7 @@ struct uart_port { #define UPIO_MEM32 (3) #define UPIO_AU (4) /* Au1x00 type IO */ #define UPIO_TSI (5) /* Tsi108/109 type IO */ +#define UPIO_DWAPB (6) /* DesignWare APB UART */ unsigned int read_status_mask; /* driver specific */ unsigned int ignore_status_mask; /* driver specific */ @@ -276,6 +277,7 @@ struct uart_port { struct device *dev; /* parent device */ unsigned char hub6; /* this should be in the 8250 driver */ unsigned char unused[3]; + void *private_data; /* generic platform data pointer */ }; /* diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h index 3c8a6aa77415..1c5ed7d92b0f 100644 --- a/include/linux/serial_reg.h +++ b/include/linux/serial_reg.h @@ -38,6 +38,8 @@ #define UART_IIR_RDI 0x04 /* Receiver data interrupt */ #define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */ +#define UART_IIR_BUSY 0x07 /* DesignWare APB Busy Detect */ + #define UART_FCR 2 /* Out: FIFO Control Register */ #define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */ #define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */ -- cgit v1.2.3-59-g8ed1b From bd71c182d5a02337305fc381831c11029dd17d64 Mon Sep 17 00:00:00 2001 From: Thomas Koeller Date: Sun, 6 May 2007 14:48:47 -0700 Subject: RM9000 serial driver Add support for the integrated serial ports of the MIPS RM9122 processor and its relatives. The patch also does some whitespace cleanup. [akpm@linux-foundation.org: cleanups] Signed-off-by: Thomas Koeller Cc: Ralf Baechle Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/Kconfig | 3 ++ drivers/serial/8250.c | 92 +++++++++++++++++++++++++++++++++++++++------ drivers/serial/Kconfig | 9 +++++ include/linux/serial_core.h | 4 +- 4 files changed, 95 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 130d825e5438..7441a2cf523e 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1042,6 +1042,9 @@ config SOC_AU1X00 select SYS_SUPPORTS_APM_EMULATION select SYS_SUPPORTS_KGDB +config SERIAL_RM9000 + bool + config PNX8550 bool select SOC_PNX8550 diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 194362d9f5a3..c9832d963f1e 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -251,9 +251,16 @@ static const struct serial8250_config uart_config[] = { .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .flags = UART_CAP_FIFO | UART_CAP_UUE, }, + [PORT_RM9000] = { + .name = "RM9000", + .fifo_size = 16, + .tx_loadsz = 16, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .flags = UART_CAP_FIFO, + }, }; -#ifdef CONFIG_SERIAL_8250_AU1X00 +#if defined (CONFIG_SERIAL_8250_AU1X00) /* Au1x00 UART hardware has a weird register layout */ static const u8 au_io_in_map[] = { @@ -289,6 +296,44 @@ static inline int map_8250_out_reg(struct uart_8250_port *up, int offset) return au_io_out_map[offset]; } +#elif defined (CONFIG_SERIAL_8250_RM9K) + +static const u8 + regmap_in[8] = { + [UART_RX] = 0x00, + [UART_IER] = 0x0c, + [UART_IIR] = 0x14, + [UART_LCR] = 0x1c, + [UART_MCR] = 0x20, + [UART_LSR] = 0x24, + [UART_MSR] = 0x28, + [UART_SCR] = 0x2c + }, + regmap_out[8] = { + [UART_TX] = 0x04, + [UART_IER] = 0x0c, + [UART_FCR] = 0x18, + [UART_LCR] = 0x1c, + [UART_MCR] = 0x20, + [UART_LSR] = 0x24, + [UART_MSR] = 0x28, + [UART_SCR] = 0x2c + }; + +static inline int map_8250_in_reg(struct uart_8250_port *up, int offset) +{ + if (up->port.iotype != UPIO_RM9000) + return offset; + return regmap_in[offset]; +} + +static inline int map_8250_out_reg(struct uart_8250_port *up, int offset) +{ + if (up->port.iotype != UPIO_RM9000) + return offset; + return regmap_out[offset]; +} + #else /* sane hardware needs no mapping */ @@ -311,6 +356,7 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset) case UPIO_DWAPB: return readb(up->port.membase + offset); + case UPIO_RM9000: case UPIO_MEM32: return readl(up->port.membase + offset); @@ -348,6 +394,7 @@ serial_out(struct uart_8250_port *up, int offset, int value) writeb(value, up->port.membase + offset); break; + case UPIO_RM9000: case UPIO_MEM32: writel(value, up->port.membase + offset); break; @@ -419,7 +466,7 @@ static inline void _serial_dl_write(struct uart_8250_port *up, int value) serial_outp(up, UART_DLM, value >> 8 & 0xff); } -#ifdef CONFIG_SERIAL_8250_AU1X00 +#if defined (CONFIG_SERIAL_8250_AU1X00) /* Au1x00 haven't got a standard divisor latch */ static int serial_dl_read(struct uart_8250_port *up) { @@ -436,6 +483,24 @@ static void serial_dl_write(struct uart_8250_port *up, int value) else _serial_dl_write(up, value); } +#elif defined (CONFIG_SERIAL_8250_RM9K) +static int serial_dl_read(struct uart_8250_port *up) +{ + return (up->port.iotype == UPIO_RM9000) ? + (((__raw_readl(up->port.membase + 0x10) << 8) | + (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) : + _serial_dl_read(up); +} + +static void serial_dl_write(struct uart_8250_port *up, int value) +{ + if (up->port.iotype == UPIO_RM9000) { + __raw_writel(value, up->port.membase + 0x08); + __raw_writel(value >> 8, up->port.membase + 0x10); + } else { + _serial_dl_write(up, value); + } +} #else #define serial_dl_read(up) _serial_dl_read(up) #define serial_dl_write(up, value) _serial_dl_write(up, value) @@ -637,7 +702,7 @@ static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p) * its clones. (We treat the broken original StarTech 16650 V1 as a * 16550, and why not? Startech doesn't seem to even acknowledge its * existence.) - * + * * What evil have men's minds wrought... */ static void autoconfig_has_efr(struct uart_8250_port *up) @@ -690,7 +755,7 @@ static void autoconfig_has_efr(struct uart_8250_port *up) up->bugs |= UART_BUG_QUOT; return; } - + /* * We check for a XR16C850 by setting DLL and DLM to 0, and then * reading back DLL and DLM. The chip type depends on the DLM @@ -833,7 +898,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ serial_outp(up, 0x04, status1); - + serial_dl_write(up, quot); serial_outp(up, UART_LCR, 0); @@ -938,7 +1003,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) /* * Do a simple existence test first; if we fail this, * there's no point trying anything else. - * + * * 0x80 is used as a nonsense port to prevent against * false positives due to ISA bus float. The * assumption is that 0x80 is a non-existent port; @@ -977,7 +1042,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) save_mcr = serial_in(up, UART_MCR); save_lcr = serial_in(up, UART_LCR); - /* + /* * Check to see if a UART is really there. Certain broken * internal modems based on the Rockwell chipset fail this * test, because they apparently don't implement the loopback @@ -1084,7 +1149,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) else serial_outp(up, UART_IER, 0); - out: + out: spin_unlock_irqrestore(&up->port.lock, flags); // restore_flags(flags); DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name); @@ -1110,7 +1175,7 @@ static void autoconfig_irq(struct uart_8250_port *up) save_mcr = serial_inp(up, UART_MCR); save_ier = serial_inp(up, UART_IER); serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); - + irqs = probe_irq_on(); serial_outp(up, UART_MCR, 0); udelay (10); @@ -1175,8 +1240,11 @@ static void serial8250_start_tx(struct uart_port *port) if (up->bugs & UART_BUG_TXEN) { unsigned char lsr, iir; lsr = serial_in(up, UART_LSR); - iir = serial_in(up, UART_IIR); - if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) + iir = serial_in(up, UART_IIR) & 0x0f; + if ((up->port.type == PORT_RM9000) ? + (lsr & UART_LSR_THRE && + (iir == UART_IIR_NO_INT || iir == UART_IIR_THRI)) : + (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT)) transmit_chars(up); } } @@ -1957,7 +2025,7 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios, /* * Ask the core to calculate the divisor for us. */ - baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); + baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); quot = serial8250_get_divisor(port, baud); /* diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index ad9f321968e1..e9d927e3b8e6 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -254,6 +254,15 @@ config SERIAL_8250_AU1X00 to this option. The driver can handle 1 or 2 serial ports. If unsure, say N. +config SERIAL_8250_RM9K + bool "Support for MIPS RM9xxx integrated serial port" + depends on SERIAL_8250 != n && SERIAL_RM9000 + select SERIAL_8250_SHARE_IRQ + help + Selecting this option will add support for the integrated serial + port hardware found on MIPS RM9122 and similar processors. + If unsure, say N. + comment "Non-8250 serial port support" config SERIAL_AMBA_PL010 diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 8b5592e6aca4..d242c731491f 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -39,7 +39,8 @@ #define PORT_RSA 13 #define PORT_NS16550A 14 #define PORT_XSCALE 15 -#define PORT_MAX_8250 15 /* max port ID */ +#define PORT_RM9000 16 /* PMC-Sierra RM9xxx internal UART */ +#define PORT_MAX_8250 16 /* max port ID */ /* * ARM specific type numbers. These are not currently guaranteed @@ -231,6 +232,7 @@ struct uart_port { #define UPIO_AU (4) /* Au1x00 type IO */ #define UPIO_TSI (5) /* Tsi108/109 type IO */ #define UPIO_DWAPB (6) /* DesignWare APB UART */ +#define UPIO_RM9000 (7) /* RM9000 type IO */ unsigned int read_status_mask; /* driver specific */ unsigned int ignore_status_mask; /* driver specific */ -- cgit v1.2.3-59-g8ed1b From abb4a2390737867353ebafc012d45f2b03f3f944 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Sun, 6 May 2007 14:48:49 -0700 Subject: serial: define FIXED_PORT flag for serial_core At present, the serial core always allows setserial in userspace to change the port address, irq and base clock of any serial port. That makes sense for legacy ISA ports, but not for (say) embedded ns16550 compatible serial ports at peculiar addresses. In these cases, the kernel code configuring the ports must know exactly where they are, and their clocking arrangements (which can be unusual on embedded boards). It doesn't make sense for userspace to change these settings. Therefore, this patch defines a UPF_FIXED_PORT flag for the uart_port structure. If this flag is set when the serial port is configured, any attempts to alter the port's type, io address, irq or base clock with setserial are ignored. In addition this patch uses the new flag for on-chip serial ports probed in arch/powerpc/kernel/legacy_serial.c, and for other hard-wired serial ports probed by drivers/serial/of_serial.c. Signed-off-by: David Gibson Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/kernel/legacy_serial.c | 3 ++- drivers/serial/of_serial.c | 3 ++- drivers/serial/serial_core.c | 22 +++++++++++++--------- include/linux/serial_core.h | 1 + 4 files changed, 18 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 63dd2c3ad95e..ae4836ea7442 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c @@ -115,7 +115,8 @@ static int __init add_legacy_soc_port(struct device_node *np, { u64 addr; const u32 *addrp; - upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; + upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ + | UPF_FIXED_PORT; struct device_node *tsi = of_get_parent(np); /* We only support ports that have a clock frequency properly diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index 09b0b736a751..336d0f4580d9 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c @@ -48,7 +48,8 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev, port->iotype = UPIO_MEM; port->type = type; port->uartclk = *clk; - port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP; + port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP + | UPF_FIXED_PORT; port->dev = &ofdev->dev; port->custom_divisor = *clk / (16 * (*spd)); diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index a677133ab2d4..f409be37b62f 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -672,19 +672,21 @@ static int uart_set_info(struct uart_state *state, */ mutex_lock(&state->mutex); - change_irq = new_serial.irq != port->irq; + change_irq = !(port->flags & UPF_FIXED_PORT) + && new_serial.irq != port->irq; /* * Since changing the 'type' of the port changes its resource * allocations, we should treat type changes the same as * IO port changes. */ - change_port = new_port != port->iobase || - (unsigned long)new_serial.iomem_base != port->mapbase || - new_serial.hub6 != port->hub6 || - new_serial.io_type != port->iotype || - new_serial.iomem_reg_shift != port->regshift || - new_serial.type != port->type; + change_port = !(port->flags & UPF_FIXED_PORT) + && (new_port != port->iobase || + (unsigned long)new_serial.iomem_base != port->mapbase || + new_serial.hub6 != port->hub6 || + new_serial.io_type != port->iotype || + new_serial.iomem_reg_shift != port->regshift || + new_serial.type != port->type); old_flags = port->flags; new_flags = new_serial.flags; @@ -796,8 +798,10 @@ static int uart_set_info(struct uart_state *state, } } - port->irq = new_serial.irq; - port->uartclk = new_serial.baud_base * 16; + if (change_irq) + port->irq = new_serial.irq; + if (!(port->flags & UPF_FIXED_PORT)) + port->uartclk = new_serial.baud_base * 16; port->flags = (port->flags & ~UPF_CHANGE_MASK) | (new_flags & UPF_CHANGE_MASK); port->custom_divisor = new_serial.custom_divisor; diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index d242c731491f..aadbfd30763f 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -263,6 +263,7 @@ struct uart_port { #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) +#define UPF_FIXED_PORT ((__force upf_t) (1 << 29)) #define UPF_DEAD ((__force upf_t) (1 << 30)) #define UPF_IOREMAP ((__force upf_t) (1 << 31)) -- cgit v1.2.3-59-g8ed1b From 411f0f3edc141a582190d3605cadd1d993abb6df Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sun, 6 May 2007 14:49:09 -0700 Subject: Introduce CONFIG_HAS_DMA Architectures that don't support DMA can say so by adding a config NO_DMA to their Kconfig file. This will prevent compilation of some dma specific driver code. Also dma-mapping-broken.h isn't needed anymore on at least s390. This avoids compilation and linking of otherwise dead/broken code. Other architectures that include dma-mapping-broken.h are arm26, h8300, m68k, m68knommu and v850. If these could be converted as well we could get rid of the header file. Signed-off-by: Heiko Carstens "John W. Linville" Cc: Kyle McMartin Cc: Cc: Tejun Heo Cc: Jeff Garzik Cc: Martin Schwidefsky Cc: Cc: Cc: Cc: Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/s390/Kconfig | 3 +++ drivers/base/Makefile | 4 ++-- include/asm-s390/dma-mapping.h | 2 -- lib/Kconfig | 5 +++++ 4 files changed, 10 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index e6ec418093e5..1a84719be264 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -49,6 +49,9 @@ config GENERIC_BUG config NO_IOMEM def_bool y +config NO_DMA + def_bool y + mainmenu "Linux Kernel Configuration" config S390 diff --git a/drivers/base/Makefile b/drivers/base/Makefile index e9eb7382ac3a..b39ea3f59c9b 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -2,10 +2,10 @@ obj-y := core.o sys.o bus.o dd.o \ driver.o class.o platform.o \ - cpu.o firmware.o init.o map.o dmapool.o \ - dma-mapping.o devres.o \ + cpu.o firmware.o init.o map.o devres.o \ attribute_container.o transport_class.o obj-y += power/ +obj-$(CONFIG_HAS_DMA) += dma-mapping.o dmapool.o obj-$(CONFIG_ISA) += isa.o obj-$(CONFIG_FW_LOADER) += firmware_class.o obj-$(CONFIG_NUMA) += node.o diff --git a/include/asm-s390/dma-mapping.h b/include/asm-s390/dma-mapping.h index 09bb7b04f967..3f8c12fde0f0 100644 --- a/include/asm-s390/dma-mapping.h +++ b/include/asm-s390/dma-mapping.h @@ -9,6 +9,4 @@ #ifndef _ASM_DMA_MAPPING_H #define _ASM_DMA_MAPPING_H -#include - #endif /* _ASM_DMA_MAPPING_H */ diff --git a/lib/Kconfig b/lib/Kconfig index 384249915047..96d6e8ca8b70 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -111,4 +111,9 @@ config HAS_IOPORT depends on HAS_IOMEM && !NO_IOPORT default y +config HAS_DMA + boolean + depends on !NO_DMA + default y + endmenu -- cgit v1.2.3-59-g8ed1b From 81819f0fc8285a2a5a921c019e3e3d7b6169d225 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Sun, 6 May 2007 14:49:36 -0700 Subject: SLUB core This is a new slab allocator which was motivated by the complexity of the existing code in mm/slab.c. It attempts to address a variety of concerns with the existing implementation. A. Management of object queues A particular concern was the complex management of the numerous object queues in SLAB. SLUB has no such queues. Instead we dedicate a slab for each allocating CPU and use objects from a slab directly instead of queueing them up. B. Storage overhead of object queues SLAB Object queues exist per node, per CPU. The alien cache queue even has a queue array that contain a queue for each processor on each node. For very large systems the number of queues and the number of objects that may be caught in those queues grows exponentially. On our systems with 1k nodes / processors we have several gigabytes just tied up for storing references to objects for those queues This does not include the objects that could be on those queues. One fears that the whole memory of the machine could one day be consumed by those queues. C. SLAB meta data overhead SLAB has overhead at the beginning of each slab. This means that data cannot be naturally aligned at the beginning of a slab block. SLUB keeps all meta data in the corresponding page_struct. Objects can be naturally aligned in the slab. F.e. a 128 byte object will be aligned at 128 byte boundaries and can fit tightly into a 4k page with no bytes left over. SLAB cannot do this. D. SLAB has a complex cache reaper SLUB does not need a cache reaper for UP systems. On SMP systems the per CPU slab may be pushed back into partial list but that operation is simple and does not require an iteration over a list of objects. SLAB expires per CPU, shared and alien object queues during cache reaping which may cause strange hold offs. E. SLAB has complex NUMA policy layer support SLUB pushes NUMA policy handling into the page allocator. This means that allocation is coarser (SLUB does interleave on a page level) but that situation was also present before 2.6.13. SLABs application of policies to individual slab objects allocated in SLAB is certainly a performance concern due to the frequent references to memory policies which may lead a sequence of objects to come from one node after another. SLUB will get a slab full of objects from one node and then will switch to the next. F. Reduction of the size of partial slab lists SLAB has per node partial lists. This means that over time a large number of partial slabs may accumulate on those lists. These can only be reused if allocator occur on specific nodes. SLUB has a global pool of partial slabs and will consume slabs from that pool to decrease fragmentation. G. Tunables SLAB has sophisticated tuning abilities for each slab cache. One can manipulate the queue sizes in detail. However, filling the queues still requires the uses of the spin lock to check out slabs. SLUB has a global parameter (min_slab_order) for tuning. Increasing the minimum slab order can decrease the locking overhead. The bigger the slab order the less motions of pages between per CPU and partial lists occur and the better SLUB will be scaling. G. Slab merging We often have slab caches with similar parameters. SLUB detects those on boot up and merges them into the corresponding general caches. This leads to more effective memory use. About 50% of all caches can be eliminated through slab merging. This will also decrease slab fragmentation because partial allocated slabs can be filled up again. Slab merging can be switched off by specifying slub_nomerge on boot up. Note that merging can expose heretofore unknown bugs in the kernel because corrupted objects may now be placed differently and corrupt differing neighboring objects. Enable sanity checks to find those. H. Diagnostics The current slab diagnostics are difficult to use and require a recompilation of the kernel. SLUB contains debugging code that is always available (but is kept out of the hot code paths). SLUB diagnostics can be enabled via the "slab_debug" option. Parameters can be specified to select a single or a group of slab caches for diagnostics. This means that the system is running with the usual performance and it is much more likely that race conditions can be reproduced. I. Resiliency If basic sanity checks are on then SLUB is capable of detecting common error conditions and recover as best as possible to allow the system to continue. J. Tracing Tracing can be enabled via the slab_debug=T, option during boot. SLUB will then protocol all actions on that slabcache and dump the object contents on free. K. On demand DMA cache creation. Generally DMA caches are not needed. If a kmalloc is used with __GFP_DMA then just create this single slabcache that is needed. For systems that have no ZONE_DMA requirement the support is completely eliminated. L. Performance increase Some benchmarks have shown speed improvements on kernbench in the range of 5-10%. The locking overhead of slub is based on the underlying base allocation size. If we can reliably allocate larger order pages then it is possible to increase slub performance much further. The anti-fragmentation patches may enable further performance increases. Tested on: i386 UP + SMP, x86_64 UP + SMP + NUMA emulation, IA64 NUMA + Simulator SLUB Boot options slub_nomerge Disable merging of slabs slub_min_order=x Require a minimum order for slab caches. This increases the managed chunk size and therefore reduces meta data and locking overhead. slub_min_objects=x Mininum objects per slab. Default is 8. slub_max_order=x Avoid generating slabs larger than order specified. slub_debug Enable all diagnostics for all caches slub_debug= Enable selective options for all caches slub_debug=, Enable selective options for a certain set of caches Available Debug options F Double Free checking, sanity and resiliency R Red zoning P Object / padding poisoning U Track last free / alloc T Trace all allocs / frees (only use for individual slabs). To use SLUB: Apply this patch and then select SLUB as the default slab allocator. [hugh@veritas.com: fix an oops-causing locking error] [akpm@linux-foundation.org: various stupid cleanups and small fixes] Signed-off-by: Christoph Lameter Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/frv/Kconfig | 4 + arch/i386/Kconfig | 4 + include/linux/mm_types.h | 17 +- include/linux/poison.h | 3 + include/linux/slab.h | 14 +- include/linux/slub_def.h | 201 +++ init/Kconfig | 53 +- mm/Makefile | 1 + mm/slub.c | 3144 ++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 3422 insertions(+), 19 deletions(-) create mode 100644 include/linux/slub_def.h create mode 100644 mm/slub.c (limited to 'arch') diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index cea237413aa2..eed694312a79 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -53,6 +53,10 @@ config ARCH_HAS_ILOG2_U64 bool default y +config ARCH_USES_SLAB_PAGE_STRUCT + bool + default y + mainmenu "Fujitsu FR-V Kernel Configuration" source "init/Kconfig" diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index a9af760c7e5f..64ad10f984a1 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -79,6 +79,10 @@ config ARCH_MAY_HAVE_PC_FDC bool default y +config ARCH_USES_SLAB_PAGE_STRUCT + bool + default y + config DMI bool default y diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index c3852fd4a1cc..e30687bad075 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -19,10 +19,16 @@ struct page { unsigned long flags; /* Atomic flags, some possibly * updated asynchronously */ atomic_t _count; /* Usage count, see below. */ - atomic_t _mapcount; /* Count of ptes mapped in mms, + union { + atomic_t _mapcount; /* Count of ptes mapped in mms, * to show when page is mapped * & limit reverse map searches. */ + struct { /* SLUB uses */ + short unsigned int inuse; + short unsigned int offset; + }; + }; union { struct { unsigned long private; /* Mapping-private opaque data: @@ -43,8 +49,15 @@ struct page { #if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS spinlock_t ptl; #endif + struct { /* SLUB uses */ + struct page *first_page; /* Compound pages */ + struct kmem_cache *slab; /* Pointer to slab */ + }; + }; + union { + pgoff_t index; /* Our offset within mapping. */ + void *freelist; /* SLUB: pointer to free object */ }; - pgoff_t index; /* Our offset within mapping. */ struct list_head lru; /* Pageout list, eg. active_list * protected by zone->lru_lock ! */ diff --git a/include/linux/poison.h b/include/linux/poison.h index 89580b764959..95f518b17684 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h @@ -18,6 +18,9 @@ #define RED_INACTIVE 0x5A2CF071UL /* when obj is inactive */ #define RED_ACTIVE 0x170FC2A5UL /* when obj is active */ +#define SLUB_RED_INACTIVE 0xbb +#define SLUB_RED_ACTIVE 0xcc + /* ...and for poisoning */ #define POISON_INUSE 0x5a /* for use-uninitialised poisoning */ #define POISON_FREE 0x6b /* for use-after-free poisoning */ diff --git a/include/linux/slab.h b/include/linux/slab.h index f9ed9346bfd6..67425c277e12 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -32,6 +32,7 @@ typedef struct kmem_cache kmem_cache_t __deprecated; #define SLAB_PANIC 0x00040000UL /* Panic if kmem_cache_create() fails */ #define SLAB_DESTROY_BY_RCU 0x00080000UL /* Defer freeing slabs to RCU */ #define SLAB_MEM_SPREAD 0x00100000UL /* Spread some memory over cpuset */ +#define SLAB_TRACE 0x00200000UL /* Trace allocations and frees */ /* Flags passed to a constructor functions */ #define SLAB_CTOR_CONSTRUCTOR 0x001UL /* If not set, then deconstructor */ @@ -42,7 +43,7 @@ typedef struct kmem_cache kmem_cache_t __deprecated; * struct kmem_cache related prototypes */ void __init kmem_cache_init(void); -extern int slab_is_available(void); +int slab_is_available(void); struct kmem_cache *kmem_cache_create(const char *, size_t, size_t, unsigned long, @@ -95,9 +96,14 @@ static inline void *kcalloc(size_t n, size_t size, gfp_t flags) * the appropriate general cache at compile time. */ -#ifdef CONFIG_SLAB +#if defined(CONFIG_SLAB) || defined(CONFIG_SLUB) +#ifdef CONFIG_SLUB +#include +#else #include +#endif /* !CONFIG_SLUB */ #else + /* * Fallback definitions for an allocator not wanting to provide * its own optimized kmalloc definitions (like SLOB). @@ -184,7 +190,7 @@ static inline void *__kmalloc_node(size_t size, gfp_t flags, int node) * allocator where we care about the real place the memory allocation * request comes from. */ -#ifdef CONFIG_DEBUG_SLAB +#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB) extern void *__kmalloc_track_caller(size_t, gfp_t, void*); #define kmalloc_track_caller(size, flags) \ __kmalloc_track_caller(size, flags, __builtin_return_address(0)) @@ -202,7 +208,7 @@ extern void *__kmalloc_track_caller(size_t, gfp_t, void*); * standard allocator where we care about the real place the memory * allocation request comes from. */ -#ifdef CONFIG_DEBUG_SLAB +#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB) extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, void *); #define kmalloc_node_track_caller(size, flags, node) \ __kmalloc_node_track_caller(size, flags, node, \ diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h new file mode 100644 index 000000000000..30b154ce7289 --- /dev/null +++ b/include/linux/slub_def.h @@ -0,0 +1,201 @@ +#ifndef _LINUX_SLUB_DEF_H +#define _LINUX_SLUB_DEF_H + +/* + * SLUB : A Slab allocator without object queues. + * + * (C) 2007 SGI, Christoph Lameter + */ +#include +#include +#include +#include + +struct kmem_cache_node { + spinlock_t list_lock; /* Protect partial list and nr_partial */ + unsigned long nr_partial; + atomic_long_t nr_slabs; + struct list_head partial; +}; + +/* + * Slab cache management. + */ +struct kmem_cache { + /* Used for retriving partial slabs etc */ + unsigned long flags; + int size; /* The size of an object including meta data */ + int objsize; /* The size of an object without meta data */ + int offset; /* Free pointer offset. */ + unsigned int order; + + /* + * Avoid an extra cache line for UP, SMP and for the node local to + * struct kmem_cache. + */ + struct kmem_cache_node local_node; + + /* Allocation and freeing of slabs */ + int objects; /* Number of objects in slab */ + int refcount; /* Refcount for slab cache destroy */ + void (*ctor)(void *, struct kmem_cache *, unsigned long); + void (*dtor)(void *, struct kmem_cache *, unsigned long); + int inuse; /* Offset to metadata */ + int align; /* Alignment */ + const char *name; /* Name (only for display!) */ + struct list_head list; /* List of slab caches */ + struct kobject kobj; /* For sysfs */ + +#ifdef CONFIG_NUMA + int defrag_ratio; + struct kmem_cache_node *node[MAX_NUMNODES]; +#endif + struct page *cpu_slab[NR_CPUS]; +}; + +/* + * Kmalloc subsystem. + */ +#define KMALLOC_SHIFT_LOW 3 + +#ifdef CONFIG_LARGE_ALLOCS +#define KMALLOC_SHIFT_HIGH 25 +#else +#if !defined(CONFIG_MMU) || NR_CPUS > 512 || MAX_NUMNODES > 256 +#define KMALLOC_SHIFT_HIGH 20 +#else +#define KMALLOC_SHIFT_HIGH 18 +#endif +#endif + +/* + * We keep the general caches in an array of slab caches that are used for + * 2^x bytes of allocations. + */ +extern struct kmem_cache kmalloc_caches[KMALLOC_SHIFT_HIGH + 1]; + +/* + * Sorry that the following has to be that ugly but some versions of GCC + * have trouble with constant propagation and loops. + */ +static inline int kmalloc_index(int size) +{ + if (size == 0) + return 0; + if (size > 64 && size <= 96) + return 1; + if (size > 128 && size <= 192) + return 2; + if (size <= 8) return 3; + if (size <= 16) return 4; + if (size <= 32) return 5; + if (size <= 64) return 6; + if (size <= 128) return 7; + if (size <= 256) return 8; + if (size <= 512) return 9; + if (size <= 1024) return 10; + if (size <= 2 * 1024) return 11; + if (size <= 4 * 1024) return 12; + if (size <= 8 * 1024) return 13; + if (size <= 16 * 1024) return 14; + if (size <= 32 * 1024) return 15; + if (size <= 64 * 1024) return 16; + if (size <= 128 * 1024) return 17; + if (size <= 256 * 1024) return 18; +#if KMALLOC_SHIFT_HIGH > 18 + if (size <= 512 * 1024) return 19; + if (size <= 1024 * 1024) return 20; +#endif +#if KMALLOC_SHIFT_HIGH > 20 + if (size <= 2 * 1024 * 1024) return 21; + if (size <= 4 * 1024 * 1024) return 22; + if (size <= 8 * 1024 * 1024) return 23; + if (size <= 16 * 1024 * 1024) return 24; + if (size <= 32 * 1024 * 1024) return 25; +#endif + return -1; + +/* + * What we really wanted to do and cannot do because of compiler issues is: + * int i; + * for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++) + * if (size <= (1 << i)) + * return i; + */ +} + +/* + * Find the slab cache for a given combination of allocation flags and size. + * + * This ought to end up with a global pointer to the right cache + * in kmalloc_caches. + */ +static inline struct kmem_cache *kmalloc_slab(size_t size) +{ + int index = kmalloc_index(size); + + if (index == 0) + return NULL; + + if (index < 0) { + /* + * Generate a link failure. Would be great if we could + * do something to stop the compile here. + */ + extern void __kmalloc_size_too_large(void); + __kmalloc_size_too_large(); + } + return &kmalloc_caches[index]; +} + +#ifdef CONFIG_ZONE_DMA +#define SLUB_DMA __GFP_DMA +#else +/* Disable DMA functionality */ +#define SLUB_DMA 0 +#endif + +static inline void *kmalloc(size_t size, gfp_t flags) +{ + if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) { + struct kmem_cache *s = kmalloc_slab(size); + + if (!s) + return NULL; + + return kmem_cache_alloc(s, flags); + } else + return __kmalloc(size, flags); +} + +static inline void *kzalloc(size_t size, gfp_t flags) +{ + if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) { + struct kmem_cache *s = kmalloc_slab(size); + + if (!s) + return NULL; + + return kmem_cache_zalloc(s, flags); + } else + return __kzalloc(size, flags); +} + +#ifdef CONFIG_NUMA +extern void *__kmalloc_node(size_t size, gfp_t flags, int node); + +static inline void *kmalloc_node(size_t size, gfp_t flags, int node) +{ + if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) { + struct kmem_cache *s = kmalloc_slab(size); + + if (!s) + return NULL; + + return kmem_cache_alloc_node(s, flags, node); + } else + return __kmalloc_node(size, flags, node); +} +#endif + +#endif /* _LINUX_SLUB_DEF_H */ diff --git a/init/Kconfig b/init/Kconfig index 29d9e47ee0da..7ce952052947 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -478,15 +478,6 @@ config SHMEM option replaces shmem and tmpfs with the much simpler ramfs code, which may be appropriate on small systems without swap. -config SLAB - default y - bool "Use full SLAB allocator" if (EMBEDDED && !SMP && !SPARSEMEM) - help - Disabling this replaces the advanced SLAB allocator and - kmalloc support with the drastically simpler SLOB allocator. - SLOB is more space efficient but does not scale well and is - more susceptible to fragmentation. - config VM_EVENT_COUNTERS default y bool "Enable VM event counters for /proc/vmstat" if EMBEDDED @@ -496,6 +487,46 @@ config VM_EVENT_COUNTERS on EMBEDDED systems. /proc/vmstat will only show page counts if VM event counters are disabled. +choice + prompt "Choose SLAB allocator" + default SLAB + help + This option allows to select a slab allocator. + +config SLAB + bool "SLAB" + help + The regular slab allocator that is established and known to work + well in all environments. It organizes chache hot objects in + per cpu and per node queues. SLAB is the default choice for + slab allocator. + +config SLUB + depends on EXPERIMENTAL && !ARCH_USES_SLAB_PAGE_STRUCT + bool "SLUB (Unqueued Allocator)" + help + SLUB is a slab allocator that minimizes cache line usage + instead of managing queues of cached objects (SLAB approach). + Per cpu caching is realized using slabs of objects instead + of queues of objects. SLUB can use memory efficiently + way and has enhanced diagnostics. + +config SLOB +# +# SLOB cannot support SMP because SLAB_DESTROY_BY_RCU does not work +# properly. +# + depends on EMBEDDED && !SMP && !SPARSEMEM + bool "SLOB (Simple Allocator)" + help + SLOB replaces the SLAB allocator with a drastically simpler + allocator. SLOB is more space efficient that SLAB but does not + scale well (single lock for all operations) and is more susceptible + to fragmentation. SLOB it is a great choice to reduce + memory usage and code size for embedded systems. + +endchoice + endmenu # General setup config RT_MUTEXES @@ -511,10 +542,6 @@ config BASE_SMALL default 0 if BASE_FULL default 1 if !BASE_FULL -config SLOB - default !SLAB - bool - menu "Loadable module support" config MODULES diff --git a/mm/Makefile b/mm/Makefile index f3c077eb0b8e..1887148e44e7 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_TMPFS_POSIX_ACL) += shmem_acl.o obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o obj-$(CONFIG_SLOB) += slob.o obj-$(CONFIG_SLAB) += slab.o +obj-$(CONFIG_SLUB) += slub.o obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o obj-$(CONFIG_FS_XIP) += filemap_xip.o obj-$(CONFIG_MIGRATION) += migrate.o diff --git a/mm/slub.c b/mm/slub.c new file mode 100644 index 000000000000..0cd56bd74b64 --- /dev/null +++ b/mm/slub.c @@ -0,0 +1,3144 @@ +/* + * SLUB: A slab allocator that limits cache line use instead of queuing + * objects in per cpu and per node lists. + * + * The allocator synchronizes using per slab locks and only + * uses a centralized lock to manage a pool of partial slabs. + * + * (C) 2007 SGI, Christoph Lameter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Lock order: + * 1. slab_lock(page) + * 2. slab->list_lock + * + * The slab_lock protects operations on the object of a particular + * slab and its metadata in the page struct. If the slab lock + * has been taken then no allocations nor frees can be performed + * on the objects in the slab nor can the slab be added or removed + * from the partial or full lists since this would mean modifying + * the page_struct of the slab. + * + * The list_lock protects the partial and full list on each node and + * the partial slab counter. If taken then no new slabs may be added or + * removed from the lists nor make the number of partial slabs be modified. + * (Note that the total number of slabs is an atomic value that may be + * modified without taking the list lock). + * + * The list_lock is a centralized lock and thus we avoid taking it as + * much as possible. As long as SLUB does not have to handle partial + * slabs, operations can continue without any centralized lock. F.e. + * allocating a long series of objects that fill up slabs does not require + * the list lock. + * + * The lock order is sometimes inverted when we are trying to get a slab + * off a list. We take the list_lock and then look for a page on the list + * to use. While we do that objects in the slabs may be freed. We can + * only operate on the slab if we have also taken the slab_lock. So we use + * a slab_trylock() on the slab. If trylock was successful then no frees + * can occur anymore and we can use the slab for allocations etc. If the + * slab_trylock() does not succeed then frees are in progress in the slab and + * we must stay away from it for a while since we may cause a bouncing + * cacheline if we try to acquire the lock. So go onto the next slab. + * If all pages are busy then we may allocate a new slab instead of reusing + * a partial slab. A new slab has noone operating on it and thus there is + * no danger of cacheline contention. + * + * Interrupts are disabled during allocation and deallocation in order to + * make the slab allocator safe to use in the context of an irq. In addition + * interrupts are disabled to ensure that the processor does not change + * while handling per_cpu slabs, due to kernel preemption. + * + * SLUB assigns one slab for allocation to each processor. + * Allocations only occur from these slabs called cpu slabs. + * + * Slabs with free elements are kept on a partial list. + * There is no list for full slabs. If an object in a full slab is + * freed then the slab will show up again on the partial lists. + * Otherwise there is no need to track full slabs unless we have to + * track full slabs for debugging purposes. + * + * Slabs are freed when they become empty. Teardown and setup is + * minimal so we rely on the page allocators per cpu caches for + * fast frees and allocs. + * + * Overloading of page flags that are otherwise used for LRU management. + * + * PageActive The slab is used as a cpu cache. Allocations + * may be performed from the slab. The slab is not + * on any slab list and cannot be moved onto one. + * + * PageError Slab requires special handling due to debug + * options set. This moves slab handling out of + * the fast path. + */ + +/* + * Issues still to be resolved: + * + * - The per cpu array is updated for each new slab and and is a remote + * cacheline for most nodes. This could become a bouncing cacheline given + * enough frequent updates. There are 16 pointers in a cacheline.so at + * max 16 cpus could compete. Likely okay. + * + * - Support PAGE_ALLOC_DEBUG. Should be easy to do. + * + * - Support DEBUG_SLAB_LEAK. Trouble is we do not know where the full + * slabs are in SLUB. + * + * - SLAB_DEBUG_INITIAL is not supported but I have never seen a use of + * it. + * + * - Variable sizing of the per node arrays + */ + +/* Enable to test recovery from slab corruption on boot */ +#undef SLUB_RESILIENCY_TEST + +#if PAGE_SHIFT <= 12 + +/* + * Small page size. Make sure that we do not fragment memory + */ +#define DEFAULT_MAX_ORDER 1 +#define DEFAULT_MIN_OBJECTS 4 + +#else + +/* + * Large page machines are customarily able to handle larger + * page orders. + */ +#define DEFAULT_MAX_ORDER 2 +#define DEFAULT_MIN_OBJECTS 8 + +#endif + +/* + * Flags from the regular SLAB that SLUB does not support: + */ +#define SLUB_UNIMPLEMENTED (SLAB_DEBUG_INITIAL) + +#define DEBUG_DEFAULT_FLAGS (SLAB_DEBUG_FREE | SLAB_RED_ZONE | \ + SLAB_POISON | SLAB_STORE_USER) +/* + * Set of flags that will prevent slab merging + */ +#define SLUB_NEVER_MERGE (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \ + SLAB_TRACE | SLAB_DESTROY_BY_RCU) + +#define SLUB_MERGE_SAME (SLAB_DEBUG_FREE | SLAB_RECLAIM_ACCOUNT | \ + SLAB_CACHE_DMA) + +#ifndef ARCH_KMALLOC_MINALIGN +#define ARCH_KMALLOC_MINALIGN sizeof(void *) +#endif + +#ifndef ARCH_SLAB_MINALIGN +#define ARCH_SLAB_MINALIGN sizeof(void *) +#endif + +/* Internal SLUB flags */ +#define __OBJECT_POISON 0x80000000 /* Poison object */ + +static int kmem_size = sizeof(struct kmem_cache); + +#ifdef CONFIG_SMP +static struct notifier_block slab_notifier; +#endif + +static enum { + DOWN, /* No slab functionality available */ + PARTIAL, /* kmem_cache_open() works but kmalloc does not */ + UP, /* Everything works */ + SYSFS /* Sysfs up */ +} slab_state = DOWN; + +/* A list of all slab caches on the system */ +static DECLARE_RWSEM(slub_lock); +LIST_HEAD(slab_caches); + +#ifdef CONFIG_SYSFS +static int sysfs_slab_add(struct kmem_cache *); +static int sysfs_slab_alias(struct kmem_cache *, const char *); +static void sysfs_slab_remove(struct kmem_cache *); +#else +static int sysfs_slab_add(struct kmem_cache *s) { return 0; } +static int sysfs_slab_alias(struct kmem_cache *s, const char *p) { return 0; } +static void sysfs_slab_remove(struct kmem_cache *s) {} +#endif + +/******************************************************************** + * Core slab cache functions + *******************************************************************/ + +int slab_is_available(void) +{ + return slab_state >= UP; +} + +static inline struct kmem_cache_node *get_node(struct kmem_cache *s, int node) +{ +#ifdef CONFIG_NUMA + return s->node[node]; +#else + return &s->local_node; +#endif +} + +/* + * Object debugging + */ +static void print_section(char *text, u8 *addr, unsigned int length) +{ + int i, offset; + int newline = 1; + char ascii[17]; + + ascii[16] = 0; + + for (i = 0; i < length; i++) { + if (newline) { + printk(KERN_ERR "%10s 0x%p: ", text, addr + i); + newline = 0; + } + printk(" %02x", addr[i]); + offset = i % 16; + ascii[offset] = isgraph(addr[i]) ? addr[i] : '.'; + if (offset == 15) { + printk(" %s\n",ascii); + newline = 1; + } + } + if (!newline) { + i %= 16; + while (i < 16) { + printk(" "); + ascii[i] = ' '; + i++; + } + printk(" %s\n", ascii); + } +} + +/* + * Slow version of get and set free pointer. + * + * This requires touching the cache lines of kmem_cache. + * The offset can also be obtained from the page. In that + * case it is in the cacheline that we already need to touch. + */ +static void *get_freepointer(struct kmem_cache *s, void *object) +{ + return *(void **)(object + s->offset); +} + +static void set_freepointer(struct kmem_cache *s, void *object, void *fp) +{ + *(void **)(object + s->offset) = fp; +} + +/* + * Tracking user of a slab. + */ +struct track { + void *addr; /* Called from address */ + int cpu; /* Was running on cpu */ + int pid; /* Pid context */ + unsigned long when; /* When did the operation occur */ +}; + +enum track_item { TRACK_ALLOC, TRACK_FREE }; + +static struct track *get_track(struct kmem_cache *s, void *object, + enum track_item alloc) +{ + struct track *p; + + if (s->offset) + p = object + s->offset + sizeof(void *); + else + p = object + s->inuse; + + return p + alloc; +} + +static void set_track(struct kmem_cache *s, void *object, + enum track_item alloc, void *addr) +{ + struct track *p; + + if (s->offset) + p = object + s->offset + sizeof(void *); + else + p = object + s->inuse; + + p += alloc; + if (addr) { + p->addr = addr; + p->cpu = smp_processor_id(); + p->pid = current ? current->pid : -1; + p->when = jiffies; + } else + memset(p, 0, sizeof(struct track)); +} + +#define set_tracking(__s, __o, __a) set_track(__s, __o, __a, \ + __builtin_return_address(0)) + +static void init_tracking(struct kmem_cache *s, void *object) +{ + if (s->flags & SLAB_STORE_USER) { + set_track(s, object, TRACK_FREE, NULL); + set_track(s, object, TRACK_ALLOC, NULL); + } +} + +static void print_track(const char *s, struct track *t) +{ + if (!t->addr) + return; + + printk(KERN_ERR "%s: ", s); + __print_symbol("%s", (unsigned long)t->addr); + printk(" jiffies_ago=%lu cpu=%u pid=%d\n", jiffies - t->when, t->cpu, t->pid); +} + +static void print_trailer(struct kmem_cache *s, u8 *p) +{ + unsigned int off; /* Offset of last byte */ + + if (s->flags & SLAB_RED_ZONE) + print_section("Redzone", p + s->objsize, + s->inuse - s->objsize); + + printk(KERN_ERR "FreePointer 0x%p -> 0x%p\n", + p + s->offset, + get_freepointer(s, p)); + + if (s->offset) + off = s->offset + sizeof(void *); + else + off = s->inuse; + + if (s->flags & SLAB_STORE_USER) { + print_track("Last alloc", get_track(s, p, TRACK_ALLOC)); + print_track("Last free ", get_track(s, p, TRACK_FREE)); + off += 2 * sizeof(struct track); + } + + if (off != s->size) + /* Beginning of the filler is the free pointer */ + print_section("Filler", p + off, s->size - off); +} + +static void object_err(struct kmem_cache *s, struct page *page, + u8 *object, char *reason) +{ + u8 *addr = page_address(page); + + printk(KERN_ERR "*** SLUB %s: %s@0x%p slab 0x%p\n", + s->name, reason, object, page); + printk(KERN_ERR " offset=%tu flags=0x%04lx inuse=%u freelist=0x%p\n", + object - addr, page->flags, page->inuse, page->freelist); + if (object > addr + 16) + print_section("Bytes b4", object - 16, 16); + print_section("Object", object, min(s->objsize, 128)); + print_trailer(s, object); + dump_stack(); +} + +static void slab_err(struct kmem_cache *s, struct page *page, char *reason, ...) +{ + va_list args; + char buf[100]; + + va_start(args, reason); + vsnprintf(buf, sizeof(buf), reason, args); + va_end(args); + printk(KERN_ERR "*** SLUB %s: %s in slab @0x%p\n", s->name, buf, + page); + dump_stack(); +} + +static void init_object(struct kmem_cache *s, void *object, int active) +{ + u8 *p = object; + + if (s->flags & __OBJECT_POISON) { + memset(p, POISON_FREE, s->objsize - 1); + p[s->objsize -1] = POISON_END; + } + + if (s->flags & SLAB_RED_ZONE) + memset(p + s->objsize, + active ? SLUB_RED_ACTIVE : SLUB_RED_INACTIVE, + s->inuse - s->objsize); +} + +static int check_bytes(u8 *start, unsigned int value, unsigned int bytes) +{ + while (bytes) { + if (*start != (u8)value) + return 0; + start++; + bytes--; + } + return 1; +} + + +static int check_valid_pointer(struct kmem_cache *s, struct page *page, + void *object) +{ + void *base; + + if (!object) + return 1; + + base = page_address(page); + if (object < base || object >= base + s->objects * s->size || + (object - base) % s->size) { + return 0; + } + + return 1; +} + +/* + * Object layout: + * + * object address + * Bytes of the object to be managed. + * If the freepointer may overlay the object then the free + * pointer is the first word of the object. + * Poisoning uses 0x6b (POISON_FREE) and the last byte is + * 0xa5 (POISON_END) + * + * object + s->objsize + * Padding to reach word boundary. This is also used for Redzoning. + * Padding is extended to word size if Redzoning is enabled + * and objsize == inuse. + * We fill with 0xbb (RED_INACTIVE) for inactive objects and with + * 0xcc (RED_ACTIVE) for objects in use. + * + * object + s->inuse + * A. Free pointer (if we cannot overwrite object on free) + * B. Tracking data for SLAB_STORE_USER + * C. Padding to reach required alignment boundary + * Padding is done using 0x5a (POISON_INUSE) + * + * object + s->size + * + * If slabcaches are merged then the objsize and inuse boundaries are to + * be ignored. And therefore no slab options that rely on these boundaries + * may be used with merged slabcaches. + */ + +static void restore_bytes(struct kmem_cache *s, char *message, u8 data, + void *from, void *to) +{ + printk(KERN_ERR "@@@ SLUB: %s Restoring %s (0x%x) from 0x%p-0x%p\n", + s->name, message, data, from, to - 1); + memset(from, data, to - from); +} + +static int check_pad_bytes(struct kmem_cache *s, struct page *page, u8 *p) +{ + unsigned long off = s->inuse; /* The end of info */ + + if (s->offset) + /* Freepointer is placed after the object. */ + off += sizeof(void *); + + if (s->flags & SLAB_STORE_USER) + /* We also have user information there */ + off += 2 * sizeof(struct track); + + if (s->size == off) + return 1; + + if (check_bytes(p + off, POISON_INUSE, s->size - off)) + return 1; + + object_err(s, page, p, "Object padding check fails"); + + /* + * Restore padding + */ + restore_bytes(s, "object padding", POISON_INUSE, p + off, p + s->size); + return 0; +} + +static int slab_pad_check(struct kmem_cache *s, struct page *page) +{ + u8 *p; + int length, remainder; + + if (!(s->flags & SLAB_POISON)) + return 1; + + p = page_address(page); + length = s->objects * s->size; + remainder = (PAGE_SIZE << s->order) - length; + if (!remainder) + return 1; + + if (!check_bytes(p + length, POISON_INUSE, remainder)) { + printk(KERN_ERR "SLUB: %s slab 0x%p: Padding fails check\n", + s->name, p); + dump_stack(); + restore_bytes(s, "slab padding", POISON_INUSE, p + length, + p + length + remainder); + return 0; + } + return 1; +} + +static int check_object(struct kmem_cache *s, struct page *page, + void *object, int active) +{ + u8 *p = object; + u8 *endobject = object + s->objsize; + + if (s->flags & SLAB_RED_ZONE) { + unsigned int red = + active ? SLUB_RED_ACTIVE : SLUB_RED_INACTIVE; + + if (!check_bytes(endobject, red, s->inuse - s->objsize)) { + object_err(s, page, object, + active ? "Redzone Active" : "Redzone Inactive"); + restore_bytes(s, "redzone", red, + endobject, object + s->inuse); + return 0; + } + } else { + if ((s->flags & SLAB_POISON) && s->objsize < s->inuse && + !check_bytes(endobject, POISON_INUSE, + s->inuse - s->objsize)) { + object_err(s, page, p, "Alignment padding check fails"); + /* + * Fix it so that there will not be another report. + * + * Hmmm... We may be corrupting an object that now expects + * to be longer than allowed. + */ + restore_bytes(s, "alignment padding", POISON_INUSE, + endobject, object + s->inuse); + } + } + + if (s->flags & SLAB_POISON) { + if (!active && (s->flags & __OBJECT_POISON) && + (!check_bytes(p, POISON_FREE, s->objsize - 1) || + p[s->objsize - 1] != POISON_END)) { + + object_err(s, page, p, "Poison check failed"); + restore_bytes(s, "Poison", POISON_FREE, + p, p + s->objsize -1); + restore_bytes(s, "Poison", POISON_END, + p + s->objsize - 1, p + s->objsize); + return 0; + } + /* + * check_pad_bytes cleans up on its own. + */ + check_pad_bytes(s, page, p); + } + + if (!s->offset && active) + /* + * Object and freepointer overlap. Cannot check + * freepointer while object is allocated. + */ + return 1; + + /* Check free pointer validity */ + if (!check_valid_pointer(s, page, get_freepointer(s, p))) { + object_err(s, page, p, "Freepointer corrupt"); + /* + * No choice but to zap it and thus loose the remainder + * of the free objects in this slab. May cause + * another error because the object count maybe + * wrong now. + */ + set_freepointer(s, p, NULL); + return 0; + } + return 1; +} + +static int check_slab(struct kmem_cache *s, struct page *page) +{ + VM_BUG_ON(!irqs_disabled()); + + if (!PageSlab(page)) { + printk(KERN_ERR "SLUB: %s Not a valid slab page @0x%p " + "flags=%lx mapping=0x%p count=%d \n", + s->name, page, page->flags, page->mapping, + page_count(page)); + return 0; + } + if (page->offset * sizeof(void *) != s->offset) { + printk(KERN_ERR "SLUB: %s Corrupted offset %lu in slab @0x%p" + " flags=0x%lx mapping=0x%p count=%d\n", + s->name, + (unsigned long)(page->offset * sizeof(void *)), + page, + page->flags, + page->mapping, + page_count(page)); + dump_stack(); + return 0; + } + if (page->inuse > s->objects) { + printk(KERN_ERR "SLUB: %s Inuse %u > max %u in slab " + "page @0x%p flags=%lx mapping=0x%p count=%d\n", + s->name, page->inuse, s->objects, page, page->flags, + page->mapping, page_count(page)); + dump_stack(); + return 0; + } + /* Slab_pad_check fixes things up after itself */ + slab_pad_check(s, page); + return 1; +} + +/* + * Determine if a certain object on a page is on the freelist and + * therefore free. Must hold the slab lock for cpu slabs to + * guarantee that the chains are consistent. + */ +static int on_freelist(struct kmem_cache *s, struct page *page, void *search) +{ + int nr = 0; + void *fp = page->freelist; + void *object = NULL; + + while (fp && nr <= s->objects) { + if (fp == search) + return 1; + if (!check_valid_pointer(s, page, fp)) { + if (object) { + object_err(s, page, object, + "Freechain corrupt"); + set_freepointer(s, object, NULL); + break; + } else { + printk(KERN_ERR "SLUB: %s slab 0x%p " + "freepointer 0x%p corrupted.\n", + s->name, page, fp); + dump_stack(); + page->freelist = NULL; + page->inuse = s->objects; + return 0; + } + break; + } + object = fp; + fp = get_freepointer(s, object); + nr++; + } + + if (page->inuse != s->objects - nr) { + printk(KERN_ERR "slab %s: page 0x%p wrong object count." + " counter is %d but counted were %d\n", + s->name, page, page->inuse, + s->objects - nr); + page->inuse = s->objects - nr; + } + return search == NULL; +} + +static int alloc_object_checks(struct kmem_cache *s, struct page *page, + void *object) +{ + if (!check_slab(s, page)) + goto bad; + + if (object && !on_freelist(s, page, object)) { + printk(KERN_ERR "SLUB: %s Object 0x%p@0x%p " + "already allocated.\n", + s->name, object, page); + goto dump; + } + + if (!check_valid_pointer(s, page, object)) { + object_err(s, page, object, "Freelist Pointer check fails"); + goto dump; + } + + if (!object) + return 1; + + if (!check_object(s, page, object, 0)) + goto bad; + init_object(s, object, 1); + + if (s->flags & SLAB_TRACE) { + printk(KERN_INFO "TRACE %s alloc 0x%p inuse=%d fp=0x%p\n", + s->name, object, page->inuse, + page->freelist); + dump_stack(); + } + return 1; +dump: + dump_stack(); +bad: + if (PageSlab(page)) { + /* + * If this is a slab page then lets do the best we can + * to avoid issues in the future. Marking all objects + * as used avoids touching the remainder. + */ + printk(KERN_ERR "@@@ SLUB: %s slab 0x%p. Marking all objects used.\n", + s->name, page); + page->inuse = s->objects; + page->freelist = NULL; + /* Fix up fields that may be corrupted */ + page->offset = s->offset / sizeof(void *); + } + return 0; +} + +static int free_object_checks(struct kmem_cache *s, struct page *page, + void *object) +{ + if (!check_slab(s, page)) + goto fail; + + if (!check_valid_pointer(s, page, object)) { + printk(KERN_ERR "SLUB: %s slab 0x%p invalid " + "object pointer 0x%p\n", + s->name, page, object); + goto fail; + } + + if (on_freelist(s, page, object)) { + printk(KERN_ERR "SLUB: %s slab 0x%p object " + "0x%p already free.\n", s->name, page, object); + goto fail; + } + + if (!check_object(s, page, object, 1)) + return 0; + + if (unlikely(s != page->slab)) { + if (!PageSlab(page)) + printk(KERN_ERR "slab_free %s size %d: attempt to" + "free object(0x%p) outside of slab.\n", + s->name, s->size, object); + else + if (!page->slab) + printk(KERN_ERR + "slab_free : no slab(NULL) for object 0x%p.\n", + object); + else + printk(KERN_ERR "slab_free %s(%d): object at 0x%p" + " belongs to slab %s(%d)\n", + s->name, s->size, object, + page->slab->name, page->slab->size); + goto fail; + } + if (s->flags & SLAB_TRACE) { + printk(KERN_INFO "TRACE %s free 0x%p inuse=%d fp=0x%p\n", + s->name, object, page->inuse, + page->freelist); + print_section("Object", object, s->objsize); + dump_stack(); + } + init_object(s, object, 0); + return 1; +fail: + dump_stack(); + printk(KERN_ERR "@@@ SLUB: %s slab 0x%p object at 0x%p not freed.\n", + s->name, page, object); + return 0; +} + +/* + * Slab allocation and freeing + */ +static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) +{ + struct page * page; + int pages = 1 << s->order; + + if (s->order) + flags |= __GFP_COMP; + + if (s->flags & SLAB_CACHE_DMA) + flags |= SLUB_DMA; + + if (node == -1) + page = alloc_pages(flags, s->order); + else + page = alloc_pages_node(node, flags, s->order); + + if (!page) + return NULL; + + mod_zone_page_state(page_zone(page), + (s->flags & SLAB_RECLAIM_ACCOUNT) ? + NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE, + pages); + + return page; +} + +static void setup_object(struct kmem_cache *s, struct page *page, + void *object) +{ + if (PageError(page)) { + init_object(s, object, 0); + init_tracking(s, object); + } + + if (unlikely(s->ctor)) { + int mode = SLAB_CTOR_CONSTRUCTOR; + + if (!(s->flags & __GFP_WAIT)) + mode |= SLAB_CTOR_ATOMIC; + + s->ctor(object, s, mode); + } +} + +static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node) +{ + struct page *page; + struct kmem_cache_node *n; + void *start; + void *end; + void *last; + void *p; + + if (flags & __GFP_NO_GROW) + return NULL; + + BUG_ON(flags & ~(GFP_DMA | GFP_LEVEL_MASK)); + + if (flags & __GFP_WAIT) + local_irq_enable(); + + page = allocate_slab(s, flags & GFP_LEVEL_MASK, node); + if (!page) + goto out; + + n = get_node(s, page_to_nid(page)); + if (n) + atomic_long_inc(&n->nr_slabs); + page->offset = s->offset / sizeof(void *); + page->slab = s; + page->flags |= 1 << PG_slab; + if (s->flags & (SLAB_DEBUG_FREE | SLAB_RED_ZONE | SLAB_POISON | + SLAB_STORE_USER | SLAB_TRACE)) + page->flags |= 1 << PG_error; + + start = page_address(page); + end = start + s->objects * s->size; + + if (unlikely(s->flags & SLAB_POISON)) + memset(start, POISON_INUSE, PAGE_SIZE << s->order); + + last = start; + for (p = start + s->size; p < end; p += s->size) { + setup_object(s, page, last); + set_freepointer(s, last, p); + last = p; + } + setup_object(s, page, last); + set_freepointer(s, last, NULL); + + page->freelist = start; + page->inuse = 0; +out: + if (flags & __GFP_WAIT) + local_irq_disable(); + return page; +} + +static void __free_slab(struct kmem_cache *s, struct page *page) +{ + int pages = 1 << s->order; + + if (unlikely(PageError(page) || s->dtor)) { + void *start = page_address(page); + void *end = start + (pages << PAGE_SHIFT); + void *p; + + slab_pad_check(s, page); + for (p = start; p <= end - s->size; p += s->size) { + if (s->dtor) + s->dtor(p, s, 0); + check_object(s, page, p, 0); + } + } + + mod_zone_page_state(page_zone(page), + (s->flags & SLAB_RECLAIM_ACCOUNT) ? + NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE, + - pages); + + page->mapping = NULL; + __free_pages(page, s->order); +} + +static void rcu_free_slab(struct rcu_head *h) +{ + struct page *page; + + page = container_of((struct list_head *)h, struct page, lru); + __free_slab(page->slab, page); +} + +static void free_slab(struct kmem_cache *s, struct page *page) +{ + if (unlikely(s->flags & SLAB_DESTROY_BY_RCU)) { + /* + * RCU free overloads the RCU head over the LRU + */ + struct rcu_head *head = (void *)&page->lru; + + call_rcu(head, rcu_free_slab); + } else + __free_slab(s, page); +} + +static void discard_slab(struct kmem_cache *s, struct page *page) +{ + struct kmem_cache_node *n = get_node(s, page_to_nid(page)); + + atomic_long_dec(&n->nr_slabs); + reset_page_mapcount(page); + page->flags &= ~(1 << PG_slab | 1 << PG_error); + free_slab(s, page); +} + +/* + * Per slab locking using the pagelock + */ +static __always_inline void slab_lock(struct page *page) +{ + bit_spin_lock(PG_locked, &page->flags); +} + +static __always_inline void slab_unlock(struct page *page) +{ + bit_spin_unlock(PG_locked, &page->flags); +} + +static __always_inline int slab_trylock(struct page *page) +{ + int rc = 1; + + rc = bit_spin_trylock(PG_locked, &page->flags); + return rc; +} + +/* + * Management of partially allocated slabs + */ +static void add_partial(struct kmem_cache *s, struct page *page) +{ + struct kmem_cache_node *n = get_node(s, page_to_nid(page)); + + spin_lock(&n->list_lock); + n->nr_partial++; + list_add(&page->lru, &n->partial); + spin_unlock(&n->list_lock); +} + +static void remove_partial(struct kmem_cache *s, + struct page *page) +{ + struct kmem_cache_node *n = get_node(s, page_to_nid(page)); + + spin_lock(&n->list_lock); + list_del(&page->lru); + n->nr_partial--; + spin_unlock(&n->list_lock); +} + +/* + * Lock page and remove it from the partial list + * + * Must hold list_lock + */ +static int lock_and_del_slab(struct kmem_cache_node *n, struct page *page) +{ + if (slab_trylock(page)) { + list_del(&page->lru); + n->nr_partial--; + return 1; + } + return 0; +} + +/* + * Try to get a partial slab from a specific node + */ +static struct page *get_partial_node(struct kmem_cache_node *n) +{ + struct page *page; + + /* + * Racy check. If we mistakenly see no partial slabs then we + * just allocate an empty slab. If we mistakenly try to get a + * partial slab then get_partials() will return NULL. + */ + if (!n || !n->nr_partial) + return NULL; + + spin_lock(&n->list_lock); + list_for_each_entry(page, &n->partial, lru) + if (lock_and_del_slab(n, page)) + goto out; + page = NULL; +out: + spin_unlock(&n->list_lock); + return page; +} + +/* + * Get a page from somewhere. Search in increasing NUMA + * distances. + */ +static struct page *get_any_partial(struct kmem_cache *s, gfp_t flags) +{ +#ifdef CONFIG_NUMA + struct zonelist *zonelist; + struct zone **z; + struct page *page; + + /* + * The defrag ratio allows to configure the tradeoffs between + * inter node defragmentation and node local allocations. + * A lower defrag_ratio increases the tendency to do local + * allocations instead of scanning throught the partial + * lists on other nodes. + * + * If defrag_ratio is set to 0 then kmalloc() always + * returns node local objects. If its higher then kmalloc() + * may return off node objects in order to avoid fragmentation. + * + * A higher ratio means slabs may be taken from other nodes + * thus reducing the number of partial slabs on those nodes. + * + * If /sys/slab/xx/defrag_ratio is set to 100 (which makes + * defrag_ratio = 1000) then every (well almost) allocation + * will first attempt to defrag slab caches on other nodes. This + * means scanning over all nodes to look for partial slabs which + * may be a bit expensive to do on every slab allocation. + */ + if (!s->defrag_ratio || get_cycles() % 1024 > s->defrag_ratio) + return NULL; + + zonelist = &NODE_DATA(slab_node(current->mempolicy)) + ->node_zonelists[gfp_zone(flags)]; + for (z = zonelist->zones; *z; z++) { + struct kmem_cache_node *n; + + n = get_node(s, zone_to_nid(*z)); + + if (n && cpuset_zone_allowed_hardwall(*z, flags) && + n->nr_partial > 2) { + page = get_partial_node(n); + if (page) + return page; + } + } +#endif + return NULL; +} + +/* + * Get a partial page, lock it and return it. + */ +static struct page *get_partial(struct kmem_cache *s, gfp_t flags, int node) +{ + struct page *page; + int searchnode = (node == -1) ? numa_node_id() : node; + + page = get_partial_node(get_node(s, searchnode)); + if (page || (flags & __GFP_THISNODE)) + return page; + + return get_any_partial(s, flags); +} + +/* + * Move a page back to the lists. + * + * Must be called with the slab lock held. + * + * On exit the slab lock will have been dropped. + */ +static void putback_slab(struct kmem_cache *s, struct page *page) +{ + if (page->inuse) { + if (page->freelist) + add_partial(s, page); + slab_unlock(page); + } else { + slab_unlock(page); + discard_slab(s, page); + } +} + +/* + * Remove the cpu slab + */ +static void deactivate_slab(struct kmem_cache *s, struct page *page, int cpu) +{ + s->cpu_slab[cpu] = NULL; + ClearPageActive(page); + + putback_slab(s, page); +} + +static void flush_slab(struct kmem_cache *s, struct page *page, int cpu) +{ + slab_lock(page); + deactivate_slab(s, page, cpu); +} + +/* + * Flush cpu slab. + * Called from IPI handler with interrupts disabled. + */ +static void __flush_cpu_slab(struct kmem_cache *s, int cpu) +{ + struct page *page = s->cpu_slab[cpu]; + + if (likely(page)) + flush_slab(s, page, cpu); +} + +static void flush_cpu_slab(void *d) +{ + struct kmem_cache *s = d; + int cpu = smp_processor_id(); + + __flush_cpu_slab(s, cpu); +} + +static void flush_all(struct kmem_cache *s) +{ +#ifdef CONFIG_SMP + on_each_cpu(flush_cpu_slab, s, 1, 1); +#else + unsigned long flags; + + local_irq_save(flags); + flush_cpu_slab(s); + local_irq_restore(flags); +#endif +} + +/* + * slab_alloc is optimized to only modify two cachelines on the fast path + * (aside from the stack): + * + * 1. The page struct + * 2. The first cacheline of the object to be allocated. + * + * The only cache lines that are read (apart from code) is the + * per cpu array in the kmem_cache struct. + * + * Fastpath is not possible if we need to get a new slab or have + * debugging enabled (which means all slabs are marked with PageError) + */ +static __always_inline void *slab_alloc(struct kmem_cache *s, + gfp_t gfpflags, int node) +{ + struct page *page; + void **object; + unsigned long flags; + int cpu; + + local_irq_save(flags); + cpu = smp_processor_id(); + page = s->cpu_slab[cpu]; + if (!page) + goto new_slab; + + slab_lock(page); + if (unlikely(node != -1 && page_to_nid(page) != node)) + goto another_slab; +redo: + object = page->freelist; + if (unlikely(!object)) + goto another_slab; + if (unlikely(PageError(page))) + goto debug; + +have_object: + page->inuse++; + page->freelist = object[page->offset]; + slab_unlock(page); + local_irq_restore(flags); + return object; + +another_slab: + deactivate_slab(s, page, cpu); + +new_slab: + page = get_partial(s, gfpflags, node); + if (likely(page)) { +have_slab: + s->cpu_slab[cpu] = page; + SetPageActive(page); + goto redo; + } + + page = new_slab(s, gfpflags, node); + if (page) { + cpu = smp_processor_id(); + if (s->cpu_slab[cpu]) { + /* + * Someone else populated the cpu_slab while we enabled + * interrupts, or we have got scheduled on another cpu. + * The page may not be on the requested node. + */ + if (node == -1 || + page_to_nid(s->cpu_slab[cpu]) == node) { + /* + * Current cpuslab is acceptable and we + * want the current one since its cache hot + */ + discard_slab(s, page); + page = s->cpu_slab[cpu]; + slab_lock(page); + goto redo; + } + /* Dump the current slab */ + flush_slab(s, s->cpu_slab[cpu], cpu); + } + slab_lock(page); + goto have_slab; + } + local_irq_restore(flags); + return NULL; +debug: + if (!alloc_object_checks(s, page, object)) + goto another_slab; + if (s->flags & SLAB_STORE_USER) + set_tracking(s, object, TRACK_ALLOC); + goto have_object; +} + +void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags) +{ + return slab_alloc(s, gfpflags, -1); +} +EXPORT_SYMBOL(kmem_cache_alloc); + +#ifdef CONFIG_NUMA +void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node) +{ + return slab_alloc(s, gfpflags, node); +} +EXPORT_SYMBOL(kmem_cache_alloc_node); +#endif + +/* + * The fastpath only writes the cacheline of the page struct and the first + * cacheline of the object. + * + * No special cachelines need to be read + */ +static void slab_free(struct kmem_cache *s, struct page *page, void *x) +{ + void *prior; + void **object = (void *)x; + unsigned long flags; + + local_irq_save(flags); + slab_lock(page); + + if (unlikely(PageError(page))) + goto debug; +checks_ok: + prior = object[page->offset] = page->freelist; + page->freelist = object; + page->inuse--; + + if (unlikely(PageActive(page))) + /* + * Cpu slabs are never on partial lists and are + * never freed. + */ + goto out_unlock; + + if (unlikely(!page->inuse)) + goto slab_empty; + + /* + * Objects left in the slab. If it + * was not on the partial list before + * then add it. + */ + if (unlikely(!prior)) + add_partial(s, page); + +out_unlock: + slab_unlock(page); + local_irq_restore(flags); + return; + +slab_empty: + if (prior) + /* + * Partially used slab that is on the partial list. + */ + remove_partial(s, page); + + slab_unlock(page); + discard_slab(s, page); + local_irq_restore(flags); + return; + +debug: + if (free_object_checks(s, page, x)) + goto checks_ok; + goto out_unlock; +} + +void kmem_cache_free(struct kmem_cache *s, void *x) +{ + struct page * page; + + page = virt_to_page(x); + + if (unlikely(PageCompound(page))) + page = page->first_page; + + + if (unlikely(PageError(page) && (s->flags & SLAB_STORE_USER))) + set_tracking(s, x, TRACK_FREE); + slab_free(s, page, x); +} +EXPORT_SYMBOL(kmem_cache_free); + +/* Figure out on which slab object the object resides */ +static struct page *get_object_page(const void *x) +{ + struct page *page = virt_to_page(x); + + if (unlikely(PageCompound(page))) + page = page->first_page; + + if (!PageSlab(page)) + return NULL; + + return page; +} + +/* + * kmem_cache_open produces objects aligned at "size" and the first object + * is placed at offset 0 in the slab (We have no metainformation on the + * slab, all slabs are in essence "off slab"). + * + * In order to get the desired alignment one just needs to align the + * size. + * + * Notice that the allocation order determines the sizes of the per cpu + * caches. Each processor has always one slab available for allocations. + * Increasing the allocation order reduces the number of times that slabs + * must be moved on and off the partial lists and therefore may influence + * locking overhead. + * + * The offset is used to relocate the free list link in each object. It is + * therefore possible to move the free list link behind the object. This + * is necessary for RCU to work properly and also useful for debugging. + */ + +/* + * Mininum / Maximum order of slab pages. This influences locking overhead + * and slab fragmentation. A higher order reduces the number of partial slabs + * and increases the number of allocations possible without having to + * take the list_lock. + */ +static int slub_min_order; +static int slub_max_order = DEFAULT_MAX_ORDER; + +/* + * Minimum number of objects per slab. This is necessary in order to + * reduce locking overhead. Similar to the queue size in SLAB. + */ +static int slub_min_objects = DEFAULT_MIN_OBJECTS; + +/* + * Merge control. If this is set then no merging of slab caches will occur. + */ +static int slub_nomerge; + +/* + * Debug settings: + */ +static int slub_debug; + +static char *slub_debug_slabs; + +/* + * Calculate the order of allocation given an slab object size. + * + * The order of allocation has significant impact on other elements + * of the system. Generally order 0 allocations should be preferred + * since they do not cause fragmentation in the page allocator. Larger + * objects may have problems with order 0 because there may be too much + * space left unused in a slab. We go to a higher order if more than 1/8th + * of the slab would be wasted. + * + * In order to reach satisfactory performance we must ensure that + * a minimum number of objects is in one slab. Otherwise we may + * generate too much activity on the partial lists. This is less a + * concern for large slabs though. slub_max_order specifies the order + * where we begin to stop considering the number of objects in a slab. + * + * Higher order allocations also allow the placement of more objects + * in a slab and thereby reduce object handling overhead. If the user + * has requested a higher mininum order then we start with that one + * instead of zero. + */ +static int calculate_order(int size) +{ + int order; + int rem; + + for (order = max(slub_min_order, fls(size - 1) - PAGE_SHIFT); + order < MAX_ORDER; order++) { + unsigned long slab_size = PAGE_SIZE << order; + + if (slub_max_order > order && + slab_size < slub_min_objects * size) + continue; + + if (slab_size < size) + continue; + + rem = slab_size % size; + + if (rem <= (PAGE_SIZE << order) / 8) + break; + + } + if (order >= MAX_ORDER) + return -E2BIG; + return order; +} + +/* + * Function to figure out which alignment to use from the + * various ways of specifying it. + */ +static unsigned long calculate_alignment(unsigned long flags, + unsigned long align, unsigned long size) +{ + /* + * If the user wants hardware cache aligned objects then + * follow that suggestion if the object is sufficiently + * large. + * + * The hardware cache alignment cannot override the + * specified alignment though. If that is greater + * then use it. + */ + if ((flags & (SLAB_MUST_HWCACHE_ALIGN | SLAB_HWCACHE_ALIGN)) && + size > L1_CACHE_BYTES / 2) + return max_t(unsigned long, align, L1_CACHE_BYTES); + + if (align < ARCH_SLAB_MINALIGN) + return ARCH_SLAB_MINALIGN; + + return ALIGN(align, sizeof(void *)); +} + +static void init_kmem_cache_node(struct kmem_cache_node *n) +{ + n->nr_partial = 0; + atomic_long_set(&n->nr_slabs, 0); + spin_lock_init(&n->list_lock); + INIT_LIST_HEAD(&n->partial); +} + +#ifdef CONFIG_NUMA +/* + * No kmalloc_node yet so do it by hand. We know that this is the first + * slab on the node for this slabcache. There are no concurrent accesses + * possible. + * + * Note that this function only works on the kmalloc_node_cache + * when allocating for the kmalloc_node_cache. + */ +static struct kmem_cache_node * __init early_kmem_cache_node_alloc(gfp_t gfpflags, + int node) +{ + struct page *page; + struct kmem_cache_node *n; + + BUG_ON(kmalloc_caches->size < sizeof(struct kmem_cache_node)); + + page = new_slab(kmalloc_caches, gfpflags | GFP_THISNODE, node); + /* new_slab() disables interupts */ + local_irq_enable(); + + BUG_ON(!page); + n = page->freelist; + BUG_ON(!n); + page->freelist = get_freepointer(kmalloc_caches, n); + page->inuse++; + kmalloc_caches->node[node] = n; + init_object(kmalloc_caches, n, 1); + init_kmem_cache_node(n); + atomic_long_inc(&n->nr_slabs); + add_partial(kmalloc_caches, page); + return n; +} + +static void free_kmem_cache_nodes(struct kmem_cache *s) +{ + int node; + + for_each_online_node(node) { + struct kmem_cache_node *n = s->node[node]; + if (n && n != &s->local_node) + kmem_cache_free(kmalloc_caches, n); + s->node[node] = NULL; + } +} + +static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags) +{ + int node; + int local_node; + + if (slab_state >= UP) + local_node = page_to_nid(virt_to_page(s)); + else + local_node = 0; + + for_each_online_node(node) { + struct kmem_cache_node *n; + + if (local_node == node) + n = &s->local_node; + else { + if (slab_state == DOWN) { + n = early_kmem_cache_node_alloc(gfpflags, + node); + continue; + } + n = kmem_cache_alloc_node(kmalloc_caches, + gfpflags, node); + + if (!n) { + free_kmem_cache_nodes(s); + return 0; + } + + } + s->node[node] = n; + init_kmem_cache_node(n); + } + return 1; +} +#else +static void free_kmem_cache_nodes(struct kmem_cache *s) +{ +} + +static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags) +{ + init_kmem_cache_node(&s->local_node); + return 1; +} +#endif + +/* + * calculate_sizes() determines the order and the distribution of data within + * a slab object. + */ +static int calculate_sizes(struct kmem_cache *s) +{ + unsigned long flags = s->flags; + unsigned long size = s->objsize; + unsigned long align = s->align; + + /* + * Determine if we can poison the object itself. If the user of + * the slab may touch the object after free or before allocation + * then we should never poison the object itself. + */ + if ((flags & SLAB_POISON) && !(flags & SLAB_DESTROY_BY_RCU) && + !s->ctor && !s->dtor) + s->flags |= __OBJECT_POISON; + else + s->flags &= ~__OBJECT_POISON; + + /* + * Round up object size to the next word boundary. We can only + * place the free pointer at word boundaries and this determines + * the possible location of the free pointer. + */ + size = ALIGN(size, sizeof(void *)); + + /* + * If we are redzoning then check if there is some space between the + * end of the object and the free pointer. If not then add an + * additional word, so that we can establish a redzone between + * the object and the freepointer to be able to check for overwrites. + */ + if ((flags & SLAB_RED_ZONE) && size == s->objsize) + size += sizeof(void *); + + /* + * With that we have determined how much of the slab is in actual + * use by the object. This is the potential offset to the free + * pointer. + */ + s->inuse = size; + + if (((flags & (SLAB_DESTROY_BY_RCU | SLAB_POISON)) || + s->ctor || s->dtor)) { + /* + * Relocate free pointer after the object if it is not + * permitted to overwrite the first word of the object on + * kmem_cache_free. + * + * This is the case if we do RCU, have a constructor or + * destructor or are poisoning the objects. + */ + s->offset = size; + size += sizeof(void *); + } + + if (flags & SLAB_STORE_USER) + /* + * Need to store information about allocs and frees after + * the object. + */ + size += 2 * sizeof(struct track); + + if (flags & DEBUG_DEFAULT_FLAGS) + /* + * Add some empty padding so that we can catch + * overwrites from earlier objects rather than let + * tracking information or the free pointer be + * corrupted if an user writes before the start + * of the object. + */ + size += sizeof(void *); + /* + * Determine the alignment based on various parameters that the + * user specified (this is unecessarily complex due to the attempt + * to be compatible with SLAB. Should be cleaned up some day). + */ + align = calculate_alignment(flags, align, s->objsize); + + /* + * SLUB stores one object immediately after another beginning from + * offset 0. In order to align the objects we have to simply size + * each object to conform to the alignment. + */ + size = ALIGN(size, align); + s->size = size; + + s->order = calculate_order(size); + if (s->order < 0) + return 0; + + /* + * Determine the number of objects per slab + */ + s->objects = (PAGE_SIZE << s->order) / size; + + /* + * Verify that the number of objects is within permitted limits. + * The page->inuse field is only 16 bit wide! So we cannot have + * more than 64k objects per slab. + */ + if (!s->objects || s->objects > 65535) + return 0; + return 1; + +} + +static int __init finish_bootstrap(void) +{ + struct list_head *h; + int err; + + slab_state = SYSFS; + + list_for_each(h, &slab_caches) { + struct kmem_cache *s = + container_of(h, struct kmem_cache, list); + + err = sysfs_slab_add(s); + BUG_ON(err); + } + return 0; +} + +static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags, + const char *name, size_t size, + size_t align, unsigned long flags, + void (*ctor)(void *, struct kmem_cache *, unsigned long), + void (*dtor)(void *, struct kmem_cache *, unsigned long)) +{ + memset(s, 0, kmem_size); + s->name = name; + s->ctor = ctor; + s->dtor = dtor; + s->objsize = size; + s->flags = flags; + s->align = align; + + BUG_ON(flags & SLUB_UNIMPLEMENTED); + + /* + * The page->offset field is only 16 bit wide. This is an offset + * in units of words from the beginning of an object. If the slab + * size is bigger then we cannot move the free pointer behind the + * object anymore. + * + * On 32 bit platforms the limit is 256k. On 64bit platforms + * the limit is 512k. + * + * Debugging or ctor/dtors may create a need to move the free + * pointer. Fail if this happens. + */ + if (s->size >= 65535 * sizeof(void *)) { + BUG_ON(flags & (SLAB_RED_ZONE | SLAB_POISON | + SLAB_STORE_USER | SLAB_DESTROY_BY_RCU)); + BUG_ON(ctor || dtor); + } + else + /* + * Enable debugging if selected on the kernel commandline. + */ + if (slub_debug && (!slub_debug_slabs || + strncmp(slub_debug_slabs, name, + strlen(slub_debug_slabs)) == 0)) + s->flags |= slub_debug; + + if (!calculate_sizes(s)) + goto error; + + s->refcount = 1; +#ifdef CONFIG_NUMA + s->defrag_ratio = 100; +#endif + + if (init_kmem_cache_nodes(s, gfpflags & ~SLUB_DMA)) + return 1; +error: + if (flags & SLAB_PANIC) + panic("Cannot create slab %s size=%lu realsize=%u " + "order=%u offset=%u flags=%lx\n", + s->name, (unsigned long)size, s->size, s->order, + s->offset, flags); + return 0; +} +EXPORT_SYMBOL(kmem_cache_open); + +/* + * Check if a given pointer is valid + */ +int kmem_ptr_validate(struct kmem_cache *s, const void *object) +{ + struct page * page; + void *addr; + + page = get_object_page(object); + + if (!page || s != page->slab) + /* No slab or wrong slab */ + return 0; + + addr = page_address(page); + if (object < addr || object >= addr + s->objects * s->size) + /* Out of bounds */ + return 0; + + if ((object - addr) % s->size) + /* Improperly aligned */ + return 0; + + /* + * We could also check if the object is on the slabs freelist. + * But this would be too expensive and it seems that the main + * purpose of kmem_ptr_valid is to check if the object belongs + * to a certain slab. + */ + return 1; +} +EXPORT_SYMBOL(kmem_ptr_validate); + +/* + * Determine the size of a slab object + */ +unsigned int kmem_cache_size(struct kmem_cache *s) +{ + return s->objsize; +} +EXPORT_SYMBOL(kmem_cache_size); + +const char *kmem_cache_name(struct kmem_cache *s) +{ + return s->name; +} +EXPORT_SYMBOL(kmem_cache_name); + +/* + * Attempt to free all slabs on a node + */ +static int free_list(struct kmem_cache *s, struct kmem_cache_node *n, + struct list_head *list) +{ + int slabs_inuse = 0; + unsigned long flags; + struct page *page, *h; + + spin_lock_irqsave(&n->list_lock, flags); + list_for_each_entry_safe(page, h, list, lru) + if (!page->inuse) { + list_del(&page->lru); + discard_slab(s, page); + } else + slabs_inuse++; + spin_unlock_irqrestore(&n->list_lock, flags); + return slabs_inuse; +} + +/* + * Release all resources used by slab cache + */ +static int kmem_cache_close(struct kmem_cache *s) +{ + int node; + + flush_all(s); + + /* Attempt to free all objects */ + for_each_online_node(node) { + struct kmem_cache_node *n = get_node(s, node); + + free_list(s, n, &n->partial); + if (atomic_long_read(&n->nr_slabs)) + return 1; + } + free_kmem_cache_nodes(s); + return 0; +} + +/* + * Close a cache and release the kmem_cache structure + * (must be used for caches created using kmem_cache_create) + */ +void kmem_cache_destroy(struct kmem_cache *s) +{ + down_write(&slub_lock); + s->refcount--; + if (!s->refcount) { + list_del(&s->list); + if (kmem_cache_close(s)) + WARN_ON(1); + sysfs_slab_remove(s); + kfree(s); + } + up_write(&slub_lock); +} +EXPORT_SYMBOL(kmem_cache_destroy); + +/******************************************************************** + * Kmalloc subsystem + *******************************************************************/ + +struct kmem_cache kmalloc_caches[KMALLOC_SHIFT_HIGH + 1] __cacheline_aligned; +EXPORT_SYMBOL(kmalloc_caches); + +#ifdef CONFIG_ZONE_DMA +static struct kmem_cache *kmalloc_caches_dma[KMALLOC_SHIFT_HIGH + 1]; +#endif + +static int __init setup_slub_min_order(char *str) +{ + get_option (&str, &slub_min_order); + + return 1; +} + +__setup("slub_min_order=", setup_slub_min_order); + +static int __init setup_slub_max_order(char *str) +{ + get_option (&str, &slub_max_order); + + return 1; +} + +__setup("slub_max_order=", setup_slub_max_order); + +static int __init setup_slub_min_objects(char *str) +{ + get_option (&str, &slub_min_objects); + + return 1; +} + +__setup("slub_min_objects=", setup_slub_min_objects); + +static int __init setup_slub_nomerge(char *str) +{ + slub_nomerge = 1; + return 1; +} + +__setup("slub_nomerge", setup_slub_nomerge); + +static int __init setup_slub_debug(char *str) +{ + if (!str || *str != '=') + slub_debug = DEBUG_DEFAULT_FLAGS; + else { + str++; + if (*str == 0 || *str == ',') + slub_debug = DEBUG_DEFAULT_FLAGS; + else + for( ;*str && *str != ','; str++) + switch (*str) { + case 'f' : case 'F' : + slub_debug |= SLAB_DEBUG_FREE; + break; + case 'z' : case 'Z' : + slub_debug |= SLAB_RED_ZONE; + break; + case 'p' : case 'P' : + slub_debug |= SLAB_POISON; + break; + case 'u' : case 'U' : + slub_debug |= SLAB_STORE_USER; + break; + case 't' : case 'T' : + slub_debug |= SLAB_TRACE; + break; + default: + printk(KERN_ERR "slub_debug option '%c' " + "unknown. skipped\n",*str); + } + } + + if (*str == ',') + slub_debug_slabs = str + 1; + return 1; +} + +__setup("slub_debug", setup_slub_debug); + +static struct kmem_cache *create_kmalloc_cache(struct kmem_cache *s, + const char *name, int size, gfp_t gfp_flags) +{ + unsigned int flags = 0; + + if (gfp_flags & SLUB_DMA) + flags = SLAB_CACHE_DMA; + + down_write(&slub_lock); + if (!kmem_cache_open(s, gfp_flags, name, size, ARCH_KMALLOC_MINALIGN, + flags, NULL, NULL)) + goto panic; + + list_add(&s->list, &slab_caches); + up_write(&slub_lock); + if (sysfs_slab_add(s)) + goto panic; + return s; + +panic: + panic("Creation of kmalloc slab %s size=%d failed.\n", name, size); +} + +static struct kmem_cache *get_slab(size_t size, gfp_t flags) +{ + int index = kmalloc_index(size); + + if (!size) + return NULL; + + /* Allocation too large? */ + BUG_ON(index < 0); + +#ifdef CONFIG_ZONE_DMA + if ((flags & SLUB_DMA)) { + struct kmem_cache *s; + struct kmem_cache *x; + char *text; + size_t realsize; + + s = kmalloc_caches_dma[index]; + if (s) + return s; + + /* Dynamically create dma cache */ + x = kmalloc(kmem_size, flags & ~SLUB_DMA); + if (!x) + panic("Unable to allocate memory for dma cache\n"); + + if (index <= KMALLOC_SHIFT_HIGH) + realsize = 1 << index; + else { + if (index == 1) + realsize = 96; + else + realsize = 192; + } + + text = kasprintf(flags & ~SLUB_DMA, "kmalloc_dma-%d", + (unsigned int)realsize); + s = create_kmalloc_cache(x, text, realsize, flags); + kmalloc_caches_dma[index] = s; + return s; + } +#endif + return &kmalloc_caches[index]; +} + +void *__kmalloc(size_t size, gfp_t flags) +{ + struct kmem_cache *s = get_slab(size, flags); + + if (s) + return kmem_cache_alloc(s, flags); + return NULL; +} +EXPORT_SYMBOL(__kmalloc); + +#ifdef CONFIG_NUMA +void *__kmalloc_node(size_t size, gfp_t flags, int node) +{ + struct kmem_cache *s = get_slab(size, flags); + + if (s) + return kmem_cache_alloc_node(s, flags, node); + return NULL; +} +EXPORT_SYMBOL(__kmalloc_node); +#endif + +size_t ksize(const void *object) +{ + struct page *page = get_object_page(object); + struct kmem_cache *s; + + BUG_ON(!page); + s = page->slab; + BUG_ON(!s); + + /* + * Debugging requires use of the padding between object + * and whatever may come after it. + */ + if (s->flags & (SLAB_RED_ZONE | SLAB_POISON)) + return s->objsize; + + /* + * If we have the need to store the freelist pointer + * back there or track user information then we can + * only use the space before that information. + */ + if (s->flags & (SLAB_DESTROY_BY_RCU | SLAB_STORE_USER)) + return s->inuse; + + /* + * Else we can use all the padding etc for the allocation + */ + return s->size; +} +EXPORT_SYMBOL(ksize); + +void kfree(const void *x) +{ + struct kmem_cache *s; + struct page *page; + + if (!x) + return; + + page = virt_to_page(x); + + if (unlikely(PageCompound(page))) + page = page->first_page; + + s = page->slab; + + if (unlikely(PageError(page) && (s->flags & SLAB_STORE_USER))) + set_tracking(s, (void *)x, TRACK_FREE); + slab_free(s, page, (void *)x); +} +EXPORT_SYMBOL(kfree); + +/** + * krealloc - reallocate memory. The contents will remain unchanged. + * + * @p: object to reallocate memory for. + * @new_size: how many bytes of memory are required. + * @flags: the type of memory to allocate. + * + * The contents of the object pointed to are preserved up to the + * lesser of the new and old sizes. If @p is %NULL, krealloc() + * behaves exactly like kmalloc(). If @size is 0 and @p is not a + * %NULL pointer, the object pointed to is freed. + */ +void *krealloc(const void *p, size_t new_size, gfp_t flags) +{ + struct kmem_cache *new_cache; + void *ret; + struct page *page; + + if (unlikely(!p)) + return kmalloc(new_size, flags); + + if (unlikely(!new_size)) { + kfree(p); + return NULL; + } + + page = virt_to_page(p); + + if (unlikely(PageCompound(page))) + page = page->first_page; + + new_cache = get_slab(new_size, flags); + + /* + * If new size fits in the current cache, bail out. + */ + if (likely(page->slab == new_cache)) + return (void *)p; + + ret = kmalloc(new_size, flags); + if (ret) { + memcpy(ret, p, min(new_size, ksize(p))); + kfree(p); + } + return ret; +} +EXPORT_SYMBOL(krealloc); + +/******************************************************************** + * Basic setup of slabs + *******************************************************************/ + +void __init kmem_cache_init(void) +{ + int i; + +#ifdef CONFIG_NUMA + /* + * Must first have the slab cache available for the allocations of the + * struct kmalloc_cache_node's. There is special bootstrap code in + * kmem_cache_open for slab_state == DOWN. + */ + create_kmalloc_cache(&kmalloc_caches[0], "kmem_cache_node", + sizeof(struct kmem_cache_node), GFP_KERNEL); +#endif + + /* Able to allocate the per node structures */ + slab_state = PARTIAL; + + /* Caches that are not of the two-to-the-power-of size */ + create_kmalloc_cache(&kmalloc_caches[1], + "kmalloc-96", 96, GFP_KERNEL); + create_kmalloc_cache(&kmalloc_caches[2], + "kmalloc-192", 192, GFP_KERNEL); + + for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++) + create_kmalloc_cache(&kmalloc_caches[i], + "kmalloc", 1 << i, GFP_KERNEL); + + slab_state = UP; + + /* Provide the correct kmalloc names now that the caches are up */ + for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++) + kmalloc_caches[i]. name = + kasprintf(GFP_KERNEL, "kmalloc-%d", 1 << i); + +#ifdef CONFIG_SMP + register_cpu_notifier(&slab_notifier); +#endif + + if (nr_cpu_ids) /* Remove when nr_cpu_ids is fixed upstream ! */ + kmem_size = offsetof(struct kmem_cache, cpu_slab) + + nr_cpu_ids * sizeof(struct page *); + + printk(KERN_INFO "SLUB: Genslabs=%d, HWalign=%d, Order=%d-%d, MinObjects=%d," + " Processors=%d, Nodes=%d\n", + KMALLOC_SHIFT_HIGH, L1_CACHE_BYTES, + slub_min_order, slub_max_order, slub_min_objects, + nr_cpu_ids, nr_node_ids); +} + +/* + * Find a mergeable slab cache + */ +static int slab_unmergeable(struct kmem_cache *s) +{ + if (slub_nomerge || (s->flags & SLUB_NEVER_MERGE)) + return 1; + + if (s->ctor || s->dtor) + return 1; + + return 0; +} + +static struct kmem_cache *find_mergeable(size_t size, + size_t align, unsigned long flags, + void (*ctor)(void *, struct kmem_cache *, unsigned long), + void (*dtor)(void *, struct kmem_cache *, unsigned long)) +{ + struct list_head *h; + + if (slub_nomerge || (flags & SLUB_NEVER_MERGE)) + return NULL; + + if (ctor || dtor) + return NULL; + + size = ALIGN(size, sizeof(void *)); + align = calculate_alignment(flags, align, size); + size = ALIGN(size, align); + + list_for_each(h, &slab_caches) { + struct kmem_cache *s = + container_of(h, struct kmem_cache, list); + + if (slab_unmergeable(s)) + continue; + + if (size > s->size) + continue; + + if (((flags | slub_debug) & SLUB_MERGE_SAME) != + (s->flags & SLUB_MERGE_SAME)) + continue; + /* + * Check if alignment is compatible. + * Courtesy of Adrian Drzewiecki + */ + if ((s->size & ~(align -1)) != s->size) + continue; + + if (s->size - size >= sizeof(void *)) + continue; + + return s; + } + return NULL; +} + +struct kmem_cache *kmem_cache_create(const char *name, size_t size, + size_t align, unsigned long flags, + void (*ctor)(void *, struct kmem_cache *, unsigned long), + void (*dtor)(void *, struct kmem_cache *, unsigned long)) +{ + struct kmem_cache *s; + + down_write(&slub_lock); + s = find_mergeable(size, align, flags, dtor, ctor); + if (s) { + s->refcount++; + /* + * Adjust the object sizes so that we clear + * the complete object on kzalloc. + */ + s->objsize = max(s->objsize, (int)size); + s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *))); + if (sysfs_slab_alias(s, name)) + goto err; + } else { + s = kmalloc(kmem_size, GFP_KERNEL); + if (s && kmem_cache_open(s, GFP_KERNEL, name, + size, align, flags, ctor, dtor)) { + if (sysfs_slab_add(s)) { + kfree(s); + goto err; + } + list_add(&s->list, &slab_caches); + } else + kfree(s); + } + up_write(&slub_lock); + return s; + +err: + up_write(&slub_lock); + if (flags & SLAB_PANIC) + panic("Cannot create slabcache %s\n", name); + else + s = NULL; + return s; +} +EXPORT_SYMBOL(kmem_cache_create); + +void *kmem_cache_zalloc(struct kmem_cache *s, gfp_t flags) +{ + void *x; + + x = kmem_cache_alloc(s, flags); + if (x) + memset(x, 0, s->objsize); + return x; +} +EXPORT_SYMBOL(kmem_cache_zalloc); + +#ifdef CONFIG_SMP +static void for_all_slabs(void (*func)(struct kmem_cache *, int), int cpu) +{ + struct list_head *h; + + down_read(&slub_lock); + list_for_each(h, &slab_caches) { + struct kmem_cache *s = + container_of(h, struct kmem_cache, list); + + func(s, cpu); + } + up_read(&slub_lock); +} + +/* + * Use the cpu notifier to insure that the slab are flushed + * when necessary. + */ +static int __cpuinit slab_cpuup_callback(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + long cpu = (long)hcpu; + + switch (action) { + case CPU_UP_CANCELED: + case CPU_DEAD: + for_all_slabs(__flush_cpu_slab, cpu); + break; + default: + break; + } + return NOTIFY_OK; +} + +static struct notifier_block __cpuinitdata slab_notifier = + { &slab_cpuup_callback, NULL, 0 }; + +#endif + +/*************************************************************** + * Compatiblility definitions + **************************************************************/ + +int kmem_cache_shrink(struct kmem_cache *s) +{ + flush_all(s); + return 0; +} +EXPORT_SYMBOL(kmem_cache_shrink); + +#ifdef CONFIG_NUMA + +/***************************************************************** + * Generic reaper used to support the page allocator + * (the cpu slabs are reaped by a per slab workqueue). + * + * Maybe move this to the page allocator? + ****************************************************************/ + +static DEFINE_PER_CPU(unsigned long, reap_node); + +static void init_reap_node(int cpu) +{ + int node; + + node = next_node(cpu_to_node(cpu), node_online_map); + if (node == MAX_NUMNODES) + node = first_node(node_online_map); + + __get_cpu_var(reap_node) = node; +} + +static void next_reap_node(void) +{ + int node = __get_cpu_var(reap_node); + + /* + * Also drain per cpu pages on remote zones + */ + if (node != numa_node_id()) + drain_node_pages(node); + + node = next_node(node, node_online_map); + if (unlikely(node >= MAX_NUMNODES)) + node = first_node(node_online_map); + __get_cpu_var(reap_node) = node; +} +#else +#define init_reap_node(cpu) do { } while (0) +#define next_reap_node(void) do { } while (0) +#endif + +#define REAPTIMEOUT_CPUC (2*HZ) + +#ifdef CONFIG_SMP +static DEFINE_PER_CPU(struct delayed_work, reap_work); + +static void cache_reap(struct work_struct *unused) +{ + next_reap_node(); + refresh_cpu_vm_stats(smp_processor_id()); + schedule_delayed_work(&__get_cpu_var(reap_work), + REAPTIMEOUT_CPUC); +} + +static void __devinit start_cpu_timer(int cpu) +{ + struct delayed_work *reap_work = &per_cpu(reap_work, cpu); + + /* + * When this gets called from do_initcalls via cpucache_init(), + * init_workqueues() has already run, so keventd will be setup + * at that time. + */ + if (keventd_up() && reap_work->work.func == NULL) { + init_reap_node(cpu); + INIT_DELAYED_WORK(reap_work, cache_reap); + schedule_delayed_work_on(cpu, reap_work, HZ + 3 * cpu); + } +} + +static int __init cpucache_init(void) +{ + int cpu; + + /* + * Register the timers that drain pcp pages and update vm statistics + */ + for_each_online_cpu(cpu) + start_cpu_timer(cpu); + return 0; +} +__initcall(cpucache_init); +#endif + +#ifdef SLUB_RESILIENCY_TEST +static unsigned long validate_slab_cache(struct kmem_cache *s); + +static void resiliency_test(void) +{ + u8 *p; + + printk(KERN_ERR "SLUB resiliency testing\n"); + printk(KERN_ERR "-----------------------\n"); + printk(KERN_ERR "A. Corruption after allocation\n"); + + p = kzalloc(16, GFP_KERNEL); + p[16] = 0x12; + printk(KERN_ERR "\n1. kmalloc-16: Clobber Redzone/next pointer" + " 0x12->0x%p\n\n", p + 16); + + validate_slab_cache(kmalloc_caches + 4); + + /* Hmmm... The next two are dangerous */ + p = kzalloc(32, GFP_KERNEL); + p[32 + sizeof(void *)] = 0x34; + printk(KERN_ERR "\n2. kmalloc-32: Clobber next pointer/next slab" + " 0x34 -> -0x%p\n", p); + printk(KERN_ERR "If allocated object is overwritten then not detectable\n\n"); + + validate_slab_cache(kmalloc_caches + 5); + p = kzalloc(64, GFP_KERNEL); + p += 64 + (get_cycles() & 0xff) * sizeof(void *); + *p = 0x56; + printk(KERN_ERR "\n3. kmalloc-64: corrupting random byte 0x56->0x%p\n", + p); + printk(KERN_ERR "If allocated object is overwritten then not detectable\n\n"); + validate_slab_cache(kmalloc_caches + 6); + + printk(KERN_ERR "\nB. Corruption after free\n"); + p = kzalloc(128, GFP_KERNEL); + kfree(p); + *p = 0x78; + printk(KERN_ERR "1. kmalloc-128: Clobber first word 0x78->0x%p\n\n", p); + validate_slab_cache(kmalloc_caches + 7); + + p = kzalloc(256, GFP_KERNEL); + kfree(p); + p[50] = 0x9a; + printk(KERN_ERR "\n2. kmalloc-256: Clobber 50th byte 0x9a->0x%p\n\n", p); + validate_slab_cache(kmalloc_caches + 8); + + p = kzalloc(512, GFP_KERNEL); + kfree(p); + p[512] = 0xab; + printk(KERN_ERR "\n3. kmalloc-512: Clobber redzone 0xab->0x%p\n\n", p); + validate_slab_cache(kmalloc_caches + 9); +} +#else +static void resiliency_test(void) {}; +#endif + +/* + * These are not as efficient as kmalloc for the non debug case. + * We do not have the page struct available so we have to touch one + * cacheline in struct kmem_cache to check slab flags. + */ +void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, void *caller) +{ + struct kmem_cache *s = get_slab(size, gfpflags); + void *object; + + if (!s) + return NULL; + + object = kmem_cache_alloc(s, gfpflags); + + if (object && (s->flags & SLAB_STORE_USER)) + set_track(s, object, TRACK_ALLOC, caller); + + return object; +} + +void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags, + int node, void *caller) +{ + struct kmem_cache *s = get_slab(size, gfpflags); + void *object; + + if (!s) + return NULL; + + object = kmem_cache_alloc_node(s, gfpflags, node); + + if (object && (s->flags & SLAB_STORE_USER)) + set_track(s, object, TRACK_ALLOC, caller); + + return object; +} + +#ifdef CONFIG_SYSFS + +static unsigned long count_partial(struct kmem_cache_node *n) +{ + unsigned long flags; + unsigned long x = 0; + struct page *page; + + spin_lock_irqsave(&n->list_lock, flags); + list_for_each_entry(page, &n->partial, lru) + x += page->inuse; + spin_unlock_irqrestore(&n->list_lock, flags); + return x; +} + +enum slab_stat_type { + SL_FULL, + SL_PARTIAL, + SL_CPU, + SL_OBJECTS +}; + +#define SO_FULL (1 << SL_FULL) +#define SO_PARTIAL (1 << SL_PARTIAL) +#define SO_CPU (1 << SL_CPU) +#define SO_OBJECTS (1 << SL_OBJECTS) + +static unsigned long slab_objects(struct kmem_cache *s, + char *buf, unsigned long flags) +{ + unsigned long total = 0; + int cpu; + int node; + int x; + unsigned long *nodes; + unsigned long *per_cpu; + + nodes = kzalloc(2 * sizeof(unsigned long) * nr_node_ids, GFP_KERNEL); + per_cpu = nodes + nr_node_ids; + + for_each_possible_cpu(cpu) { + struct page *page = s->cpu_slab[cpu]; + int node; + + if (page) { + node = page_to_nid(page); + if (flags & SO_CPU) { + int x = 0; + + if (flags & SO_OBJECTS) + x = page->inuse; + else + x = 1; + total += x; + nodes[node] += x; + } + per_cpu[node]++; + } + } + + for_each_online_node(node) { + struct kmem_cache_node *n = get_node(s, node); + + if (flags & SO_PARTIAL) { + if (flags & SO_OBJECTS) + x = count_partial(n); + else + x = n->nr_partial; + total += x; + nodes[node] += x; + } + + if (flags & SO_FULL) { + int full_slabs = atomic_read(&n->nr_slabs) + - per_cpu[node] + - n->nr_partial; + + if (flags & SO_OBJECTS) + x = full_slabs * s->objects; + else + x = full_slabs; + total += x; + nodes[node] += x; + } + } + + x = sprintf(buf, "%lu", total); +#ifdef CONFIG_NUMA + for_each_online_node(node) + if (nodes[node]) + x += sprintf(buf + x, " N%d=%lu", + node, nodes[node]); +#endif + kfree(nodes); + return x + sprintf(buf + x, "\n"); +} + +static int any_slab_objects(struct kmem_cache *s) +{ + int node; + int cpu; + + for_each_possible_cpu(cpu) + if (s->cpu_slab[cpu]) + return 1; + + for_each_node(node) { + struct kmem_cache_node *n = get_node(s, node); + + if (n->nr_partial || atomic_read(&n->nr_slabs)) + return 1; + } + return 0; +} + +#define to_slab_attr(n) container_of(n, struct slab_attribute, attr) +#define to_slab(n) container_of(n, struct kmem_cache, kobj); + +struct slab_attribute { + struct attribute attr; + ssize_t (*show)(struct kmem_cache *s, char *buf); + ssize_t (*store)(struct kmem_cache *s, const char *x, size_t count); +}; + +#define SLAB_ATTR_RO(_name) \ + static struct slab_attribute _name##_attr = __ATTR_RO(_name) + +#define SLAB_ATTR(_name) \ + static struct slab_attribute _name##_attr = \ + __ATTR(_name, 0644, _name##_show, _name##_store) + + +static ssize_t slab_size_show(struct kmem_cache *s, char *buf) +{ + return sprintf(buf, "%d\n", s->size); +} +SLAB_ATTR_RO(slab_size); + +static ssize_t align_show(struct kmem_cache *s, char *buf) +{ + return sprintf(buf, "%d\n", s->align); +} +SLAB_ATTR_RO(align); + +static ssize_t object_size_show(struct kmem_cache *s, char *buf) +{ + return sprintf(buf, "%d\n", s->objsize); +} +SLAB_ATTR_RO(object_size); + +static ssize_t objs_per_slab_show(struct kmem_cache *s, char *buf) +{ + return sprintf(buf, "%d\n", s->objects); +} +SLAB_ATTR_RO(objs_per_slab); + +static ssize_t order_show(struct kmem_cache *s, char *buf) +{ + return sprintf(buf, "%d\n", s->order); +} +SLAB_ATTR_RO(order); + +static ssize_t ctor_show(struct kmem_cache *s, char *buf) +{ + if (s->ctor) { + int n = sprint_symbol(buf, (unsigned long)s->ctor); + + return n + sprintf(buf + n, "\n"); + } + return 0; +} +SLAB_ATTR_RO(ctor); + +static ssize_t dtor_show(struct kmem_cache *s, char *buf) +{ + if (s->dtor) { + int n = sprint_symbol(buf, (unsigned long)s->dtor); + + return n + sprintf(buf + n, "\n"); + } + return 0; +} +SLAB_ATTR_RO(dtor); + +static ssize_t aliases_show(struct kmem_cache *s, char *buf) +{ + return sprintf(buf, "%d\n", s->refcount - 1); +} +SLAB_ATTR_RO(aliases); + +static ssize_t slabs_show(struct kmem_cache *s, char *buf) +{ + return slab_objects(s, buf, SO_FULL|SO_PARTIAL|SO_CPU); +} +SLAB_ATTR_RO(slabs); + +static ssize_t partial_show(struct kmem_cache *s, char *buf) +{ + return slab_objects(s, buf, SO_PARTIAL); +} +SLAB_ATTR_RO(partial); + +static ssize_t cpu_slabs_show(struct kmem_cache *s, char *buf) +{ + return slab_objects(s, buf, SO_CPU); +} +SLAB_ATTR_RO(cpu_slabs); + +static ssize_t objects_show(struct kmem_cache *s, char *buf) +{ + return slab_objects(s, buf, SO_FULL|SO_PARTIAL|SO_CPU|SO_OBJECTS); +} +SLAB_ATTR_RO(objects); + +static ssize_t sanity_checks_show(struct kmem_cache *s, char *buf) +{ + return sprintf(buf, "%d\n", !!(s->flags & SLAB_DEBUG_FREE)); +} + +static ssize_t sanity_checks_store(struct kmem_cache *s, + const char *buf, size_t length) +{ + s->flags &= ~SLAB_DEBUG_FREE; + if (buf[0] == '1') + s->flags |= SLAB_DEBUG_FREE; + return length; +} +SLAB_ATTR(sanity_checks); + +static ssize_t trace_show(struct kmem_cache *s, char *buf) +{ + return sprintf(buf, "%d\n", !!(s->flags & SLAB_TRACE)); +} + +static ssize_t trace_store(struct kmem_cache *s, const char *buf, + size_t length) +{ + s->flags &= ~SLAB_TRACE; + if (buf[0] == '1') + s->flags |= SLAB_TRACE; + return length; +} +SLAB_ATTR(trace); + +static ssize_t reclaim_account_show(struct kmem_cache *s, char *buf) +{ + return sprintf(buf, "%d\n", !!(s->flags & SLAB_RECLAIM_ACCOUNT)); +} + +static ssize_t reclaim_account_store(struct kmem_cache *s, + const char *buf, size_t length) +{ + s->flags &= ~SLAB_RECLAIM_ACCOUNT; + if (buf[0] == '1') + s->flags |= SLAB_RECLAIM_ACCOUNT; + return length; +} +SLAB_ATTR(reclaim_account); + +static ssize_t hwcache_align_show(struct kmem_cache *s, char *buf) +{ + return sprintf(buf, "%d\n", !!(s->flags & + (SLAB_HWCACHE_ALIGN|SLAB_MUST_HWCACHE_ALIGN))); +} +SLAB_ATTR_RO(hwcache_align); + +#ifdef CONFIG_ZONE_DMA +static ssize_t cache_dma_show(struct kmem_cache *s, char *buf) +{ + return sprintf(buf, "%d\n", !!(s->flags & SLAB_CACHE_DMA)); +} +SLAB_ATTR_RO(cache_dma); +#endif + +static ssize_t destroy_by_rcu_show(struct kmem_cache *s, char *buf) +{ + return sprintf(buf, "%d\n", !!(s->flags & SLAB_DESTROY_BY_RCU)); +} +SLAB_ATTR_RO(destroy_by_rcu); + +static ssize_t red_zone_show(struct kmem_cache *s, char *buf) +{ + return sprintf(buf, "%d\n", !!(s->flags & SLAB_RED_ZONE)); +} + +static ssize_t red_zone_store(struct kmem_cache *s, + const char *buf, size_t length) +{ + if (any_slab_objects(s)) + return -EBUSY; + + s->flags &= ~SLAB_RED_ZONE; + if (buf[0] == '1') + s->flags |= SLAB_RED_ZONE; + calculate_sizes(s); + return length; +} +SLAB_ATTR(red_zone); + +static ssize_t poison_show(struct kmem_cache *s, char *buf) +{ + return sprintf(buf, "%d\n", !!(s->flags & SLAB_POISON)); +} + +static ssize_t poison_store(struct kmem_cache *s, + const char *buf, size_t length) +{ + if (any_slab_objects(s)) + return -EBUSY; + + s->flags &= ~SLAB_POISON; + if (buf[0] == '1') + s->flags |= SLAB_POISON; + calculate_sizes(s); + return length; +} +SLAB_ATTR(poison); + +static ssize_t store_user_show(struct kmem_cache *s, char *buf) +{ + return sprintf(buf, "%d\n", !!(s->flags & SLAB_STORE_USER)); +} + +static ssize_t store_user_store(struct kmem_cache *s, + const char *buf, size_t length) +{ + if (any_slab_objects(s)) + return -EBUSY; + + s->flags &= ~SLAB_STORE_USER; + if (buf[0] == '1') + s->flags |= SLAB_STORE_USER; + calculate_sizes(s); + return length; +} +SLAB_ATTR(store_user); + +#ifdef CONFIG_NUMA +static ssize_t defrag_ratio_show(struct kmem_cache *s, char *buf) +{ + return sprintf(buf, "%d\n", s->defrag_ratio / 10); +} + +static ssize_t defrag_ratio_store(struct kmem_cache *s, + const char *buf, size_t length) +{ + int n = simple_strtoul(buf, NULL, 10); + + if (n < 100) + s->defrag_ratio = n * 10; + return length; +} +SLAB_ATTR(defrag_ratio); +#endif + +static struct attribute * slab_attrs[] = { + &slab_size_attr.attr, + &object_size_attr.attr, + &objs_per_slab_attr.attr, + &order_attr.attr, + &objects_attr.attr, + &slabs_attr.attr, + &partial_attr.attr, + &cpu_slabs_attr.attr, + &ctor_attr.attr, + &dtor_attr.attr, + &aliases_attr.attr, + &align_attr.attr, + &sanity_checks_attr.attr, + &trace_attr.attr, + &hwcache_align_attr.attr, + &reclaim_account_attr.attr, + &destroy_by_rcu_attr.attr, + &red_zone_attr.attr, + &poison_attr.attr, + &store_user_attr.attr, +#ifdef CONFIG_ZONE_DMA + &cache_dma_attr.attr, +#endif +#ifdef CONFIG_NUMA + &defrag_ratio_attr.attr, +#endif + NULL +}; + +static struct attribute_group slab_attr_group = { + .attrs = slab_attrs, +}; + +static ssize_t slab_attr_show(struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + struct slab_attribute *attribute; + struct kmem_cache *s; + int err; + + attribute = to_slab_attr(attr); + s = to_slab(kobj); + + if (!attribute->show) + return -EIO; + + err = attribute->show(s, buf); + + return err; +} + +static ssize_t slab_attr_store(struct kobject *kobj, + struct attribute *attr, + const char *buf, size_t len) +{ + struct slab_attribute *attribute; + struct kmem_cache *s; + int err; + + attribute = to_slab_attr(attr); + s = to_slab(kobj); + + if (!attribute->store) + return -EIO; + + err = attribute->store(s, buf, len); + + return err; +} + +static struct sysfs_ops slab_sysfs_ops = { + .show = slab_attr_show, + .store = slab_attr_store, +}; + +static struct kobj_type slab_ktype = { + .sysfs_ops = &slab_sysfs_ops, +}; + +static int uevent_filter(struct kset *kset, struct kobject *kobj) +{ + struct kobj_type *ktype = get_ktype(kobj); + + if (ktype == &slab_ktype) + return 1; + return 0; +} + +static struct kset_uevent_ops slab_uevent_ops = { + .filter = uevent_filter, +}; + +decl_subsys(slab, &slab_ktype, &slab_uevent_ops); + +#define ID_STR_LENGTH 64 + +/* Create a unique string id for a slab cache: + * format + * :[flags-]size:[memory address of kmemcache] + */ +static char *create_unique_id(struct kmem_cache *s) +{ + char *name = kmalloc(ID_STR_LENGTH, GFP_KERNEL); + char *p = name; + + BUG_ON(!name); + + *p++ = ':'; + /* + * First flags affecting slabcache operations. We will only + * get here for aliasable slabs so we do not need to support + * too many flags. The flags here must cover all flags that + * are matched during merging to guarantee that the id is + * unique. + */ + if (s->flags & SLAB_CACHE_DMA) + *p++ = 'd'; + if (s->flags & SLAB_RECLAIM_ACCOUNT) + *p++ = 'a'; + if (s->flags & SLAB_DEBUG_FREE) + *p++ = 'F'; + if (p != name + 1) + *p++ = '-'; + p += sprintf(p, "%07d", s->size); + BUG_ON(p > name + ID_STR_LENGTH - 1); + return name; +} + +static int sysfs_slab_add(struct kmem_cache *s) +{ + int err; + const char *name; + int unmergeable; + + if (slab_state < SYSFS) + /* Defer until later */ + return 0; + + unmergeable = slab_unmergeable(s); + if (unmergeable) { + /* + * Slabcache can never be merged so we can use the name proper. + * This is typically the case for debug situations. In that + * case we can catch duplicate names easily. + */ + sysfs_remove_link(&slab_subsys.kset.kobj, s->name); + name = s->name; + } else { + /* + * Create a unique name for the slab as a target + * for the symlinks. + */ + name = create_unique_id(s); + } + + kobj_set_kset_s(s, slab_subsys); + kobject_set_name(&s->kobj, name); + kobject_init(&s->kobj); + err = kobject_add(&s->kobj); + if (err) + return err; + + err = sysfs_create_group(&s->kobj, &slab_attr_group); + if (err) + return err; + kobject_uevent(&s->kobj, KOBJ_ADD); + if (!unmergeable) { + /* Setup first alias */ + sysfs_slab_alias(s, s->name); + kfree(name); + } + return 0; +} + +static void sysfs_slab_remove(struct kmem_cache *s) +{ + kobject_uevent(&s->kobj, KOBJ_REMOVE); + kobject_del(&s->kobj); +} + +/* + * Need to buffer aliases during bootup until sysfs becomes + * available lest we loose that information. + */ +struct saved_alias { + struct kmem_cache *s; + const char *name; + struct saved_alias *next; +}; + +struct saved_alias *alias_list; + +static int sysfs_slab_alias(struct kmem_cache *s, const char *name) +{ + struct saved_alias *al; + + if (slab_state == SYSFS) { + /* + * If we have a leftover link then remove it. + */ + sysfs_remove_link(&slab_subsys.kset.kobj, name); + return sysfs_create_link(&slab_subsys.kset.kobj, + &s->kobj, name); + } + + al = kmalloc(sizeof(struct saved_alias), GFP_KERNEL); + if (!al) + return -ENOMEM; + + al->s = s; + al->name = name; + al->next = alias_list; + alias_list = al; + return 0; +} + +static int __init slab_sysfs_init(void) +{ + int err; + + err = subsystem_register(&slab_subsys); + if (err) { + printk(KERN_ERR "Cannot register slab subsystem.\n"); + return -ENOSYS; + } + + finish_bootstrap(); + + while (alias_list) { + struct saved_alias *al = alias_list; + + alias_list = alias_list->next; + err = sysfs_slab_alias(al->s, al->name); + BUG_ON(err); + kfree(al); + } + + resiliency_test(); + return 0; +} + +__initcall(slab_sysfs_init); +#else +__initcall(finish_bootstrap); +#endif -- cgit v1.2.3-59-g8ed1b From 30520864839dc796fd314812e7036e754880b47d Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Sun, 6 May 2007 14:49:38 -0700 Subject: PowerPC: Disable SLUB for configurations in which slab page structs are modified PowerPC uses the slab allocator to manage the lowest level of the page table. In high cpu configurations we also use the page struct to split the page table lock. Disallow the selection of SLUB for that case. Signed-off-by: Christoph Lameter Cc: Hugh Dickins Cc: Paul Mackerras Acked-by: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/Kconfig | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index a54a9a2e36f3..8de5f9ff4ade 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -117,6 +117,19 @@ config GENERIC_BUG default y depends on BUG +# +# Powerpc uses the slab allocator to manage its ptes and the +# page structs of ptes are used for splitting the page table +# lock for configurations supporting more than SPLIT_PTLOCK_CPUS. +# +# In that special configuration the page structs of slabs are modified. +# This setting disables the selection of SLUB as a slab allocator. +# +config ARCH_USES_SLAB_PAGE_STRUCT + bool + default y + depends on SPLIT_PTLOCK_CPUS <= NR_CPUS + config DEFAULT_UIMAGE bool help -- cgit v1.2.3-59-g8ed1b From d85f33855c303acfa87fa457157cef755b6087df Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Sun, 6 May 2007 14:49:39 -0700 Subject: Make page->private usable in compound pages If we add a new flag so that we can distinguish between the first page and the tail pages then we can avoid to use page->private in the first page. page->private == page for the first page, so there is no real information in there. Freeing up page->private makes the use of compound pages more transparent. They become more usable like real pages. Right now we have to be careful f.e. if we are going beyond PAGE_SIZE allocations in the slab on i386 because we can then no longer use the private field. This is one of the issues that cause us not to support debugging for page size slabs in SLAB. Having page->private available for SLUB would allow more meta information in the page struct. I can probably avoid the 16 bit ints that I have in there right now. Also if page->private is available then a compound page may be equipped with buffer heads. This may free up the way for filesystems to support larger blocks than page size. We add PageTail as an alias of PageReclaim. Compound pages cannot currently be reclaimed. Because of the alias one needs to check PageCompound first. The RFC for the this approach was discussed at http://marc.info/?t=117574302800001&r=1&w=2 [nacc@us.ibm.com: fix hugetlbfs] Signed-off-by: Christoph Lameter Signed-off-by: Nishanth Aravamudan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/mm/init.c | 2 +- fs/hugetlbfs/inode.c | 2 +- include/linux/mm.h | 33 ++++++++++++++++++++++++++++----- include/linux/page-flags.h | 14 ++++++++++++++ mm/internal.h | 2 +- mm/page_alloc.c | 29 ++++++++++++++++++++--------- mm/slab.c | 6 ++---- mm/slub.c | 19 ++++--------------- mm/swap.c | 2 +- 9 files changed, 72 insertions(+), 37 deletions(-) (limited to 'arch') diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 4f36987eea72..2da841110727 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -121,7 +121,7 @@ lazy_mmu_prot_update (pte_t pte) return; /* i-cache is already coherent with d-cache */ if (PageCompound(page)) { - order = (unsigned long) (page[1].lru.prev); + order = compound_order(page); flush_icache_range(addr, addr + (1UL << order << PAGE_SHIFT)); } else diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 9ba71b252f3e..8e1b7825e2f3 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -450,7 +450,7 @@ static int hugetlbfs_symlink(struct inode *dir, */ static int hugetlbfs_set_page_dirty(struct page *page) { - struct page *head = (struct page *)page_private(page); + struct page *head = compound_head(page); SetPageDirty(head); return 0; diff --git a/include/linux/mm.h b/include/linux/mm.h index c95d96ebd5ad..8c149fa4491d 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -267,17 +267,28 @@ static inline int get_page_unless_zero(struct page *page) return atomic_inc_not_zero(&page->_count); } +static inline struct page *compound_head(struct page *page) +{ + /* + * We could avoid the PageCompound(page) check if + * we would not overload PageTail(). + * + * This check has to be done in several performance critical + * paths of the slab etc. IMHO PageTail deserves its own flag. + */ + if (unlikely(PageCompound(page) && PageTail(page))) + return page->first_page; + return page; +} + static inline int page_count(struct page *page) { - if (unlikely(PageCompound(page))) - page = (struct page *)page_private(page); - return atomic_read(&page->_count); + return atomic_read(&compound_head(page)->_count); } static inline void get_page(struct page *page) { - if (unlikely(PageCompound(page))) - page = (struct page *)page_private(page); + page = compound_head(page); VM_BUG_ON(atomic_read(&page->_count) == 0); atomic_inc(&page->_count); } @@ -314,6 +325,18 @@ static inline compound_page_dtor *get_compound_page_dtor(struct page *page) return (compound_page_dtor *)page[1].lru.next; } +static inline int compound_order(struct page *page) +{ + if (!PageCompound(page) || PageTail(page)) + return 0; + return (unsigned long)page[1].lru.prev; +} + +static inline void set_compound_order(struct page *page, unsigned long order) +{ + page[1].lru.prev = (void *)order; +} + /* * Multiple processes may "see" the same page. E.g. for untouched * mappings of /dev/null, all processes see the same page full of diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 96326594e55d..a1e143634946 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -94,6 +94,12 @@ /* PG_owner_priv_1 users should have descriptive aliases */ #define PG_checked PG_owner_priv_1 /* Used by some filesystems */ +/* + * Marks tail portion of a compound page. We currently do not reclaim + * compound pages so we can reuse a flag only used for reclaim here. + */ +#define PG_tail PG_reclaim + #if (BITS_PER_LONG > 32) /* * 64-bit-only flags build down from bit 31 @@ -241,6 +247,14 @@ static inline void SetPageUptodate(struct page *page) #define __SetPageCompound(page) __set_bit(PG_compound, &(page)->flags) #define __ClearPageCompound(page) __clear_bit(PG_compound, &(page)->flags) +/* + * Note: PG_tail is an alias of another page flag. The result of PageTail() + * is only valid if PageCompound(page) is true. + */ +#define PageTail(page) test_bit(PG_tail, &(page)->flags) +#define __SetPageTail(page) __set_bit(PG_tail, &(page)->flags) +#define __ClearPageTail(page) __clear_bit(PG_tail, &(page)->flags) + #ifdef CONFIG_SWAP #define PageSwapCache(page) test_bit(PG_swapcache, &(page)->flags) #define SetPageSwapCache(page) set_bit(PG_swapcache, &(page)->flags) diff --git a/mm/internal.h b/mm/internal.h index d527b80b292f..a3110c02aea7 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -24,7 +24,7 @@ static inline void set_page_count(struct page *page, int v) */ static inline void set_page_refcounted(struct page *page) { - VM_BUG_ON(PageCompound(page) && page_private(page) != (unsigned long)page); + VM_BUG_ON(PageCompound(page) && PageTail(page)); VM_BUG_ON(atomic_read(&page->_count)); set_page_count(page, 1); } diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 542fc088ff50..fc241fe295ab 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -225,7 +225,7 @@ static void bad_page(struct page *page) static void free_compound_page(struct page *page) { - __free_pages_ok(page, (unsigned long)page[1].lru.prev); + __free_pages_ok(page, compound_order(page)); } static void prep_compound_page(struct page *page, unsigned long order) @@ -234,12 +234,14 @@ static void prep_compound_page(struct page *page, unsigned long order) int nr_pages = 1 << order; set_compound_page_dtor(page, free_compound_page); - page[1].lru.prev = (void *)order; - for (i = 0; i < nr_pages; i++) { + set_compound_order(page, order); + __SetPageCompound(page); + for (i = 1; i < nr_pages; i++) { struct page *p = page + i; + __SetPageTail(p); __SetPageCompound(p); - set_page_private(p, (unsigned long)page); + p->first_page = page; } } @@ -248,15 +250,19 @@ static void destroy_compound_page(struct page *page, unsigned long order) int i; int nr_pages = 1 << order; - if (unlikely((unsigned long)page[1].lru.prev != order)) + if (unlikely(compound_order(page) != order)) bad_page(page); - for (i = 0; i < nr_pages; i++) { + if (unlikely(!PageCompound(page))) + bad_page(page); + __ClearPageCompound(page); + for (i = 1; i < nr_pages; i++) { struct page *p = page + i; - if (unlikely(!PageCompound(p) | - (page_private(p) != (unsigned long)page))) + if (unlikely(!PageCompound(p) | !PageTail(p) | + (p->first_page != page))) bad_page(page); + __ClearPageTail(p); __ClearPageCompound(p); } } @@ -429,13 +435,18 @@ static inline int free_pages_check(struct page *page) 1 << PG_private | 1 << PG_locked | 1 << PG_active | - 1 << PG_reclaim | 1 << PG_slab | 1 << PG_swapcache | 1 << PG_writeback | 1 << PG_reserved | 1 << PG_buddy )))) bad_page(page); + /* + * PageReclaim == PageTail. It is only an error + * for PageReclaim to be set if PageCompound is clear. + */ + if (unlikely(!PageCompound(page) && PageReclaim(page))) + bad_page(page); if (PageDirty(page)) __ClearPageDirty(page); /* diff --git a/mm/slab.c b/mm/slab.c index 9cd01fa60004..f4b2e22b5c61 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -602,8 +602,7 @@ static inline void page_set_cache(struct page *page, struct kmem_cache *cache) static inline struct kmem_cache *page_get_cache(struct page *page) { - if (unlikely(PageCompound(page))) - page = (struct page *)page_private(page); + page = compound_head(page); BUG_ON(!PageSlab(page)); return (struct kmem_cache *)page->lru.next; } @@ -615,8 +614,7 @@ static inline void page_set_slab(struct page *page, struct slab *slab) static inline struct slab *page_get_slab(struct page *page) { - if (unlikely(PageCompound(page))) - page = (struct page *)page_private(page); + page = compound_head(page); BUG_ON(!PageSlab(page)); return (struct slab *)page->lru.prev; } diff --git a/mm/slub.c b/mm/slub.c index 9d52cce7c999..8fa1c6e937f5 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1325,9 +1325,7 @@ void kmem_cache_free(struct kmem_cache *s, void *x) page = virt_to_page(x); - if (unlikely(PageCompound(page))) - page = page->first_page; - + page = compound_head(page); if (unlikely(PageError(page) && (s->flags & SLAB_STORE_USER))) set_tracking(s, x, TRACK_FREE); @@ -1338,10 +1336,7 @@ EXPORT_SYMBOL(kmem_cache_free); /* Figure out on which slab object the object resides */ static struct page *get_object_page(const void *x) { - struct page *page = virt_to_page(x); - - if (unlikely(PageCompound(page))) - page = page->first_page; + struct page *page = compound_head(virt_to_page(x)); if (!PageSlab(page)) return NULL; @@ -2081,10 +2076,7 @@ void kfree(const void *x) if (!x) return; - page = virt_to_page(x); - - if (unlikely(PageCompound(page))) - page = page->first_page; + page = compound_head(virt_to_page(x)); s = page->slab; @@ -2120,10 +2112,7 @@ void *krealloc(const void *p, size_t new_size, gfp_t flags) return NULL; } - page = virt_to_page(p); - - if (unlikely(PageCompound(page))) - page = page->first_page; + page = compound_head(virt_to_page(p)); new_cache = get_slab(new_size, flags); diff --git a/mm/swap.c b/mm/swap.c index 2ed7be39795e..218c52a24a21 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -55,7 +55,7 @@ static void fastcall __page_cache_release(struct page *page) static void put_compound_page(struct page *page) { - page = (struct page *)page_private(page); + page = compound_head(page); if (put_page_testzero(page)) { compound_page_dtor *dtor; -- cgit v1.2.3-59-g8ed1b From 3a2cba993b0a04f258ab75e15cf3f08ada268dbd Mon Sep 17 00:00:00 2001 From: David Miller Date: Sun, 6 May 2007 14:49:51 -0700 Subject: Quicklist support for sparc64 I ported this to sparc64 as per the patch below, tested on UP SunBlade1500 and 24 cpu Niagara T1000. Signed-off-by: David S. Miller Signed-off-by: Christoph Lameter Cc: "David S. Miller" Cc: Andi Kleen Cc: "Luck, Tony" Cc: William Lee Irwin III Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc64/Kconfig | 4 ++++ arch/sparc64/mm/init.c | 24 ------------------------ arch/sparc64/mm/tsb.c | 2 +- include/asm-sparc64/pgalloc.h | 26 ++++++++++++++------------ 4 files changed, 19 insertions(+), 37 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index be9e10b94ef8..ad8d6b256a70 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -34,6 +34,10 @@ config MMU bool default y +config QUICKLIST + bool + default y + config STACKTRACE_SUPPORT bool default y diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index cafadcbcdf38..d7004eaf1c8e 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -164,30 +164,6 @@ unsigned long sparc64_kern_sec_context __read_mostly; int bigkernel = 0; -struct kmem_cache *pgtable_cache __read_mostly; - -static void zero_ctor(void *addr, struct kmem_cache *cache, unsigned long flags) -{ - clear_page(addr); -} - -extern void tsb_cache_init(void); - -void pgtable_cache_init(void) -{ - pgtable_cache = kmem_cache_create("pgtable_cache", - PAGE_SIZE, PAGE_SIZE, - SLAB_HWCACHE_ALIGN | - SLAB_MUST_HWCACHE_ALIGN, - zero_ctor, - NULL); - if (!pgtable_cache) { - prom_printf("Could not create pgtable_cache\n"); - prom_halt(); - } - tsb_cache_init(); -} - #ifdef CONFIG_DEBUG_DCFLUSH atomic_t dcpage_flushes = ATOMIC_INIT(0); #ifdef CONFIG_SMP diff --git a/arch/sparc64/mm/tsb.c b/arch/sparc64/mm/tsb.c index 236d02f41a01..57eb3025537a 100644 --- a/arch/sparc64/mm/tsb.c +++ b/arch/sparc64/mm/tsb.c @@ -252,7 +252,7 @@ static const char *tsb_cache_names[8] = { "tsb_1MB", }; -void __init tsb_cache_init(void) +void __init pgtable_cache_init(void) { unsigned long i; diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h index 5891ff7ba760..5d66b858a965 100644 --- a/include/asm-sparc64/pgalloc.h +++ b/include/asm-sparc64/pgalloc.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -13,52 +14,50 @@ #include /* Page table allocation/freeing. */ -extern struct kmem_cache *pgtable_cache; static inline pgd_t *pgd_alloc(struct mm_struct *mm) { - return kmem_cache_alloc(pgtable_cache, GFP_KERNEL); + return quicklist_alloc(0, GFP_KERNEL, NULL); } static inline void pgd_free(pgd_t *pgd) { - kmem_cache_free(pgtable_cache, pgd); + quicklist_free(0, NULL, pgd); } #define pud_populate(MM, PUD, PMD) pud_set(PUD, PMD) static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) { - return kmem_cache_alloc(pgtable_cache, - GFP_KERNEL|__GFP_REPEAT); + return quicklist_alloc(0, GFP_KERNEL, NULL); } static inline void pmd_free(pmd_t *pmd) { - kmem_cache_free(pgtable_cache, pmd); + quicklist_free(0, NULL, pmd); } static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - return kmem_cache_alloc(pgtable_cache, - GFP_KERNEL|__GFP_REPEAT); + return quicklist_alloc(0, GFP_KERNEL, NULL); } static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) { - return virt_to_page(pte_alloc_one_kernel(mm, address)); + void *pg = quicklist_alloc(0, GFP_KERNEL, NULL); + return pg ? virt_to_page(pg) : NULL; } static inline void pte_free_kernel(pte_t *pte) { - kmem_cache_free(pgtable_cache, pte); + quicklist_free(0, NULL, pte); } static inline void pte_free(struct page *ptepage) { - pte_free_kernel(page_address(ptepage)); + quicklist_free_page(0, NULL, ptepage); } @@ -66,6 +65,9 @@ static inline void pte_free(struct page *ptepage) #define pmd_populate(MM,PMD,PTE_PAGE) \ pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE)) -#define check_pgt_cache() do { } while (0) +static inline void check_pgt_cache(void) +{ + quicklist_trim(0, NULL, 25, 16); +} #endif /* _SPARC64_PGALLOC_H */ -- cgit v1.2.3-59-g8ed1b From 5af60839909b8e3b28ca7cd7912fa0b23475617f Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Sun, 6 May 2007 14:49:56 -0700 Subject: slab allocators: Remove obsolete SLAB_MUST_HWCACHE_ALIGN This patch was recently posted to lkml and acked by Pekka. The flag SLAB_MUST_HWCACHE_ALIGN is 1. Never checked by SLAB at all. 2. A duplicate of SLAB_HWCACHE_ALIGN for SLUB 3. Fulfills the role of SLAB_HWCACHE_ALIGN for SLOB. The only remaining use is in sparc64 and ppc64 and their use there reflects some earlier role that the slab flag once may have had. If its specified then SLAB_HWCACHE_ALIGN is also specified. The flag is confusing, inconsistent and has no purpose. Remove it. Acked-by: Pekka Enberg Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/mm/hugetlbpage.c | 3 +-- arch/powerpc/mm/init_64.c | 3 +-- arch/sparc64/mm/tsb.c | 3 +-- include/linux/slab.h | 1 - mm/slab.c | 4 ++-- mm/slob.c | 4 ++-- mm/slub.c | 5 ++--- 7 files changed, 9 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 8508f973d9cc..c8814177b716 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -1057,8 +1057,7 @@ static int __init hugetlbpage_init(void) huge_pgtable_cache = kmem_cache_create("hugepte_cache", HUGEPTE_TABLE_SIZE, HUGEPTE_TABLE_SIZE, - SLAB_HWCACHE_ALIGN | - SLAB_MUST_HWCACHE_ALIGN, + SLAB_HWCACHE_ALIGN, zero_ctor, NULL); if (! huge_pgtable_cache) panic("hugetlbpage_init(): could not create hugepte cache\n"); diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index d12a87ec5ae9..5a7750147b7d 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -183,8 +183,7 @@ void pgtable_cache_init(void) "for size: %08x...\n", name, i, size); pgtable_cache[i] = kmem_cache_create(name, size, size, - SLAB_HWCACHE_ALIGN | - SLAB_MUST_HWCACHE_ALIGN, + SLAB_HWCACHE_ALIGN, zero_ctor, NULL); if (! pgtable_cache[i]) diff --git a/arch/sparc64/mm/tsb.c b/arch/sparc64/mm/tsb.c index 57eb3025537a..4be378d9a382 100644 --- a/arch/sparc64/mm/tsb.c +++ b/arch/sparc64/mm/tsb.c @@ -262,8 +262,7 @@ void __init pgtable_cache_init(void) tsb_caches[i] = kmem_cache_create(name, size, size, - SLAB_HWCACHE_ALIGN | - SLAB_MUST_HWCACHE_ALIGN, + SLAB_HWCACHE_ALIGN, NULL, NULL); if (!tsb_caches[i]) { prom_printf("Could not create %s cache\n", name); diff --git a/include/linux/slab.h b/include/linux/slab.h index 67425c277e12..a9befa50d3e3 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -26,7 +26,6 @@ typedef struct kmem_cache kmem_cache_t __deprecated; #define SLAB_POISON 0x00000800UL /* DEBUG: Poison objects */ #define SLAB_HWCACHE_ALIGN 0x00002000UL /* Align objs on cache lines */ #define SLAB_CACHE_DMA 0x00004000UL /* Use GFP_DMA memory */ -#define SLAB_MUST_HWCACHE_ALIGN 0x00008000UL /* Force alignment even if debuggin is active */ #define SLAB_STORE_USER 0x00010000UL /* DEBUG: Store the last owner for bug hunting */ #define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* Objects are reclaimable */ #define SLAB_PANIC 0x00040000UL /* Panic if kmem_cache_create() fails */ diff --git a/mm/slab.c b/mm/slab.c index 997c3b2f50c9..583644f6ae11 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -175,12 +175,12 @@ # define CREATE_MASK (SLAB_DEBUG_INITIAL | SLAB_RED_ZONE | \ SLAB_POISON | SLAB_HWCACHE_ALIGN | \ SLAB_CACHE_DMA | \ - SLAB_MUST_HWCACHE_ALIGN | SLAB_STORE_USER | \ + SLAB_STORE_USER | \ SLAB_RECLAIM_ACCOUNT | SLAB_PANIC | \ SLAB_DESTROY_BY_RCU | SLAB_MEM_SPREAD) #else # define CREATE_MASK (SLAB_HWCACHE_ALIGN | \ - SLAB_CACHE_DMA | SLAB_MUST_HWCACHE_ALIGN | \ + SLAB_CACHE_DMA | \ SLAB_RECLAIM_ACCOUNT | SLAB_PANIC | \ SLAB_DESTROY_BY_RCU | SLAB_MEM_SPREAD) #endif diff --git a/mm/slob.c b/mm/slob.c index 77786be032e0..c9401a7eaa5f 100644 --- a/mm/slob.c +++ b/mm/slob.c @@ -21,7 +21,7 @@ * * SLAB is emulated on top of SLOB by simply calling constructors and * destructors for every SLAB allocation. Objects are returned with - * the 8-byte alignment unless the SLAB_MUST_HWCACHE_ALIGN flag is + * the 8-byte alignment unless the SLAB_HWCACHE_ALIGN flag is * set, in which case the low-level allocator will fragment blocks to * create the proper alignment. Again, objects of page-size or greater * are allocated by calling __get_free_pages. As SLAB objects know @@ -295,7 +295,7 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, c->ctor = ctor; c->dtor = dtor; /* ignore alignment unless it's forced */ - c->align = (flags & SLAB_MUST_HWCACHE_ALIGN) ? SLOB_ALIGN : 0; + c->align = (flags & SLAB_HWCACHE_ALIGN) ? SLOB_ALIGN : 0; if (c->align < align) c->align = align; } else if (flags & SLAB_PANIC) diff --git a/mm/slub.c b/mm/slub.c index 3904002bdb35..79940e98e5e6 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1496,7 +1496,7 @@ static unsigned long calculate_alignment(unsigned long flags, * specified alignment though. If that is greater * then use it. */ - if ((flags & (SLAB_MUST_HWCACHE_ALIGN | SLAB_HWCACHE_ALIGN)) && + if ((flags & SLAB_HWCACHE_ALIGN) && size > L1_CACHE_BYTES / 2) return max_t(unsigned long, align, L1_CACHE_BYTES); @@ -3142,8 +3142,7 @@ SLAB_ATTR(reclaim_account); static ssize_t hwcache_align_show(struct kmem_cache *s, char *buf) { - return sprintf(buf, "%d\n", !!(s->flags & - (SLAB_HWCACHE_ALIGN|SLAB_MUST_HWCACHE_ALIGN))); + return sprintf(buf, "%d\n", !!(s->flags & SLAB_HWCACHE_ALIGN)); } SLAB_ATTR_RO(hwcache_align); -- cgit v1.2.3-59-g8ed1b From f0f3980b21508bd573eff1746d469436f50a903d Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Sun, 6 May 2007 14:49:58 -0700 Subject: slab allocators: remove multiple alignment specifications It is not necessary to tell the slab allocators to align to a cacheline if an explicit alignment was already specified. It is rather confusing to specify multiple alignments. Make sure that the call sites only use one form of alignment. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/mm/hugetlbpage.c | 2 +- arch/powerpc/mm/init_64.c | 2 +- arch/sparc64/mm/tsb.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index c8814177b716..d0ec887f05a2 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -1057,7 +1057,7 @@ static int __init hugetlbpage_init(void) huge_pgtable_cache = kmem_cache_create("hugepte_cache", HUGEPTE_TABLE_SIZE, HUGEPTE_TABLE_SIZE, - SLAB_HWCACHE_ALIGN, + 0, zero_ctor, NULL); if (! huge_pgtable_cache) panic("hugetlbpage_init(): could not create hugepte cache\n"); diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 5a7750147b7d..4416d5140c53 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -183,7 +183,7 @@ void pgtable_cache_init(void) "for size: %08x...\n", name, i, size); pgtable_cache[i] = kmem_cache_create(name, size, size, - SLAB_HWCACHE_ALIGN, + 0, zero_ctor, NULL); if (! pgtable_cache[i]) diff --git a/arch/sparc64/mm/tsb.c b/arch/sparc64/mm/tsb.c index 4be378d9a382..8eb8a7c76ec9 100644 --- a/arch/sparc64/mm/tsb.c +++ b/arch/sparc64/mm/tsb.c @@ -262,7 +262,7 @@ void __init pgtable_cache_init(void) tsb_caches[i] = kmem_cache_create(name, size, size, - SLAB_HWCACHE_ALIGN, + 0, NULL, NULL); if (!tsb_caches[i]) { prom_printf("Could not create %s cache\n", name); -- cgit v1.2.3-59-g8ed1b From d506a7725114aaddbf982fd18621b3e0e5c27f1b Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 6 May 2007 14:50:02 -0700 Subject: get_unmapped_area handles MAP_FIXED on powerpc The current get_unmapped_area code calls the f_ops->get_unmapped_area or the arch one (via the mm) only when MAP_FIXED is not passed. That makes it impossible for archs to impose proper constraints on regions of the virtual address space. To work around that, get_unmapped_area() then calls some hugetlbfs specific hacks. This cause several problems, among others: - It makes it impossible for a driver or filesystem to do the same thing that hugetlbfs does (for example, to allow a driver to use larger page sizes to map external hardware) if that requires applying a constraint on the addresses (constraining that mapping in certain regions and other mappings out of those regions). - Some archs like arm, mips, sparc, sparc64, sh and sh64 already want MAP_FIXED to be passed down in order to deal with aliasing issues. The code is there to handle it... but is never called. This series of patches moves the logic to handle MAP_FIXED down to the various arch/driver get_unmapped_area() implementations, and then changes the generic code to always call them. The hugetlbfs hacks then disappear from the generic code. Since I need to do some special 64K pages mappings for SPEs on cell, I need to work around the first problem at least. I have further patches thus implementing a "slices" layer that handles multiple page sizes through slices of the address space for use by hugetlbfs, the SPE code, and possibly others, but it requires that serie of patches first/ There is still a potential (but not practical) issue due to the fact that filesystems/drivers implemeting g_u_a will effectively bypass all arch checks. This is not an issue in practice as the only filesystems/drivers using that hook are doing so for arch specific purposes in the first place. There is also a problem with mremap that will completely bypass all arch checks. I'll try to address that separately, I'm not 100% certain yet how, possibly by making it not work when the vma has a file whose f_ops has a get_unmapped_area callback, and by making it use is_hugepage_only_range() before expanding into a new area. Also, I want to turn is_hugepage_only_range() into a more generic is_normal_page_range() as that's really what it will end up meaning when used in stack grow, brk grow and mremap. None of the above "issues" however are introduced by this patch, they are already there, so I think the patch can go ini for 2.6.22. This patch: Handle MAP_FIXED in powerpc's arch_get_unmapped_area() in all 3 implementations of it. Signed-off-by: Benjamin Herrenschmidt Acked-by: William Irwin Cc: Paul Mackerras Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Russell King Cc: David Howells Cc: Andi Kleen Cc: "Luck, Tony" Cc: Kyle McMartin Cc: Grant Grundler Cc: Matthew Wilcox Cc: "David S. Miller" Cc: Adam Litke Cc: David Gibson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/mm/hugetlbpage.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index d0ec887f05a2..1f07f70ac89f 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -566,6 +566,13 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, if (len > TASK_SIZE) return -ENOMEM; + /* handle fixed mapping: prevent overlap with huge pages */ + if (flags & MAP_FIXED) { + if (is_hugepage_only_range(mm, addr, len)) + return -EINVAL; + return addr; + } + if (addr) { addr = PAGE_ALIGN(addr); vma = find_vma(mm, addr); @@ -641,6 +648,13 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, if (len > TASK_SIZE) return -ENOMEM; + /* handle fixed mapping: prevent overlap with huge pages */ + if (flags & MAP_FIXED) { + if (is_hugepage_only_range(mm, addr, len)) + return -EINVAL; + return addr; + } + /* dont allow allocations above current base */ if (mm->free_area_cache > base) mm->free_area_cache = base; @@ -823,6 +837,13 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, /* Paranoia, caller should have dealt with this */ BUG_ON((addr + len) < addr); + /* Handle MAP_FIXED */ + if (flags & MAP_FIXED) { + if (prepare_hugepage_range(addr, len, pgoff)) + return -EINVAL; + return addr; + } + if (test_thread_flag(TIF_32BIT)) { curareas = current->mm->context.low_htlb_areas; -- cgit v1.2.3-59-g8ed1b From 4b87b3b2eb1fa2d6ac0a1400ad5fb8f4b7cbfc09 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 6 May 2007 14:50:06 -0700 Subject: get_unmapped_area handles MAP_FIXED on alpha Handle MAP_FIXED in alpha's arch_get_unmapped_area(), simple case, just return the address as passed in Signed-off-by: Benjamin Herrenschmidt Cc: Richard Henderson Cc: Ivan Kokshaysky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/osf_sys.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index be133f1f75a4..67ae41dcb6fa 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -1267,6 +1267,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, if (len > limit) return -ENOMEM; + if (flags & MAP_FIXED) + return addr; + /* First, see if the given suggestion fits. The OSF/1 loader (/sbin/loader) relies on us returning an -- cgit v1.2.3-59-g8ed1b From acec0ac0a87ca821f9d204780c2d1aa0509a6346 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 6 May 2007 14:50:07 -0700 Subject: get_unmapped_area handles MAP_FIXED on arm ARM already had a case for MAP_FIXED in arch_get_unmapped_area() though it was not called before. Fix the comment to reflect that it will now be called. Signed-off-by: Benjamin Herrenschmidt Acked-by: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/mm/mmap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index b0b5f4694070..2c4c2422cd1e 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -49,8 +49,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, #endif /* - * We should enforce the MAP_FIXED case. However, currently - * the generic kernel code doesn't allow us to handle this. + * We enforce the MAP_FIXED case. */ if (flags & MAP_FIXED) { if (aliasing && flags & MAP_SHARED && addr & (SHMLBA - 1)) -- cgit v1.2.3-59-g8ed1b From 2fd3bebaad9da3b3b99c46a3389099424bf7ee35 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 6 May 2007 14:50:07 -0700 Subject: get_unmapped_area handles MAP_FIXED on frv Handle MAP_FIXED in arch_get_unmapped_area on frv. Trivial case, just return the address. Signed-off-by: Benjamin Herrenschmidt Cc: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/frv/mm/elf-fdpic.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/frv/mm/elf-fdpic.c b/arch/frv/mm/elf-fdpic.c index 9477ccce070e..cac2c01a3a56 100644 --- a/arch/frv/mm/elf-fdpic.c +++ b/arch/frv/mm/elf-fdpic.c @@ -64,6 +64,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi if (len > TASK_SIZE) return -ENOMEM; + /* handle MAP_FIXED */ + if (flags & MAP_FIXED) + return addr; + /* only honour a hint if we're not going to clobber something doing so */ if (addr) { addr = PAGE_ALIGN(addr); -- cgit v1.2.3-59-g8ed1b From 5a8130f2b186ac91190d1dcea875d66d08e6a1de Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 6 May 2007 14:50:08 -0700 Subject: get_unmapped_area handles MAP_FIXED on i386 Handle MAP_FIXED in i386 hugetlb_get_unmapped_area(), just call prepare_hugepage_range. Signed-off-by: Benjamin Herrenschmidt Acked-by: William Irwin Cc: Andi Kleen Cc: Adam Litke Cc: David Gibson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/mm/hugetlbpage.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c index 34728e4afe48..6272a4fd9e7c 100644 --- a/arch/i386/mm/hugetlbpage.c +++ b/arch/i386/mm/hugetlbpage.c @@ -367,6 +367,12 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, if (len > TASK_SIZE) return -ENOMEM; + if (flags & MAP_FIXED) { + if (prepare_hugepage_range(addr, len, pgoff)) + return -EINVAL; + return addr; + } + if (addr) { addr = ALIGN(addr, HPAGE_SIZE); vma = find_vma(mm, addr); -- cgit v1.2.3-59-g8ed1b From afa37394d6bfc91907b0e08c902d36d848232b99 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 6 May 2007 14:50:09 -0700 Subject: get_unmapped_area handles MAP_FIXED on ia64 Handle MAP_FIXED in ia64 arch_get_unmapped_area and hugetlb_get_unmapped_area(), just call prepare_hugepage_range in the later and is_hugepage_only_range() in the former. Signed-off-by: Benjamin Herrenschmidt Acked-by: William Irwin Cc: "Luck, Tony" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/kernel/sys_ia64.c | 7 +++++++ arch/ia64/mm/hugetlbpage.c | 8 ++++++++ 2 files changed, 15 insertions(+) (limited to 'arch') diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index 9ef62a3fbfad..2fcaa2051aa3 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c @@ -33,6 +33,13 @@ arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len if (len > RGN_MAP_LIMIT) return -ENOMEM; + /* handle fixed mapping: prevent overlap with huge pages */ + if (flags & MAP_FIXED) { + if (is_hugepage_only_range(mm, addr, len)) + return -EINVAL; + return addr; + } + #ifdef CONFIG_HUGETLB_PAGE if (REGION_NUMBER(addr) == RGN_HPAGE) addr = 0; diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c index 0c7e94edc20e..c7c90f4f4298 100644 --- a/arch/ia64/mm/hugetlbpage.c +++ b/arch/ia64/mm/hugetlbpage.c @@ -148,6 +148,14 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, u return -ENOMEM; if (len & ~HPAGE_MASK) return -EINVAL; + + /* Handle MAP_FIXED */ + if (flags & MAP_FIXED) { + if (prepare_hugepage_range(addr, len, pgoff)) + return -EINVAL; + return addr; + } + /* This code assumes that RGN_HPAGE != 0. */ if ((REGION_NUMBER(addr) != RGN_HPAGE) || (addr & (HPAGE_SIZE - 1))) addr = HPAGE_REGION_BASE; -- cgit v1.2.3-59-g8ed1b From 869e5101728fe2f307f0a3c3cf599c184f81f0ee Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 6 May 2007 14:50:09 -0700 Subject: get_unmapped_area handles MAP_FIXED on parisc Handle MAP_FIXED in parisc arch_get_unmapped_area(), just return the address. We might want to also check for possible cache aliasing issues now that we get called in that case (like ARM or MIPS), leave a comment for the maintainers to pick up. Signed-off-by: Benjamin Herrenschmidt Cc: Kyle McMartin Cc: Grant Grundler Cc: Matthew Wilcox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/parisc/kernel/sys_parisc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 512642d8f707..6fed0803c593 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -106,6 +106,11 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, { if (len > TASK_SIZE) return -ENOMEM; + /* Might want to check for cache aliasing issues for MAP_FIXED case + * like ARM or MIPS ??? --BenH. + */ + if (flags & MAP_FIXED) + return addr; if (!addr) addr = TASK_UNMAPPED_BASE; -- cgit v1.2.3-59-g8ed1b From ac35ee484df361e1aed89873a458900693effdbe Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 6 May 2007 14:50:10 -0700 Subject: get_unmapped_area handles MAP_FIXED on sparc64 Handle MAP_FIXED in hugetlb_get_unmapped_area on sparc64 by just using prepare_hugepage_range() Signed-off-by: Benjamin Herrenschmidt Acked-by: William Irwin Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc64/mm/hugetlbpage.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c index 00677b5e1d7d..e224a94e6a1b 100644 --- a/arch/sparc64/mm/hugetlbpage.c +++ b/arch/sparc64/mm/hugetlbpage.c @@ -175,6 +175,12 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, if (len > task_size) return -ENOMEM; + if (flags & MAP_FIXED) { + if (prepare_hugepage_range(addr, len, pgoff)) + return -EINVAL; + return addr; + } + if (addr) { addr = ALIGN(addr, HPAGE_SIZE); vma = find_vma(mm, addr); -- cgit v1.2.3-59-g8ed1b From 11300a64d08ebce03e30cac8eb58e8ce008e4bb7 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 6 May 2007 14:50:11 -0700 Subject: get_unmapped_area handles MAP_FIXED on x86_64 Handle MAP_FIXED in x86_64 arch_get_unmapped_area(), simple case, just return the address as passed in Signed-off-by: Benjamin Herrenschmidt Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/sys_x86_64.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c index 76bf7c241fe4..f891931eb753 100644 --- a/arch/x86_64/kernel/sys_x86_64.c +++ b/arch/x86_64/kernel/sys_x86_64.c @@ -93,6 +93,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long start_addr; unsigned long begin, end; + if (flags & MAP_FIXED) + return addr; + find_start_end(flags, &begin, &end); if (len > end) -- cgit v1.2.3-59-g8ed1b From 50953fe9e00ebbeffa032a565ab2f08312d51a87 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Sun, 6 May 2007 14:50:16 -0700 Subject: slab allocators: Remove SLAB_DEBUG_INITIAL flag I have never seen a use of SLAB_DEBUG_INITIAL. It is only supported by SLAB. I think its purpose was to have a callback after an object has been freed to verify that the state is the constructor state again? The callback is performed before each freeing of an object. I would think that it is much easier to check the object state manually before the free. That also places the check near the code object manipulation of the object. Also the SLAB_DEBUG_INITIAL callback is only performed if the kernel was compiled with SLAB debugging on. If there would be code in a constructor handling SLAB_DEBUG_INITIAL then it would have to be conditional on SLAB_DEBUG otherwise it would just be dead code. But there is no such code in the kernel. I think SLUB_DEBUG_INITIAL is too problematic to make real use of, difficult to understand and there are easier ways to accomplish the same effect (i.e. add debug code before kfree). There is a related flag SLAB_CTOR_VERIFY that is frequently checked to be clear in fs inode caches. Remove the pointless checks (they would even be pointless without removeal of SLAB_DEBUG_INITIAL) from the fs constructors. This is the last slab flag that SLUB did not support. Remove the check for unimplemented flags from SLUB. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/platforms/cell/spufs/inode.c | 3 +-- drivers/mtd/ubi/eba.c | 3 +-- fs/adfs/super.c | 3 +-- fs/affs/super.c | 3 +-- fs/afs/super.c | 3 +-- fs/befs/linuxvfs.c | 3 +-- fs/bfs/inode.c | 3 +-- fs/block_dev.c | 4 +--- fs/buffer.c | 3 +-- fs/cifs/cifsfs.c | 3 +-- fs/coda/inode.c | 3 +-- fs/ecryptfs/main.c | 3 +-- fs/efs/super.c | 3 +-- fs/ext2/super.c | 3 +-- fs/ext3/super.c | 3 +-- fs/ext4/super.c | 3 +-- fs/fat/cache.c | 3 +-- fs/fat/inode.c | 3 +-- fs/fuse/inode.c | 3 +-- fs/gfs2/main.c | 6 ++---- fs/hfs/super.c | 2 +- fs/hfsplus/super.c | 2 +- fs/hpfs/super.c | 3 +-- fs/hugetlbfs/inode.c | 3 +-- fs/inode.c | 3 +-- fs/isofs/inode.c | 3 +-- fs/jffs2/super.c | 3 +-- fs/jfs/jfs_metapage.c | 3 +-- fs/jfs/super.c | 3 +-- fs/locks.c | 3 +-- fs/minix/inode.c | 3 +-- fs/ncpfs/inode.c | 3 +-- fs/nfs/inode.c | 3 +-- fs/ntfs/super.c | 3 +-- fs/ocfs2/dlm/dlmfs.c | 3 +-- fs/ocfs2/super.c | 3 +-- fs/openpromfs/inode.c | 3 +-- fs/proc/inode.c | 3 +-- fs/qnx4/inode.c | 3 +-- fs/reiserfs/super.c | 3 +-- fs/romfs/inode.c | 3 +-- fs/smbfs/inode.c | 3 +-- fs/sysv/inode.c | 3 +-- fs/udf/super.c | 4 +--- fs/ufs/super.c | 3 +-- fs/xfs/linux-2.6/xfs_super.c | 3 +-- include/linux/slab.h | 2 -- ipc/mqueue.c | 3 +-- kernel/fork.c | 3 +-- mm/rmap.c | 3 +-- mm/shmem.c | 3 +-- mm/slab.c | 20 ++------------------ mm/slub.c | 10 ---------- net/socket.c | 3 +-- net/sunrpc/rpc_pipe.c | 3 +-- 55 files changed, 55 insertions(+), 136 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 13e4f70ec8c0..a93f328a7317 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -71,8 +71,7 @@ spufs_init_once(void *p, struct kmem_cache * cachep, unsigned long flags) { struct spufs_inode_info *ei = p; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { inode_init_once(&ei->vfs_inode); } } diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index d847ee1da3d9..3dba5733ed1f 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -940,8 +940,7 @@ static void ltree_entry_ctor(void *obj, struct kmem_cache *cache, { struct ltree_entry *le = obj; - if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) != - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) return; le->users = 0; diff --git a/fs/adfs/super.c b/fs/adfs/super.c index 2e5f2c8371ee..30c296508497 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c @@ -232,8 +232,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct adfs_inode_info *ei = (struct adfs_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); } diff --git a/fs/affs/super.c b/fs/affs/super.c index c3986a1911b0..beff7d21e6e2 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -87,8 +87,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct affs_inode_info *ei = (struct affs_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { init_MUTEX(&ei->i_link_lock); init_MUTEX(&ei->i_ext_lock); inode_init_once(&ei->vfs_inode); diff --git a/fs/afs/super.c b/fs/afs/super.c index 41173f81ac47..7030d76155fc 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -453,8 +453,7 @@ static void afs_i_init_once(void *_vnode, struct kmem_cache *cachep, { struct afs_vnode *vnode = _vnode; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { memset(vnode, 0, sizeof(*vnode)); inode_init_once(&vnode->vfs_inode); init_waitqueue_head(&vnode->update_waitq); diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index cc6cc8ed2e39..fe96108a788d 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c @@ -293,8 +293,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct befs_inode_info *bi = (struct befs_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { inode_init_once(&bi->vfs_inode); } } diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 93d6219243ad..edc08d89aabc 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -248,8 +248,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct bfs_inode_info *bi = foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&bi->vfs_inode); } diff --git a/fs/block_dev.c b/fs/block_dev.c index 6fe49b9349ea..f02b7bdd9864 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -457,9 +457,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag struct bdev_inode *ei = (struct bdev_inode *) foo; struct block_device *bdev = &ei->bdev; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) - { + if (flags & SLAB_CTOR_CONSTRUCTOR) { memset(bdev, 0, sizeof(*bdev)); mutex_init(&bdev->bd_mutex); sema_init(&bdev->bd_mount_sem, 1); diff --git a/fs/buffer.c b/fs/buffer.c index 80291aad6de6..7db24b9e5449 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2953,8 +2953,7 @@ EXPORT_SYMBOL(free_buffer_head); static void init_buffer_head(void *data, struct kmem_cache *cachep, unsigned long flags) { - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { struct buffer_head * bh = (struct buffer_head *)data; memset(bh, 0, sizeof(*bh)); diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 5036dae09cd7..8568e100953c 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -701,8 +701,7 @@ cifs_init_once(void *inode, struct kmem_cache * cachep, unsigned long flags) { struct cifsInodeInfo *cifsi = inode; - if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { inode_init_once(&cifsi->vfs_inode); INIT_LIST_HEAD(&cifsi->lockList); } diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 614175a3b02e..0aaff3651d14 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c @@ -62,8 +62,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct coda_inode_info *ei = (struct coda_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); } diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 6acc8f4fc588..8cbf3f69ebe5 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -583,8 +583,7 @@ inode_info_init_once(void *vptr, struct kmem_cache *cachep, unsigned long flags) { struct ecryptfs_inode_info *ei = (struct ecryptfs_inode_info *)vptr; - if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); } diff --git a/fs/efs/super.c b/fs/efs/super.c index c2235e46edcd..ba7a8b9da0c1 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c @@ -72,8 +72,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct efs_inode_info *ei = (struct efs_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); } diff --git a/fs/ext2/super.c b/fs/ext2/super.c index a046a419d8af..685a1c287177 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -160,8 +160,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct ext2_inode_info *ei = (struct ext2_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { rwlock_init(&ei->i_meta_lock); #ifdef CONFIG_EXT2_FS_XATTR init_rwsem(&ei->xattr_sem); diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 4266b708ca01..54d3c9041259 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -466,8 +466,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { INIT_LIST_HEAD(&ei->i_orphan); #ifdef CONFIG_EXT3_FS_XATTR init_rwsem(&ei->xattr_sem); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 25e8d0096176..719126932354 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -517,8 +517,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct ext4_inode_info *ei = (struct ext4_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { INIT_LIST_HEAD(&ei->i_orphan); #ifdef CONFIG_EXT4DEV_FS_XATTR init_rwsem(&ei->xattr_sem); diff --git a/fs/fat/cache.c b/fs/fat/cache.c index 05c2941c74f2..1959143c1d27 100644 --- a/fs/fat/cache.c +++ b/fs/fat/cache.c @@ -40,8 +40,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) { struct fat_cache *cache = (struct fat_cache *)foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) INIT_LIST_HEAD(&cache->cache_list); } diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 9bfe607c892e..65cb54bde481 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -499,8 +499,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct msdos_inode_info *ei = (struct msdos_inode_info *)foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { spin_lock_init(&ei->cache_lru_lock); ei->nr_caches = 0; ei->cache_valid_id = FAT_CACHE_VALID + 1; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index bdffe0cfe09a..d8003be56e05 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -685,8 +685,7 @@ static void fuse_inode_init_once(void *foo, struct kmem_cache *cachep, { struct inode * inode = foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(inode); } diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index 6e8a59809abf..e2bffae683cc 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c @@ -27,8 +27,7 @@ static void gfs2_init_inode_once(void *foo, struct kmem_cache *cachep, unsigned long flags) { struct gfs2_inode *ip = foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { inode_init_once(&ip->i_inode); spin_lock_init(&ip->i_spin); init_rwsem(&ip->i_rw_mutex); @@ -39,8 +38,7 @@ static void gfs2_init_inode_once(void *foo, struct kmem_cache *cachep, unsigned static void gfs2_init_glock_once(void *foo, struct kmem_cache *cachep, unsigned long flags) { struct gfs2_glock *gl = foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { INIT_HLIST_NODE(&gl->gl_list); spin_lock_init(&gl->gl_spin); INIT_LIST_HEAD(&gl->gl_holders); diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 623f509f1d47..4f1888f16cf0 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -434,7 +434,7 @@ static void hfs_init_once(void *p, struct kmem_cache *cachep, unsigned long flag { struct hfs_inode_info *i = p; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&i->vfs_inode); } diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 1a97f9293447..37afbec8a761 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -470,7 +470,7 @@ static void hfsplus_init_once(void *p, struct kmem_cache *cachep, unsigned long { struct hfsplus_inode_info *i = p; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&i->vfs_inode); } diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index e0174e338526..1b95f39fbc37 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c @@ -176,8 +176,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { mutex_init(&ei->i_mutex); mutex_init(&ei->i_parent_mutex); inode_init_once(&ei->vfs_inode); diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index fe625cd1719a..842a4ed4052d 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -556,8 +556,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) { struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); } diff --git a/fs/inode.c b/fs/inode.c index 5abb097ab1b0..b4296bf62739 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -213,8 +213,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct inode * inode = (struct inode *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(inode); } diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 64a96cdfe3a4..e99f7ff4ecb4 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -77,8 +77,7 @@ static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags { struct iso_inode_info *ei = foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); } diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index e51164a8a8d4..45368f8bbe72 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -47,8 +47,7 @@ static void jffs2_i_init_once(void * foo, struct kmem_cache * cachep, unsigned l { struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { init_MUTEX(&ei->sem); inode_init_once(&ei->vfs_inode); } diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index 58deae007507..6b3acb0b5781 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c @@ -184,8 +184,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) { struct metapage *mp = (struct metapage *)foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { mp->lid = 0; mp->lsn = 0; mp->flag = 0; diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 52d73d54a931..ea9dc3e65dcf 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -752,8 +752,7 @@ static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags { struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { memset(jfs_ip, 0, sizeof(struct jfs_inode_info)); INIT_LIST_HEAD(&jfs_ip->anon_inode_list); init_rwsem(&jfs_ip->rdwrlock); diff --git a/fs/locks.c b/fs/locks.c index 52a81005dab4..325578074742 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -203,8 +203,7 @@ static void init_once(void *foo, struct kmem_cache *cache, unsigned long flags) { struct file_lock *lock = (struct file_lock *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) != - SLAB_CTOR_CONSTRUCTOR) + if (!(flags & SLAB_CTOR_CONSTRUCTOR)) return; locks_init_lock(lock); diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 92e383af3709..2f4d43a2a310 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -73,8 +73,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct minix_inode_info *ei = (struct minix_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); } diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 7285c94956c4..c29f00ad495d 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -60,8 +60,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct ncp_inode_info *ei = (struct ncp_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { mutex_init(&ei->open_mutex); inode_init_once(&ei->vfs_inode); } diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 44aa9b726573..1e9a915d1fea 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1167,8 +1167,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct nfs_inode *nfsi = (struct nfs_inode *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { inode_init_once(&nfsi->vfs_inode); spin_lock_init(&nfsi->req_lock); INIT_LIST_HEAD(&nfsi->dirty); diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 2ddde534db0a..21d834e5ed73 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -3085,8 +3085,7 @@ static void ntfs_big_inode_init_once(void *foo, struct kmem_cache *cachep, { ntfs_inode *ni = (ntfs_inode *)foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(VFS_I(ni)); } diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c index de952eba29a9..d4e46d067edd 100644 --- a/fs/ocfs2/dlm/dlmfs.c +++ b/fs/ocfs2/dlm/dlmfs.c @@ -263,8 +263,7 @@ static void dlmfs_init_once(void *foo, struct dlmfs_inode_private *ip = (struct dlmfs_inode_private *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { ip->ip_dlm = NULL; ip->ip_parent = NULL; diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index f5493540d94f..7c5e3f5d6634 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -937,8 +937,7 @@ static void ocfs2_inode_init_once(void *data, { struct ocfs2_inode_info *oi = data; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { oi->ip_flags = 0; oi->ip_open_count = 0; spin_lock_init(&oi->ip_lock); diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c index bde1c164417d..731a90e9f0cd 100644 --- a/fs/openpromfs/inode.c +++ b/fs/openpromfs/inode.c @@ -419,8 +419,7 @@ static void op_inode_init_once(void *data, struct kmem_cache * cachep, unsigned { struct op_inode_info *oi = (struct op_inode_info *) data; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&oi->vfs_inode); } diff --git a/fs/proc/inode.c b/fs/proc/inode.c index c372eb151a3a..22b1158389ae 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -109,8 +109,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct proc_inode *ei = (struct proc_inode *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); } diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index 83bc8e7824cd..75fc8498f2e2 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c @@ -536,8 +536,7 @@ static void init_once(void *foo, struct kmem_cache * cachep, { struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); } diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index f13a7f164dc6..7054aaef0493 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -511,8 +511,7 @@ static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags { struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo; - if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { INIT_LIST_HEAD(&ei->i_prealloc_list); inode_init_once(&ei->vfs_inode); #ifdef CONFIG_REISERFS_FS_POSIX_ACL diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c index fd601014813e..804285190271 100644 --- a/fs/romfs/inode.c +++ b/fs/romfs/inode.c @@ -570,8 +570,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct romfs_inode_info *ei = (struct romfs_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); } diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 5faba4f1c9ab..424a3ddf86dd 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c @@ -69,9 +69,8 @@ static void smb_destroy_inode(struct inode *inode) static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) { struct smb_inode_info *ei = (struct smb_inode_info *) foo; - unsigned long flagmask = SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR; - if ((flags & flagmask) == SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); } diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index 9311cac186fe..3152d7415606 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c @@ -322,8 +322,7 @@ static void init_once(void *p, struct kmem_cache *cachep, unsigned long flags) { struct sysv_inode_info *si = (struct sysv_inode_info *)p; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&si->vfs_inode); } diff --git a/fs/udf/super.c b/fs/udf/super.c index 8672b88f7ff2..023b304fdd99 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -134,9 +134,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct udf_inode_info *ei = (struct udf_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) - { + if (flags & SLAB_CTOR_CONSTRUCTOR) { ei->i_ext.i_data = NULL; inode_init_once(&ei->vfs_inode); } diff --git a/fs/ufs/super.c b/fs/ufs/super.c index b5a6461ec66b..be7c48c5f203 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1237,8 +1237,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct ufs_inode_info *ei = (struct ufs_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); } diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 2f2c40db562e..14e2cbe5a8d5 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -360,8 +360,7 @@ xfs_fs_inode_init_once( kmem_zone_t *zonep, unsigned long flags) { - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(vn_to_inode((bhv_vnode_t *)vnode)); } diff --git a/include/linux/slab.h b/include/linux/slab.h index e14b4c338b89..1ffe0a959cd4 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -21,7 +21,6 @@ typedef struct kmem_cache kmem_cache_t __deprecated; * The ones marked DEBUG are only valid if CONFIG_SLAB_DEBUG is set. */ #define SLAB_DEBUG_FREE 0x00000100UL /* DEBUG: Perform (expensive) checks on free */ -#define SLAB_DEBUG_INITIAL 0x00000200UL /* DEBUG: Call constructor (as verifier) */ #define SLAB_RED_ZONE 0x00000400UL /* DEBUG: Red zone objs in a cache */ #define SLAB_POISON 0x00000800UL /* DEBUG: Poison objects */ #define SLAB_HWCACHE_ALIGN 0x00002000UL /* Align objs on cache lines */ @@ -36,7 +35,6 @@ typedef struct kmem_cache kmem_cache_t __deprecated; /* Flags passed to a constructor functions */ #define SLAB_CTOR_CONSTRUCTOR 0x001UL /* If not set, then deconstructor */ #define SLAB_CTOR_ATOMIC 0x002UL /* Tell constructor it can't sleep */ -#define SLAB_CTOR_VERIFY 0x004UL /* Tell constructor it's a verify call */ /* * struct kmem_cache related prototypes diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 554ac368be79..d17821d3f483 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -215,8 +215,7 @@ static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags { struct mqueue_inode_info *p = (struct mqueue_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&p->vfs_inode); } diff --git a/kernel/fork.c b/kernel/fork.c index ffccefb28b6a..b7d169def942 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1425,8 +1425,7 @@ static void sighand_ctor(void *data, struct kmem_cache *cachep, unsigned long fl { struct sighand_struct *sighand = data; - if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) spin_lock_init(&sighand->siglock); } diff --git a/mm/rmap.c b/mm/rmap.c index 59da5b734c80..75a32be64a21 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -162,8 +162,7 @@ void anon_vma_unlink(struct vm_area_struct *vma) static void anon_vma_ctor(void *data, struct kmem_cache *cachep, unsigned long flags) { - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { struct anon_vma *anon_vma = data; spin_lock_init(&anon_vma->lock); diff --git a/mm/shmem.c b/mm/shmem.c index b2a35ebf071a..f01e8deed645 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -2358,8 +2358,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, { struct shmem_inode_info *p = (struct shmem_inode_info *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { inode_init_once(&p->vfs_inode); #ifdef CONFIG_TMPFS_POSIX_ACL p->i_acl = NULL; diff --git a/mm/slab.c b/mm/slab.c index 2a3cbd6e675d..a877d6f3d687 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -116,8 +116,7 @@ #include /* - * DEBUG - 1 for kmem_cache_create() to honour; SLAB_DEBUG_INITIAL, - * SLAB_RED_ZONE & SLAB_POISON. + * DEBUG - 1 for kmem_cache_create() to honour; SLAB_RED_ZONE & SLAB_POISON. * 0 for faster, smaller code (especially in the critical paths). * * STATS - 1 to collect stats for /proc/slabinfo. @@ -172,7 +171,7 @@ /* Legal flag mask for kmem_cache_create(). */ #if DEBUG -# define CREATE_MASK (SLAB_DEBUG_INITIAL | SLAB_RED_ZONE | \ +# define CREATE_MASK (SLAB_RED_ZONE | \ SLAB_POISON | SLAB_HWCACHE_ALIGN | \ SLAB_CACHE_DMA | \ SLAB_STORE_USER | \ @@ -2184,12 +2183,6 @@ kmem_cache_create (const char *name, size_t size, size_t align, #if DEBUG WARN_ON(strchr(name, ' ')); /* It confuses parsers */ - if ((flags & SLAB_DEBUG_INITIAL) && !ctor) { - /* No constructor, but inital state check requested */ - printk(KERN_ERR "%s: No con, but init state check " - "requested - %s\n", __FUNCTION__, name); - flags &= ~SLAB_DEBUG_INITIAL; - } #if FORCED_DEBUG /* * Enable redzoning and last user accounting, except for caches with @@ -2895,15 +2888,6 @@ static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp, BUG_ON(objnr >= cachep->num); BUG_ON(objp != index_to_obj(cachep, slabp, objnr)); - if (cachep->flags & SLAB_DEBUG_INITIAL) { - /* - * Need to call the slab's constructor so the caller can - * perform a verify of its state (debugging). Called without - * the cache-lock held. - */ - cachep->ctor(objp + obj_offset(cachep), - cachep, SLAB_CTOR_CONSTRUCTOR | SLAB_CTOR_VERIFY); - } if (cachep->flags & SLAB_POISON && cachep->dtor) { /* we want to cache poison the object, * call the destruction callback diff --git a/mm/slub.c b/mm/slub.c index 79940e98e5e6..bd86182e595e 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -97,9 +97,6 @@ * * - Support PAGE_ALLOC_DEBUG. Should be easy to do. * - * - SLAB_DEBUG_INITIAL is not supported but I have never seen a use of - * it. - * * - Variable sizing of the per node arrays */ @@ -125,11 +122,6 @@ #endif -/* - * Flags from the regular SLAB that SLUB does not support: - */ -#define SLUB_UNIMPLEMENTED (SLAB_DEBUG_INITIAL) - /* * Mininum number of partial slabs. These will be left on the partial * lists even if they are empty. kmem_cache_shrink may reclaim them. @@ -1748,8 +1740,6 @@ static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags, s->flags = flags; s->align = align; - BUG_ON(flags & SLUB_UNIMPLEMENTED); - /* * The page->offset field is only 16 bit wide. This is an offset * in units of words from the beginning of an object. If the slab diff --git a/net/socket.c b/net/socket.c index 1ad62c08377b..759825b7ca26 100644 --- a/net/socket.c +++ b/net/socket.c @@ -261,8 +261,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) { struct socket_alloc *ei = (struct socket_alloc *)foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) - == SLAB_CTOR_CONSTRUCTOR) + if (flags & SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); } diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 9b9ea5045569..ad39b47e05bc 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -828,8 +828,7 @@ init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) { struct rpc_inode *rpci = (struct rpc_inode *) foo; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + if (flags & SLAB_CTOR_CONSTRUCTOR) { inode_init_once(&rpci->vfs_inode); rpci->private = NULL; rpci->nreaders = 0; -- cgit v1.2.3-59-g8ed1b From 1394f03221790a988afc3e4b3cb79f2e477246a9 Mon Sep 17 00:00:00 2001 From: Bryan Wu Date: Sun, 6 May 2007 14:50:22 -0700 Subject: blackfin architecture This adds support for the Analog Devices Blackfin processor architecture, and currently supports the BF533, BF532, BF531, BF537, BF536, BF534, and BF561 (Dual Core) devices, with a variety of development platforms including those avaliable from Analog Devices (BF533-EZKit, BF533-STAMP, BF537-STAMP, BF561-EZKIT), and Bluetechnix! Tinyboards. The Blackfin architecture was jointly developed by Intel and Analog Devices Inc. (ADI) as the Micro Signal Architecture (MSA) core and introduced it in December of 2000. Since then ADI has put this core into its Blackfin processor family of devices. The Blackfin core has the advantages of a clean, orthogonal,RISC-like microprocessor instruction set. It combines a dual-MAC (Multiply/Accumulate), state-of-the-art signal processing engine and single-instruction, multiple-data (SIMD) multimedia capabilities into a single instruction-set architecture. The Blackfin architecture, including the instruction set, is described by the ADSP-BF53x/BF56x Blackfin Processor Programming Reference http://blackfin.uclinux.org/gf/download/frsrelease/29/2549/Blackfin_PRM.pdf The Blackfin processor is already supported by major releases of gcc, and there are binary and source rpms/tarballs for many architectures at: http://blackfin.uclinux.org/gf/project/toolchain/frs There is complete documentation, including "getting started" guides available at: http://docs.blackfin.uclinux.org/ which provides links to the sources and patches you will need in order to set up a cross-compiling environment for bfin-linux-uclibc This patch, as well as the other patches (toolchain, distribution, uClibc) are actively supported by Analog Devices Inc, at: http://blackfin.uclinux.org/ We have tested this on LTP, and our test plan (including pass/fails) can be found at: http://docs.blackfin.uclinux.org/doku.php?id=testing_the_linux_kernel [m.kozlowski@tuxland.pl: balance parenthesis in blackfin header files] Signed-off-by: Bryan Wu Signed-off-by: Mariusz Kozlowski Signed-off-by: Aubrey Li Signed-off-by: Jie Zhang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/blackfin/00-INDEX | 11 + Documentation/blackfin/Filesystems | 169 ++ Documentation/blackfin/cache-lock.txt | 48 + Documentation/blackfin/cachefeatures.txt | 65 + MAINTAINERS | 38 + arch/blackfin/Kconfig | 989 ++++++++ arch/blackfin/Makefile | 80 + arch/blackfin/boot/Makefile | 27 + arch/blackfin/defconfig | 1314 ++++++++++ arch/blackfin/kernel/Makefile | 14 + arch/blackfin/kernel/asm-offsets.c | 136 ++ arch/blackfin/kernel/bfin_dma_5xx.c | 742 ++++++ arch/blackfin/kernel/bfin_gpio.c | 637 +++++ arch/blackfin/kernel/bfin_ksyms.c | 119 + arch/blackfin/kernel/dma-mapping.c | 183 ++ arch/blackfin/kernel/dualcore_test.c | 49 + arch/blackfin/kernel/entry.S | 94 + arch/blackfin/kernel/flat.c | 101 + arch/blackfin/kernel/init_task.c | 60 + arch/blackfin/kernel/irqchip.c | 147 ++ arch/blackfin/kernel/module.c | 429 ++++ arch/blackfin/kernel/process.c | 394 +++ arch/blackfin/kernel/ptrace.c | 430 ++++ arch/blackfin/kernel/setup.c | 902 +++++++ arch/blackfin/kernel/signal.c | 356 +++ arch/blackfin/kernel/sys_bfin.c | 115 + arch/blackfin/kernel/time.c | 326 +++ arch/blackfin/kernel/traps.c | 649 +++++ arch/blackfin/kernel/vmlinux.lds.S | 228 ++ arch/blackfin/lib/Makefile | 11 + arch/blackfin/lib/ashldi3.c | 58 + arch/blackfin/lib/ashrdi3.c | 59 + arch/blackfin/lib/checksum.c | 140 ++ arch/blackfin/lib/divsi3.S | 216 ++ arch/blackfin/lib/gcclib.h | 47 + arch/blackfin/lib/ins.S | 69 + arch/blackfin/lib/lshrdi3.c | 72 + arch/blackfin/lib/memchr.S | 70 + arch/blackfin/lib/memcmp.S | 110 + arch/blackfin/lib/memcpy.S | 142 ++ arch/blackfin/lib/memmove.S | 103 + arch/blackfin/lib/memset.S | 109 + arch/blackfin/lib/modsi3.S | 79 + arch/blackfin/lib/muldi3.c | 99 + arch/blackfin/lib/outs.S | 62 + arch/blackfin/lib/smulsi3_highpart.S | 30 + arch/blackfin/lib/strcmp.c | 11 + arch/blackfin/lib/strcpy.c | 11 + arch/blackfin/lib/strncmp.c | 11 + arch/blackfin/lib/strncpy.c | 11 + arch/blackfin/lib/udivsi3.S | 298 +++ arch/blackfin/lib/umodsi3.S | 66 + arch/blackfin/lib/umulsi3_highpart.S | 23 + arch/blackfin/mach-bf533/Kconfig | 92 + arch/blackfin/mach-bf533/Makefile | 9 + arch/blackfin/mach-bf533/boards/Makefile | 8 + arch/blackfin/mach-bf533/boards/cm_bf533.c | 267 +++ arch/blackfin/mach-bf533/boards/ezkit.c | 224 ++ arch/blackfin/mach-bf533/boards/generic_board.c | 95 + arch/blackfin/mach-bf533/boards/stamp.c | 321 +++ arch/blackfin/mach-bf533/cpu.c | 161 ++ arch/blackfin/mach-bf533/head.S | 774 ++++++ arch/blackfin/mach-bf533/ints-priority.c | 65 + arch/blackfin/mach-bf537/Kconfig | 141 ++ arch/blackfin/mach-bf537/Makefile | 9 + arch/blackfin/mach-bf537/boards/Makefile | 9 + arch/blackfin/mach-bf537/boards/cm_bf537.c | 364 +++ arch/blackfin/mach-bf537/boards/eth_mac.c | 51 + arch/blackfin/mach-bf537/boards/generic_board.c | 445 ++++ arch/blackfin/mach-bf537/boards/led.S | 183 ++ arch/blackfin/mach-bf537/boards/pnav10.c | 523 ++++ arch/blackfin/mach-bf537/boards/stamp.c | 615 +++++ arch/blackfin/mach-bf537/cpu.c | 161 ++ arch/blackfin/mach-bf537/head.S | 602 +++++ arch/blackfin/mach-bf537/ints-priority.c | 74 + arch/blackfin/mach-bf561/Kconfig | 222 ++ arch/blackfin/mach-bf561/Makefile | 9 + arch/blackfin/mach-bf561/boards/Makefile | 7 + arch/blackfin/mach-bf561/boards/cm_bf561.c | 289 +++ arch/blackfin/mach-bf561/boards/ezkit.c | 147 ++ arch/blackfin/mach-bf561/boards/generic_board.c | 82 + arch/blackfin/mach-bf561/coreb.c | 402 ++++ arch/blackfin/mach-bf561/head.S | 512 ++++ arch/blackfin/mach-bf561/ints-priority.c | 108 + arch/blackfin/mach-common/Makefile | 12 + arch/blackfin/mach-common/cache.S | 253 ++ arch/blackfin/mach-common/cacheinit.S | 137 ++ arch/blackfin/mach-common/cplbhdlr.S | 130 + arch/blackfin/mach-common/cplbinfo.c | 211 ++ arch/blackfin/mach-common/cplbmgr.S | 607 +++++ arch/blackfin/mach-common/dpmc.S | 418 ++++ arch/blackfin/mach-common/entry.S | 1207 ++++++++++ arch/blackfin/mach-common/interrupt.S | 253 ++ arch/blackfin/mach-common/ints-priority-dc.c | 476 ++++ arch/blackfin/mach-common/ints-priority-sc.c | 577 +++++ arch/blackfin/mach-common/irqpanic.c | 194 ++ arch/blackfin/mach-common/lock.S | 204 ++ arch/blackfin/mach-common/pm.c | 181 ++ arch/blackfin/mm/Makefile | 5 + arch/blackfin/mm/blackfin_sram.c | 540 +++++ arch/blackfin/mm/blackfin_sram.h | 38 + arch/blackfin/mm/init.c | 208 ++ arch/blackfin/oprofile/Kconfig | 29 + arch/blackfin/oprofile/Makefile | 14 + arch/blackfin/oprofile/common.c | 168 ++ arch/blackfin/oprofile/op_blackfin.h | 98 + arch/blackfin/oprofile/op_model_bf533.c | 161 ++ arch/blackfin/oprofile/timer_int.c | 74 + fs/Kconfig.binfmt | 2 +- include/asm-blackfin/Kbuild | 1 + include/asm-blackfin/a.out.h | 25 + include/asm-blackfin/atomic.h | 144 ++ include/asm-blackfin/auxvec.h | 4 + include/asm-blackfin/bf5xx_timers.h | 209 ++ include/asm-blackfin/bfin-global.h | 120 + include/asm-blackfin/bfin5xx_spi.h | 170 ++ include/asm-blackfin/bfin_simple_timer.h | 13 + include/asm-blackfin/bfin_sport.h | 175 ++ include/asm-blackfin/bitops.h | 213 ++ include/asm-blackfin/blackfin.h | 81 + include/asm-blackfin/bug.h | 4 + include/asm-blackfin/bugs.h | 16 + include/asm-blackfin/byteorder.h | 48 + include/asm-blackfin/cache.h | 29 + include/asm-blackfin/cacheflush.h | 90 + include/asm-blackfin/checksum.h | 101 + include/asm-blackfin/cplb.h | 51 + include/asm-blackfin/cplbinit.h | 203 ++ include/asm-blackfin/cpumask.h | 6 + include/asm-blackfin/cputime.h | 6 + include/asm-blackfin/current.h | 23 + include/asm-blackfin/delay.h | 44 + include/asm-blackfin/device.h | 7 + include/asm-blackfin/div64.h | 1 + include/asm-blackfin/dma-mapping.h | 66 + include/asm-blackfin/dma.h | 188 ++ include/asm-blackfin/dpmc.h | 70 + include/asm-blackfin/elf.h | 127 + include/asm-blackfin/emergency-restart.h | 6 + include/asm-blackfin/entry.h | 56 + include/asm-blackfin/errno.h | 6 + include/asm-blackfin/fcntl.h | 13 + include/asm-blackfin/flat.h | 58 + include/asm-blackfin/futex.h | 6 + include/asm-blackfin/gpio.h | 367 +++ include/asm-blackfin/hardirq.h | 41 + include/asm-blackfin/hw_irq.h | 6 + include/asm-blackfin/ide.h | 32 + include/asm-blackfin/io.h | 207 ++ include/asm-blackfin/ioctl.h | 1 + include/asm-blackfin/ioctls.h | 82 + include/asm-blackfin/ipc.h | 1 + include/asm-blackfin/ipcbuf.h | 30 + include/asm-blackfin/irq.h | 70 + include/asm-blackfin/irq_handler.h | 22 + include/asm-blackfin/irq_regs.h | 1 + include/asm-blackfin/kdebug.h | 1 + include/asm-blackfin/kmap_types.h | 21 + include/asm-blackfin/l1layout.h | 31 + include/asm-blackfin/linkage.h | 7 + include/asm-blackfin/local.h | 6 + include/asm-blackfin/mach-bf533/anomaly.h | 175 ++ include/asm-blackfin/mach-bf533/bf533.h | 306 +++ include/asm-blackfin/mach-bf533/bfin_serial_5xx.h | 108 + include/asm-blackfin/mach-bf533/blackfin.h | 45 + include/asm-blackfin/mach-bf533/cdefBF532.h | 706 ++++++ include/asm-blackfin/mach-bf533/defBF532.h | 1175 +++++++++ include/asm-blackfin/mach-bf533/dma.h | 54 + include/asm-blackfin/mach-bf533/irq.h | 177 ++ include/asm-blackfin/mach-bf533/mem_init.h | 316 +++ include/asm-blackfin/mach-bf533/mem_map.h | 168 ++ include/asm-blackfin/mach-bf537/anomaly.h | 120 + include/asm-blackfin/mach-bf537/bf537.h | 287 +++ include/asm-blackfin/mach-bf537/bfin_serial_5xx.h | 147 ++ include/asm-blackfin/mach-bf537/blackfin.h | 430 ++++ include/asm-blackfin/mach-bf537/cdefBF534.h | 1823 ++++++++++++++ include/asm-blackfin/mach-bf537/cdefBF537.h | 209 ++ include/asm-blackfin/mach-bf537/defBF534.h | 2501 ++++++++++++++++++++ include/asm-blackfin/mach-bf537/defBF537.h | 404 ++++ include/asm-blackfin/mach-bf537/dma.h | 55 + include/asm-blackfin/mach-bf537/irq.h | 219 ++ include/asm-blackfin/mach-bf537/mem_init.h | 330 +++ include/asm-blackfin/mach-bf537/mem_map.h | 175 ++ include/asm-blackfin/mach-bf561/anomaly.h | 184 ++ include/asm-blackfin/mach-bf561/bf561.h | 408 ++++ include/asm-blackfin/mach-bf561/bfin_serial_5xx.h | 108 + include/asm-blackfin/mach-bf561/blackfin.h | 52 + include/asm-blackfin/mach-bf561/cdefBF561.h | 1543 ++++++++++++ include/asm-blackfin/mach-bf561/defBF561.h | 1717 ++++++++++++++ include/asm-blackfin/mach-bf561/dma.h | 35 + include/asm-blackfin/mach-bf561/irq.h | 450 ++++ include/asm-blackfin/mach-bf561/mem_init.h | 322 +++ include/asm-blackfin/mach-bf561/mem_map.h | 75 + include/asm-blackfin/mach-common/cdef_LPBlackfin.h | 471 ++++ include/asm-blackfin/mach-common/context.S | 350 +++ include/asm-blackfin/mach-common/def_LPBlackfin.h | 691 ++++++ include/asm-blackfin/macros.h | 95 + include/asm-blackfin/mem_map.h | 12 + include/asm-blackfin/mman.h | 45 + include/asm-blackfin/mmu.h | 30 + include/asm-blackfin/mmu_context.h | 129 + include/asm-blackfin/module.h | 19 + include/asm-blackfin/msgbuf.h | 31 + include/asm-blackfin/mutex.h | 9 + include/asm-blackfin/namei.h | 19 + include/asm-blackfin/page.h | 89 + include/asm-blackfin/page_offset.h | 6 + include/asm-blackfin/param.h | 22 + include/asm-blackfin/pci.h | 148 ++ include/asm-blackfin/percpu.h | 6 + include/asm-blackfin/pgalloc.h | 8 + include/asm-blackfin/pgtable.h | 96 + include/asm-blackfin/poll.h | 24 + include/asm-blackfin/posix_types.h | 65 + include/asm-blackfin/processor.h | 130 + include/asm-blackfin/ptrace.h | 166 ++ include/asm-blackfin/resource.h | 6 + include/asm-blackfin/scatterlist.h | 26 + include/asm-blackfin/sections.h | 7 + include/asm-blackfin/segment.h | 7 + include/asm-blackfin/semaphore-helper.h | 82 + include/asm-blackfin/semaphore.h | 106 + include/asm-blackfin/sembuf.h | 25 + include/asm-blackfin/setup.h | 17 + include/asm-blackfin/shmbuf.h | 42 + include/asm-blackfin/shmparam.h | 6 + include/asm-blackfin/sigcontext.h | 55 + include/asm-blackfin/siginfo.h | 35 + include/asm-blackfin/signal.h | 160 ++ include/asm-blackfin/socket.h | 53 + include/asm-blackfin/sockios.h | 13 + include/asm-blackfin/spinlock.h | 6 + include/asm-blackfin/stat.h | 63 + include/asm-blackfin/statfs.h | 6 + include/asm-blackfin/string.h | 104 + include/asm-blackfin/system.h | 250 ++ include/asm-blackfin/termbits.h | 184 ++ include/asm-blackfin/termios.h | 106 + include/asm-blackfin/thread_info.h | 143 ++ include/asm-blackfin/timex.h | 18 + include/asm-blackfin/tlb.h | 16 + include/asm-blackfin/tlbflush.h | 62 + include/asm-blackfin/topology.h | 6 + include/asm-blackfin/traps.h | 75 + include/asm-blackfin/types.h | 66 + include/asm-blackfin/uaccess.h | 271 +++ include/asm-blackfin/ucontext.h | 17 + include/asm-blackfin/unaligned.h | 6 + include/asm-blackfin/unistd.h | 382 +++ include/asm-blackfin/user.h | 89 + include/linux/elf-em.h | 1 + include/linux/spi/ad7877.h | 24 + include/linux/usb_sl811.h | 26 + init/Kconfig | 2 +- lib/Kconfig.debug | 4 +- scripts/genksyms/genksyms.c | 3 +- scripts/mod/mk_elfconfig.c | 3 +- 257 files changed, 47285 insertions(+), 6 deletions(-) create mode 100644 Documentation/blackfin/00-INDEX create mode 100644 Documentation/blackfin/Filesystems create mode 100644 Documentation/blackfin/cache-lock.txt create mode 100644 Documentation/blackfin/cachefeatures.txt create mode 100644 arch/blackfin/Kconfig create mode 100644 arch/blackfin/Makefile create mode 100644 arch/blackfin/boot/Makefile create mode 100644 arch/blackfin/defconfig create mode 100644 arch/blackfin/kernel/Makefile create mode 100644 arch/blackfin/kernel/asm-offsets.c create mode 100644 arch/blackfin/kernel/bfin_dma_5xx.c create mode 100644 arch/blackfin/kernel/bfin_gpio.c create mode 100644 arch/blackfin/kernel/bfin_ksyms.c create mode 100644 arch/blackfin/kernel/dma-mapping.c create mode 100644 arch/blackfin/kernel/dualcore_test.c create mode 100644 arch/blackfin/kernel/entry.S create mode 100644 arch/blackfin/kernel/flat.c create mode 100644 arch/blackfin/kernel/init_task.c create mode 100644 arch/blackfin/kernel/irqchip.c create mode 100644 arch/blackfin/kernel/module.c create mode 100644 arch/blackfin/kernel/process.c create mode 100644 arch/blackfin/kernel/ptrace.c create mode 100644 arch/blackfin/kernel/setup.c create mode 100644 arch/blackfin/kernel/signal.c create mode 100644 arch/blackfin/kernel/sys_bfin.c create mode 100644 arch/blackfin/kernel/time.c create mode 100644 arch/blackfin/kernel/traps.c create mode 100644 arch/blackfin/kernel/vmlinux.lds.S create mode 100644 arch/blackfin/lib/Makefile create mode 100644 arch/blackfin/lib/ashldi3.c create mode 100644 arch/blackfin/lib/ashrdi3.c create mode 100644 arch/blackfin/lib/checksum.c create mode 100644 arch/blackfin/lib/divsi3.S create mode 100644 arch/blackfin/lib/gcclib.h create mode 100644 arch/blackfin/lib/ins.S create mode 100644 arch/blackfin/lib/lshrdi3.c create mode 100644 arch/blackfin/lib/memchr.S create mode 100644 arch/blackfin/lib/memcmp.S create mode 100644 arch/blackfin/lib/memcpy.S create mode 100644 arch/blackfin/lib/memmove.S create mode 100644 arch/blackfin/lib/memset.S create mode 100644 arch/blackfin/lib/modsi3.S create mode 100644 arch/blackfin/lib/muldi3.c create mode 100644 arch/blackfin/lib/outs.S create mode 100644 arch/blackfin/lib/smulsi3_highpart.S create mode 100644 arch/blackfin/lib/strcmp.c create mode 100644 arch/blackfin/lib/strcpy.c create mode 100644 arch/blackfin/lib/strncmp.c create mode 100644 arch/blackfin/lib/strncpy.c create mode 100644 arch/blackfin/lib/udivsi3.S create mode 100644 arch/blackfin/lib/umodsi3.S create mode 100644 arch/blackfin/lib/umulsi3_highpart.S create mode 100644 arch/blackfin/mach-bf533/Kconfig create mode 100644 arch/blackfin/mach-bf533/Makefile create mode 100644 arch/blackfin/mach-bf533/boards/Makefile create mode 100644 arch/blackfin/mach-bf533/boards/cm_bf533.c create mode 100644 arch/blackfin/mach-bf533/boards/ezkit.c create mode 100644 arch/blackfin/mach-bf533/boards/generic_board.c create mode 100644 arch/blackfin/mach-bf533/boards/stamp.c create mode 100644 arch/blackfin/mach-bf533/cpu.c create mode 100644 arch/blackfin/mach-bf533/head.S create mode 100644 arch/blackfin/mach-bf533/ints-priority.c create mode 100644 arch/blackfin/mach-bf537/Kconfig create mode 100644 arch/blackfin/mach-bf537/Makefile create mode 100644 arch/blackfin/mach-bf537/boards/Makefile create mode 100644 arch/blackfin/mach-bf537/boards/cm_bf537.c create mode 100644 arch/blackfin/mach-bf537/boards/eth_mac.c create mode 100644 arch/blackfin/mach-bf537/boards/generic_board.c create mode 100644 arch/blackfin/mach-bf537/boards/led.S create mode 100644 arch/blackfin/mach-bf537/boards/pnav10.c create mode 100644 arch/blackfin/mach-bf537/boards/stamp.c create mode 100644 arch/blackfin/mach-bf537/cpu.c create mode 100644 arch/blackfin/mach-bf537/head.S create mode 100644 arch/blackfin/mach-bf537/ints-priority.c create mode 100644 arch/blackfin/mach-bf561/Kconfig create mode 100644 arch/blackfin/mach-bf561/Makefile create mode 100644 arch/blackfin/mach-bf561/boards/Makefile create mode 100644 arch/blackfin/mach-bf561/boards/cm_bf561.c create mode 100644 arch/blackfin/mach-bf561/boards/ezkit.c create mode 100644 arch/blackfin/mach-bf561/boards/generic_board.c create mode 100644 arch/blackfin/mach-bf561/coreb.c create mode 100644 arch/blackfin/mach-bf561/head.S create mode 100644 arch/blackfin/mach-bf561/ints-priority.c create mode 100644 arch/blackfin/mach-common/Makefile create mode 100644 arch/blackfin/mach-common/cache.S create mode 100644 arch/blackfin/mach-common/cacheinit.S create mode 100644 arch/blackfin/mach-common/cplbhdlr.S create mode 100644 arch/blackfin/mach-common/cplbinfo.c create mode 100644 arch/blackfin/mach-common/cplbmgr.S create mode 100644 arch/blackfin/mach-common/dpmc.S create mode 100644 arch/blackfin/mach-common/entry.S create mode 100644 arch/blackfin/mach-common/interrupt.S create mode 100644 arch/blackfin/mach-common/ints-priority-dc.c create mode 100644 arch/blackfin/mach-common/ints-priority-sc.c create mode 100644 arch/blackfin/mach-common/irqpanic.c create mode 100644 arch/blackfin/mach-common/lock.S create mode 100644 arch/blackfin/mach-common/pm.c create mode 100644 arch/blackfin/mm/Makefile create mode 100644 arch/blackfin/mm/blackfin_sram.c create mode 100644 arch/blackfin/mm/blackfin_sram.h create mode 100644 arch/blackfin/mm/init.c create mode 100644 arch/blackfin/oprofile/Kconfig create mode 100644 arch/blackfin/oprofile/Makefile create mode 100644 arch/blackfin/oprofile/common.c create mode 100644 arch/blackfin/oprofile/op_blackfin.h create mode 100644 arch/blackfin/oprofile/op_model_bf533.c create mode 100644 arch/blackfin/oprofile/timer_int.c create mode 100644 include/asm-blackfin/Kbuild create mode 100644 include/asm-blackfin/a.out.h create mode 100644 include/asm-blackfin/atomic.h create mode 100644 include/asm-blackfin/auxvec.h create mode 100644 include/asm-blackfin/bf5xx_timers.h create mode 100644 include/asm-blackfin/bfin-global.h create mode 100644 include/asm-blackfin/bfin5xx_spi.h create mode 100644 include/asm-blackfin/bfin_simple_timer.h create mode 100644 include/asm-blackfin/bfin_sport.h create mode 100644 include/asm-blackfin/bitops.h create mode 100644 include/asm-blackfin/blackfin.h create mode 100644 include/asm-blackfin/bug.h create mode 100644 include/asm-blackfin/bugs.h create mode 100644 include/asm-blackfin/byteorder.h create mode 100644 include/asm-blackfin/cache.h create mode 100644 include/asm-blackfin/cacheflush.h create mode 100644 include/asm-blackfin/checksum.h create mode 100644 include/asm-blackfin/cplb.h create mode 100644 include/asm-blackfin/cplbinit.h create mode 100644 include/asm-blackfin/cpumask.h create mode 100644 include/asm-blackfin/cputime.h create mode 100644 include/asm-blackfin/current.h create mode 100644 include/asm-blackfin/delay.h create mode 100644 include/asm-blackfin/device.h create mode 100644 include/asm-blackfin/div64.h create mode 100644 include/asm-blackfin/dma-mapping.h create mode 100644 include/asm-blackfin/dma.h create mode 100644 include/asm-blackfin/dpmc.h create mode 100644 include/asm-blackfin/elf.h create mode 100644 include/asm-blackfin/emergency-restart.h create mode 100644 include/asm-blackfin/entry.h create mode 100644 include/asm-blackfin/errno.h create mode 100644 include/asm-blackfin/fcntl.h create mode 100644 include/asm-blackfin/flat.h create mode 100644 include/asm-blackfin/futex.h create mode 100644 include/asm-blackfin/gpio.h create mode 100644 include/asm-blackfin/hardirq.h create mode 100644 include/asm-blackfin/hw_irq.h create mode 100644 include/asm-blackfin/ide.h create mode 100644 include/asm-blackfin/io.h create mode 100644 include/asm-blackfin/ioctl.h create mode 100644 include/asm-blackfin/ioctls.h create mode 100644 include/asm-blackfin/ipc.h create mode 100644 include/asm-blackfin/ipcbuf.h create mode 100644 include/asm-blackfin/irq.h create mode 100644 include/asm-blackfin/irq_handler.h create mode 100644 include/asm-blackfin/irq_regs.h create mode 100644 include/asm-blackfin/kdebug.h create mode 100644 include/asm-blackfin/kmap_types.h create mode 100644 include/asm-blackfin/l1layout.h create mode 100644 include/asm-blackfin/linkage.h create mode 100644 include/asm-blackfin/local.h create mode 100644 include/asm-blackfin/mach-bf533/anomaly.h create mode 100644 include/asm-blackfin/mach-bf533/bf533.h create mode 100644 include/asm-blackfin/mach-bf533/bfin_serial_5xx.h create mode 100644 include/asm-blackfin/mach-bf533/blackfin.h create mode 100644 include/asm-blackfin/mach-bf533/cdefBF532.h create mode 100644 include/asm-blackfin/mach-bf533/defBF532.h create mode 100644 include/asm-blackfin/mach-bf533/dma.h create mode 100644 include/asm-blackfin/mach-bf533/irq.h create mode 100644 include/asm-blackfin/mach-bf533/mem_init.h create mode 100644 include/asm-blackfin/mach-bf533/mem_map.h create mode 100644 include/asm-blackfin/mach-bf537/anomaly.h create mode 100644 include/asm-blackfin/mach-bf537/bf537.h create mode 100644 include/asm-blackfin/mach-bf537/bfin_serial_5xx.h create mode 100644 include/asm-blackfin/mach-bf537/blackfin.h create mode 100644 include/asm-blackfin/mach-bf537/cdefBF534.h create mode 100644 include/asm-blackfin/mach-bf537/cdefBF537.h create mode 100644 include/asm-blackfin/mach-bf537/defBF534.h create mode 100644 include/asm-blackfin/mach-bf537/defBF537.h create mode 100644 include/asm-blackfin/mach-bf537/dma.h create mode 100644 include/asm-blackfin/mach-bf537/irq.h create mode 100644 include/asm-blackfin/mach-bf537/mem_init.h create mode 100644 include/asm-blackfin/mach-bf537/mem_map.h create mode 100644 include/asm-blackfin/mach-bf561/anomaly.h create mode 100644 include/asm-blackfin/mach-bf561/bf561.h create mode 100644 include/asm-blackfin/mach-bf561/bfin_serial_5xx.h create mode 100644 include/asm-blackfin/mach-bf561/blackfin.h create mode 100644 include/asm-blackfin/mach-bf561/cdefBF561.h create mode 100644 include/asm-blackfin/mach-bf561/defBF561.h create mode 100644 include/asm-blackfin/mach-bf561/dma.h create mode 100644 include/asm-blackfin/mach-bf561/irq.h create mode 100644 include/asm-blackfin/mach-bf561/mem_init.h create mode 100644 include/asm-blackfin/mach-bf561/mem_map.h create mode 100644 include/asm-blackfin/mach-common/cdef_LPBlackfin.h create mode 100644 include/asm-blackfin/mach-common/context.S create mode 100644 include/asm-blackfin/mach-common/def_LPBlackfin.h create mode 100644 include/asm-blackfin/macros.h create mode 100644 include/asm-blackfin/mem_map.h create mode 100644 include/asm-blackfin/mman.h create mode 100644 include/asm-blackfin/mmu.h create mode 100644 include/asm-blackfin/mmu_context.h create mode 100644 include/asm-blackfin/module.h create mode 100644 include/asm-blackfin/msgbuf.h create mode 100644 include/asm-blackfin/mutex.h create mode 100644 include/asm-blackfin/namei.h create mode 100644 include/asm-blackfin/page.h create mode 100644 include/asm-blackfin/page_offset.h create mode 100644 include/asm-blackfin/param.h create mode 100644 include/asm-blackfin/pci.h create mode 100644 include/asm-blackfin/percpu.h create mode 100644 include/asm-blackfin/pgalloc.h create mode 100644 include/asm-blackfin/pgtable.h create mode 100644 include/asm-blackfin/poll.h create mode 100644 include/asm-blackfin/posix_types.h create mode 100644 include/asm-blackfin/processor.h create mode 100644 include/asm-blackfin/ptrace.h create mode 100644 include/asm-blackfin/resource.h create mode 100644 include/asm-blackfin/scatterlist.h create mode 100644 include/asm-blackfin/sections.h create mode 100644 include/asm-blackfin/segment.h create mode 100644 include/asm-blackfin/semaphore-helper.h create mode 100644 include/asm-blackfin/semaphore.h create mode 100644 include/asm-blackfin/sembuf.h create mode 100644 include/asm-blackfin/setup.h create mode 100644 include/asm-blackfin/shmbuf.h create mode 100644 include/asm-blackfin/shmparam.h create mode 100644 include/asm-blackfin/sigcontext.h create mode 100644 include/asm-blackfin/siginfo.h create mode 100644 include/asm-blackfin/signal.h create mode 100644 include/asm-blackfin/socket.h create mode 100644 include/asm-blackfin/sockios.h create mode 100644 include/asm-blackfin/spinlock.h create mode 100644 include/asm-blackfin/stat.h create mode 100644 include/asm-blackfin/statfs.h create mode 100644 include/asm-blackfin/string.h create mode 100644 include/asm-blackfin/system.h create mode 100644 include/asm-blackfin/termbits.h create mode 100644 include/asm-blackfin/termios.h create mode 100644 include/asm-blackfin/thread_info.h create mode 100644 include/asm-blackfin/timex.h create mode 100644 include/asm-blackfin/tlb.h create mode 100644 include/asm-blackfin/tlbflush.h create mode 100644 include/asm-blackfin/topology.h create mode 100644 include/asm-blackfin/traps.h create mode 100644 include/asm-blackfin/types.h create mode 100644 include/asm-blackfin/uaccess.h create mode 100644 include/asm-blackfin/ucontext.h create mode 100644 include/asm-blackfin/unaligned.h create mode 100644 include/asm-blackfin/unistd.h create mode 100644 include/asm-blackfin/user.h create mode 100644 include/linux/spi/ad7877.h create mode 100644 include/linux/usb_sl811.h (limited to 'arch') diff --git a/Documentation/blackfin/00-INDEX b/Documentation/blackfin/00-INDEX new file mode 100644 index 000000000000..7cb3b356b249 --- /dev/null +++ b/Documentation/blackfin/00-INDEX @@ -0,0 +1,11 @@ +00-INDEX + - This file + +cache-lock.txt + - HOWTO for blackfin cache locking. + +cachefeatures.txt + - Supported cache features. + +Filesystems + - Requirements for mounting the root file system. diff --git a/Documentation/blackfin/Filesystems b/Documentation/blackfin/Filesystems new file mode 100644 index 000000000000..51260a1b8032 --- /dev/null +++ b/Documentation/blackfin/Filesystems @@ -0,0 +1,169 @@ +/* + * File: Documentation/blackfin/Filesystems + * Based on: + * Author: + * + * Created: + * Description: This file contains the simple DMA Implementation for Blackfin + * + * Rev: $Id: Filesystems 2384 2006-11-01 04:12:43Z magicyang $ + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + */ + + How to mount the root file system in uClinux/Blackfin + ----------------------------------------------------- + +1 Mounting EXT3 File system. + ------------------------ + + Creating an EXT3 File system for uClinux/Blackfin: + + +Please follow the steps to form the EXT3 File system and mount the same as root +file system. + +a Make an ext3 file system as large as you want the final root file + system. + + mkfs.ext3 /dev/ram0 + +b Mount this Empty file system on a free directory as: + + mount -t ext3 /dev/ram0 ./test + where ./test is the empty directory. + +c Copy your root fs directory that you have so carefully made over. + + cp -af /tmp/my_final_rootfs_files/* ./test + + (For ex: cp -af uClinux-dist/romfs/* ./test) + +d If you have done everything right till now you should be able to see + the required "root" dir's (that's etc, root, bin, lib, sbin...) + +e Now unmount the file system + + umount ./test + +f Create the root file system image. + + dd if=/dev/ram0 bs=1k count= \ + > ext3fs.img + + +Now you have to tell the kernel that will be mounting this file system as +rootfs. +So do a make menuconfig under kernel and select the Ext3 journaling file system +support under File system --> submenu. + + +2. Mounting EXT2 File system. + ------------------------- + +By default the ext2 file system image will be created if you invoke make from +the top uClinux-dist directory. + + +3. Mounting CRAMFS File System + ---------------------------- + +To create a CRAMFS file system image execute the command + + mkfs.cramfs ./test cramfs.img + + where ./test is the target directory. + + +4. Mounting ROMFS File System + -------------------------- + +To create a ROMFS file system image execute the command + + genromfs -v -V "ROMdisk" -f romfs.img -d ./test + + where ./test is the target directory + + +5. Mounting the JFFS2 Filesystem + ----------------------------- + +To create a compressed JFFS filesystem (JFFS2), please execute the command + + mkfs.jffs2 -d ./test -o jffs2.img + + where ./test is the target directory. + +However, please make sure the following is in your kernel config. + +/* + * RAM/ROM/Flash chip drivers + */ +#define CONFIG_MTD_CFI 1 +#define CONFIG_MTD_ROM 1 +/* + * Mapping drivers for chip access + */ +#define CONFIG_MTD_COMPLEX_MAPPINGS 1 +#define CONFIG_MTD_BF533 1 +#undef CONFIG_MTD_UCLINUX + +Through the u-boot boot loader, use the jffs2.img in the corresponding +partition made in linux-2.6.x/drivers/mtd/maps/bf533_flash.c. + +NOTE - Currently the Flash driver is available only for EZKIT. Watch out for a + STAMP driver soon. + + +6. Mounting the NFS File system + ----------------------------- + + For mounting the NFS please do the following in the kernel config. + + In Networking Support --> Networking options --> TCP/IP networking --> + IP: kernel level autoconfiguration + + Enable BOOTP Support. + + In Kernel hacking --> Compiled-in kernel boot parameter add the following + + root=/dev/nfs rw ip=bootp + + In File system --> Network File system, Enable + + NFS file system support --> NFSv3 client support + Root File system on NFS + + in uClibc menuconfig, do the following + In Networking Support + enable Remote Procedure Call (RPC) support + Full RPC Support + + On the Host side, ensure that /etc/dhcpd.conf looks something like this + + ddns-update-style ad-hoc; + allow bootp; + subnet 10.100.4.0 netmask 255.255.255.0 { + default-lease-time 122209600; + max-lease-time 31557600; + group { + host bf533 { + hardware ethernet 00:CF:52:49:C3:01; + fixed-address 10.100.4.50; + option root-path "/home/nfsmount"; + } + } + + ensure that /etc/exports looks something like this + /home/nfsmount *(rw,no_root_squash,no_all_squash) + + run the following commands as root (may differ depending on your + distribution) : + - service nfs start + - service portmap start + - service dhcpd start + - /usr/sbin/exportfs diff --git a/Documentation/blackfin/cache-lock.txt b/Documentation/blackfin/cache-lock.txt new file mode 100644 index 000000000000..88ba1e6c31c3 --- /dev/null +++ b/Documentation/blackfin/cache-lock.txt @@ -0,0 +1,48 @@ +/* + * File: Documentation/blackfin/cache-lock.txt + * Based on: + * Author: + * + * Created: + * Description: This file contains the simple DMA Implementation for Blackfin + * + * Rev: $Id: cache-lock.txt 2384 2006-11-01 04:12:43Z magicyang $ + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + */ + +How to lock your code in cache in uClinux/blackfin +-------------------------------------------------- + +There are only a few steps required to lock your code into the cache. +Currently you can lock the code by Way. + +Below are the interface provided for locking the cache. + + +1. cache_grab_lock(int Ways); + +This function grab the lock for locking your code into the cache specified +by Ways. + + +2. cache_lock(int Ways); + +This function should be called after your critical code has been executed. +Once the critical code exits, the code is now loaded into the cache. This +function locks the code into the cache. + + +So, the example sequence will be: + + cache_grab_lock(WAY0_L); /* Grab the lock */ + + critical_code(); /* Execute the code of interest */ + + cache_lock(WAY0_L); /* Lock the cache */ + +Where WAY0_L signifies WAY0 locking. diff --git a/Documentation/blackfin/cachefeatures.txt b/Documentation/blackfin/cachefeatures.txt new file mode 100644 index 000000000000..0fbec23becb5 --- /dev/null +++ b/Documentation/blackfin/cachefeatures.txt @@ -0,0 +1,65 @@ +/* + * File: Documentation/blackfin/cachefeatures.txt + * Based on: + * Author: + * + * Created: + * Description: This file contains the simple DMA Implementation for Blackfin + * + * Rev: $Id: cachefeatures.txt 2384 2006-11-01 04:12:43Z magicyang $ + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + */ + + - Instruction and Data cache initialization. + icache_init(); + dcache_init(); + + - Instruction and Data cache Invalidation Routines, when flushing the + same is not required. + _icache_invalidate(); + _dcache_invalidate(); + + Also, for invalidating the entire instruction and data cache, the below + routines are provided (another method for invalidation, refer page no 267 and 287 of + ADSP-BF533 Hardware Reference manual) + + invalidate_entire_dcache(); + invalidate_entire_icache(); + + -External Flushing of Instruction and data cache routines. + + flush_instruction_cache(); + flush_data_cache(); + + - Internal Flushing of Instruction and Data Cache. + + icplb_flush(); + dcplb_flush(); + + - Locking the cache. + + cache_grab_lock(); + cache_lock(); + + Please refer linux-2.6.x/Documentation/blackfin/cache-lock.txt for how to + lock the cache. + + Locking the cache is optional feature. + + - Miscellaneous cache functions. + + flush_cache_all(); + flush_cache_mm(); + invalidate_dcache_range(); + flush_dcache_range(); + flush_dcache_page(); + flush_cache_range(); + flush_cache_page(); + invalidate_dcache_range(); + flush_page_to_ram(); + diff --git a/MAINTAINERS b/MAINTAINERS index 0492dd88e12a..6d665ac13f99 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -700,6 +700,44 @@ P: Richard Purdie M: rpurdie@rpsys.net S: Maintained +BLACKFIN ARCHITECTURE +P: Aubrey Li +M: aubrey.li@analog.com +P: Bernd Schmidt +M: bernd.schmidt@analog.com +P: Bryan Wu +M: bryan.wu@analog.com +P: Grace Pan +M: grace.pan@analog.com +P: Michael Hennerich +M: michael.hennerich@analog.com +P: Mike Frysinger +M: michael.frysinger@analog.com +P: Jane Lv +M: jane.lv@analog.com +P: Jerry Zeng +M: jerry.zeng@analog.com +P: Jie Zhang +M: jie.zhang@analog.com +P: Robin Getz +M: robin.getz@analog.com +P: Roy Huang +M: roy.huang@analog.com +P: Sonic Zhang +M: sonic.zhang@analog.com +P: Yi Li +M: yi.li@analog.com +L: uclinux-dist-devel@blackfin.uclinux.org +W: http://blackfin.uclinux.org +S: Supported + +BLACKFIN SERIAL DRIVER +P: Aubrey Li +M: aubrey.li@analog.com +L: uclinux-dist-devel@blackfin.uclinux.org +W: http://blackfin.uclinux.org +S: Supported + BAYCOM/HDLCDRV DRIVERS FOR AX.25 P: Thomas Sailer M: t.sailer@alumni.ethz.ch diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig new file mode 100644 index 000000000000..1a4930509325 --- /dev/null +++ b/arch/blackfin/Kconfig @@ -0,0 +1,989 @@ +# +# For a description of the syntax of this configuration file, +# see Documentation/kbuild/kconfig-language.txt. +# + +mainmenu "uClinux/Blackfin (w/o MMU) Kernel Configuration" + +config MMU + bool + default n + +config FPU + bool + default n + +config RWSEM_GENERIC_SPINLOCK + bool + default y + +config RWSEM_XCHGADD_ALGORITHM + bool + default n + +config BLACKFIN + bool + default y + +config BFIN + bool + default y + +config SEMAPHORE_SLEEPERS + bool + default y + +config GENERIC_FIND_NEXT_BIT + bool + default y + +config GENERIC_HWEIGHT + bool + default y + +config GENERIC_HARDIRQS + bool + default y + +config GENERIC_IRQ_PROBE + bool + default y + +config GENERIC_TIME + bool + default n + +config GENERIC_CALIBRATE_DELAY + bool + default y + +config FORCE_MAX_ZONEORDER + int + default "14" + +config GENERIC_CALIBRATE_DELAY + bool + default y + +config IRQCHIP_DEMUX_GPIO + bool + default y + +source "init/Kconfig" +source "kernel/Kconfig.preempt" + +menu "Blackfin Processor Options" + +comment "Processor and Board Settings" + +choice + prompt "CPU" + default BF533 + +config BF531 + bool "BF531" + help + BF531 Processor Support. + +config BF532 + bool "BF532" + help + BF532 Processor Support. + +config BF533 + bool "BF533" + help + BF533 Processor Support. + +config BF534 + bool "BF534" + help + BF534 Processor Support. + +config BF536 + bool "BF536" + help + BF536 Processor Support. + +config BF537 + bool "BF537" + help + BF537 Processor Support. + +config BF561 + bool "BF561" + help + Not Supported Yet - Work in progress - BF561 Processor Support. + +endchoice + +choice + prompt "Silicon Rev" + default BF_REV_0_2 if BF537 + default BF_REV_0_3 if BF533 + +config BF_REV_0_2 + bool "0.2" + depends on (BF537 || BF536 || BF534) + +config BF_REV_0_3 + bool "0.3" + depends on (BF561 || BF537 || BF536 || BF534 || BF533 || BF532 || BF531) + +config BF_REV_0_4 + bool "0.4" + depends on (BF561 || BF533 || BF532 || BF531) + +config BF_REV_0_5 + bool "0.5" + depends on (BF561 || BF533 || BF532 || BF531) + +endchoice + +config BFIN_DUAL_CORE + bool + depends on (BF561) + default y + +config BFIN_SINGLE_CORE + bool + depends on !BFIN_DUAL_CORE + default y + +choice + prompt "System type" + default BFIN533_STAMP + help + Do NOT change the board here. Please use the top level + configuration to ensure that all the other settings are + correct. + +config BFIN533_EZKIT + bool "BF533-EZKIT" + depends on (BF533 || BF532 || BF531) + help + BF533-EZKIT-LITE board Support. + +config BFIN533_STAMP + bool "BF533-STAMP" + depends on (BF533 || BF532 || BF531) + help + BF533-STAMP board Support. + +config BFIN537_STAMP + bool "BF537-STAMP" + depends on (BF537 || BF536 || BF534) + help + BF537-STAMP board Support. + +config BFIN533_BLUETECHNIX_CM + bool "Bluetechnix CM-BF533" + depends on (BF533) + help + CM-BF533 support for EVAL- and DEV-Board. + +config BFIN537_BLUETECHNIX_CM + bool "Bluetechnix CM-BF537" + depends on (BF537) + help + CM-BF537 support for EVAL- and DEV-Board. + +config BFIN561_BLUETECHNIX_CM + bool "BF561-CM" + depends on (BF561) + help + CM-BF561 support for EVAL- and DEV-Board. + +config BFIN561_EZKIT + bool "BF561-EZKIT" + depends on (BF561) + help + BF561-EZKIT-LITE board Support. + +config PNAV10 + bool "PNAV 1.0 board" + depends on (BF537) + help + PNAV 1.0 board Support. + +config GENERIC_BOARD + bool "Custom" + depends on (BF537 || BF536 \ + || BF534 || BF561 || BF535 || BF533 || BF532 || BF531) + help + GENERIC or Custom board Support. + +endchoice + +config MEM_GENERIC_BOARD + bool + depends on GENERIC_BOARD + default y + +config MEM_MT48LC64M4A2FB_7E + bool + depends on (BFIN533_STAMP) + default y + +config MEM_MT48LC16M16A2TG_75 + bool + depends on (BFIN533_EZKIT || BFIN561_EZKIT \ + || BFIN533_BLUETECHNIX_CM || BFIN537_BLUETECHNIX_CM) + default y + +config MEM_MT48LC32M8A2_75 + bool + depends on (BFIN537_STAMP || PNAV10) + default y + +config MEM_MT48LC8M32B2B5_7 + bool + depends on (BFIN561_BLUETECHNIX_CM) + default y + +config BFIN_SHARED_FLASH_ENET + bool + depends on (BFIN533_STAMP) + default y + +source "arch/blackfin/mach-bf533/Kconfig" +source "arch/blackfin/mach-bf561/Kconfig" +source "arch/blackfin/mach-bf537/Kconfig" + +menu "Board customizations" + +config CMDLINE_BOOL + bool "Default bootloader kernel arguments" + +config CMDLINE + string "Initial kernel command string" + depends on CMDLINE_BOOL + default "console=ttyBF0,57600" + help + If you don't have a boot loader capable of passing a command line string + to the kernel, you may specify one here. As a minimum, you should specify + the memory size and the root device (e.g., mem=8M, root=/dev/nfs). + +comment "Board Setup" + +config CLKIN_HZ + int "Crystal Frequency in Hz" + default "11059200" if BFIN533_STAMP + default "27000000" if BFIN533_EZKIT + default "25000000" if BFIN537_STAMP + default "30000000" if BFIN561_EZKIT + default "24576000" if PNAV10 + help + The frequency of CLKIN crystal oscillator on the board in Hz. + +config MEM_SIZE + int "SDRAM Memory Size in MBytes" + default 32 if BFIN533_EZKIT + default 64 if BFIN537_STAMP + default 64 if BFIN561_EZKIT + default 128 if BFIN533_STAMP + default 64 if PNAV10 + +config MEM_ADD_WIDTH + int "SDRAM Memory Address Width" + default 9 if BFIN533_EZKIT + default 9 if BFIN561_EZKIT + default 10 if BFIN537_STAMP + default 11 if BFIN533_STAMP + default 10 if PNAV10 + +config ENET_FLASH_PIN + int "PF port/pin used for flash and ethernet sharing" + depends on (BFIN533_STAMP) + default 0 + help + PF port/pin used for flash and ethernet sharing to allow other PF + pins to be used on other platforms without having to touch common + code. + For example: PF0 --> 0,PF1 --> 1,PF2 --> 2, etc. + +config BOOT_LOAD + hex "Kernel load address for booting" + default "0x1000" + help + This option allows you to set the load address of the kernel. + This can be useful if you are on a board which has a small amount + of memory or you wish to reserve some memory at the beginning of + the address space. + + Note that you generally want to keep this value at or above 4k + (0x1000) as this will allow the kernel to capture NULL pointer + references. + +comment "LED Status Indicators" + depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM) + +config BFIN_ALIVE_LED + bool "Enable Board Alive" + depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM) + default n + help + Blink the LEDs you select when the kernel is running. Helps detect + a hung kernel. + +config BFIN_ALIVE_LED_NUM + int "LED" + depends on BFIN_ALIVE_LED + range 1 3 if BFIN533_STAMP + default "3" if BFIN533_STAMP + help + Select the LED (marked on the board) for you to blink. + +config BFIN_IDLE_LED + bool "Enable System Load/Idle LED" + depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM) + default n + help + Blinks the LED you select when to determine kernel load. + +config BFIN_IDLE_LED_NUM + int "LED" + depends on BFIN_IDLE_LED + range 1 3 if BFIN533_STAMP + default "2" if BFIN533_STAMP + help + Select the LED (marked on the board) for you to blink. + +# +# Sorry - but you need to put the hex address here - +# + +# Flag Data register +config BFIN_ALIVE_LED_PORT + hex + default 0xFFC00700 if (BFIN533_STAMP) + +# Peripheral Flag Direction Register +config BFIN_ALIVE_LED_DPORT + hex + default 0xFFC00730 if (BFIN533_STAMP) + +config BFIN_ALIVE_LED_PIN + hex + default 0x04 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 1) + default 0x08 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 2) + default 0x10 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 3) + +config BFIN_IDLE_LED_PORT + hex + default 0xFFC00700 if (BFIN533_STAMP) + +# Peripheral Flag Direction Register +config BFIN_IDLE_LED_DPORT + hex + default 0xFFC00730 if (BFIN533_STAMP) + +config BFIN_IDLE_LED_PIN + hex + default 0x04 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 1) + default 0x08 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 2) + default 0x10 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 3) + +comment "Console UART Setup" + +choice + prompt "Baud Rate" + default BAUD_57600 +config BAUD_9600 + bool "9600" +config BAUD_19200 + bool "19200" +config BAUD_38400 + bool "38400" +config BAUD_57600 + bool "57600" +config BAUD_115200 + bool "115200" +endchoice + +choice + prompt "Parity" + default BAUD_NO_PARITY +config BAUD_NO_PARITY + bool "No Parity" +config BAUD_PARITY + bool "Parity" +endchoice + +choice + prompt "Stop Bits" + default BAUD_1_STOPBIT +config BAUD_1_STOPBIT + bool "1" +config BAUD_2_STOPBIT + bool "2" +endchoice + +endmenu + + +menu "Blackfin Kernel Optimizations" + +comment "Timer Tick" + +source kernel/Kconfig.hz + +comment "Memory Optimizations" + +config I_ENTRY_L1 + bool "Locate interrupt entry code in L1 Memory" + default y + help + If enabled interrupt entry code (STORE/RESTORE CONTEXT) is linked + into L1 instruction memory.(less latency) + +config EXCPT_IRQ_SYSC_L1 + bool "Locate entire ASM lowlevel excepetion / interrupt - Syscall and CPLB handler code in L1 Memory" + default y + help + If enabled entire ASM lowlevel exception and interrupt entry code (STORE/RESTORE CONTEXT) is linked + into L1 instruction memory.(less latency) + +config DO_IRQ_L1 + bool "Locate frequently called do_irq dispatcher function in L1 Memory" + default y + help + If enabled frequently called do_irq dispatcher function is linked + into L1 instruction memory.(less latency) + +config CORE_TIMER_IRQ_L1 + bool "Locate frequently called timer_interrupt() function in L1 Memory" + default y + help + If enabled frequently called timer_interrupt() function is linked + into L1 instruction memory.(less latency) + +config IDLE_L1 + bool "Locate frequently idle function in L1 Memory" + default y + help + If enabled frequently called idle function is linked + into L1 instruction memory.(less latency) + +config SCHEDULE_L1 + bool "Locate kernel schedule function in L1 Memory" + default y + help + If enabled frequently called kernel schedule is linked + into L1 instruction memory.(less latency) + +config ARITHMETIC_OPS_L1 + bool "Locate kernel owned arithmetic functions in L1 Memory" + default y + help + If enabled arithmetic functions are linked + into L1 instruction memory.(less latency) + +config ACCESS_OK_L1 + bool "Locate access_ok function in L1 Memory" + default y + help + If enabled access_ok function is linked + into L1 instruction memory.(less latency) + +config MEMSET_L1 + bool "Locate memset function in L1 Memory" + default y + help + If enabled memset function is linked + into L1 instruction memory.(less latency) + +config MEMCPY_L1 + bool "Locate memcpy function in L1 Memory" + default y + help + If enabled memcpy function is linked + into L1 instruction memory.(less latency) + +config SYS_BFIN_SPINLOCK_L1 + bool "Locate sys_bfin_spinlock function in L1 Memory" + default y + help + If enabled sys_bfin_spinlock function is linked + into L1 instruction memory.(less latency) + +config IP_CHECKSUM_L1 + bool "Locate IP Checksum function in L1 Memory" + default n + help + If enabled IP Checksum function is linked + into L1 instruction memory.(less latency) + +config CACHELINE_ALIGNED_L1 + bool "Locate cacheline_aligned data to L1 Data Memory" + default y + depends on !BF531 + help + If enabled cacheline_anligned data is linked + into L1 data memory.(less latency) + +config SYSCALL_TAB_L1 + bool "Locate Syscall Table L1 Data Memory" + default n + depends on !BF531 + help + If enabled the Syscall LUT is linked + into L1 data memory.(less latency) + +config CPLB_SWITCH_TAB_L1 + bool "Locate CPLB Switch Tables L1 Data Memory" + default n + depends on !BF531 + help + If enabled the CPLB Switch Tables are linked + into L1 data memory.(less latency) + +endmenu + + +choice + prompt "Kernel executes from" + help + Choose the memory type that the kernel will be running in. + +config RAMKERNEL + bool "RAM" + help + The kernel will be resident in RAM when running. + +config ROMKERNEL + bool "ROM" + help + The kernel will be resident in FLASH/ROM when running. + +endchoice + +source "mm/Kconfig" + +config LARGE_ALLOCS + bool "Allow allocating large blocks (> 1MB) of memory" + help + Allow the slab memory allocator to keep chains for very large + memory sizes - upto 32MB. You may need this if your system has + a lot of RAM, and you need to able to allocate very large + contiguous chunks. If unsure, say N. + +config BFIN_DMA_5XX + bool "Enable DMA Support" + depends on (BF533 || BF532 || BF531 || BF537 || BF536 || BF534 || BF561) + default y + help + DMA driver for BF5xx. + +choice + prompt "Uncached SDRAM region" + default DMA_UNCACHED_1M + depends BFIN_DMA_5XX +config DMA_UNCACHED_2M + bool "Enable 2M DMA region" +config DMA_UNCACHED_1M + bool "Enable 1M DMA region" +config DMA_UNCACHED_NONE + bool "Disable DMA region" +endchoice + + +comment "Cache Support" +config BLKFIN_CACHE + bool "Enable ICACHE" +config BLKFIN_DCACHE + bool "Enable DCACHE" +config BLKFIN_DCACHE_BANKA + bool "Enable only 16k BankA DCACHE - BankB is SRAM" + depends on BLKFIN_DCACHE && !BF531 + default n +config BLKFIN_CACHE_LOCK + bool "Enable Cache Locking" + +choice + prompt "Policy" + depends on BLKFIN_DCACHE + default BLKFIN_WB +config BLKFIN_WB + bool "Write back" + help + Write Back Policy: + Cached data will be written back to SDRAM only when needed. + This can give a nice increase in performance, but beware of + broken drivers that do not properly invalidate/flush their + cache. + + Write Through Policy: + Cached data will always be written back to SDRAM when the + cache is updated. This is a completely safe setting, but + performance is worse than Write Back. + + If you are unsure of the options and you want to be safe, + then go with Write Through. + +config BLKFIN_WT + bool "Write through" + help + Write Back Policy: + Cached data will be written back to SDRAM only when needed. + This can give a nice increase in performance, but beware of + broken drivers that do not properly invalidate/flush their + cache. + + Write Through Policy: + Cached data will always be written back to SDRAM when the + cache is updated. This is a completely safe setting, but + performance is worse than Write Back. + + If you are unsure of the options and you want to be safe, + then go with Write Through. + +endchoice + +config L1_MAX_PIECE + int "Set the max L1 SRAM pieces" + default 16 + help + Set the max memory pieces for the L1 SRAM allocation algorithm. + Min value is 16. Max value is 1024. + +menu "Clock Settings" + + +config BFIN_KERNEL_CLOCK + bool "Re-program Clocks while Kernel boots?" + default n + help + This option decides if kernel clocks are re-programed from the + bootloader settings. If the clocks are not set, the SDRAM settings + are also not changed, and the Bootloader does 100% of the hardware + configuration. + +config VCO_MULT + int "VCO Multiplier" + depends on BFIN_KERNEL_CLOCK + default "22" if BFIN533_EZKIT + default "45" if BFIN533_STAMP + default "20" if BFIN537_STAMP + default "22" if BFIN533_BLUETECHNIX_CM + default "20" if BFIN537_BLUETECHNIX_CM + default "20" if BFIN561_BLUETECHNIX_CM + default "20" if BFIN561_EZKIT + +config CCLK_DIV + int "Core Clock Divider" + depends on BFIN_KERNEL_CLOCK + default 1 if BFIN533_EZKIT + default 1 if BFIN533_STAMP + default 1 if BFIN537_STAMP + default 1 if BFIN533_BLUETECHNIX_CM + default 1 if BFIN537_BLUETECHNIX_CM + default 1 if BFIN561_BLUETECHNIX_CM + default 1 if BFIN561_EZKIT + +config SCLK_DIV + int "System Clock Divider" + depends on BFIN_KERNEL_CLOCK + default 5 if BFIN533_EZKIT + default 5 if BFIN533_STAMP + default 4 if BFIN537_STAMP + default 5 if BFIN533_BLUETECHNIX_CM + default 4 if BFIN537_BLUETECHNIX_CM + default 4 if BFIN561_BLUETECHNIX_CM + default 5 if BFIN561_EZKIT + +config CLKIN_HALF + bool "Half ClockIn" + depends on BFIN_KERNEL_CLOCK + default n + +config PLL_BYPASS + bool "Bypass PLL" + depends on BFIN_KERNEL_CLOCK + default n + +endmenu + +comment "Asynchonous Memory Configuration" + +menu "EBIU_AMBCTL Global Control" +config C_AMCKEN + bool "Enable CLKOUT" + default y + +config C_CDPRIO + bool "DMA has priority over core for ext. accesses" + default n + +config C_B0PEN + depends on BF561 + bool "Bank 0 16 bit packing enable" + default y + +config C_B1PEN + depends on BF561 + bool "Bank 1 16 bit packing enable" + default y + +config C_B2PEN + depends on BF561 + bool "Bank 2 16 bit packing enable" + default y + +config C_B3PEN + depends on BF561 + bool "Bank 3 16 bit packing enable" + default n + +choice + prompt"Enable Asynchonous Memory Banks" + default C_AMBEN_ALL + +config C_AMBEN + bool "Disable All Banks" + +config C_AMBEN_B0 + bool "Enable Bank 0" + +config C_AMBEN_B0_B1 + bool "Enable Bank 0 & 1" + +config C_AMBEN_B0_B1_B2 + bool "Enable Bank 0 & 1 & 2" + +config C_AMBEN_ALL + bool "Enable All Banks" +endchoice +endmenu + +menu "EBIU_AMBCTL Control" +config BANK_0 + hex "Bank 0" + default 0x7BB0 + +config BANK_1 + hex "Bank 1" + default 0x7BB0 + +config BANK_2 + hex "Bank 2" + default 0x7BB0 + +config BANK_3 + hex "Bank 3" + default 0x99B3 +endmenu + +endmenu + +############################################################################# +menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" + +config PCI + bool "PCI support" + help + Support for PCI bus. + +source "drivers/pci/Kconfig" + +config HOTPLUG + bool "Support for hot-pluggable device" + help + Say Y here if you want to plug devices into your computer while + the system is running, and be able to use them quickly. In many + cases, the devices can likewise be unplugged at any time too. + + One well known example of this is PCMCIA- or PC-cards, credit-card + size devices such as network cards, modems or hard drives which are + plugged into slots found on all modern laptop computers. Another + example, used on modern desktops as well as laptops, is USB. + + Enable HOTPLUG and KMOD, and build a modular kernel. Get agent + software (at ) and install it. + Then your kernel will automatically call out to a user mode "policy + agent" (/sbin/hotplug) to load modules and set up software needed + to use devices as you hotplug them. + +source "drivers/pcmcia/Kconfig" + +source "drivers/pci/hotplug/Kconfig" + +endmenu + +menu "Executable file formats" + +source "fs/Kconfig.binfmt" + +endmenu + +menu "Power management options" +source "kernel/power/Kconfig" + +choice + prompt "Select PM Wakeup Event Source" + default PM_WAKEUP_GPIO_BY_SIC_IWR + depends on PM + help + If you have a GPIO already configured as input with the corresponding PORTx_MASK + bit set - "Specify Wakeup Event by SIC_IWR value" + +config PM_WAKEUP_GPIO_BY_SIC_IWR + bool "Specify Wakeup Event by SIC_IWR value" +config PM_WAKEUP_BY_GPIO + bool "Cause Wakeup Event by GPIO" +config PM_WAKEUP_GPIO_API + bool "Configure Wakeup Event by PM GPIO API" + +endchoice + +config PM_WAKEUP_SIC_IWR + hex "Wakeup Events (SIC_IWR)" + depends on PM_WAKEUP_GPIO_BY_SIC_IWR + default 0x80000000 if (BF537 || BF536 || BF534) + default 0x100000 if (BF533 || BF532 || BF531) + +config PM_WAKEUP_GPIO_NUMBER + int "Wakeup GPIO number" + range 0 47 + depends on PM_WAKEUP_BY_GPIO + default 2 if BFIN537_STAMP + +choice + prompt "GPIO Polarity" + depends on PM_WAKEUP_BY_GPIO + default PM_WAKEUP_GPIO_POLAR_H +config PM_WAKEUP_GPIO_POLAR_H + bool "Active High" +config PM_WAKEUP_GPIO_POLAR_L + bool "Active Low" +config PM_WAKEUP_GPIO_POLAR_EDGE_F + bool "Falling EDGE" +config PM_WAKEUP_GPIO_POLAR_EDGE_R + bool "Rising EDGE" +config PM_WAKEUP_GPIO_POLAR_EDGE_B + bool "Both EDGE" +endchoice + +endmenu + +if (BF537 || BF533) + +menu "CPU Frequency scaling" + +source "drivers/cpufreq/Kconfig" + +config CPU_FREQ + bool + default n + help + If you want to enable this option, you should select the + DPMC driver from Character Devices. +endmenu + +endif + +source "net/Kconfig" + +source "drivers/Kconfig" + +source "fs/Kconfig" + +source "arch/blackfin/oprofile/Kconfig" + +menu "Kernel hacking" + +source "lib/Kconfig.debug" + +config DEBUG_HWERR + bool "Hardware error interrupt debugging" + depends on DEBUG_KERNEL + help + When enabled, the hardware error interrupt is never disabled, and + will happen immediately when an error condition occurs. This comes + at a slight cost in code size, but is necessary if you are getting + hardware error interrupts and need to know where they are coming + from. + +config DEBUG_ICACHE_CHECK + bool "Check Instruction cache coherancy" + depends on DEBUG_KERNEL + depends on DEBUG_HWERR + help + Say Y here if you are getting wierd unexplained errors. This will + ensure that icache is what SDRAM says it should be, by doing a + byte wise comparision between SDRAM and instruction cache. This + also relocates the irq_panic() function to L1 memory, (which is + un-cached). + +config DEBUG_KERNEL_START + bool "Debug Kernel Startup" + depends on DEBUG_KERNEL + help + Say Y here to put in an mini-execption handler before the kernel + replaces the bootloader exception handler. This will stop kernels + from dieing at startup with no visible error messages. + +config DEBUG_SERIAL_EARLY_INIT + bool "Initialize serial driver early" + default n + depends on SERIAL_BFIN + help + Say Y here if you want to get kernel output early when kernel + crashes before the normal console initialization. If this option + is enable, console output will always go to the ttyBF0, no matter + what kernel boot paramters you set. + +config DEBUG_HUNT_FOR_ZERO + bool "Catch NULL pointer reads/writes" + default y + help + Say Y here to catch reads/writes to anywhere in the memory range + from 0x0000 - 0x0FFF (the first 4k) of memory. This is useful in + catching common programming errors such as NULL pointer dereferences. + + Misbehaving applications will be killed (generate a SEGV) while the + kernel will trigger a panic. + + Enabling this option will take up an extra entry in CPLB table. + Otherwise, there is no extra overhead. + +config DEBUG_BFIN_NO_KERN_HWTRACE + bool "Trace user apps (turn off hwtrace in kernel)" + default n + help + Some pieces of the kernel contain a lot of flow changes which can + quickly fill up the hardware trace buffer. When debugging crashes, + the hardware trace may indicate that the problem lies in kernel + space when in reality an application is buggy. + + Say Y here to disable hardware tracing in some known "jumpy" pieces + of code so that the trace buffer will extend further back. + +config DUAL_CORE_TEST_MODULE + tristate "Dual Core Test Module" + depends on (BF561) + default n + help + Say Y here to build-in dual core test module for dual core test. + +config CPLB_INFO + bool "Display the CPLB information" + help + Display the CPLB information. + +config ACCESS_CHECK + bool "Check the user pointer address" + default y + help + Usually the pointer transfer from user space is checked to see if its + address is in the kernel space. + + Say N here to disable that check to improve the performance. + +endmenu + +source "security/Kconfig" + +source "crypto/Kconfig" + +source "lib/Kconfig" diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile new file mode 100644 index 000000000000..52d4dbdb2b1a --- /dev/null +++ b/arch/blackfin/Makefile @@ -0,0 +1,80 @@ +# +# arch/blackfin/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# + + +CROSS_COMPILE ?= bfin-uclinux- +LDFLAGS_vmlinux := -X +OBJCOPYFLAGS := -O binary -R .note -R .comment -S +GZFLAGS := -9 + +CFLAGS_MODULE += -mlong-calls +KALLSYMS += --symbol-prefix=_ + + +# setup the machine name and the machine dependent settings +machine-$(CONFIG_BF531) := bf533 +machine-$(CONFIG_BF532) := bf533 +machine-$(CONFIG_BF533) := bf533 +machine-$(CONFIG_BF534) := bf537 +machine-$(CONFIG_BF536) := bf537 +machine-$(CONFIG_BF537) := bf537 +machine-$(CONFIG_BF561) := bf561 +MACHINE := $(machine-y) +export MACHINE + + +head-y := arch/$(ARCH)/mach-$(MACHINE)/head.o arch/$(ARCH)/kernel/init_task.o + +core-y += arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/ arch/$(ARCH)/mach-common/ + +# If we have a machine-specific directory, then include it in the build. +ifneq ($(machine-y),) +core-y += arch/$(ARCH)/mach-$(MACHINE)/ +core-y += arch/$(ARCH)/mach-$(MACHINE)/boards/ +endif + +libs-y += arch/$(ARCH)/lib/ + +drivers-$(CONFIG_OPROFILE) += arch/$(ARCH)/oprofile/ + + + +# Update machine arch symlinks if something which affects +# them changed. We use .mach to indicate when they were updated +# last, otherwise make uses the target directory mtime. + +include/asm-blackfin/.mach: $(wildcard include/config/arch/*.h) include/config/auto.conf + @echo ' SYMLINK include/asm-$(ARCH)/mach-$(MACHINE) -> include/asm-$(ARCH)/mach' +ifneq ($(KBUILD_SRC),) + $(Q)mkdir -p include/asm-$(ARCH) + $(Q)ln -fsn $(srctree)/include/asm-$(ARCH)/mach-$(MACHINE) include/asm-$(ARCH)/mach +else + $(Q)ln -fsn mach-$(MACHINE) include/asm-$(ARCH)/mach +endif + @touch $@ + +CLEAN_FILES += \ + include/asm-$(ARCH)/asm-offsets.h \ + arch/$(ARCH)/kernel/asm-offsets.s \ + include/asm-$(ARCH)/mach \ + include/asm-$(ARCH)/.mach + +archprepare: include/asm-blackfin/.mach +archclean: + $(Q)$(MAKE) $(clean)=$(boot) + + +all: vmImage +boot := arch/$(ARCH)/boot +BOOT_TARGETS = vmImage +.PHONY: $(BOOT_TARGETS) +$(BOOT_TARGETS): vmlinux + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ +define archhelp + echo '* vmImage - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage)' +endef diff --git a/arch/blackfin/boot/Makefile b/arch/blackfin/boot/Makefile new file mode 100644 index 000000000000..49e8098d4c21 --- /dev/null +++ b/arch/blackfin/boot/Makefile @@ -0,0 +1,27 @@ +# +# arch/blackfin/boot/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# + +MKIMAGE := $(srctree)/scripts/mkuboot.sh + +targets := vmImage +extra-y += vmlinux.bin vmlinux.gz + +quiet_cmd_uimage = UIMAGE $@ + cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \ + -C gzip -a $(CONFIG_BOOT_LOAD) -e $(CONFIG_BOOT_LOAD) -n 'Linux-$(KERNELRELEASE)' \ + -d $< $@ + +$(obj)/vmlinux.bin: vmlinux FORCE + $(call if_changed,objcopy) + +$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE + $(call if_changed,gzip) + +$(obj)/vmImage: $(obj)/vmlinux.gz + $(call if_changed,uimage) + @echo 'Kernel: $@ is ready' diff --git a/arch/blackfin/defconfig b/arch/blackfin/defconfig new file mode 100644 index 000000000000..d5904ca994cf --- /dev/null +++ b/arch/blackfin/defconfig @@ -0,0 +1,1314 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.20 +# +# CONFIG_MMU is not set +# CONFIG_FPU is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BFIN=y +CONFIG_SEMAPHORE_SLEEPERS=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_UCLINUX=y +CONFIG_FORCE_MAX_ZONEORDER=14 +CONFIG_IRQCHIP_DEMUX_GPIO=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +# CONFIG_LIMIT_PAGECACHE is not set +CONFIG_BUDDY=y +# CONFIG_NP2 is not set +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +# CONFIG_IOSCHED_DEADLINE is not set +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Blackfin Processor Options +# + +# +# Processor and Board Settings +# +# CONFIG_BF531 is not set +# CONFIG_BF532 is not set +# CONFIG_BF533 is not set +# CONFIG_BF534 is not set +# CONFIG_BF535 is not set +# CONFIG_BF536 is not set +CONFIG_BF537=y +# CONFIG_BF561 is not set +CONFIG_BF_REV_0_2=y +# CONFIG_BF_REV_0_3 is not set +# CONFIG_BF_REV_0_4 is not set +# CONFIG_BF_REV_0_5 is not set +CONFIG_BLACKFIN=y +CONFIG_BFIN_SINGLE_CORE=y +# CONFIG_BFIN533_EZKIT is not set +# CONFIG_BFIN533_STAMP is not set +CONFIG_BFIN537_STAMP=y +# CONFIG_BFIN533_BLUETECHNIX_CM is not set +# CONFIG_BFIN537_BLUETECHNIX_CM is not set +# CONFIG_BFIN561_BLUETECHNIX_CM is not set +# CONFIG_BFIN561_EZKIT is not set +# CONFIG_PNAV10 is not set +# CONFIG_GENERIC_BOARD is not set +CONFIG_MEM_MT48LC32M8A2_75=y +CONFIG_IRQ_PLL_WAKEUP=7 + +# +# BF537 Specific Configuration +# + +# +# PORT F/G Selection +# +CONFIG_BF537_PORT_F=y +# CONFIG_BF537_PORT_G is not set +# CONFIG_BF537_PORT_H is not set + +# +# Interrupt Priority Assignment +# + +# +# Priority +# +CONFIG_IRQ_DMA_ERROR=7 +CONFIG_IRQ_ERROR=7 +CONFIG_IRQ_RTC=8 +CONFIG_IRQ_PPI=8 +CONFIG_IRQ_SPORT0_RX=9 +CONFIG_IRQ_SPORT0_TX=9 +CONFIG_IRQ_SPORT1_RX=9 +CONFIG_IRQ_SPORT1_TX=9 +CONFIG_IRQ_TWI=10 +CONFIG_IRQ_SPI=10 +CONFIG_IRQ_UART0_RX=10 +CONFIG_IRQ_UART0_TX=10 +CONFIG_IRQ_UART1_RX=10 +CONFIG_IRQ_UART1_TX=10 +CONFIG_IRQ_CAN_RX=11 +CONFIG_IRQ_CAN_TX=11 +CONFIG_IRQ_MAC_RX=11 +CONFIG_IRQ_MAC_TX=11 +CONFIG_IRQ_TMR0=12 +CONFIG_IRQ_TMR1=12 +CONFIG_IRQ_TMR2=12 +CONFIG_IRQ_TMR3=12 +CONFIG_IRQ_TMR4=12 +CONFIG_IRQ_TMR5=12 +CONFIG_IRQ_TMR6=12 +CONFIG_IRQ_TMR7=12 +CONFIG_IRQ_PROG_INTA=12 +CONFIG_IRQ_PORTG_INTB=12 +CONFIG_IRQ_MEM_DMA0=13 +CONFIG_IRQ_MEM_DMA1=13 +CONFIG_IRQ_WATCH=13 + +# +# Board customizations +# + +# +# Board Setup +# +CONFIG_CLKIN_HZ=25000000 +CONFIG_MEM_SIZE=64 +CONFIG_MEM_ADD_WIDTH=10 +CONFIG_BOOT_LOAD=0x1000 + +# +# Console UART Setup +# +# CONFIG_BAUD_9600 is not set +# CONFIG_BAUD_19200 is not set +# CONFIG_BAUD_38400 is not set +CONFIG_BAUD_57600=y +# CONFIG_BAUD_115200 is not set +CONFIG_BAUD_NO_PARITY=y +# CONFIG_BAUD_PARITY is not set +CONFIG_BAUD_1_STOPBIT=y +# CONFIG_BAUD_2_STOPBIT is not set + +# +# Blackfin Kernel Optimizations +# + +# +# Timer Tick +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 + +# +# Memory Optimizations +# +CONFIG_I_ENTRY_L1=y +CONFIG_RAMKERNEL=y +# CONFIG_ROMKERNEL is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_LARGE_ALLOCS=y +CONFIG_BFIN_DMA_5XX=y +# CONFIG_DMA_UNCACHED_2M is not set +CONFIG_DMA_UNCACHED_1M=y +# CONFIG_DMA_UNCACHED_NONE is not set + +# +# Cache Support +# +CONFIG_BLKFIN_CACHE=y +CONFIG_BLKFIN_DCACHE=y +# CONFIG_BLKFIN_CACHE_LOCK is not set +# CONFIG_BLKFIN_WB is not set +CONFIG_BLKFIN_WT=y +CONFIG_L1_MAX_PIECE=16 + +# +# Clock Settings +# +# CONFIG_BFIN_KERNEL_CLOCK is not set + +# +# Asynchonous Memory Configuration +# + +# +# EBIU_AMBCTL Global Control +# +CONFIG_C_AMCKEN=y +CONFIG_C_CDPRIO=y +# CONFIG_C_AMBEN is not set +# CONFIG_C_AMBEN_B0 is not set +# CONFIG_C_AMBEN_B0_B1 is not set +# CONFIG_C_AMBEN_B0_B1_B2 is not set +CONFIG_C_AMBEN_ALL=y + +# +# EBIU_AMBCTL Control +# +CONFIG_BANK_0=0x7BB0 +CONFIG_BANK_1=0x7BB0 +CONFIG_BANK_2=0x7BB0 +CONFIG_BANK_3=0x99B3 + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +# CONFIG_PCI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# + +# +# Executable file formats +# +CONFIG_BINFMT_ELF_FDPIC=y +CONFIG_BINFMT_FLAT=y +CONFIG_BINFMT_ZFLAT=y +# CONFIG_BINFMT_SHARED_FLAT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set +# CONFIG_PM_SYSFS_DEPRECATED is not set +CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y +# CONFIG_PM_WAKEUP_BY_GPIO is not set +# CONFIG_PM_WAKEUP_GPIO_API is not set +CONFIG_PM_WAKEUP_SIC_IWR=0x80000000 + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETLABEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +# CONFIG_IRDA_FAST_RR is not set +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# Old SIR device drivers +# +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_MW320D=m +CONFIG_MTD_RAM=y +CONFIG_MTD_ROM=m +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_BF5xx=m +CONFIG_BFIN_FLASH_SIZE=0x400000 +CONFIG_EBIU_FLASH_BASE=0x20000000 + +# +# FLASH_EBIU_AMBCTL Control +# +CONFIG_BFIN_FLASH_BANK_0=0x7BB0 +CONFIG_BFIN_FLASH_BANK_1=0x7BB0 +CONFIG_BFIN_FLASH_BANK_2=0x7BB0 +CONFIG_BFIN_FLASH_BANK_3=0x7BB0 +CONFIG_MTD_UCLINUX=y +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_BFIN=m +CONFIG_BFIN_NAND_BASE=0x20212000 +CONFIG_BFIN_NAND_CLE=2 +CONFIG_BFIN_NAND_ALE=1 +CONFIG_BFIN_NAND_READY=3 +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# Misc devices +# +# CONFIG_TIFM_CORE is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_NETLINK is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_SMC91X is not set +CONFIG_BFIN_MAC=y +CONFIG_BFIN_MAC_USE_L1=y +CONFIG_BFIN_TX_DESC_NUM=10 +CONFIG_BFIN_RX_DESC_NUM=20 +# CONFIG_BFIN_MAC_RMII is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_UINPUT is not set +# CONFIG_BF53X_PFBUTTONS is not set +CONFIG_TWI_KEYPAD=m +CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=72 + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_AD9960 is not set +# CONFIG_SPI_ADC_BF533 is not set +# CONFIG_BF533_PFLAGS is not set +# CONFIG_BF5xx_PPIFCD is not set +# CONFIG_BF5xx_TIMERS is not set +# CONFIG_BF5xx_PPI is not set +CONFIG_BFIN_SPORT=y +# CONFIG_BFIN_TIMER_LATENCY is not set +CONFIG_TWI_LCD=m +CONFIG_TWI_LCD_SLAVE_ADDR=34 +# CONFIG_AD5304 is not set +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_BFIN=y +CONFIG_SERIAL_BFIN_CONSOLE=y +CONFIG_SERIAL_BFIN_DMA=y +# CONFIG_SERIAL_BFIN_PIO is not set +CONFIG_SERIAL_BFIN_UART0=y +# CONFIG_BFIN_UART0_CTSRTS is not set +# CONFIG_SERIAL_BFIN_UART1 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_BFIN_SPORT is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# CAN, the car bus and industrial fieldbus +# +CONFIG_CAN4LINUX=y + +# +# linux embedded drivers +# +# CONFIG_CAN_MCF5282 is not set +# CONFIG_CAN_UNCTWINCAN is not set +CONFIG_CAN_BLACKFIN=m + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_GEN_RTC is not set +CONFIG_BLACKFIN_DPMC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=m +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_BFIN_GPIO is not set +CONFIG_I2C_BFIN_TWI=m +CONFIG_TWICLK_KHZ=50 +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +CONFIG_SENSORS_AD5252=m +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8575 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +CONFIG_SPI_BFIN=y + +# +# SPI Protocol Masters +# + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FIRMWARE_EDID=y +CONFIG_FB=m +CONFIG_FB_CFB_FILLRECT=m +CONFIG_FB_CFB_COPYAREA=m +CONFIG_FB_CFB_IMAGEBLIT=m +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_BFIN_7171=m +CONFIG_FB_BFIN_7393=m +CONFIG_NTSC=y +# CONFIG_PAL is not set +# CONFIG_NTSC_640x480 is not set +# CONFIG_PAL_640x480 is not set +# CONFIG_NTSC_YCBCR is not set +# CONFIG_PAL_YCBCR is not set +CONFIG_ADV7393_1XMEM=y +# CONFIG_ADV7393_2XMEM is not set +CONFIG_FB_BF537_LQ035=m +CONFIG_LQ035_SLAVE_ADDR=0x58 +# CONFIG_FB_BFIN_LANDSCAPE is not set +# CONFIG_FB_BFIN_BGR is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_BACKLIGHT_DEVICE=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_DEVICE=y + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +# CONFIG_SND_SEQUENCER is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# HID Devices +# +CONFIG_HID=y + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_SPI_MMC is not set +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set + +# +# RTC drivers +# +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_V3020 is not set +CONFIG_RTC_DRV_BFIN=y + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# Virtualization +# + +# +# PBX support +# +# CONFIG_PBX is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_YAFFS_FS=m +CONFIG_YAFFS_YAFFS1=y +# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_YAFFS2=y +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_HUNT_FOR_ZERO=y +# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set +# CONFIG_BOOTPARAM is not set +# CONFIG_NO_KERNEL_MSG is not set +CONFIG_CPLB_INFO=y +# CONFIG_NO_ACCESS_CHECK is not set + +# +# Security options +# +# CONFIG_KEYS is not set +CONFIG_SECURITY=y +# CONFIG_SECURITY_NETWORK is not set +CONFIG_SECURITY_CAPABILITIES=y + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=m +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_PLIST=y +CONFIG_IOMAP_COPY=y diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile new file mode 100644 index 000000000000..f3b7d2f9d49c --- /dev/null +++ b/arch/blackfin/kernel/Makefile @@ -0,0 +1,14 @@ +# +# arch/blackfin/kernel/Makefile +# + +extra-y := init_task.o vmlinux.lds + +obj-y := \ + entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \ + sys_bfin.o time.o traps.o irqchip.o dma-mapping.o bfin_gpio.o \ + flat.o + +obj-$(CONFIG_MODULES) += module.o +obj-$(CONFIG_BFIN_DMA_5XX) += bfin_dma_5xx.o +obj-$(CONFIG_DUAL_CORE_TEST_MODULE) += dualcore_test.o diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c new file mode 100644 index 000000000000..41d9a9f89700 --- /dev/null +++ b/arch/blackfin/kernel/asm-offsets.c @@ -0,0 +1,136 @@ +/* + * File: arch/blackfin/kernel/asm-offsets.c + * Based on: + * Author: + * + * Created: + * Description: generate definitions needed by assembly language modules. + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DEFINE(sym, val) \ + asm volatile("\n->" #sym " %0 " #val : : "i" (val)) + +int main(void) +{ + /* offsets into the task struct */ + DEFINE(TASK_STATE, offsetof(struct task_struct, state)); + DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags)); + DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace)); + DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked)); + DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); + DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, thread_info)); + DEFINE(TASK_MM, offsetof(struct task_struct, mm)); + DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); + DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, pending)); + + /* offsets into the irq_cpustat_t struct */ + DEFINE(CPUSTAT_SOFTIRQ_PENDING, + offsetof(irq_cpustat_t, __softirq_pending)); + + /* offsets into the thread struct */ + DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); + DEFINE(THREAD_USP, offsetof(struct thread_struct, usp)); + DEFINE(THREAD_SR, offsetof(struct thread_struct, seqstat)); + DEFINE(PT_SR, offsetof(struct thread_struct, seqstat)); + DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0)); + DEFINE(THREAD_PC, offsetof(struct thread_struct, pc)); + DEFINE(KERNEL_STACK_SIZE, THREAD_SIZE); + + /* offsets into the pt_regs */ + DEFINE(PT_ORIG_P0, offsetof(struct pt_regs, orig_p0)); + DEFINE(PT_ORIG_PC, offsetof(struct pt_regs, orig_pc)); + DEFINE(PT_R0, offsetof(struct pt_regs, r0)); + DEFINE(PT_R1, offsetof(struct pt_regs, r1)); + DEFINE(PT_R2, offsetof(struct pt_regs, r2)); + DEFINE(PT_R3, offsetof(struct pt_regs, r3)); + DEFINE(PT_R4, offsetof(struct pt_regs, r4)); + DEFINE(PT_R5, offsetof(struct pt_regs, r5)); + DEFINE(PT_R6, offsetof(struct pt_regs, r6)); + DEFINE(PT_R7, offsetof(struct pt_regs, r7)); + + DEFINE(PT_P0, offsetof(struct pt_regs, p0)); + DEFINE(PT_P1, offsetof(struct pt_regs, p1)); + DEFINE(PT_P2, offsetof(struct pt_regs, p2)); + DEFINE(PT_P3, offsetof(struct pt_regs, p3)); + DEFINE(PT_P4, offsetof(struct pt_regs, p4)); + DEFINE(PT_P5, offsetof(struct pt_regs, p5)); + + DEFINE(PT_FP, offsetof(struct pt_regs, fp)); + DEFINE(PT_USP, offsetof(struct pt_regs, usp)); + DEFINE(PT_I0, offsetof(struct pt_regs, i0)); + DEFINE(PT_I1, offsetof(struct pt_regs, i1)); + DEFINE(PT_I2, offsetof(struct pt_regs, i2)); + DEFINE(PT_I3, offsetof(struct pt_regs, i3)); + DEFINE(PT_M0, offsetof(struct pt_regs, m0)); + DEFINE(PT_M1, offsetof(struct pt_regs, m1)); + DEFINE(PT_M2, offsetof(struct pt_regs, m2)); + DEFINE(PT_M3, offsetof(struct pt_regs, m3)); + DEFINE(PT_L0, offsetof(struct pt_regs, l0)); + DEFINE(PT_L1, offsetof(struct pt_regs, l1)); + DEFINE(PT_L2, offsetof(struct pt_regs, l2)); + DEFINE(PT_L3, offsetof(struct pt_regs, l3)); + DEFINE(PT_B0, offsetof(struct pt_regs, b0)); + DEFINE(PT_B1, offsetof(struct pt_regs, b1)); + DEFINE(PT_B2, offsetof(struct pt_regs, b2)); + DEFINE(PT_B3, offsetof(struct pt_regs, b3)); + DEFINE(PT_A0X, offsetof(struct pt_regs, a0x)); + DEFINE(PT_A0W, offsetof(struct pt_regs, a0w)); + DEFINE(PT_A1X, offsetof(struct pt_regs, a1x)); + DEFINE(PT_A1W, offsetof(struct pt_regs, a1w)); + DEFINE(PT_LC0, offsetof(struct pt_regs, lc0)); + DEFINE(PT_LC1, offsetof(struct pt_regs, lc1)); + DEFINE(PT_LT0, offsetof(struct pt_regs, lt0)); + DEFINE(PT_LT1, offsetof(struct pt_regs, lt1)); + DEFINE(PT_LB0, offsetof(struct pt_regs, lb0)); + DEFINE(PT_LB1, offsetof(struct pt_regs, lb1)); + DEFINE(PT_ASTAT, offsetof(struct pt_regs, astat)); + DEFINE(PT_RESERVED, offsetof(struct pt_regs, reserved)); + DEFINE(PT_RETS, offsetof(struct pt_regs, rets)); + DEFINE(PT_PC, offsetof(struct pt_regs, pc)); + DEFINE(PT_RETX, offsetof(struct pt_regs, retx)); + DEFINE(PT_RETN, offsetof(struct pt_regs, retn)); + DEFINE(PT_RETE, offsetof(struct pt_regs, rete)); + DEFINE(PT_SEQSTAT, offsetof(struct pt_regs, seqstat)); + DEFINE(PT_SYSCFG, offsetof(struct pt_regs, syscfg)); + DEFINE(PT_IPEND, offsetof(struct pt_regs, ipend)); + DEFINE(SIZEOF_PTREGS, sizeof(struct pt_regs)); + DEFINE(PT_TEXT_ADDR, sizeof(struct pt_regs)); /* Needed by gdb */ + DEFINE(PT_TEXT_END_ADDR, 4 + sizeof(struct pt_regs));/* Needed by gdb */ + DEFINE(PT_DATA_ADDR, 8 + sizeof(struct pt_regs)); /* Needed by gdb */ + DEFINE(PT_FDPIC_EXEC, 12 + sizeof(struct pt_regs)); /* Needed by gdb */ + DEFINE(PT_FDPIC_INTERP, 16 + sizeof(struct pt_regs));/* Needed by gdb */ + + /* signal defines */ + DEFINE(SIGSEGV, SIGSEGV); + DEFINE(SIGTRAP, SIGTRAP); + + return 0; +} diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c new file mode 100644 index 000000000000..8ea079ebecb5 --- /dev/null +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -0,0 +1,742 @@ +/* + * File: arch/blackfin/kernel/bfin_dma_5xx.c + * Based on: + * Author: + * + * Created: + * Description: This file contains the simple DMA Implementation for Blackfin + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +/* Remove unused code not exported by symbol or internally called */ +#define REMOVE_DEAD_CODE + +/************************************************************************** + * Global Variables +***************************************************************************/ + +static struct dma_channel dma_ch[MAX_BLACKFIN_DMA_CHANNEL]; +#if defined (CONFIG_BF561) +static struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = { + (struct dma_register *) DMA1_0_NEXT_DESC_PTR, + (struct dma_register *) DMA1_1_NEXT_DESC_PTR, + (struct dma_register *) DMA1_2_NEXT_DESC_PTR, + (struct dma_register *) DMA1_3_NEXT_DESC_PTR, + (struct dma_register *) DMA1_4_NEXT_DESC_PTR, + (struct dma_register *) DMA1_5_NEXT_DESC_PTR, + (struct dma_register *) DMA1_6_NEXT_DESC_PTR, + (struct dma_register *) DMA1_7_NEXT_DESC_PTR, + (struct dma_register *) DMA1_8_NEXT_DESC_PTR, + (struct dma_register *) DMA1_9_NEXT_DESC_PTR, + (struct dma_register *) DMA1_10_NEXT_DESC_PTR, + (struct dma_register *) DMA1_11_NEXT_DESC_PTR, + (struct dma_register *) DMA2_0_NEXT_DESC_PTR, + (struct dma_register *) DMA2_1_NEXT_DESC_PTR, + (struct dma_register *) DMA2_2_NEXT_DESC_PTR, + (struct dma_register *) DMA2_3_NEXT_DESC_PTR, + (struct dma_register *) DMA2_4_NEXT_DESC_PTR, + (struct dma_register *) DMA2_5_NEXT_DESC_PTR, + (struct dma_register *) DMA2_6_NEXT_DESC_PTR, + (struct dma_register *) DMA2_7_NEXT_DESC_PTR, + (struct dma_register *) DMA2_8_NEXT_DESC_PTR, + (struct dma_register *) DMA2_9_NEXT_DESC_PTR, + (struct dma_register *) DMA2_10_NEXT_DESC_PTR, + (struct dma_register *) DMA2_11_NEXT_DESC_PTR, + (struct dma_register *) MDMA1_D0_NEXT_DESC_PTR, + (struct dma_register *) MDMA1_S0_NEXT_DESC_PTR, + (struct dma_register *) MDMA1_D1_NEXT_DESC_PTR, + (struct dma_register *) MDMA1_S1_NEXT_DESC_PTR, + (struct dma_register *) MDMA2_D0_NEXT_DESC_PTR, + (struct dma_register *) MDMA2_S0_NEXT_DESC_PTR, + (struct dma_register *) MDMA2_D1_NEXT_DESC_PTR, + (struct dma_register *) MDMA2_S1_NEXT_DESC_PTR, + (struct dma_register *) IMDMA_D0_NEXT_DESC_PTR, + (struct dma_register *) IMDMA_S0_NEXT_DESC_PTR, + (struct dma_register *) IMDMA_D1_NEXT_DESC_PTR, + (struct dma_register *) IMDMA_S1_NEXT_DESC_PTR, +}; +#else +static struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = { + (struct dma_register *) DMA0_NEXT_DESC_PTR, + (struct dma_register *) DMA1_NEXT_DESC_PTR, + (struct dma_register *) DMA2_NEXT_DESC_PTR, + (struct dma_register *) DMA3_NEXT_DESC_PTR, + (struct dma_register *) DMA4_NEXT_DESC_PTR, + (struct dma_register *) DMA5_NEXT_DESC_PTR, + (struct dma_register *) DMA6_NEXT_DESC_PTR, + (struct dma_register *) DMA7_NEXT_DESC_PTR, +#if (defined(CONFIG_BF537) || defined(CONFIG_BF534) || defined(CONFIG_BF536)) + (struct dma_register *) DMA8_NEXT_DESC_PTR, + (struct dma_register *) DMA9_NEXT_DESC_PTR, + (struct dma_register *) DMA10_NEXT_DESC_PTR, + (struct dma_register *) DMA11_NEXT_DESC_PTR, +#endif + (struct dma_register *) MDMA_D0_NEXT_DESC_PTR, + (struct dma_register *) MDMA_S0_NEXT_DESC_PTR, + (struct dma_register *) MDMA_D1_NEXT_DESC_PTR, + (struct dma_register *) MDMA_S1_NEXT_DESC_PTR, +}; +#endif + +/*------------------------------------------------------------------------------ + * Set the Buffer Clear bit in the Configuration register of specific DMA + * channel. This will stop the descriptor based DMA operation. + *-----------------------------------------------------------------------------*/ +static void clear_dma_buffer(unsigned int channel) +{ + dma_ch[channel].regs->cfg |= RESTART; + SSYNC(); + dma_ch[channel].regs->cfg &= ~RESTART; + SSYNC(); +} + +int __init blackfin_dma_init(void) +{ + int i; + + printk(KERN_INFO "Blackfin DMA Controller\n"); + + for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; i++) { + dma_ch[i].chan_status = DMA_CHANNEL_FREE; + dma_ch[i].regs = base_addr[i]; + mutex_init(&(dma_ch[i].dmalock)); + } + + return 0; +} + +arch_initcall(blackfin_dma_init); + +/* + * Form the channel find the irq number for that channel. + */ +#if !defined(CONFIG_BF561) + +static int bf533_channel2irq(unsigned int channel) +{ + int ret_irq = -1; + + switch (channel) { + case CH_PPI: + ret_irq = IRQ_PPI; + break; + +#if (defined(CONFIG_BF537) || defined(CONFIG_BF534) || defined(CONFIG_BF536)) + case CH_EMAC_RX: + ret_irq = IRQ_MAC_RX; + break; + + case CH_EMAC_TX: + ret_irq = IRQ_MAC_TX; + break; + + case CH_UART1_RX: + ret_irq = IRQ_UART1_RX; + break; + + case CH_UART1_TX: + ret_irq = IRQ_UART1_TX; + break; +#endif + + case CH_SPORT0_RX: + ret_irq = IRQ_SPORT0_RX; + break; + + case CH_SPORT0_TX: + ret_irq = IRQ_SPORT0_TX; + break; + + case CH_SPORT1_RX: + ret_irq = IRQ_SPORT1_RX; + break; + + case CH_SPORT1_TX: + ret_irq = IRQ_SPORT1_TX; + break; + + case CH_SPI: + ret_irq = IRQ_SPI; + break; + + case CH_UART_RX: + ret_irq = IRQ_UART_RX; + break; + + case CH_UART_TX: + ret_irq = IRQ_UART_TX; + break; + + case CH_MEM_STREAM0_SRC: + case CH_MEM_STREAM0_DEST: + ret_irq = IRQ_MEM_DMA0; + break; + + case CH_MEM_STREAM1_SRC: + case CH_MEM_STREAM1_DEST: + ret_irq = IRQ_MEM_DMA1; + break; + } + return ret_irq; +} + +# define channel2irq(channel) bf533_channel2irq(channel) + +#else + +static int bf561_channel2irq(unsigned int channel) +{ + int ret_irq = -1; + + switch (channel) { + case CH_PPI0: + ret_irq = IRQ_PPI0; + break; + case CH_PPI1: + ret_irq = IRQ_PPI1; + break; + case CH_SPORT0_RX: + ret_irq = IRQ_SPORT0_RX; + break; + case CH_SPORT0_TX: + ret_irq = IRQ_SPORT0_TX; + break; + case CH_SPORT1_RX: + ret_irq = IRQ_SPORT1_RX; + break; + case CH_SPORT1_TX: + ret_irq = IRQ_SPORT1_TX; + break; + case CH_SPI: + ret_irq = IRQ_SPI; + break; + case CH_UART_RX: + ret_irq = IRQ_UART_RX; + break; + case CH_UART_TX: + ret_irq = IRQ_UART_TX; + break; + + case CH_MEM_STREAM0_SRC: + case CH_MEM_STREAM0_DEST: + ret_irq = IRQ_MEM_DMA0; + break; + case CH_MEM_STREAM1_SRC: + case CH_MEM_STREAM1_DEST: + ret_irq = IRQ_MEM_DMA1; + break; + case CH_MEM_STREAM2_SRC: + case CH_MEM_STREAM2_DEST: + ret_irq = IRQ_MEM_DMA2; + break; + case CH_MEM_STREAM3_SRC: + case CH_MEM_STREAM3_DEST: + ret_irq = IRQ_MEM_DMA3; + break; + + case CH_IMEM_STREAM0_SRC: + case CH_IMEM_STREAM0_DEST: + ret_irq = IRQ_IMEM_DMA0; + break; + case CH_IMEM_STREAM1_SRC: + case CH_IMEM_STREAM1_DEST: + ret_irq = IRQ_IMEM_DMA1; + break; + } + return ret_irq; +} + +# define channel2irq(channel) bf561_channel2irq(channel) + +#endif + +/*------------------------------------------------------------------------------ + * Request the specific DMA channel from the system. + *-----------------------------------------------------------------------------*/ +int request_dma(unsigned int channel, char *device_id) +{ + + pr_debug("request_dma() : BEGIN \n"); + mutex_lock(&(dma_ch[channel].dmalock)); + + if ((dma_ch[channel].chan_status == DMA_CHANNEL_REQUESTED) + || (dma_ch[channel].chan_status == DMA_CHANNEL_ENABLED)) { + mutex_unlock(&(dma_ch[channel].dmalock)); + pr_debug("DMA CHANNEL IN USE \n"); + return -EBUSY; + } else { + dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED; + pr_debug("DMA CHANNEL IS ALLOCATED \n"); + } + + mutex_unlock(&(dma_ch[channel].dmalock)); + + dma_ch[channel].device_id = device_id; + dma_ch[channel].irq_callback = NULL; + + /* This is to be enabled by putting a restriction - + * you have to request DMA, before doing any operations on + * descriptor/channel + */ + pr_debug("request_dma() : END \n"); + return channel; +} +EXPORT_SYMBOL(request_dma); + +int set_dma_callback(unsigned int channel, dma_interrupt_t callback, void *data) +{ + int ret_irq = 0; + + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + if (callback != NULL) { + int ret_val; + ret_irq = channel2irq(channel); + + dma_ch[channel].data = data; + + ret_val = + request_irq(ret_irq, (void *)callback, IRQF_DISABLED, + dma_ch[channel].device_id, data); + if (ret_val) { + printk(KERN_NOTICE + "Request irq in DMA engine failed.\n"); + return -EPERM; + } + dma_ch[channel].irq_callback = callback; + } + return 0; +} +EXPORT_SYMBOL(set_dma_callback); + +void free_dma(unsigned int channel) +{ + int ret_irq; + + pr_debug("freedma() : BEGIN \n"); + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + /* Halt the DMA */ + disable_dma(channel); + clear_dma_buffer(channel); + + if (dma_ch[channel].irq_callback != NULL) { + ret_irq = channel2irq(channel); + free_irq(ret_irq, dma_ch[channel].data); + } + + /* Clear the DMA Variable in the Channel */ + mutex_lock(&(dma_ch[channel].dmalock)); + dma_ch[channel].chan_status = DMA_CHANNEL_FREE; + mutex_unlock(&(dma_ch[channel].dmalock)); + + pr_debug("freedma() : END \n"); +} +EXPORT_SYMBOL(free_dma); + +void dma_enable_irq(unsigned int channel) +{ + int ret_irq; + + pr_debug("dma_enable_irq() : BEGIN \n"); + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + ret_irq = channel2irq(channel); + enable_irq(ret_irq); +} +EXPORT_SYMBOL(dma_enable_irq); + +void dma_disable_irq(unsigned int channel) +{ + int ret_irq; + + pr_debug("dma_disable_irq() : BEGIN \n"); + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + ret_irq = channel2irq(channel); + disable_irq(ret_irq); +} +EXPORT_SYMBOL(dma_disable_irq); + +int dma_channel_active(unsigned int channel) +{ + if (dma_ch[channel].chan_status == DMA_CHANNEL_FREE) { + return 0; + } else { + return 1; + } +} +EXPORT_SYMBOL(dma_channel_active); + +/*------------------------------------------------------------------------------ +* stop the specific DMA channel. +*-----------------------------------------------------------------------------*/ +void disable_dma(unsigned int channel) +{ + pr_debug("stop_dma() : BEGIN \n"); + + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + dma_ch[channel].regs->cfg &= ~DMAEN; /* Clean the enable bit */ + SSYNC(); + dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED; + /* Needs to be enabled Later */ + pr_debug("stop_dma() : END \n"); + return; +} +EXPORT_SYMBOL(disable_dma); + +void enable_dma(unsigned int channel) +{ + pr_debug("enable_dma() : BEGIN \n"); + + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + dma_ch[channel].chan_status = DMA_CHANNEL_ENABLED; + dma_ch[channel].regs->curr_x_count = 0; + dma_ch[channel].regs->curr_y_count = 0; + + dma_ch[channel].regs->cfg |= DMAEN; /* Set the enable bit */ + SSYNC(); + pr_debug("enable_dma() : END \n"); + return; +} +EXPORT_SYMBOL(enable_dma); + +/*------------------------------------------------------------------------------ +* Set the Start Address register for the specific DMA channel +* This function can be used for register based DMA, +* to setup the start address +* addr: Starting address of the DMA Data to be transferred. +*-----------------------------------------------------------------------------*/ +void set_dma_start_addr(unsigned int channel, unsigned long addr) +{ + pr_debug("set_dma_start_addr() : BEGIN \n"); + + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + dma_ch[channel].regs->start_addr = addr; + SSYNC(); + pr_debug("set_dma_start_addr() : END\n"); +} +EXPORT_SYMBOL(set_dma_start_addr); + +void set_dma_next_desc_addr(unsigned int channel, unsigned long addr) +{ + pr_debug("set_dma_next_desc_addr() : BEGIN \n"); + + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + dma_ch[channel].regs->next_desc_ptr = addr; + SSYNC(); + pr_debug("set_dma_start_addr() : END\n"); +} +EXPORT_SYMBOL(set_dma_next_desc_addr); + +void set_dma_x_count(unsigned int channel, unsigned short x_count) +{ + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + dma_ch[channel].regs->x_count = x_count; + SSYNC(); +} +EXPORT_SYMBOL(set_dma_x_count); + +void set_dma_y_count(unsigned int channel, unsigned short y_count) +{ + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + dma_ch[channel].regs->y_count = y_count; + SSYNC(); +} +EXPORT_SYMBOL(set_dma_y_count); + +void set_dma_x_modify(unsigned int channel, short x_modify) +{ + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + dma_ch[channel].regs->x_modify = x_modify; + SSYNC(); +} +EXPORT_SYMBOL(set_dma_x_modify); + +void set_dma_y_modify(unsigned int channel, short y_modify) +{ + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + dma_ch[channel].regs->y_modify = y_modify; + SSYNC(); +} +EXPORT_SYMBOL(set_dma_y_modify); + +void set_dma_config(unsigned int channel, unsigned short config) +{ + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + dma_ch[channel].regs->cfg = config; + SSYNC(); +} +EXPORT_SYMBOL(set_dma_config); + +unsigned short +set_bfin_dma_config(char direction, char flow_mode, + char intr_mode, char dma_mode, char width) +{ + unsigned short config; + + config = + ((direction << 1) | (width << 2) | (dma_mode << 4) | + (intr_mode << 6) | (flow_mode << 12) | RESTART); + return config; +} +EXPORT_SYMBOL(set_bfin_dma_config); + +void set_dma_sg(unsigned int channel, struct dmasg * sg, int nr_sg) +{ + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + dma_ch[channel].regs->cfg |= ((nr_sg & 0x0F) << 8); + + dma_ch[channel].regs->next_desc_ptr = (unsigned int)sg; + + SSYNC(); +} +EXPORT_SYMBOL(set_dma_sg); + +/*------------------------------------------------------------------------------ + * Get the DMA status of a specific DMA channel from the system. + *-----------------------------------------------------------------------------*/ +unsigned short get_dma_curr_irqstat(unsigned int channel) +{ + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + return dma_ch[channel].regs->irq_status; +} +EXPORT_SYMBOL(get_dma_curr_irqstat); + +/*------------------------------------------------------------------------------ + * Clear the DMA_DONE bit in DMA status. Stop the DMA completion interrupt. + *-----------------------------------------------------------------------------*/ +void clear_dma_irqstat(unsigned int channel) +{ + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + dma_ch[channel].regs->irq_status |= 3; +} +EXPORT_SYMBOL(clear_dma_irqstat); + +/*------------------------------------------------------------------------------ + * Get current DMA xcount of a specific DMA channel from the system. + *-----------------------------------------------------------------------------*/ +unsigned short get_dma_curr_xcount(unsigned int channel) +{ + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + return dma_ch[channel].regs->curr_x_count; +} +EXPORT_SYMBOL(get_dma_curr_xcount); + +/*------------------------------------------------------------------------------ + * Get current DMA ycount of a specific DMA channel from the system. + *-----------------------------------------------------------------------------*/ +unsigned short get_dma_curr_ycount(unsigned int channel) +{ + BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE + && channel < MAX_BLACKFIN_DMA_CHANNEL)); + + return dma_ch[channel].regs->curr_y_count; +} +EXPORT_SYMBOL(get_dma_curr_ycount); + +void *dma_memcpy(void *dest, const void *src, size_t size) +{ + int direction; /* 1 - address decrease, 0 - address increase */ + int flag_align; /* 1 - address aligned, 0 - address unaligned */ + int flag_2D; /* 1 - 2D DMA needed, 0 - 1D DMA needed */ + + if (size <= 0) + return NULL; + + if ((unsigned long)src < memory_end) + blackfin_dcache_flush_range((unsigned int)src, + (unsigned int)(src + size)); + + bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); + + if ((unsigned long)src < (unsigned long)dest) + direction = 1; + else + direction = 0; + + if ((((unsigned long)dest % 2) == 0) && (((unsigned long)src % 2) == 0) + && ((size % 2) == 0)) + flag_align = 1; + else + flag_align = 0; + + if (size > 0x10000) /* size > 64K */ + flag_2D = 1; + else + flag_2D = 0; + + /* Setup destination and source start address */ + if (direction) { + if (flag_align) { + bfin_write_MDMA_D0_START_ADDR(dest + size - 2); + bfin_write_MDMA_S0_START_ADDR(src + size - 2); + } else { + bfin_write_MDMA_D0_START_ADDR(dest + size - 1); + bfin_write_MDMA_S0_START_ADDR(src + size - 1); + } + } else { + bfin_write_MDMA_D0_START_ADDR(dest); + bfin_write_MDMA_S0_START_ADDR(src); + } + + /* Setup destination and source xcount */ + if (flag_2D) { + if (flag_align) { + bfin_write_MDMA_D0_X_COUNT(1024 / 2); + bfin_write_MDMA_S0_X_COUNT(1024 / 2); + } else { + bfin_write_MDMA_D0_X_COUNT(1024); + bfin_write_MDMA_S0_X_COUNT(1024); + } + bfin_write_MDMA_D0_Y_COUNT(size >> 10); + bfin_write_MDMA_S0_Y_COUNT(size >> 10); + } else { + if (flag_align) { + bfin_write_MDMA_D0_X_COUNT(size / 2); + bfin_write_MDMA_S0_X_COUNT(size / 2); + } else { + bfin_write_MDMA_D0_X_COUNT(size); + bfin_write_MDMA_S0_X_COUNT(size); + } + } + + /* Setup destination and source xmodify and ymodify */ + if (direction) { + if (flag_align) { + bfin_write_MDMA_D0_X_MODIFY(-2); + bfin_write_MDMA_S0_X_MODIFY(-2); + if (flag_2D) { + bfin_write_MDMA_D0_Y_MODIFY(-2); + bfin_write_MDMA_S0_Y_MODIFY(-2); + } + } else { + bfin_write_MDMA_D0_X_MODIFY(-1); + bfin_write_MDMA_S0_X_MODIFY(-1); + if (flag_2D) { + bfin_write_MDMA_D0_Y_MODIFY(-1); + bfin_write_MDMA_S0_Y_MODIFY(-1); + } + } + } else { + if (flag_align) { + bfin_write_MDMA_D0_X_MODIFY(2); + bfin_write_MDMA_S0_X_MODIFY(2); + if (flag_2D) { + bfin_write_MDMA_D0_Y_MODIFY(2); + bfin_write_MDMA_S0_Y_MODIFY(2); + } + } else { + bfin_write_MDMA_D0_X_MODIFY(1); + bfin_write_MDMA_S0_X_MODIFY(1); + if (flag_2D) { + bfin_write_MDMA_D0_Y_MODIFY(1); + bfin_write_MDMA_S0_Y_MODIFY(1); + } + } + } + + /* Enable source DMA */ + if (flag_2D) { + if (flag_align) { + bfin_write_MDMA_S0_CONFIG(DMAEN | DMA2D | WDSIZE_16); + bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | DMA2D | WDSIZE_16); + } else { + bfin_write_MDMA_S0_CONFIG(DMAEN | DMA2D); + bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | DMA2D); + } + } else { + if (flag_align) { + bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16); + bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16); + } else { + bfin_write_MDMA_S0_CONFIG(DMAEN); + bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN); + } + } + + while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) + ; + + bfin_write_MDMA_D0_IRQ_STATUS(bfin_read_MDMA_D0_IRQ_STATUS() | + (DMA_DONE | DMA_ERR)); + + bfin_write_MDMA_S0_CONFIG(0); + bfin_write_MDMA_D0_CONFIG(0); + + if ((unsigned long)dest < memory_end) + blackfin_dcache_invalidate_range((unsigned int)dest, + (unsigned int)(dest + size)); + + return dest; +} +EXPORT_SYMBOL(dma_memcpy); + +void *safe_dma_memcpy(void *dest, const void *src, size_t size) +{ + int flags = 0; + void *addr; + local_irq_save(flags); + addr = dma_memcpy(dest, src, size); + local_irq_restore(flags); + return addr; +} +EXPORT_SYMBOL(safe_dma_memcpy); diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c new file mode 100644 index 000000000000..e9f24a9a46ba --- /dev/null +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -0,0 +1,637 @@ +/* + * File: arch/blackfin/kernel/bfin_gpio.c + * Based on: + * Author: Michael Hennerich (hennerich@blackfin.uclinux.org) + * + * Created: + * Description: GPIO Abstraction Layer + * + * Modified: + * Copyright 2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* +* Number BF537/6/4 BF561 BF533/2/1 +* +* GPIO_0 PF0 PF0 PF0 +* GPIO_1 PF1 PF1 PF1 +* GPIO_2 PF2 PF2 PF2 +* GPIO_3 PF3 PF3 PF3 +* GPIO_4 PF4 PF4 PF4 +* GPIO_5 PF5 PF5 PF5 +* GPIO_6 PF6 PF6 PF6 +* GPIO_7 PF7 PF7 PF7 +* GPIO_8 PF8 PF8 PF8 +* GPIO_9 PF9 PF9 PF9 +* GPIO_10 PF10 PF10 PF10 +* GPIO_11 PF11 PF11 PF11 +* GPIO_12 PF12 PF12 PF12 +* GPIO_13 PF13 PF13 PF13 +* GPIO_14 PF14 PF14 PF14 +* GPIO_15 PF15 PF15 PF15 +* GPIO_16 PG0 PF16 +* GPIO_17 PG1 PF17 +* GPIO_18 PG2 PF18 +* GPIO_19 PG3 PF19 +* GPIO_20 PG4 PF20 +* GPIO_21 PG5 PF21 +* GPIO_22 PG6 PF22 +* GPIO_23 PG7 PF23 +* GPIO_24 PG8 PF24 +* GPIO_25 PG9 PF25 +* GPIO_26 PG10 PF26 +* GPIO_27 PG11 PF27 +* GPIO_28 PG12 PF28 +* GPIO_29 PG13 PF29 +* GPIO_30 PG14 PF30 +* GPIO_31 PG15 PF31 +* GPIO_32 PH0 PF32 +* GPIO_33 PH1 PF33 +* GPIO_34 PH2 PF34 +* GPIO_35 PH3 PF35 +* GPIO_36 PH4 PF36 +* GPIO_37 PH5 PF37 +* GPIO_38 PH6 PF38 +* GPIO_39 PH7 PF39 +* GPIO_40 PH8 PF40 +* GPIO_41 PH9 PF41 +* GPIO_42 PH10 PF42 +* GPIO_43 PH11 PF43 +* GPIO_44 PH12 PF44 +* GPIO_45 PH13 PF45 +* GPIO_46 PH14 PF46 +* GPIO_47 PH15 PF47 +*/ + +#include +#include +#include +#include +#include + +#ifdef BF533_FAMILY +static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = { + (struct gpio_port_t *) FIO_FLAG_D, +}; +#endif + +#ifdef BF537_FAMILY +static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = { + (struct gpio_port_t *) PORTFIO, + (struct gpio_port_t *) PORTGIO, + (struct gpio_port_t *) PORTHIO, +}; + +static unsigned short *port_fer[gpio_bank(MAX_BLACKFIN_GPIOS)] = { + (unsigned short *) PORTF_FER, + (unsigned short *) PORTG_FER, + (unsigned short *) PORTH_FER, +}; + +#endif + +#ifdef BF561_FAMILY +static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = { + (struct gpio_port_t *) FIO0_FLAG_D, + (struct gpio_port_t *) FIO1_FLAG_D, + (struct gpio_port_t *) FIO2_FLAG_D, +}; +#endif + +static unsigned short reserved_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; + +#ifdef CONFIG_PM +static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; +static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; +static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; + +#ifdef BF533_FAMILY +static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB}; +#endif + +#ifdef BF537_FAMILY +static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX}; +#endif + +#ifdef BF561_FAMILY +static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB}; +#endif + +#endif /* CONFIG_PM */ + +inline int check_gpio(unsigned short gpio) +{ + if (gpio > MAX_BLACKFIN_GPIOS) + return -EINVAL; + return 0; +} + +#ifdef BF537_FAMILY +void port_setup(unsigned short gpio, unsigned short usage) +{ + if (usage == GPIO_USAGE) { + if (*port_fer[gpio_bank(gpio)] & gpio_bit(gpio)) + printk(KERN_WARNING "bfin-gpio: Possible Conflict with Peripheral " + "usage and GPIO %d detected!\n", gpio); + *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio); + } else + *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio); + SSYNC(); +} +#else +# define port_setup(...) do { } while (0) +#endif + + +void default_gpio(unsigned short gpio) +{ + unsigned short bank,bitmask; + + bank = gpio_bank(gpio); + bitmask = gpio_bit(gpio); + + gpio_bankb[bank]->maska_clear = bitmask; + gpio_bankb[bank]->maskb_clear = bitmask; + SSYNC(); + gpio_bankb[bank]->inen &= ~bitmask; + gpio_bankb[bank]->dir &= ~bitmask; + gpio_bankb[bank]->polar &= ~bitmask; + gpio_bankb[bank]->both &= ~bitmask; + gpio_bankb[bank]->edge &= ~bitmask; +} + + +int __init bfin_gpio_init(void) +{ + int i; + + printk(KERN_INFO "Blackfin GPIO Controller\n"); + + for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) + reserved_map[gpio_bank(i)] = 0; + +#if defined(BF537_FAMILY) && (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) +# if defined(CONFIG_BFIN_MAC_RMII) + reserved_map[PORT_H] = 0xC373; +# else + reserved_map[PORT_H] = 0xFFFF; +# endif +#endif + + return 0; +} + +arch_initcall(bfin_gpio_init); + + +/*********************************************************** +* +* FUNCTIONS: Blackfin General Purpose Ports Access Functions +* +* INPUTS/OUTPUTS: +* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS +* +* +* DESCRIPTION: These functions abstract direct register access +* to Blackfin processor General Purpose +* Ports Regsiters +* +* CAUTION: These functions do not belong to the GPIO Driver API +************************************************************* +* MODIFICATION HISTORY : +**************************************************************/ + +/* Set a specific bit */ + +#define SET_GPIO(name) \ +void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ +{ \ + unsigned long flags; \ + BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \ + local_irq_save(flags); \ + if (arg) \ + gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ + else \ + gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \ + local_irq_restore(flags); \ +} \ +EXPORT_SYMBOL(set_gpio_ ## name); + +SET_GPIO(dir) +SET_GPIO(inen) +SET_GPIO(polar) +SET_GPIO(edge) +SET_GPIO(both) + + +#define SET_GPIO_SC(name) \ +void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ +{ \ + BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \ + if (arg) \ + gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ + else \ + gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ +} \ +EXPORT_SYMBOL(set_gpio_ ## name); + +SET_GPIO_SC(maska) +SET_GPIO_SC(maskb) + +#if defined(ANOMALY_05000311) +void set_gpio_data(unsigned short gpio, unsigned short arg) +{ + unsigned long flags; + BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); + local_irq_save(flags); + if (arg) + gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); + else + gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); + bfin_read_CHIPID(); + local_irq_restore(flags); +} +EXPORT_SYMBOL(set_gpio_data); +#else +SET_GPIO_SC(data) +#endif + + +#if defined(ANOMALY_05000311) +void set_gpio_toggle(unsigned short gpio) +{ + unsigned long flags; + BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); + local_irq_save(flags); + gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); + bfin_read_CHIPID(); + local_irq_restore(flags); +} +#else +void set_gpio_toggle(unsigned short gpio) +{ + BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); + gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); +} +#endif +EXPORT_SYMBOL(set_gpio_toggle); + + +/*Set current PORT date (16-bit word)*/ + +#define SET_GPIO_P(name) \ +void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \ +{ \ + gpio_bankb[gpio_bank(gpio)]->name = arg; \ +} \ +EXPORT_SYMBOL(set_gpiop_ ## name); + +SET_GPIO_P(dir) +SET_GPIO_P(inen) +SET_GPIO_P(polar) +SET_GPIO_P(edge) +SET_GPIO_P(both) +SET_GPIO_P(maska) +SET_GPIO_P(maskb) + + +#if defined(ANOMALY_05000311) +void set_gpiop_data(unsigned short gpio, unsigned short arg) +{ + unsigned long flags; + local_irq_save(flags); + gpio_bankb[gpio_bank(gpio)]->data = arg; + bfin_read_CHIPID(); + local_irq_restore(flags); +} +EXPORT_SYMBOL(set_gpiop_data); +#else +SET_GPIO_P(data) +#endif + + + +/* Get a specific bit */ + +#define GET_GPIO(name) \ +unsigned short get_gpio_ ## name(unsigned short gpio) \ +{ \ + return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \ +} \ +EXPORT_SYMBOL(get_gpio_ ## name); + +GET_GPIO(dir) +GET_GPIO(inen) +GET_GPIO(polar) +GET_GPIO(edge) +GET_GPIO(both) +GET_GPIO(maska) +GET_GPIO(maskb) + + +#if defined(ANOMALY_05000311) +unsigned short get_gpio_data(unsigned short gpio) +{ + unsigned long flags; + unsigned short ret; + BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); + local_irq_save(flags); + ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->data >> gpio_sub_n(gpio)); + bfin_read_CHIPID(); + local_irq_restore(flags); + return ret; +} +EXPORT_SYMBOL(get_gpio_data); +#else +GET_GPIO(data) +#endif + +/*Get current PORT date (16-bit word)*/ + +#define GET_GPIO_P(name) \ +unsigned short get_gpiop_ ## name(unsigned short gpio) \ +{ \ + return (gpio_bankb[gpio_bank(gpio)]->name);\ +} \ +EXPORT_SYMBOL(get_gpiop_ ## name); + +GET_GPIO_P(dir) +GET_GPIO_P(inen) +GET_GPIO_P(polar) +GET_GPIO_P(edge) +GET_GPIO_P(both) +GET_GPIO_P(maska) +GET_GPIO_P(maskb) + +#if defined(ANOMALY_05000311) +unsigned short get_gpiop_data(unsigned short gpio) +{ + unsigned long flags; + unsigned short ret; + local_irq_save(flags); + ret = gpio_bankb[gpio_bank(gpio)]->data; + bfin_read_CHIPID(); + local_irq_restore(flags); + return ret; +} +EXPORT_SYMBOL(get_gpiop_data); +#else +GET_GPIO_P(data) +#endif + +#ifdef CONFIG_PM +/*********************************************************** +* +* FUNCTIONS: Blackfin PM Setup API +* +* INPUTS/OUTPUTS: +* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS +* type - +* PM_WAKE_RISING +* PM_WAKE_FALLING +* PM_WAKE_HIGH +* PM_WAKE_LOW +* PM_WAKE_BOTH_EDGES +* +* DESCRIPTION: Blackfin PM Driver API +* +* CAUTION: +************************************************************* +* MODIFICATION HISTORY : +**************************************************************/ +int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type) +{ + unsigned long flags; + + if ((check_gpio(gpio) < 0) || !type) + return -EINVAL; + + local_irq_save(flags); + + wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); + wakeup_flags_map[gpio] = type; + local_irq_restore(flags); + + return 0; +} +EXPORT_SYMBOL(gpio_pm_wakeup_request); + +void gpio_pm_wakeup_free(unsigned short gpio) +{ + unsigned long flags; + + if (check_gpio(gpio) < 0) + return; + + local_irq_save(flags); + + wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); + + local_irq_restore(flags); +} +EXPORT_SYMBOL(gpio_pm_wakeup_free); + +static int bfin_gpio_wakeup_type(unsigned short gpio, unsigned char type) +{ + port_setup(gpio, GPIO_USAGE); + set_gpio_dir(gpio, 0); + set_gpio_inen(gpio, 1); + + if (type & (PM_WAKE_RISING | PM_WAKE_FALLING)) + set_gpio_edge(gpio, 1); + else + set_gpio_edge(gpio, 0); + + if ((type & (PM_WAKE_BOTH_EDGES)) == (PM_WAKE_BOTH_EDGES)) + set_gpio_both(gpio, 1); + else + set_gpio_both(gpio, 0); + + if ((type & (PM_WAKE_FALLING | PM_WAKE_LOW))) + set_gpio_polar(gpio, 1); + else + set_gpio_polar(gpio, 0); + + SSYNC(); + + return 0; +} + +u32 gpio_pm_setup(void) +{ + u32 sic_iwr = 0; + u16 bank, mask, i, gpio; + + for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) { + mask = wakeup_map[gpio_bank(i)]; + bank = gpio_bank(i); + + gpio_bank_saved[bank].maskb = gpio_bankb[bank]->maskb; + gpio_bankb[bank]->maskb = 0; + + if (mask) { +#ifdef BF537_FAMILY + gpio_bank_saved[bank].fer = *port_fer[bank]; +#endif + gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; + gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar; + gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir; + gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge; + gpio_bank_saved[bank].both = gpio_bankb[bank]->both; + + gpio = i; + + while (mask) { + if (mask & 1) { + bfin_gpio_wakeup_type(gpio, wakeup_flags_map[gpio]); + set_gpio_data(gpio, 0); /*Clear*/ + } + gpio++; + mask >>= 1; + } + + sic_iwr |= 1 << (sic_iwr_irqs[bank] - (IRQ_CORETMR + 1)); + gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)]; + } + } + + if (sic_iwr) + return sic_iwr; + else + return IWR_ENABLE_ALL; +} + + +void gpio_pm_restore(void) +{ + u16 bank, mask, i; + + for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) { + mask = wakeup_map[gpio_bank(i)]; + bank = gpio_bank(i); + + if (mask) { +#ifdef BF537_FAMILY + *port_fer[bank] = gpio_bank_saved[bank].fer; +#endif + gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; + gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir; + gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar; + gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge; + gpio_bankb[bank]->both = gpio_bank_saved[bank].both; + } + + gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb; + } +} + +#endif + +/*********************************************************** +* +* FUNCTIONS: Blackfin GPIO Driver +* +* INPUTS/OUTPUTS: +* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS +* +* +* DESCRIPTION: Blackfin GPIO Driver API +* +* CAUTION: +************************************************************* +* MODIFICATION HISTORY : +**************************************************************/ + +int gpio_request(unsigned short gpio, const char *label) +{ + unsigned long flags; + + if (check_gpio(gpio) < 0) + return -EINVAL; + + local_irq_save(flags); + + if (unlikely(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))) { + printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved!\n", gpio); + dump_stack(); + local_irq_restore(flags); + return -EBUSY; + } + reserved_map[gpio_bank(gpio)] |= gpio_bit(gpio); + + local_irq_restore(flags); + + port_setup(gpio, GPIO_USAGE); + + return 0; +} +EXPORT_SYMBOL(gpio_request); + + +void gpio_free(unsigned short gpio) +{ + unsigned long flags; + + if (check_gpio(gpio) < 0) + return; + + local_irq_save(flags); + + if (unlikely(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { + printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio); + dump_stack(); + local_irq_restore(flags); + return; + } + + default_gpio(gpio); + + reserved_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); + + local_irq_restore(flags); +} +EXPORT_SYMBOL(gpio_free); + + +void gpio_direction_input(unsigned short gpio) +{ + unsigned long flags; + + BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); + + local_irq_save(flags); + gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); + gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio); + local_irq_restore(flags); +} +EXPORT_SYMBOL(gpio_direction_input); + +void gpio_direction_output(unsigned short gpio) +{ + unsigned long flags; + + BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); + + local_irq_save(flags); + gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); + gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio); + local_irq_restore(flags); +} +EXPORT_SYMBOL(gpio_direction_output); diff --git a/arch/blackfin/kernel/bfin_ksyms.c b/arch/blackfin/kernel/bfin_ksyms.c new file mode 100644 index 000000000000..f64ecb638fab --- /dev/null +++ b/arch/blackfin/kernel/bfin_ksyms.c @@ -0,0 +1,119 @@ +/* + * File: arch/blackfin/kernel/bfin_ksyms.c + * Based on: none - original work + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +/* platform dependent support */ + +EXPORT_SYMBOL(__ioremap); +EXPORT_SYMBOL(strcmp); +EXPORT_SYMBOL(strncmp); +EXPORT_SYMBOL(dump_thread); + +EXPORT_SYMBOL(ip_fast_csum); + +EXPORT_SYMBOL(kernel_thread); + +EXPORT_SYMBOL(__up); +EXPORT_SYMBOL(__down); +EXPORT_SYMBOL(__down_trylock); +EXPORT_SYMBOL(__down_interruptible); + +EXPORT_SYMBOL(is_in_rom); + +/* Networking helper routines. */ +EXPORT_SYMBOL(csum_partial_copy); + +/* The following are special because they're not called + * explicitly (the C compiler generates them). Fortunately, + * their interface isn't gonna change any time soon now, so + * it's OK to leave it out of version control. + */ +EXPORT_SYMBOL(memcpy); +EXPORT_SYMBOL(memset); +EXPORT_SYMBOL(memcmp); +EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(memchr); +EXPORT_SYMBOL(get_wchan); + +/* + * libgcc functions - functions that are used internally by the + * compiler... (prototypes are not correct though, but that + * doesn't really matter since they're not versioned). + */ +extern void __ashldi3(void); +extern void __ashrdi3(void); +extern void __smulsi3_highpart(void); +extern void __umulsi3_highpart(void); +extern void __divsi3(void); +extern void __lshrdi3(void); +extern void __modsi3(void); +extern void __muldi3(void); +extern void __udivsi3(void); +extern void __umodsi3(void); + +/* gcc lib functions */ +EXPORT_SYMBOL(__ashldi3); +EXPORT_SYMBOL(__ashrdi3); +EXPORT_SYMBOL(__umulsi3_highpart); +EXPORT_SYMBOL(__smulsi3_highpart); +EXPORT_SYMBOL(__divsi3); +EXPORT_SYMBOL(__lshrdi3); +EXPORT_SYMBOL(__modsi3); +EXPORT_SYMBOL(__muldi3); +EXPORT_SYMBOL(__udivsi3); +EXPORT_SYMBOL(__umodsi3); + +EXPORT_SYMBOL(outsb); +EXPORT_SYMBOL(insb); +EXPORT_SYMBOL(outsw); +EXPORT_SYMBOL(insw); +EXPORT_SYMBOL(outsl); +EXPORT_SYMBOL(insl); +EXPORT_SYMBOL(irq_flags); +EXPORT_SYMBOL(iounmap); +EXPORT_SYMBOL(blackfin_dcache_invalidate_range); +EXPORT_SYMBOL(blackfin_icache_dcache_flush_range); +EXPORT_SYMBOL(blackfin_icache_flush_range); +EXPORT_SYMBOL(blackfin_dcache_flush_range); +EXPORT_SYMBOL(blackfin_dflush_page); + +EXPORT_SYMBOL(csum_partial); +EXPORT_SYMBOL(__init_begin); +EXPORT_SYMBOL(__init_end); +EXPORT_SYMBOL(_ebss_l1); +EXPORT_SYMBOL(_stext_l1); +EXPORT_SYMBOL(_etext_l1); +EXPORT_SYMBOL(_sdata_l1); +EXPORT_SYMBOL(_ebss_b_l1); +EXPORT_SYMBOL(_sdata_b_l1); diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c new file mode 100644 index 000000000000..539eb24e062f --- /dev/null +++ b/arch/blackfin/kernel/dma-mapping.c @@ -0,0 +1,183 @@ +/* + * File: arch/blackfin/kernel/dma-mapping.c + * Based on: + * Author: + * + * Created: + * Description: Dynamic DMA mapping support. + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static spinlock_t dma_page_lock; +static unsigned int *dma_page; +static unsigned int dma_pages; +static unsigned long dma_base; +static unsigned long dma_size; +static unsigned int dma_initialized; + +void dma_alloc_init(unsigned long start, unsigned long end) +{ + spin_lock_init(&dma_page_lock); + dma_initialized = 0; + + dma_page = (unsigned int *)__get_free_page(GFP_KERNEL); + memset(dma_page, 0, PAGE_SIZE); + dma_base = PAGE_ALIGN(start); + dma_size = PAGE_ALIGN(end) - PAGE_ALIGN(start); + dma_pages = dma_size >> PAGE_SHIFT; + memset((void *)dma_base, 0, DMA_UNCACHED_REGION); + dma_initialized = 1; + + printk(KERN_INFO "%s: dma_page @ 0x%p - %d pages at 0x%08lx\n", __FUNCTION__, + dma_page, dma_pages, dma_base); +} + +static inline unsigned int get_pages(size_t size) +{ + return ((size - 1) >> PAGE_SHIFT) + 1; +} + +static unsigned long __alloc_dma_pages(unsigned int pages) +{ + unsigned long ret = 0, flags; + int i, count = 0; + + if (dma_initialized == 0) + dma_alloc_init(_ramend - DMA_UNCACHED_REGION, _ramend); + + spin_lock_irqsave(&dma_page_lock, flags); + + for (i = 0; i < dma_pages;) { + if (dma_page[i++] == 0) { + if (++count == pages) { + while (count--) + dma_page[--i] = 1; + ret = dma_base + (i << PAGE_SHIFT); + break; + } + } else + count = 0; + } + spin_unlock_irqrestore(&dma_page_lock, flags); + return ret; +} + +static void __free_dma_pages(unsigned long addr, unsigned int pages) +{ + unsigned long page = (addr - dma_base) >> PAGE_SHIFT; + unsigned long flags; + int i; + + if ((page + pages) > dma_pages) { + printk(KERN_ERR "%s: freeing outside range.\n", __FUNCTION__); + BUG(); + } + + spin_lock_irqsave(&dma_page_lock, flags); + for (i = page; i < page + pages; i++) { + dma_page[i] = 0; + } + spin_unlock_irqrestore(&dma_page_lock, flags); +} + +void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t * dma_handle, gfp_t gfp) +{ + void *ret; + + ret = (void *)__alloc_dma_pages(get_pages(size)); + + if (ret) { + memset(ret, 0, size); + *dma_handle = virt_to_phys(ret); + } + + return ret; +} +EXPORT_SYMBOL(dma_alloc_coherent); + +void +dma_free_coherent(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle) +{ + __free_dma_pages((unsigned long)vaddr, get_pages(size)); +} +EXPORT_SYMBOL(dma_free_coherent); + +/* + * Dummy functions defined for some existing drivers + */ + +dma_addr_t +dma_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); + + invalidate_dcache_range((unsigned long)ptr, + (unsigned long)ptr + size); + + return (dma_addr_t) ptr; +} +EXPORT_SYMBOL(dma_map_single); + +int +dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction direction) +{ + int i; + + BUG_ON(direction == DMA_NONE); + + for (i = 0; i < nents; i++) + invalidate_dcache_range(sg_dma_address(&sg[i]), + sg_dma_address(&sg[i]) + + sg_dma_len(&sg[i])); + + return nents; +} +EXPORT_SYMBOL(dma_map_sg); + +void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} +EXPORT_SYMBOL(dma_unmap_single); + +void dma_unmap_sg(struct device *dev, struct scatterlist *sg, + int nhwentries, enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} +EXPORT_SYMBOL(dma_unmap_sg); diff --git a/arch/blackfin/kernel/dualcore_test.c b/arch/blackfin/kernel/dualcore_test.c new file mode 100644 index 000000000000..8b89c99f9dfa --- /dev/null +++ b/arch/blackfin/kernel/dualcore_test.c @@ -0,0 +1,49 @@ +/* + * File: arch/blackfin/kernel/dualcore_test.c + * Based on: + * Author: + * + * Created: + * Description: Small test code for CoreB on a BF561 + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +static int *testarg = (int*)0xfeb00000; + +static int test_init(void) +{ + *testarg = 1; + printk("Dual core test module inserted: set testarg = [%d]\n @ [%p]\n", + *testarg, testarg); + return 0; +} + +static void test_exit(void) +{ + printk("Dual core test module removed: testarg = [%d]\n", *testarg); +} + +module_init(test_init); +module_exit(test_exit); diff --git a/arch/blackfin/kernel/entry.S b/arch/blackfin/kernel/entry.S new file mode 100644 index 000000000000..5880b270bd50 --- /dev/null +++ b/arch/blackfin/kernel/entry.S @@ -0,0 +1,94 @@ +/* + * File: arch/blackfin/kernel/entry.S + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#include + +#ifdef CONFIG_EXCPT_IRQ_SYSC_L1 +.section .l1.text +#else +.text +#endif + +ENTRY(_ret_from_fork) + SP += -12; + call _schedule_tail; + SP += 12; + r0 = [sp + PT_IPEND]; + cc = bittst(r0,1); + if cc jump .Lin_kernel; + RESTORE_CONTEXT + rti; +.Lin_kernel: + bitclr(r0,1); + [sp + PT_IPEND] = r0; + /* do a 'fake' RTI by jumping to [RETI] + * to avoid clearing supervisor mode in child + */ + RESTORE_ALL_SYS + p0 = reti; + jump (p0); + +ENTRY(_sys_fork) + r0 = -EINVAL; + rts; + +ENTRY(_sys_vfork) + r0 = sp; + r0 += 24; + [--sp] = rets; + SP += -12; + call _bfin_vfork; + SP += 12; + rets = [sp++]; + rts; + +ENTRY(_sys_clone) + r0 = sp; + r0 += 24; + [--sp] = rets; + SP += -12; + call _bfin_clone; + SP += 12; + rets = [sp++]; + rts; + +ENTRY(_sys_rt_sigreturn) + r0 = sp; + r0 += 24; + [--sp] = rets; + SP += -12; + call _do_rt_sigreturn; + SP += 12; + rets = [sp++]; + rts; diff --git a/arch/blackfin/kernel/flat.c b/arch/blackfin/kernel/flat.c new file mode 100644 index 000000000000..a92587b628b5 --- /dev/null +++ b/arch/blackfin/kernel/flat.c @@ -0,0 +1,101 @@ +/* + * arch/blackfin/kernel/flat.c + * + * Copyright (C) 2007 Analog Devices, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +#define FLAT_BFIN_RELOC_TYPE_16_BIT 0 +#define FLAT_BFIN_RELOC_TYPE_16H_BIT 1 +#define FLAT_BFIN_RELOC_TYPE_32_BIT 2 + +unsigned long bfin_get_addr_from_rp(unsigned long *ptr, + unsigned long relval, + unsigned long flags, + unsigned long *persistent) +{ + unsigned short *usptr = (unsigned short *)ptr; + int type = (relval >> 26) & 7; + unsigned long val; + + switch (type) { + case FLAT_BFIN_RELOC_TYPE_16_BIT: + case FLAT_BFIN_RELOC_TYPE_16H_BIT: + usptr = (unsigned short *)ptr; + pr_debug("*usptr = %x", get_unaligned(usptr)); + val = get_unaligned(usptr); + val += *persistent; + break; + + case FLAT_BFIN_RELOC_TYPE_32_BIT: + pr_debug("*ptr = %lx", get_unaligned(ptr)); + val = get_unaligned(ptr); + break; + + default: + pr_debug("BINFMT_FLAT: Unknown relocation type %x\n", + type); + + return 0; + } + + /* + * Stack-relative relocs contain the offset into the stack, we + * have to add the stack's start address here and return 1 from + * flat_addr_absolute to prevent the normal address calculations + */ + if (relval & (1 << 29)) + return val + current->mm->context.end_brk; + + if ((flags & FLAT_FLAG_GOTPIC) == 0) + val = htonl(val); + return val; +} +EXPORT_SYMBOL(bfin_get_addr_from_rp); + +/* + * Insert the address ADDR into the symbol reference at RP; + * RELVAL is the raw relocation-table entry from which RP is derived + */ +void bfin_put_addr_at_rp(unsigned long *ptr, unsigned long addr, + unsigned long relval) +{ + unsigned short *usptr = (unsigned short *)ptr; + int type = (relval >> 26) & 7; + + switch (type) { + case FLAT_BFIN_RELOC_TYPE_16_BIT: + put_unaligned(addr, usptr); + pr_debug("new value %x at %p", get_unaligned(usptr), + usptr); + break; + + case FLAT_BFIN_RELOC_TYPE_16H_BIT: + put_unaligned(addr >> 16, usptr); + pr_debug("new value %x", get_unaligned(usptr)); + break; + + case FLAT_BFIN_RELOC_TYPE_32_BIT: + put_unaligned(addr, ptr); + pr_debug("new ptr =%lx", get_unaligned(ptr)); + break; + } +} +EXPORT_SYMBOL(bfin_put_addr_at_rp); diff --git a/arch/blackfin/kernel/init_task.c b/arch/blackfin/kernel/init_task.c new file mode 100644 index 000000000000..b45188f8512e --- /dev/null +++ b/arch/blackfin/kernel/init_task.c @@ -0,0 +1,60 @@ +/* + * File: arch/blackfin/kernel/init_task.c + * Based on: + * Author: + * + * Created: + * Description: This file contains the simple DMA Implementation for Blackfin + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +static struct fs_struct init_fs = INIT_FS; +static struct files_struct init_files = INIT_FILES; +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); + +struct mm_struct init_mm = INIT_MM(init_mm); +EXPORT_SYMBOL(init_mm); + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); +EXPORT_SYMBOL(init_task); + +/* + * Initial thread structure. + * + * We need to make sure that this is 8192-byte aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry. + */ +union thread_union init_thread_union + __attribute__ ((__section__(".data.init_task"))) = { +INIT_THREAD_INFO(init_task)}; diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c new file mode 100644 index 000000000000..df5bf022cf79 --- /dev/null +++ b/arch/blackfin/kernel/irqchip.c @@ -0,0 +1,147 @@ +/* + * File: arch/blackfin/kernel/irqchip.c + * Based on: + * Author: + * + * Created: + * Description: This file contains the simple DMA Implementation for Blackfin + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +static unsigned long irq_err_count; +static spinlock_t irq_controller_lock; + +/* + * Dummy mask/unmask handler + */ +void dummy_mask_unmask_irq(unsigned int irq) +{ +} + +void ack_bad_irq(unsigned int irq) +{ + irq_err_count += 1; + printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq); +} +EXPORT_SYMBOL(ack_bad_irq); + +static struct irq_chip bad_chip = { + .ack = dummy_mask_unmask_irq, + .mask = dummy_mask_unmask_irq, + .unmask = dummy_mask_unmask_irq, +}; + +static struct irq_desc bad_irq_desc = { + .chip = &bad_chip, + .handle_irq = handle_bad_irq, + .depth = 1, +}; + +int show_interrupts(struct seq_file *p, void *v) +{ + int i = *(loff_t *) v; + struct irqaction *action; + unsigned long flags; + + if (i < NR_IRQS) { + spin_lock_irqsave(&irq_desc[i].lock, flags); + action = irq_desc[i].action; + if (!action) + goto unlock; + + seq_printf(p, "%3d: %10u ", i, kstat_irqs(i)); + seq_printf(p, " %s", action->name); + for (action = action->next; action; action = action->next) + seq_printf(p, ", %s", action->name); + + seq_putc(p, '\n'); + unlock: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); + } else if (i == NR_IRQS) { + seq_printf(p, "Err: %10lu\n", irq_err_count); + } + return 0; +} + +/* + * do_IRQ handles all hardware IRQ's. Decoded IRQs should not + * come via this function. Instead, they should provide their + * own 'handler' + */ + +#ifdef CONFIG_DO_IRQ_L1 +asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)__attribute__((l1_text)); +#endif + +asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) +{ + struct pt_regs *old_regs; + struct irq_desc *desc = irq_desc + irq; + unsigned short pending, other_ints; + + old_regs = set_irq_regs(regs); + + /* + * Some hardware gives randomly wrong interrupts. Rather + * than crashing, do something sensible. + */ + if (irq >= NR_IRQS) + desc = &bad_irq_desc; + + irq_enter(); + + generic_handle_irq(irq); + + /* If we're the only interrupt running (ignoring IRQ15 which is for + syscalls), lower our priority to IRQ14 so that softirqs run at + that level. If there's another, lower-level interrupt, irq_exit + will defer softirqs to that. */ + CSYNC(); + pending = bfin_read_IPEND() & ~0x8000; + other_ints = pending & (pending - 1); + if (other_ints == 0) + lower_to_irq14(); + irq_exit(); + + set_irq_regs(old_regs); +} + +void __init init_IRQ(void) +{ + struct irq_desc *desc; + int irq; + + spin_lock_init(&irq_controller_lock); + for (irq = 0, desc = irq_desc; irq < NR_IRQS; irq++, desc++) { + *desc = bad_irq_desc; + } + + init_arch_irq(); +} diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c new file mode 100644 index 000000000000..372f756f1ad9 --- /dev/null +++ b/arch/blackfin/kernel/module.c @@ -0,0 +1,429 @@ +/* + * File: arch/blackfin/kernel/module.c + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * handle arithmetic relocations. + * See binutils/bfd/elf32-bfin.c for more details + */ +#define RELOC_STACK_SIZE 100 +static uint32_t reloc_stack[RELOC_STACK_SIZE]; +static unsigned int reloc_stack_tos; + +#define is_reloc_stack_empty() ((reloc_stack_tos > 0)?0:1) + +static void reloc_stack_push(uint32_t value) +{ + reloc_stack[reloc_stack_tos++] = value; +} + +static uint32_t reloc_stack_pop(void) +{ + return reloc_stack[--reloc_stack_tos]; +} + +static uint32_t reloc_stack_operate(unsigned int oper, struct module *mod) +{ + uint32_t value; + + switch (oper) { + case R_add: + value = reloc_stack[reloc_stack_tos - 2] + + reloc_stack[reloc_stack_tos - 1]; + reloc_stack_tos -= 2; + break; + case R_sub: + value = reloc_stack[reloc_stack_tos - 2] - + reloc_stack[reloc_stack_tos - 1]; + reloc_stack_tos -= 2; + break; + case R_mult: + value = reloc_stack[reloc_stack_tos - 2] * + reloc_stack[reloc_stack_tos - 1]; + reloc_stack_tos -= 2; + break; + case R_div: + value = reloc_stack[reloc_stack_tos - 2] / + reloc_stack[reloc_stack_tos - 1]; + reloc_stack_tos -= 2; + break; + case R_mod: + value = reloc_stack[reloc_stack_tos - 2] % + reloc_stack[reloc_stack_tos - 1]; + reloc_stack_tos -= 2; + break; + case R_lshift: + value = reloc_stack[reloc_stack_tos - 2] << + reloc_stack[reloc_stack_tos - 1]; + reloc_stack_tos -= 2; + break; + case R_rshift: + value = reloc_stack[reloc_stack_tos - 2] >> + reloc_stack[reloc_stack_tos - 1]; + reloc_stack_tos -= 2; + break; + case R_and: + value = reloc_stack[reloc_stack_tos - 2] & + reloc_stack[reloc_stack_tos - 1]; + reloc_stack_tos -= 2; + break; + case R_or: + value = reloc_stack[reloc_stack_tos - 2] | + reloc_stack[reloc_stack_tos - 1]; + reloc_stack_tos -= 2; + break; + case R_xor: + value = reloc_stack[reloc_stack_tos - 2] ^ + reloc_stack[reloc_stack_tos - 1]; + reloc_stack_tos -= 2; + break; + case R_land: + value = reloc_stack[reloc_stack_tos - 2] && + reloc_stack[reloc_stack_tos - 1]; + reloc_stack_tos -= 2; + break; + case R_lor: + value = reloc_stack[reloc_stack_tos - 2] || + reloc_stack[reloc_stack_tos - 1]; + reloc_stack_tos -= 2; + break; + case R_neg: + value = -reloc_stack[reloc_stack_tos - 1]; + reloc_stack_tos--; + break; + case R_comp: + value = ~reloc_stack[reloc_stack_tos - 1]; + reloc_stack_tos -= 1; + break; + default: + printk(KERN_WARNING "module %s: unhandled reloction\n", + mod->name); + return 0; + } + + /* now push the new value back on stack */ + reloc_stack_push(value); + + return value; +} + +void *module_alloc(unsigned long size) +{ + if (size == 0) + return NULL; + return vmalloc(size); +} + +/* Free memory returned from module_alloc */ +void module_free(struct module *mod, void *module_region) +{ + vfree(module_region); +} + +/* Transfer the section to the L1 memory */ +int +module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, + char *secstrings, struct module *mod) +{ + Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum; + void *dest = NULL; + + for (s = sechdrs; s < sechdrs_end; ++s) { + if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) || + ((strcmp(".text", secstrings + s->sh_name)==0) && + (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) { + mod->arch.text_l1 = s; + dest = l1_inst_sram_alloc(s->sh_size); + if (dest == NULL) { + printk(KERN_ERR + "module %s: L1 instruction memory allocation failed\n", + mod->name); + return -1; + } + dma_memcpy(dest, (void *)s->sh_addr, s->sh_size); + s->sh_flags &= ~SHF_ALLOC; + s->sh_addr = (unsigned long)dest; + } + if ((strcmp(".l1.data", secstrings + s->sh_name) == 0)|| + ((strcmp(".data", secstrings + s->sh_name)==0) && + (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { + mod->arch.data_a_l1 = s; + dest = l1_data_sram_alloc(s->sh_size); + if (dest == NULL) { + printk(KERN_ERR + "module %s: L1 data memory allocation failed\n", + mod->name); + return -1; + } + memcpy(dest, (void *)s->sh_addr, s->sh_size); + s->sh_flags &= ~SHF_ALLOC; + s->sh_addr = (unsigned long)dest; + } + if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 || + ((strcmp(".bss", secstrings + s->sh_name)==0) && + (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { + mod->arch.bss_a_l1 = s; + dest = l1_data_sram_alloc(s->sh_size); + if (dest == NULL) { + printk(KERN_ERR + "module %s: L1 data memory allocation failed\n", + mod->name); + return -1; + } + memset(dest, 0, s->sh_size); + s->sh_flags &= ~SHF_ALLOC; + s->sh_addr = (unsigned long)dest; + } + if (strcmp(".l1.data.B", secstrings + s->sh_name) == 0) { + mod->arch.data_b_l1 = s; + dest = l1_data_B_sram_alloc(s->sh_size); + if (dest == NULL) { + printk(KERN_ERR + "module %s: L1 data memory allocation failed\n", + mod->name); + return -1; + } + memcpy(dest, (void *)s->sh_addr, s->sh_size); + s->sh_flags &= ~SHF_ALLOC; + s->sh_addr = (unsigned long)dest; + } + if (strcmp(".l1.bss.B", secstrings + s->sh_name) == 0) { + mod->arch.bss_b_l1 = s; + dest = l1_data_B_sram_alloc(s->sh_size); + if (dest == NULL) { + printk(KERN_ERR + "module %s: L1 data memory allocation failed\n", + mod->name); + return -1; + } + memset(dest, 0, s->sh_size); + s->sh_flags &= ~SHF_ALLOC; + s->sh_addr = (unsigned long)dest; + } + } + return 0; +} + +int +apply_relocate(Elf_Shdr * sechdrs, const char *strtab, + unsigned int symindex, unsigned int relsec, struct module *me) +{ + printk(KERN_ERR "module %s: .rel unsupported\n", me->name); + return -ENOEXEC; +} + +/*************************************************************************/ +/* FUNCTION : apply_relocate_add */ +/* ABSTRACT : Blackfin specific relocation handling for the loadable */ +/* modules. Modules are expected to be .o files. */ +/* Arithmetic relocations are handled. */ +/* We do not expect LSETUP to be split and hence is not */ +/* handled. */ +/* R_byte and R_byte2 are also not handled as the gas */ +/* does not generate it. */ +/*************************************************************************/ +int +apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab, + unsigned int symindex, unsigned int relsec, + struct module *mod) +{ + unsigned int i; + unsigned short tmp; + Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr; + Elf32_Sym *sym; + uint32_t *location32; + uint16_t *location16; + uint32_t value; + + pr_debug("Applying relocate section %u to %u\n", relsec, + sechdrs[relsec].sh_info); + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { + /* This is where to make the change */ + location16 = + (uint16_t *) (sechdrs[sechdrs[relsec].sh_info].sh_addr + + rel[i].r_offset); + location32 = (uint32_t *) location16; + /* This is the symbol it is referring to. Note that all + undefined symbols have been resolved. */ + sym = (Elf32_Sym *) sechdrs[symindex].sh_addr + + ELF32_R_SYM(rel[i].r_info); + if (is_reloc_stack_empty()) { + value = sym->st_value; + } else { + value = reloc_stack_pop(); + } + value += rel[i].r_addend; + pr_debug("location is %x, value is %x type is %d \n", + (unsigned int) location32, value, + ELF32_R_TYPE(rel[i].r_info)); + + switch (ELF32_R_TYPE(rel[i].r_info)) { + + case R_pcrel24: + case R_pcrel24_jump_l: + /* Add the value, subtract its postition */ + location16 = + (uint16_t *) (sechdrs[sechdrs[relsec].sh_info]. + sh_addr + rel[i].r_offset - 2); + location32 = (uint32_t *) location16; + value -= (uint32_t) location32; + value >>= 1; + pr_debug("value is %x, before %x-%x after %x-%x\n", value, + *location16, *(location16 + 1), + (*location16 & 0xff00) | (value >> 16 & 0x00ff), + value & 0xffff); + *location16 = + (*location16 & 0xff00) | (value >> 16 & 0x00ff); + *(location16 + 1) = value & 0xffff; + break; + case R_pcrel12_jump: + case R_pcrel12_jump_s: + value -= (uint32_t) location32; + value >>= 1; + *location16 = (value & 0xfff); + break; + case R_pcrel10: + value -= (uint32_t) location32; + value >>= 1; + *location16 = (value & 0x3ff); + break; + case R_luimm16: + pr_debug("before %x after %x\n", *location16, + (value & 0xffff)); + tmp = (value & 0xffff); + if((unsigned long)location16 >= L1_CODE_START) { + dma_memcpy(location16, &tmp, 2); + } else + *location16 = tmp; + break; + case R_huimm16: + pr_debug("before %x after %x\n", *location16, + ((value >> 16) & 0xffff)); + tmp = ((value >> 16) & 0xffff); + if((unsigned long)location16 >= L1_CODE_START) { + dma_memcpy(location16, &tmp, 2); + } else + *location16 = tmp; + break; + case R_rimm16: + *location16 = (value & 0xffff); + break; + case R_byte4_data: + pr_debug("before %x after %x\n", *location32, value); + *location32 = value; + break; + case R_push: + reloc_stack_push(value); + break; + case R_const: + reloc_stack_push(rel[i].r_addend); + break; + case R_add: + case R_sub: + case R_mult: + case R_div: + case R_mod: + case R_lshift: + case R_rshift: + case R_and: + case R_or: + case R_xor: + case R_land: + case R_lor: + case R_neg: + case R_comp: + reloc_stack_operate(ELF32_R_TYPE(rel[i].r_info), mod); + break; + default: + printk(KERN_ERR "module %s: Unknown relocation: %u\n", + mod->name, ELF32_R_TYPE(rel[i].r_info)); + return -ENOEXEC; + } + } + return 0; +} + +int +module_finalize(const Elf_Ehdr * hdr, + const Elf_Shdr * sechdrs, struct module *mod) +{ + unsigned int i, strindex = 0, symindex = 0; + char *secstrings; + + secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + + for (i = 1; i < hdr->e_shnum; i++) { + /* Internal symbols and strings. */ + if (sechdrs[i].sh_type == SHT_SYMTAB) { + symindex = i; + strindex = sechdrs[i].sh_link; + } + } + + for (i = 1; i < hdr->e_shnum; i++) { + const char *strtab = (char *)sechdrs[strindex].sh_addr; + unsigned int info = sechdrs[i].sh_info; + + /* Not a valid relocation section? */ + if (info >= hdr->e_shnum) + continue; + + if ((sechdrs[i].sh_type == SHT_RELA) && + ((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0)|| + ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) && + (hdr->e_flags & FLG_CODE_IN_L1)))) { + apply_relocate_add((Elf_Shdr *) sechdrs, strtab, + symindex, i, mod); + } + } + return 0; +} + +void module_arch_cleanup(struct module *mod) +{ + if ((mod->arch.text_l1) && (mod->arch.text_l1->sh_addr)) + l1_inst_sram_free((void*)mod->arch.text_l1->sh_addr); + if ((mod->arch.data_a_l1) && (mod->arch.data_a_l1->sh_addr)) + l1_data_sram_free((void*)mod->arch.data_a_l1->sh_addr); + if ((mod->arch.bss_a_l1) && (mod->arch.bss_a_l1->sh_addr)) + l1_data_sram_free((void*)mod->arch.bss_a_l1->sh_addr); + if ((mod->arch.data_b_l1) && (mod->arch.data_b_l1->sh_addr)) + l1_data_B_sram_free((void*)mod->arch.data_b_l1->sh_addr); + if ((mod->arch.bss_b_l1) && (mod->arch.bss_b_l1->sh_addr)) + l1_data_B_sram_free((void*)mod->arch.bss_b_l1->sh_addr); +} diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c new file mode 100644 index 000000000000..3eff7439d8d3 --- /dev/null +++ b/arch/blackfin/kernel/process.c @@ -0,0 +1,394 @@ +/* + * File: arch/blackfin/kernel/process.c + * Based on: + * Author: + * + * Created: + * Description: Blackfin architecture-dependent process handling. + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +#include +#include + +#define LED_ON 0 +#define LED_OFF 1 + +asmlinkage void ret_from_fork(void); + +/* Points to the SDRAM backup memory for the stack that is currently in + * L1 scratchpad memory. + */ +void *current_l1_stack_save; + +/* The number of tasks currently using a L1 stack area. The SRAM is + * allocated/deallocated whenever this changes from/to zero. + */ +int nr_l1stack_tasks; + +/* Start and length of the area in L1 scratchpad memory which we've allocated + * for process stacks. + */ +void *l1_stack_base; +unsigned long l1_stack_len; + +/* + * Powermanagement idle function, if any.. + */ +void (*pm_idle)(void) = NULL; +EXPORT_SYMBOL(pm_idle); + +void (*pm_power_off)(void) = NULL; +EXPORT_SYMBOL(pm_power_off); + +/* + * We are using a different LED from the one used to indicate timer interrupt. + */ +#if defined(CONFIG_BFIN_IDLE_LED) +static inline void leds_switch(int flag) +{ + unsigned short tmp = 0; + + tmp = bfin_read_CONFIG_BFIN_IDLE_LED_PORT(); + SSYNC(); + + if (flag == LED_ON) + tmp &= ~CONFIG_BFIN_IDLE_LED_PIN; /* light on */ + else + tmp |= CONFIG_BFIN_IDLE_LED_PIN; /* light off */ + + bfin_write_CONFIG_BFIN_IDLE_LED_PORT(tmp); + SSYNC(); + +} +#else +static inline void leds_switch(int flag) +{ +} +#endif + +/* + * The idle loop on BFIN + */ +#ifdef CONFIG_IDLE_L1 +void default_idle(void)__attribute__((l1_text)); +void cpu_idle(void)__attribute__((l1_text)); +#endif + +void default_idle(void) +{ + while (!need_resched()) { + leds_switch(LED_OFF); + local_irq_disable(); + if (likely(!need_resched())) + idle_with_irq_disabled(); + local_irq_enable(); + leds_switch(LED_ON); + } +} + +void (*idle)(void) = default_idle; + +/* + * The idle thread. There's no useful work to be + * done, so just try to conserve power and have a + * low exit latency (ie sit in a loop waiting for + * somebody to say that they'd like to reschedule) + */ +void cpu_idle(void) +{ + /* endless idle loop with no priority at all */ + while (1) { + idle(); + preempt_enable_no_resched(); + schedule(); + preempt_disable(); + } +} + +void machine_restart(char *__unused) +{ +#if defined(CONFIG_BLKFIN_CACHE) + bfin_write_IMEM_CONTROL(0x01); + SSYNC(); +#endif + bfin_reset(); + /* Dont do anything till the reset occurs */ + while (1) { + SSYNC(); + } +} + +void machine_halt(void) +{ + for (;;) + asm volatile ("idle"); +} + +void machine_power_off(void) +{ + for (;;) + asm volatile ("idle"); +} + +void show_regs(struct pt_regs *regs) +{ + printk(KERN_NOTICE "\n"); + printk(KERN_NOTICE + "PC: %08lu Status: %04lu SysStatus: %04lu RETS: %08lu\n", + regs->pc, regs->astat, regs->seqstat, regs->rets); + printk(KERN_NOTICE + "A0.x: %08lx A0.w: %08lx A1.x: %08lx A1.w: %08lx\n", + regs->a0x, regs->a0w, regs->a1x, regs->a1w); + printk(KERN_NOTICE "P0: %08lx P1: %08lx P2: %08lx P3: %08lx\n", + regs->p0, regs->p1, regs->p2, regs->p3); + printk(KERN_NOTICE "P4: %08lx P5: %08lx\n", regs->p4, regs->p5); + printk(KERN_NOTICE "R0: %08lx R1: %08lx R2: %08lx R3: %08lx\n", + regs->r0, regs->r1, regs->r2, regs->r3); + printk(KERN_NOTICE "R4: %08lx R5: %08lx R6: %08lx R7: %08lx\n", + regs->r4, regs->r5, regs->r6, regs->r7); + + if (!(regs->ipend)) + printk("USP: %08lx\n", rdusp()); +} + +/* Fill in the fpu structure for a core dump. */ + +int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpregs) +{ + return 1; +} + +/* + * This gets run with P1 containing the + * function to call, and R1 containing + * the "args". Note P0 is clobbered on the way here. + */ +void kernel_thread_helper(void); +__asm__(".section .text\n" + ".align 4\n" + "_kernel_thread_helper:\n\t" + "\tsp += -12;\n\t" + "\tr0 = r1;\n\t" "\tcall (p1);\n\t" "\tcall _do_exit;\n" ".previous"); + +/* + * Create a kernel thread. + */ +pid_t kernel_thread(int (*fn) (void *), void *arg, unsigned long flags) +{ + struct pt_regs regs; + + memset(®s, 0, sizeof(regs)); + + regs.r1 = (unsigned long)arg; + regs.p1 = (unsigned long)fn; + regs.pc = (unsigned long)kernel_thread_helper; + regs.orig_p0 = -1; + /* Set bit 2 to tell ret_from_fork we should be returning to kernel + mode. */ + regs.ipend = 0x8002; + __asm__ __volatile__("%0 = syscfg;":"=da"(regs.syscfg):); + return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, + NULL); +} + +void flush_thread(void) +{ +} + +asmlinkage int bfin_vfork(struct pt_regs *regs) +{ + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, + NULL); +} + +asmlinkage int bfin_clone(struct pt_regs *regs) +{ + unsigned long clone_flags; + unsigned long newsp; + + /* syscall2 puts clone_flags in r0 and usp in r1 */ + clone_flags = regs->r0; + newsp = regs->r1; + if (!newsp) + newsp = rdusp(); + else + newsp -= 12; + return do_fork(clone_flags, newsp, regs, 0, NULL, NULL); +} + +int +copy_thread(int nr, unsigned long clone_flags, + unsigned long usp, unsigned long topstk, + struct task_struct *p, struct pt_regs *regs) +{ + struct pt_regs *childregs; + + childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; + *childregs = *regs; + childregs->r0 = 0; + + p->thread.usp = usp; + p->thread.ksp = (unsigned long)childregs; + p->thread.pc = (unsigned long)ret_from_fork; + + return 0; +} + +/* + * fill in the user structure for a core dump.. + */ +void dump_thread(struct pt_regs *regs, struct user *dump) +{ + dump->magic = CMAGIC; + dump->start_code = 0; + dump->start_stack = rdusp() & ~(PAGE_SIZE - 1); + dump->u_tsize = ((unsigned long)current->mm->end_code) >> PAGE_SHIFT; + dump->u_dsize = ((unsigned long)(current->mm->brk + + (PAGE_SIZE - 1))) >> PAGE_SHIFT; + dump->u_dsize -= dump->u_tsize; + dump->u_ssize = 0; + + if (dump->start_stack < TASK_SIZE) + dump->u_ssize = + ((unsigned long)(TASK_SIZE - + dump->start_stack)) >> PAGE_SHIFT; + + dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump); + + dump->regs.r0 = regs->r0; + dump->regs.r1 = regs->r1; + dump->regs.r2 = regs->r2; + dump->regs.r3 = regs->r3; + dump->regs.r4 = regs->r4; + dump->regs.r5 = regs->r5; + dump->regs.r6 = regs->r6; + dump->regs.r7 = regs->r7; + dump->regs.p0 = regs->p0; + dump->regs.p1 = regs->p1; + dump->regs.p2 = regs->p2; + dump->regs.p3 = regs->p3; + dump->regs.p4 = regs->p4; + dump->regs.p5 = regs->p5; + dump->regs.orig_p0 = regs->orig_p0; + dump->regs.a0w = regs->a0w; + dump->regs.a1w = regs->a1w; + dump->regs.a0x = regs->a0x; + dump->regs.a1x = regs->a1x; + dump->regs.rets = regs->rets; + dump->regs.astat = regs->astat; + dump->regs.pc = regs->pc; +} + +/* + * sys_execve() executes a new program. + */ + +asmlinkage int sys_execve(char *name, char **argv, char **envp) +{ + int error; + char *filename; + struct pt_regs *regs = (struct pt_regs *)((&name) + 6); + + lock_kernel(); + filename = getname(name); + error = PTR_ERR(filename); + if (IS_ERR(filename)) + goto out; + error = do_execve(filename, argv, envp, regs); + putname(filename); + out: + unlock_kernel(); + return error; +} + +unsigned long get_wchan(struct task_struct *p) +{ + unsigned long fp, pc; + unsigned long stack_page; + int count = 0; + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + + stack_page = (unsigned long)p; + fp = p->thread.usp; + do { + if (fp < stack_page + sizeof(struct thread_info) || + fp >= 8184 + stack_page) + return 0; + pc = ((unsigned long *)fp)[1]; + if (!in_sched_functions(pc)) + return pc; + fp = *(unsigned long *)fp; + } + while (count++ < 16); + return 0; +} + +#if defined(CONFIG_ACCESS_CHECK) +int _access_ok(unsigned long addr, unsigned long size) +{ + + if (addr > (addr + size)) + return 0; + if (segment_eq(get_fs(),KERNEL_DS)) + return 1; +#ifdef CONFIG_MTD_UCLINUX + if (addr >= memory_start && (addr + size) <= memory_end) + return 1; + if (addr >= memory_mtd_end && (addr + size) <= physical_mem_end) + return 1; +#else + if (addr >= memory_start && (addr + size) <= physical_mem_end) + return 1; +#endif + if (addr >= (unsigned long)__init_begin && + addr + size <= (unsigned long)__init_end) + return 1; + if (addr >= L1_SCRATCH_START + && addr + size <= L1_SCRATCH_START + L1_SCRATCH_LENGTH) + return 1; +#if L1_CODE_LENGTH != 0 + if (addr >= L1_CODE_START + (_etext_l1 - _stext_l1) + && addr + size <= L1_CODE_START + L1_CODE_LENGTH) + return 1; +#endif +#if L1_DATA_A_LENGTH != 0 + if (addr >= L1_DATA_A_START + (_ebss_l1 - _sdata_l1) + && addr + size <= L1_DATA_A_START + L1_DATA_A_LENGTH) + return 1; +#endif +#if L1_DATA_B_LENGTH != 0 + if (addr >= L1_DATA_B_START + && addr + size <= L1_DATA_B_START + L1_DATA_B_LENGTH) + return 1; +#endif + return 0; +} +EXPORT_SYMBOL(_access_ok); +#endif /* CONFIG_ACCESS_CHECK */ diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c new file mode 100644 index 000000000000..d7c8e514cb92 --- /dev/null +++ b/arch/blackfin/kernel/ptrace.c @@ -0,0 +1,430 @@ +/* + * File: arch/blackfin/kernel/ptrace.c + * Based on: Taken from linux/kernel/ptrace.c + * Author: linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds + * + * Created: 1/23/92 + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define MAX_SHARED_LIBS 3 +#define TEXT_OFFSET 0 +/* + * does not yet catch signals sent when the child dies. + * in exit.c or in signal.c. + */ + +/* determines which bits in the SYSCFG reg the user has access to. */ +/* 1 = access 0 = no access */ +#define SYSCFG_MASK 0x0007 /* SYSCFG reg */ +/* sets the trace bits. */ +#define TRACE_BITS 0x0001 + +/* Find the stack offset for a register, relative to thread.esp0. */ +#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg) + +/* + * Get the address of the live pt_regs for the specified task. + * These are saved onto the top kernel stack when the process + * is not running. + * + * Note: if a user thread is execve'd from kernel space, the + * kernel stack will not be empty on entry to the kernel, so + * ptracing these tasks will fail. + */ +static inline struct pt_regs *get_user_regs(struct task_struct *task) +{ + return (struct pt_regs *) + ((unsigned long)task->thread_info + + (THREAD_SIZE - sizeof(struct pt_regs))); +} + +/* + * Get all user integer registers. + */ +static inline int ptrace_getregs(struct task_struct *tsk, void __user * uregs) +{ + struct pt_regs *regs = get_user_regs(tsk); + return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0; +} + +/* Mapping from PT_xxx to the stack offset at which the register is + * saved. Notice that usp has no stack-slot and needs to be treated + * specially (see get_reg/put_reg below). + */ + +/* + * Get contents of register REGNO in task TASK. + */ +static inline long get_reg(struct task_struct *task, int regno) +{ + unsigned char *reg_ptr; + + struct pt_regs *regs = + (struct pt_regs *)((unsigned long)task->thread_info + + (THREAD_SIZE - sizeof(struct pt_regs))); + reg_ptr = (char *)regs; + + switch (regno) { + case PT_USP: + return task->thread.usp; + default: + if (regno <= 216) + return *(long *)(reg_ptr + regno); + } + /* slight mystery ... never seems to come here but kernel misbehaves without this code! */ + + printk(KERN_WARNING "Request to get for unknown register %d\n", regno); + return 0; +} + +/* + * Write contents of register REGNO in task TASK. + */ +static inline int +put_reg(struct task_struct *task, int regno, unsigned long data) +{ + char * reg_ptr; + + struct pt_regs *regs = + (struct pt_regs *)((unsigned long)task->thread_info + + (THREAD_SIZE - sizeof(struct pt_regs))); + reg_ptr = (char *)regs; + + switch (regno) { + case PT_PC: + /*********************************************************************/ + /* At this point the kernel is most likely in exception. */ + /* The RETX register will be used to populate the pc of the process. */ + /*********************************************************************/ + regs->retx = data; + regs->pc = data; + break; + case PT_RETX: + break; /* regs->retx = data; break; */ + case PT_USP: + regs->usp = data; + task->thread.usp = data; + break; + default: + if (regno <= 216) + *(long *)(reg_ptr + regno) = data; + } + return 0; +} + +/* + * check that an address falls within the bounds of the target process's memory mappings + */ +static inline int is_user_addr_valid(struct task_struct *child, + unsigned long start, unsigned long len) +{ + struct vm_list_struct *vml; + struct sram_list_struct *sraml; + + for (vml = child->mm->context.vmlist; vml; vml = vml->next) + if (start >= vml->vma->vm_start && start + len <= vml->vma->vm_end) + return 0; + + for (sraml = child->mm->context.sram_list; sraml; sraml = sraml->next) + if (start >= (unsigned long)sraml->addr + && start + len <= (unsigned long)sraml->addr + sraml->length) + return 0; + + return -EIO; +} + +/* + * Called by kernel/ptrace.c when detaching.. + * + * Make sure the single step bit is not set. + */ +void ptrace_disable(struct task_struct *child) +{ + unsigned long tmp; + /* make sure the single step bit is not set. */ + tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16); + put_reg(child, PT_SR, tmp); +} + +long arch_ptrace(struct task_struct *child, long request, long addr, long data) +{ + int ret; + int add = 0; + + switch (request) { + /* when I and D space are separate, these will need to be fixed. */ + case PTRACE_PEEKDATA: + pr_debug("ptrace: PEEKDATA\n"); + add = MAX_SHARED_LIBS * 4; /* space between text and data */ + /* fall through */ + case PTRACE_PEEKTEXT: /* read word at location addr. */ + { + unsigned long tmp = 0; + int copied; + + ret = -EIO; + pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + add %d %ld\n", addr, add, + sizeof(data)); + if (is_user_addr_valid(child, addr + add, sizeof(tmp)) < 0) + break; + pr_debug("ptrace: user address is valid\n"); + +#if L1_CODE_LENGTH != 0 + if (addr + add >= L1_CODE_START + && addr + add + sizeof(tmp) <= L1_CODE_START + L1_CODE_LENGTH) { + safe_dma_memcpy (&tmp, (const void *)(addr + add), sizeof(tmp)); + copied = sizeof(tmp); + } else +#endif + copied = + access_process_vm(child, addr + add, &tmp, + sizeof(tmp), 0); + pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp); + if (copied != sizeof(tmp)) + break; + ret = put_user(tmp, (unsigned long *)data); + break; + } + + /* read the word at location addr in the USER area. */ + case PTRACE_PEEKUSR: + { + unsigned long tmp; + ret = -EIO; + tmp = 0; + if ((addr & 3) || (addr > (sizeof(struct pt_regs) + 16))) { + printk(KERN_WARNING "ptrace error : PEEKUSR : temporarily returning " + "0 - %x sizeof(pt_regs) is %lx\n", + (int)addr, sizeof(struct pt_regs)); + break; + } + if (addr == sizeof(struct pt_regs)) { + /* PT_TEXT_ADDR */ + tmp = child->mm->start_code + TEXT_OFFSET; + } else if (addr == (sizeof(struct pt_regs) + 4)) { + /* PT_TEXT_END_ADDR */ + tmp = child->mm->end_code; + } else if (addr == (sizeof(struct pt_regs) + 8)) { + /* PT_DATA_ADDR */ + tmp = child->mm->start_data; +#ifdef CONFIG_BINFMT_ELF_FDPIC + } else if (addr == (sizeof(struct pt_regs) + 12)) { + tmp = child->mm->context.exec_fdpic_loadmap; + } else if (addr == (sizeof(struct pt_regs) + 16)) { + tmp = child->mm->context.interp_fdpic_loadmap; +#endif + } else { + tmp = get_reg(child, addr); + } + ret = put_user(tmp, (unsigned long *)data); + break; + } + + /* when I and D space are separate, this will have to be fixed. */ + case PTRACE_POKEDATA: + printk(KERN_NOTICE "ptrace: PTRACE_PEEKDATA\n"); + /* fall through */ + case PTRACE_POKETEXT: /* write the word at location addr. */ + { + int copied; + + ret = -EIO; + pr_debug("ptrace: POKETEXT at addr 0x%08lx + add %d %ld bytes %lx\n", + addr, add, sizeof(data), data); + if (is_user_addr_valid(child, addr + add, sizeof(data)) < 0) + break; + pr_debug("ptrace: user address is valid\n"); + +#if L1_CODE_LENGTH != 0 + if (addr + add >= L1_CODE_START + && addr + add + sizeof(data) <= L1_CODE_START + L1_CODE_LENGTH) { + safe_dma_memcpy ((void *)(addr + add), &data, sizeof(data)); + copied = sizeof(data); + } else +#endif + copied = + access_process_vm(child, addr + add, &data, + sizeof(data), 1); + pr_debug("ptrace: copied size %d\n", copied); + if (copied != sizeof(data)) + break; + ret = 0; + break; + } + + case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ + ret = -EIO; + if ((addr & 3) || (addr > (sizeof(struct pt_regs) + 16))) { + printk(KERN_WARNING "ptrace error : POKEUSR: temporarily returning 0\n"); + break; + } + + if (addr >= (sizeof(struct pt_regs))) { + ret = 0; + break; + } + if (addr == PT_SYSCFG) { + data &= SYSCFG_MASK; + data |= get_reg(child, PT_SYSCFG); + } + ret = put_reg(child, addr, data); + break; + + case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ + case PTRACE_CONT: + { /* restart after signal. */ + long tmp; + + pr_debug("ptrace_cont\n"); + + ret = -EIO; + if (!valid_signal(data)) + break; + if (request == PTRACE_SYSCALL) + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + else + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + + child->exit_code = data; + /* make sure the single step bit is not set. */ + tmp = get_reg(child, PT_SYSCFG) & ~(TRACE_BITS); + put_reg(child, PT_SYSCFG, tmp); + pr_debug("before wake_up_process\n"); + wake_up_process(child); + ret = 0; + break; + } + + /* + * make the child exit. Best I can do is send it a sigkill. + * perhaps it should be put in the status that it wants to + * exit. + */ + case PTRACE_KILL: + { + long tmp; + ret = 0; + if (child->exit_state == EXIT_ZOMBIE) /* already dead */ + break; + child->exit_code = SIGKILL; + /* make sure the single step bit is not set. */ + tmp = get_reg(child, PT_SYSCFG) & ~(TRACE_BITS); + put_reg(child, PT_SYSCFG, tmp); + wake_up_process(child); + break; + } + + case PTRACE_SINGLESTEP: + { /* set the trap flag. */ + long tmp; + + pr_debug("single step\n"); + ret = -EIO; + if (!valid_signal(data)) + break; + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + + tmp = get_reg(child, PT_SYSCFG) | (TRACE_BITS); + put_reg(child, PT_SYSCFG, tmp); + + child->exit_code = data; + /* give it a chance to run. */ + wake_up_process(child); + ret = 0; + break; + } + + case PTRACE_DETACH: + { /* detach a process that was attached. */ + ret = ptrace_detach(child, data); + break; + } + + case PTRACE_GETREGS: + { + + /* Get all gp regs from the child. */ + ret = ptrace_getregs(child, (void __user *)data); + break; + } + + case PTRACE_SETREGS: + { + printk(KERN_NOTICE + "ptrace: SETREGS: **** NOT IMPLEMENTED ***\n"); + /* Set all gp regs in the child. */ + ret = 0; + break; + } + default: + ret = ptrace_request(child, request, addr, data); + break; + } + + return ret; +} + +asmlinkage void syscall_trace(void) +{ + + if (!test_thread_flag(TIF_SYSCALL_TRACE)) + return; + + if (!(current->ptrace & PT_PTRACED)) + return; + + /* the 0x80 provides a way for the tracing parent to distinguish + * between a syscall stop and SIGTRAP delivery + */ + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) + ? 0x80 : 0)); + + /* + * this isn't the same as continuing with a signal, but it will do + * for normal use. strace only continues with a signal if the + * stopping signal is not SIGTRAP. -brl + */ + if (current->exit_code) { + send_sig(current->exit_code, current, 1); + current->exit_code = 0; + } +} diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c new file mode 100644 index 000000000000..342bb8dd56ac --- /dev/null +++ b/arch/blackfin/kernel/setup.c @@ -0,0 +1,902 @@ +/* + * File: arch/blackfin/kernel/setup.c + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +unsigned long memory_start, memory_end, physical_mem_end; +unsigned long reserved_mem_dcache_on; +unsigned long reserved_mem_icache_on; +EXPORT_SYMBOL(memory_start); +EXPORT_SYMBOL(memory_end); +EXPORT_SYMBOL(physical_mem_end); +EXPORT_SYMBOL(_ramend); + +#ifdef CONFIG_MTD_UCLINUX +unsigned long memory_mtd_end, memory_mtd_start, mtd_size; +unsigned long _ebss; +EXPORT_SYMBOL(memory_mtd_end); +EXPORT_SYMBOL(memory_mtd_start); +EXPORT_SYMBOL(mtd_size); +#endif + +char command_line[COMMAND_LINE_SIZE]; + +#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE) +static void generate_cpl_tables(void); +#endif + +void __init bf53x_cache_init(void) +{ +#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE) + generate_cpl_tables(); +#endif + +#ifdef CONFIG_BLKFIN_CACHE + bfin_icache_init(); + printk(KERN_INFO "Instruction Cache Enabled\n"); +#endif + +#ifdef CONFIG_BLKFIN_DCACHE + bfin_dcache_init(); + printk(KERN_INFO "Data Cache Enabled" +# if defined CONFIG_BLKFIN_WB + " (write-back)" +# elif defined CONFIG_BLKFIN_WT + " (write-through)" +# endif + "\n"); +#endif +} + +void bf53x_relocate_l1_mem(void) +{ + unsigned long l1_code_length; + unsigned long l1_data_a_length; + unsigned long l1_data_b_length; + + l1_code_length = _etext_l1 - _stext_l1; + if (l1_code_length > L1_CODE_LENGTH) + l1_code_length = L1_CODE_LENGTH; + /* cannot complain as printk is not available as yet. + * But we can continue booting and complain later! + */ + + /* Copy _stext_l1 to _etext_l1 to L1 instruction SRAM */ + dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length); + + l1_data_a_length = _ebss_l1 - _sdata_l1; + if (l1_data_a_length > L1_DATA_A_LENGTH) + l1_data_a_length = L1_DATA_A_LENGTH; + + /* Copy _sdata_l1 to _ebss_l1 to L1 data bank A SRAM */ + dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length); + + l1_data_b_length = _ebss_b_l1 - _sdata_b_l1; + if (l1_data_b_length > L1_DATA_B_LENGTH) + l1_data_b_length = L1_DATA_B_LENGTH; + + /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */ + dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + + l1_data_a_length, l1_data_b_length); + +} + +/* + * Initial parsing of the command line. Currently, we support: + * - Controlling the linux memory size: mem=xxx[KMG] + * - Controlling the physical memory size: max_mem=xxx[KMG][$][#] + * $ -> reserved memory is dcacheable + * # -> reserved memory is icacheable + */ +static __init void parse_cmdline_early(char *cmdline_p) +{ + char c = ' ', *to = cmdline_p; + unsigned int memsize; + for (;;) { + if (c == ' ') { + + if (!memcmp(to, "mem=", 4)) { + to += 4; + memsize = memparse(to, &to); + if (memsize) + _ramend = memsize; + + } else if (!memcmp(to, "max_mem=", 8)) { + to += 8; + memsize = memparse(to, &to); + if (memsize) { + physical_mem_end = memsize; + if (*to != ' ') { + if (*to == '$' + || *(to + 1) == '$') + reserved_mem_dcache_on = + 1; + if (*to == '#' + || *(to + 1) == '#') + reserved_mem_icache_on = + 1; + } + } + } + + } + c = *(to++); + if (!c) + break; + } +} + +void __init setup_arch(char **cmdline_p) +{ + int bootmap_size; + unsigned long l1_length, sclk, cclk; +#ifdef CONFIG_MTD_UCLINUX + unsigned long mtd_phys = 0; +#endif + + cclk = get_cclk(); + sclk = get_sclk(); + +#if !defined(CONFIG_BFIN_KERNEL_CLOCK) && defined(ANOMALY_05000273) + if (cclk == sclk) + panic("ANOMALY 05000273, SCLK can not be same as CCLK"); +#endif + +#if defined(ANOMALY_05000266) + bfin_read_IMDMA_D0_IRQ_STATUS(); + bfin_read_IMDMA_D1_IRQ_STATUS(); +#endif + +#ifdef DEBUG_SERIAL_EARLY_INIT + bfin_console_init(); /* early console registration */ + /* this give a chance to get printk() working before crash. */ +#endif + +#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) + /* we need to initialize the Flashrom device here since we might + * do things with flash early on in the boot + */ + flash_probe(); +#endif + +#if defined(CONFIG_CMDLINE_BOOL) + memset(command_line, 0, sizeof(command_line)); + strncpy(&command_line[0], CONFIG_CMDLINE, sizeof(command_line)); + command_line[sizeof(command_line) - 1] = 0; +#endif + + /* Keep a copy of command line */ + *cmdline_p = &command_line[0]; + memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); + boot_command_line[COMMAND_LINE_SIZE - 1] = 0; + + /* setup memory defaults from the user config */ + physical_mem_end = 0; + _ramend = CONFIG_MEM_SIZE * 1024 * 1024; + + parse_cmdline_early(&command_line[0]); + + if (physical_mem_end == 0) + physical_mem_end = _ramend; + + /* by now the stack is part of the init task */ + memory_end = _ramend - DMA_UNCACHED_REGION; + + _ramstart = (unsigned long)__bss_stop; + memory_start = PAGE_ALIGN(_ramstart); + +#if defined(CONFIG_MTD_UCLINUX) + /* generic memory mapped MTD driver */ + memory_mtd_end = memory_end; + + mtd_phys = _ramstart; + mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 8))); + +# if defined(CONFIG_EXT2_FS) || defined(CONFIG_EXT3_FS) + if (*((unsigned short *)(mtd_phys + 0x438)) == EXT2_SUPER_MAGIC) + mtd_size = + PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x404)) << 10); +# endif + +# if defined(CONFIG_CRAMFS) + if (*((unsigned long *)(mtd_phys)) == CRAMFS_MAGIC) + mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x4))); +# endif + +# if defined(CONFIG_ROMFS_FS) + if (((unsigned long *)mtd_phys)[0] == ROMSB_WORD0 + && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1) + mtd_size = + PAGE_ALIGN(be32_to_cpu(((unsigned long *)mtd_phys)[2])); +# if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263)) + /* Due to a Hardware Anomaly we need to limit the size of usable + * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on + * 05000263 - Hardware loop corrupted when taking an ICPLB exception + */ +# if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO)) + if (memory_end >= 56 * 1024 * 1024) + memory_end = 56 * 1024 * 1024; +# else + if (memory_end >= 60 * 1024 * 1024) + memory_end = 60 * 1024 * 1024; +# endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */ +# endif /* ANOMALY_05000263 */ +# endif /* CONFIG_ROMFS_FS */ + + memory_end -= mtd_size; + + if (mtd_size == 0) { + console_init(); + panic("Don't boot kernel without rootfs attached.\n"); + } + + /* Relocate MTD image to the top of memory after the uncached memory area */ + dma_memcpy((char *)memory_end, __bss_stop, mtd_size); + + memory_mtd_start = memory_end; + _ebss = memory_mtd_start; /* define _ebss for compatible */ +#endif /* CONFIG_MTD_UCLINUX */ + +#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263)) + /* Due to a Hardware Anomaly we need to limit the size of usable + * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on + * 05000263 - Hardware loop corrupted when taking an ICPLB exception + */ +#if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO)) + if (memory_end >= 56 * 1024 * 1024) + memory_end = 56 * 1024 * 1024; +#else + if (memory_end >= 60 * 1024 * 1024) + memory_end = 60 * 1024 * 1024; +#endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */ + printk(KERN_NOTICE "Warning: limiting memory to %liMB due to hardware anomaly 05000263\n", memory_end >> 20); +#endif /* ANOMALY_05000263 */ + +#if !defined(CONFIG_MTD_UCLINUX) + memory_end -= SIZE_4K; /*In case there is no valid CPLB behind memory_end make sure we don't get to close*/ +#endif + init_mm.start_code = (unsigned long)_stext; + init_mm.end_code = (unsigned long)_etext; + init_mm.end_data = (unsigned long)_edata; + init_mm.brk = (unsigned long)0; + + init_leds(); + + printk(KERN_INFO "Blackfin support (C) 2004-2007 Analog Devices, Inc.\n"); + printk(KERN_INFO "Compiled for ADSP-%s Rev 0.%d\n", CPU, bfin_compiled_revid()); + if (bfin_revid() != bfin_compiled_revid()) + printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n", + bfin_compiled_revid(), bfin_revid()); + if (bfin_revid() < SUPPORTED_REVID) + printk(KERN_ERR "Warning: Unsupported Chip Revision ADSP-%s Rev 0.%d detected\n", + CPU, bfin_revid()); + printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); + + printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu Mhz System Clock\n", + cclk / 1000000, sclk / 1000000); + +#if defined(ANOMALY_05000273) + if ((cclk >> 1) <= sclk) + printk("\n\n\nANOMALY_05000273: CCLK must be >= 2*SCLK !!!\n\n\n"); +#endif + + printk(KERN_INFO "Board Memory: %ldMB\n", physical_mem_end >> 20); + printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20); + + printk(KERN_INFO "Memory map:\n" + KERN_INFO " text = 0x%p-0x%p\n" + KERN_INFO " init = 0x%p-0x%p\n" + KERN_INFO " data = 0x%p-0x%p\n" + KERN_INFO " stack = 0x%p-0x%p\n" + KERN_INFO " bss = 0x%p-0x%p\n" + KERN_INFO " available = 0x%p-0x%p\n" +#ifdef CONFIG_MTD_UCLINUX + KERN_INFO " rootfs = 0x%p-0x%p\n" +#endif +#if DMA_UNCACHED_REGION > 0 + KERN_INFO " DMA Zone = 0x%p-0x%p\n" +#endif + , _stext, _etext, + __init_begin, __init_end, + _sdata, _edata, + (void*)&init_thread_union, (void*)((int)(&init_thread_union) + 0x2000), + __bss_start, __bss_stop, + (void*)_ramstart, (void*)memory_end +#ifdef CONFIG_MTD_UCLINUX + , (void*)memory_mtd_start, (void*)(memory_mtd_start + mtd_size) +#endif +#if DMA_UNCACHED_REGION > 0 + , (void*)(_ramend - DMA_UNCACHED_REGION), (void*)(_ramend) +#endif + ); + + /* + * give all the memory to the bootmap allocator, tell it to put the + * boot mem_map at the start of memory + */ + bootmap_size = init_bootmem_node(NODE_DATA(0), memory_start >> PAGE_SHIFT, /* map goes here */ + PAGE_OFFSET >> PAGE_SHIFT, + memory_end >> PAGE_SHIFT); + /* + * free the usable memory, we have to make sure we do not free + * the bootmem bitmap so we then reserve it after freeing it :-) + */ + free_bootmem(memory_start, memory_end - memory_start); + + reserve_bootmem(memory_start, bootmap_size); + /* + * get kmalloc into gear + */ + paging_init(); + + /* check the size of the l1 area */ + l1_length = _etext_l1 - _stext_l1; + if (l1_length > L1_CODE_LENGTH) + panic("L1 memory overflow\n"); + + l1_length = _ebss_l1 - _sdata_l1; + if (l1_length > L1_DATA_A_LENGTH) + panic("L1 memory overflow\n"); + + bf53x_cache_init(); + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +# if defined(CONFIG_BFIN_SHARED_FLASH_ENET) && defined(CONFIG_BFIN533_STAMP) + /* setup BF533_STAMP CPLD to route AMS3 to Ethernet MAC */ + bfin_write_FIO_DIR(bfin_read_FIO_DIR() | (1 << CONFIG_ENET_FLASH_PIN)); + bfin_write_FIO_FLAG_S(1 << CONFIG_ENET_FLASH_PIN); + SSYNC(); +# endif +# if defined (CONFIG_BFIN561_EZKIT) + bfin_write_FIO0_DIR(bfin_read_FIO0_DIR() | (1 << 12)); + SSYNC(); +# endif /* defined (CONFIG_BFIN561_EZKIT) */ +#endif + + printk(KERN_INFO "Hardware Trace Enabled\n"); + bfin_write_TBUFCTL(0x03); +} + +#if defined(CONFIG_BF561) +static struct cpu cpu[2]; +#else +static struct cpu cpu[1]; +#endif +static int __init topology_init(void) +{ +#if defined (CONFIG_BF561) + register_cpu(&cpu[0], 0); + register_cpu(&cpu[1], 1); + return 0; +#else + return register_cpu(cpu, 0); +#endif +} + +subsys_initcall(topology_init); + +#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE) +u16 lock_kernel_check(u32 start, u32 end) +{ + if ((start <= (u32) _stext && end >= (u32) _end) + || (start >= (u32) _stext && end <= (u32) _end)) + return IN_KERNEL; + return 0; +} + +static unsigned short __init +fill_cplbtab(struct cplb_tab *table, + unsigned long start, unsigned long end, + unsigned long block_size, unsigned long cplb_data) +{ + int i; + + switch (block_size) { + case SIZE_4M: + i = 3; + break; + case SIZE_1M: + i = 2; + break; + case SIZE_4K: + i = 1; + break; + case SIZE_1K: + default: + i = 0; + break; + } + + cplb_data = (cplb_data & ~(3 << 16)) | (i << 16); + + while ((start < end) && (table->pos < table->size)) { + + table->tab[table->pos++] = start; + + if (lock_kernel_check(start, start + block_size) == IN_KERNEL) + table->tab[table->pos++] = + cplb_data | CPLB_LOCK | CPLB_DIRTY; + else + table->tab[table->pos++] = cplb_data; + + start += block_size; + } + return 0; +} + +static unsigned short __init +close_cplbtab(struct cplb_tab *table) +{ + + while (table->pos < table->size) { + + table->tab[table->pos++] = 0; + table->tab[table->pos++] = 0; /* !CPLB_VALID */ + } + return 0; +} + +static void __init generate_cpl_tables(void) +{ + + u16 i, j, process; + u32 a_start, a_end, as, ae, as_1m; + + struct cplb_tab *t_i = NULL; + struct cplb_tab *t_d = NULL; + struct s_cplb cplb; + + cplb.init_i.size = MAX_CPLBS; + cplb.init_d.size = MAX_CPLBS; + cplb.switch_i.size = MAX_SWITCH_I_CPLBS; + cplb.switch_d.size = MAX_SWITCH_D_CPLBS; + + cplb.init_i.pos = 0; + cplb.init_d.pos = 0; + cplb.switch_i.pos = 0; + cplb.switch_d.pos = 0; + + cplb.init_i.tab = icplb_table; + cplb.init_d.tab = dcplb_table; + cplb.switch_i.tab = ipdt_table; + cplb.switch_d.tab = dpdt_table; + + cplb_data[SDRAM_KERN].end = memory_end; + +#ifdef CONFIG_MTD_UCLINUX + cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start; + cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size; + cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0; +# if defined(CONFIG_ROMFS_FS) + cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB; + + /* + * The ROMFS_FS size is often not multiple of 1MB. + * This can cause multiple CPLB sets covering the same memory area. + * This will then cause multiple CPLB hit exceptions. + * Workaround: We ensure a contiguous memory area by extending the kernel + * memory section over the mtd section. + * For ROMFS_FS memory must be covered with ICPLBs anyways. + * So there is no difference between kernel and mtd memory setup. + */ + + cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;; + cplb_data[SDRAM_RAM_MTD].valid = 0; + +# endif +#else + cplb_data[SDRAM_RAM_MTD].valid = 0; +#endif + + cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION; + cplb_data[SDRAM_DMAZ].end = _ramend; + + cplb_data[RES_MEM].start = _ramend; + cplb_data[RES_MEM].end = physical_mem_end; + + if (reserved_mem_dcache_on) + cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC; + else + cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL; + + if (reserved_mem_icache_on) + cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC; + else + cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL; + + for (i = ZERO_P; i <= L2_MEM; i++) { + + if (cplb_data[i].valid) { + + as_1m = cplb_data[i].start % SIZE_1M; + + /* We need to make sure all sections are properly 1M aligned + * However between Kernel Memory and the Kernel mtd section, depending on the + * rootfs size, there can be overlapping memory areas. + */ + + if (as_1m && i!=L1I_MEM && i!=L1D_MEM) { +#ifdef CONFIG_MTD_UCLINUX + if (i == SDRAM_RAM_MTD) { + if ((cplb_data[SDRAM_KERN].end + 1) > cplb_data[SDRAM_RAM_MTD].start) + cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M)) + SIZE_1M; + else + cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M)); + } else +#endif + printk(KERN_WARNING "Unaligned Start of %s at 0x%X\n", + cplb_data[i].name, cplb_data[i].start); + } + + as = cplb_data[i].start % SIZE_4M; + ae = cplb_data[i].end % SIZE_4M; + + if (as) + a_start = cplb_data[i].start + (SIZE_4M - (as)); + else + a_start = cplb_data[i].start; + + a_end = cplb_data[i].end - ae; + + for (j = INITIAL_T; j <= SWITCH_T; j++) { + + switch (j) { + case INITIAL_T: + if (cplb_data[i].attr & INITIAL_T) { + t_i = &cplb.init_i; + t_d = &cplb.init_d; + process = 1; + } else + process = 0; + break; + case SWITCH_T: + if (cplb_data[i].attr & SWITCH_T) { + t_i = &cplb.switch_i; + t_d = &cplb.switch_d; + process = 1; + } else + process = 0; + break; + default: + process = 0; + break; + } + + if (process) { + if (cplb_data[i].attr & I_CPLB) { + + if (cplb_data[i].psize) { + fill_cplbtab(t_i, + cplb_data[i].start, + cplb_data[i].end, + cplb_data[i].psize, + cplb_data[i].i_conf); + } else { + /*icplb_table */ +#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263)) + if (i == SDRAM_KERN) { + fill_cplbtab(t_i, + cplb_data[i].start, + cplb_data[i].end, + SIZE_4M, + cplb_data[i].i_conf); + } else +#endif + { + fill_cplbtab(t_i, + cplb_data[i].start, + a_start, + SIZE_1M, + cplb_data[i].i_conf); + fill_cplbtab(t_i, + a_start, + a_end, + SIZE_4M, + cplb_data[i].i_conf); + fill_cplbtab(t_i, a_end, + cplb_data[i].end, + SIZE_1M, + cplb_data[i].i_conf); + } + } + + } + if (cplb_data[i].attr & D_CPLB) { + + if (cplb_data[i].psize) { + fill_cplbtab(t_d, + cplb_data[i].start, + cplb_data[i].end, + cplb_data[i].psize, + cplb_data[i].d_conf); + } else { +/*dcplb_table*/ + fill_cplbtab(t_d, + cplb_data[i].start, + a_start, SIZE_1M, + cplb_data[i].d_conf); + fill_cplbtab(t_d, a_start, + a_end, SIZE_4M, + cplb_data[i].d_conf); + fill_cplbtab(t_d, a_end, + cplb_data[i].end, + SIZE_1M, + cplb_data[i].d_conf); + + } + + } + } + } + + } + } + +/* close tables */ + + close_cplbtab(&cplb.init_i); + close_cplbtab(&cplb.init_d); + + cplb.init_i.tab[cplb.init_i.pos] = -1; + cplb.init_d.tab[cplb.init_d.pos] = -1; + cplb.switch_i.tab[cplb.switch_i.pos] = -1; + cplb.switch_d.tab[cplb.switch_d.pos] = -1; + +} + +#endif + +static inline u_long get_vco(void) +{ + u_long msel; + u_long vco; + + msel = (bfin_read_PLL_CTL() >> 9) & 0x3F; + if (0 == msel) + msel = 64; + + vco = CONFIG_CLKIN_HZ; + vco >>= (1 & bfin_read_PLL_CTL()); /* DF bit */ + vco = msel * vco; + return vco; +} + +/*Get the Core clock*/ +u_long get_cclk(void) +{ + u_long csel, ssel; + if (bfin_read_PLL_STAT() & 0x1) + return CONFIG_CLKIN_HZ; + + ssel = bfin_read_PLL_DIV(); + csel = ((ssel >> 4) & 0x03); + ssel &= 0xf; + if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */ + return get_vco() / ssel; + return get_vco() >> csel; +} + +EXPORT_SYMBOL(get_cclk); + +/* Get the System clock */ +u_long get_sclk(void) +{ + u_long ssel; + + if (bfin_read_PLL_STAT() & 0x1) + return CONFIG_CLKIN_HZ; + + ssel = (bfin_read_PLL_DIV() & 0xf); + if (0 == ssel) { + printk(KERN_WARNING "Invalid System Clock\n"); + ssel = 1; + } + + return get_vco() / ssel; +} + +EXPORT_SYMBOL(get_sclk); + +/* + * Get CPU information for use by the procfs. + */ +static int show_cpuinfo(struct seq_file *m, void *v) +{ + char *cpu, *mmu, *fpu, *name; + uint32_t revid; + + u_long cclk = 0, sclk = 0; + u_int dcache_size = 0, dsup_banks = 0; + + cpu = CPU; + mmu = "none"; + fpu = "none"; + revid = bfin_revid(); + name = bfin_board_name; + + cclk = get_cclk(); + sclk = get_sclk(); + + seq_printf(m, "CPU:\t\tADSP-%s Rev. 0.%d\n" + "MMU:\t\t%s\n" + "FPU:\t\t%s\n" + "Core Clock:\t%9lu Hz\n" + "System Clock:\t%9lu Hz\n" + "BogoMips:\t%lu.%02lu\n" + "Calibration:\t%lu loops\n", + cpu, revid, mmu, fpu, + cclk, + sclk, + (loops_per_jiffy * HZ) / 500000, + ((loops_per_jiffy * HZ) / 5000) % 100, + (loops_per_jiffy * HZ)); + seq_printf(m, "Board Name:\t%s\n", name); + seq_printf(m, "Board Memory:\t%ld MB\n", physical_mem_end >> 20); + seq_printf(m, "Kernel Memory:\t%ld MB\n", (unsigned long)_ramend >> 20); + if (bfin_read_IMEM_CONTROL() & (ENICPLB | IMC)) + seq_printf(m, "I-CACHE:\tON\n"); + else + seq_printf(m, "I-CACHE:\tOFF\n"); + if ((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE)) + seq_printf(m, "D-CACHE:\tON" +#if defined CONFIG_BLKFIN_WB + " (write-back)" +#elif defined CONFIG_BLKFIN_WT + " (write-through)" +#endif + "\n"); + else + seq_printf(m, "D-CACHE:\tOFF\n"); + + + switch(bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) { + case ACACHE_BSRAM: + seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n"); + dcache_size = 16; + dsup_banks = 1; + break; + case ACACHE_BCACHE: + seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n"); + dcache_size = 32; + dsup_banks = 2; + break; + case ASRAM_BSRAM: + seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n"); + dcache_size = 0; + dsup_banks = 0; + break; + default: + break; + } + + + seq_printf(m, "I-CACHE Size:\t%dKB\n", BLKFIN_ICACHESIZE / 1024); + seq_printf(m, "D-CACHE Size:\t%dKB\n", dcache_size); + seq_printf(m, "I-CACHE Setup:\t%d Sub-banks/%d Ways, %d Lines/Way\n", + BLKFIN_ISUBBANKS, BLKFIN_IWAYS, BLKFIN_ILINES); + seq_printf(m, + "D-CACHE Setup:\t%d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n", + dsup_banks, BLKFIN_DSUBBANKS, BLKFIN_DWAYS, + BLKFIN_DLINES); +#ifdef CONFIG_BLKFIN_CACHE_LOCK + switch (read_iloc()) { + case WAY0_L: + seq_printf(m, "Way0 Locked-Down\n"); + break; + case WAY1_L: + seq_printf(m, "Way1 Locked-Down\n"); + break; + case WAY01_L: + seq_printf(m, "Way0,Way1 Locked-Down\n"); + break; + case WAY2_L: + seq_printf(m, "Way2 Locked-Down\n"); + break; + case WAY02_L: + seq_printf(m, "Way0,Way2 Locked-Down\n"); + break; + case WAY12_L: + seq_printf(m, "Way1,Way2 Locked-Down\n"); + break; + case WAY012_L: + seq_printf(m, "Way0,Way1 & Way2 Locked-Down\n"); + break; + case WAY3_L: + seq_printf(m, "Way3 Locked-Down\n"); + break; + case WAY03_L: + seq_printf(m, "Way0,Way3 Locked-Down\n"); + break; + case WAY13_L: + seq_printf(m, "Way1,Way3 Locked-Down\n"); + break; + case WAY013_L: + seq_printf(m, "Way 0,Way1,Way3 Locked-Down\n"); + break; + case WAY32_L: + seq_printf(m, "Way3,Way2 Locked-Down\n"); + break; + case WAY320_L: + seq_printf(m, "Way3,Way2,Way0 Locked-Down\n"); + break; + case WAY321_L: + seq_printf(m, "Way3,Way2,Way1 Locked-Down\n"); + break; + case WAYALL_L: + seq_printf(m, "All Ways are locked\n"); + break; + default: + seq_printf(m, "No Ways are locked\n"); + } +#endif + return 0; +} + +static void *c_start(struct seq_file *m, loff_t *pos) +{ + return *pos < NR_CPUS ? ((void *)0x12345678) : NULL; +} + +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return c_start(m, pos); +} + +static void c_stop(struct seq_file *m, void *v) +{ +} + +struct seq_operations cpuinfo_op = { + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, +}; + +void cmdline_init(unsigned long r0) +{ + if (r0) + strncpy(command_line, (char *)r0, COMMAND_LINE_SIZE); +} diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c new file mode 100644 index 000000000000..316e65c3439d --- /dev/null +++ b/arch/blackfin/kernel/signal.c @@ -0,0 +1,356 @@ +/* + * File: arch/blackfin/kernel/signal.c + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) + +struct fdpic_func_descriptor { + unsigned long text; + unsigned long GOT; +}; + +struct rt_sigframe { + int sig; + struct siginfo *pinfo; + void *puc; + char retcode[8]; + struct siginfo info; + struct ucontext uc; +}; + +asmlinkage int sys_sigaltstack(const stack_t * uss, stack_t * uoss) +{ + return do_sigaltstack(uss, uoss, rdusp()); +} + +static inline int +rt_restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *pr0) +{ + unsigned long usp = 0; + int err = 0; + +#define RESTORE(x) err |= __get_user(regs->x, &sc->sc_##x) + + /* restore passed registers */ + RESTORE(r0); RESTORE(r1); RESTORE(r2); RESTORE(r3); + RESTORE(r4); RESTORE(r5); RESTORE(r6); RESTORE(r7); + RESTORE(p0); RESTORE(p1); RESTORE(p2); RESTORE(p3); + RESTORE(p4); RESTORE(p5); + err |= __get_user(usp, &sc->sc_usp); + wrusp(usp); + RESTORE(a0w); RESTORE(a1w); + RESTORE(a0x); RESTORE(a1x); + RESTORE(astat); + RESTORE(rets); + RESTORE(pc); + RESTORE(retx); + RESTORE(fp); + RESTORE(i0); RESTORE(i1); RESTORE(i2); RESTORE(i3); + RESTORE(m0); RESTORE(m1); RESTORE(m2); RESTORE(m3); + RESTORE(l0); RESTORE(l1); RESTORE(l2); RESTORE(l3); + RESTORE(b0); RESTORE(b1); RESTORE(b2); RESTORE(b3); + RESTORE(lc0); RESTORE(lc1); + RESTORE(lt0); RESTORE(lt1); + RESTORE(lb0); RESTORE(lb1); + RESTORE(seqstat); + + regs->orig_p0 = -1; /* disable syscall checks */ + + *pr0 = regs->r0; + return err; +} + +asmlinkage int do_rt_sigreturn(unsigned long __unused) +{ + struct pt_regs *regs = (struct pt_regs *)__unused; + unsigned long usp = rdusp(); + struct rt_sigframe *frame = (struct rt_sigframe *)(usp); + sigset_t set; + int r0; + + if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + if (rt_restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) + goto badframe; + + if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->usp) == -EFAULT) + goto badframe; + + return r0; + + badframe: + force_sig(SIGSEGV, current); + return 0; +} + +static inline int rt_setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs) +{ + int err = 0; + +#define SETUP(x) err |= __put_user(regs->x, &sc->sc_##x) + + SETUP(r0); SETUP(r1); SETUP(r2); SETUP(r3); + SETUP(r4); SETUP(r5); SETUP(r6); SETUP(r7); + SETUP(p0); SETUP(p1); SETUP(p2); SETUP(p3); + SETUP(p4); SETUP(p5); + err |= __put_user(rdusp(), &sc->sc_usp); + SETUP(a0w); SETUP(a1w); + SETUP(a0x); SETUP(a1x); + SETUP(astat); + SETUP(rets); + SETUP(pc); + SETUP(retx); + SETUP(fp); + SETUP(i0); SETUP(i1); SETUP(i2); SETUP(i3); + SETUP(m0); SETUP(m1); SETUP(m2); SETUP(m3); + SETUP(l0); SETUP(l1); SETUP(l2); SETUP(l3); + SETUP(b0); SETUP(b1); SETUP(b2); SETUP(b3); + SETUP(lc0); SETUP(lc1); + SETUP(lt0); SETUP(lt1); + SETUP(lb0); SETUP(lb1); + SETUP(seqstat); + + return err; +} + +static inline void push_cache(unsigned long vaddr, unsigned int len) +{ + flush_icache_range(vaddr, vaddr + len); +} + +static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, + size_t frame_size) +{ + unsigned long usp; + + /* Default to using normal stack. */ + usp = rdusp(); + + /* This is the X/Open sanctioned signal stack switching. */ + if (ka->sa.sa_flags & SA_ONSTACK) { + if (!on_sig_stack(usp)) + usp = current->sas_ss_sp + current->sas_ss_size; + } + return (void *)((usp - frame_size) & -8UL); +} + +static int +setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info, + sigset_t * set, struct pt_regs *regs) +{ + struct rt_sigframe *frame; + int err = 0; + + frame = get_sigframe(ka, regs, sizeof(*frame)); + + err |= __put_user((current_thread_info()->exec_domain + && current_thread_info()->exec_domain->signal_invmap + && sig < 32 + ? current_thread_info()->exec_domain-> + signal_invmap[sig] : sig), &frame->sig); + + err |= __put_user(&frame->info, &frame->pinfo); + err |= __put_user(&frame->uc, &frame->puc); + err |= copy_siginfo_to_user(&frame->info, info); + + /* Create the ucontext. */ + err |= __put_user(0, &frame->uc.uc_flags); + err |= __put_user(0, &frame->uc.uc_link); + err |= + __put_user((void *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); + err |= __put_user(sas_ss_flags(rdusp()), &frame->uc.uc_stack.ss_flags); + err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); + err |= rt_setup_sigcontext(&frame->uc.uc_mcontext, regs); + err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + + /* Set up to return from userspace. */ + err |= __put_user(0x28, &(frame->retcode[0])); + err |= __put_user(0xe1, &(frame->retcode[1])); + err |= __put_user(0xad, &(frame->retcode[2])); + err |= __put_user(0x00, &(frame->retcode[3])); + err |= __put_user(0xa0, &(frame->retcode[4])); + err |= __put_user(0x00, &(frame->retcode[5])); + + if (err) + goto give_sigsegv; + + push_cache((unsigned long)&frame->retcode, sizeof(frame->retcode)); + + /* Set up registers for signal handler */ + wrusp((unsigned long)frame); + if (get_personality & FDPIC_FUNCPTRS) { + struct fdpic_func_descriptor __user *funcptr = + (struct fdpic_func_descriptor *) ka->sa.sa_handler; + __get_user(regs->pc, &funcptr->text); + __get_user(regs->p3, &funcptr->GOT); + } else + regs->pc = (unsigned long)ka->sa.sa_handler; + regs->rets = (unsigned long)(frame->retcode); + + regs->r0 = frame->sig; + regs->r1 = (unsigned long)(&frame->info); + regs->r2 = (unsigned long)(&frame->uc); + + return 0; + + give_sigsegv: + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); + return -EFAULT; +} + +static inline void +handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) +{ + switch (regs->r0) { + case -ERESTARTNOHAND: + if (!has_handler) + goto do_restart; + regs->r0 = -EINTR; + break; + + case -ERESTARTSYS: + if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { + regs->r0 = -EINTR; + break; + } + /* fallthrough */ + case -ERESTARTNOINTR: + do_restart: + regs->p0 = regs->orig_p0; + regs->r0 = regs->orig_r0; + regs->pc -= 2; + break; + } +} + +/* + * OK, we're invoking a handler + */ +static int +handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, + sigset_t *oldset, struct pt_regs *regs) +{ + int ret; + + /* are we from a system call? to see pt_regs->orig_p0 */ + if (regs->orig_p0 >= 0) + /* If so, check system call restarting.. */ + handle_restart(regs, ka, 1); + + /* set up the stack frame */ + ret = setup_rt_frame(sig, ka, info, oldset, regs); + + if (ret == 0) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked, ¤t->blocked, + &ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(¤t->blocked, sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } + return ret; +} + +/* + * Note that 'init' is a special process: it doesn't get signals it doesn't + * want to handle. Thus you cannot kill init even with a SIGKILL even by + * mistake. + * + * Note that we go through the signals twice: once to check the signals + * that the kernel can handle, and then we build all the user-level signal + * handling stack-frames in one go after that. + */ +asmlinkage void do_signal(struct pt_regs *regs) +{ + siginfo_t info; + int signr; + struct k_sigaction ka; + sigset_t *oldset; + + current->thread.esp0 = (unsigned long)regs; + + if (try_to_freeze()) + goto no_signal; + + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + oldset = ¤t->saved_sigmask; + else + oldset = ¤t->blocked; + + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + if (signr > 0) { + /* Whee! Actually deliver the signal. */ + if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { + /* a signal was successfully delivered; the saved + * sigmask will have been stored in the signal frame, + * and will be restored by sigreturn, so we can simply + * clear the TIF_RESTORE_SIGMASK flag */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + clear_thread_flag(TIF_RESTORE_SIGMASK); + } + + return; + } + +no_signal: + /* Did we come from a system call? */ + if (regs->orig_p0 >= 0) + /* Restart the system call - no handlers present */ + handle_restart(regs, NULL, 0); + + /* if there's no signal to deliver, we just put the saved sigmask + * back */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { + clear_thread_flag(TIF_RESTORE_SIGMASK); + sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); + } +} diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c new file mode 100644 index 000000000000..f436e6743f5a --- /dev/null +++ b/arch/blackfin/kernel/sys_bfin.c @@ -0,0 +1,115 @@ +/* + * File: arch/blackfin/kernel/sys_bfin.c + * Based on: + * Author: + * + * Created: + * Description: This file contains various random system calls that + * have a non-standard calling sequence on the Linux/bfin + * platform. + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way unix traditionally does this, though. + */ +asmlinkage int sys_pipe(unsigned long *fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2 * sizeof(int))) + error = -EFAULT; + } + return error; +} + +/* common code for old and new mmaps */ +static inline long +do_mmap2(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + int error = -EBADF; + struct file *file = NULL; + + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + if (!(flags & MAP_ANONYMOUS)) { + file = fget(fd); + if (!file) + goto out; + } + + down_write(¤t->mm->mmap_sem); + error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + up_write(¤t->mm->mmap_sem); + + if (file) + fput(file); + out: + return error; +} + +asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + return do_mmap2(addr, len, prot, flags, fd, pgoff); +} + +asmlinkage int sys_getpagesize(void) +{ + return PAGE_SIZE; +} + +asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags) +{ + return sram_alloc_with_lsl(size, flags); +} + +asmlinkage int sys_sram_free(const void *addr) +{ + return sram_free_with_lsl(addr); +} + +asmlinkage void *sys_dma_memcpy(void *dest, const void *src, size_t len) +{ + return safe_dma_memcpy(dest, src, len); +} diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c new file mode 100644 index 000000000000..f578176b6d92 --- /dev/null +++ b/arch/blackfin/kernel/time.c @@ -0,0 +1,326 @@ +/* + * File: arch/blackfin/kernel/time.c + * Based on: none - original work + * Author: + * + * Created: + * Description: This file contains the bfin-specific time handling details. + * Most of the stuff is located in the machine specific files. + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +#include + +/* This is an NTP setting */ +#define TICK_SIZE (tick_nsec / 1000) + +static void time_sched_init(irqreturn_t(*timer_routine) + (int, void *)); +static unsigned long gettimeoffset(void); +static inline void do_leds(void); + +#if (defined(CONFIG_BFIN_ALIVE_LED) || defined(CONFIG_BFIN_IDLE_LED)) +void __init init_leds(void) +{ + unsigned int tmp = 0; + +#if defined(CONFIG_BFIN_ALIVE_LED) + /* config pins as output. */ + tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_DPORT(); + SSYNC(); + bfin_write_CONFIG_BFIN_ALIVE_LED_DPORT(tmp | CONFIG_BFIN_ALIVE_LED_PIN); + SSYNC(); + + /* First set led be off */ + tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_PORT(); + SSYNC(); + bfin_write_CONFIG_BFIN_ALIVE_LED_PORT(tmp | CONFIG_BFIN_ALIVE_LED_PIN); /* light off */ + SSYNC(); +#endif + +#if defined(CONFIG_BFIN_IDLE_LED) + /* config pins as output. */ + tmp = bfin_read_CONFIG_BFIN_IDLE_LED_DPORT(); + SSYNC(); + bfin_write_CONFIG_BFIN_IDLE_LED_DPORT(tmp | CONFIG_BFIN_IDLE_LED_PIN); + SSYNC(); + + /* First set led be off */ + tmp = bfin_read_CONFIG_BFIN_IDLE_LED_PORT(); + SSYNC(); + bfin_write_CONFIG_BFIN_IDLE_LED_PORT(tmp | CONFIG_BFIN_IDLE_LED_PIN); /* light off */ + SSYNC(); +#endif +} +#else +void __init init_leds(void) +{ +} +#endif + +#if defined(CONFIG_BFIN_ALIVE_LED) +static inline void do_leds(void) +{ + static unsigned int count = 50; + static int flag = 0; + unsigned short tmp = 0; + + if (--count == 0) { + count = 50; + flag = ~flag; + } + tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_PORT(); + SSYNC(); + + if (flag) + tmp &= ~CONFIG_BFIN_ALIVE_LED_PIN; /* light on */ + else + tmp |= CONFIG_BFIN_ALIVE_LED_PIN; /* light off */ + + bfin_write_CONFIG_BFIN_ALIVE_LED_PORT(tmp); + SSYNC(); + +} +#else +static inline void do_leds(void) +{ +} +#endif + +static struct irqaction bfin_timer_irq = { + .name = "BFIN Timer Tick", + .flags = IRQF_DISABLED +}; + +/* + * The way that the Blackfin core timer works is: + * - CCLK is divided by a programmable 8-bit pre-scaler (TSCALE) + * - Every time TSCALE ticks, a 32bit is counted down (TCOUNT) + * + * If you take the fastest clock (1ns, or 1GHz to make the math work easier) + * 10ms is 10,000,000 clock ticks, which fits easy into a 32-bit counter + * (32 bit counter is 4,294,967,296ns or 4.2 seconds) so, we don't need + * to use TSCALE, and program it to zero (which is pass CCLK through). + * If you feel like using it, try to keep HZ * TIMESCALE to some + * value that divides easy (like power of 2). + */ + +#define TIME_SCALE 1 + +static void +time_sched_init(irqreturn_t(*timer_routine) (int, void *)) +{ + u32 tcount; + + /* power up the timer, but don't enable it just yet */ + bfin_write_TCNTL(1); + CSYNC(); + + /* + * the TSCALE prescaler counter. + */ + bfin_write_TSCALE((TIME_SCALE - 1)); + + tcount = ((get_cclk() / (HZ * TIME_SCALE)) - 1); + bfin_write_TPERIOD(tcount); + bfin_write_TCOUNT(tcount); + + /* now enable the timer */ + CSYNC(); + + bfin_write_TCNTL(7); + + bfin_timer_irq.handler = (irq_handler_t)timer_routine; + /* call setup_irq instead of request_irq because request_irq calls + * kmalloc which has not been initialized yet + */ + setup_irq(IRQ_CORETMR, &bfin_timer_irq); +} + +/* + * Should return useconds since last timer tick + */ +static unsigned long gettimeoffset(void) +{ + unsigned long offset; + unsigned long clocks_per_jiffy; + + clocks_per_jiffy = bfin_read_TPERIOD(); + offset = + (clocks_per_jiffy - + bfin_read_TCOUNT()) / (((clocks_per_jiffy + 1) * HZ) / + USEC_PER_SEC); + + /* Check if we just wrapped the counters and maybe missed a tick */ + if ((bfin_read_ILAT() & (1 << IRQ_CORETMR)) + && (offset < (100000 / HZ / 2))) + offset += (USEC_PER_SEC / HZ); + + return offset; +} + +static inline int set_rtc_mmss(unsigned long nowtime) +{ + return 0; +} + +/* + * timer_interrupt() needs to keep up the real-time clock, + * as well as call the "do_timer()" routine every clocktick + */ +#ifdef CONFIG_CORE_TIMER_IRQ_L1 +irqreturn_t timer_interrupt(int irq, void *dummy)__attribute__((l1_text)); +#endif + +irqreturn_t timer_interrupt(int irq, void *dummy) +{ + /* last time the cmos clock got updated */ + static long last_rtc_update = 0; + + write_seqlock(&xtime_lock); + + do_timer(1); + do_leds(); + +#ifndef CONFIG_SMP + update_process_times(user_mode(get_irq_regs())); +#endif + profile_tick(CPU_PROFILING); + + /* + * If we have an externally synchronized Linux clock, then update + * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be + * called as close as possible to 500 ms before the new second starts. + */ + + if (ntp_synced() && + xtime.tv_sec > last_rtc_update + 660 && + (xtime.tv_nsec / NSEC_PER_USEC) >= + 500000 - ((unsigned)TICK_SIZE) / 2 + && (xtime.tv_nsec / NSEC_PER_USEC) <= + 500000 + ((unsigned)TICK_SIZE) / 2) { + if (set_rtc_mmss(xtime.tv_sec) == 0) + last_rtc_update = xtime.tv_sec; + else + /* Do it again in 60s. */ + last_rtc_update = xtime.tv_sec - 600; + } + write_sequnlock(&xtime_lock); + return IRQ_HANDLED; +} + +void __init time_init(void) +{ + time_t secs_since_1970 = (365 * 37 + 9) * 24 * 60 * 60; /* 1 Jan 2007 */ + +#ifdef CONFIG_RTC_DRV_BFIN + /* [#2663] hack to filter junk RTC values that would cause + * userspace to have to deal with time values greater than + * 2^31 seconds (which uClibc cannot cope with yet) + */ + if ((bfin_read_RTC_STAT() & 0xC0000000) == 0xC0000000) { + printk(KERN_NOTICE "bfin-rtc: invalid date; resetting\n"); + bfin_write_RTC_STAT(0); + } +#endif + + /* Initialize xtime. From now on, xtime is updated with timer interrupts */ + xtime.tv_sec = secs_since_1970; + xtime.tv_nsec = 0; + + wall_to_monotonic.tv_sec = -xtime.tv_sec; + + time_sched_init(timer_interrupt); +} + +#ifndef CONFIG_GENERIC_TIME +void do_gettimeofday(struct timeval *tv) +{ + unsigned long flags; + unsigned long seq; + unsigned long usec, sec; + + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + usec = gettimeoffset(); + sec = xtime.tv_sec; + usec += (xtime.tv_nsec / NSEC_PER_USEC); + } + while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); + + while (usec >= USEC_PER_SEC) { + usec -= USEC_PER_SEC; + sec++; + } + + tv->tv_sec = sec; + tv->tv_usec = usec; +} +EXPORT_SYMBOL(do_gettimeofday); + +int do_settimeofday(struct timespec *tv) +{ + time_t wtm_sec, sec = tv->tv_sec; + long wtm_nsec, nsec = tv->tv_nsec; + + if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) + return -EINVAL; + + write_seqlock_irq(&xtime_lock); + /* + * This is revolting. We need to set the xtime.tv_usec + * correctly. However, the value in this location is + * is value at the last tick. + * Discover what correction gettimeofday + * would have done, and then undo it! + */ + nsec -= (gettimeoffset() * NSEC_PER_USEC); + + wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); + wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); + + set_normalized_timespec(&xtime, sec, nsec); + set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); + + ntp_clear(); + + write_sequnlock_irq(&xtime_lock); + clock_was_set(); + + return 0; +} +EXPORT_SYMBOL(do_settimeofday); +#endif /* !CONFIG_GENERIC_TIME */ + +/* + * Scheduler clock - returns current time in nanosec units. + */ +unsigned long long sched_clock(void) +{ + return (unsigned long long)jiffies *(NSEC_PER_SEC / HZ); +} diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c new file mode 100644 index 000000000000..9556b73de808 --- /dev/null +++ b/arch/blackfin/kernel/traps.c @@ -0,0 +1,649 @@ +/* + * File: arch/blackfin/kernel/traps.c + * Based on: + * Author: Hamish Macdonald + * + * Created: + * Description: uses S/W interrupt 15 for the system calls + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_KGDB +# include +# include +#endif + +/* Initiate the event table handler */ +void __init trap_init(void) +{ + CSYNC(); + bfin_write_EVT3(trap); + CSYNC(); +} + +asmlinkage void trap_c(struct pt_regs *fp); + +int kstack_depth_to_print = 48; + +static int printk_address(unsigned long address) +{ + struct vm_list_struct *vml; + struct task_struct *p; + struct mm_struct *mm; + +#ifdef CONFIG_KALLSYMS + unsigned long offset = 0, symsize; + const char *symname; + char *modname; + char *delim = ":"; + char namebuf[128]; + + /* look up the address and see if we are in kernel space */ + symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); + + if (symname) { + /* yeah! kernel space! */ + if (!modname) + modname = delim = ""; + return printk("<0x%p> { %s%s%s%s + 0x%lx }", + (void*)address, delim, modname, delim, symname, + (unsigned long)offset); + + } +#endif + + /* looks like we're off in user-land, so let's walk all the + * mappings of all our processes and see if we can't be a whee + * bit more specific + */ + write_lock_irq(&tasklist_lock); + for_each_process(p) { + mm = get_task_mm(p); + if (!mm) + continue; + + vml = mm->context.vmlist; + while (vml) { + struct vm_area_struct *vma = vml->vma; + + if (address >= vma->vm_start && address < vma->vm_end) { + char *name = p->comm; + struct file *file = vma->vm_file; + if (file) { + char _tmpbuf[256]; + name = d_path(file->f_dentry, + file->f_vfsmnt, + _tmpbuf, + sizeof(_tmpbuf)); + } + + write_unlock_irq(&tasklist_lock); + return printk("<0x%p> [ %s + 0x%lx ]", + (void*)address, name, + (unsigned long) + ((address - vma->vm_start) + + (vma->vm_pgoff << PAGE_SHIFT))); + } + + vml = vml->next; + } + } + write_unlock_irq(&tasklist_lock); + + /* we were unable to find this address anywhere */ + return printk("[<0x%p>]", (void*)address); +} + +#define trace_buffer_save(x) \ + do { \ + (x) = bfin_read_TBUFCTL(); \ + bfin_write_TBUFCTL((x) & ~TBUFEN); \ + } while (0) +#define trace_buffer_restore(x) \ + do { \ + bfin_write_TBUFCTL((x)); \ + } while (0) + +asmlinkage void trap_c(struct pt_regs *fp) +{ + int j, sig = 0; + siginfo_t info; + unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; + +#ifdef CONFIG_KGDB +# define CHK_DEBUGGER_TRAP() do { CHK_DEBUGGER(trapnr, sig, info.si_code, fp,); } while (0) +# define CHK_DEBUGGER_TRAP_MAYBE() do { if (kgdb_connected) CHK_DEBUGGER_TRAP(); } while (0) +#else +# define CHK_DEBUGGER_TRAP() do { } while (0) +# define CHK_DEBUGGER_TRAP_MAYBE() do { } while (0) +#endif + + trace_buffer_save(j); + + /* trap_c() will be called for exceptions. During exceptions + * processing, the pc value should be set with retx value. + * With this change we can cleanup some code in signal.c- TODO + */ + fp->orig_pc = fp->retx; + /* printk("exception: 0x%x, ipend=%x, reti=%x, retx=%x\n", + trapnr, fp->ipend, fp->pc, fp->retx); */ + + /* send the appropriate signal to the user program */ + switch (trapnr) { + + /* This table works in conjuction with the one in ./mach-common/entry.S + * Some exceptions are handled there (in assembly, in exception space) + * Some are handled here, (in C, in interrupt space) + * Some, like CPLB, are handled in both, where the normal path is + * handled in assembly/exception space, and the error path is handled + * here + */ + + /* 0x00 - Linux Syscall, getting here is an error */ + /* 0x01 - userspace gdb breakpoint, handled here */ + case VEC_EXCPT01: + info.si_code = TRAP_ILLTRAP; + sig = SIGTRAP; + CHK_DEBUGGER_TRAP_MAYBE(); + /* Check if this is a breakpoint in kernel space */ + if (fp->ipend & 0xffc0) + return; + else + break; +#ifdef CONFIG_KGDB + case VEC_EXCPT02 : /* gdb connection */ + info.si_code = TRAP_ILLTRAP; + sig = SIGTRAP; + CHK_DEBUGGER_TRAP(); + return; +#else + /* 0x02 - User Defined, Caught by default */ +#endif + /* 0x03 - Atomic test and set */ + case VEC_EXCPT03: + info.si_code = SEGV_STACKFLOW; + sig = SIGSEGV; + printk(KERN_EMERG EXC_0x03); + CHK_DEBUGGER_TRAP(); + break; + /* 0x04 - spinlock - handled by _ex_spinlock, + getting here is an error */ + /* 0x05 - User Defined, Caught by default */ + /* 0x06 - User Defined, Caught by default */ + /* 0x07 - User Defined, Caught by default */ + /* 0x08 - User Defined, Caught by default */ + /* 0x09 - User Defined, Caught by default */ + /* 0x0A - User Defined, Caught by default */ + /* 0x0B - User Defined, Caught by default */ + /* 0x0C - User Defined, Caught by default */ + /* 0x0D - User Defined, Caught by default */ + /* 0x0E - User Defined, Caught by default */ + /* 0x0F - User Defined, Caught by default */ + /* 0x10 HW Single step, handled here */ + case VEC_STEP: + info.si_code = TRAP_STEP; + sig = SIGTRAP; + CHK_DEBUGGER_TRAP_MAYBE(); + /* Check if this is a single step in kernel space */ + if (fp->ipend & 0xffc0) + return; + else + break; + /* 0x11 - Trace Buffer Full, handled here */ + case VEC_OVFLOW: + info.si_code = TRAP_TRACEFLOW; + sig = SIGTRAP; + printk(KERN_EMERG EXC_0x11); + CHK_DEBUGGER_TRAP(); + break; + /* 0x12 - Reserved, Caught by default */ + /* 0x13 - Reserved, Caught by default */ + /* 0x14 - Reserved, Caught by default */ + /* 0x15 - Reserved, Caught by default */ + /* 0x16 - Reserved, Caught by default */ + /* 0x17 - Reserved, Caught by default */ + /* 0x18 - Reserved, Caught by default */ + /* 0x19 - Reserved, Caught by default */ + /* 0x1A - Reserved, Caught by default */ + /* 0x1B - Reserved, Caught by default */ + /* 0x1C - Reserved, Caught by default */ + /* 0x1D - Reserved, Caught by default */ + /* 0x1E - Reserved, Caught by default */ + /* 0x1F - Reserved, Caught by default */ + /* 0x20 - Reserved, Caught by default */ + /* 0x21 - Undefined Instruction, handled here */ + case VEC_UNDEF_I: + info.si_code = ILL_ILLOPC; + sig = SIGILL; + printk(KERN_EMERG EXC_0x21); + CHK_DEBUGGER_TRAP(); + break; + /* 0x22 - Illegal Instruction Combination, handled here */ + case VEC_ILGAL_I: + info.si_code = ILL_ILLPARAOP; + sig = SIGILL; + printk(KERN_EMERG EXC_0x22); + CHK_DEBUGGER_TRAP(); + break; + /* 0x23 - Data CPLB Protection Violation, + normal case is handled in _cplb_hdr */ + case VEC_CPLB_VL: + info.si_code = ILL_CPLB_VI; + sig = SIGILL; + printk(KERN_EMERG EXC_0x23); + CHK_DEBUGGER_TRAP(); + break; + /* 0x24 - Data access misaligned, handled here */ + case VEC_MISALI_D: + info.si_code = BUS_ADRALN; + sig = SIGBUS; + printk(KERN_EMERG EXC_0x24); + CHK_DEBUGGER_TRAP(); + break; + /* 0x25 - Unrecoverable Event, handled here */ + case VEC_UNCOV: + info.si_code = ILL_ILLEXCPT; + sig = SIGILL; + printk(KERN_EMERG EXC_0x25); + CHK_DEBUGGER_TRAP(); + break; + /* 0x26 - Data CPLB Miss, normal case is handled in _cplb_hdr, + error case is handled here */ + case VEC_CPLB_M: + info.si_code = BUS_ADRALN; + sig = SIGBUS; + printk(KERN_EMERG EXC_0x26); + CHK_DEBUGGER_TRAP(); + break; + /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */ + case VEC_CPLB_MHIT: + info.si_code = ILL_CPLB_MULHIT; +#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO + sig = SIGSEGV; + printk(KERN_EMERG "\n\nNULL pointer access (probably)\n"); +#else + sig = SIGILL; + printk(KERN_EMERG EXC_0x27); +#endif + CHK_DEBUGGER_TRAP(); + break; + /* 0x28 - Emulation Watchpoint, handled here */ + case VEC_WATCH: + info.si_code = TRAP_WATCHPT; + sig = SIGTRAP; + pr_debug(EXC_0x28); + CHK_DEBUGGER_TRAP_MAYBE(); + /* Check if this is a watchpoint in kernel space */ + if (fp->ipend & 0xffc0) + return; + else + break; +#ifdef CONFIG_BF535 + /* 0x29 - Instruction fetch access error (535 only) */ + case VEC_ISTRU_VL: /* ADSP-BF535 only (MH) */ + info.si_code = BUS_OPFETCH; + sig = SIGBUS; + printk(KERN_EMERG "BF535: VEC_ISTRU_VL\n"); + CHK_DEBUGGER_TRAP(); + break; +#else + /* 0x29 - Reserved, Caught by default */ +#endif + /* 0x2A - Instruction fetch misaligned, handled here */ + case VEC_MISALI_I: + info.si_code = BUS_ADRALN; + sig = SIGBUS; + printk(KERN_EMERG EXC_0x2A); + CHK_DEBUGGER_TRAP(); + break; + /* 0x2B - Instruction CPLB protection Violation, + handled in _cplb_hdr */ + case VEC_CPLB_I_VL: + info.si_code = ILL_CPLB_VI; + sig = SIGILL; + printk(KERN_EMERG EXC_0x2B); + CHK_DEBUGGER_TRAP(); + break; + /* 0x2C - Instruction CPLB miss, handled in _cplb_hdr */ + case VEC_CPLB_I_M: + info.si_code = ILL_CPLB_MISS; + sig = SIGBUS; + printk(KERN_EMERG EXC_0x2C); + CHK_DEBUGGER_TRAP(); + break; + /* 0x2D - Instruction CPLB Multiple Hits, handled here */ + case VEC_CPLB_I_MHIT: + info.si_code = ILL_CPLB_MULHIT; +#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO + sig = SIGSEGV; + printk(KERN_EMERG "\n\nJump to address 0 - 0x0fff\n"); +#else + sig = SIGILL; + printk(KERN_EMERG EXC_0x2D); +#endif + CHK_DEBUGGER_TRAP(); + break; + /* 0x2E - Illegal use of Supervisor Resource, handled here */ + case VEC_ILL_RES: + info.si_code = ILL_PRVOPC; + sig = SIGILL; + printk(KERN_EMERG EXC_0x2E); + CHK_DEBUGGER_TRAP(); + break; + /* 0x2F - Reserved, Caught by default */ + /* 0x30 - Reserved, Caught by default */ + /* 0x31 - Reserved, Caught by default */ + /* 0x32 - Reserved, Caught by default */ + /* 0x33 - Reserved, Caught by default */ + /* 0x34 - Reserved, Caught by default */ + /* 0x35 - Reserved, Caught by default */ + /* 0x36 - Reserved, Caught by default */ + /* 0x37 - Reserved, Caught by default */ + /* 0x38 - Reserved, Caught by default */ + /* 0x39 - Reserved, Caught by default */ + /* 0x3A - Reserved, Caught by default */ + /* 0x3B - Reserved, Caught by default */ + /* 0x3C - Reserved, Caught by default */ + /* 0x3D - Reserved, Caught by default */ + /* 0x3E - Reserved, Caught by default */ + /* 0x3F - Reserved, Caught by default */ + default: + info.si_code = TRAP_ILLTRAP; + sig = SIGTRAP; + printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n", + (fp->seqstat & SEQSTAT_EXCAUSE)); + CHK_DEBUGGER_TRAP(); + break; + } + + info.si_signo = sig; + info.si_errno = 0; + info.si_addr = (void *)fp->pc; + force_sig_info(sig, &info, current); + if (sig != 0 && sig != SIGTRAP) { + unsigned long stack; + dump_bfin_regs(fp, (void *)fp->retx); + dump_bfin_trace_buffer(); + show_stack(current, &stack); + if (current->mm == NULL) + panic("Kernel exception"); + } + + /* if the address that we are about to return to is not valid, set it + * to a valid address, if we have a current application or panic + */ + if (!(fp->pc <= physical_mem_end +#if L1_CODE_LENGTH != 0 + || (fp->pc >= L1_CODE_START && + fp->pc <= (L1_CODE_START + L1_CODE_LENGTH)) +#endif + )) { + if (current->mm) { + fp->pc = current->mm->start_code; + } else { + printk(KERN_EMERG "I can't return to memory that doesn't exist - bad things happen\n"); + panic("Help - I've fallen and can't get up\n"); + } + } + + trace_buffer_restore(j); + return; +} + +/* Typical exception handling routines */ + +void dump_bfin_trace_buffer(void) +{ + int tflags; + trace_buffer_save(tflags); + + if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { + int i; + printk(KERN_EMERG "Hardware Trace:\n"); + for (i = 0; bfin_read_TBUFSTAT() & TBUFCNT; i++) { + printk(KERN_EMERG "%2i Target : ", i); + printk_address((unsigned long)bfin_read_TBUF()); + printk("\n" KERN_EMERG " Source : "); + printk_address((unsigned long)bfin_read_TBUF()); + printk("\n"); + } + } + + trace_buffer_restore(tflags); +} +EXPORT_SYMBOL(dump_bfin_trace_buffer); + +static void show_trace(struct task_struct *tsk, unsigned long *sp) +{ + unsigned long addr; + + printk("\nCall Trace:"); +#ifdef CONFIG_KALLSYMS + printk("\n"); +#endif + + while (!kstack_end(sp)) { + addr = *sp++; + /* + * If the address is either in the text segment of the + * kernel, or in the region which contains vmalloc'ed + * memory, it *may* be the address of a calling + * routine; if so, print it so that someone tracing + * down the cause of the crash will be able to figure + * out the call path that was taken. + */ + if (kernel_text_address(addr)) + print_ip_sym(addr); + } + + printk("\n"); +} + +void show_stack(struct task_struct *task, unsigned long *stack) +{ + unsigned long *endstack, addr; + int i; + + /* Cannot call dump_bfin_trace_buffer() here as show_stack() is + * called externally in some places in the kernel. + */ + + if (!stack) { + if (task) + stack = (unsigned long *)task->thread.ksp; + else + stack = (unsigned long *)&stack; + } + + addr = (unsigned long)stack; + endstack = (unsigned long *)PAGE_ALIGN(addr); + + printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack); + for (i = 0; i < kstack_depth_to_print; i++) { + if (stack + 1 > endstack) + break; + if (i % 8 == 0) + printk("\n" KERN_EMERG " "); + printk(" %08lx", *stack++); + } + + show_trace(task, stack); +} + +void dump_stack(void) +{ + unsigned long stack; + int tflags; + trace_buffer_save(tflags); + dump_bfin_trace_buffer(); + show_stack(current, &stack); + trace_buffer_restore(tflags); +} + +EXPORT_SYMBOL(dump_stack); + +void dump_bfin_regs(struct pt_regs *fp, void *retaddr) +{ + if (current->pid) { + printk("\nCURRENT PROCESS:\n\n"); + printk("COMM=%s PID=%d\n", current->comm, current->pid); + } else { + printk + ("\nNo Valid pid - Either things are really messed up, or you are in the kernel\n"); + } + + if (current->mm) { + printk("TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" + "BSS = 0x%p-0x%p USER-STACK = 0x%p\n\n", + (void*)current->mm->start_code, + (void*)current->mm->end_code, + (void*)current->mm->start_data, + (void*)current->mm->end_data, + (void*)current->mm->end_data, + (void*)current->mm->brk, + (void*)current->mm->start_stack); + } + + printk("return address: 0x%p; contents of [PC-16...PC+8]:\n", retaddr); + if (retaddr != 0 && retaddr <= (void*)physical_mem_end +#if L1_CODE_LENGTH != 0 + /* FIXME: Copy the code out of L1 Instruction SRAM through dma + memcpy. */ + && !(retaddr >= (void*)L1_CODE_START + && retaddr < (void*)(L1_CODE_START + L1_CODE_LENGTH)) +#endif + ) { + int i = 0; + unsigned short x = 0; + for (i = -16; i < 8; i++) { + if (get_user(x, (unsigned short *)retaddr + i)) + break; +#ifndef CONFIG_DEBUG_HWERR + /* If one of the last few instructions was a STI + * it is likily that the error occured awhile ago + * and we just noticed + */ + if (x >= 0x0040 && x <= 0x0047 && i <= 0) + panic("\n\nWARNING : You should reconfigure the kernel to turn on\n" + " 'Hardware error interrupt debugging'\n" + " The rest of this error is meanless\n"); +#endif + + if (i == -8) + printk("\n"); + if (i == 0) + printk("X\n"); + printk("%04x ", x); + } + } else + printk("Cannot look at the [PC] for it is in unreadable L1 SRAM - sorry\n"); + + printk("\n\n"); + + printk("RETE: %08lx RETN: %08lx RETX: %08lx RETS: %08lx\n", + fp->rete, fp->retn, fp->retx, fp->rets); + printk("IPEND: %04lx SYSCFG: %04lx\n", fp->ipend, fp->syscfg); + printk("SEQSTAT: %08lx SP: %08lx\n", (long)fp->seqstat, (long)fp); + printk("R0: %08lx R1: %08lx R2: %08lx R3: %08lx\n", + fp->r0, fp->r1, fp->r2, fp->r3); + printk("R4: %08lx R5: %08lx R6: %08lx R7: %08lx\n", + fp->r4, fp->r5, fp->r6, fp->r7); + printk("P0: %08lx P1: %08lx P2: %08lx P3: %08lx\n", + fp->p0, fp->p1, fp->p2, fp->p3); + printk("P4: %08lx P5: %08lx FP: %08lx\n", fp->p4, fp->p5, fp->fp); + printk("A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", + fp->a0w, fp->a0x, fp->a1w, fp->a1x); + + printk("LB0: %08lx LT0: %08lx LC0: %08lx\n", fp->lb0, fp->lt0, + fp->lc0); + printk("LB1: %08lx LT1: %08lx LC1: %08lx\n", fp->lb1, fp->lt1, + fp->lc1); + printk("B0: %08lx L0: %08lx M0: %08lx I0: %08lx\n", fp->b0, fp->l0, + fp->m0, fp->i0); + printk("B1: %08lx L1: %08lx M1: %08lx I1: %08lx\n", fp->b1, fp->l1, + fp->m1, fp->i1); + printk("B2: %08lx L2: %08lx M2: %08lx I2: %08lx\n", fp->b2, fp->l2, + fp->m2, fp->i2); + printk("B3: %08lx L3: %08lx M3: %08lx I3: %08lx\n", fp->b3, fp->l3, + fp->m3, fp->i3); + + printk("\nUSP: %08lx ASTAT: %08lx\n", rdusp(), fp->astat); + if ((long)fp->seqstat & SEQSTAT_EXCAUSE) { + printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void*)bfin_read_DCPLB_FAULT_ADDR()); + printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void*)bfin_read_ICPLB_FAULT_ADDR()); + } + + printk("\n\n"); +} + +#ifdef CONFIG_SYS_BFIN_SPINLOCK_L1 +asmlinkage int sys_bfin_spinlock(int *spinlock)__attribute__((l1_text)); +#endif + +asmlinkage int sys_bfin_spinlock(int *spinlock) +{ + int ret = 0; + int tmp = 0; + + local_irq_disable(); + ret = get_user(tmp, spinlock); + if (ret == 0) { + if (tmp) + ret = 1; + tmp = 1; + put_user(tmp, spinlock); + } + local_irq_enable(); + return ret; +} + +void panic_cplb_error(int cplb_panic, struct pt_regs *fp) +{ + switch (cplb_panic) { + case CPLB_NO_UNLOCKED: + printk(KERN_EMERG "All CPLBs are locked\n"); + break; + case CPLB_PROT_VIOL: + return; + case CPLB_NO_ADDR_MATCH: + return; + case CPLB_UNKNOWN_ERR: + printk(KERN_EMERG "Unknown CPLB Exception\n"); + break; + } + + printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void*)bfin_read_DCPLB_FAULT_ADDR()); + printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void*)bfin_read_ICPLB_FAULT_ADDR()); + dump_bfin_regs(fp, (void *)fp->retx); + dump_stack(); + panic("Unrecoverable event\n"); +} diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S new file mode 100644 index 000000000000..6ae9ebbd8e58 --- /dev/null +++ b/arch/blackfin/kernel/vmlinux.lds.S @@ -0,0 +1,228 @@ +/* + * File: arch/blackfin/kernel/vmlinux.lds.S + * Based on: none - original work + * Author: + * + * Created: Tue Sep 21 2004 + * Description: Master linker script for blackfin architecture + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define VMLINUX_SYMBOL(_sym_) _##_sym_ + +#include +#include + + +OUTPUT_FORMAT("elf32-bfin") +ENTRY(__start) +_jiffies = _jiffies_64; + +MEMORY +{ + ram : ORIGIN = CONFIG_BOOT_LOAD, LENGTH = (CONFIG_MEM_SIZE * 1024 * 1024) - (CONFIG_BOOT_LOAD) + l1_data_a : ORIGIN = L1_DATA_A_START, LENGTH = L1_DATA_A_LENGTH + l1_data_b : ORIGIN = L1_DATA_B_START, LENGTH = L1_DATA_B_LENGTH + l1_code : ORIGIN = L1_CODE_START, LENGTH = L1_CODE_LENGTH + l1_scratch : ORIGIN = L1_SCRATCH_START, LENGTH = L1_SCRATCH_LENGTH +} + +SECTIONS +{ + . = CONFIG_BOOT_LOAD; + + .text : + { + _text = .; + __stext = .; + *(.text) + SCHED_TEXT + *(.text.lock) + . = ALIGN(16); + ___start___ex_table = .; + *(__ex_table) + ___stop___ex_table = .; + + *($code) + *(.rodata) + *(.rodata.*) + *(__vermagic) /* Kernel version magic */ + *(.rodata1) + *(.fixup) + *(.spinlock.text) + + /* Kernel symbol table: Normal symbols */ + . = ALIGN(4); + ___start___ksymtab = .; + *(__ksymtab) + ___stop___ksymtab = .; + + /* Kernel symbol table: GPL-only symbols */ + ___start___ksymtab_gpl = .; + *(__ksymtab_gpl) + ___stop___ksymtab_gpl = .; + + /* Kernel symbol table: Normal unused symbols */ \ + ___start___ksymtab_unused = .; + *(__ksymtab_unused) + ___stop___ksymtab_unused = .; + + /* Kernel symbol table: GPL-only unused symbols */ + ___start___ksymtab_unused_gpl = .; + *(__ksymtab_unused_gpl) + ___stop___ksymtab_unused_gpl = .; + + + /* Kernel symbol table: GPL-future symbols */ + ___start___ksymtab_gpl_future = .; + *(__ksymtab_gpl_future) + ___stop___ksymtab_gpl_future = .; + + /* Kernel symbol table: Normal symbols */ + ___start___kcrctab = .; + *(__kcrctab) + ___stop___kcrctab = .; + + /* Kernel symbol table: GPL-only symbols */ + ___start___kcrctab_gpl = .; + *(__kcrctab_gpl) + ___stop___kcrctab_gpl = .; + + /* Kernel symbol table: GPL-future symbols */ + ___start___kcrctab_gpl_future = .; + *(__kcrctab_gpl_future) + ___stop___kcrctab_gpl_future = .; + + /* Kernel symbol table: strings */ + *(__ksymtab_strings) + + . = ALIGN(4); + __etext = .; + } > ram + + .init : + { + . = ALIGN(4096); + ___init_begin = .; + __sinittext = .; + *(.init.text) + __einittext = .; + *(.init.data) + . = ALIGN(16); + ___setup_start = .; + *(.init.setup) + ___setup_end = .; + ___start___param = .; + *(__param) + ___stop___param = .; + ___initcall_start = .; + INITCALLS + ___initcall_end = .; + ___con_initcall_start = .; + *(.con_initcall.init) + ___con_initcall_end = .; + ___security_initcall_start = .; + *(.security_initcall.init) + ___security_initcall_end = .; + . = ALIGN(4); + ___initramfs_start = .; + *(.init.ramfs) + ___initramfs_end = .; + . = ALIGN(4); + ___init_end = .; + } > ram + + __l1_lma_start = .; + + .text_l1 : + { + . = ALIGN(4); + __stext_l1 = .; + *(.l1.text) + + . = ALIGN(4); + __etext_l1 = .; + } > l1_code AT > ram + + .data_l1 : + { + . = ALIGN(4); + __sdata_l1 = .; + *(.l1.data) + __edata_l1 = .; + + . = ALIGN(4); + __sbss_l1 = .; + *(.l1.bss) + + . = ALIGN(32); + *(.data_l1.cacheline_aligned) + + . = ALIGN(4); + __ebss_l1 = .; + } > l1_data_a AT > ram + .data_b_l1 : + { + . = ALIGN(4); + __sdata_b_l1 = .; + *(.l1.data.B) + __edata_b_l1 = .; + + . = ALIGN(4); + __sbss_b_l1 = .; + *(.l1.bss.B) + + . = ALIGN(4); + __ebss_b_l1 = .; + } > l1_data_b AT > ram + + .data : + { + __sdata = .; + . = ALIGN(0x2000); + *(.data.init_task) + *(.data) + + . = ALIGN(32); + *(.data.cacheline_aligned) + + . = ALIGN(0x2000); + __edata = .; + } > ram + + /DISCARD/ : { /* Exit code and data*/ + *(.exit.text) + *(.exit.data) + *(.exitcall.exit) + } > ram + + .bss : + { + . = ALIGN(4); + ___bss_start = .; + *(.bss) + *(COMMON) + . = ALIGN(4); + ___bss_stop = .; + __end = . ; + } > ram +} diff --git a/arch/blackfin/lib/Makefile b/arch/blackfin/lib/Makefile new file mode 100644 index 000000000000..635288fc5f54 --- /dev/null +++ b/arch/blackfin/lib/Makefile @@ -0,0 +1,11 @@ +# +# arch/blackfin/lib/Makefile +# + +lib-y := \ + ashldi3.o ashrdi3.o lshrdi3.o \ + muldi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \ + checksum.o memcpy.o memset.o memcmp.o memchr.o memmove.o \ + strcmp.o strcpy.o strncmp.o strncpy.o \ + umulsi3_highpart.o smulsi3_highpart.o \ + ins.o outs.o diff --git a/arch/blackfin/lib/ashldi3.c b/arch/blackfin/lib/ashldi3.c new file mode 100644 index 000000000000..a8c279e9b192 --- /dev/null +++ b/arch/blackfin/lib/ashldi3.c @@ -0,0 +1,58 @@ +/* + * File: arch/blackfin/lib/ashldi3.c + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "gcclib.h" + +#ifdef CONFIG_ARITHMETIC_OPS_L1 +DItype __ashldi3(DItype u, word_type b)__attribute__((l1_text)); +#endif + +DItype __ashldi3(DItype u, word_type b) +{ + DIunion w; + word_type bm; + DIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof(SItype) * BITS_PER_UNIT) - b; + if (bm <= 0) { + w.s.low = 0; + w.s.high = (USItype) uu.s.low << -bm; + } else { + USItype carries = (USItype) uu.s.low >> bm; + w.s.low = (USItype) uu.s.low << b; + w.s.high = ((USItype) uu.s.high << b) | carries; + } + + return w.ll; +} diff --git a/arch/blackfin/lib/ashrdi3.c b/arch/blackfin/lib/ashrdi3.c new file mode 100644 index 000000000000..a0d3419329ca --- /dev/null +++ b/arch/blackfin/lib/ashrdi3.c @@ -0,0 +1,59 @@ +/* + * File: arch/blackfin/lib/ashrdi3.c + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "gcclib.h" + +#ifdef CONFIG_ARITHMETIC_OPS_L1 +DItype __ashrdi3(DItype u, word_type b)__attribute__((l1_text)); +#endif + +DItype __ashrdi3(DItype u, word_type b) +{ + DIunion w; + word_type bm; + DIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof(SItype) * BITS_PER_UNIT) - b; + if (bm <= 0) { + /* w.s.high = 1..1 or 0..0 */ + w.s.high = uu.s.high >> (sizeof(SItype) * BITS_PER_UNIT - 1); + w.s.low = uu.s.high >> -bm; + } else { + USItype carries = (USItype) uu.s.high << bm; + w.s.high = uu.s.high >> b; + w.s.low = ((USItype) uu.s.low >> b) | carries; + } + + return w.ll; +} diff --git a/arch/blackfin/lib/checksum.c b/arch/blackfin/lib/checksum.c new file mode 100644 index 000000000000..42768e0c80ca --- /dev/null +++ b/arch/blackfin/lib/checksum.c @@ -0,0 +1,140 @@ +/* + * File: arch/blackfin/lib/checksum.c + * Based on: none - original work + * Author: + * + * Created: + * Description: An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#ifdef CONFIG_IP_CHECKSUM_L1 +static unsigned short do_csum(const unsigned char *buff, int len)__attribute__((l1_text)); +#endif + +static unsigned short do_csum(const unsigned char *buff, int len) +{ + register unsigned long sum = 0; + int swappem = 0; + + if (1 & (unsigned long)buff) { + sum = *buff << 8; + buff++; + len--; + ++swappem; + } + + while (len > 1) { + sum += *(unsigned short *)buff; + buff += 2; + len -= 2; + } + + if (len > 0) + sum += *buff; + + /* Fold 32-bit sum to 16 bits */ + while (sum >> 16) + sum = (sum & 0xffff) + (sum >> 16); + + if (swappem) + sum = ((sum & 0xff00) >> 8) + ((sum & 0x00ff) << 8); + + return sum; + +} + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + */ +unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) +{ + return ~do_csum(iph, ihl * 4); +} + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum) +{ + /* + * Just in case we get nasty checksum data... + * Like 0xffff6ec3 in the case of our IPv6 multicast header. + * We fold to begin with, as well as at the end. + */ + sum = (sum & 0xffff) + (sum >> 16); + + sum += do_csum(buff, len); + + sum = (sum & 0xffff) + (sum >> 16); + + return sum; +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ +unsigned short ip_compute_csum(const unsigned char *buff, int len) +{ + return ~do_csum(buff, len); +} + +/* + * copy from fs while checksumming, otherwise like csum_partial + */ + +unsigned int +csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, + int len, int sum, int *csum_err) +{ + if (csum_err) + *csum_err = 0; + memcpy(dst, src, len); + return csum_partial(dst, len, sum); +} + +/* + * copy from ds while checksumming, otherwise like csum_partial + */ + +unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, + int len, int sum) +{ + memcpy(dst, src, len); + return csum_partial(dst, len, sum); +} diff --git a/arch/blackfin/lib/divsi3.S b/arch/blackfin/lib/divsi3.S new file mode 100644 index 000000000000..3e29861852b2 --- /dev/null +++ b/arch/blackfin/lib/divsi3.S @@ -0,0 +1,216 @@ +/* + * File: arch/blackfin/lib/divsi3.S + * Based on: + * Author: + * + * Created: + * Description: 16 / 32 bit signed division. + * Special cases : + * 1) If(numerator == 0) + * return 0 + * 2) If(denominator ==0) + * return positive max = 0x7fffffff + * 3) If(numerator == denominator) + * return 1 + * 4) If(denominator ==1) + * return numerator + * 5) If(denominator == -1) + * return -numerator + * + * Operand : R0 - Numerator (i) + * R1 - Denominator (i) + * R0 - Quotient (o) + * Registers Used : R2-R7,P0-P2 + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +.global ___divsi3; + +#ifdef CONFIG_ARITHMETIC_OPS_L1 +.section .l1.text +#else +.text +#endif + +.align 2; +___divsi3 : + + + R3 = R0 ^ R1; + R0 = ABS R0; + + CC = V; + + r3 = rot r3 by -1; + r1 = abs r1; /* now both positive, r3.30 means "negate result", + ** r3.31 means overflow, add one to result + */ + cc = r0 < r1; + if cc jump .Lret_zero; + r2 = r1 >> 15; + cc = r2; + if cc jump .Lidents; + r2 = r1 << 16; + cc = r2 <= r0; + if cc jump .Lidents; + + DIVS(R0, R1); + DIVQ(R0, R1); + DIVQ(R0, R1); + DIVQ(R0, R1); + DIVQ(R0, R1); + DIVQ(R0, R1); + DIVQ(R0, R1); + DIVQ(R0, R1); + DIVQ(R0, R1); + DIVQ(R0, R1); + DIVQ(R0, R1); + DIVQ(R0, R1); + DIVQ(R0, R1); + DIVQ(R0, R1); + DIVQ(R0, R1); + DIVQ(R0, R1); + DIVQ(R0, R1); + + R0 = R0.L (Z); + r1 = r3 >> 31; /* add overflow issue back in */ + r0 = r0 + r1; + r1 = -r0; + cc = bittst(r3, 30); + if cc r0 = r1; + RTS; + +/* Can't use the primitives. Test common identities. +** If the identity is true, return the value in R2. +*/ + +.Lidents: + CC = R1 == 0; /* check for divide by zero */ + IF CC JUMP .Lident_return; + + CC = R0 == 0; /* check for division of zero */ + IF CC JUMP .Lzero_return; + + CC = R0 == R1; /* check for identical operands */ + IF CC JUMP .Lident_return; + + CC = R1 == 1; /* check for divide by 1 */ + IF CC JUMP .Lident_return; + + R2.L = ONES R1; + R2 = R2.L (Z); + CC = R2 == 1; + IF CC JUMP .Lpower_of_two; + + /* Identities haven't helped either. + ** Perform the full division process. + */ + + P1 = 31; /* Set loop counter */ + + [--SP] = (R7:5); /* Push registers R5-R7 */ + R2 = -R1; + [--SP] = R2; + R2 = R0 << 1; /* R2 lsw of dividend */ + R6 = R0 ^ R1; /* Get sign */ + R5 = R6 >> 31; /* Shift sign to LSB */ + + R0 = 0 ; /* Clear msw partial remainder */ + R2 = R2 | R5; /* Shift quotient bit */ + R6 = R0 ^ R1; /* Get new quotient bit */ + + LSETUP(.Llst,.Llend) LC0 = P1; /* Setup loop */ +.Llst: R7 = R2 >> 31; /* record copy of carry from R2 */ + R2 = R2 << 1; /* Shift 64 bit dividend up by 1 bit */ + R0 = R0 << 1 || R5 = [SP]; + R0 = R0 | R7; /* and add carry */ + CC = R6 < 0; /* Check quotient(AQ) */ + /* we might be subtracting divisor (AQ==0) */ + IF CC R5 = R1; /* or we might be adding divisor (AQ==1)*/ + R0 = R0 + R5; /* do add or subtract, as indicated by AQ */ + R6 = R0 ^ R1; /* Generate next quotient bit */ + R5 = R6 >> 31; + /* Assume AQ==1, shift in zero */ + BITTGL(R5,0); /* tweak AQ to be what we want to shift in */ +.Llend: R2 = R2 + R5; /* and then set shifted-in value to + ** tweaked AQ. + */ + r1 = r3 >> 31; + r2 = r2 + r1; + cc = bittst(r3,30); + r0 = -r2; + if !cc r0 = r2; + SP += 4; + (R7:5)= [SP++]; /* Pop registers R6-R7 */ + RTS; + +.Lident_return: + CC = R1 == 0; /* check for divide by zero => 0x7fffffff */ + R2 = -1 (X); + R2 >>= 1; + IF CC JUMP .Ltrue_ident_return; + + CC = R0 == R1; /* check for identical operands => 1 */ + R2 = 1 (Z); + IF CC JUMP .Ltrue_ident_return; + + R2 = R0; /* assume divide by 1 => numerator */ + /*FALLTHRU*/ + +.Ltrue_ident_return: + R0 = R2; /* Return an identity value */ + R2 = -R2; + CC = bittst(R3,30); + IF CC R0 = R2; +.Lzero_return: + RTS; /* ...including zero */ + +.Lpower_of_two: + /* Y has a single bit set, which means it's a power of two. + ** That means we can perform the division just by shifting + ** X to the right the appropriate number of bits + */ + + /* signbits returns the number of sign bits, minus one. + ** 1=>30, 2=>29, ..., 0x40000000=>0. Which means we need + ** to shift right n-signbits spaces. It also means 0x80000000 + ** is a special case, because that *also* gives a signbits of 0 + */ + + R2 = R0 >> 31; + CC = R1 < 0; + IF CC JUMP .Ltrue_ident_return; + + R1.l = SIGNBITS R1; + R1 = R1.L (Z); + R1 += -30; + R0 = LSHIFT R0 by R1.L; + r1 = r3 >> 31; + r0 = r0 + r1; + R2 = -R0; // negate result if necessary + CC = bittst(R3,30); + IF CC R0 = R2; + RTS; + +.Lret_zero: + R0 = 0; + RTS; diff --git a/arch/blackfin/lib/gcclib.h b/arch/blackfin/lib/gcclib.h new file mode 100644 index 000000000000..9ccd39a135ee --- /dev/null +++ b/arch/blackfin/lib/gcclib.h @@ -0,0 +1,47 @@ +/* + * File: arch/blackfin/lib/gcclib.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define BITS_PER_UNIT 8 +#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT) + +typedef unsigned int UQItype __attribute__ ((mode(QI))); +typedef int SItype __attribute__ ((mode(SI))); +typedef unsigned int USItype __attribute__ ((mode(SI))); +typedef int DItype __attribute__ ((mode(DI))); +typedef int word_type __attribute__ ((mode(__word__))); +typedef unsigned int UDItype __attribute__ ((mode(DI))); + +struct DIstruct { + SItype low, high; +}; + +typedef union { + struct DIstruct s; + DItype ll; +} DIunion; diff --git a/arch/blackfin/lib/ins.S b/arch/blackfin/lib/ins.S new file mode 100644 index 000000000000..730d2b427538 --- /dev/null +++ b/arch/blackfin/lib/ins.S @@ -0,0 +1,69 @@ +/* + * File: arch/blackfin/lib/ins.S + * Based on: + * Author: Bas Vermeulen + * + * Created: Tue Mar 22 15:27:24 CEST 2005 + * Description: Implementation of ins{bwl} for BlackFin processors using zero overhead loops. + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * Copyright (C) 2005 Bas Vermeulen, BuyWays BV + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +.align 2 + +ENTRY(_insl) + P0 = R0; /* P0 = port */ + cli R3; + P1 = R1; /* P1 = address */ + P2 = R2; /* P2 = count */ + SSYNC; + LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2; +.Llong_loop_s: R0 = [P0]; +.Llong_loop_e: [P1++] = R0; + sti R3; + RTS; + +ENTRY(_insw) + P0 = R0; /* P0 = port */ + cli R3; + P1 = R1; /* P1 = address */ + P2 = R2; /* P2 = count */ + SSYNC; + LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2; +.Lword_loop_s: R0 = W[P0]; +.Lword_loop_e: W[P1++] = R0; + sti R3; + RTS; + +ENTRY(_insb) + P0 = R0; /* P0 = port */ + cli R3; + P1 = R1; /* P1 = address */ + P2 = R2; /* P2 = count */ + SSYNC; + LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2; +.Lbyte_loop_s: R0 = B[P0]; +.Lbyte_loop_e: B[P1++] = R0; + sti R3; + RTS; diff --git a/arch/blackfin/lib/lshrdi3.c b/arch/blackfin/lib/lshrdi3.c new file mode 100644 index 000000000000..84b9c5592220 --- /dev/null +++ b/arch/blackfin/lib/lshrdi3.c @@ -0,0 +1,72 @@ +/* + * File: arch/blackfin/lib/lshrdi3.c + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define BITS_PER_UNIT 8 + +typedef int SItype __attribute__ ((mode(SI))); +typedef unsigned int USItype __attribute__ ((mode(SI))); +typedef int DItype __attribute__ ((mode(DI))); +typedef int word_type __attribute__ ((mode(__word__))); + +struct DIstruct { + SItype high, low; +}; + +typedef union { + struct DIstruct s; + DItype ll; +} DIunion; + +#ifdef CONFIG_ARITHMETIC_OPS_L1 +DItype __lshrdi3(DItype u, word_type b)__attribute__((l1_text)); +#endif + +DItype __lshrdi3(DItype u, word_type b) +{ + DIunion w; + word_type bm; + DIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof(SItype) * BITS_PER_UNIT) - b; + if (bm <= 0) { + w.s.high = 0; + w.s.low = (USItype) uu.s.high >> -bm; + } else { + USItype carries = (USItype) uu.s.high << bm; + w.s.high = (USItype) uu.s.high >> b; + w.s.low = ((USItype) uu.s.low >> b) | carries; + } + + return w.ll; +} diff --git a/arch/blackfin/lib/memchr.S b/arch/blackfin/lib/memchr.S new file mode 100644 index 000000000000..498122250d07 --- /dev/null +++ b/arch/blackfin/lib/memchr.S @@ -0,0 +1,70 @@ +/* + * File: arch/blackfin/lib/memchr.S + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* void *memchr(const void *s, int c, size_t n); + * R0 = address (s) + * R1 = sought byte (c) + * R2 = count (n) + * + * Returns pointer to located character. + */ + +.text + +.align 2 + +ENTRY(_memchr) + P0 = R0; /* P0 = address */ + P2 = R2; /* P2 = count */ + R1 = R1.B(Z); + CC = R2 == 0; + IF CC JUMP .Lfailed; + +.Lbytes: + LSETUP (.Lbyte_loop_s, .Lbyte_loop_e) LC0=P2; + +.Lbyte_loop_s: + R3 = B[P0++](Z); + CC = R3 == R1; + IF CC JUMP .Lfound; +.Lbyte_loop_e: + NOP; + +.Lfailed: + R0=0; + RTS; + +.Lfound: + R0 = P0; + R0 += -1; + RTS; + +.size _memchr,.-_memchr diff --git a/arch/blackfin/lib/memcmp.S b/arch/blackfin/lib/memcmp.S new file mode 100644 index 000000000000..5b9502368fc6 --- /dev/null +++ b/arch/blackfin/lib/memcmp.S @@ -0,0 +1,110 @@ +/* + * File: arch/blackfin/lib/memcmp.S + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* int memcmp(const void *s1, const void *s2, size_t n); + * R0 = First Address (s1) + * R1 = Second Address (s2) + * R2 = count (n) + * + * Favours word aligned data. + */ + +.text + +.align 2 + +ENTRY(_memcmp) + I1 = P3; + P0 = R0; /* P0 = s1 address */ + P3 = R1; /* P3 = s2 Address */ + P2 = R2 ; /* P2 = count */ + CC = R2 <= 7(IU); + IF CC JUMP .Ltoo_small; + I0 = R1; /* s2 */ + R1 = R1 | R0; /* OR addresses together */ + R1 <<= 30; /* check bottom two bits */ + CC = AZ; /* AZ set if zero. */ + IF !CC JUMP .Lbytes ; /* Jump if addrs not aligned. */ + + P1 = P2 >> 2; /* count = n/4 */ + R3 = 3; + R2 = R2 & R3; /* remainder */ + P2 = R2; /* set remainder */ + + LSETUP (.Lquad_loop_s, .Lquad_loop_e) LC0=P1; +.Lquad_loop_s: + MNOP || R0 = [P0++] || R1 = [I0++]; + CC = R0 == R1; + IF !CC JUMP .Lquad_different; +.Lquad_loop_e: + NOP; + + P3 = I0; /* s2 */ +.Ltoo_small: + CC = P2 == 0; /* Check zero count*/ + IF CC JUMP .Lfinished; /* very unlikely*/ + +.Lbytes: + LSETUP (.Lbyte_loop_s, .Lbyte_loop_e) LC0=P2; +.Lbyte_loop_s: + R1 = B[P3++](Z); /* *s2 */ + R0 = B[P0++](Z); /* *s1 */ + CC = R0 == R1; + IF !CC JUMP .Ldifferent; +.Lbyte_loop_e: + NOP; + +.Ldifferent: + R0 = R0 - R1; + P3 = I1; + RTS; + +.Lquad_different: + /* We've read two quads which don't match. + * Can't just compare them, because we're + * a little-endian machine, so the MSBs of + * the regs occur at later addresses in the + * string. + * Arrange to re-read those two quads again, + * byte-by-byte. + */ + P0 += -4; /* back up to the start of the */ + P3 = I0; /* quads, and increase the*/ + P2 += 4; /* remainder count*/ + P3 += -4; + JUMP .Lbytes; + +.Lfinished: + R0 = 0; + P3 = I1; + RTS; + +.size _memcmp,.-_memcmp diff --git a/arch/blackfin/lib/memcpy.S b/arch/blackfin/lib/memcpy.S new file mode 100644 index 000000000000..c1e00eff541c --- /dev/null +++ b/arch/blackfin/lib/memcpy.S @@ -0,0 +1,142 @@ +/* + * File: arch/blackfin/lib/memcpy.S + * Based on: + * Author: + * + * Created: + * Description: internal version of memcpy(), issued by the compiler + * to copy blocks of data around. + * This is really memmove() - it has to be able to deal with + * possible overlaps, because that ambiguity is when the compiler + * gives up and calls a function. We have our own, internal version + * so that we get something we trust, even if the user has redefined + * the normal symbol. + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* void *memcpy(void *dest, const void *src, size_t n); + * R0 = To Address (dest) (leave unchanged to form result) + * R1 = From Address (src) + * R2 = count + * + * Note: Favours word alignment + */ + +#ifdef CONFIG_MEMCPY_L1 +.section .l1.text +#else +.text +#endif + +.align 2 + +ENTRY(_memcpy) + CC = R2 <= 0; /* length not positive? */ + IF CC JUMP .L_P1L2147483647; /* Nothing to do */ + + P0 = R0 ; /* dst*/ + P1 = R1 ; /* src*/ + P2 = R2 ; /* length */ + + /* check for overlapping data */ + CC = R1 < R0; /* src < dst */ + IF !CC JUMP .Lno_overlap; + R3 = R1 + R2; + CC = R0 < R3; /* and dst < src+len */ + IF CC JUMP .Lhas_overlap; + +.Lno_overlap: + /* Check for aligned data.*/ + + R3 = R1 | R0; + R0 = 0x3; + R3 = R3 & R0; + CC = R3; /* low bits set on either address? */ + IF CC JUMP .Lnot_aligned; + + /* Both addresses are word-aligned, so we can copy + at least part of the data using word copies.*/ + P2 = P2 >> 2; + CC = P2 <= 2; + IF !CC JUMP .Lmore_than_seven; + /* less than eight bytes... */ + P2 = R2; + LSETUP(.Lthree_start, .Lthree_end) LC0=P2; + R0 = R1; /* setup src address for return */ +.Lthree_start: + R3 = B[P1++] (X); +.Lthree_end: + B[P0++] = R3; + + RTS; + +.Lmore_than_seven: + /* There's at least eight bytes to copy. */ + P2 += -1; /* because we unroll one iteration */ + LSETUP(.Lword_loop, .Lword_loop) LC0=P2; + R0 = R1; + I1 = P1; + R3 = [I1++]; +.Lword_loop: + MNOP || [P0++] = R3 || R3 = [I1++]; + + [P0++] = R3; + /* Any remaining bytes to copy? */ + R3 = 0x3; + R3 = R2 & R3; + CC = R3 == 0; + P1 = I1; /* in case there's something left, */ + IF !CC JUMP .Lbytes_left; + RTS; +.Lbytes_left: P2 = R3; +.Lnot_aligned: + /* From here, we're copying byte-by-byte. */ + LSETUP (.Lbyte_start, .Lbyte_end) LC0=P2; + R0 = R1; /* Save src address for return */ +.Lbyte_start: + R1 = B[P1++] (X); +.Lbyte_end: + B[P0++] = R1; + +.L_P1L2147483647: + RTS; + +.Lhas_overlap: + /* Need to reverse the copying, because the + * dst would clobber the src. + * Don't bother to work out alignment for + * the reverse case. + */ + R0 = R1; /* save src for later. */ + P0 = P0 + P2; + P0 += -1; + P1 = P1 + P2; + P1 += -1; + LSETUP(.Lover_start, .Lover_end) LC0=P2; +.Lover_start: + R1 = B[P1--] (X); +.Lover_end: + B[P0--] = R1; + + RTS; diff --git a/arch/blackfin/lib/memmove.S b/arch/blackfin/lib/memmove.S new file mode 100644 index 000000000000..2e5fb7f8df13 --- /dev/null +++ b/arch/blackfin/lib/memmove.S @@ -0,0 +1,103 @@ +/* + * File: arch/blackfin/lib/memmove.S + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +.align 2 + +/* + * C Library function MEMMOVE + * R0 = To Address (leave unchanged to form result) + * R1 = From Address + * R2 = count + * Data may overlap + */ + +ENTRY(_memmove) + I1 = P3; + P0 = R0; /* P0 = To address */ + P3 = R1; /* P3 = From Address */ + P2 = R2; /* P2 = count */ + CC = P2 == 0; /* Check zero count*/ + IF CC JUMP .Lfinished; /* very unlikely */ + + CC = R1 < R0 (IU); /* From < To */ + IF !CC JUMP .Lno_overlap; + R3 = R1 + R2; + CC = R0 <= R3 (IU); /* (From+len) >= To */ + IF CC JUMP .Loverlap; +.Lno_overlap: + R3 = 11; + CC = R2 <= R3; + IF CC JUMP .Lbytes; + R3 = R1 | R0; /* OR addresses together */ + R3 <<= 30; /* check bottom two bits */ + CC = AZ; /* AZ set if zero.*/ + IF !CC JUMP .Lbytes; /* Jump if addrs not aligned.*/ + + I0 = P3; + P1 = P2 >> 2; /* count = n/4 */ + P1 += -1; + R3 = 3; + R2 = R2 & R3; /* remainder */ + P2 = R2; /* set remainder */ + R1 = [I0++]; + + LSETUP (.Lquad_loop, .Lquad_loop) LC0=P1; +.Lquad_loop: MNOP || [P0++] = R1 || R1 = [I0++]; + [P0++] = R1; + + CC = P2 == 0; /* any remaining bytes? */ + P3 = I0; /* Ammend P3 to updated ptr. */ + IF !CC JUMP .Lbytes; + P3 = I1; + RTS; + +.Lbytes: LSETUP (.Lbyte2_s, .Lbyte2_e) LC0=P2; +.Lbyte2_s: R1 = B[P3++](Z); +.Lbyte2_e: B[P0++] = R1; + +.Lfinished: P3 = I1; + RTS; + +.Loverlap: + P2 += -1; + P0 = P0 + P2; + P3 = P3 + P2; + R1 = B[P3--] (Z); + CC = P2 == 0; + IF CC JUMP .Lno_loop; + LSETUP (.Lol_s, .Lol_e) LC0 = P2; +.Lol_s: B[P0--] = R1; +.Lol_e: R1 = B[P3--] (Z); +.Lno_loop: B[P0] = R1; + P3 = I1; + RTS; + +.size _memmove,.-_memmove diff --git a/arch/blackfin/lib/memset.S b/arch/blackfin/lib/memset.S new file mode 100644 index 000000000000..ba6d047568dd --- /dev/null +++ b/arch/blackfin/lib/memset.S @@ -0,0 +1,109 @@ +/* + * File: arch/blackfin/lib/memset.S + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +.align 2 + +#ifdef CONFIG_MEMSET_L1 +.section .l1.text +#else +.text +#endif + +/* + * C Library function MEMSET + * R0 = address (leave unchanged to form result) + * R1 = filler byte + * R2 = count + * Favours word aligned data. + */ + +ENTRY(_memset) + P0 = R0 ; /* P0 = address */ + P2 = R2 ; /* P2 = count */ + R3 = R0 + R2; /* end */ + CC = R2 <= 7(IU); + IF CC JUMP .Ltoo_small; + R1 = R1.B (Z); /* R1 = fill char */ + R2 = 3; + R2 = R0 & R2; /* addr bottom two bits */ + CC = R2 == 0; /* AZ set if zero. */ + IF !CC JUMP .Lforce_align ; /* Jump if addr not aligned. */ + +.Laligned: + P1 = P2 >> 2; /* count = n/4 */ + R2 = R1 << 8; /* create quad filler */ + R2.L = R2.L + R1.L(NS); + R2.H = R2.L + R1.H(NS); + P2 = R3; + + LSETUP (.Lquad_loop , .Lquad_loop) LC0=P1; +.Lquad_loop: + [P0++] = R2; + + CC = P0 == P2; + IF !CC JUMP .Lbytes_left; + RTS; + +.Lbytes_left: + R2 = R3; /* end point */ + R3 = P0; /* current position */ + R2 = R2 - R3; /* bytes left */ + P2 = R2; + +.Ltoo_small: + CC = P2 == 0; /* Check zero count */ + IF CC JUMP .Lfinished; /* Unusual */ + +.Lbytes: + LSETUP (.Lbyte_loop , .Lbyte_loop) LC0=P2; +.Lbyte_loop: + B[P0++] = R1; + +.Lfinished: + RTS; + +.Lforce_align: + CC = BITTST (R0, 0); /* odd byte */ + R0 = 4; + R0 = R0 - R2; + P1 = R0; + R0 = P0; /* Recover return address */ + IF !CC JUMP .Lskip1; + B[P0++] = R1; +.Lskip1: + CC = R2 <= 2; /* 2 bytes */ + P2 -= P1; /* reduce count */ + IF !CC JUMP .Laligned; + B[P0++] = R1; + B[P0++] = R1; + JUMP .Laligned; + +.size _memset,.-_memset diff --git a/arch/blackfin/lib/modsi3.S b/arch/blackfin/lib/modsi3.S new file mode 100644 index 000000000000..528b8b1ccb34 --- /dev/null +++ b/arch/blackfin/lib/modsi3.S @@ -0,0 +1,79 @@ +/* + * File: arch/blackfin/lib/modsi3.S + * Based on: + * Author: + * + * Created: + * Description: This program computes 32 bit signed remainder. It calls div32 function + * for quotient estimation. + * + * Registers used : + * Numerator/ Denominator in R0, R1 + * R0 - returns remainder. + * R2-R7 + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +.global ___modsi3; +.type ___modsi3, STT_FUNC; +.extern ___divsi3; +.type ___divsi3, STT_FUNC; + +#ifdef CONFIG_ARITHMETIC_OPS_L1 +.section .l1.text +#else +.text +#endif + +___modsi3: + + CC=R0==0; + IF CC JUMP .LRETURN_R0; /* Return 0, if numerator == 0 */ + CC=R1==0; + IF CC JUMP .LRETURN_ZERO; /* Return 0, if denominator == 0 */ + CC=R0==R1; + IF CC JUMP .LRETURN_ZERO; /* Return 0, if numerator == denominator */ + CC = R1 == 1; + IF CC JUMP .LRETURN_ZERO; /* Return 0, if denominator == 1 */ + CC = R1 == -1; + IF CC JUMP .LRETURN_ZERO; /* Return 0, if denominator == -1 */ + + /* Valid input. Use __divsi3() to compute the quotient, and then + * derive the remainder from that. */ + + [--SP] = (R7:6); /* Push R7 and R6 */ + [--SP] = RETS; /* and return address */ + R7 = R0; /* Copy of R0 */ + R6 = R1; /* Save for later */ + SP += -12; /* Should always provide this space */ + CALL ___divsi3; /* Compute signed quotient using ___divsi3()*/ + SP += 12; + R0 *= R6; /* Quotient * divisor */ + R0 = R7 - R0; /* Dividend - (quotient * divisor) */ + RETS = [SP++]; /* Get back return address */ + (R7:6) = [SP++]; /* Pop registers R7 and R4 */ + RTS; /* Store remainder */ + +.LRETURN_ZERO: + R0 = 0; +.LRETURN_R0: + RTS; diff --git a/arch/blackfin/lib/muldi3.c b/arch/blackfin/lib/muldi3.c new file mode 100644 index 000000000000..303d0c6a6dba --- /dev/null +++ b/arch/blackfin/lib/muldi3.c @@ -0,0 +1,99 @@ +/* + * File: arch/blackfin/lib/muldi3.c + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SI_TYPE_SIZE +#define SI_TYPE_SIZE 32 +#endif +#define __ll_b (1L << (SI_TYPE_SIZE / 2)) +#define __ll_lowpart(t) ((usitype) (t) % __ll_b) +#define __ll_highpart(t) ((usitype) (t) / __ll_b) +#define BITS_PER_UNIT 8 + +#if !defined(umul_ppmm) +#define umul_ppmm(w1, w0, u, v) \ + do { \ + usitype __x0, __x1, __x2, __x3; \ + usitype __ul, __vl, __uh, __vh; \ + \ + __ul = __ll_lowpart (u); \ + __uh = __ll_highpart (u); \ + __vl = __ll_lowpart (v); \ + __vh = __ll_highpart (v); \ + \ + __x0 = (usitype) __ul * __vl; \ + __x1 = (usitype) __ul * __vh; \ + __x2 = (usitype) __uh * __vl; \ + __x3 = (usitype) __uh * __vh; \ + \ + __x1 += __ll_highpart (__x0);/* this can't give carry */ \ + __x1 += __x2; /* but this indeed can */ \ + if (__x1 < __x2) /* did we get it? */ \ + __x3 += __ll_b; /* yes, add it in the proper pos. */ \ + \ + (w1) = __x3 + __ll_highpart (__x1); \ + (w0) = __ll_lowpart (__x1) * __ll_b + __ll_lowpart (__x0); \ + } while (0) +#endif + +#if !defined(__umulsidi3) +#define __umulsidi3(u, v) \ + ({diunion __w; \ + umul_ppmm (__w.s.high, __w.s.low, u, v); \ + __w.ll; }) +#endif + +typedef unsigned int usitype __attribute__ ((mode(SI))); +typedef int sitype __attribute__ ((mode(SI))); +typedef int ditype __attribute__ ((mode(DI))); +typedef int word_type __attribute__ ((mode(__word__))); + +struct distruct { + sitype low, high; +}; +typedef union { + struct distruct s; + ditype ll; +} diunion; + +#ifdef CONFIG_ARITHMETIC_OPS_L1 +ditype __muldi3(ditype u, ditype v)__attribute__((l1_text)); +#endif + +ditype __muldi3(ditype u, ditype v) +{ + diunion w; + diunion uu, vv; + + uu.ll = u, vv.ll = v; + w.ll = __umulsidi3(uu.s.low, vv.s.low); + w.s.high += ((usitype) uu.s.low * (usitype) vv.s.high + + (usitype) uu.s.high * (usitype) vv.s.low); + + return w.ll; +} diff --git a/arch/blackfin/lib/outs.S b/arch/blackfin/lib/outs.S new file mode 100644 index 000000000000..f8c876fe8930 --- /dev/null +++ b/arch/blackfin/lib/outs.S @@ -0,0 +1,62 @@ +/* + * File: arch/blackfin/lib/outs.S + * Based on: + * Author: Bas Vermeulen + * + * Created: Tue Mar 22 15:27:24 CEST 2005 + * Description: Implementation of outs{bwl} for BlackFin processors using zero overhead loops. + * + * Modified: Copyright (C) 2005 Bas Vermeulen, BuyWays BV + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +.align 2 + +ENTRY(_outsl) + P0 = R0; /* P0 = port */ + P1 = R1; /* P1 = address */ + P2 = R2; /* P2 = count */ + + LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2; +.Llong_loop_s: R0 = [P1++]; +.Llong_loop_e: [P0] = R0; + RTS; + +ENTRY(_outsw) + P0 = R0; /* P0 = port */ + P1 = R1; /* P1 = address */ + P2 = R2; /* P2 = count */ + + LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2; +.Lword_loop_s: R0 = W[P1++]; +.Lword_loop_e: W[P0] = R0; + RTS; + +ENTRY(_outsb) + P0 = R0; /* P0 = port */ + P1 = R1; /* P1 = address */ + P2 = R2; /* P2 = count */ + + LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2; +.Lbyte_loop_s: R0 = B[P1++]; +.Lbyte_loop_e: B[P0] = R0; + RTS; diff --git a/arch/blackfin/lib/smulsi3_highpart.S b/arch/blackfin/lib/smulsi3_highpart.S new file mode 100644 index 000000000000..10b8f8da576f --- /dev/null +++ b/arch/blackfin/lib/smulsi3_highpart.S @@ -0,0 +1,30 @@ +.align 2 +.global ___smulsi3_highpart; +.type ___smulsi3_highpart, STT_FUNC; + +#ifdef CONFIG_ARITHMETIC_OPS_L1 +.section .l1.text +#else +.text +#endif + +___smulsi3_highpart: + R2 = R1.L * R0.L (FU); + R3 = R1.H * R0.L (IS,M); + R0 = R0.H * R1.H, R1 = R0.H * R1.L (IS,M); + + R1.L = R2.H + R1.L; + cc = ac0; + R2 = cc; + + R1.L = R1.L + R3.L; + cc = ac0; + R1 >>>= 16; + R3 >>>= 16; + R1 = R1 + R3; + R1 = R1 + R2; + R2 = cc; + R1 = R1 + R2; + + R0 = R0 + R1; + RTS; diff --git a/arch/blackfin/lib/strcmp.c b/arch/blackfin/lib/strcmp.c new file mode 100644 index 000000000000..2ad47c4254ba --- /dev/null +++ b/arch/blackfin/lib/strcmp.c @@ -0,0 +1,11 @@ +#include + +#define strcmp __inline_strcmp +#include +#undef strcmp + +int strcmp(const char *dest, const char *src) +{ + return __inline_strcmp(dest, src); +} + diff --git a/arch/blackfin/lib/strcpy.c b/arch/blackfin/lib/strcpy.c new file mode 100644 index 000000000000..4dc835a8a19b --- /dev/null +++ b/arch/blackfin/lib/strcpy.c @@ -0,0 +1,11 @@ +#include + +#define strcpy __inline_strcpy +#include +#undef strcpy + +char *strcpy(char *dest, const char *src) +{ + return __inline_strcpy(dest, src); +} + diff --git a/arch/blackfin/lib/strncmp.c b/arch/blackfin/lib/strncmp.c new file mode 100644 index 000000000000..947bcfe3f3bb --- /dev/null +++ b/arch/blackfin/lib/strncmp.c @@ -0,0 +1,11 @@ +#include + +#define strncmp __inline_strncmp +#include +#undef strncmp + +int strncmp(const char *cs, const char *ct, size_t count) +{ + return __inline_strncmp(cs, ct, count); +} + diff --git a/arch/blackfin/lib/strncpy.c b/arch/blackfin/lib/strncpy.c new file mode 100644 index 000000000000..77a9b2e95097 --- /dev/null +++ b/arch/blackfin/lib/strncpy.c @@ -0,0 +1,11 @@ +#include + +#define strncpy __inline_strncpy +#include +#undef strncpy + +char *strncpy(char *dest, const char *src, size_t n) +{ + return __inline_strncpy(dest, src, n); +} + diff --git a/arch/blackfin/lib/udivsi3.S b/arch/blackfin/lib/udivsi3.S new file mode 100644 index 000000000000..d39a12916259 --- /dev/null +++ b/arch/blackfin/lib/udivsi3.S @@ -0,0 +1,298 @@ +/* + * File: arch/blackfin/lib/udivsi3.S + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#define CARRY AC0 + +#ifdef CONFIG_ARITHMETIC_OPS_L1 +.section .l1.text +#else +.text +#endif + + +ENTRY(___udivsi3) + + CC = R0 < R1 (IU); /* If X < Y, always return 0 */ + IF CC JUMP .Lreturn_ident; + + R2 = R1 << 16; + CC = R2 <= R0 (IU); + IF CC JUMP .Lidents; + + R2 = R0 >> 31; /* if X is a 31-bit number */ + R3 = R1 >> 15; /* and Y is a 15-bit number */ + R2 = R2 | R3; /* then it's okay to use the DIVQ builtins (fallthrough to fast)*/ + CC = R2; + IF CC JUMP .Ly_16bit; + +/* METHOD 1: FAST DIVQ + We know we have a 31-bit dividend, and 15-bit divisor so we can use the + simple divq approach (first setting AQ to 0 - implying unsigned division, + then 16 DIVQ's). +*/ + + AQ = CC; /* Clear AQ (CC==0) */ + +/* ISR States: When dividing two integers (32.0/16.0) using divide primitives, + we need to shift the dividend one bit to the left. + We have already checked that we have a 31-bit number so we are safe to do + that. +*/ + R0 <<= 1; + DIVQ(R0, R1); // 1 + DIVQ(R0, R1); // 2 + DIVQ(R0, R1); // 3 + DIVQ(R0, R1); // 4 + DIVQ(R0, R1); // 5 + DIVQ(R0, R1); // 6 + DIVQ(R0, R1); // 7 + DIVQ(R0, R1); // 8 + DIVQ(R0, R1); // 9 + DIVQ(R0, R1); // 10 + DIVQ(R0, R1); // 11 + DIVQ(R0, R1); // 12 + DIVQ(R0, R1); // 13 + DIVQ(R0, R1); // 14 + DIVQ(R0, R1); // 15 + DIVQ(R0, R1); // 16 + R0 = R0.L (Z); + RTS; + +.Ly_16bit: + /* We know that the upper 17 bits of Y might have bits set, + ** or that the sign bit of X might have a bit. If Y is a + ** 16-bit number, but not bigger, then we can use the builtins + ** with a post-divide correction. + ** R3 currently holds Y>>15, which means R3's LSB is the + ** bit we're interested in. + */ + + /* According to the ISR, to use the Divide primitives for + ** unsigned integer divide, the useable range is 31 bits + */ + CC = ! BITTST(R0, 31); + + /* IF condition is true we can scale our inputs and use the divide primitives, + ** with some post-adjustment + */ + R3 += -1; /* if so, Y is 0x00008nnn */ + CC &= AZ; + + /* If condition is true we can scale our inputs and use the divide primitives, + ** with some post-adjustment + */ + R3 = R1 >> 1; /* Pre-scaled divisor for primitive case */ + R2 = R0 >> 16; + + R2 = R3 - R2; /* shifted divisor < upper 16 bits of dividend */ + CC &= CARRY; + IF CC JUMP .Lshift_and_correct; + + /* Fall through to the identities */ + +/* METHOD 2: identities and manual calculation + We are not able to use the divide primites, but may still catch some special + cases. +*/ +.Lidents: + /* Test for common identities. Value to be returned is placed in R2. */ + CC = R0 == 0; /* 0/Y => 0 */ + IF CC JUMP .Lreturn_r0; + CC = R0 == R1; /* X==Y => 1 */ + IF CC JUMP .Lreturn_ident; + CC = R1 == 1; /* X/1 => X */ + IF CC JUMP .Lreturn_ident; + + R2.L = ONES R1; + R2 = R2.L (Z); + CC = R2 == 1; + IF CC JUMP .Lpower_of_two; + + [--SP] = (R7:5); /* Push registers R5-R7 */ + + /* Idents don't match. Go for the full operation. */ + + + R6 = 2; /* assume we'll shift two */ + R3 = 1; + + P2 = R1; + /* If either R0 or R1 have sign set, */ + /* divide them by two, and note it's */ + /* been done. */ + CC = R1 < 0; + R2 = R1 >> 1; + IF CC R1 = R2; /* Possibly-shifted R1 */ + IF !CC R6 = R3; /* R1 doesn't, so at most 1 shifted */ + + P0 = 0; + R3 = -R1; + [--SP] = R3; + R2 = R0 >> 1; + R2 = R0 >> 1; + CC = R0 < 0; + IF CC P0 = R6; /* Number of values divided */ + IF !CC R2 = R0; /* Shifted R0 */ + + /* P0 is 0, 1 (NR/=2) or 2 (NR/=2, DR/=2) */ + + /* r2 holds Copy dividend */ + R3 = 0; /* Clear partial remainder */ + R7 = 0; /* Initialise quotient bit */ + + P1 = 32; /* Set loop counter */ + LSETUP(.Lulst, .Lulend) LC0 = P1; /* Set loop counter */ +.Lulst: R6 = R2 >> 31; /* R6 = sign bit of R2, for carry */ + R2 = R2 << 1; /* Shift 64 bit dividend up by 1 bit */ + R3 = R3 << 1 || R5 = [SP]; + R3 = R3 | R6; /* Include any carry */ + CC = R7 < 0; /* Check quotient(AQ) */ + /* If AQ==0, we'll sub divisor */ + IF CC R5 = R1; /* and if AQ==1, we'll add it. */ + R3 = R3 + R5; /* Add/sub divsor to partial remainder */ + R7 = R3 ^ R1; /* Generate next quotient bit */ + + R5 = R7 >> 31; /* Get AQ */ + BITTGL(R5, 0); /* Invert it, to get what we'll shift */ +.Lulend: R2 = R2 + R5; /* and "shift" it in. */ + + CC = P0 == 0; /* Check how many inputs we shifted */ + IF CC JUMP .Lno_mult; /* if none... */ + R6 = R2 << 1; + CC = P0 == 1; + IF CC R2 = R6; /* if 1, Q = Q*2 */ + IF !CC R1 = P2; /* if 2, restore stored divisor */ + + R3 = R2; /* Copy of R2 */ + R3 *= R1; /* Q * divisor */ + R5 = R0 - R3; /* Z = (dividend - Q * divisor) */ + CC = R1 <= R5 (IU); /* Check if divisor <= Z? */ + R6 = CC; /* if yes, R6 = 1 */ + R2 = R2 + R6; /* if yes, add one to quotient(Q) */ +.Lno_mult: + SP += 4; + (R7:5) = [SP++]; /* Pop registers R5-R7 */ + R0 = R2; /* Store quotient */ + RTS; + +.Lreturn_ident: + CC = R0 < R1 (IU); /* If X < Y, always return 0 */ + R2 = 0; + IF CC JUMP .Ltrue_return_ident; + R2 = -1 (X); /* X/0 => 0xFFFFFFFF */ + CC = R1 == 0; + IF CC JUMP .Ltrue_return_ident; + R2 = -R2; /* R2 now 1 */ + CC = R0 == R1; /* X==Y => 1 */ + IF CC JUMP .Ltrue_return_ident; + R2 = R0; /* X/1 => X */ + /*FALLTHRU*/ + +.Ltrue_return_ident: + R0 = R2; +.Lreturn_r0: + RTS; + +.Lpower_of_two: + /* Y has a single bit set, which means it's a power of two. + ** That means we can perform the division just by shifting + ** X to the right the appropriate number of bits + */ + + /* signbits returns the number of sign bits, minus one. + ** 1=>30, 2=>29, ..., 0x40000000=>0. Which means we need + ** to shift right n-signbits spaces. It also means 0x80000000 + ** is a special case, because that *also* gives a signbits of 0 + */ + + R2 = R0 >> 31; + CC = R1 < 0; + IF CC JUMP .Ltrue_return_ident; + + R1.l = SIGNBITS R1; + R1 = R1.L (Z); + R1 += -30; + R0 = LSHIFT R0 by R1.L; + RTS; + +/* METHOD 3: PRESCALE AND USE THE DIVIDE PRIMITIVES WITH SOME POST-CORRECTION + Two scaling operations are required to use the divide primitives with a + divisor > 0x7FFFF. + Firstly (as in method 1) we need to shift the dividend 1 to the left for + integer division. + Secondly we need to shift both the divisor and dividend 1 to the right so + both are in range for the primitives. + The left/right shift of the dividend does nothing so we can skip it. +*/ +.Lshift_and_correct: + R2 = R0; + // R3 is already R1 >> 1 + CC=!CC; + AQ = CC; /* Clear AQ, got here with CC = 0 */ + DIVQ(R2, R3); // 1 + DIVQ(R2, R3); // 2 + DIVQ(R2, R3); // 3 + DIVQ(R2, R3); // 4 + DIVQ(R2, R3); // 5 + DIVQ(R2, R3); // 6 + DIVQ(R2, R3); // 7 + DIVQ(R2, R3); // 8 + DIVQ(R2, R3); // 9 + DIVQ(R2, R3); // 10 + DIVQ(R2, R3); // 11 + DIVQ(R2, R3); // 12 + DIVQ(R2, R3); // 13 + DIVQ(R2, R3); // 14 + DIVQ(R2, R3); // 15 + DIVQ(R2, R3); // 16 + + /* According to the Instruction Set Reference: + To divide by a divisor > 0x7FFF, + 1. prescale and perform divide to obtain quotient (Q) (done above), + 2. multiply quotient by unscaled divisor (result M) + 3. subtract the product from the divident to get an error (E = X - M) + 4. if E < divisor (Y) subtract 1, if E > divisor (Y) add 1, else return quotient (Q) + */ + R3 = R2.L (Z); /* Q = X' / Y' */ + R2 = R3; /* Preserve Q */ + R2 *= R1; /* M = Q * Y */ + R2 = R0 - R2; /* E = X - M */ + R0 = R3; /* Copy Q into result reg */ + +/* Correction: If result of the multiply is negative, we overflowed + and need to correct the result by subtracting 1 from the result.*/ + R3 = 0xFFFF (Z); + R2 = R2 >> 16; /* E >> 16 */ + CC = R2 == R3; + R3 = 1 ; + R1 = R0 - R3; + IF CC R0 = R1; + RTS; diff --git a/arch/blackfin/lib/umodsi3.S b/arch/blackfin/lib/umodsi3.S new file mode 100644 index 000000000000..b55ce96ab89f --- /dev/null +++ b/arch/blackfin/lib/umodsi3.S @@ -0,0 +1,66 @@ +/* + * File: arch/blackfin/lib/umodsi3.S + * Based on: + * Author: + * + * Created: + * Description: libgcc1 routines for Blackfin 5xx + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef CONFIG_ARITHMETIC_OPS_L1 +.section .l1.text +#else +.text +#endif + +.extern ___udivsi3; +.globl ___umodsi3 +___umodsi3: + + CC=R0==0; + IF CC JUMP .LRETURN_R0; /* Return 0, if NR == 0 */ + CC= R1==0; + IF CC JUMP .LRETURN_ZERO_VAL; /* Return 0, if DR == 0 */ + CC=R0==R1; + IF CC JUMP .LRETURN_ZERO_VAL; /* Return 0, if NR == DR */ + CC = R1 == 1; + IF CC JUMP .LRETURN_ZERO_VAL; /* Return 0, if DR == 1 */ + CC = R0>= 16; + /* Unsigned multiplication has the nice property that we can + ignore carry on this first addition. */ + R0 = R0 + R3; + R0 = R0 + R1; + cc = ac0; + R1 = cc; + R1 = PACK(R1.l,R0.h); + R0 = R1 + R2; + RTS; diff --git a/arch/blackfin/mach-bf533/Kconfig b/arch/blackfin/mach-bf533/Kconfig new file mode 100644 index 000000000000..14297b3ed5c3 --- /dev/null +++ b/arch/blackfin/mach-bf533/Kconfig @@ -0,0 +1,92 @@ +if (BF533 || BF532 || BF531) + +menu "BF533/2/1 Specific Configuration" + +comment "Interrupt Priority Assignment" +menu "Priority" + +config UART_ERROR + int "UART ERROR" + default 7 +config SPORT0_ERROR + int "SPORT0 ERROR" + default 7 +config SPI_ERROR + int "SPI ERROR" + default 7 +config SPORT1_ERROR + int "SPORT1 ERROR" + default 7 +config PPI_ERROR + int "PPI ERROR" + default 7 +config DMA_ERROR + int "DMA ERROR" + default 7 +config PLLWAKE_ERROR + int "PLL WAKEUP ERROR" + default 7 + +config RTC_ERROR + int "RTC ERROR" + default 8 +config DMA0_PPI + int "DMA0 PPI" + default 8 + +config DMA1_SPORT0RX + int "DMA1 (SPORT0 RX)" + default 9 +config DMA2_SPORT0TX + int "DMA2 (SPORT0 TX)" + default 9 +config DMA3_SPORT1RX + int "DMA3 (SPORT1 RX)" + default 9 +config DMA4_SPORT1TX + int "DMA4 (SPORT1 TX)" + default 9 +config DMA5_SPI + int "DMA5 (SPI)" + default 10 +config DMA6_UARTRX + int "DMA6 (UART0 RX)" + default 10 +config DMA7_UARTTX + int "DMA7 (UART0 TX)" + default 10 +config TIMER0 + int "TIMER0" + default 11 +config TIMER1 + int "TIMER1" + default 11 +config TIMER2 + int "TIMER2" + default 11 +config PFA + int "PF Interrupt A" + default 12 +config PFB + int "PF Interrupt B" + default 12 +config MEMDMA0 + int "MEMORY DMA0" + default 13 +config MEMDMA1 + int "MEMORY DMA1" + default 13 +config WDTIMER + int "WATCH DOG TIMER" + default 13 + + help + Enter the priority numbers between 7-13 ONLY. Others are Reserved. + This applies to all the above. It is not recommended to assign the + highest priority number 7 to UART or any other device. + +endmenu + +endmenu + +endif diff --git a/arch/blackfin/mach-bf533/Makefile b/arch/blackfin/mach-bf533/Makefile new file mode 100644 index 000000000000..76d2c2b8579a --- /dev/null +++ b/arch/blackfin/mach-bf533/Makefile @@ -0,0 +1,9 @@ +# +# arch/blackfin/mach-bf533/Makefile +# + +extra-y := head.o + +obj-y := ints-priority.o + +obj-$(CONFIG_CPU_FREQ_BF533) += cpu.o diff --git a/arch/blackfin/mach-bf533/boards/Makefile b/arch/blackfin/mach-bf533/boards/Makefile new file mode 100644 index 000000000000..12a631ab389d --- /dev/null +++ b/arch/blackfin/mach-bf533/boards/Makefile @@ -0,0 +1,8 @@ +# +# arch/blackfin/mach-bf533/boards/Makefile +# + +obj-$(CONFIG_GENERIC_BOARD) += generic_board.o +obj-$(CONFIG_BFIN533_STAMP) += stamp.o +obj-$(CONFIG_BFIN533_EZKIT) += ezkit.o +obj-$(CONFIG_BFIN533_BLUETECHNIX_CM) += cm_bf533.o diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c new file mode 100644 index 000000000000..23a7f607df3f --- /dev/null +++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c @@ -0,0 +1,267 @@ +/* + * File: arch/blackfin/mach-bf533/boards/cm_bf533.c + * Based on: arch/blackfin/mach-bf533/boards/ezkit.c + * Author: Aidan Williams Copright 2005 + * + * Created: 2005 + * Description: Board description file + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Name the Board for the /proc/cpuinfo + */ +char *bfin_board_name = "Bluetechnix CM BF533"; + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* all SPI peripherals info goes here */ + +static struct mtd_partition bfin_spi_flash_partitions[] = { + { + .name = "bootloader", + .size = 0x00020000, + .offset = 0, + .mask_flags = MTD_CAP_ROM + },{ + .name = "kernel", + .size = 0xe0000, + .offset = 0x20000 + },{ + .name = "file system", + .size = 0x700000, + .offset = 0x00100000, + } +}; + +static struct flash_platform_data bfin_spi_flash_data = { + .name = "m25p80", + .parts = bfin_spi_flash_partitions, + .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), + .type = "m25p64", +}; + +/* SPI flash chip (m25p64) */ +static struct bfin5xx_spi_chip spi_flash_chip_info = { + .enable_dma = 0, /* use dma transfer with this chip*/ + .bits_per_word = 8, +}; + +/* SPI ADC chip */ +static struct bfin5xx_spi_chip spi_adc_chip_info = { + .enable_dma = 1, /* use dma transfer with this chip*/ + .bits_per_word = 16, +}; + +#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +static struct bfin5xx_spi_chip ad1836_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +static struct spi_board_info bfin_spi_board_info[] __initdata = { + { + /* the modalias must be the same as spi device driver name */ + .modalias = "m25p80", /* Name of spi_driver for this device */ + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ + .platform_data = &bfin_spi_flash_data, + .controller_data = &spi_flash_chip_info, + .mode = SPI_MODE_3, + },{ + .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ + .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, /* Framework bus number */ + .chip_select = 2, /* Framework chip select. */ + .platform_data = NULL, /* No spi_driver specific config */ + .controller_data = &spi_adc_chip_info, + }, +#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) + { + .modalias = "ad1836-spi", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, + .controller_data = &ad1836_spi_chip_info, + }, +#endif +}; + +/* SPI controller data */ +static struct bfin5xx_spi_master spi_bfin_master_info = { + .num_chipselect = 8, + .enable_dma = 1, /* master has the ability to do dma transfer */ +}; + +static struct platform_device spi_bfin_master_device = { + .name = "bfin-spi-master", + .id = 1, /* Bus number */ + .dev = { + .platform_data = &spi_bfin_master_info, /* Passed to driver */ + }, +}; +#endif /* spi master and devices */ + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) +static struct platform_device rtc_device = { + .name = "rtc-bfin", + .id = -1, +}; +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +static struct resource smc91x_resources[] = { + { + .start = 0x20200300, + .end = 0x20200300 + 16, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PF0, + .end = IRQ_PF0, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +static struct resource bfin_uart_resources[] = { + { + .start = 0xFFC00400, + .end = 0xFFC004FF, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device bfin_uart_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart_resources), + .resource = bfin_uart_resources, +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +static struct platform_device bfin_sport0_uart_device = { + .name = "bfin-sport-uart", + .id = 0, +}; + +static struct platform_device bfin_sport1_uart_device = { + .name = "bfin-sport-uart", + .id = 1, +}; +#endif + +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) +static struct resource isp1362_hcd_resources[] = { + { + .start = 0x20308000, + .end = 0x20308000, + .flags = IORESOURCE_MEM, + },{ + .start = 0x20308004, + .end = 0x20308004, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PF4, + .end = IRQ_PF4, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct isp1362_platform_data isp1362_priv = { + .sel15Kres = 1, + .clknotstop = 0, + .oc_enable = 0, + .int_act_high = 0, + .int_edge_triggered = 0, + .remote_wakeup_connected = 0, + .no_power_switching = 1, + .power_switching_mode = 0, +}; + +static struct platform_device isp1362_hcd_device = { + .name = "isp1362-hcd", + .id = 0, + .dev = { + .platform_data = &isp1362_priv, + }, + .num_resources = ARRAY_SIZE(isp1362_hcd_resources), + .resource = isp1362_hcd_resources, +}; +#endif + +static struct platform_device *cm_bf533_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) + &bfin_uart_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) + &bfin_sport0_uart_device, + &bfin_sport1_uart_device, +#endif + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) + &rtc_device, +#endif + +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) + &isp1362_hcd_device, +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + &smc91x_device, +#endif + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + &spi_bfin_master_device, +#endif +}; + +static int __init cm_bf533_init(void) +{ + printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); + platform_add_devices(cm_bf533_devices, ARRAY_SIZE(cm_bf533_devices)); +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); +#endif + return 0; +} + +arch_initcall(cm_bf533_init); diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c new file mode 100644 index 000000000000..747298ea907b --- /dev/null +++ b/arch/blackfin/mach-bf533/boards/ezkit.c @@ -0,0 +1,224 @@ +/* + * File: arch/blackfin/mach-bf533/ezkit.c + * Based on: Orginal Work + * Author: Aidan Williams + * + * Created: 2005 + * Description: + * + * Modified: Robin Getz - Named the boards + * Copyright 2005 National ICT Australia (NICTA) + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Name the Board for the /proc/cpuinfo + */ +char *bfin_board_name = "ADDS-BF533-EZKIT"; + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) +static struct platform_device rtc_device = { + .name = "rtc-bfin", + .id = -1, +}; +#endif + +/* + * USB-LAN EzExtender board + * Driver needs to know address, irq and flag pin. + */ +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +static struct resource smc91x_resources[] = { + { + .name = "smc91x-regs", + .start = 0x20310300, + .end = 0x20310300 + 16, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PF9, + .end = IRQ_PF9, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* all SPI peripherals info goes here */ + +#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) +static struct mtd_partition bfin_spi_flash_partitions[] = { + { + .name = "bootloader", + .size = 0x00020000, + .offset = 0, + .mask_flags = MTD_CAP_ROM + },{ + .name = "kernel", + .size = 0xe0000, + .offset = 0x20000 + },{ + .name = "file system", + .size = 0x700000, + .offset = 0x00100000, + } +}; + +static struct flash_platform_data bfin_spi_flash_data = { + .name = "m25p80", + .parts = bfin_spi_flash_partitions, + .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), + .type = "m25p64", +}; + +/* SPI flash chip (m25p64) */ +static struct bfin5xx_spi_chip spi_flash_chip_info = { + .enable_dma = 0, /* use dma transfer with this chip*/ + .bits_per_word = 8, +}; +#endif + +#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) +/* SPI ADC chip */ +static struct bfin5xx_spi_chip spi_adc_chip_info = { + .enable_dma = 1, /* use dma transfer with this chip*/ + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +static struct bfin5xx_spi_chip ad1836_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +static struct spi_board_info bfin_spi_board_info[] __initdata = { +#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) + { + /* the modalias must be the same as spi device driver name */ + .modalias = "m25p80", /* Name of spi_driver for this device */ + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, /* Framework bus number */ + .chip_select = 2, /* Framework chip select. On STAMP537 it is SPISSEL2*/ + .platform_data = &bfin_spi_flash_data, + .controller_data = &spi_flash_chip_info, + .mode = SPI_MODE_3, + }, +#endif + +#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) + { + .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ + .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. */ + .platform_data = NULL, /* No spi_driver specific config */ + .controller_data = &spi_adc_chip_info, + }, +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) + { + .modalias = "ad1836-spi", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, + .controller_data = &ad1836_spi_chip_info, + }, +#endif +}; + +/* SPI controller data */ +static struct bfin5xx_spi_master spi_bfin_master_info = { + .num_chipselect = 8, + .enable_dma = 1, /* master has the ability to do dma transfer */ +}; + +static struct platform_device spi_bfin_master_device = { + .name = "bfin-spi-master", + .id = 1, /* Bus number */ + .dev = { + .platform_data = &spi_bfin_master_info, /* Passed to driver */ + }, +}; +#endif /* spi master and devices */ + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +static struct resource bfin_uart_resources[] = { + { + .start = 0xFFC00400, + .end = 0xFFC004FF, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device bfin_uart_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart_resources), + .resource = bfin_uart_resources, +}; +#endif + +static struct platform_device *ezkit_devices[] __initdata = { +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + &smc91x_device, +#endif + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + &spi_bfin_master_device, +#endif + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) + &rtc_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) + &bfin_uart_device, +#endif +}; + +static int __init ezkit_init(void) +{ + printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); + platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices)); +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); +#endif + return 0; +} + +arch_initcall(ezkit_init); diff --git a/arch/blackfin/mach-bf533/boards/generic_board.c b/arch/blackfin/mach-bf533/boards/generic_board.c new file mode 100644 index 000000000000..c0f43ccfbfb5 --- /dev/null +++ b/arch/blackfin/mach-bf533/boards/generic_board.c @@ -0,0 +1,95 @@ +/* + * File: arch/blackfin/mach-bf533/generic_board.c + * Based on: arch/blackfin/mach-bf533/ezkit.c + * Author: Aidan Williams + * + * Created: 2005 + * Description: + * + * Modified: + * Copyright 2005 National ICT Australia (NICTA) + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +/* + * Name the Board for the /proc/cpuinfo + */ +char *bfin_board_name = "UNKNOWN BOARD"; + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) +static struct platform_device rtc_device = { + .name = "rtc-bfin", + .id = -1, +}; +#endif + +/* + * Driver needs to know address, irq and flag pin. + */ +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +static struct resource smc91x_resources[] = { + { + .start = 0x20300300, + .end = 0x20300300 + 16, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PROG_INTB, + .end = IRQ_PROG_INTB, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + },{ + /* + * denotes the flag pin and is used directly if + * CONFIG_IRQCHIP_DEMUX_GPIO is defined. + */ + .start = IRQ_PF7, + .end = IRQ_PF7, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +static struct platform_device *generic_board_devices[] __initdata = { +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) + &rtc_device, +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + &smc91x_device, +#endif +}; + +static int __init generic_board_init(void) +{ + printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); + return platform_add_devices(generic_board_devices, ARRAY_SIZE(generic_board_devices)); +} + +arch_initcall(generic_board_init); diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c new file mode 100644 index 000000000000..d7b3a5d74e8c --- /dev/null +++ b/arch/blackfin/mach-bf533/boards/stamp.c @@ -0,0 +1,321 @@ +/* + * File: arch/blackfin/mach-bf533/stamp.c + * Based on: arch/blackfin/mach-bf533/ezkit.c + * Author: Aidan Williams + * + * Created: 2005 + * Description: Board Info File for the BF533-STAMP + * + * Modified: + * Copyright 2005 National ICT Australia (NICTA) + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) +#include +#endif +#include +#include + +/* + * Name the Board for the /proc/cpuinfo + */ +char *bfin_board_name = "ADDS-BF533-STAMP"; + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) +static struct platform_device rtc_device = { + .name = "rtc-bfin", + .id = -1, +}; +#endif + +/* + * Driver needs to know address, irq and flag pin. + */ +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +static struct resource smc91x_resources[] = { + { + .name = "smc91x-regs", + .start = 0x20300300, + .end = 0x20300300 + 16, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PF7, + .end = IRQ_PF7, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) +static struct resource net2272_bfin_resources[] = { + { + .start = 0x20300000, + .end = 0x20300000 + 0x100, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PF10, + .end = IRQ_PF10, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device net2272_bfin_device = { + .name = "net2272", + .id = -1, + .num_resources = ARRAY_SIZE(net2272_bfin_resources), + .resource = net2272_bfin_resources, +}; +#endif + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* all SPI peripherals info goes here */ + +#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) +static struct mtd_partition bfin_spi_flash_partitions[] = { + { + .name = "bootloader", + .size = 0x00020000, + .offset = 0, + .mask_flags = MTD_CAP_ROM + },{ + .name = "kernel", + .size = 0xe0000, + .offset = 0x20000 + },{ + .name = "file system", + .size = 0x700000, + .offset = 0x00100000, + } +}; + +static struct flash_platform_data bfin_spi_flash_data = { + .name = "m25p80", + .parts = bfin_spi_flash_partitions, + .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), + .type = "m25p64", +}; + +/* SPI flash chip (m25p64) */ +static struct bfin5xx_spi_chip spi_flash_chip_info = { + .enable_dma = 0, /* use dma transfer with this chip*/ + .bits_per_word = 8, +}; +#endif + +#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) +/* SPI ADC chip */ +static struct bfin5xx_spi_chip spi_adc_chip_info = { + .enable_dma = 1, /* use dma transfer with this chip*/ + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +static struct bfin5xx_spi_chip ad1836_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_PBX) +static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { + .ctl_reg = 0x4, /* send zero */ + .enable_dma = 0, + .bits_per_word = 8, + .cs_change_per_word = 1, +}; +#endif + +#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) +static struct bfin5xx_spi_chip ad5304_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +static struct spi_board_info bfin_spi_board_info[] __initdata = { +#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) + { + /* the modalias must be the same as spi device driver name */ + .modalias = "m25p80", /* Name of spi_driver for this device */ + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, /* Framework bus number */ + .chip_select = 2, /* Framework chip select. On STAMP537 it is SPISSEL2*/ + .platform_data = &bfin_spi_flash_data, + .controller_data = &spi_flash_chip_info, + .mode = SPI_MODE_3, + }, +#endif + +#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) + { + .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ + .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. */ + .platform_data = NULL, /* No spi_driver specific config */ + .controller_data = &spi_adc_chip_info, + }, +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) + { + .modalias = "ad1836-spi", + .max_speed_hz = 31250000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, + .controller_data = &ad1836_spi_chip_info, + }, +#endif + +#if defined(CONFIG_PBX) + { + .modalias = "fxs-spi", + .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 3, + .controller_data= &spi_si3xxx_chip_info, + .mode = SPI_MODE_3, + }, + { + .modalias = "fxo-spi", + .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 2, + .controller_data= &spi_si3xxx_chip_info, + .mode = SPI_MODE_3, + }, +#endif + +#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) + { + .modalias = "ad5304_spi", + .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 2, + .platform_data = NULL, + .controller_data = &ad5304_chip_info, + .mode = SPI_MODE_2, + }, +#endif +}; + +/* SPI controller data */ +static struct bfin5xx_spi_master spi_bfin_master_info = { + .num_chipselect = 8, + .enable_dma = 1, /* master has the ability to do dma transfer */ +}; + +static struct platform_device spi_bfin_master_device = { + .name = "bfin-spi-master", + .id = 1, /* Bus number */ + .dev = { + .platform_data = &spi_bfin_master_info, /* Passed to driver */ + }, +}; +#endif /* spi master and devices */ + +#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) +static struct platform_device bfin_fb_device = { + .name = "bf537-fb", +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +static struct resource bfin_uart_resources[] = { + { + .start = 0xFFC00400, + .end = 0xFFC004FF, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device bfin_uart_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart_resources), + .resource = bfin_uart_resources, +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +static struct platform_device bfin_sport0_uart_device = { + .name = "bfin-sport-uart", + .id = 0, +}; + +static struct platform_device bfin_sport1_uart_device = { + .name = "bfin-sport-uart", + .id = 1, +}; +#endif + +static struct platform_device *stamp_devices[] __initdata = { +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) + &rtc_device, +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + &smc91x_device, +#endif + +#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) + &net2272_bfin_device, +#endif + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + &spi_bfin_master_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) + &bfin_uart_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) + &bfin_sport0_uart_device, + &bfin_sport1_uart_device, +#endif +}; + +static int __init stamp_init(void) +{ + printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); + platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); +#endif + return 0; +} + +arch_initcall(stamp_init); diff --git a/arch/blackfin/mach-bf533/cpu.c b/arch/blackfin/mach-bf533/cpu.c new file mode 100644 index 000000000000..99547c4c290e --- /dev/null +++ b/arch/blackfin/mach-bf533/cpu.c @@ -0,0 +1,161 @@ +/* + * File: arch/blackfin/mach-bf533/cpu.c + * Based on: + * Author: michael.kang@analog.com + * + * Created: + * Description: clock scaling for the bf533 + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +/* CONFIG_CLKIN_HZ=11059200 */ +#define VCO5 (CONFIG_CLKIN_HZ*45) /*497664000 */ +#define VCO4 (CONFIG_CLKIN_HZ*36) /*398131200 */ +#define VCO3 (CONFIG_CLKIN_HZ*27) /*298598400 */ +#define VCO2 (CONFIG_CLKIN_HZ*18) /*199065600 */ +#define VCO1 (CONFIG_CLKIN_HZ*9) /*99532800 */ +#define VCO(x) VCO##x + +#define FREQ(x) {VCO(x),VCO(x)/4},{VCO(x),VCO(x)/2},{VCO(x),VCO(x)} +/* frequency */ +static struct cpufreq_frequency_table bf533_freq_table[] = { + FREQ(1), + FREQ(3), + {VCO4, VCO4 / 2}, {VCO4, VCO4}, + FREQ(5), + {0, CPUFREQ_TABLE_END}, +}; + +/* + * dpmc_fops->ioctl() + * static int dpmc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) + */ +static int bf533_getfreq(unsigned int cpu) +{ + unsigned long cclk_mhz, vco_mhz; + + /* The driver only support single cpu */ + if (cpu == 0) + dpmc_fops.ioctl(NULL, NULL, IOCTL_GET_CORECLOCK, &cclk_mhz); + else + cclk_mhz = -1; + return cclk_mhz; +} + +static int bf533_target(struct cpufreq_policy *policy, + unsigned int target_freq, unsigned int relation) +{ + unsigned long cclk_mhz; + unsigned long vco_mhz; + unsigned long flags; + unsigned int index, vco_index; + int i; + + struct cpufreq_freqs freqs; + if (cpufreq_frequency_table_target + (policy, bf533_freq_table, target_freq, relation, &index)) + return -EINVAL; + cclk_mhz = bf533_freq_table[index].frequency; + vco_mhz = bf533_freq_table[index].index; + + dpmc_fops.ioctl(NULL, NULL, IOCTL_CHANGE_FREQUENCY, &vco_mhz); + freqs.old = bf533_getfreq(0); + freqs.new = cclk_mhz; + freqs.cpu = 0; + + pr_debug("cclk begin change to cclk %d,vco=%d,index=%d,target=%d,oldfreq=%d\n", + cclk_mhz, vco_mhz, index, target_freq, freqs.old); + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + local_irq_save(flags); + dpmc_fops.ioctl(NULL, NULL, IOCTL_SET_CCLK, &cclk_mhz); + local_irq_restore(flags); + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + vco_mhz = get_vco(); + cclk_mhz = get_cclk(); + return 0; +} + +/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on + * this platform, anyway. + */ +static int bf533_verify_speed(struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, &bf533_freq_table); +} + +static int __init __bf533_cpu_init(struct cpufreq_policy *policy) +{ + int result; + + if (policy->cpu != 0) + return -EINVAL; + + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + + policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; + /*Now ,only support one cpu */ + policy->cur = bf533_getfreq(0); + cpufreq_frequency_table_get_attr(bf533_freq_table, policy->cpu); + return cpufreq_frequency_table_cpuinfo(policy, bf533_freq_table); +} + +static struct freq_attr *bf533_freq_attr[] = { + &cpufreq_freq_attr_scaling_available_freqs, + NULL, +}; + +static struct cpufreq_driver bf533_driver = { + .verify = bf533_verify_speed, + .target = bf533_target, + .get = bf533_getfreq, + .init = __bf533_cpu_init, + .name = "bf533", + .owner = THIS_MODULE, + .attr = bf533_freq_attr, +}; + +static int __init bf533_cpu_init(void) +{ + return cpufreq_register_driver(&bf533_driver); +} + +static void __exit bf533_cpu_exit(void) +{ + cpufreq_unregister_driver(&bf533_driver); +} + +MODULE_AUTHOR("Mickael Kang"); +MODULE_DESCRIPTION("cpufreq driver for BF533 CPU"); +MODULE_LICENSE("GPL"); + +module_init(bf533_cpu_init); +module_exit(bf533_cpu_exit); diff --git a/arch/blackfin/mach-bf533/head.S b/arch/blackfin/mach-bf533/head.S new file mode 100644 index 000000000000..4808edb0680f --- /dev/null +++ b/arch/blackfin/mach-bf533/head.S @@ -0,0 +1,774 @@ +/* + * File: arch/blackfin/mach-bf533/head.S + * Based on: + * Author: Jeff Dionne COPYRIGHT 1998 D. Jeff Dionne + * + * Created: 1998 + * Description: bf533 startup file + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#if CONFIG_BFIN_KERNEL_CLOCK +#include +#endif +#if CONFIG_DEBUG_KERNEL_START +#include +#endif + +.global __rambase +.global __ramstart +.global __ramend +.extern ___bss_stop +.extern ___bss_start +.extern _bf53x_relocate_l1_mem + +#define INITIAL_STACK 0xFFB01000 + +.text + +ENTRY(__start) +ENTRY(__stext) + /* R0: argument of command line string, passed from uboot, save it */ + R7 = R0; + /* Set the SYSCFG register */ + R0 = 0x36; + /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/ + SYSCFG = R0; + R0 = 0; + + /*Clear Out All the data and pointer Registers*/ + R1 = R0; + R2 = R0; + R3 = R0; + R4 = R0; + R5 = R0; + R6 = R0; + + P0 = R0; + P1 = R0; + P2 = R0; + P3 = R0; + P4 = R0; + P5 = R0; + + LC0 = r0; + LC1 = r0; + L0 = r0; + L1 = r0; + L2 = r0; + L3 = r0; + + /* Clear Out All the DAG Registers*/ + B0 = r0; + B1 = r0; + B2 = r0; + B3 = r0; + + I0 = r0; + I1 = r0; + I2 = r0; + I3 = r0; + + M0 = r0; + M1 = r0; + M2 = r0; + M3 = r0; + +#if CONFIG_DEBUG_KERNEL_START + +/* + * Set up a temporary Event Vector Table, so if something bad happens before + * the kernel is fully started, it doesn't vector off into the bootloaders + * table + */ + P0.l = lo(EVT2); + P0.h = hi(EVT2); + P1.l = lo(EVT15); + P1.h = hi(EVT15); + P2.l = debug_kernel_start_trap; + P2.h = debug_kernel_start_trap; + + RTS = P2; + RTI = P2; + RTX = P2; + RTN = P2; + RTE = P2; + +.Lfill_temp_vector_table: + [P0++] = P2; /* Core Event Vector Table */ + CC = P0 == P1; + if !CC JUMP .Lfill_temp_vector_table + P0 = r0; + P1 = r0; + P2 = r0; + +#endif + + p0.h = hi(FIO_MASKA_C); + p0.l = lo(FIO_MASKA_C); + r0 = 0xFFFF(Z); + w[p0] = r0.L; /* Disable all interrupts */ + ssync; + + p0.h = hi(FIO_MASKB_C); + p0.l = lo(FIO_MASKB_C); + r0 = 0xFFFF(Z); + w[p0] = r0.L; /* Disable all interrupts */ + ssync; + + /* Turn off the icache */ + p0.l = (IMEM_CONTROL & 0xFFFF); + p0.h = (IMEM_CONTROL >> 16); + R1 = [p0]; + R0 = ~ENICPLB; + R0 = R0 & R1; + + /* Anomaly 05000125 */ +#ifdef ANOMALY_05000125 + CLI R2; + SSYNC; +#endif + [p0] = R0; + SSYNC; +#ifdef ANOMALY_05000125 + STI R2; +#endif + + /* Turn off the dcache */ + p0.l = (DMEM_CONTROL & 0xFFFF); + p0.h = (DMEM_CONTROL >> 16); + R1 = [p0]; + R0 = ~ENDCPLB; + R0 = R0 & R1; + + /* Anomaly 05000125 */ +#ifdef ANOMALY_05000125 + CLI R2; + SSYNC; +#endif + [p0] = R0; + SSYNC; +#ifdef ANOMALY_05000125 + STI R2; +#endif + + /* Initialise UART */ + p0.h = hi(UART_LCR); + p0.l = lo(UART_LCR); + r0 = 0x0(Z); + w[p0] = r0.L; /* To enable DLL writes */ + ssync; + + p0.h = hi(UART_DLL); + p0.l = lo(UART_DLL); + r0 = 0x0(Z); + w[p0] = r0.L; + ssync; + + p0.h = hi(UART_DLH); + p0.l = lo(UART_DLH); + r0 = 0x00(Z); + w[p0] = r0.L; + ssync; + + p0.h = hi(UART_GCTL); + p0.l = lo(UART_GCTL); + r0 = 0x0(Z); + w[p0] = r0.L; /* To enable UART clock */ + ssync; + + /* Initialize stack pointer */ + sp.l = lo(INITIAL_STACK); + sp.h = hi(INITIAL_STACK); + fp = sp; + usp = sp; + + /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ + call _bf53x_relocate_l1_mem; +#if CONFIG_BFIN_KERNEL_CLOCK + call _start_dma_code; +#endif + + /* Code for initializing Async memory banks */ + + p2.h = hi(EBIU_AMBCTL1); + p2.l = lo(EBIU_AMBCTL1); + r0.h = hi(AMBCTL1VAL); + r0.l = lo(AMBCTL1VAL); + [p2] = r0; + ssync; + + p2.h = hi(EBIU_AMBCTL0); + p2.l = lo(EBIU_AMBCTL0); + r0.h = hi(AMBCTL0VAL); + r0.l = lo(AMBCTL0VAL); + [p2] = r0; + ssync; + + p2.h = hi(EBIU_AMGCTL); + p2.l = lo(EBIU_AMGCTL); + r0 = AMGCTLVAL; + w[p2] = r0; + ssync; + + /* This section keeps the processor in supervisor mode + * during kernel boot. Switches to user mode at end of boot. + * See page 3-9 of Hardware Reference manual for documentation. + */ + + /* EVT15 = _real_start */ + + p0.l = lo(EVT15); + p0.h = hi(EVT15); + p1.l = _real_start; + p1.h = _real_start; + [p0] = p1; + csync; + + p0.l = lo(IMASK); + p0.h = hi(IMASK); + p1.l = IMASK_IVG15; + p1.h = 0x0; + [p0] = p1; + csync; + + raise 15; + p0.l = .LWAIT_HERE; + p0.h = .LWAIT_HERE; + reti = p0; +#if defined(ANOMALY_05000281) + nop; nop; nop; +#endif + rti; + +.LWAIT_HERE: + jump .LWAIT_HERE; + +ENTRY(_real_start) + [ -- sp ] = reti; + p0.l = lo(WDOG_CTL); + p0.h = hi(WDOG_CTL); + r0 = 0xAD6(z); + w[p0] = r0; /* watchdog off for now */ + ssync; + + /* Code update for BSS size == 0 + * Zero out the bss region. + */ + + p1.l = ___bss_start; + p1.h = ___bss_start; + p2.l = ___bss_stop; + p2.h = ___bss_stop; + r0 = 0; + p2 -= p1; + lsetup (.L_clear_bss, .L_clear_bss) lc0 = p2; +.L_clear_bss: + B[p1++] = r0; + + /* In case there is a NULL pointer reference + * Zero out region before stext + */ + + p1.l = 0x0; + p1.h = 0x0; + r0.l = __stext; + r0.h = __stext; + r0 = r0 >> 1; + p2 = r0; + r0 = 0; + lsetup (.L_clear_zero, .L_clear_zero) lc0 = p2; +.L_clear_zero: + W[p1++] = r0; + +/* pass the uboot arguments to the global value command line */ + R0 = R7; + call _cmdline_init; + + p1.l = __rambase; + p1.h = __rambase; + r0.l = __sdata; + r0.h = __sdata; + [p1] = r0; + + p1.l = __ramstart; + p1.h = __ramstart; + p3.l = ___bss_stop; + p3.h = ___bss_stop; + + r1 = p3; + [p1] = r1; + + /* + * load the current thread pointer and stack + */ + r1.l = _init_thread_union; + r1.h = _init_thread_union; + + r2.l = 0x2000; + r2.h = 0x0000; + r1 = r1 + r2; + sp = r1; + usp = sp; + fp = sp; + call _start_kernel; +.L_exit: + jump.s .L_exit; + +.section .l1.text +#if CONFIG_BFIN_KERNEL_CLOCK +ENTRY(_start_dma_code) + p0.h = hi(SIC_IWR); + p0.l = lo(SIC_IWR); + r0.l = 0x1; + r0.h = 0x0; + [p0] = r0; + SSYNC; + + /* + * Set PLL_CTL + * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors + * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK + * - [7] = output delay (add 200ps of delay to mem signals) + * - [6] = input delay (add 200ps of input delay to mem signals) + * - [5] = PDWN : 1=All Clocks off + * - [3] = STOPCK : 1=Core Clock off + * - [1] = PLL_OFF : 1=Disable Power to PLL + * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL + * all other bits set to zero + */ + + p0.h = hi(PLL_LOCKCNT); + p0.l = lo(PLL_LOCKCNT); + r0 = 0x300(Z); + w[p0] = r0.l; + ssync; + + P2.H = hi(EBIU_SDGCTL); + P2.L = lo(EBIU_SDGCTL); + R0 = [P2]; + BITSET (R0, 24); + [P2] = R0; + SSYNC; + + r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */ + r0 = r0 << 9; /* Shift it over, */ + r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/ + r0 = r1 | r0; + r1 = PLL_BYPASS; /* Bypass the PLL? */ + r1 = r1 << 8; /* Shift it over */ + r0 = r1 | r0; /* add them all together */ + + p0.h = hi(PLL_CTL); + p0.l = lo(PLL_CTL); /* Load the address */ + cli r2; /* Disable interrupts */ + ssync; + w[p0] = r0.l; /* Set the value */ + idle; /* Wait for the PLL to stablize */ + sti r2; /* Enable interrupts */ + +.Lcheck_again: + p0.h = hi(PLL_STAT); + p0.l = lo(PLL_STAT); + R0 = W[P0](Z); + CC = BITTST(R0,5); + if ! CC jump .Lcheck_again; + + /* Configure SCLK & CCLK Dividers */ + r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV); + p0.h = hi(PLL_DIV); + p0.l = lo(PLL_DIV); + w[p0] = r0.l; + ssync; + + p0.l = lo(EBIU_SDRRC); + p0.h = hi(EBIU_SDRRC); + r0 = mem_SDRRC; + w[p0] = r0.l; + ssync; + + p0.l = (EBIU_SDBCTL & 0xFFFF); + p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */ + r0 = mem_SDBCTL; + w[p0] = r0.l; + ssync; + + P2.H = hi(EBIU_SDGCTL); + P2.L = lo(EBIU_SDGCTL); + R0 = [P2]; + BITCLR (R0, 24); + p0.h = hi(EBIU_SDSTAT); + p0.l = lo(EBIU_SDSTAT); + r2.l = w[p0]; + cc = bittst(r2,3); + if !cc jump .Lskip; + NOP; + BITSET (R0, 23); +.Lskip: + [P2] = R0; + SSYNC; + + R0.L = lo(mem_SDGCTL); + R0.H = hi(mem_SDGCTL); + R1 = [p2]; + R1 = R1 | R0; + [P2] = R1; + SSYNC; + + p0.h = hi(SIC_IWR); + p0.l = lo(SIC_IWR); + r0.l = lo(IWR_ENABLE_ALL) + r0.h = hi(IWR_ENABLE_ALL) + [p0] = r0; + SSYNC; + + RTS; +#endif /* CONFIG_BFIN_KERNEL_CLOCK */ + +ENTRY(_bfin_reset) + /* No more interrupts to be handled*/ + CLI R6; + SSYNC; + +#if defined(CONFIG_BFIN_SHARED_FLASH_ENET) + p0.h = hi(FIO_INEN); + p0.l = lo(FIO_INEN); + r0.l = ~(1 << CONFIG_ENET_FLASH_PIN); + w[p0] = r0.l; + + p0.h = hi(FIO_DIR); + p0.l = lo(FIO_DIR); + r0.l = (1 << CONFIG_ENET_FLASH_PIN); + w[p0] = r0.l; + + p0.h = hi(FIO_FLAG_C); + p0.l = lo(FIO_FLAG_C); + r0.l = (1 << CONFIG_ENET_FLASH_PIN); + w[p0] = r0.l; +#endif + + /* Clear the bits 13-15 in SWRST if they werent cleared */ + p0.h = hi(SWRST); + p0.l = lo(SWRST); + csync; + r0.l = w[p0]; + + /* Clear the IMASK register */ + p0.h = hi(IMASK); + p0.l = lo(IMASK); + r0 = 0x0; + [p0] = r0; + + /* Clear the ILAT register */ + p0.h = hi(ILAT); + p0.l = lo(ILAT); + r0 = [p0]; + [p0] = r0; + SSYNC; + + /* Disable the WDOG TIMER */ + p0.h = hi(WDOG_CTL); + p0.l = lo(WDOG_CTL); + r0.l = 0xAD6; + w[p0] = r0.l; + SSYNC; + + /* Clear the sticky bit incase it is already set */ + p0.h = hi(WDOG_CTL); + p0.l = lo(WDOG_CTL); + r0.l = 0x8AD6; + w[p0] = r0.l; + SSYNC; + + /* Program the count value */ + R0.l = 0x100; + R0.h = 0x0; + P0.h = hi(WDOG_CNT); + P0.l = lo(WDOG_CNT); + [P0] = R0; + SSYNC; + + /* Program WDOG_STAT if necessary */ + P0.h = hi(WDOG_CTL); + P0.l = lo(WDOG_CTL); + R0 = W[P0](Z); + CC = BITTST(R0,1); + if !CC JUMP .LWRITESTAT; + CC = BITTST(R0,2); + if !CC JUMP .LWRITESTAT; + JUMP .LSKIP_WRITE; + +.LWRITESTAT: + /* When watch dog timer is enabled, a write to STAT will load the contents of CNT to STAT */ + R0 = 0x0000(z); + P0.h = hi(WDOG_STAT); + P0.l = lo(WDOG_STAT) + [P0] = R0; + SSYNC; + +.LSKIP_WRITE: + /* Enable the reset event */ + P0.h = hi(WDOG_CTL); + P0.l = lo(WDOG_CTL); + R0 = W[P0](Z); + BITCLR(R0,1); + BITCLR(R0,2); + W[P0] = R0.L; + SSYNC; + NOP; + + /* Enable the wdog counter */ + R0 = W[P0](Z); + BITCLR(R0,4); + W[P0] = R0.L; + SSYNC; + + IDLE; + + RTS; + +#if CONFIG_DEBUG_KERNEL_START +debug_kernel_start_trap: + /* Set up a temp stack in L1 - SDRAM might not be working */ + P0.L = lo(L1_DATA_A_START + 0x100); + P0.H = hi(L1_DATA_A_START + 0x100); + SP = P0; + + /* Make sure the Clocks are the way I think they should be */ + r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */ + r0 = r0 << 9; /* Shift it over, */ + r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/ + r0 = r1 | r0; + r1 = PLL_BYPASS; /* Bypass the PLL? */ + r1 = r1 << 8; /* Shift it over */ + r0 = r1 | r0; /* add them all together */ + + p0.h = hi(PLL_CTL); + p0.l = lo(PLL_CTL); /* Load the address */ + cli r2; /* Disable interrupts */ + ssync; + w[p0] = r0.l; /* Set the value */ + idle; /* Wait for the PLL to stablize */ + sti r2; /* Enable interrupts */ + +.Lcheck_again1: + p0.h = hi(PLL_STAT); + p0.l = lo(PLL_STAT); + R0 = W[P0](Z); + CC = BITTST(R0,5); + if ! CC jump .Lcheck_again1; + + /* Configure SCLK & CCLK Dividers */ + r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV); + p0.h = hi(PLL_DIV); + p0.l = lo(PLL_DIV); + w[p0] = r0.l; + ssync; + + /* Make sure UART is enabled - you can never be sure */ + +/* + * Setup for console. Argument comes from the menuconfig + */ + +#ifdef CONFIG_BAUD_9600 +#define CONSOLE_BAUD_RATE 9600 +#elif CONFIG_BAUD_19200 +#define CONSOLE_BAUD_RATE 19200 +#elif CONFIG_BAUD_38400 +#define CONSOLE_BAUD_RATE 38400 +#elif CONFIG_BAUD_57600 +#define CONSOLE_BAUD_RATE 57600 +#elif CONFIG_BAUD_115200 +#define CONSOLE_BAUD_RATE 115200 +#endif + + p0.h = hi(UART_GCTL); + p0.l = lo(UART_GCTL); + r0 = 0x00(Z); + w[p0] = r0.L; /* To Turn off UART clocks */ + ssync; + + p0.h = hi(UART_LCR); + p0.l = lo(UART_LCR); + r0 = 0x83(Z); + w[p0] = r0.L; /* To enable DLL writes */ + ssync; + + R1 = (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_SCLK_DIV) / (CONSOLE_BAUD_RATE * 16)); + + p0.h = hi(UART_DLL); + p0.l = lo(UART_DLL); + r0 = 0xFF(Z); + r0 = R1 & R0; + w[p0] = r0.L; + ssync; + + p0.h = hi(UART_DLH); + p0.l = lo(UART_DLH); + r1 >>= 8 ; + w[p0] = r1.L; + ssync; + + p0.h = hi(UART_GCTL); + p0.l = lo(UART_GCTL); + r0 = 0x0(Z); + w[p0] = r0.L; /* To enable UART clock */ + ssync; + + p0.h = hi(UART_LCR); + p0.l = lo(UART_LCR); + r0 = 0x03(Z); + w[p0] = r0.L; /* To Turn on UART */ + ssync; + + p0.h = hi(UART_GCTL); + p0.l = lo(UART_GCTL); + r0 = 0x01(Z); + w[p0] = r0.L; /* To Turn on UART Clocks */ + ssync; + + P0.h = hi(UART_THR); + P0.l = lo(UART_THR); + P1.h = hi(UART_LSR); + P1.l = lo(UART_LSR); + + R0.L = 'K'; + call .Lwait_char; + R0.L='e'; + call .Lwait_char; + R0.L='r'; + call .Lwait_char; + R0.L='n' + call .Lwait_char; + R0.L='e' + call .Lwait_char; + R0.L='l'; + call .Lwait_char; + R0.L=' '; + call .Lwait_char; + R0.L='c'; + call .Lwait_char; + R0.L='r'; + call .Lwait_char; + R0.L='a'; + call .Lwait_char; + R0.L='s'; + call .Lwait_char; + R0.L='h'; + call .Lwait_char; + R0.L='\r'; + call .Lwait_char; + R0.L='\n'; + call .Lwait_char; + + R0.L='S'; + call .Lwait_char; + R0.L='E'; + call .Lwait_char; + R0.L='Q' + call .Lwait_char; + R0.L='S' + call .Lwait_char; + R0.L='T'; + call .Lwait_char; + R0.L='A'; + call .Lwait_char; + R0.L='T'; + call .Lwait_char; + R0.L='='; + call .Lwait_char; + R2 = SEQSTAT; + call .Ldump_reg; + + R0.L=' '; + call .Lwait_char; + R0.L='R'; + call .Lwait_char; + R0.L='E' + call .Lwait_char; + R0.L='T' + call .Lwait_char; + R0.L='X'; + call .Lwait_char; + R0.L='='; + call .Lwait_char; + R2 = RETX; + call .Ldump_reg; + + R0.L='\r'; + call .Lwait_char; + R0.L='\n'; + call .Lwait_char; + +.Ldebug_kernel_start_trap_done: + JUMP .Ldebug_kernel_start_trap_done; +.Ldump_reg: + R3 = 32; + R4 = 0x0F; + R5 = ':'; /* one past 9 */ + +.Ldump_reg2: + R0 = R2; + R3 += -4; + R0 >>>= R3; + R0 = R0 & R4; + R0 += 0x30; + CC = R0 <= R5; + if CC JUMP .Ldump_reg1; + R0 += 7; + +.Ldump_reg1: + R1.l = W[P1]; + CC = BITTST(R1, 5); + if !CC JUMP .Ldump_reg1; + W[P0] = r0; + + CC = R3 == 0; + if !CC JUMP .Ldump_reg2 + RTS; + +.Lwait_char: + R1.l = W[P1]; + CC = BITTST(R1, 5); + if !CC JUMP .Lwait_char; + W[P0] = r0; + RTS; + +#endif /* CONFIG_DEBUG_KERNEL_START */ + +.data + +/* + * Set up the usable of RAM stuff. Size of RAM is determined then + * an initial stack set up at the end. + */ + +.align 4 +__rambase: +.long 0 +__ramstart: +.long 0 +__ramend: +.long 0 diff --git a/arch/blackfin/mach-bf533/ints-priority.c b/arch/blackfin/mach-bf533/ints-priority.c new file mode 100644 index 000000000000..36a693345204 --- /dev/null +++ b/arch/blackfin/mach-bf533/ints-priority.c @@ -0,0 +1,65 @@ +/* + * File: arch/blackfin/mach-bf533/ints-priority.c + * Based on: + * Author: Michael Hennerich + * + * Created: ? + * Description: Set up the interupt priorities + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +void program_IAR(void) +{ + /* Program the IAR0 Register with the configured priority */ + bfin_write_SIC_IAR0(((CONFIG_PLLWAKE_ERROR - 7) << PLLWAKE_ERROR_POS) | + ((CONFIG_DMA_ERROR - 7) << DMA_ERROR_POS) | + ((CONFIG_PPI_ERROR - 7) << PPI_ERROR_POS) | + ((CONFIG_SPORT0_ERROR - 7) << SPORT0_ERROR_POS) | + ((CONFIG_SPI_ERROR - 7) << SPI_ERROR_POS) | + ((CONFIG_SPORT1_ERROR - 7) << SPORT1_ERROR_POS) | + ((CONFIG_UART_ERROR - 7) << UART_ERROR_POS) | + ((CONFIG_RTC_ERROR - 7) << RTC_ERROR_POS)); + + bfin_write_SIC_IAR1(((CONFIG_DMA0_PPI - 7) << DMA0_PPI_POS) | + ((CONFIG_DMA1_SPORT0RX - 7) << DMA1_SPORT0RX_POS) | + ((CONFIG_DMA2_SPORT0TX - 7) << DMA2_SPORT0TX_POS) | + ((CONFIG_DMA3_SPORT1RX - 7) << DMA3_SPORT1RX_POS) | + ((CONFIG_DMA4_SPORT1TX - 7) << DMA4_SPORT1TX_POS) | + ((CONFIG_DMA5_SPI - 7) << DMA5_SPI_POS) | + ((CONFIG_DMA6_UARTRX - 7) << DMA6_UARTRX_POS) | + ((CONFIG_DMA7_UARTTX - 7) << DMA7_UARTTX_POS)); + + bfin_write_SIC_IAR2(((CONFIG_TIMER0 - 7) << TIMER0_POS) | + ((CONFIG_TIMER1 - 7) << TIMER1_POS) | + ((CONFIG_TIMER2 - 7) << TIMER2_POS) | + ((CONFIG_PFA - 7) << PFA_POS) | + ((CONFIG_PFB - 7) << PFB_POS) | + ((CONFIG_MEMDMA0 - 7) << MEMDMA0_POS) | + ((CONFIG_MEMDMA1 - 7) << MEMDMA1_POS) | + ((CONFIG_WDTIMER - 7) << WDTIMER_POS)); + + SSYNC(); +} diff --git a/arch/blackfin/mach-bf537/Kconfig b/arch/blackfin/mach-bf537/Kconfig new file mode 100644 index 000000000000..cc9ae38a4dda --- /dev/null +++ b/arch/blackfin/mach-bf537/Kconfig @@ -0,0 +1,141 @@ +if (BF537 || BF534 || BF536) + +menu "BF537 Specific Configuration" + +comment "PORT F/G Selection" +choice + prompt "Select BF537/6/4 default GPIO PFx PORTx" + help + Quick Hack for BF537/6/4 default GPIO PFx PORTF. + +config BF537_PORT_F + bool "Select BF537/6/4 default GPIO PFx PORTF" + depends on (BF537 || BF536 || BF534) + help + Quick Hack for BF537/6/4 default GPIO PFx PORTF. + +config BF537_PORT_G + bool "Select BF537/6/4 default GPIO PFx PORTG" + depends on (BF537 || BF536 || BF534) + help + Quick Hack for BF537/6/4 default GPIO PFx PORTG. + +config BF537_PORT_H + bool "Select BF537/6/4 default GPIO PFx PORTH" + depends on (BF537 || BF536 || BF534) + help + Quick Hack for BF537/6/4 default GPIO PFx PORTH + Use only when Blackfin EMAC support is not required. + +endchoice + +comment "Interrupt Priority Assignment" +menu "Priority" + +config IRQ_PLL_WAKEUP + int "IRQ_PLL_WAKEUP" + default 7 +config IRQ_DMA_ERROR + int "IRQ_DMA_ERROR Generic" + default 7 +config IRQ_ERROR + int "IRQ_ERROR: CAN MAC SPORT0 SPORT1 SPI UART0 UART1" + default 7 +config IRQ_RTC + int "IRQ_RTC" + default 8 +config IRQ_PPI + int "IRQ_PPI" + default 8 +config IRQ_SPORT0_RX + int "IRQ_SPORT0_RX" + default 9 +config IRQ_SPORT0_TX + int "IRQ_SPORT0_TX" + default 9 +config IRQ_SPORT1_RX + int "IRQ_SPORT1_RX" + default 9 +config IRQ_SPORT1_TX + int "IRQ_SPORT1_TX" + default 9 +config IRQ_TWI + int "IRQ_TWI" + default 10 +config IRQ_SPI + int "IRQ_SPI" + default 10 +config IRQ_UART0_RX + int "IRQ_UART0_RX" + default 10 +config IRQ_UART0_TX + int "IRQ_UART0_TX" + default 10 +config IRQ_UART1_RX + int "IRQ_UART1_RX" + default 10 +config IRQ_UART1_TX + int "IRQ_UART1_TX" + default 10 +config IRQ_CAN_RX + int "IRQ_CAN_RX" + default 11 +config IRQ_CAN_TX + int "IRQ_CAN_TX" + default 11 +config IRQ_MAC_RX + int "IRQ_MAC_RX" + default 11 +config IRQ_MAC_TX + int "IRQ_MAC_TX" + default 11 +config IRQ_TMR0 + int "IRQ_TMR0" + default 12 +config IRQ_TMR1 + int "IRQ_TMR1" + default 12 +config IRQ_TMR2 + int "IRQ_TMR2" + default 12 +config IRQ_TMR3 + int "IRQ_TMR3" + default 12 +config IRQ_TMR4 + int "IRQ_TMR4" + default 12 +config IRQ_TMR5 + int "IRQ_TMR5" + default 12 +config IRQ_TMR6 + int "IRQ_TMR6" + default 12 +config IRQ_TMR7 + int "IRQ_TMR7" + default 12 +config IRQ_PROG_INTA + int "IRQ_PROG_INTA" + default 12 +config IRQ_PORTG_INTB + int "IRQ_PORTG_INTB" + default 12 +config IRQ_MEM_DMA0 + int "IRQ_MEM_DMA0" + default 13 +config IRQ_MEM_DMA1 + int "IRQ_MEM_DMA1" + default 13 +config IRQ_WATCH + int "IRQ_WATCH" + default 13 + + help + Enter the priority numbers between 7-13 ONLY. Others are Reserved. + This applies to all the above. It is not recommended to assign the + highest priority number 7 to UART or any other device. + +endmenu + +endmenu + +endif diff --git a/arch/blackfin/mach-bf537/Makefile b/arch/blackfin/mach-bf537/Makefile new file mode 100644 index 000000000000..f32d44215bb7 --- /dev/null +++ b/arch/blackfin/mach-bf537/Makefile @@ -0,0 +1,9 @@ +# +# arch/blackfin/mach-bf537/Makefile +# + +extra-y := head.o + +obj-y := ints-priority.o + +obj-$(CONFIG_CPU_FREQ) += cpu.o diff --git a/arch/blackfin/mach-bf537/boards/Makefile b/arch/blackfin/mach-bf537/boards/Makefile new file mode 100644 index 000000000000..23323cacc3aa --- /dev/null +++ b/arch/blackfin/mach-bf537/boards/Makefile @@ -0,0 +1,9 @@ +# +# arch/blackfin/mach-bf537/boards/Makefile +# + +obj-y += eth_mac.o +obj-$(CONFIG_GENERIC_BOARD) += generic_board.o +obj-$(CONFIG_BFIN537_STAMP) += stamp.o led.o +obj-$(CONFIG_BFIN537_BLUETECHNIX_CM) += cm_bf537.o +obj-$(CONFIG_PNAV10) += pnav10.o diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537.c b/arch/blackfin/mach-bf537/boards/cm_bf537.c new file mode 100644 index 000000000000..6a60618a78ec --- /dev/null +++ b/arch/blackfin/mach-bf537/boards/cm_bf537.c @@ -0,0 +1,364 @@ +/* + * File: arch/blackfin/mach-bf537/boards/cm_bf537.c + * Based on: arch/blackfin/mach-bf533/boards/ezkit.c + * Author: Aidan Williams + * + * Created: 2005 + * Description: Board description file + * + * Modified: + * Copyright 2005 National ICT Australia (NICTA) + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Name the Board for the /proc/cpuinfo + */ +char *bfin_board_name = "Bluetechnix CM BF537"; + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* all SPI peripherals info goes here */ + +#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) +static struct mtd_partition bfin_spi_flash_partitions[] = { + { + .name = "bootloader", + .size = 0x00020000, + .offset = 0, + .mask_flags = MTD_CAP_ROM + },{ + .name = "kernel", + .size = 0xe0000, + .offset = 0x20000 + },{ + .name = "file system", + .size = 0x700000, + .offset = 0x00100000, + } +}; + +static struct flash_platform_data bfin_spi_flash_data = { + .name = "m25p80", + .parts = bfin_spi_flash_partitions, + .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), + .type = "m25p64", +}; + +/* SPI flash chip (m25p64) */ +static struct bfin5xx_spi_chip spi_flash_chip_info = { + .enable_dma = 0, /* use dma transfer with this chip*/ + .bits_per_word = 8, +}; +#endif + +#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) +/* SPI ADC chip */ +static struct bfin5xx_spi_chip spi_adc_chip_info = { + .enable_dma = 1, /* use dma transfer with this chip*/ + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +static struct bfin5xx_spi_chip ad1836_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) +static struct bfin5xx_spi_chip ad9960_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) +static struct bfin5xx_spi_chip spi_mmc_chip_info = { + .enable_dma = 1, + .bits_per_word = 8, +}; +#endif + +static struct spi_board_info bfin_spi_board_info[] __initdata = { +#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) + { + /* the modalias must be the same as spi device driver name */ + .modalias = "m25p80", /* Name of spi_driver for this device */ + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ + .platform_data = &bfin_spi_flash_data, + .controller_data = &spi_flash_chip_info, + .mode = SPI_MODE_3, + }, +#endif + +#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) + { + .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ + .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. */ + .platform_data = NULL, /* No spi_driver specific config */ + .controller_data = &spi_adc_chip_info, + }, +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) + { + .modalias = "ad1836-spi", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, + .controller_data = &ad1836_spi_chip_info, + }, +#endif + +#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) + { + .modalias = "ad9960-spi", + .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 1, + .controller_data = &ad9960_spi_chip_info, + }, +#endif + +#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) + { + .modalias = "spi_mmc_dummy", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 7, + .platform_data = NULL, + .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, + { + .modalias = "spi_mmc", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = CONFIG_SPI_MMC_CS_CHAN, + .platform_data = NULL, + .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, +#endif +}; + +/* SPI controller data */ +static struct bfin5xx_spi_master spi_bfin_master_info = { + .num_chipselect = 8, + .enable_dma = 1, /* master has the ability to do dma transfer */ +}; + +static struct platform_device spi_bfin_master_device = { + .name = "bfin-spi-master", + .id = 1, /* Bus number */ + .dev = { + .platform_data = &spi_bfin_master_info, /* Passed to driver */ + }, +}; +#endif /* spi master and devices */ + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) +static struct platform_device rtc_device = { + .name = "rtc-bfin", + .id = -1, +}; +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +static struct resource smc91x_resources[] = { + { + .start = 0x20200300, + .end = 0x20200300 + 16, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PF14, + .end = IRQ_PF14, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) +static struct resource isp1362_hcd_resources[] = { + { + .start = 0x20308000, + .end = 0x20308000, + .flags = IORESOURCE_MEM, + },{ + .start = 0x20308004, + .end = 0x20308004, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PG15, + .end = IRQ_PG15, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct isp1362_platform_data isp1362_priv = { + .sel15Kres = 1, + .clknotstop = 0, + .oc_enable = 0, + .int_act_high = 0, + .int_edge_triggered = 0, + .remote_wakeup_connected = 0, + .no_power_switching = 1, + .power_switching_mode = 0, +}; + +static struct platform_device isp1362_hcd_device = { + .name = "isp1362-hcd", + .id = 0, + .dev = { + .platform_data = &isp1362_priv, + }, + .num_resources = ARRAY_SIZE(isp1362_hcd_resources), + .resource = isp1362_hcd_resources, +}; +#endif + +#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) +static struct resource net2272_bfin_resources[] = { + { + .start = 0x20200000, + .end = 0x20200000 + 0x100, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PF7, + .end = IRQ_PF7, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device net2272_bfin_device = { + .name = "net2272", + .id = -1, + .num_resources = ARRAY_SIZE(net2272_bfin_resources), + .resource = net2272_bfin_resources, +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +static struct resource bfin_uart_resources[] = { + { + .start = 0xFFC00400, + .end = 0xFFC004FF, + .flags = IORESOURCE_MEM, + },{ + .start = 0xFFC02000, + .end = 0xFFC020FF, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device bfin_uart_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart_resources), + .resource = bfin_uart_resources, +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +static struct platform_device bfin_sport0_uart_device = { + .name = "bfin-sport-uart", + .id = 0, +}; + +static struct platform_device bfin_sport1_uart_device = { + .name = "bfin-sport-uart", + .id = 1, +}; +#endif + +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +static struct platform_device bfin_mac_device = { + .name = "bfin_mac", +}; +#endif + +static struct platform_device *cm_bf537_devices[] __initdata = { +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) + &rtc_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) + &bfin_uart_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) + &bfin_sport0_uart_device, + &bfin_sport1_uart_device, +#endif + +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) + &isp1362_hcd_device, +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + &smc91x_device, +#endif + +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) + &bfin_mac_device, +#endif + +#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) + &net2272_bfin_device, +#endif + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + &spi_bfin_master_device, +#endif +}; + +static int __init cm_bf537_init(void) +{ + printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); + platform_add_devices(cm_bf537_devices, ARRAY_SIZE(cm_bf537_devices)); +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); +#endif + return 0; +} + +arch_initcall(cm_bf537_init); diff --git a/arch/blackfin/mach-bf537/boards/eth_mac.c b/arch/blackfin/mach-bf537/boards/eth_mac.c new file mode 100644 index 000000000000..e129a08d63de --- /dev/null +++ b/arch/blackfin/mach-bf537/boards/eth_mac.c @@ -0,0 +1,51 @@ +/* + * arch/blackfin/mach-bf537/board/eth_mac.c + * + * Copyright (C) 2007 Analog Devices, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include + +#if defined(CONFIG_GENERIC_BOARD) \ + || defined(CONFIG_BFIN537_STAMP) + +/* + * Currently the MAC address is saved in Flash by U-Boot + */ +#define FLASH_MAC 0x203f0000 + +void get_bf537_ether_addr(char *addr) +{ + unsigned int flash_mac = (unsigned int) FLASH_MAC; + *(u32 *)(&(addr[0])) = bfin_read32(flash_mac); + flash_mac += 4; + *(u16 *)(&(addr[4])) = bfin_read16(flash_mac); +} + +#else + +/* + * Provide MAC address function for other specific board setting + */ +void get_bf537_ether_addr(char *addr) +{ + printk(KERN_WARNING "%s: No valid Ethernet MAC address found\n",__FILE__); +} + +#endif + +EXPORT_SYMBOL(get_bf537_ether_addr); diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c new file mode 100644 index 000000000000..9019c0edbe7c --- /dev/null +++ b/arch/blackfin/mach-bf537/boards/generic_board.c @@ -0,0 +1,445 @@ +/* + * File: arch/blackfin/mach-bf537/boards/generic_board.c + * Based on: arch/blackfin/mach-bf533/boards/ezkit.c + * Author: Aidan Williams + * + * Created: + * Description: + * + * Modified: + * Copyright 2005 National ICT Australia (NICTA) + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Name the Board for the /proc/cpuinfo + */ +char *bfin_board_name = "UNKNOWN BOARD"; + +/* + * Driver needs to know address, irq and flag pin. + */ + +#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) +static struct resource bfin_pcmcia_cf_resources[] = { + { + .start = 0x20310000, /* IO PORT */ + .end = 0x20312000, + .flags = IORESOURCE_MEM, + },{ + .start = 0x20311000, /* Attribute Memeory */ + .end = 0x20311FFF, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PROG_INTA, + .end = IRQ_PROG_INTA, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + },{ + .start = IRQ_PF4, + .end = IRQ_PF4, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + },{ + .start = 6, /* Card Detect PF6 */ + .end = 6, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_pcmcia_cf_device = { + .name = "bfin_cf_pcmcia", + .id = -1, + .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources), + .resource = bfin_pcmcia_cf_resources, +}; +#endif + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) +static struct platform_device rtc_device = { + .name = "rtc-bfin", + .id = -1, +}; +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +static struct resource smc91x_resources[] = { + { + .name = "smc91x-regs", + .start = 0x20300300, + .end = 0x20300300 + 16, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PROG_INTB, + .end = IRQ_PROG_INTB, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + },{ + /* + * denotes the flag pin and is used directly if + * CONFIG_IRQCHIP_DEMUX_GPIO is defined. + */ + .start = IRQ_PF7, + .end = IRQ_PF7, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) +static struct resource sl811_hcd_resources[] = { + { + .start = 0x20340000, + .end = 0x20340000, + .flags = IORESOURCE_MEM, + },{ + .start = 0x20340004, + .end = 0x20340004, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PROG_INTA, + .end = IRQ_PROG_INTA, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + },{ + .start = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO, + .end = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) +void sl811_port_power(struct device *dev, int is_on) +{ + unsigned short mask = (1< +#include + +/* All functions in this file save the registers they uses. + So there is no need to save any registers before calling them. */ + + .text; + +/* Initialize LEDs. */ + +ENTRY(_led_init) + LINK 12; + [--SP] = P0; + [--SP] = R0; + [--SP] = R1; + [--SP] = R2; + R1 = PF6|PF7|PF8|PF9|PF10|PF11 (Z); + R2 = ~R1; + + P0.H = hi(PORTF_FER); + P0.L = lo(PORTF_FER); + R0 = W[P0](Z); + SSYNC; + R0 = R0 & R2; + W[P0] = R0.L; + SSYNC; + + P0.H = hi(PORTFIO_DIR); + P0.L = lo(PORTFIO_DIR); + R0 = W[P0](Z); + SSYNC; + R0 = R0 | R1; + W[P0] = R0.L; + SSYNC; + + P0.H = hi(PORTFIO_INEN); + P0.L = lo(PORTFIO_INEN); + R0 = W[P0](Z); + SSYNC; + R0 = R0 & R2; + W[P0] = R0.L; + SSYNC; + + R2 = [SP++]; + R1 = [SP++]; + R0 = [SP++]; + P0 = [SP++]; + UNLINK; + RTS; + .size _led_init, .-_led_init + +/* Set one LED on. Leave other LEDs unchanged. + It expects the LED number passed through R0. */ + +ENTRY(_led_on) + LINK 12; + [--SP] = P0; + [--SP] = R1; + CALL _led_init; + R1 = 1; + R0 += 5; + R1 <<= R0; + P0.H = hi(PORTFIO); + P0.L = lo(PORTFIO); + R0 = W[P0](Z); + SSYNC; + R0 = R0 | R1; + W[P0] = R0.L; + SSYNC; + R1 = [SP++]; + P0 = [SP++]; + UNLINK; + RTS; + .size _led_on, .-_led_on + +/* Set one LED off. Leave other LEDs unchanged. */ + +ENTRY(_led_off) + LINK 12; + [--SP] = P0; + [--SP] = R1; + CALL _led_init; + R1 = 1; + R0 += 5; + R1 <<= R0; + R1 = ~R1; + P0.H = hi(PORTFIO); + P0.L = lo(PORTFIO); + R0 = W[P0](Z); + SSYNC; + R0 = R0 & R1; + W[P0] = R0.L; + SSYNC; + R1 = [SP++]; + P0 = [SP++]; + UNLINK; + RTS; + .size _led_off, .-_led_off + +/* Toggle one LED. Leave other LEDs unchanged. */ + +ENTRY(_led_toggle) + LINK 12; + [--SP] = P0; + [--SP] = R1; + CALL _led_init; + R1 = 1; + R0 += 5; + R1 <<= R0; + P0.H = hi(PORTFIO); + P0.L = lo(PORTFIO); + R0 = W[P0](Z); + SSYNC; + R0 = R0 ^ R1; + W[P0] = R0.L; + SSYNC; + R1 = [SP++]; + P0 = [SP++]; + UNLINK; + RTS; + .size _led_toggle, .-_led_toggle + +/* Display the number using LEDs in binary format. */ + +ENTRY(_led_disp_num) + LINK 12; + [--SP] = P0; + [--SP] = R1; + [--SP] = R2; + CALL _led_init; + R1 = 0x3f(X); + R0 = R0 & R1; + R2 = 6(X); + R0 <<= R2; + R1 <<= R2; + P0.H = hi(PORTFIO); + P0.L = lo(PORTFIO); + R2 = W[P0](Z); + SSYNC; + R1 = ~R1; + R2 = R2 & R1; + R2 = R2 | R0; + W[P0] = R2.L; + SSYNC; + R2 = [SP++]; + R1 = [SP++]; + P0 = [SP++]; + UNLINK; + RTS; + .size _led_disp_num, .-_led_disp_num + +/* Toggle the number using LEDs in binary format. */ + +ENTRY(_led_toggle_num) + LINK 12; + [--SP] = P0; + [--SP] = R1; + [--SP] = R2; + CALL _led_init; + R1 = 0x3f(X); + R0 = R0 & R1; + R1 = 6(X); + R0 <<= R1; + P0.H = hi(PORTFIO); + P0.L = lo(PORTFIO); + R1 = W[P0](Z); + SSYNC; + R1 = R1 ^ R0; + W[P0] = R1.L; + SSYNC; + R2 = [SP++]; + R1 = [SP++]; + P0 = [SP++]; + UNLINK; + RTS; + .size _led_toggle_num, .-_led_toggle_num + diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c new file mode 100644 index 000000000000..40d3a1b70ee7 --- /dev/null +++ b/arch/blackfin/mach-bf537/boards/pnav10.c @@ -0,0 +1,523 @@ +/* + * File: arch/blackfin/mach-bf537/boards/stamp.c + * Based on: arch/blackfin/mach-bf533/boards/ezkit.c + * Author: Aidan Williams + * + * Created: + * Description: + * + * Modified: + * Copyright 2005 National ICT Australia (NICTA) + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) +#include +#endif +#include +#include +#include + +#include + +/* + * Name the Board for the /proc/cpuinfo + */ +char *bfin_board_name = "PNAV-1.0"; + +/* + * Driver needs to know address, irq and flag pin. + */ + +#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) +static struct resource bfin_pcmcia_cf_resources[] = { + { + .start = 0x20310000, /* IO PORT */ + .end = 0x20312000, + .flags = IORESOURCE_MEM, + },{ + .start = 0x20311000, /* Attribute Memeory */ + .end = 0x20311FFF, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PF4, + .end = IRQ_PF4, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + },{ + .start = 6, /* Card Detect PF6 */ + .end = 6, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_pcmcia_cf_device = { + .name = "bfin_cf_pcmcia", + .id = -1, + .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources), + .resource = bfin_pcmcia_cf_resources, +}; +#endif + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) +static struct platform_device rtc_device = { + .name = "rtc-bfin", + .id = -1, +}; +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +static struct resource smc91x_resources[] = { + { + .name = "smc91x-regs", + .start = 0x20300300, + .end = 0x20300300 + 16, + .flags = IORESOURCE_MEM, + },{ + + .start = IRQ_PF7, + .end = IRQ_PF7, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) +static struct resource sl811_hcd_resources[] = { + { + .start = 0x20340000, + .end = 0x20340000, + .flags = IORESOURCE_MEM, + },{ + .start = 0x20340004, + .end = 0x20340004, + .flags = IORESOURCE_MEM, + },{ + .start = CONFIG_USB_SL811_BFIN_IRQ, + .end = CONFIG_USB_SL811_BFIN_IRQ, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) +void sl811_port_power(struct device *dev, int is_on) +{ + unsigned short mask = (1 << CONFIG_USB_SL811_BFIN_GPIO_VBUS); + + bfin_write_PORT_FER(bfin_read_PORT_FER() & ~mask); + bfin_write_FIO_DIR(bfin_read_FIO_DIR() | mask); + + if (is_on) + bfin_write_FIO_FLAG_S(mask); + else + bfin_write_FIO_FLAG_C(mask); +} +#endif + +static struct sl811_platform_data sl811_priv = { + .potpg = 10, + .power = 250, /* == 500mA */ +#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) + .port_power = &sl811_port_power, +#endif +}; + +static struct platform_device sl811_hcd_device = { + .name = "sl811-hcd", + .id = 0, + .dev = { + .platform_data = &sl811_priv, + }, + .num_resources = ARRAY_SIZE(sl811_hcd_resources), + .resource = sl811_hcd_resources, +}; +#endif + +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) +static struct resource isp1362_hcd_resources[] = { + { + .start = 0x20360000, + .end = 0x20360000, + .flags = IORESOURCE_MEM, + },{ + .start = 0x20360004, + .end = 0x20360004, + .flags = IORESOURCE_MEM, + },{ + .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, + .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct isp1362_platform_data isp1362_priv = { + .sel15Kres = 1, + .clknotstop = 0, + .oc_enable = 0, + .int_act_high = 0, + .int_edge_triggered = 0, + .remote_wakeup_connected = 0, + .no_power_switching = 1, + .power_switching_mode = 0, +}; + +static struct platform_device isp1362_hcd_device = { + .name = "isp1362-hcd", + .id = 0, + .dev = { + .platform_data = &isp1362_priv, + }, + .num_resources = ARRAY_SIZE(isp1362_hcd_resources), + .resource = isp1362_hcd_resources, +}; +#endif + +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +static struct platform_device bfin_mac_device = { + .name = "bfin_mac", +}; +#endif + +#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) +static struct resource net2272_bfin_resources[] = { + { + .start = 0x20300000, + .end = 0x20300000 + 0x100, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PF7, + .end = IRQ_PF7, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device net2272_bfin_device = { + .name = "net2272", + .id = -1, + .num_resources = ARRAY_SIZE(net2272_bfin_resources), + .resource = net2272_bfin_resources, +}; +#endif + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* all SPI peripherals info goes here */ + +#if defined(CONFIG_MTD_M25P80) \ + || defined(CONFIG_MTD_M25P80_MODULE) +static struct mtd_partition bfin_spi_flash_partitions[] = { + { + .name = "bootloader", + .size = 0x00020000, + .offset = 0, + .mask_flags = MTD_CAP_ROM + },{ + .name = "kernel", + .size = 0xe0000, + .offset = 0x20000 + },{ + .name = "file system", + .size = 0x700000, + .offset = 0x00100000, + } +}; + +static struct flash_platform_data bfin_spi_flash_data = { + .name = "m25p80", + .parts = bfin_spi_flash_partitions, + .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), + .type = "m25p64", +}; + +/* SPI flash chip (m25p64) */ +static struct bfin5xx_spi_chip spi_flash_chip_info = { + .enable_dma = 0, /* use dma transfer with this chip*/ + .bits_per_word = 8, +}; +#endif + +#if defined(CONFIG_SPI_ADC_BF533) \ + || defined(CONFIG_SPI_ADC_BF533_MODULE) +/* SPI ADC chip */ +static struct bfin5xx_spi_chip spi_adc_chip_info = { + .enable_dma = 1, /* use dma transfer with this chip*/ + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) \ + || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +static struct bfin5xx_spi_chip ad1836_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) +static struct bfin5xx_spi_chip ad9960_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) +static struct bfin5xx_spi_chip spi_mmc_chip_info = { + .enable_dma = 1, + .bits_per_word = 8, +}; +#endif + +#if defined(CONFIG_PBX) +static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { + .ctl_reg = 0x4, /* send zero */ + .enable_dma = 0, + .bits_per_word = 8, + .cs_change_per_word = 1, +}; +#endif + + +#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) +static struct bfin5xx_spi_chip spi_ad7877_chip_info = { + .cs_change_per_word = 1, + .enable_dma = 0, + .bits_per_word = 16, +}; + +static const struct ad7877_platform_data bfin_ad7877_ts_info = { + .model = 7877, + .vref_delay_usecs = 50, /* internal, no capacitor */ + .x_plate_ohms = 419, + .y_plate_ohms = 486, + .pressure_max = 1000, + .pressure_min = 0, + .stopacq_polarity = 1, + .first_conversion_delay = 3, + .acquisition_time = 1, + .averaging = 1, + .pen_down_acc_interval = 1, +}; +#endif + +static struct spi_board_info bfin_spi_board_info[] __initdata = { +#if defined(CONFIG_MTD_M25P80) \ + || defined(CONFIG_MTD_M25P80_MODULE) + { + /* the modalias must be the same as spi device driver name */ + .modalias = "m25p80", /* Name of spi_driver for this device */ + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ + .platform_data = &bfin_spi_flash_data, + .controller_data = &spi_flash_chip_info, + .mode = SPI_MODE_3, + }, +#endif + +#if defined(CONFIG_SPI_ADC_BF533) \ + || defined(CONFIG_SPI_ADC_BF533_MODULE) + { + .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ + .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. */ + .platform_data = NULL, /* No spi_driver specific config */ + .controller_data = &spi_adc_chip_info, + }, +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) \ + || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) + { + .modalias = "ad1836-spi", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, + .controller_data = &ad1836_spi_chip_info, + }, +#endif +#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) + { + .modalias = "ad9960-spi", + .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 1, + .controller_data = &ad9960_spi_chip_info, + }, +#endif +#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) + { + .modalias = "spi_mmc_dummy", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 7, + .platform_data = NULL, + .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, + { + .modalias = "spi_mmc", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = CONFIG_SPI_MMC_CS_CHAN, + .platform_data = NULL, + .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, +#endif +#if defined(CONFIG_PBX) + { + .modalias = "fxs-spi", + .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 3, + .controller_data= &spi_si3xxx_chip_info, + .mode = SPI_MODE_3, + }, + { + .modalias = "fxo-spi", + .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 2, + .controller_data= &spi_si3xxx_chip_info, + .mode = SPI_MODE_3, + }, +#endif +#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) +{ + .modalias = "ad7877", + .platform_data = &bfin_ad7877_ts_info, + .irq = IRQ_PF2, + .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 5, + .controller_data = &spi_ad7877_chip_info, +}, +#endif + +}; + +/* SPI controller data */ +static struct bfin5xx_spi_master spi_bfin_master_info = { + .num_chipselect = 8, + .enable_dma = 1, /* master has the ability to do dma transfer */ +}; + +static struct platform_device spi_bfin_master_device = { + .name = "bfin-spi-master", + .id = 1, /* Bus number */ + .dev = { + .platform_data = &spi_bfin_master_info, /* Passed to driver */ + }, +}; +#endif /* spi master and devices */ + +#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) +static struct platform_device bfin_fb_device = { + .name = "bf537-fb", +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +static struct resource bfin_uart_resources[] = { + { + .start = 0xFFC00400, + .end = 0xFFC004FF, + .flags = IORESOURCE_MEM, + },{ + .start = 0xFFC02000, + .end = 0xFFC020FF, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device bfin_uart_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart_resources), + .resource = bfin_uart_resources, +}; +#endif + + +static struct platform_device *stamp_devices[] __initdata = { +#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) + &bfin_pcmcia_cf_device, +#endif + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) + &rtc_device, +#endif + +#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) + &sl811_hcd_device, +#endif + +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) + &isp1362_hcd_device, +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + &smc91x_device, +#endif + +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) + &bfin_mac_device, +#endif + +#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) + &net2272_bfin_device, +#endif + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + &spi_bfin_master_device, +#endif + +#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) + &bfin_fb_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) + &bfin_uart_device, +#endif +}; + +static int __init stamp_init(void) +{ + printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); + platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + spi_register_board_info(bfin_spi_board_info, + ARRAY_SIZE(bfin_spi_board_info)); +#endif + return 0; +} + +arch_initcall(stamp_init); diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c new file mode 100644 index 000000000000..ba2f875a7f7d --- /dev/null +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -0,0 +1,615 @@ +/* + * File: arch/blackfin/mach-bf537/boards/stamp.c + * Based on: arch/blackfin/mach-bf533/boards/ezkit.c + * Author: Aidan Williams + * + * Created: + * Description: + * + * Modified: + * Copyright 2005 National ICT Australia (NICTA) + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) +#include +#endif +#include +#include +#include +#include +#include + +#include + +/* + * Name the Board for the /proc/cpuinfo + */ +char *bfin_board_name = "ADDS-BF537-STAMP"; + +/* + * Driver needs to know address, irq and flag pin. + */ + +#define ISP1761_BASE 0x203C0000 +#define ISP1761_IRQ IRQ_PF7 + +#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) +static struct resource bfin_isp1761_resources[] = { + [0] = { + .name = "isp1761-regs", + .start = ISP1761_BASE + 0x00000000, + .end = ISP1761_BASE + 0x000fffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = ISP1761_IRQ, + .end = ISP1761_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_isp1761_device = { + .name = "isp1761", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_isp1761_resources), + .resource = bfin_isp1761_resources, +}; + +static struct platform_device *bfin_isp1761_devices[] = { + &bfin_isp1761_device, +}; + +int __init bfin_isp1761_init(void) +{ + unsigned int num_devices=ARRAY_SIZE(bfin_isp1761_devices); + + printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); + set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING); + + return platform_add_devices(bfin_isp1761_devices, num_devices); +} + +void __exit bfin_isp1761_exit(void) +{ + platform_device_unregister(&bfin_isp1761_device); +} + +arch_initcall(bfin_isp1761_init); +#endif + +#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) +static struct resource bfin_pcmcia_cf_resources[] = { + { + .start = 0x20310000, /* IO PORT */ + .end = 0x20312000, + .flags = IORESOURCE_MEM, + },{ + .start = 0x20311000, /* Attribute Memeory */ + .end = 0x20311FFF, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PF4, + .end = IRQ_PF4, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + },{ + .start = 6, /* Card Detect PF6 */ + .end = 6, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_pcmcia_cf_device = { + .name = "bfin_cf_pcmcia", + .id = -1, + .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources), + .resource = bfin_pcmcia_cf_resources, +}; +#endif + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) +static struct platform_device rtc_device = { + .name = "rtc-bfin", + .id = -1, +}; +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +static struct resource smc91x_resources[] = { + { + .name = "smc91x-regs", + .start = 0x20300300, + .end = 0x20300300 + 16, + .flags = IORESOURCE_MEM, + },{ + + .start = IRQ_PF7, + .end = IRQ_PF7, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) +static struct resource sl811_hcd_resources[] = { + { + .start = 0x20340000, + .end = 0x20340000, + .flags = IORESOURCE_MEM, + },{ + .start = 0x20340004, + .end = 0x20340004, + .flags = IORESOURCE_MEM, + },{ + .start = CONFIG_USB_SL811_BFIN_IRQ, + .end = CONFIG_USB_SL811_BFIN_IRQ, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) +void sl811_port_power(struct device *dev, int is_on) +{ + unsigned short mask = (1 << CONFIG_USB_SL811_BFIN_GPIO_VBUS); + + bfin_write_PORT_FER(bfin_read_PORT_FER() & ~mask); + bfin_write_FIO_DIR(bfin_read_FIO_DIR() | mask); + + if (is_on) + bfin_write_FIO_FLAG_S(mask); + else + bfin_write_FIO_FLAG_C(mask); +} +#endif + +static struct sl811_platform_data sl811_priv = { + .potpg = 10, + .power = 250, /* == 500mA */ +#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) + .port_power = &sl811_port_power, +#endif +}; + +static struct platform_device sl811_hcd_device = { + .name = "sl811-hcd", + .id = 0, + .dev = { + .platform_data = &sl811_priv, + }, + .num_resources = ARRAY_SIZE(sl811_hcd_resources), + .resource = sl811_hcd_resources, +}; +#endif + +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) +static struct resource isp1362_hcd_resources[] = { + { + .start = 0x20360000, + .end = 0x20360000, + .flags = IORESOURCE_MEM, + },{ + .start = 0x20360004, + .end = 0x20360004, + .flags = IORESOURCE_MEM, + },{ + .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, + .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct isp1362_platform_data isp1362_priv = { + .sel15Kres = 1, + .clknotstop = 0, + .oc_enable = 0, + .int_act_high = 0, + .int_edge_triggered = 0, + .remote_wakeup_connected = 0, + .no_power_switching = 1, + .power_switching_mode = 0, +}; + +static struct platform_device isp1362_hcd_device = { + .name = "isp1362-hcd", + .id = 0, + .dev = { + .platform_data = &isp1362_priv, + }, + .num_resources = ARRAY_SIZE(isp1362_hcd_resources), + .resource = isp1362_hcd_resources, +}; +#endif + +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +static struct platform_device bfin_mac_device = { + .name = "bfin_mac", +}; +#endif + +#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) +static struct resource net2272_bfin_resources[] = { + { + .start = 0x20300000, + .end = 0x20300000 + 0x100, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PF7, + .end = IRQ_PF7, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device net2272_bfin_device = { + .name = "net2272", + .id = -1, + .num_resources = ARRAY_SIZE(net2272_bfin_resources), + .resource = net2272_bfin_resources, +}; +#endif + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* all SPI peripherals info goes here */ + +#if defined(CONFIG_MTD_M25P80) \ + || defined(CONFIG_MTD_M25P80_MODULE) +static struct mtd_partition bfin_spi_flash_partitions[] = { + { + .name = "bootloader", + .size = 0x00020000, + .offset = 0, + .mask_flags = MTD_CAP_ROM + },{ + .name = "kernel", + .size = 0xe0000, + .offset = 0x20000 + },{ + .name = "file system", + .size = 0x700000, + .offset = 0x00100000, + } +}; + +static struct flash_platform_data bfin_spi_flash_data = { + .name = "m25p80", + .parts = bfin_spi_flash_partitions, + .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), + .type = "m25p64", +}; + +/* SPI flash chip (m25p64) */ +static struct bfin5xx_spi_chip spi_flash_chip_info = { + .enable_dma = 0, /* use dma transfer with this chip*/ + .bits_per_word = 8, +}; +#endif + +#if defined(CONFIG_SPI_ADC_BF533) \ + || defined(CONFIG_SPI_ADC_BF533_MODULE) +/* SPI ADC chip */ +static struct bfin5xx_spi_chip spi_adc_chip_info = { + .enable_dma = 1, /* use dma transfer with this chip*/ + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) \ + || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +static struct bfin5xx_spi_chip ad1836_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) +static struct bfin5xx_spi_chip ad9960_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) +static struct bfin5xx_spi_chip spi_mmc_chip_info = { + .enable_dma = 1, + .bits_per_word = 8, +}; +#endif + +#if defined(CONFIG_PBX) +static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { + .ctl_reg = 0x4, /* send zero */ + .enable_dma = 0, + .bits_per_word = 8, + .cs_change_per_word = 1, +}; +#endif + +#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) +static struct bfin5xx_spi_chip ad5304_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) +static struct bfin5xx_spi_chip spi_ad7877_chip_info = { +// .cs_change_per_word = 1, + .enable_dma = 0, + .bits_per_word = 16, +}; + +static const struct ad7877_platform_data bfin_ad7877_ts_info = { + .model = 7877, + .vref_delay_usecs = 50, /* internal, no capacitor */ + .x_plate_ohms = 419, + .y_plate_ohms = 486, + .pressure_max = 1000, + .pressure_min = 0, + .stopacq_polarity = 1, + .first_conversion_delay = 3, + .acquisition_time = 1, + .averaging = 1, + .pen_down_acc_interval = 1, +}; +#endif + +static struct spi_board_info bfin_spi_board_info[] __initdata = { +#if defined(CONFIG_MTD_M25P80) \ + || defined(CONFIG_MTD_M25P80_MODULE) + { + /* the modalias must be the same as spi device driver name */ + .modalias = "m25p80", /* Name of spi_driver for this device */ + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ + .platform_data = &bfin_spi_flash_data, + .controller_data = &spi_flash_chip_info, + .mode = SPI_MODE_3, + }, +#endif + +#if defined(CONFIG_SPI_ADC_BF533) \ + || defined(CONFIG_SPI_ADC_BF533_MODULE) + { + .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ + .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. */ + .platform_data = NULL, /* No spi_driver specific config */ + .controller_data = &spi_adc_chip_info, + }, +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) \ + || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) + { + .modalias = "ad1836-spi", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, + .controller_data = &ad1836_spi_chip_info, + }, +#endif +#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) + { + .modalias = "ad9960-spi", + .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 1, + .controller_data = &ad9960_spi_chip_info, + }, +#endif +#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) + { + .modalias = "spi_mmc_dummy", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 0, + .platform_data = NULL, + .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, + { + .modalias = "spi_mmc", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = CONFIG_SPI_MMC_CS_CHAN, + .platform_data = NULL, + .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, +#endif +#if defined(CONFIG_PBX) + { + .modalias = "fxs-spi", + .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 3, + .controller_data= &spi_si3xxx_chip_info, + .mode = SPI_MODE_3, + }, + { + .modalias = "fxo-spi", + .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 2, + .controller_data= &spi_si3xxx_chip_info, + .mode = SPI_MODE_3, + }, +#endif +#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) + { + .modalias = "ad5304_spi", + .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 2, + .platform_data = NULL, + .controller_data = &ad5304_chip_info, + .mode = SPI_MODE_2, + }, +#endif +#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) + { + .modalias = "ad7877", + .platform_data = &bfin_ad7877_ts_info, + .irq = IRQ_PF6, + .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 1, + .controller_data = &spi_ad7877_chip_info, + }, +#endif +}; + +/* SPI controller data */ +static struct bfin5xx_spi_master spi_bfin_master_info = { + .num_chipselect = 8, + .enable_dma = 1, /* master has the ability to do dma transfer */ +}; + +static struct platform_device spi_bfin_master_device = { + .name = "bfin-spi-master", + .id = 1, /* Bus number */ + .dev = { + .platform_data = &spi_bfin_master_info, /* Passed to driver */ + }, +}; +#endif /* spi master and devices */ + +#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) +static struct platform_device bfin_fb_device = { + .name = "bf537-fb", +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +static struct resource bfin_uart_resources[] = { + { + .start = 0xFFC00400, + .end = 0xFFC004FF, + .flags = IORESOURCE_MEM, + },{ + .start = 0xFFC02000, + .end = 0xFFC020FF, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device bfin_uart_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart_resources), + .resource = bfin_uart_resources, +}; +#endif + +#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static struct platform_device i2c_bfin_twi_device = { + .name = "i2c-bfin-twi", + .id = 0, +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +static struct platform_device bfin_sport0_uart_device = { + .name = "bfin-sport-uart", + .id = 0, +}; + +static struct platform_device bfin_sport1_uart_device = { + .name = "bfin-sport-uart", + .id = 1, +}; +#endif + +static struct platform_device *stamp_devices[] __initdata = { +#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) + &bfin_pcmcia_cf_device, +#endif + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) + &rtc_device, +#endif + +#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) + &sl811_hcd_device, +#endif + +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) + &isp1362_hcd_device, +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + &smc91x_device, +#endif + +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) + &bfin_mac_device, +#endif + +#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) + &net2272_bfin_device, +#endif + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + &spi_bfin_master_device, +#endif + +#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) + &bfin_fb_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) + &bfin_uart_device, +#endif + +#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) + &i2c_bfin_twi_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) + &bfin_sport0_uart_device, + &bfin_sport1_uart_device, +#endif +}; + +static int __init stamp_init(void) +{ + printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); + platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + spi_register_board_info(bfin_spi_board_info, + ARRAY_SIZE(bfin_spi_board_info)); +#endif + return 0; +} + +arch_initcall(stamp_init); diff --git a/arch/blackfin/mach-bf537/cpu.c b/arch/blackfin/mach-bf537/cpu.c new file mode 100644 index 000000000000..2d83b7e35469 --- /dev/null +++ b/arch/blackfin/mach-bf537/cpu.c @@ -0,0 +1,161 @@ +/* + * File: arch/blackfin/mach-bf537/cpu.c + * Based on: + * Author: michael.kang@analog.com + * + * Created: + * Description: clock scaling for the bf537 + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +/* CONFIG_CLKIN_HZ=11059200 */ +#define VCO5 (CONFIG_CLKIN_HZ*45) /*497664000 */ +#define VCO4 (CONFIG_CLKIN_HZ*36) /*398131200 */ +#define VCO3 (CONFIG_CLKIN_HZ*27) /*298598400 */ +#define VCO2 (CONFIG_CLKIN_HZ*18) /*199065600 */ +#define VCO1 (CONFIG_CLKIN_HZ*9) /*99532800 */ +#define VCO(x) VCO##x + +#define FREQ(x) {VCO(x),VCO(x)/4},{VCO(x),VCO(x)/2},{VCO(x),VCO(x)} +/* frequency */ +static struct cpufreq_frequency_table bf537_freq_table[] = { + FREQ(1), + FREQ(3), + {VCO4, VCO4 / 2}, {VCO4, VCO4}, + FREQ(5), + {0, CPUFREQ_TABLE_END}, +}; + +/* + * dpmc_fops->ioctl() + * static int dpmc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) + */ +static int bf537_getfreq(unsigned int cpu) +{ + unsigned long cclk_mhz, vco_mhz; + + /* The driver only support single cpu */ + if (cpu == 0) + dpmc_fops.ioctl(NULL, NULL, IOCTL_GET_CORECLOCK, &cclk_mhz); + else + cclk_mhz = -1; + return cclk_mhz; +} + +static int bf537_target(struct cpufreq_policy *policy, + unsigned int target_freq, unsigned int relation) +{ + unsigned long cclk_mhz; + unsigned long vco_mhz; + unsigned long flags; + unsigned int index, vco_index; + int i; + + struct cpufreq_freqs freqs; + if (cpufreq_frequency_table_target + (policy, bf537_freq_table, target_freq, relation, &index)) + return -EINVAL; + cclk_mhz = bf537_freq_table[index].frequency; + vco_mhz = bf537_freq_table[index].index; + + dpmc_fops.ioctl(NULL, NULL, IOCTL_CHANGE_FREQUENCY, &vco_mhz); + freqs.old = bf537_getfreq(0); + freqs.new = cclk_mhz; + freqs.cpu = 0; + + pr_debug("cclk begin change to cclk %d,vco=%d,index=%d,target=%d,oldfreq=%d\n", + cclk_mhz, vco_mhz, index, target_freq, freqs.old); + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + local_irq_save(flags); + dpmc_fops.ioctl(NULL, NULL, IOCTL_SET_CCLK, &cclk_mhz); + local_irq_restore(flags); + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + vco_mhz = get_vco(); + cclk_mhz = get_cclk(); + return 0; +} + +/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on + * this platform, anyway. + */ +static int bf537_verify_speed(struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, &bf537_freq_table); +} + +static int __init __bf537_cpu_init(struct cpufreq_policy *policy) +{ + int result; + + if (policy->cpu != 0) + return -EINVAL; + + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + + policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; + /*Now ,only support one cpu */ + policy->cur = bf537_getfreq(0); + cpufreq_frequency_table_get_attr(bf537_freq_table, policy->cpu); + return cpufreq_frequency_table_cpuinfo(policy, bf537_freq_table); +} + +static struct freq_attr *bf537_freq_attr[] = { + &cpufreq_freq_attr_scaling_available_freqs, + NULL, +}; + +static struct cpufreq_driver bf537_driver = { + .verify = bf537_verify_speed, + .target = bf537_target, + .get = bf537_getfreq, + .init = __bf537_cpu_init, + .name = "bf537", + .owner = THIS_MODULE, + .attr = bf537_freq_attr, +}; + +static int __init bf537_cpu_init(void) +{ + return cpufreq_register_driver(&bf537_driver); +} + +static void __exit bf537_cpu_exit(void) +{ + cpufreq_unregister_driver(&bf537_driver); +} + +MODULE_AUTHOR("Mickael Kang"); +MODULE_DESCRIPTION("cpufreq driver for BF537 CPU"); +MODULE_LICENSE("GPL"); + +module_init(bf537_cpu_init); +module_exit(bf537_cpu_exit); diff --git a/arch/blackfin/mach-bf537/head.S b/arch/blackfin/mach-bf537/head.S new file mode 100644 index 000000000000..d104e1d8e07a --- /dev/null +++ b/arch/blackfin/mach-bf537/head.S @@ -0,0 +1,602 @@ +/* + * File: arch/blackfin/mach-bf537/head.S + * Based on: arch/blackfin/mach-bf533/head.S + * Author: Jeff Dionne COPYRIGHT 1998 D. Jeff Dionne + * + * Created: 1998 + * Description: Startup code for Blackfin BF537 + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#if CONFIG_BFIN_KERNEL_CLOCK +#include +#endif + +.global __rambase +.global __ramstart +.global __ramend +.extern ___bss_stop +.extern ___bss_start +.extern _bf53x_relocate_l1_mem + +#define INITIAL_STACK 0xFFB01000 + +.text + +ENTRY(__start) +ENTRY(__stext) + /* R0: argument of command line string, passed from uboot, save it */ + R7 = R0; + /* Set the SYSCFG register */ + R0 = 0x36; + SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/ + R0 = 0; + + /* Clear Out All the data and pointer Registers*/ + R1 = R0; + R2 = R0; + R3 = R0; + R4 = R0; + R5 = R0; + R6 = R0; + + P0 = R0; + P1 = R0; + P2 = R0; + P3 = R0; + P4 = R0; + P5 = R0; + + LC0 = r0; + LC1 = r0; + L0 = r0; + L1 = r0; + L2 = r0; + L3 = r0; + + /* Clear Out All the DAG Registers*/ + B0 = r0; + B1 = r0; + B2 = r0; + B3 = r0; + + I0 = r0; + I1 = r0; + I2 = r0; + I3 = r0; + + M0 = r0; + M1 = r0; + M2 = r0; + M3 = r0; + + /* Turn off the icache */ + p0.l = (IMEM_CONTROL & 0xFFFF); + p0.h = (IMEM_CONTROL >> 16); + R1 = [p0]; + R0 = ~ENICPLB; + R0 = R0 & R1; + + /* Anomaly 05000125 */ +#ifdef ANOMALY_05000125 + CLI R2; + SSYNC; +#endif + [p0] = R0; + SSYNC; +#ifdef ANOMALY_05000125 + STI R2; +#endif + + /* Turn off the dcache */ + p0.l = (DMEM_CONTROL & 0xFFFF); + p0.h = (DMEM_CONTROL >> 16); + R1 = [p0]; + R0 = ~ENDCPLB; + R0 = R0 & R1; + + /* Anomaly 05000125 */ +#ifdef ANOMALY_05000125 + CLI R2; + SSYNC; +#endif + [p0] = R0; + SSYNC; +#ifdef ANOMALY_05000125 + STI R2; +#endif + + /* Initialise General-Purpose I/O Modules on BF537 */ + /* Rev 0.0 Anomaly 05000212 - PORTx_FER, + * PORT_MUX Registers Do Not accept "writes" correctly: + */ + p0.h = hi(BFIN_PORT_MUX); + p0.l = lo(BFIN_PORT_MUX); +#ifdef ANOMALY_05000212 + R0.L = W[P0]; /* Read */ + SSYNC; +#endif + R0 = (PGDE_UART | PFTE_UART)(Z); +#ifdef ANOMALY_05000212 + W[P0] = R0.L; /* Write */ + SSYNC; +#endif + W[P0] = R0.L; /* Enable both UARTS */ + SSYNC; + + p0.h = hi(PORTF_FER); + p0.l = lo(PORTF_FER); +#ifdef ANOMALY_05000212 + R0.L = W[P0]; /* Read */ + SSYNC; +#endif + R0 = 0x000F(Z); +#ifdef ANOMALY_05000212 + W[P0] = R0.L; /* Write */ + SSYNC; +#endif + /* Enable peripheral function of PORTF for UART0 and UART1 */ + W[P0] = R0.L; + SSYNC; + +#if !defined(CONFIG_BF534) + p0.h = hi(EMAC_SYSTAT); + p0.l = lo(EMAC_SYSTAT); + R0.h = 0xFFFF; /* Clear EMAC Interrupt Status bits */ + R0.l = 0xFFFF; + [P0] = R0; + SSYNC; +#endif + +#ifdef CONFIG_BF537_PORT_H + p0.h = hi(PORTH_FER); + p0.l = lo(PORTH_FER); + R0.L = W[P0]; /* Read */ + SSYNC; + R0 = 0x0000; + W[P0] = R0.L; /* Write */ + SSYNC; + W[P0] = R0.L; /* Disable peripheral function of PORTH */ + SSYNC; +#endif + + /*Initialise UART*/ + p0.h = hi(UART_LCR); + p0.l = lo(UART_LCR); + r0 = 0x0(Z); + w[p0] = r0.L; /* To enable DLL writes */ + ssync; + + p0.h = hi(UART_DLL); + p0.l = lo(UART_DLL); + r0 = 0x00(Z); + w[p0] = r0.L; + ssync; + + p0.h = hi(UART_DLH); + p0.l = lo(UART_DLH); + r0 = 0x00(Z); + w[p0] = r0.L; + ssync; + + p0.h = hi(UART_GCTL); + p0.l = lo(UART_GCTL); + r0 = 0x0(Z); + w[p0] = r0.L; /* To enable UART clock */ + ssync; + + /* Initialize stack pointer */ + sp.l = lo(INITIAL_STACK); + sp.h = hi(INITIAL_STACK); + fp = sp; + usp = sp; + + /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ + call _bf53x_relocate_l1_mem; +#if CONFIG_BFIN_KERNEL_CLOCK + call _start_dma_code; +#endif + /* Code for initializing Async memory banks */ + + p2.h = hi(EBIU_AMBCTL1); + p2.l = lo(EBIU_AMBCTL1); + r0.h = hi(AMBCTL1VAL); + r0.l = lo(AMBCTL1VAL); + [p2] = r0; + ssync; + + p2.h = hi(EBIU_AMBCTL0); + p2.l = lo(EBIU_AMBCTL0); + r0.h = hi(AMBCTL0VAL); + r0.l = lo(AMBCTL0VAL); + [p2] = r0; + ssync; + + p2.h = hi(EBIU_AMGCTL); + p2.l = lo(EBIU_AMGCTL); + r0 = AMGCTLVAL; + w[p2] = r0; + ssync; + + /* This section keeps the processor in supervisor mode + * during kernel boot. Switches to user mode at end of boot. + * See page 3-9 of Hardware Reference manual for documentation. + */ + + /* EVT15 = _real_start */ + + p0.l = lo(EVT15); + p0.h = hi(EVT15); + p1.l = _real_start; + p1.h = _real_start; + [p0] = p1; + csync; + + p0.l = lo(IMASK); + p0.h = hi(IMASK); + p1.l = IMASK_IVG15; + p1.h = 0x0; + [p0] = p1; + csync; + + raise 15; + p0.l = .LWAIT_HERE; + p0.h = .LWAIT_HERE; + reti = p0; +#if defined(ANOMALY_05000281) + nop; nop; nop; +#endif + rti; + +.LWAIT_HERE: + jump .LWAIT_HERE; + +ENTRY(_real_start) + [ -- sp ] = reti; + p0.l = lo(WDOG_CTL); + p0.h = hi(WDOG_CTL); + r0 = 0xAD6(z); + w[p0] = r0; /* watchdog off for now */ + ssync; + + /* Code update for BSS size == 0 + * Zero out the bss region. + */ + + p1.l = ___bss_start; + p1.h = ___bss_start; + p2.l = ___bss_stop; + p2.h = ___bss_stop; + r0 = 0; + p2 -= p1; + lsetup (.L_clear_bss, .L_clear_bss ) lc0 = p2; +.L_clear_bss: + B[p1++] = r0; + + /* In case there is a NULL pointer reference + * Zero out region before stext + */ + + p1.l = 0x0; + p1.h = 0x0; + r0.l = __stext; + r0.h = __stext; + r0 = r0 >> 1; + p2 = r0; + r0 = 0; + lsetup (.L_clear_zero, .L_clear_zero ) lc0 = p2; +.L_clear_zero: + W[p1++] = r0; + + /* pass the uboot arguments to the global value command line */ + R0 = R7; + call _cmdline_init; + + p1.l = __rambase; + p1.h = __rambase; + r0.l = __sdata; + r0.h = __sdata; + [p1] = r0; + + p1.l = __ramstart; + p1.h = __ramstart; + p3.l = ___bss_stop; + p3.h = ___bss_stop; + + r1 = p3; + [p1] = r1; + + + /* + * load the current thread pointer and stack + */ + r1.l = _init_thread_union; + r1.h = _init_thread_union; + + r2.l = 0x2000; + r2.h = 0x0000; + r1 = r1 + r2; + sp = r1; + usp = sp; + fp = sp; + call _start_kernel; +.L_exit: + jump.s .L_exit; + +.section .l1.text +#if CONFIG_BFIN_KERNEL_CLOCK +ENTRY(_start_dma_code) + + /* Enable PHY CLK buffer output */ + p0.h = hi(VR_CTL); + p0.l = lo(VR_CTL); + r0.l = w[p0]; + bitset(r0, 14); + w[p0] = r0.l; + ssync; + + p0.h = hi(SIC_IWR); + p0.l = lo(SIC_IWR); + r0.l = 0x1; + r0.h = 0x0; + [p0] = r0; + SSYNC; + + /* + * Set PLL_CTL + * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors + * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK + * - [7] = output delay (add 200ps of delay to mem signals) + * - [6] = input delay (add 200ps of input delay to mem signals) + * - [5] = PDWN : 1=All Clocks off + * - [3] = STOPCK : 1=Core Clock off + * - [1] = PLL_OFF : 1=Disable Power to PLL + * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL + * all other bits set to zero + */ + + p0.h = hi(PLL_LOCKCNT); + p0.l = lo(PLL_LOCKCNT); + r0 = 0x300(Z); + w[p0] = r0.l; + ssync; + + P2.H = hi(EBIU_SDGCTL); + P2.L = lo(EBIU_SDGCTL); + R0 = [P2]; + BITSET (R0, 24); + [P2] = R0; + SSYNC; + + r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */ + r0 = r0 << 9; /* Shift it over, */ + r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/ + r0 = r1 | r0; + r1 = PLL_BYPASS; /* Bypass the PLL? */ + r1 = r1 << 8; /* Shift it over */ + r0 = r1 | r0; /* add them all together */ + + p0.h = hi(PLL_CTL); + p0.l = lo(PLL_CTL); /* Load the address */ + cli r2; /* Disable interrupts */ + ssync; + w[p0] = r0.l; /* Set the value */ + idle; /* Wait for the PLL to stablize */ + sti r2; /* Enable interrupts */ + +.Lcheck_again: + p0.h = hi(PLL_STAT); + p0.l = lo(PLL_STAT); + R0 = W[P0](Z); + CC = BITTST(R0,5); + if ! CC jump .Lcheck_again; + + /* Configure SCLK & CCLK Dividers */ + r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV); + p0.h = hi(PLL_DIV); + p0.l = lo(PLL_DIV); + w[p0] = r0.l; + ssync; + + p0.l = lo(EBIU_SDRRC); + p0.h = hi(EBIU_SDRRC); + r0 = mem_SDRRC; + w[p0] = r0.l; + ssync; + + p0.l = (EBIU_SDBCTL & 0xFFFF); + p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */ + r0 = mem_SDBCTL; + w[p0] = r0.l; + ssync; + + P2.H = hi(EBIU_SDGCTL); + P2.L = lo(EBIU_SDGCTL); + R0 = [P2]; + BITCLR (R0, 24); + p0.h = hi(EBIU_SDSTAT); + p0.l = lo(EBIU_SDSTAT); + r2.l = w[p0]; + cc = bittst(r2,3); + if !cc jump .Lskip; + NOP; + BITSET (R0, 23); +.Lskip: + [P2] = R0; + SSYNC; + + R0.L = lo(mem_SDGCTL); + R0.H = hi(mem_SDGCTL); + R1 = [p2]; + R1 = R1 | R0; + [P2] = R1; + SSYNC; + + p0.h = hi(SIC_IWR); + p0.l = lo(SIC_IWR); + r0.l = lo(IWR_ENABLE_ALL); + r0.h = hi(IWR_ENABLE_ALL); + [p0] = r0; + SSYNC; + + RTS; +#endif /* CONFIG_BFIN_KERNEL_CLOCK */ + +ENTRY(_bfin_reset) + /* No more interrupts to be handled*/ + CLI R6; + SSYNC; + +#if defined(CONFIG_MTD_M25P80) +/* + * The following code fix the SPI flash reboot issue, + * /CS signal of the chip which is using PF10 return to GPIO mode + */ + p0.h = hi(PORTF_FER); + p0.l = lo(PORTF_FER); + r0.l = 0x0000; + w[p0] = r0.l; + SSYNC; + +/* /CS return to high */ + p0.h = hi(PORTFIO); + p0.l = lo(PORTFIO); + r0.l = 0xFFFF; + w[p0] = r0.l; + SSYNC; + +/* Delay some time, This is necessary */ + r1.h = 0; + r1.l = 0x400; + p1 = r1; + lsetup (_delay_lab1,_delay_lab1_end ) lc1 = p1; +_delay_lab1: + r0.h = 0; + r0.l = 0x8000; + p0 = r0; + lsetup (_delay_lab0,_delay_lab0_end ) lc0 = p0; +_delay_lab0: + nop; +_delay_lab0_end: + nop; +_delay_lab1_end: + nop; +#endif + + /* Clear the bits 13-15 in SWRST if they werent cleared */ + p0.h = hi(SWRST); + p0.l = lo(SWRST); + csync; + r0.l = w[p0]; + + /* Clear the IMASK register */ + p0.h = hi(IMASK); + p0.l = lo(IMASK); + r0 = 0x0; + [p0] = r0; + + /* Clear the ILAT register */ + p0.h = hi(ILAT); + p0.l = lo(ILAT); + r0 = [p0]; + [p0] = r0; + SSYNC; + + /* Disable the WDOG TIMER */ + p0.h = hi(WDOG_CTL); + p0.l = lo(WDOG_CTL); + r0.l = 0xAD6; + w[p0] = r0.l; + SSYNC; + + /* Clear the sticky bit incase it is already set */ + p0.h = hi(WDOG_CTL); + p0.l = lo(WDOG_CTL); + r0.l = 0x8AD6; + w[p0] = r0.l; + SSYNC; + + /* Program the count value */ + R0.l = 0x100; + R0.h = 0x0; + P0.h = hi(WDOG_CNT); + P0.l = lo(WDOG_CNT); + [P0] = R0; + SSYNC; + + /* Program WDOG_STAT if necessary */ + P0.h = hi(WDOG_CTL); + P0.l = lo(WDOG_CTL); + R0 = W[P0](Z); + CC = BITTST(R0,1); + if !CC JUMP .LWRITESTAT; + CC = BITTST(R0,2); + if !CC JUMP .LWRITESTAT; + JUMP .LSKIP_WRITE; + +.LWRITESTAT: + /* When watch dog timer is enabled, + * a write to STAT will load the contents of CNT to STAT + */ + R0 = 0x0000(z); + P0.h = hi(WDOG_STAT); + P0.l = lo(WDOG_STAT) + [P0] = R0; + SSYNC; + +.LSKIP_WRITE: + /* Enable the reset event */ + P0.h = hi(WDOG_CTL); + P0.l = lo(WDOG_CTL); + R0 = W[P0](Z); + BITCLR(R0,1); + BITCLR(R0,2); + W[P0] = R0.L; + SSYNC; + NOP; + + /* Enable the wdog counter */ + R0 = W[P0](Z); + BITCLR(R0,4); + W[P0] = R0.L; + SSYNC; + + IDLE; + + RTS; + +.data + +/* + * Set up the usable of RAM stuff. Size of RAM is determined then + * an initial stack set up at the end. + */ + +.align 4 +__rambase: +.long 0 +__ramstart: +.long 0 +__ramend: +.long 0 diff --git a/arch/blackfin/mach-bf537/ints-priority.c b/arch/blackfin/mach-bf537/ints-priority.c new file mode 100644 index 000000000000..fd6308eccbe6 --- /dev/null +++ b/arch/blackfin/mach-bf537/ints-priority.c @@ -0,0 +1,74 @@ +/* + * File: arch/blackfin/mach-bf537/ints-priority.c + * Based on: arch/blackfin/mach-bf533/ints-priority.c + * Author: Michael Hennerich + * + * Created: + * Description: Set up the interupt priorities + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +void program_IAR(void) +{ + /* Program the IAR0 Register with the configured priority */ + bfin_write_SIC_IAR0(((CONFIG_IRQ_PLL_WAKEUP - 7) << IRQ_PLL_WAKEUP_POS) | + ((CONFIG_IRQ_DMA_ERROR - 7) << IRQ_DMA_ERROR_POS) | + ((CONFIG_IRQ_ERROR - 7) << IRQ_ERROR_POS) | + ((CONFIG_IRQ_RTC - 7) << IRQ_RTC_POS) | + ((CONFIG_IRQ_PPI - 7) << IRQ_PPI_POS) | + ((CONFIG_IRQ_SPORT0_RX - 7) << IRQ_SPORT0_RX_POS) | + ((CONFIG_IRQ_SPORT0_TX - 7) << IRQ_SPORT0_TX_POS) | + ((CONFIG_IRQ_SPORT1_RX - 7) << IRQ_SPORT1_RX_POS)); + + bfin_write_SIC_IAR1(((CONFIG_IRQ_SPORT1_TX - 7) << IRQ_SPORT1_TX_POS) | + ((CONFIG_IRQ_TWI - 7) << IRQ_TWI_POS) | + ((CONFIG_IRQ_SPI - 7) << IRQ_SPI_POS) | + ((CONFIG_IRQ_UART0_RX - 7) << IRQ_UART0_RX_POS) | + ((CONFIG_IRQ_UART0_TX - 7) << IRQ_UART0_TX_POS) | + ((CONFIG_IRQ_UART1_RX - 7) << IRQ_UART1_RX_POS) | + ((CONFIG_IRQ_UART1_TX - 7) << IRQ_UART1_TX_POS) | + ((CONFIG_IRQ_CAN_RX - 7) << IRQ_CAN_RX_POS)); + + bfin_write_SIC_IAR2(((CONFIG_IRQ_CAN_TX - 7) << IRQ_CAN_TX_POS) | + ((CONFIG_IRQ_MAC_RX - 7) << IRQ_MAC_RX_POS) | + ((CONFIG_IRQ_MAC_TX - 7) << IRQ_MAC_TX_POS) | + ((CONFIG_IRQ_TMR0 - 7) << IRQ_TMR0_POS) | + ((CONFIG_IRQ_TMR1 - 7) << IRQ_TMR1_POS) | + ((CONFIG_IRQ_TMR2 - 7) << IRQ_TMR2_POS) | + ((CONFIG_IRQ_TMR3 - 7) << IRQ_TMR3_POS) | + ((CONFIG_IRQ_TMR4 - 7) << IRQ_TMR4_POS)); + + bfin_write_SIC_IAR3(((CONFIG_IRQ_TMR5 - 7) << IRQ_TMR5_POS) | + ((CONFIG_IRQ_TMR6 - 7) << IRQ_TMR6_POS) | + ((CONFIG_IRQ_TMR7 - 7) << IRQ_TMR7_POS) | + ((CONFIG_IRQ_PROG_INTA - 7) << IRQ_PROG_INTA_POS) | + ((CONFIG_IRQ_PORTG_INTB - 7) << IRQ_PORTG_INTB_POS) | + ((CONFIG_IRQ_MEM_DMA0 - 7) << IRQ_MEM_DMA0_POS) | + ((CONFIG_IRQ_MEM_DMA1 - 7) << IRQ_MEM_DMA1_POS) | + ((CONFIG_IRQ_WATCH - 7) << IRQ_WATCH_POS)); + + SSYNC(); +} diff --git a/arch/blackfin/mach-bf561/Kconfig b/arch/blackfin/mach-bf561/Kconfig new file mode 100644 index 000000000000..0a17c4cf0059 --- /dev/null +++ b/arch/blackfin/mach-bf561/Kconfig @@ -0,0 +1,222 @@ +if BF561 + +menu "BF561 Specific Configuration" + +comment "Core B Support" + +menu "Core B Support" + +config BF561_COREB + bool "Enable Core B support" + default y + +config BF561_COREB_RESET + bool "Enable Core B reset support" + default n + help + This requires code in the application that is loaded + into Core B. In order to reset, the application needs + to install an interrupt handler for Supplemental + Interrupt 0, that sets RETI to 0xff600000 and writes + bit 11 of SICB_SYSCR when bit 5 of SICA_SYSCR is 0. + This causes Core B to stall when Supplemental Interrupt + 0 is set, and will reset PC to 0xff600000 when + COREB_SRAM_INIT is cleared. + +endmenu + +comment "Interrupt Priority Assignment" + +menu "Priority" + +config IRQ_PLL_WAKEUP + int "PLL Wakeup Interrupt" + default 7 +config IRQ_DMA1_ERROR + int "DMA1 Error (generic)" + default 7 +config IRQ_DMA2_ERROR + int "DMA2 Error (generic)" + default 7 +config IRQ_IMDMA_ERROR + int "IMDMA Error (generic)" + default 7 +config IRQ_PPI0_ERROR + int "PPI0 Error Interrupt" + default 7 +config IRQ_PPI1_ERROR + int "PPI1 Error Interrupt" + default 7 +config IRQ_SPORT0_ERROR + int "SPORT0 Error Interrupt" + default 7 +config IRQ_SPORT1_ERROR + int "SPORT1 Error Interrupt" + default 7 +config IRQ_SPI_ERROR + int "SPI Error Interrupt" + default 7 +config IRQ_UART_ERROR + int "UART Error Interrupt" + default 7 +config IRQ_RESERVED_ERROR + int "Reserved Interrupt" + default 7 +config IRQ_DMA1_0 + int "DMA1 0 Interrupt(PPI1)" + default 8 +config IRQ_DMA1_1 + int "DMA1 1 Interrupt(PPI2)" + default 8 +config IRQ_DMA1_2 + int "DMA1 2 Interrupt" + default 8 +config IRQ_DMA1_3 + int "DMA1 3 Interrupt" + default 8 +config IRQ_DMA1_4 + int "DMA1 4 Interrupt" + default 8 +config IRQ_DMA1_5 + int "DMA1 5 Interrupt" + default 8 +config IRQ_DMA1_6 + int "DMA1 6 Interrupt" + default 8 +config IRQ_DMA1_7 + int "DMA1 7 Interrupt" + default 8 +config IRQ_DMA1_8 + int "DMA1 8 Interrupt" + default 8 +config IRQ_DMA1_9 + int "DMA1 9 Interrupt" + default 8 +config IRQ_DMA1_10 + int "DMA1 10 Interrupt" + default 8 +config IRQ_DMA1_11 + int "DMA1 11 Interrupt" + default 8 +config IRQ_DMA2_0 + int "DMA2 0 (SPORT0 RX)" + default 9 +config IRQ_DMA2_1 + int "DMA2 1 (SPORT0 TX)" + default 9 +config IRQ_DMA2_2 + int "DMA2 2 (SPORT1 RX)" + default 9 +config IRQ_DMA2_3 + int "DMA2 3 (SPORT2 TX)" + default 9 +config IRQ_DMA2_4 + int "DMA2 4 (SPI)" + default 9 +config IRQ_DMA2_5 + int "DMA2 5 (UART RX)" + default 9 +config IRQ_DMA2_6 + int "DMA2 6 (UART TX)" + default 9 +config IRQ_DMA2_7 + int "DMA2 7 Interrupt" + default 9 +config IRQ_DMA2_8 + int "DMA2 8 Interrupt" + default 9 +config IRQ_DMA2_9 + int "DMA2 9 Interrupt" + default 9 +config IRQ_DMA2_10 + int "DMA2 10 Interrupt" + default 9 +config IRQ_DMA2_11 + int "DMA2 11 Interrupt" + default 9 +config IRQ_TIMER0 + int "TIMER 0 Interrupt" + default 10 +config IRQ_TIMER1 + int "TIMER 1 Interrupt" + default 10 +config IRQ_TIMER2 + int "TIMER 2 Interrupt" + default 10 +config IRQ_TIMER3 + int "TIMER 3 Interrupt" + default 10 +config IRQ_TIMER4 + int "TIMER 4 Interrupt" + default 10 +config IRQ_TIMER5 + int "TIMER 5 Interrupt" + default 10 +config IRQ_TIMER6 + int "TIMER 6 Interrupt" + default 10 +config IRQ_TIMER7 + int "TIMER 7 Interrupt" + default 10 +config IRQ_TIMER8 + int "TIMER 8 Interrupt" + default 10 +config IRQ_TIMER9 + int "TIMER 9 Interrupt" + default 10 +config IRQ_TIMER10 + int "TIMER 10 Interrupt" + default 10 +config IRQ_TIMER11 + int "TIMER 11 Interrupt" + default 10 +config IRQ_PROG0_INTA + int "Programmable Flags0 A (8)" + default 11 +config IRQ_PROG0_INTB + int "Programmable Flags0 B (8)" + default 11 +config IRQ_PROG1_INTA + int "Programmable Flags1 A (8)" + default 11 +config IRQ_PROG1_INTB + int "Programmable Flags1 B (8)" + default 11 +config IRQ_PROG2_INTA + int "Programmable Flags2 A (8)" + default 11 +config IRQ_PROG2_INTB + int "Programmable Flags2 B (8)" + default 11 +config IRQ_DMA1_WRRD0 + int "MDMA1 0 write/read INT" + default 8 +config IRQ_DMA1_WRRD1 + int "MDMA1 1 write/read INT" + default 8 +config IRQ_DMA2_WRRD0 + int "MDMA2 0 write/read INT" + default 9 +config IRQ_DMA2_WRRD1 + int "MDMA2 1 write/read INT" + default 9 +config IRQ_IMDMA_WRRD0 + int "IMDMA 0 write/read INT" + default 12 +config IRQ_IMDMA_WRRD1 + int "IMDMA 1 write/read INT" + default 12 +config IRQ_WDTIMER + int "Watch Dog Timer" + default 13 + + help + Enter the priority numbers between 7-13 ONLY. Others are Reserved. + This applies to all the above. It is not recommended to assign the + highest priority number 7 to UART or any other device. + +endmenu + +endmenu + +endif diff --git a/arch/blackfin/mach-bf561/Makefile b/arch/blackfin/mach-bf561/Makefile new file mode 100644 index 000000000000..57f475a55161 --- /dev/null +++ b/arch/blackfin/mach-bf561/Makefile @@ -0,0 +1,9 @@ +# +# arch/blackfin/mach-bf561/Makefile +# + +extra-y := head.o + +obj-y := ints-priority.o + +obj-$(CONFIG_BF561_COREB) += coreb.o diff --git a/arch/blackfin/mach-bf561/boards/Makefile b/arch/blackfin/mach-bf561/boards/Makefile new file mode 100644 index 000000000000..886edc739ab4 --- /dev/null +++ b/arch/blackfin/mach-bf561/boards/Makefile @@ -0,0 +1,7 @@ +# +# arch/blackfin/mach-bf561/boards/Makefile +# + +obj-$(CONFIG_GENERIC_BOARD) += generic_board.o +obj-$(CONFIG_BFIN561_EZKIT) += ezkit.o +obj-$(CONFIG_BFIN561_BLUETECHNIX_CM) += cm_bf561.o diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c new file mode 100644 index 000000000000..6824e956d153 --- /dev/null +++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c @@ -0,0 +1,289 @@ +/* + * File: arch/blackfin/mach-bf533/boards/cm_bf561.c + * Based on: arch/blackfin/mach-bf533/boards/ezkit.c + * Author: Aidan Williams Copright 2005 + * + * Created: 2006 + * Description: Board description file + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Name the Board for the /proc/cpuinfo + */ +char *bfin_board_name = "Bluetechnix CM BF561"; + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* all SPI perpherals info goes here */ + +#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) +static struct mtd_partition bfin_spi_flash_partitions[] = { + { + .name = "bootloader", + .size = 0x00020000, + .offset = 0, + .mask_flags = MTD_CAP_ROM + },{ + .name = "kernel", + .size = 0xe0000, + .offset = 0x20000 + },{ + .name = "file system", + .size = 0x700000, + .offset = 0x00100000, + } +}; + +static struct flash_platform_data bfin_spi_flash_data = { + .name = "m25p80", + .parts = bfin_spi_flash_partitions, + .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), + .type = "m25p64", +}; + +/* SPI flash chip (m25p64) */ +static struct bfin5xx_spi_chip spi_flash_chip_info = { + .enable_dma = 0, /* use dma transfer with this chip*/ + .bits_per_word = 8, +}; +#endif + +#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) +/* SPI ADC chip */ +static struct bfin5xx_spi_chip spi_adc_chip_info = { + .enable_dma = 1, /* use dma transfer with this chip*/ + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +static struct bfin5xx_spi_chip ad1836_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) +static struct bfin5xx_spi_chip ad9960_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) +static struct bfin5xx_spi_chip spi_mmc_chip_info = { + .enable_dma = 1, + .bits_per_word = 8, +}; +#endif + +static struct spi_board_info bfin_spi_board_info[] __initdata = { +#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) + { + /* the modalias must be the same as spi device driver name */ + .modalias = "m25p80", /* Name of spi_driver for this device */ + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ + .platform_data = &bfin_spi_flash_data, + .controller_data = &spi_flash_chip_info, + .mode = SPI_MODE_3, + }, +#endif + +#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) + { + .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ + .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. */ + .platform_data = NULL, /* No spi_driver specific config */ + .controller_data = &spi_adc_chip_info, + }, +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) + { + .modalias = "ad1836-spi", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, + .controller_data = &ad1836_spi_chip_info, + }, +#endif +#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) + { + .modalias = "ad9960-spi", + .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 1, + .controller_data = &ad9960_spi_chip_info, + }, +#endif +#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) + { + .modalias = "spi_mmc", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = CONFIG_SPI_MMC_CS_CHAN, + .platform_data = NULL, + .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, +#endif +}; + +/* SPI controller data */ +static struct bfin5xx_spi_master spi_bfin_master_info = { + .num_chipselect = 8, + .enable_dma = 1, /* master has the ability to do dma transfer */ +}; + +static struct platform_device spi_bfin_master_device = { + .name = "bfin-spi-master", + .id = 1, /* Bus number */ + .dev = { + .platform_data = &spi_bfin_master_info, /* Passed to driver */ + }, +}; +#endif /* spi master and devices */ + + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + +static struct resource smc91x_resources[] = { + { + .name = "smc91x-regs", + .start = 0x28000300, + .end = 0x28000300 + 16, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PF0, + .end = IRQ_PF0, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) +static struct resource isp1362_hcd_resources[] = { + { + .start = 0x24008000, + .end = 0x24008000, + .flags = IORESOURCE_MEM, + },{ + .start = 0x24008004, + .end = 0x24008004, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PF47, + .end = IRQ_PF47, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct isp1362_platform_data isp1362_priv = { + .sel15Kres = 1, + .clknotstop = 0, + .oc_enable = 0, + .int_act_high = 0, + .int_edge_triggered = 0, + .remote_wakeup_connected = 0, + .no_power_switching = 1, + .power_switching_mode = 0, +}; + +static struct platform_device isp1362_hcd_device = { + .name = "isp1362-hcd", + .id = 0, + .dev = { + .platform_data = &isp1362_priv, + }, + .num_resources = ARRAY_SIZE(isp1362_hcd_resources), + .resource = isp1362_hcd_resources, +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +static struct resource bfin_uart_resources[] = { + { + .start = 0xFFC00400, + .end = 0xFFC004FF, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device bfin_uart_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart_resources), + .resource = bfin_uart_resources, +}; +#endif + +static struct platform_device *cm_bf561_devices[] __initdata = { + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) + &bfin_uart_device, +#endif + +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) + &isp1362_hcd_device, +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + &smc91x_device, +#endif + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + &spi_bfin_master_device, +#endif + +}; + +static int __init cm_bf561_init(void) +{ + printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); + platform_add_devices(cm_bf561_devices, ARRAY_SIZE(cm_bf561_devices)); +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); +#endif + return 0; +} + +arch_initcall(cm_bf561_init); diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c new file mode 100644 index 000000000000..14eb4f9a68ea --- /dev/null +++ b/arch/blackfin/mach-bf561/boards/ezkit.c @@ -0,0 +1,147 @@ +/* + * File: arch/blackfin/mach-bf561/ezkit.c + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +/* + * Name the Board for the /proc/cpuinfo + */ +char *bfin_board_name = "ADDS-BF561-EZKIT"; + +/* + * USB-LAN EzExtender board + * Driver needs to know address, irq and flag pin. + */ +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +static struct resource smc91x_resources[] = { + { + .name = "smc91x-regs", + .start = 0x2C010300, + .end = 0x2C010300 + 16, + .flags = IORESOURCE_MEM, + },{ + + .start = IRQ_PF9, + .end = IRQ_PF9, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +static struct resource bfin_uart_resources[] = { + { + .start = 0xFFC00400, + .end = 0xFFC004FF, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device bfin_uart_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart_resources), + .resource = bfin_uart_resources, +}; +#endif + +#ifdef CONFIG_SPI_BFIN +#if defined(CONFIG_SND_BLACKFIN_AD1836) \ + || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +static struct bfin5xx_spi_chip ad1836_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif +#endif + +/* SPI controller data */ +static struct bfin5xx_spi_master spi_bfin_master_info = { + .num_chipselect = 8, + .enable_dma = 1, /* master has the ability to do dma transfer */ +}; + +static struct platform_device spi_bfin_master_device = { + .name = "bfin-spi-master", + .id = 1, /* Bus number */ + .dev = { + .platform_data = &spi_bfin_master_info, /* Passed to driver */ + }, +}; + +static struct spi_board_info bfin_spi_board_info[] __initdata = { +#if defined(CONFIG_SND_BLACKFIN_AD1836) \ + || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) + { + .modalias = "ad1836-spi", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, + .controller_data = &ad1836_spi_chip_info, + }, +#endif +}; + +static struct platform_device *ezkit_devices[] __initdata = { +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + &smc91x_device, +#endif +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + &spi_bfin_master_device, +#endif +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) + &bfin_uart_device, +#endif +}; + +static int __init ezkit_init(void) +{ + int ret; + + printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); + ret = platform_add_devices(ezkit_devices, + ARRAY_SIZE(ezkit_devices)); + if (ret < 0) + return ret; + return spi_register_board_info(bfin_spi_board_info, + ARRAY_SIZE(bfin_spi_board_info)); +} + +arch_initcall(ezkit_init); diff --git a/arch/blackfin/mach-bf561/boards/generic_board.c b/arch/blackfin/mach-bf561/boards/generic_board.c new file mode 100644 index 000000000000..585ecdd2f6a5 --- /dev/null +++ b/arch/blackfin/mach-bf561/boards/generic_board.c @@ -0,0 +1,82 @@ +/* + * File: arch/blackfin/mach-bf561/generic_board.c + * Based on: arch/blackfin/mach-bf533/ezkit.c + * Author: Aidan Williams + * + * Created: + * Description: + * + * Modified: + * Copyright 2005 National ICT Australia (NICTA) + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +char *bfin_board_name = "UNKNOWN BOARD"; + +/* + * Driver needs to know address, irq and flag pin. + */ +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +static struct resource smc91x_resources[] = { + { + .start = 0x2C010300, + .end = 0x2C010300 + 16, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PROG_INTB, + .end = IRQ_PROG_INTB, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + },{ + /* + * denotes the flag pin and is used directly if + * CONFIG_IRQCHIP_DEMUX_GPIO is defined. + */ + .start = IRQ_PF9, + .end = IRQ_PF9, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +static struct platform_device *generic_board_devices[] __initdata = { +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + &smc91x_device, +#endif +}; + +static int __init generic_board_init(void) +{ + printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); + return platform_add_devices(generic_board_devices, + ARRAY_SIZE(generic_board_devices)); +} + +arch_initcall(generic_board_init); diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c new file mode 100644 index 000000000000..b28582fe083c --- /dev/null +++ b/arch/blackfin/mach-bf561/coreb.c @@ -0,0 +1,402 @@ +/* + * File: arch/blackfin/mach-bf561/coreb.c + * Based on: + * Author: + * + * Created: + * Description: Handle CoreB on a BF561 + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#define MODULE_VER "v0.1" + +static spinlock_t coreb_lock; +static wait_queue_head_t coreb_dma_wait; + +#define COREB_IS_OPEN 0x00000001 +#define COREB_IS_RUNNING 0x00000010 + +#define CMD_COREB_INDEX 1 +#define CMD_COREB_START 2 +#define CMD_COREB_STOP 3 +#define CMD_COREB_RESET 4 + +#define COREB_MINOR 229 + +static unsigned long coreb_status = 0; +static unsigned long coreb_base = 0xff600000; +static unsigned long coreb_size = 0x4000; +int coreb_dma_done; + +static loff_t coreb_lseek(struct file *file, loff_t offset, int origin); +static ssize_t coreb_read(struct file *file, char *buf, size_t count, + loff_t * ppos); +static ssize_t coreb_write(struct file *file, const char *buf, size_t count, + loff_t * ppos); +static int coreb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg); +static int coreb_open(struct inode *inode, struct file *file); +static int coreb_release(struct inode *inode, struct file *file); + +static irqreturn_t coreb_dma_interrupt(int irq, void *dev_id) +{ + clear_dma_irqstat(CH_MEM_STREAM2_DEST); + coreb_dma_done = 1; + wake_up_interruptible(&coreb_dma_wait); + return IRQ_HANDLED; +} + +static ssize_t coreb_write(struct file *file, const char *buf, size_t count, + loff_t * ppos) +{ + unsigned long p = *ppos; + ssize_t wrote = 0; + + if (p + count > coreb_size) + return -EFAULT; + + while (count > 0) { + int len = count; + + if (len > PAGE_SIZE) + len = PAGE_SIZE; + + coreb_dma_done = 0; + + /* Source Channel */ + set_dma_start_addr(CH_MEM_STREAM2_SRC, (unsigned long)buf); + set_dma_x_count(CH_MEM_STREAM2_SRC, len); + set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char)); + set_dma_config(CH_MEM_STREAM2_SRC, RESTART); + /* Destination Channel */ + set_dma_start_addr(CH_MEM_STREAM2_DEST, coreb_base + p); + set_dma_x_count(CH_MEM_STREAM2_DEST, len); + set_dma_x_modify(CH_MEM_STREAM2_DEST, sizeof(char)); + set_dma_config(CH_MEM_STREAM2_DEST, WNR | RESTART | DI_EN); + + enable_dma(CH_MEM_STREAM2_SRC); + enable_dma(CH_MEM_STREAM2_DEST); + + wait_event_interruptible(coreb_dma_wait, coreb_dma_done); + + disable_dma(CH_MEM_STREAM2_SRC); + disable_dma(CH_MEM_STREAM2_DEST); + + count -= len; + wrote += len; + buf += len; + p += len; + } + *ppos = p; + return wrote; +} + +static ssize_t coreb_read(struct file *file, char *buf, size_t count, + loff_t * ppos) +{ + unsigned long p = *ppos; + ssize_t read = 0; + + if ((p + count) > coreb_size) + return -EFAULT; + + while (count > 0) { + int len = count; + + if (len > PAGE_SIZE) + len = PAGE_SIZE; + + coreb_dma_done = 0; + + /* Source Channel */ + set_dma_start_addr(CH_MEM_STREAM2_SRC, coreb_base + p); + set_dma_x_count(CH_MEM_STREAM2_SRC, len); + set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char)); + set_dma_config(CH_MEM_STREAM2_SRC, RESTART); + /* Destination Channel */ + set_dma_start_addr(CH_MEM_STREAM2_DEST, (unsigned long)buf); + set_dma_x_count(CH_MEM_STREAM2_DEST, len); + set_dma_x_modify(CH_MEM_STREAM2_DEST, sizeof(char)); + set_dma_config(CH_MEM_STREAM2_DEST, WNR | RESTART | DI_EN); + + enable_dma(CH_MEM_STREAM2_SRC); + enable_dma(CH_MEM_STREAM2_DEST); + + wait_event_interruptible(coreb_dma_wait, coreb_dma_done); + + disable_dma(CH_MEM_STREAM2_SRC); + disable_dma(CH_MEM_STREAM2_DEST); + + count -= len; + read += len; + buf += len; + p += len; + } + + return read; +} + +static loff_t coreb_lseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret; + + mutex_lock(&file->f_dentry->d_inode->i_mutex); + + switch (origin) { + case 0 /* SEEK_SET */ : + if (offset < coreb_size) { + file->f_pos = offset; + ret = file->f_pos; + } else + ret = -EINVAL; + break; + case 1 /* SEEK_CUR */ : + if ((offset + file->f_pos) < coreb_size) { + file->f_pos += offset; + ret = file->f_pos; + } else + ret = -EINVAL; + default: + ret = -EINVAL; + } + mutex_unlock(&file->f_dentry->d_inode->i_mutex); + return ret; +} + +static int coreb_open(struct inode *inode, struct file *file) +{ + spin_lock_irq(&coreb_lock); + + if (coreb_status & COREB_IS_OPEN) + goto out_busy; + + coreb_status |= COREB_IS_OPEN; + + spin_unlock_irq(&coreb_lock); + return 0; + + out_busy: + spin_unlock_irq(&coreb_lock); + return -EBUSY; +} + +static int coreb_release(struct inode *inode, struct file *file) +{ + spin_lock_irq(&coreb_lock); + coreb_status &= ~COREB_IS_OPEN; + spin_unlock_irq(&coreb_lock); + return 0; +} + +static int coreb_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int retval = 0; + int coreb_index = 0; + + switch (cmd) { + case CMD_COREB_INDEX: + if (copy_from_user(&coreb_index, (int *)arg, sizeof(int))) { + retval = -EFAULT; + break; + } + + spin_lock_irq(&coreb_lock); + switch (coreb_index) { + case 0: + coreb_base = 0xff600000; + coreb_size = 0x4000; + break; + case 1: + coreb_base = 0xff610000; + coreb_size = 0x4000; + break; + case 2: + coreb_base = 0xff500000; + coreb_size = 0x8000; + break; + case 3: + coreb_base = 0xff400000; + coreb_size = 0x8000; + break; + default: + retval = -EINVAL; + break; + } + spin_unlock_irq(&coreb_lock); + + mutex_lock(&file->f_dentry->d_inode->i_mutex); + file->f_pos = 0; + mutex_unlock(&file->f_dentry->d_inode->i_mutex); + break; + case CMD_COREB_START: + spin_lock_irq(&coreb_lock); + if (coreb_status & COREB_IS_RUNNING) { + retval = -EBUSY; + break; + } + printk(KERN_INFO "Starting Core B\n"); + coreb_status |= COREB_IS_RUNNING; + bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~0x0020); + SSYNC(); + spin_lock_irq(&coreb_lock); + break; +#if defined(CONFIG_BF561_COREB_RESET) + case CMD_COREB_STOP: + spin_lock_irq(&coreb_lock); + printk(KERN_INFO "Stopping Core B\n"); + bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() | 0x0020); + bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080); + coreb_status &= ~COREB_IS_RUNNING; + spin_lock_irq(&coreb_lock); + break; + case CMD_COREB_RESET: + printk(KERN_INFO "Resetting Core B\n"); + bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080); + break; +#endif + } + + return retval; +} + +static struct file_operations coreb_fops = { + .owner = THIS_MODULE, + .llseek = coreb_lseek, + .read = coreb_read, + .write = coreb_write, + .ioctl = coreb_ioctl, + .open = coreb_open, + .release = coreb_release +}; + +static struct miscdevice coreb_dev = { + COREB_MINOR, + "coreb", + &coreb_fops +}; + +static ssize_t coreb_show_status(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, + "Base Address:\t0x%08lx\n" + "Core B is %s\n" + "SICA_SYSCR:\t%04x\n" + "SICB_SYSCR:\t%04x\n" + "\n" + "IRQ Status:\tCore A\t\tCore B\n" + "ISR0:\t\t%08x\t\t%08x\n" + "ISR1:\t\t%08x\t\t%08x\n" + "IMASK0:\t\t%08x\t\t%08x\n" + "IMASK1:\t\t%08x\t\t%08x\n", + coreb_base, + coreb_status & COREB_IS_RUNNING ? "running" : "stalled", + bfin_read_SICA_SYSCR(), bfin_read_SICB_SYSCR(), + bfin_read_SICA_ISR0(), bfin_read_SICB_ISR0(), + bfin_read_SICA_ISR1(), bfin_read_SICB_ISR0(), + bfin_read_SICA_IMASK0(), bfin_read_SICB_IMASK0(), + bfin_read_SICA_IMASK1(), bfin_read_SICB_IMASK1()); +} + +static DEVICE_ATTR(coreb_status, S_IRUGO, coreb_show_status, NULL); + +int __init bf561_coreb_init(void) +{ + init_waitqueue_head(&coreb_dma_wait); + + spin_lock_init(&coreb_lock); + /* Request the core memory regions for Core B */ + if (request_mem_region(0xff600000, 0x4000, + "Core B - Instruction SRAM") == NULL) + goto exit; + + if (request_mem_region(0xFF610000, 0x4000, + "Core B - Instruction SRAM") == NULL) + goto release_instruction_a_sram; + + if (request_mem_region(0xFF500000, 0x8000, + "Core B - Data Bank B SRAM") == NULL) + goto release_instruction_b_sram; + + if (request_mem_region(0xff400000, 0x8000, + "Core B - Data Bank A SRAM") == NULL) + goto release_data_b_sram; + + if (request_dma(CH_MEM_STREAM2_DEST, "Core B - DMA Destination") < 0) + goto release_data_a_sram; + + if (request_dma(CH_MEM_STREAM2_SRC, "Core B - DMA Source") < 0) + goto release_dma_dest; + + set_dma_callback(CH_MEM_STREAM2_DEST, coreb_dma_interrupt, NULL); + + misc_register(&coreb_dev); + + if (device_create_file(coreb_dev.this_device, &dev_attr_coreb_status)) + goto release_dma_src; + + printk(KERN_INFO "BF561 Core B driver %s initialized.\n", MODULE_VER); + return 0; + + release_dma_src: + free_dma(CH_MEM_STREAM2_SRC); + release_dma_dest: + free_dma(CH_MEM_STREAM2_DEST); + release_data_a_sram: + release_mem_region(0xff400000, 0x8000); + release_data_b_sram: + release_mem_region(0xff500000, 0x8000); + release_instruction_b_sram: + release_mem_region(0xff610000, 0x4000); + release_instruction_a_sram: + release_mem_region(0xff600000, 0x4000); + exit: + return -ENOMEM; +} + +void __exit bf561_coreb_exit(void) +{ + device_remove_file(coreb_dev.this_device, &dev_attr_coreb_status); + misc_deregister(&coreb_dev); + + release_mem_region(0xff610000, 0x4000); + release_mem_region(0xff600000, 0x4000); + release_mem_region(0xff500000, 0x8000); + release_mem_region(0xff400000, 0x8000); + + free_dma(CH_MEM_STREAM2_DEST); + free_dma(CH_MEM_STREAM2_SRC); +} + +module_init(bf561_coreb_init); +module_exit(bf561_coreb_exit); + +MODULE_AUTHOR("Bas Vermeulen "); +MODULE_DESCRIPTION("BF561 Core B Support"); diff --git a/arch/blackfin/mach-bf561/head.S b/arch/blackfin/mach-bf561/head.S new file mode 100644 index 000000000000..7bca478526b9 --- /dev/null +++ b/arch/blackfin/mach-bf561/head.S @@ -0,0 +1,512 @@ +/* + * File: arch/blackfin/mach-bf561/head.S + * Based on: arch/blackfin/mach-bf533/head.S + * Author: + * + * Created: + * Description: BF561 startup file + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#if CONFIG_BFIN_KERNEL_CLOCK +#include +#endif + +.global __rambase +.global __ramstart +.global __ramend +.extern ___bss_stop +.extern ___bss_start +.extern _bf53x_relocate_l1_mem + +#define INITIAL_STACK 0xFFB01000 + +.text + +ENTRY(__start) +ENTRY(__stext) + /* R0: argument of command line string, passed from uboot, save it */ + R7 = R0; + /* Set the SYSCFG register */ + R0 = 0x36; + SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/ + R0 = 0; + + /*Clear Out All the data and pointer Registers*/ + R1 = R0; + R2 = R0; + R3 = R0; + R4 = R0; + R5 = R0; + R6 = R0; + + P0 = R0; + P1 = R0; + P2 = R0; + P3 = R0; + P4 = R0; + P5 = R0; + + LC0 = r0; + LC1 = r0; + L0 = r0; + L1 = r0; + L2 = r0; + L3 = r0; + + /* Clear Out All the DAG Registers*/ + B0 = r0; + B1 = r0; + B2 = r0; + B3 = r0; + + I0 = r0; + I1 = r0; + I2 = r0; + I3 = r0; + + M0 = r0; + M1 = r0; + M2 = r0; + M3 = r0; + + /* Turn off the icache */ + p0.l = (IMEM_CONTROL & 0xFFFF); + p0.h = (IMEM_CONTROL >> 16); + R1 = [p0]; + R0 = ~ENICPLB; + R0 = R0 & R1; + + /* Anomaly 05000125 */ +#ifdef ANOMALY_05000125 + CLI R2; + SSYNC; +#endif + [p0] = R0; + SSYNC; +#ifdef ANOMALY_05000125 + STI R2; +#endif + + /* Turn off the dcache */ + p0.l = (DMEM_CONTROL & 0xFFFF); + p0.h = (DMEM_CONTROL >> 16); + R1 = [p0]; + R0 = ~ENDCPLB; + R0 = R0 & R1; + + /* Anomaly 05000125 */ +#ifdef ANOMALY_05000125 + CLI R2; + SSYNC; +#endif + [p0] = R0; + SSYNC; +#ifdef ANOMALY_05000125 + STI R2; +#endif + + /* Initialise UART*/ + p0.h = hi(UART_LCR); + p0.l = lo(UART_LCR); + r0 = 0x0(Z); + w[p0] = r0.L; /* To enable DLL writes */ + ssync; + + p0.h = hi(UART_DLL); + p0.l = lo(UART_DLL); + r0 = 0x0(Z); + w[p0] = r0.L; + ssync; + + p0.h = hi(UART_DLH); + p0.l = lo(UART_DLH); + r0 = 0x00(Z); + w[p0] = r0.L; + ssync; + + p0.h = hi(UART_GCTL); + p0.l = lo(UART_GCTL); + r0 = 0x0(Z); + w[p0] = r0.L; /* To enable UART clock */ + ssync; + + /* Initialize stack pointer */ + sp.l = lo(INITIAL_STACK); + sp.h = hi(INITIAL_STACK); + fp = sp; + usp = sp; + + /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ + call _bf53x_relocate_l1_mem; +#if CONFIG_BFIN_KERNEL_CLOCK + call _start_dma_code; +#endif + + /* Code for initializing Async memory banks */ + + p2.h = hi(EBIU_AMBCTL1); + p2.l = lo(EBIU_AMBCTL1); + r0.h = hi(AMBCTL1VAL); + r0.l = lo(AMBCTL1VAL); + [p2] = r0; + ssync; + + p2.h = hi(EBIU_AMBCTL0); + p2.l = lo(EBIU_AMBCTL0); + r0.h = hi(AMBCTL0VAL); + r0.l = lo(AMBCTL0VAL); + [p2] = r0; + ssync; + + p2.h = hi(EBIU_AMGCTL); + p2.l = lo(EBIU_AMGCTL); + r0 = AMGCTLVAL; + w[p2] = r0; + ssync; + + /* This section keeps the processor in supervisor mode + * during kernel boot. Switches to user mode at end of boot. + * See page 3-9 of Hardware Reference manual for documentation. + */ + + /* EVT15 = _real_start */ + + p0.l = lo(EVT15); + p0.h = hi(EVT15); + p1.l = _real_start; + p1.h = _real_start; + [p0] = p1; + csync; + + p0.l = lo(IMASK); + p0.h = hi(IMASK); + p1.l = IMASK_IVG15; + p1.h = 0x0; + [p0] = p1; + csync; + + raise 15; + p0.l = .LWAIT_HERE; + p0.h = .LWAIT_HERE; + reti = p0; +#if defined(ANOMALY_05000281) + nop; nop; nop; +#endif + rti; + +.LWAIT_HERE: + jump .LWAIT_HERE; + +ENTRY(_real_start) + [ -- sp ] = reti; + p0.l = lo(WDOGA_CTL); + p0.h = hi(WDOGA_CTL); + r0 = 0xAD6(z); + w[p0] = r0; /* watchdog off for now */ + ssync; + + /* Code update for BSS size == 0 + * Zero out the bss region. + */ + + p1.l = ___bss_start; + p1.h = ___bss_start; + p2.l = ___bss_stop; + p2.h = ___bss_stop; + r0 = 0; + p2 -= p1; + lsetup (.L_clear_bss, .L_clear_bss ) lc0 = p2; +.L_clear_bss: + B[p1++] = r0; + + /* In case there is a NULL pointer reference + * Zero out region before stext + */ + + p1.l = 0x0; + p1.h = 0x0; + r0.l = __stext; + r0.h = __stext; + r0 = r0 >> 1; + p2 = r0; + r0 = 0; + lsetup (.L_clear_zero, .L_clear_zero ) lc0 = p2; +.L_clear_zero: + W[p1++] = r0; + +/* pass the uboot arguments to the global value command line */ + R0 = R7; + call _cmdline_init; + + p1.l = __rambase; + p1.h = __rambase; + r0.l = __sdata; + r0.h = __sdata; + [p1] = r0; + + p1.l = __ramstart; + p1.h = __ramstart; + p3.l = ___bss_stop; + p3.h = ___bss_stop; + + r1 = p3; + [p1] = r1; + + /* + * load the current thread pointer and stack + */ + r1.l = _init_thread_union; + r1.h = _init_thread_union; + + r2.l = 0x2000; + r2.h = 0x0000; + r1 = r1 + r2; + sp = r1; + usp = sp; + fp = sp; + call _start_kernel; +.L_exit: + jump.s .L_exit; + +.section .l1.text +#if CONFIG_BFIN_KERNEL_CLOCK +ENTRY(_start_dma_code) + p0.h = hi(SICA_IWR0); + p0.l = lo(SICA_IWR0); + r0.l = 0x1; + [p0] = r0; + SSYNC; + + /* + * Set PLL_CTL + * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors + * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK + * - [7] = output delay (add 200ps of delay to mem signals) + * - [6] = input delay (add 200ps of input delay to mem signals) + * - [5] = PDWN : 1=All Clocks off + * - [3] = STOPCK : 1=Core Clock off + * - [1] = PLL_OFF : 1=Disable Power to PLL + * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL + * all other bits set to zero + */ + + p0.h = hi(PLL_LOCKCNT); + p0.l = lo(PLL_LOCKCNT); + r0 = 0x300(Z); + w[p0] = r0.l; + ssync; + + P2.H = hi(EBIU_SDGCTL); + P2.L = lo(EBIU_SDGCTL); + R0 = [P2]; + BITSET (R0, 24); + [P2] = R0; + SSYNC; + + r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */ + r0 = r0 << 9; /* Shift it over, */ + r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/ + r0 = r1 | r0; + r1 = PLL_BYPASS; /* Bypass the PLL? */ + r1 = r1 << 8; /* Shift it over */ + r0 = r1 | r0; /* add them all together */ + + p0.h = hi(PLL_CTL); + p0.l = lo(PLL_CTL); /* Load the address */ + cli r2; /* Disable interrupts */ + ssync; + w[p0] = r0.l; /* Set the value */ + idle; /* Wait for the PLL to stablize */ + sti r2; /* Enable interrupts */ + +.Lcheck_again: + p0.h = hi(PLL_STAT); + p0.l = lo(PLL_STAT); + R0 = W[P0](Z); + CC = BITTST(R0,5); + if ! CC jump .Lcheck_again; + + /* Configure SCLK & CCLK Dividers */ + r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV); + p0.h = hi(PLL_DIV); + p0.l = lo(PLL_DIV); + w[p0] = r0.l; + ssync; + + p0.l = lo(EBIU_SDRRC); + p0.h = hi(EBIU_SDRRC); + r0 = mem_SDRRC; + w[p0] = r0.l; + ssync; + + p0.l = (EBIU_SDBCTL & 0xFFFF); + p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */ + r0 = mem_SDBCTL; + w[p0] = r0.l; + ssync; + + P2.H = hi(EBIU_SDGCTL); + P2.L = lo(EBIU_SDGCTL); + R0 = [P2]; + BITCLR (R0, 24); + p0.h = hi(EBIU_SDSTAT); + p0.l = lo(EBIU_SDSTAT); + r2.l = w[p0]; + cc = bittst(r2,3); + if !cc jump .Lskip; + NOP; + BITSET (R0, 23); +.Lskip: + [P2] = R0; + SSYNC; + + R0.L = lo(mem_SDGCTL); + R0.H = hi(mem_SDGCTL); + R1 = [p2]; + R1 = R1 | R0; + [P2] = R1; + SSYNC; + + RTS; +#endif /* CONFIG_BFIN_KERNEL_CLOCK */ + +ENTRY(_bfin_reset) + /* No more interrupts to be handled*/ + CLI R6; + SSYNC; + +#if defined(CONFIG_BFIN_SHARED_FLASH_ENET) + p0.h = hi(FIO_INEN); + p0.l = lo(FIO_INEN); + r0.l = ~(PF1 | PF0); + w[p0] = r0.l; + + p0.h = hi(FIO_DIR); + p0.l = lo(FIO_DIR); + r0.l = (PF1 | PF0); + w[p0] = r0.l; + + p0.h = hi(FIO_FLAG_C); + p0.l = lo(FIO_FLAG_C); + r0.l = (PF1 | PF0); + w[p0] = r0.l; +#endif + + /* Clear the bits 13-15 in SWRST if they werent cleared */ + p0.h = hi(SICA_SWRST); + p0.l = lo(SICA_SWRST); + csync; + r0.l = w[p0]; + + /* Clear the IMASK register */ + p0.h = hi(IMASK); + p0.l = lo(IMASK); + r0 = 0x0; + [p0] = r0; + + /* Clear the ILAT register */ + p0.h = hi(ILAT); + p0.l = lo(ILAT); + r0 = [p0]; + [p0] = r0; + SSYNC; + + /* Disable the WDOG TIMER */ + p0.h = hi(WDOGA_CTL); + p0.l = lo(WDOGA_CTL); + r0.l = 0xAD6; + w[p0] = r0.l; + SSYNC; + + /* Clear the sticky bit incase it is already set */ + p0.h = hi(WDOGA_CTL); + p0.l = lo(WDOGA_CTL); + r0.l = 0x8AD6; + w[p0] = r0.l; + SSYNC; + + /* Program the count value */ + R0.l = 0x100; + R0.h = 0x0; + P0.h = hi(WDOGA_CNT); + P0.l = lo(WDOGA_CNT); + [P0] = R0; + SSYNC; + + /* Program WDOG_STAT if necessary */ + P0.h = hi(WDOGA_CTL); + P0.l = lo(WDOGA_CTL); + R0 = W[P0](Z); + CC = BITTST(R0,1); + if !CC JUMP .LWRITESTAT; + CC = BITTST(R0,2); + if !CC JUMP .LWRITESTAT; + JUMP .LSKIP_WRITE; + +.LWRITESTAT: + /* When watch dog timer is enabled, + * a write to STAT will load the contents of CNT to STAT + */ + R0 = 0x0000(z); + P0.h = hi(WDOGA_STAT); + P0.l = lo(WDOGA_STAT) + [P0] = R0; + SSYNC; + +.LSKIP_WRITE: + /* Enable the reset event */ + P0.h = hi(WDOGA_CTL); + P0.l = lo(WDOGA_CTL); + R0 = W[P0](Z); + BITCLR(R0,1); + BITCLR(R0,2); + W[P0] = R0.L; + SSYNC; + NOP; + + /* Enable the wdog counter */ + R0 = W[P0](Z); + BITCLR(R0,4); + W[P0] = R0.L; + SSYNC; + + IDLE; + + RTS; + +.data + +/* + * Set up the usable of RAM stuff. Size of RAM is determined then + * an initial stack set up at the end. + */ + +.align 4 +__rambase: +.long 0 +__ramstart: +.long 0 +__ramend: +.long 0 diff --git a/arch/blackfin/mach-bf561/ints-priority.c b/arch/blackfin/mach-bf561/ints-priority.c new file mode 100644 index 000000000000..89c52ff95b27 --- /dev/null +++ b/arch/blackfin/mach-bf561/ints-priority.c @@ -0,0 +1,108 @@ +/* + * File: arch/blackfin/mach-bf561/ints-priority.c + * Based on: arch/blackfin/mach-bf537/ints-priority.c + * Author: Michael Hennerich + * + * Created: + * Description: Set up the interupt priorities + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +void program_IAR(void) +{ + /* Program the IAR0 Register with the configured priority */ + bfin_write_SICA_IAR0(((CONFIG_IRQ_PLL_WAKEUP - 7) << IRQ_PLL_WAKEUP_POS) | + ((CONFIG_IRQ_DMA1_ERROR - 7) << IRQ_DMA1_ERROR_POS) | + ((CONFIG_IRQ_DMA2_ERROR - 7) << IRQ_DMA2_ERROR_POS) | + ((CONFIG_IRQ_IMDMA_ERROR - 7) << IRQ_IMDMA_ERROR_POS) | + ((CONFIG_IRQ_PPI0_ERROR - 7) << IRQ_PPI0_ERROR_POS) | + ((CONFIG_IRQ_PPI1_ERROR - 7) << IRQ_PPI1_ERROR_POS) | + ((CONFIG_IRQ_SPORT0_ERROR - 7) << IRQ_SPORT0_ERROR_POS) | + ((CONFIG_IRQ_SPORT1_ERROR - 7) << IRQ_SPORT1_ERROR_POS)); + + bfin_write_SICA_IAR1(((CONFIG_IRQ_SPI_ERROR - 7) << IRQ_SPI_ERROR_POS) | + ((CONFIG_IRQ_UART_ERROR - 7) << IRQ_UART_ERROR_POS) | + ((CONFIG_IRQ_RESERVED_ERROR - 7) << IRQ_RESERVED_ERROR_POS) | + ((CONFIG_IRQ_DMA1_0 - 7) << IRQ_DMA1_0_POS) | + ((CONFIG_IRQ_DMA1_1 - 7) << IRQ_DMA1_1_POS) | + ((CONFIG_IRQ_DMA1_2 - 7) << IRQ_DMA1_2_POS) | + ((CONFIG_IRQ_DMA1_3 - 7) << IRQ_DMA1_3_POS) | + ((CONFIG_IRQ_DMA1_4 - 7) << IRQ_DMA1_4_POS)); + + bfin_write_SICA_IAR2(((CONFIG_IRQ_DMA1_5 - 7) << IRQ_DMA1_5_POS) | + ((CONFIG_IRQ_DMA1_6 - 7) << IRQ_DMA1_6_POS) | + ((CONFIG_IRQ_DMA1_7 - 7) << IRQ_DMA1_7_POS) | + ((CONFIG_IRQ_DMA1_8 - 7) << IRQ_DMA1_8_POS) | + ((CONFIG_IRQ_DMA1_9 - 7) << IRQ_DMA1_9_POS) | + ((CONFIG_IRQ_DMA1_10 - 7) << IRQ_DMA1_10_POS) | + ((CONFIG_IRQ_DMA1_11 - 7) << IRQ_DMA1_11_POS) | + ((CONFIG_IRQ_DMA2_0 - 7) << IRQ_DMA2_0_POS)); + + bfin_write_SICA_IAR3(((CONFIG_IRQ_DMA2_1 - 7) << IRQ_DMA2_1_POS) | + ((CONFIG_IRQ_DMA2_2 - 7) << IRQ_DMA2_2_POS) | + ((CONFIG_IRQ_DMA2_3 - 7) << IRQ_DMA2_3_POS) | + ((CONFIG_IRQ_DMA2_4 - 7) << IRQ_DMA2_4_POS) | + ((CONFIG_IRQ_DMA2_5 - 7) << IRQ_DMA2_5_POS) | + ((CONFIG_IRQ_DMA2_6 - 7) << IRQ_DMA2_6_POS) | + ((CONFIG_IRQ_DMA2_7 - 7) << IRQ_DMA2_7_POS) | + ((CONFIG_IRQ_DMA2_8 - 7) << IRQ_DMA2_8_POS)); + + bfin_write_SICA_IAR4(((CONFIG_IRQ_DMA2_9 - 7) << IRQ_DMA2_9_POS) | + ((CONFIG_IRQ_DMA2_10 - 7) << IRQ_DMA2_10_POS) | + ((CONFIG_IRQ_DMA2_11 - 7) << IRQ_DMA2_11_POS) | + ((CONFIG_IRQ_TIMER0 - 7) << IRQ_TIMER0_POS) | + ((CONFIG_IRQ_TIMER1 - 7) << IRQ_TIMER1_POS) | + ((CONFIG_IRQ_TIMER2 - 7) << IRQ_TIMER2_POS) | + ((CONFIG_IRQ_TIMER3 - 7) << IRQ_TIMER3_POS) | + ((CONFIG_IRQ_TIMER4 - 7) << IRQ_TIMER4_POS)); + + bfin_write_SICA_IAR5(((CONFIG_IRQ_TIMER5 - 7) << IRQ_TIMER5_POS) | + ((CONFIG_IRQ_TIMER6 - 7) << IRQ_TIMER6_POS) | + ((CONFIG_IRQ_TIMER7 - 7) << IRQ_TIMER7_POS) | + ((CONFIG_IRQ_TIMER8 - 7) << IRQ_TIMER8_POS) | + ((CONFIG_IRQ_TIMER9 - 7) << IRQ_TIMER9_POS) | + ((CONFIG_IRQ_TIMER10 - 7) << IRQ_TIMER10_POS) | + ((CONFIG_IRQ_TIMER11 - 7) << IRQ_TIMER11_POS) | + ((CONFIG_IRQ_PROG0_INTA - 7) << IRQ_PROG0_INTA_POS)); + + bfin_write_SICA_IAR6(((CONFIG_IRQ_PROG0_INTB - 7) << IRQ_PROG0_INTB_POS) | + ((CONFIG_IRQ_PROG1_INTA - 7) << IRQ_PROG1_INTA_POS) | + ((CONFIG_IRQ_PROG1_INTB - 7) << IRQ_PROG1_INTB_POS) | + ((CONFIG_IRQ_PROG2_INTA - 7) << IRQ_PROG2_INTA_POS) | + ((CONFIG_IRQ_PROG2_INTB - 7) << IRQ_PROG2_INTB_POS) | + ((CONFIG_IRQ_DMA1_WRRD0 - 7) << IRQ_DMA1_WRRD0_POS) | + ((CONFIG_IRQ_DMA1_WRRD1 - 7) << IRQ_DMA1_WRRD1_POS) | + ((CONFIG_IRQ_DMA2_WRRD0 - 7) << IRQ_DMA2_WRRD0_POS)); + + bfin_write_SICA_IAR7(((CONFIG_IRQ_DMA2_WRRD1 - 7) << IRQ_DMA2_WRRD1_POS) | + ((CONFIG_IRQ_IMDMA_WRRD0 - 7) << IRQ_IMDMA_WRRD0_POS) | + ((CONFIG_IRQ_IMDMA_WRRD1 - 7) << IRQ_IMDMA_WRRD1_POS) | + ((CONFIG_IRQ_WDTIMER - 7) << IRQ_WDTIMER_POS) | + (0 << IRQ_RESERVED_1_POS) | (0 << IRQ_RESERVED_2_POS) | + (0 << IRQ_SUPPLE_0_POS) | (0 << IRQ_SUPPLE_1_POS)); + + SSYNC(); +} diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile new file mode 100644 index 000000000000..d3a49073d196 --- /dev/null +++ b/arch/blackfin/mach-common/Makefile @@ -0,0 +1,12 @@ +# +# arch/blackfin/mach-common/Makefile +# + +obj-y := \ + cache.o cacheinit.o cplbhdlr.o cplbmgr.o entry.o \ + interrupt.o lock.o dpmc.o irqpanic.o + +obj-$(CONFIG_CPLB_INFO) += cplbinfo.o +obj-$(CONFIG_BFIN_SINGLE_CORE) += ints-priority-sc.o +obj-$(CONFIG_BFIN_DUAL_CORE) += ints-priority-dc.o +obj-$(CONFIG_PM) += pm.o diff --git a/arch/blackfin/mach-common/cache.S b/arch/blackfin/mach-common/cache.S new file mode 100644 index 000000000000..bb9446ef66ef --- /dev/null +++ b/arch/blackfin/mach-common/cache.S @@ -0,0 +1,253 @@ +/* + * File: arch/blackfin/mach-common/cache.S + * Based on: + * Author: LG Soft India + * + * Created: + * Description: cache control support + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +.text +.align 2 +ENTRY(_cache_invalidate) + + /* + * Icache or DcacheA or DcacheB Invalidation + * or any combination thereof + * R0 has bits + * CPLB_ENABLE_ICACHE_P,CPLB_ENABLE_DCACHE_P,CPLB_ENABLE_DCACHE2_P + * set as required + */ + [--SP] = R7; + + R7 = R0; + CC = BITTST(R7,CPLB_ENABLE_ICACHE_P); + IF !CC JUMP .Lno_icache; + [--SP] = RETS; + CALL _icache_invalidate; + RETS = [SP++]; +.Lno_icache: + CC = BITTST(R7,CPLB_ENABLE_DCACHE_P); + IF !CC JUMP .Lno_dcache_a; + R0 = 0; /* specifies bank A */ + [--SP] = RETS; + CALL _dcache_invalidate; + RETS = [SP++]; +.Lno_dcache_a: + CC = BITTST(R7,CPLB_ENABLE_DCACHE2_P); + IF !CC JUMP .Lno_dcache_b; + R0 = 0; + BITSET(R0, 23); /* specifies bank B */ + [--SP] = RETS; + CALL _dcache_invalidate; + RETS = [SP++]; +.Lno_dcache_b: + R7 = [SP++]; + RTS; + +/* Invalidate the Entire Instruction cache by + * disabling IMC bit + */ +ENTRY(_icache_invalidate) +ENTRY(_invalidate_entire_icache) + [--SP] = ( R7:5); + + P0.L = (IMEM_CONTROL & 0xFFFF); + P0.H = (IMEM_CONTROL >> 16); + R7 = [P0]; + + /* Clear the IMC bit , All valid bits in the instruction + * cache are set to the invalid state + */ + BITCLR(R7,IMC_P); + CLI R6; + SSYNC; /* SSYNC required before invalidating cache. */ + .align 8; + [P0] = R7; + SSYNC; + STI R6; + + /* Configures the instruction cache agian */ + R6 = (IMC | ENICPLB); + R7 = R7 | R6; + + CLI R6; + SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ + .align 8; + [P0] = R7; + SSYNC; + STI R6; + + ( R7:5) = [SP++]; + RTS; + +/* + * blackfin_cache_flush_range(start, end) + * Invalidate all cache lines assocoiated with this + * area of memory. + * + * start: Start address + * end: End address + */ +ENTRY(_blackfin_icache_flush_range) + R2 = -L1_CACHE_BYTES; + R2 = R0 & R2; + P0 = R2; + P1 = R1; + CSYNC; + IFLUSH [P0]; +1: + IFLUSH [P0++]; + CC = P0 < P1 (iu); + IF CC JUMP 1b (bp); + IFLUSH [P0]; + SSYNC; + RTS; + +/* + * blackfin_icache_dcache_flush_range(start, end) + * FLUSH all cache lines assocoiated with this + * area of memory. + * + * start: Start address + * end: End address + */ + +ENTRY(_blackfin_icache_dcache_flush_range) + R2 = -L1_CACHE_BYTES; + R2 = R0 & R2; + P0 = R2; + P1 = R1; + CSYNC; + IFLUSH [P0]; +1: + FLUSH [P0]; + IFLUSH [P0++]; + CC = P0 < P1 (iu); + IF CC JUMP 1b (bp); + IFLUSH [P0]; + FLUSH [P0]; + SSYNC; + RTS; + +/* Throw away all D-cached data in specified region without any obligation to + * write them back. However, we must clean the D-cached entries around the + * boundaries of the start and/or end address is not cache aligned. + * + * Start: start address, + * end : end address. + */ + +ENTRY(_blackfin_dcache_invalidate_range) + R2 = -L1_CACHE_BYTES; + R2 = R0 & R2; + P0 = R2; + P1 = R1; + CSYNC; + FLUSHINV[P0]; +1: + FLUSHINV[P0++]; + CC = P0 < P1 (iu); + IF CC JUMP 1b (bp); + + /* If the data crosses a cache line, then we'll be pointing to + * the last cache line, but won't have flushed/invalidated it yet, + * so do one more. + */ + FLUSHINV[P0]; + SSYNC; + RTS; + +/* Invalidate the Entire Data cache by + * clearing DMC[1:0] bits + */ +ENTRY(_invalidate_entire_dcache) +ENTRY(_dcache_invalidate) + [--SP] = ( R7:6); + + P0.L = (DMEM_CONTROL & 0xFFFF); + P0.H = (DMEM_CONTROL >> 16); + R7 = [P0]; + + /* Clear the DMC[1:0] bits, All valid bits in the data + * cache are set to the invalid state + */ + BITCLR(R7,DMC0_P); + BITCLR(R7,DMC1_P); + CLI R6; + SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ + .align 8; + [P0] = R7; + SSYNC; + STI R6; + + /* Configures the data cache again */ + + R6 = DMEM_CNTR; + R7 = R7 | R6; + + CLI R6; + SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ + .align 8; + [P0] = R7; + SSYNC; + STI R6; + + ( R7:6) = [SP++]; + RTS; + +ENTRY(_blackfin_dcache_flush_range) + R2 = -L1_CACHE_BYTES; + R2 = R0 & R2; + P0 = R2; + P1 = R1; + CSYNC; + FLUSH[P0]; +1: + FLUSH[P0++]; + CC = P0 < P1 (iu); + IF CC JUMP 1b (bp); + + /* If the data crosses a cache line, then we'll be pointing to + * the last cache line, but won't have flushed it yet, so do + * one more. + */ + FLUSH[P0]; + SSYNC; + RTS; + +ENTRY(_blackfin_dflush_page) + P1 = 1 << (PAGE_SHIFT - L1_CACHE_SHIFT); + P0 = R0; + CSYNC; + FLUSH[P0]; + LSETUP (.Lfl1, .Lfl1) LC0 = P1; +.Lfl1: FLUSH [P0++]; + SSYNC; + RTS; diff --git a/arch/blackfin/mach-common/cacheinit.S b/arch/blackfin/mach-common/cacheinit.S new file mode 100644 index 000000000000..8c17f099e5eb --- /dev/null +++ b/arch/blackfin/mach-common/cacheinit.S @@ -0,0 +1,137 @@ +/* + * File: arch/blackfin/mach-common/cacheinit.S + * Based on: + * Author: LG Soft India + * + * Created: ? + * Description: cache initialization + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* This function sets up the data and instruction cache. The + * tables like icplb table, dcplb table and Page Descriptor table + * are defined in cplbtab.h. You can configure those tables for + * your suitable requirements + */ + +#include +#include + +.text + +#if defined(CONFIG_BLKFIN_CACHE) +ENTRY(_bfin_icache_init) + + /* Initialize Instruction CPLBS */ + + I0.L = (ICPLB_ADDR0 & 0xFFFF); + I0.H = (ICPLB_ADDR0 >> 16); + + I1.L = (ICPLB_DATA0 & 0xFFFF); + I1.H = (ICPLB_DATA0 >> 16); + + I2.L = _icplb_table; + I2.H = _icplb_table; + + r1 = -1; /* end point comparison */ + r3 = 15; /* max counter */ + +/* read entries from table */ + +.Lread_iaddr: + R0 = [I2++]; + CC = R0 == R1; + IF CC JUMP .Lidone; + [I0++] = R0; + +.Lread_idata: + R2 = [I2++]; + [I1++] = R2; + R3 = R3 + R1; + CC = R3 == R1; + IF !CC JUMP .Lread_iaddr; + +.Lidone: + /* Enable Instruction Cache */ + P0.l = (IMEM_CONTROL & 0xFFFF); + P0.h = (IMEM_CONTROL >> 16); + R1 = [P0]; + R0 = (IMC | ENICPLB); + R0 = R0 | R1; + + /* Anomaly 05000125 */ + CLI R2; + SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ + .align 8; + [P0] = R0; + SSYNC; + STI R2; + RTS; +#endif + +#if defined(CONFIG_BLKFIN_DCACHE) +ENTRY(_bfin_dcache_init) + + /* Initialize Data CPLBS */ + + I0.L = (DCPLB_ADDR0 & 0xFFFF); + I0.H = (DCPLB_ADDR0 >> 16); + + I1.L = (DCPLB_DATA0 & 0xFFFF); + I1.H = (DCPLB_DATA0 >> 16); + + I2.L = _dcplb_table; + I2.H = _dcplb_table; + + R1 = -1; /* end point comparison */ + R3 = 15; /* max counter */ + + /* read entries from table */ +.Lread_daddr: + R0 = [I2++]; + cc = R0 == R1; + IF CC JUMP .Lddone; + [I0++] = R0; + +.Lread_ddata: + R2 = [I2++]; + [I1++] = R2; + R3 = R3 + R1; + CC = R3 == R1; + IF !CC JUMP .Lread_daddr; +.Lddone: + P0.L = (DMEM_CONTROL & 0xFFFF); + P0.H = (DMEM_CONTROL >> 16); + R1 = [P0]; + + R0 = DMEM_CNTR; + + R0 = R0 | R1; + /* Anomaly 05000125 */ + CLI R2; + SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ + .align 8; + [P0] = R0; + SSYNC; + STI R2; + RTS; +#endif diff --git a/arch/blackfin/mach-common/cplbhdlr.S b/arch/blackfin/mach-common/cplbhdlr.S new file mode 100644 index 000000000000..b979067c49ef --- /dev/null +++ b/arch/blackfin/mach-common/cplbhdlr.S @@ -0,0 +1,130 @@ +/* + * File: arch/blackfin/mach-common/cplbhdlr.S + * Based on: + * Author: LG Soft India + * + * Created: ? + * Description: CPLB exception handler + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#ifdef CONFIG_EXCPT_IRQ_SYSC_L1 +.section .l1.text +#else +.text +#endif + +.type _cplb_mgr, STT_FUNC; +.type _panic_cplb_error, STT_FUNC; + +.align 2 + +.global __cplb_hdr; +.type __cplb_hdr, STT_FUNC; +ENTRY(__cplb_hdr) + R2 = SEQSTAT; + + /* Mask the contents of SEQSTAT and leave only EXCAUSE in R2 */ + R2 <<= 26; + R2 >>= 26; + + R1 = 0x23; /* Data access CPLB protection violation */ + CC = R2 == R1; + IF !CC JUMP .Lnot_data_write; + R0 = 2; /* is a write to data space*/ + JUMP .Lis_icplb_miss; + +.Lnot_data_write: + R1 = 0x2C; /* CPLB miss on an instruction fetch */ + CC = R2 == R1; + R0 = 0; /* is_data_miss == False*/ + IF CC JUMP .Lis_icplb_miss; + + R1 = 0x26; + CC = R2 == R1; + IF !CC JUMP .Lunknown; + + R0 = 1; /* is_data_miss == True*/ + +.Lis_icplb_miss: + +#if defined(CONFIG_BLKFIN_CACHE) || defined(CONFIG_BLKFIN_DCACHE) +# if defined(CONFIG_BLKFIN_CACHE) && !defined(CONFIG_BLKFIN_DCACHE) + R1 = CPLB_ENABLE_ICACHE; +# endif +# if !defined(CONFIG_BLKFIN_CACHE) && defined(CONFIG_BLKFIN_DCACHE) + R1 = CPLB_ENABLE_DCACHE; +# endif +# if defined(CONFIG_BLKFIN_CACHE) && defined(CONFIG_BLKFIN_DCACHE) + R1 = CPLB_ENABLE_DCACHE | CPLB_ENABLE_ICACHE; +# endif +#else + R1 = 0; +#endif + + [--SP] = RETS; + CALL _cplb_mgr; + RETS = [SP++]; + CC = R0 == 0; + IF !CC JUMP .Lnot_replaced; + RTS; + +/* + * Diagnostic exception handlers + */ +.Lunknown: + R0 = CPLB_UNKNOWN_ERR; + JUMP .Lcplb_error; + +.Lnot_replaced: + CC = R0 == CPLB_NO_UNLOCKED; + IF !CC JUMP .Lnext_check; + R0 = CPLB_NO_UNLOCKED; + JUMP .Lcplb_error; + +.Lnext_check: + CC = R0 == CPLB_NO_ADDR_MATCH; + IF !CC JUMP .Lnext_check2; + R0 = CPLB_NO_ADDR_MATCH; + JUMP .Lcplb_error; + +.Lnext_check2: + CC = R0 == CPLB_PROT_VIOL; + IF !CC JUMP .Lstrange_return_from_cplb_mgr; + R0 = CPLB_PROT_VIOL; + JUMP .Lcplb_error; + +.Lstrange_return_from_cplb_mgr: + IDLE; + CSYNC; + JUMP .Lstrange_return_from_cplb_mgr; + +.Lcplb_error: + R1 = sp; + SP += -12; + call _panic_cplb_error; + SP += 12; + JUMP _handle_bad_cplb; diff --git a/arch/blackfin/mach-common/cplbinfo.c b/arch/blackfin/mach-common/cplbinfo.c new file mode 100644 index 000000000000..d65fac39d1bf --- /dev/null +++ b/arch/blackfin/mach-common/cplbinfo.c @@ -0,0 +1,211 @@ +/* + * File: arch/blackfin/mach-common/cplbinfo.c + * Based on: + * Author: Sonic Zhang + * + * Created: Jan. 2005 + * Description: Display CPLB status + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#define CPLB_I 1 +#define CPLB_D 2 + +#define SYNC_SYS SSYNC() +#define SYNC_CORE CSYNC() + +#define CPLB_BIT_PAGESIZE 0x30000 + +static int page_size_table[4] = { + 0x00000400, /* 1K */ + 0x00001000, /* 4K */ + 0x00100000, /* 1M */ + 0x00400000 /* 4M */ +}; + +static char page_size_string_table[][4] = { "1K", "4K", "1M", "4M" }; + +static int cplb_find_entry(unsigned long *cplb_addr, + unsigned long *cplb_data, unsigned long addr, + unsigned long data) +{ + int ii; + + for (ii = 0; ii < 16; ii++) + if (addr >= cplb_addr[ii] && addr < cplb_addr[ii] + + page_size_table[(cplb_data[ii] & CPLB_BIT_PAGESIZE) >> 16] + && (cplb_data[ii] == data)) + return ii; + + return -1; +} + +static char *cplb_print_entry(char *buf, int type) +{ + unsigned long *p_addr = dpdt_table; + unsigned long *p_data = dpdt_table + 1; + unsigned long *p_icount = dpdt_swapcount_table; + unsigned long *p_ocount = dpdt_swapcount_table + 1; + unsigned long *cplb_addr = (unsigned long *)DCPLB_ADDR0; + unsigned long *cplb_data = (unsigned long *)DCPLB_DATA0; + int entry = 0, used_cplb = 0; + + if (type == CPLB_I) { + buf += sprintf(buf, "Instrction CPLB entry:\n"); + p_addr = ipdt_table; + p_data = ipdt_table + 1; + p_icount = ipdt_swapcount_table; + p_ocount = ipdt_swapcount_table + 1; + cplb_addr = (unsigned long *)ICPLB_ADDR0; + cplb_data = (unsigned long *)ICPLB_DATA0; + } else + buf += sprintf(buf, "Data CPLB entry:\n"); + + buf += sprintf(buf, "Address\t\tData\tSize\tValid\tLocked\tSwapin\ +\tiCount\toCount\n"); + + while (*p_addr != 0xffffffff) { + entry = cplb_find_entry(cplb_addr, cplb_data, *p_addr, *p_data); + if (entry >= 0) + used_cplb |= 1 << entry; + + buf += + sprintf(buf, + "0x%08lx\t0x%05lx\t%s\t%c\t%c\t%2d\t%ld\t%ld\n", + *p_addr, *p_data, + page_size_string_table[(*p_data & 0x30000) >> 16], + (*p_data & CPLB_VALID) ? 'Y' : 'N', + (*p_data & CPLB_LOCK) ? 'Y' : 'N', entry, *p_icount, + *p_ocount); + + p_addr += 2; + p_data += 2; + p_icount += 2; + p_ocount += 2; + } + + if (used_cplb != 0xffff) { + buf += sprintf(buf, "Unused/mismatched CPLBs:\n"); + + for (entry = 0; entry < 16; entry++) + if (0 == ((1 << entry) & used_cplb)) { + int flags = cplb_data[entry]; + buf += + sprintf(buf, + "%2d: 0x%08lx\t0x%05x\t%s\t%c\t%c\n", + entry, cplb_addr[entry], flags, + page_size_string_table[(flags & + 0x30000) >> + 16], + (flags & CPLB_VALID) ? 'Y' : 'N', + (flags & CPLB_LOCK) ? 'Y' : 'N'); + } + } + + buf += sprintf(buf, "\n"); + + return buf; +} + +static int cplbinfo_proc_output(char *buf) +{ + char *p; + + p = buf; + + p += sprintf(p, + "------------------ CPLB Information ------------------\n\n"); + + if (bfin_read_IMEM_CONTROL() & ENICPLB) + p = cplb_print_entry(p, CPLB_I); + else + p += sprintf(p, "Instruction CPLB is disabled.\n\n"); + + if (bfin_read_DMEM_CONTROL() & ENDCPLB) + p = cplb_print_entry(p, CPLB_D); + else + p += sprintf(p, "Data CPLB is disabled.\n"); + + return p - buf; +} + +static int cplbinfo_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len; + + len = cplbinfo_proc_output(page); + if (len <= off + count) + *eof = 1; + *start = page + off; + len -= off; + if (len > count) + len = count; + if (len < 0) + len = 0; + return len; +} + +static int cplbinfo_write_proc(struct file *file, const char __user *buffer, + unsigned long count, void *data) +{ + printk(KERN_INFO "Reset the CPLB swap in/out counts.\n"); + memset(ipdt_swapcount_table, 0, MAX_SWITCH_I_CPLBS * sizeof(unsigned long)); + memset(dpdt_swapcount_table, 0, MAX_SWITCH_D_CPLBS * sizeof(unsigned long)); + + return count; +} + +static int __init cplbinfo_init(void) +{ + struct proc_dir_entry *entry; + + if ((entry = create_proc_entry("cplbinfo", 0, NULL)) == NULL) { + return -ENOMEM; + } + + entry->read_proc = cplbinfo_read_proc; + entry->write_proc = cplbinfo_write_proc; + entry->data = NULL; + + return 0; +} + +static void __exit cplbinfo_exit(void) +{ + remove_proc_entry("cplbinfo", NULL); +} + +module_init(cplbinfo_init); +module_exit(cplbinfo_exit); diff --git a/arch/blackfin/mach-common/cplbmgr.S b/arch/blackfin/mach-common/cplbmgr.S new file mode 100644 index 000000000000..f5efc4bc65e6 --- /dev/null +++ b/arch/blackfin/mach-common/cplbmgr.S @@ -0,0 +1,607 @@ +/* + * File: arch/blackfin/mach-common/cplbmgtr.S + * Based on: + * Author: LG Soft India + * + * Created: ? + * Description: CPLB replacement routine for CPLB mismatch + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Usage: int _cplb_mgr(is_data_miss,int enable_cache) + * is_data_miss==2 => Mark as Dirty, write to the clean data page + * is_data_miss==1 => Replace a data CPLB. + * is_data_miss==0 => Replace an instruction CPLB. + * + * Returns: + * CPLB_RELOADED => Successfully updated CPLB table. + * CPLB_NO_UNLOCKED => All CPLBs are locked, so cannot be evicted. + * This indicates that the CPLBs in the configuration + * tablei are badly configured, as this should never + * occur. + * CPLB_NO_ADDR_MATCH => The address being accessed, that triggered the + * exception, is not covered by any of the CPLBs in + * the configuration table. The application is + * presumably misbehaving. + * CPLB_PROT_VIOL => The address being accessed, that triggered the + * exception, was not a first-write to a clean Write + * Back Data page, and so presumably is a genuine + * violation of the page's protection attributes. + * The application is misbehaving. + */ + +#include +#include +#include + +#ifdef CONFIG_EXCPT_IRQ_SYSC_L1 +.section .l1.text +#else +.text +#endif + +.align 2; +ENTRY(_cplb_mgr) + + [--SP]=( R7:4,P5:3 ); + + CC = R0 == 2; + IF CC JUMP .Ldcplb_write; + + CC = R0 == 0; + IF !CC JUMP .Ldcplb_miss_compare; + + /* ICPLB Miss Exception. We need to choose one of the + * currently-installed CPLBs, and replace it with one + * from the configuration table. + */ + + P4.L = (ICPLB_FAULT_ADDR & 0xFFFF); + P4.H = (ICPLB_FAULT_ADDR >> 16); + + P1 = 16; + P5.L = _page_size_table; + P5.H = _page_size_table; + + P0.L = (ICPLB_DATA0 & 0xFFFF); + P0.H = (ICPLB_DATA0 >> 16); + R4 = [P4]; /* Get faulting address*/ + R6 = 64; /* Advance past the fault address, which*/ + R6 = R6 + R4; /* we'll use if we find a match*/ + R3 = ((16 << 8) | 2); /* Extract mask, bits 16 and 17.*/ + + R5 = 0; +.Lisearch: + + R1 = [P0-0x100]; /* Address for this CPLB */ + + R0 = [P0++]; /* Info for this CPLB*/ + CC = BITTST(R0,0); /* Is the CPLB valid?*/ + IF !CC JUMP .Lnomatch; /* Skip it, if not.*/ + CC = R4 < R1(IU); /* If fault address less than page start*/ + IF CC JUMP .Lnomatch; /* then skip this one.*/ + R2 = EXTRACT(R0,R3.L) (Z); /* Get page size*/ + P1 = R2; + P1 = P5 + (P1<<2); /* index into page-size table*/ + R2 = [P1]; /* Get the page size*/ + R1 = R1 + R2; /* and add to page start, to get page end*/ + CC = R4 < R1(IU); /* and see whether fault addr is in page.*/ + IF !CC R4 = R6; /* If so, advance the address and finish loop.*/ + IF !CC JUMP .Lisearch_done; +.Lnomatch: + /* Go around again*/ + R5 += 1; + CC = BITTST(R5, 4); /* i.e CC = R5 >= 16*/ + IF !CC JUMP .Lisearch; + +.Lisearch_done: + I0 = R4; /* Fault address we'll search for*/ + + /* set up pointers */ + P0.L = (ICPLB_DATA0 & 0xFFFF); + P0.H = (ICPLB_DATA0 >> 16); + + /* The replacement procedure for ICPLBs */ + + P4.L = (IMEM_CONTROL & 0xFFFF); + P4.H = (IMEM_CONTROL >> 16); + + /* disable cplbs */ + R5 = [P4]; /* Control Register*/ + BITCLR(R5,ENICPLB_P); + CLI R1; + SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ + .align 8; + [P4] = R5; + SSYNC; + STI R1; + + R1 = -1; /* end point comparison */ + R3 = 16; /* counter */ + + /* Search through CPLBs for first non-locked entry */ + /* Overwrite it by moving everyone else up by 1 */ +.Licheck_lock: + R0 = [P0++]; + R3 = R3 + R1; + CC = R3 == R1; + IF CC JUMP .Lall_locked; + CC = BITTST(R0, 0); /* an invalid entry is good */ + IF !CC JUMP .Lifound_victim; + CC = BITTST(R0,1); /* but a locked entry isn't */ + IF CC JUMP .Licheck_lock; + +.Lifound_victim: +#ifdef CONFIG_CPLB_INFO + R7 = [P0 - 0x104]; + P2.L = _ipdt_table; + P2.H = _ipdt_table; + P3.L = _ipdt_swapcount_table; + P3.H = _ipdt_swapcount_table; + P3 += -4; +.Licount: + R2 = [P2]; /* address from config table */ + P2 += 8; + P3 += 8; + CC = R2==-1; + IF CC JUMP .Licount_done; + CC = R7==R2; + IF !CC JUMP .Licount; + R7 = [P3]; + R7 += 1; + [P3] = R7; + CSYNC; +.Licount_done: +#endif + LC0=R3; + LSETUP(.Lis_move,.Lie_move) LC0; +.Lis_move: + R0 = [P0]; + [P0 - 4] = R0; + R0 = [P0 - 0x100]; + [P0-0x104] = R0; +.Lie_move:P0+=4; + + /* We've made space in the ICPLB table, so that ICPLB15 + * is now free to be overwritten. Next, we have to determine + * which CPLB we need to install, from the configuration + * table. This is a matter of getting the start-of-page + * addresses and page-lengths from the config table, and + * determining whether the fault address falls within that + * range. + */ + + P2.L = _ipdt_table; + P2.H = _ipdt_table; +#ifdef CONFIG_CPLB_INFO + P3.L = _ipdt_swapcount_table; + P3.H = _ipdt_swapcount_table; + P3 += -8; +#endif + P0.L = _page_size_table; + P0.H = _page_size_table; + + /* Retrieve our fault address (which may have been advanced + * because the faulting instruction crossed a page boundary). + */ + + R0 = I0; + + /* An extraction pattern, to get the page-size bits from + * the CPLB data entry. Bits 16-17, so two bits at posn 16. + */ + + R1 = ((16<<8)|2); +.Linext: R4 = [P2++]; /* address from config table */ + R2 = [P2++]; /* data from config table */ +#ifdef CONFIG_CPLB_INFO + P3 += 8; +#endif + + CC = R4 == -1; /* End of config table*/ + IF CC JUMP .Lno_page_in_table; + + /* See if failed address > start address */ + CC = R4 <= R0(IU); + IF !CC JUMP .Linext; + + /* extract page size (17:16)*/ + R3 = EXTRACT(R2, R1.L) (Z); + + /* add page size to addr to get range */ + + P5 = R3; + P5 = P0 + (P5 << 2); /* scaled, for int access*/ + R3 = [P5]; + R3 = R3 + R4; + + /* See if failed address < (start address + page size) */ + CC = R0 < R3(IU); + IF !CC JUMP .Linext; + + /* We've found a CPLB in the config table that covers + * the faulting address, so install this CPLB into the + * last entry of the table. + */ + + P1.L = (ICPLB_DATA15 & 0xFFFF); /* ICPLB_DATA15 */ + P1.H = (ICPLB_DATA15 >> 16); + [P1] = R2; + [P1-0x100] = R4; +#ifdef CONFIG_CPLB_INFO + R3 = [P3]; + R3 += 1; + [P3] = R3; +#endif + + /* P4 points to IMEM_CONTROL, and R5 contains its old + * value, after we disabled ICPLBS. Re-enable them. + */ + + BITSET(R5,ENICPLB_P); + CLI R2; + SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ + .align 8; + [P4] = R5; + SSYNC; + STI R2; + + ( R7:4,P5:3 ) = [SP++]; + R0 = CPLB_RELOADED; + RTS; + +/* FAILED CASES*/ +.Lno_page_in_table: + ( R7:4,P5:3 ) = [SP++]; + R0 = CPLB_NO_ADDR_MATCH; + RTS; +.Lall_locked: + ( R7:4,P5:3 ) = [SP++]; + R0 = CPLB_NO_UNLOCKED; + RTS; +.Lprot_violation: + ( R7:4,P5:3 ) = [SP++]; + R0 = CPLB_PROT_VIOL; + RTS; + +.Ldcplb_write: + + /* if a DCPLB is marked as write-back (CPLB_WT==0), and + * it is clean (CPLB_DIRTY==0), then a write to the + * CPLB's page triggers a protection violation. We have to + * mark the CPLB as dirty, to indicate that there are + * pending writes associated with the CPLB. + */ + + P4.L = (DCPLB_STATUS & 0xFFFF); + P4.H = (DCPLB_STATUS >> 16); + P3.L = (DCPLB_DATA0 & 0xFFFF); + P3.H = (DCPLB_DATA0 >> 16); + R5 = [P4]; + + /* A protection violation can be caused by more than just writes + * to a clean WB page, so we have to ensure that: + * - It's a write + * - to a clean WB page + * - and is allowed in the mode the access occurred. + */ + + CC = BITTST(R5, 16); /* ensure it was a write*/ + IF !CC JUMP .Lprot_violation; + + /* to check the rest, we have to retrieve the DCPLB.*/ + + /* The low half of DCPLB_STATUS is a bit mask*/ + + R2 = R5.L (Z); /* indicating which CPLB triggered the event.*/ + R3 = 30; /* so we can use this to determine the offset*/ + R2.L = SIGNBITS R2; + R2 = R2.L (Z); /* into the DCPLB table.*/ + R3 = R3 - R2; + P4 = R3; + P3 = P3 + (P4<<2); + R3 = [P3]; /* Retrieve the CPLB*/ + + /* Now we can check whether it's a clean WB page*/ + + CC = BITTST(R3, 14); /* 0==WB, 1==WT*/ + IF CC JUMP .Lprot_violation; + CC = BITTST(R3, 7); /* 0 == clean, 1 == dirty*/ + IF CC JUMP .Lprot_violation; + + /* Check whether the write is allowed in the mode that was active.*/ + + R2 = 1<<3; /* checking write in user mode*/ + CC = BITTST(R5, 17); /* 0==was user, 1==was super*/ + R5 = CC; + R2 <<= R5; /* if was super, check write in super mode*/ + R2 = R3 & R2; + CC = R2 == 0; + IF CC JUMP .Lprot_violation; + + /* It's a genuine write-to-clean-page.*/ + + BITSET(R3, 7); /* mark as dirty*/ + [P3] = R3; /* and write back.*/ + NOP; + CSYNC; + ( R7:4,P5:3 ) = [SP++]; + R0 = CPLB_RELOADED; + RTS; + +.Ldcplb_miss_compare: + + /* Data CPLB Miss event. We need to choose a CPLB to + * evict, and then locate a new CPLB to install from the + * config table, that covers the faulting address. + */ + + P1.L = (DCPLB_DATA15 & 0xFFFF); + P1.H = (DCPLB_DATA15 >> 16); + + P4.L = (DCPLB_FAULT_ADDR & 0xFFFF); + P4.H = (DCPLB_FAULT_ADDR >> 16); + R4 = [P4]; + I0 = R4; + + /* The replacement procedure for DCPLBs*/ + + R6 = R1; /* Save for later*/ + + /* Turn off CPLBs while we work.*/ + P4.L = (DMEM_CONTROL & 0xFFFF); + P4.H = (DMEM_CONTROL >> 16); + R5 = [P4]; + BITCLR(R5,ENDCPLB_P); + CLI R0; + SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ + .align 8; + [P4] = R5; + SSYNC; + STI R0; + + /* Start looking for a CPLB to evict. Our order of preference + * is: invalid CPLBs, clean CPLBs, dirty CPLBs. Locked CPLBs + * are no good. + */ + + I1.L = (DCPLB_DATA0 & 0xFFFF); + I1.H = (DCPLB_DATA0 >> 16); + P1 = 2; + P2 = 16; + I2.L = _dcplb_preference; + I2.H = _dcplb_preference; + LSETUP(.Lsdsearch1, .Ledsearch1) LC0 = P1; +.Lsdsearch1: + R0 = [I2++]; /* Get the bits we're interested in*/ + P0 = I1; /* Go back to start of table*/ + LSETUP (.Lsdsearch2, .Ledsearch2) LC1 = P2; +.Lsdsearch2: + R1 = [P0++]; /* Fetch each installed CPLB in turn*/ + R2 = R1 & R0; /* and test for interesting bits.*/ + CC = R2 == 0; /* If none are set, it'll do.*/ + IF !CC JUMP .Lskip_stack_check; + + R2 = [P0 - 0x104]; /* R2 - PageStart */ + P3.L = _page_size_table; /* retrieve end address */ + P3.H = _page_size_table; /* retrieve end address */ + R3 = 0x1002; /* 16th - position, 2 bits -length */ +#ifdef ANOMALY_05000209 + nop; /* Anomaly 05000209 */ +#endif + R7 = EXTRACT(R1,R3.l); + R7 = R7 << 2; /* Page size index offset */ + P5 = R7; + P3 = P3 + P5; + R7 = [P3]; /* page size in bytes */ + + R7 = R2 + R7; /* R7 - PageEnd */ + R4 = SP; /* Test SP is in range */ + + CC = R7 < R4; /* if PageEnd < SP */ + IF CC JUMP .Ldfound_victim; + R3 = 0x284; /* stack length from start of trap till + * the point. + * 20 stack locations for future modifications + */ + R4 = R4 + R3; + CC = R4 < R2; /* if SP + stacklen < PageStart */ + IF CC JUMP .Ldfound_victim; +.Lskip_stack_check: + +.Ledsearch2: NOP; +.Ledsearch1: NOP; + + /* If we got here, we didn't find a DCPLB we considered + * replacable, which means all of them were locked. + */ + + JUMP .Lall_locked; +.Ldfound_victim: + +#ifdef CONFIG_CPLB_INFO + R7 = [P0 - 0x104]; + P2.L = _dpdt_table; + P2.H = _dpdt_table; + P3.L = _dpdt_swapcount_table; + P3.H = _dpdt_swapcount_table; + P3 += -4; +.Ldicount: + R2 = [P2]; + P2 += 8; + P3 += 8; + CC = R2==-1; + IF CC JUMP .Ldicount_done; + CC = R7==R2; + IF !CC JUMP .Ldicount; + R7 = [P3]; + R7 += 1; + [P3] = R7; +.Ldicount_done: +#endif + + /* Clean down the hardware loops*/ + R2 = 0; + LC1 = R2; + LC0 = R2; + + /* There's a suitable victim in [P0-4] (because we've + * advanced already). + */ + +.LDdoverwrite: + + /* [P0-4] is a suitable victim CPLB, so we want to + * overwrite it by moving all the following CPLBs + * one space closer to the start. + */ + + R1.L = (DCPLB_DATA16 & 0xFFFF); /* DCPLB_DATA15 + 4 */ + R1.H = (DCPLB_DATA16 >> 16); + R0 = P0; + + /* If the victim happens to be in DCPLB15, + * we don't need to move anything. + */ + + CC = R1 == R0; + IF CC JUMP .Lde_moved; + R1 = R1 - R0; + R1 >>= 2; + P1 = R1; + LSETUP(.Lds_move, .Lde_move) LC0=P1; +.Lds_move: + R0 = [P0++]; /* move data */ + [P0 - 8] = R0; + R0 = [P0-0x104] /* move address */ +.Lde_move: [P0-0x108] = R0; + + /* We've now made space in DCPLB15 for the new CPLB to be + * installed. The next stage is to locate a CPLB in the + * config table that covers the faulting address. + */ + +.Lde_moved:NOP; + R0 = I0; /* Our faulting address */ + + P2.L = _dpdt_table; + P2.H = _dpdt_table; +#ifdef CONFIG_CPLB_INFO + P3.L = _dpdt_swapcount_table; + P3.H = _dpdt_swapcount_table; + P3 += -8; +#endif + + P1.L = _page_size_table; + P1.H = _page_size_table; + + /* An extraction pattern, to retrieve bits 17:16.*/ + + R1 = (16<<8)|2; +.Ldnext: R4 = [P2++]; /* address */ + R2 = [P2++]; /* data */ +#ifdef CONFIG_CPLB_INFO + P3 += 8; +#endif + + CC = R4 == -1; + IF CC JUMP .Lno_page_in_table; + + /* See if failed address > start address */ + CC = R4 <= R0(IU); + IF !CC JUMP .Ldnext; + + /* extract page size (17:16)*/ + R3 = EXTRACT(R2, R1.L) (Z); + + /* add page size to addr to get range */ + + P5 = R3; + P5 = P1 + (P5 << 2); + R3 = [P5]; + R3 = R3 + R4; + + /* See if failed address < (start address + page size) */ + CC = R0 < R3(IU); + IF !CC JUMP .Ldnext; + + /* We've found the CPLB that should be installed, so + * write it into CPLB15, masking off any caching bits + * if necessary. + */ + + P1.L = (DCPLB_DATA15 & 0xFFFF); + P1.H = (DCPLB_DATA15 >> 16); + + /* If the DCPLB has cache bits set, but caching hasn't + * been enabled, then we want to mask off the cache-in-L1 + * bit before installing. Moreover, if caching is off, we + * also want to ensure that the DCPLB has WT mode set, rather + * than WB, since WB pages still trigger first-write exceptions + * even when not caching is off, and the page isn't marked as + * cachable. Finally, we could mark the page as clean, not dirty, + * but we choose to leave that decision to the user; if the user + * chooses to have a CPLB pre-defined as dirty, then they always + * pay the cost of flushing during eviction, but don't pay the + * cost of first-write exceptions to mark the page as dirty. + */ + +#ifdef CONFIG_BLKFIN_WT + BITSET(R6, 14); /* Set WT*/ +#endif + + [P1] = R2; + [P1-0x100] = R4; +#ifdef CONFIG_CPLB_INFO + R3 = [P3]; + R3 += 1; + [P3] = R3; +#endif + + /* We've installed the CPLB, so re-enable CPLBs. P4 + * points to DMEM_CONTROL, and R5 is the value we + * last wrote to it, when we were disabling CPLBs. + */ + + BITSET(R5,ENDCPLB_P); + CLI R2; + .align 8; + [P4] = R5; + SSYNC; + STI R2; + + ( R7:4,P5:3 ) = [SP++]; + R0 = CPLB_RELOADED; + RTS; + +.data +.align 4; +_page_size_table: +.byte4 0x00000400; /* 1K */ +.byte4 0x00001000; /* 4K */ +.byte4 0x00100000; /* 1M */ +.byte4 0x00400000; /* 4M */ + +.align 4; +_dcplb_preference: +.byte4 0x00000001; /* valid bit */ +.byte4 0x00000002; /* lock bit */ diff --git a/arch/blackfin/mach-common/dpmc.S b/arch/blackfin/mach-common/dpmc.S new file mode 100644 index 000000000000..97cdcd6a00d4 --- /dev/null +++ b/arch/blackfin/mach-common/dpmc.S @@ -0,0 +1,418 @@ +/* + * File: arch/blackfin/mach-common/dpmc.S + * Based on: + * Author: LG Soft India + * + * Created: ? + * Description: Watchdog Timer APIs + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +.text + +ENTRY(_unmask_wdog_wakeup_evt) + [--SP] = ( R7:0, P5:0 ); +#if defined(CONFIG_BF561) + P0.H = hi(SICA_IWR1); + P0.L = lo(SICA_IWR1); +#else + P0.h = (SIC_IWR >> 16); + P0.l = (SIC_IWR & 0xFFFF); +#endif + R7 = [P0]; +#if defined(CONFIG_BF561) + BITSET(R7, 27); +#else + BITSET(R7,(IRQ_WATCH - IVG7)); +#endif + [P0] = R7; + SSYNC; + + ( R7:0, P5:0 ) = [SP++]; + RTS; + +.LWRITE_TO_STAT: + /* When watch dog timer is enabled, a write to STAT will load the + * contents of CNT to STAT + */ + R7 = 0x0000(z); +#if defined(CONFIG_BF561) + P0.h = (WDOGA_STAT >> 16); + P0.l = (WDOGA_STAT & 0xFFFF); +#else + P0.h = (WDOG_STAT >> 16); + P0.l = (WDOG_STAT & 0xFFFF); +#endif + [P0] = R7; + SSYNC; + JUMP .LSKIP_WRITE_TO_STAT; + +ENTRY(_program_wdog_timer) + [--SP] = ( R7:0, P5:0 ); +#if defined(CONFIG_BF561) + P0.h = (WDOGA_CNT >> 16); + P0.l = (WDOGA_CNT & 0xFFFF); +#else + P0.h = (WDOG_CNT >> 16); + P0.l = (WDOG_CNT & 0xFFFF); +#endif + [P0] = R0; + SSYNC; + +#if defined(CONFIG_BF561) + P0.h = (WDOGA_CTL >> 16); + P0.l = (WDOGA_CTL & 0xFFFF); +#else + P0.h = (WDOG_CTL >> 16); + P0.l = (WDOG_CTL & 0xFFFF); +#endif + R7 = W[P0](Z); + CC = BITTST(R7,1); + if !CC JUMP .LWRITE_TO_STAT; + CC = BITTST(R7,2); + if !CC JUMP .LWRITE_TO_STAT; + +.LSKIP_WRITE_TO_STAT: +#if defined(CONFIG_BF561) + P0.h = (WDOGA_CTL >> 16); + P0.l = (WDOGA_CTL & 0xFFFF); +#else + P0.h = (WDOG_CTL >> 16); + P0.l = (WDOG_CTL & 0xFFFF); +#endif + R7 = W[P0](Z); + BITCLR(R7,1); /* Enable GP event */ + BITSET(R7,2); + W[P0] = R7.L; + SSYNC; + NOP; + + R7 = W[P0](Z); + BITCLR(R7,4); /* Enable the wdog counter */ + W[P0] = R7.L; + SSYNC; + + ( R7:0, P5:0 ) = [SP++]; + RTS; + +ENTRY(_clear_wdog_wakeup_evt) + [--SP] = ( R7:0, P5:0 ); + +#if defined(CONFIG_BF561) + P0.h = (WDOGA_CTL >> 16); + P0.l = (WDOGA_CTL & 0xFFFF); +#else + P0.h = (WDOG_CTL >> 16); + P0.l = (WDOG_CTL & 0xFFFF); +#endif + R7 = 0x0AD6(Z); + W[P0] = R7.L; + SSYNC; + + R7 = W[P0](Z); + BITSET(R7,15); + W[P0] = R7.L; + SSYNC; + + R7 = W[P0](Z); + BITSET(R7,1); + BITSET(R7,2); + W[P0] = R7.L; + SSYNC; + + ( R7:0, P5:0 ) = [SP++]; + RTS; + +ENTRY(_disable_wdog_timer) + [--SP] = ( R7:0, P5:0 ); +#if defined(CONFIG_BF561) + P0.h = (WDOGA_CTL >> 16); + P0.l = (WDOGA_CTL & 0xFFFF); +#else + P0.h = (WDOG_CTL >> 16); + P0.l = (WDOG_CTL & 0xFFFF); +#endif + R7 = 0xAD6(Z); + W[P0] = R7.L; + SSYNC; + ( R7:0, P5:0 ) = [SP++]; + RTS; + +#if !defined(CONFIG_BF561) + +.section .l1.text + +ENTRY(_sleep_mode) + [--SP] = ( R7:0, P5:0 ); + [--SP] = RETS; + + call _set_sic_iwr; + + R0 = 0xFFFF (Z); + call _set_rtc_istat + + P0.H = hi(PLL_CTL); + P0.L = lo(PLL_CTL); + R1 = W[P0](z); + BITSET (R1, 3); + W[P0] = R1.L; + + CLI R2; + SSYNC; + IDLE; + STI R2; + + call _test_pll_locked; + + R0 = IWR_ENABLE(0); + call _set_sic_iwr; + + P0.H = hi(PLL_CTL); + P0.L = lo(PLL_CTL); + R7 = w[p0](z); + BITCLR (R7, 3); + BITCLR (R7, 5); + w[p0] = R7.L; + IDLE; + call _test_pll_locked; + + RETS = [SP++]; + ( R7:0, P5:0 ) = [SP++]; + RTS; + +ENTRY(_hibernate_mode) + [--SP] = ( R7:0, P5:0 ); + [--SP] = RETS; + + call _set_sic_iwr; + + R0 = 0xFFFF (Z); + call _set_rtc_istat + + P0.H = hi(VR_CTL); + P0.L = lo(VR_CTL); + R1 = W[P0](z); + BITSET (R1, 8); + BITCLR (R1, 0); + BITCLR (R1, 1); + W[P0] = R1.L; + SSYNC; + + CLI R2; + IDLE; + + /* Actually, adding anything may not be necessary...SDRAM contents + * are lost + */ + +ENTRY(_deep_sleep) + [--SP] = ( R7:0, P5:0 ); + [--SP] = RETS; + + CLI R4; + + call _set_sic_iwr; + + call _set_sdram_srfs; + + /* Clear all the interrupts,bits sticky */ + R0 = 0xFFFF (Z); + call _set_rtc_istat + + P0.H = hi(PLL_CTL); + P0.L = lo(PLL_CTL); + R0 = W[P0](z); + BITSET (R0, 5); + W[P0] = R0.L; + + call _test_pll_locked; + + SSYNC; + IDLE; + + call _unset_sdram_srfs; + + call _test_pll_locked; + + R0 = IWR_ENABLE(0); + call _set_sic_iwr; + + P0.H = hi(PLL_CTL); + P0.L = lo(PLL_CTL); + R0 = w[p0](z); + BITCLR (R0, 3); + BITCLR (R0, 5); + BITCLR (R0, 8); + w[p0] = R0; + IDLE; + call _test_pll_locked; + + STI R4; + + RETS = [SP++]; + ( R7:0, P5:0 ) = [SP++]; + RTS; + +ENTRY(_sleep_deeper) + [--SP] = ( R7:0, P5:0 ); + [--SP] = RETS; + + CLI R4; + + P3 = R0; + R0 = IWR_ENABLE(0); + call _set_sic_iwr; + call _set_sdram_srfs; + + /* Clear all the interrupts,bits sticky */ + R0 = 0xFFFF (Z); + call _set_rtc_istat + + P0.H = hi(PLL_DIV); + P0.L = lo(PLL_DIV); + R6 = W[P0](z); + R0.L = 0xF; + W[P0] = R0.l; + + P0.H = hi(PLL_CTL); + P0.L = lo(PLL_CTL); + R5 = W[P0](z); + R0.L = (MIN_VC/CONFIG_CLKIN_HZ) << 9; + W[P0] = R0.l; + + SSYNC; + IDLE; + + call _test_pll_locked; + + P0.H = hi(VR_CTL); + P0.L = lo(VR_CTL); + R7 = W[P0](z); + R1 = 0x6; + R1 <<= 16; + R2 = 0x0404(Z); + R1 = R1|R2; + + R2 = DEPOSIT(R7, R1); + W[P0] = R2; + + SSYNC; + IDLE; + + call _test_pll_locked; + + P0.H = hi(PLL_CTL); + P0.L = lo(PLL_CTL); + R0 = W[P0](z); + BITSET (R0, 3); + W[P0] = R0.L; + + R0 = P3; + call _set_sic_iwr; + + SSYNC; + IDLE; + + call _test_pll_locked; + + R0 = IWR_ENABLE(0); + call _set_sic_iwr; + + P0.H = hi(VR_CTL); + P0.L = lo(VR_CTL); + W[P0]= R7; + + SSYNC; + IDLE; + + call _test_pll_locked; + + P0.H = hi(PLL_DIV); + P0.L = lo(PLL_DIV); + W[P0]= R6; + + P0.H = hi(PLL_CTL); + P0.L = lo(PLL_CTL); + w[p0] = R5; + IDLE; + call _test_pll_locked; + + call _unset_sdram_srfs; + + STI R4; + + RETS = [SP++]; + ( R7:0, P5:0 ) = [SP++]; + RTS; + +ENTRY(_set_sdram_srfs) + /* set the sdram to self refresh mode */ + P0.H = hi(EBIU_SDGCTL); + P0.L = lo(EBIU_SDGCTL); + R2 = [P0]; + R3.H = hi(SRFS); + R3.L = lo(SRFS); + R2 = R2|R3; + [P0] = R2; + ssync; + RTS; + +ENTRY(_unset_sdram_srfs) + /* set the sdram out of self refresh mode */ + P0.H = hi(EBIU_SDGCTL); + P0.L = lo(EBIU_SDGCTL); + R2 = [P0]; + R3.H = hi(SRFS); + R3.L = lo(SRFS); + R3 = ~R3; + R2 = R2&R3; + [P0] = R2; + ssync; + RTS; + +ENTRY(_set_sic_iwr) + P0.H = hi(SIC_IWR); + P0.L = lo(SIC_IWR); + [P0] = R0; + SSYNC; + RTS; + +ENTRY(_set_rtc_istat) + P0.H = hi(RTC_ISTAT); + P0.L = lo(RTC_ISTAT); + w[P0] = R0.L; + SSYNC; + RTS; + +ENTRY(_test_pll_locked) + P0.H = hi(PLL_STAT); + P0.L = lo(PLL_STAT); +1: + R0 = W[P0] (Z); + CC = BITTST(R0,5); + IF !CC JUMP 1b; + RTS; +#endif diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S new file mode 100644 index 000000000000..8eb0a9023482 --- /dev/null +++ b/arch/blackfin/mach-common/entry.S @@ -0,0 +1,1207 @@ +/* + * File: arch/blackfin/mach-common/entry.S + * Based on: + * Author: Linus Torvalds + * + * Created: ? + * Description: contains the system-call and fault low-level handling routines. + * This also contains the timer-interrupt handler, as well as all + * interrupts and faults that can result in a task-switch. + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * 25-Dec-2004 - LG Soft India + * 1. Fix in return_from_int, to make sure any pending + * system call in ILAT for this process to get + * executed, otherwise in case context switch happens, + * system call of first process (i.e in ILAT) will be + * carried forward to the switched process. + * 2. Removed Constant references for the following + * a. IPEND + * b. EXCAUSE mask + * c. PAGE Mask + */ + +/* + * NOTE: This code handles signal-recognition, which happens every time + * after a timer-interrupt and after each system call. + */ + + +#include +#include +#include +#include +#include /* TIF_NEED_RESCHED */ +#include + +#include + +#ifdef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE + /* + * TODO: this should be proper save/restore, but for now + * we'll just cheat and use 0x1/0x13 + */ +# define DEBUG_START_HWTRACE \ + P5.l = LO(TBUFCTL); \ + P5.h = HI(TBUFCTL); \ + R7 = 0x13; \ + [P5] = R7; +# define DEBUG_STOP_HWTRACE \ + P5.l = LO(TBUFCTL); \ + P5.h = HI(TBUFCTL); \ + R7 = 0x01; \ + [P5] = R7; +#else +# define DEBUG_START_HWTRACE +# define DEBUG_STOP_HWTRACE +#endif + +#ifdef CONFIG_EXCPT_IRQ_SYSC_L1 +.section .l1.text +#else +.text +#endif + +/* Slightly simplified and streamlined entry point for CPLB misses. + * This one does not lower the level to IRQ5, and thus can be used to + * patch up CPLB misses on the kernel stack. + */ +ENTRY(_ex_dcplb) +#if defined(ANOMALY_05000261) + /* + * Work around an anomaly: if we see a new DCPLB fault, return + * without doing anything. Then, if we get the same fault again, + * handle it. + */ + p5.l = _last_cplb_fault_retx; + p5.h = _last_cplb_fault_retx; + r7 = [p5]; + r6 = retx; + [p5] = r6; + cc = r6 == r7; + if !cc jump _return_from_exception; + /* fall through */ +#endif + +ENTRY(_ex_icplb) + (R7:6,P5:4) = [sp++]; + ASTAT = [sp++]; + SAVE_ALL_SYS + call __cplb_hdr; + DEBUG_START_HWTRACE + RESTORE_ALL_SYS + SP = RETN; + rtx; + +ENTRY(_ex_spinlock) + /* Transform this into a syscall - twiddle the syscall vector. */ + p5.l = lo(EVT15); + p5.h = hi(EVT15); + r7.l = _spinlock_bh; + r7.h = _spinlock_bh; + [p5] = r7; + csync; + /* Fall through. */ + +ENTRY(_ex_syscall) + DEBUG_START_HWTRACE + (R7:6,P5:4) = [sp++]; + ASTAT = [sp++]; + raise 15; /* invoked by TRAP #0, for sys call */ + sp = retn; + rtx + +ENTRY(_spinlock_bh) + SAVE_ALL_SYS + /* To end up here, vector 15 was changed - so we have to change it + * back. + */ + p0.l = lo(EVT15); + p0.h = hi(EVT15); + p1.l = _evt_system_call; + p1.h = _evt_system_call; + [p0] = p1; + csync; + r0 = [sp + PT_R0]; + sp += -12; + call _sys_bfin_spinlock; + sp += 12; + [SP + PT_R0] = R0; + RESTORE_ALL_SYS + rti; + +ENTRY(_ex_soft_bp) + r7 = retx; + r7 += -2; + retx = r7; + jump.s _ex_trap_c; + +ENTRY(_ex_single_step) + r7 = retx; + r6 = reti; + cc = r7 == r6; + if cc jump _return_from_exception + r7 = syscfg; + bitclr (r7, 0); + syscfg = R7; + + p5.l = lo(IPEND); + p5.h = hi(IPEND); + r6 = [p5]; + cc = bittst(r6, 5); + if !cc jump _ex_trap_c; + p4.l = lo(EVT5); + p4.h = hi(EVT5); + r6.h = _exception_to_level5; + r6.l = _exception_to_level5; + r7 = [p4]; + cc = r6 == r7; + if !cc jump _ex_trap_c; + +_return_from_exception: + DEBUG_START_HWTRACE + (R7:6,P5:4) = [sp++]; + ASTAT = [sp++]; + sp = retn; + rtx; + +ENTRY(_handle_bad_cplb) + /* To get here, we just tried and failed to change a CPLB + * so, handle things in trap_c (C code), by lowering to + * IRQ5, just like we normally do. Since this is not a + * "normal" return path, we have a do alot of stuff to + * the stack to get ready so, we can fall through - we + * need to make a CPLB exception look like a normal exception + */ + + DEBUG_START_HWTRACE + RESTORE_ALL_SYS + [--sp] = ASTAT; + [--sp] = (R7:6, P5:4); + +ENTRY(_ex_trap_c) + /* Call C code (trap_c) to handle the exception, which most + * likely involves sending a signal to the current process. + * To avoid double faults, lower our priority to IRQ5 first. + */ + P5.h = _exception_to_level5; + P5.l = _exception_to_level5; + p4.l = lo(EVT5); + p4.h = hi(EVT5); + [p4] = p5; + csync; + + /* Disable all interrupts, but make sure level 5 is enabled so + * we can switch to that level. Save the old mask. */ + cli r6; + p4.l = _excpt_saved_imask; + p4.h = _excpt_saved_imask; + [p4] = r6; + r6 = 0x3f; + sti r6; + + /* Save the excause into a circular buffer, in case the instruction + * which caused this excecptions causes others. + */ + P5.l = _in_ptr_excause; + P5.h = _in_ptr_excause; + R7 = [P5]; + R7 += 4; + R6 = 0xF; + R7 = R7 & R6; + [P5] = R7; + R6.l = _excause_circ_buf; + R6.h = _excause_circ_buf; + R7 = R7 + R6; + p5 = R7; + R6 = SEQSTAT; + [P5] = R6; + + DEBUG_START_HWTRACE + (R7:6,P5:4) = [sp++]; + ASTAT = [sp++]; + SP = RETN; + raise 5; + rtx; + +ENTRY(_exception_to_level5) + SAVE_ALL_SYS + + /* Restore interrupt mask. We haven't pushed RETI, so this + * doesn't enable interrupts until we return from this handler. */ + p4.l = _excpt_saved_imask; + p4.h = _excpt_saved_imask; + r6 = [p4]; + sti r6; + + /* Restore the hardware error vector. */ + P5.h = _evt_ivhw; + P5.l = _evt_ivhw; + p4.l = lo(EVT5); + p4.h = hi(EVT5); + [p4] = p5; + csync; + + p2.l = lo(IPEND); + p2.h = hi(IPEND); + csync; + r0 = [p2]; /* Read current IPEND */ + [sp + PT_IPEND] = r0; /* Store IPEND */ + + /* Pop the excause from the circular buffer and push it on the stack + * (in the right place - if you change the location of SEQSTAT, you + * must change this offset. + */ +.L_excep_to_5_again: + P5.l = _out_ptr_excause; + P5.h = _out_ptr_excause; + R7 = [P5]; + R7 += 4; + R6 = 0xF; + R7 = R7 & R6; + [P5] = R7; + R6.l = _excause_circ_buf; + R6.h = _excause_circ_buf; + R7 = R7 + R6; + P5 = R7; + R1 = [P5]; + [SP + 8] = r1; + + r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ + SP += -12; + call _trap_c; + SP += 12; + + /* See if anything else is in the exception buffer + * if there is, process it + */ + P5.l = _out_ptr_excause; + P5.h = _out_ptr_excause; + P4.l = _in_ptr_excause; + P4.h = _in_ptr_excause; + R6 = [P5]; + R7 = [P4]; + CC = R6 == R7; + if ! CC JUMP .L_excep_to_5_again + + call _ret_from_exception; + RESTORE_ALL_SYS + rti; + +ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ + /* Since the kernel stack can be anywhere, it's not guaranteed to be + * covered by a CPLB. Switch to an exception stack; use RETN as a + * scratch register (for want of a better option). + */ + retn = sp; + sp.l = _exception_stack_top; + sp.h = _exception_stack_top; + /* Try to deal with syscalls quickly. */ + [--sp] = ASTAT; + [--sp] = (R7:6, P5:4); + DEBUG_STOP_HWTRACE + r7 = SEQSTAT; /* reason code is in bit 5:0 */ + r6.l = lo(SEQSTAT_EXCAUSE); + r6.h = hi(SEQSTAT_EXCAUSE); + r7 = r7 & r6; + p5.h = _extable; + p5.l = _extable; + p4 = r7; + p5 = p5 + (p4 << 2); + p4 = [p5]; + jump (p4); + +.Lbadsys: + r7 = -ENOSYS; /* signextending enough */ + [sp + PT_R0] = r7; /* return value from system call */ + jump .Lsyscall_really_exit; + +ENTRY(_kernel_execve) + link SIZEOF_PTREGS; + p0 = sp; + r3 = SIZEOF_PTREGS / 4; + r4 = 0(x); +0: + [p0++] = r4; + r3 += -1; + cc = r3 == 0; + if !cc jump 0b (bp); + + p0 = sp; + sp += -16; + [sp + 12] = p0; + call _do_execve; + SP += 16; + cc = r0 == 0; + if ! cc jump 1f; + /* Success. Copy our temporary pt_regs to the top of the kernel + * stack and do a normal exception return. + */ + r1 = sp; + r0 = (-KERNEL_STACK_SIZE) (x); + r1 = r1 & r0; + p2 = r1; + p3 = [p2]; + r0 = KERNEL_STACK_SIZE - 4 (z); + p1 = r0; + p1 = p1 + p2; + + p0 = fp; + r4 = [p0--]; + r3 = SIZEOF_PTREGS / 4; +0: + r4 = [p0--]; + [p1--] = r4; + r3 += -1; + cc = r3 == 0; + if ! cc jump 0b (bp); + + r0 = (KERNEL_STACK_SIZE - SIZEOF_PTREGS) (z); + p1 = r0; + p1 = p1 + p2; + sp = p1; + r0 = syscfg; + [SP + PT_SYSCFG] = r0; + [p3 + (TASK_THREAD + THREAD_KSP)] = sp; + + RESTORE_CONTEXT; + rti; +1: + unlink; + rts; + +ENTRY(_system_call) + /* Store IPEND */ + p2.l = lo(IPEND); + p2.h = hi(IPEND); + csync; + r0 = [p2]; + [sp + PT_IPEND] = r0; + + /* Store RETS for now */ + r0 = rets; + [sp + PT_RESERVED] = r0; + /* Set the stack for the current process */ + r7 = sp; + r6.l = lo(ALIGN_PAGE_MASK); + r6.h = hi(ALIGN_PAGE_MASK); + r7 = r7 & r6; /* thread_info */ + p2 = r7; + p2 = [p2]; + + [p2+(TASK_THREAD+THREAD_KSP)] = sp; + + /* Check the System Call */ + r7 = __NR_syscall; + /* System call number is passed in P0 */ + r6 = p0; + cc = r6 < r7; + if ! cc jump .Lbadsys; + + /* are we tracing syscalls?*/ + r7 = sp; + r6.l = lo(ALIGN_PAGE_MASK); + r6.h = hi(ALIGN_PAGE_MASK); + r7 = r7 & r6; + p2 = r7; + r7 = [p2+TI_FLAGS]; + CC = BITTST(r7,TIF_SYSCALL_TRACE); + if CC JUMP _sys_trace; + + /* Execute the appropriate system call */ + + p4 = p0; + p5.l = _sys_call_table; + p5.h = _sys_call_table; + p5 = p5 + (p4 << 2); + r0 = [sp + PT_R0]; + r1 = [sp + PT_R1]; + r2 = [sp + PT_R2]; + p5 = [p5]; + + [--sp] = r5; + [--sp] = r4; + [--sp] = r3; + SP += -12; + call (p5); + SP += 24; + [sp + PT_R0] = r0; + +.Lresume_userspace: + r7 = sp; + r4.l = lo(ALIGN_PAGE_MASK); + r4.h = hi(ALIGN_PAGE_MASK); + r7 = r7 & r4; /* thread_info->flags */ + p5 = r7; +.Lresume_userspace_1: + /* Disable interrupts. */ + [--sp] = reti; + reti = [sp++]; + + r7 = [p5 + TI_FLAGS]; + r4.l = lo(_TIF_WORK_MASK); + r4.h = hi(_TIF_WORK_MASK); + r7 = r7 & r4; + +.Lsyscall_resched: + cc = BITTST(r7, TIF_NEED_RESCHED); + if !cc jump .Lsyscall_sigpending; + + /* Reenable interrupts. */ + [--sp] = reti; + r0 = [sp++]; + + SP += -12; + call _schedule; + SP += 12; + + jump .Lresume_userspace_1; + +.Lsyscall_sigpending: + cc = BITTST(r7, TIF_RESTORE_SIGMASK); + if cc jump .Lsyscall_do_signals; + cc = BITTST(r7, TIF_SIGPENDING); + if !cc jump .Lsyscall_really_exit; +.Lsyscall_do_signals: + /* Reenable interrupts. */ + [--sp] = reti; + r0 = [sp++]; + + r0 = sp; + SP += -12; + call _do_signal; + SP += 12; + +.Lsyscall_really_exit: + r5 = [sp + PT_RESERVED]; + rets = r5; + rts; + +_sys_trace: + call _syscall_trace; + + /* Execute the appropriate system call */ + + p4 = [SP + PT_P0]; + p5.l = _sys_call_table; + p5.h = _sys_call_table; + p5 = p5 + (p4 << 2); + r0 = [sp + PT_R0]; + r1 = [sp + PT_R1]; + r2 = [sp + PT_R2]; + r3 = [sp + PT_R3]; + r4 = [sp + PT_R4]; + r5 = [sp + PT_R5]; + p5 = [p5]; + + [--sp] = r5; + [--sp] = r4; + [--sp] = r3; + SP += -12; + call (p5); + SP += 24; + [sp + PT_R0] = r0; + + call _syscall_trace; + jump .Lresume_userspace; + +ENTRY(_resume) + /* + * Beware - when entering resume, prev (the current task) is + * in r0, next (the new task) is in r1. + */ + p0 = r0; + p1 = r1; + [--sp] = rets; + [--sp] = fp; + [--sp] = (r7:4, p5:3); + + /* save usp */ + p2 = usp; + [p0+(TASK_THREAD+THREAD_USP)] = p2; + + /* save current kernel stack pointer */ + [p0+(TASK_THREAD+THREAD_KSP)] = sp; + + /* save program counter */ + r1.l = _new_old_task; + r1.h = _new_old_task; + [p0+(TASK_THREAD+THREAD_PC)] = r1; + + /* restore the kernel stack pointer */ + sp = [p1+(TASK_THREAD+THREAD_KSP)]; + + /* restore user stack pointer */ + p0 = [p1+(TASK_THREAD+THREAD_USP)]; + usp = p0; + + /* restore pc */ + p0 = [p1+(TASK_THREAD+THREAD_PC)]; + jump (p0); + + /* + * Following code actually lands up in a new (old) task. + */ + +_new_old_task: + (r7:4, p5:3) = [sp++]; + fp = [sp++]; + rets = [sp++]; + + /* + * When we come out of resume, r0 carries "old" task, becuase we are + * in "new" task. + */ + rts; + +ENTRY(_ret_from_exception) + p2.l = lo(IPEND); + p2.h = hi(IPEND); + + csync; + r0 = [p2]; + [sp + PT_IPEND] = r0; + +1: + r1 = 0x37(Z); + r2 = ~r1; + r2.h = 0; + r0 = r2 & r0; + cc = r0 == 0; + if !cc jump 4f; /* if not return to user mode, get out */ + + /* Make sure any pending system call or deferred exception + * return in ILAT for this process to get executed, otherwise + * in case context switch happens, system call of + * first process (i.e in ILAT) will be carried + * forward to the switched process + */ + + p2.l = lo(ILAT); + p2.h = hi(ILAT); + r0 = [p2]; + r1 = (EVT_IVG14 | EVT_IVG15) (z); + r0 = r0 & r1; + cc = r0 == 0; + if !cc jump 5f; + + /* Set the stack for the current process */ + r7 = sp; + r4.l = lo(ALIGN_PAGE_MASK); + r4.h = hi(ALIGN_PAGE_MASK); + r7 = r7 & r4; /* thread_info->flags */ + p5 = r7; + r7 = [p5 + TI_FLAGS]; + r4.l = lo(_TIF_WORK_MASK); + r4.h = hi(_TIF_WORK_MASK); + r7 = r7 & r4; + cc = r7 == 0; + if cc jump 4f; + + p0.l = lo(EVT15); + p0.h = hi(EVT15); + p1.l = _schedule_and_signal; + p1.h = _schedule_and_signal; + [p0] = p1; + csync; + raise 15; /* raise evt14 to do signal or reschedule */ +4: + r0 = syscfg; + bitclr(r0, 0); + syscfg = r0; +5: + rts; + +ENTRY(_return_from_int) + /* If someone else already raised IRQ 15, do nothing. */ + csync; + p2.l = lo(ILAT); + p2.h = hi(ILAT); + r0 = [p2]; + cc = bittst (r0, EVT_IVG15_P); + if cc jump 2f; + + /* if not return to user mode, get out */ + p2.l = lo(IPEND); + p2.h = hi(IPEND); + r0 = [p2]; + r1 = 0x17(Z); + r2 = ~r1; + r2.h = 0; + r0 = r2 & r0; + r1 = 1; + r1 = r0 - r1; + r2 = r0 & r1; + cc = r2 == 0; + if !cc jump 2f; + + /* Lower the interrupt level to 15. */ + p0.l = lo(EVT15); + p0.h = hi(EVT15); + p1.l = _schedule_and_signal_from_int; + p1.h = _schedule_and_signal_from_int; + [p0] = p1; + csync; +#if defined(ANOMALY_05000281) + r0.l = lo(CONFIG_BOOT_LOAD); + r0.h = hi(CONFIG_BOOT_LOAD); + reti = r0; +#endif + r0 = 0x801f (z); + STI r0; + raise 15; /* raise evt15 to do signal or reschedule */ + rti; +2: + rts; + +ENTRY(_lower_to_irq14) +#if defined(ANOMALY_05000281) + r0.l = lo(CONFIG_BOOT_LOAD); + r0.h = hi(CONFIG_BOOT_LOAD); + reti = r0; +#endif + r0 = 0x401f; + sti r0; + raise 14; + rti; +ENTRY(_evt14_softirq) +#ifdef CONFIG_DEBUG_HWERR + r0 = 0x3f; + sti r0; +#else + cli r0; +#endif + [--sp] = RETI; + SP += 4; + rts; + +_schedule_and_signal_from_int: + /* To end up here, vector 15 was changed - so we have to change it + * back. + */ + p0.l = lo(EVT15); + p0.h = hi(EVT15); + p1.l = _evt_system_call; + p1.h = _evt_system_call; + [p0] = p1; + csync; + p1 = rets; + [sp + PT_RESERVED] = p1; + + p0.l = _irq_flags; + p0.h = _irq_flags; + r0 = [p0]; + sti r0; + + jump.s .Lresume_userspace; + +_schedule_and_signal: + SAVE_CONTEXT_SYSCALL + /* To end up here, vector 15 was changed - so we have to change it + * back. + */ + p0.l = lo(EVT15); + p0.h = hi(EVT15); + p1.l = _evt_system_call; + p1.h = _evt_system_call; + [p0] = p1; + csync; + p0.l = 1f; + p0.h = 1f; + [sp + PT_RESERVED] = P0; + call .Lresume_userspace; +1: + RESTORE_CONTEXT + rti; + +/* Make sure when we start, that the circular buffer is initialized properly + * R0 and P0 are call clobbered, so we can use them here. + */ +ENTRY(_init_exception_buff) + r0 = 0; + p0.h = _in_ptr_excause; + p0.l = _in_ptr_excause; + [p0] = r0; + p0.h = _out_ptr_excause; + p0.l = _out_ptr_excause; + [p0] = r0; + rts; + +/* + * Put these in the kernel data section - that should always be covered by + * a CPLB. This is needed to ensure we don't get double fault conditions + */ + +#ifdef CONFIG_SYSCALL_TAB_L1 +.section .l1.data +#else +.data +#endif +ALIGN +_extable: + /* entry for each EXCAUSE[5:0] + * This table bmust be in sync with the table in ./kernel/traps.c + * EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined + */ + .long _ex_syscall; /* 0x00 - User Defined - Linux Syscall */ + .long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */ + .long _ex_trap_c /* 0x02 - User Defined */ + .long _ex_trap_c /* 0x03 - User Defined - Atomic test and set service */ + .long _ex_spinlock /* 0x04 - User Defined */ + .long _ex_trap_c /* 0x05 - User Defined */ + .long _ex_trap_c /* 0x06 - User Defined */ + .long _ex_trap_c /* 0x07 - User Defined */ + .long _ex_trap_c /* 0x08 - User Defined */ + .long _ex_trap_c /* 0x09 - User Defined */ + .long _ex_trap_c /* 0x0A - User Defined */ + .long _ex_trap_c /* 0x0B - User Defined */ + .long _ex_trap_c /* 0x0C - User Defined */ + .long _ex_trap_c /* 0x0D - User Defined */ + .long _ex_trap_c /* 0x0E - User Defined */ + .long _ex_trap_c /* 0x0F - User Defined */ + .long _ex_single_step /* 0x10 - HW Single step */ + .long _ex_trap_c /* 0x11 - Trace Buffer Full */ + .long _ex_trap_c /* 0x12 - Reserved */ + .long _ex_trap_c /* 0x13 - Reserved */ + .long _ex_trap_c /* 0x14 - Reserved */ + .long _ex_trap_c /* 0x15 - Reserved */ + .long _ex_trap_c /* 0x16 - Reserved */ + .long _ex_trap_c /* 0x17 - Reserved */ + .long _ex_trap_c /* 0x18 - Reserved */ + .long _ex_trap_c /* 0x19 - Reserved */ + .long _ex_trap_c /* 0x1A - Reserved */ + .long _ex_trap_c /* 0x1B - Reserved */ + .long _ex_trap_c /* 0x1C - Reserved */ + .long _ex_trap_c /* 0x1D - Reserved */ + .long _ex_trap_c /* 0x1E - Reserved */ + .long _ex_trap_c /* 0x1F - Reserved */ + .long _ex_trap_c /* 0x20 - Reserved */ + .long _ex_trap_c /* 0x21 - Undefined Instruction */ + .long _ex_trap_c /* 0x22 - Illegal Instruction Combination */ + .long _ex_dcplb /* 0x23 - Data CPLB Protection Violation */ + .long _ex_trap_c /* 0x24 - Data access misaligned */ + .long _ex_trap_c /* 0x25 - Unrecoverable Event */ + .long _ex_dcplb /* 0x26 - Data CPLB Miss */ + .long _ex_trap_c /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero */ + .long _ex_trap_c /* 0x28 - Emulation Watchpoint */ + .long _ex_trap_c /* 0x29 - Instruction fetch access error (535 only) */ + .long _ex_trap_c /* 0x2A - Instruction fetch misaligned */ + .long _ex_icplb /* 0x2B - Instruction CPLB protection Violation */ + .long _ex_icplb /* 0x2C - Instruction CPLB miss */ + .long _ex_trap_c /* 0x2D - Instruction CPLB Multiple Hits */ + .long _ex_trap_c /* 0x2E - Illegal use of Supervisor Resource */ + .long _ex_trap_c /* 0x2E - Illegal use of Supervisor Resource */ + .long _ex_trap_c /* 0x2F - Reserved */ + .long _ex_trap_c /* 0x30 - Reserved */ + .long _ex_trap_c /* 0x31 - Reserved */ + .long _ex_trap_c /* 0x32 - Reserved */ + .long _ex_trap_c /* 0x33 - Reserved */ + .long _ex_trap_c /* 0x34 - Reserved */ + .long _ex_trap_c /* 0x35 - Reserved */ + .long _ex_trap_c /* 0x36 - Reserved */ + .long _ex_trap_c /* 0x37 - Reserved */ + .long _ex_trap_c /* 0x38 - Reserved */ + .long _ex_trap_c /* 0x39 - Reserved */ + .long _ex_trap_c /* 0x3A - Reserved */ + .long _ex_trap_c /* 0x3B - Reserved */ + .long _ex_trap_c /* 0x3C - Reserved */ + .long _ex_trap_c /* 0x3D - Reserved */ + .long _ex_trap_c /* 0x3E - Reserved */ + .long _ex_trap_c /* 0x3F - Reserved */ + +ALIGN +ENTRY(_sys_call_table) + .long _sys_ni_syscall /* 0 - old "setup()" system call*/ + .long _sys_exit + .long _sys_fork + .long _sys_read + .long _sys_write + .long _sys_open /* 5 */ + .long _sys_close + .long _sys_ni_syscall /* old waitpid */ + .long _sys_creat + .long _sys_link + .long _sys_unlink /* 10 */ + .long _sys_execve + .long _sys_chdir + .long _sys_time + .long _sys_mknod + .long _sys_chmod /* 15 */ + .long _sys_chown /* chown16 */ + .long _sys_ni_syscall /* old break syscall holder */ + .long _sys_ni_syscall /* old stat */ + .long _sys_lseek + .long _sys_getpid /* 20 */ + .long _sys_mount + .long _sys_ni_syscall /* old umount */ + .long _sys_setuid + .long _sys_getuid + .long _sys_stime /* 25 */ + .long _sys_ptrace + .long _sys_alarm + .long _sys_ni_syscall /* old fstat */ + .long _sys_pause + .long _sys_ni_syscall /* old utime */ /* 30 */ + .long _sys_ni_syscall /* old stty syscall holder */ + .long _sys_ni_syscall /* old gtty syscall holder */ + .long _sys_access + .long _sys_nice + .long _sys_ni_syscall /* 35 */ /* old ftime syscall holder */ + .long _sys_sync + .long _sys_kill + .long _sys_rename + .long _sys_mkdir + .long _sys_rmdir /* 40 */ + .long _sys_dup + .long _sys_pipe + .long _sys_times + .long _sys_ni_syscall /* old prof syscall holder */ + .long _sys_brk /* 45 */ + .long _sys_setgid + .long _sys_getgid + .long _sys_ni_syscall /* old sys_signal */ + .long _sys_geteuid /* geteuid16 */ + .long _sys_getegid /* getegid16 */ /* 50 */ + .long _sys_acct + .long _sys_umount /* recycled never used phys() */ + .long _sys_ni_syscall /* old lock syscall holder */ + .long _sys_ioctl + .long _sys_fcntl /* 55 */ + .long _sys_ni_syscall /* old mpx syscall holder */ + .long _sys_setpgid + .long _sys_ni_syscall /* old ulimit syscall holder */ + .long _sys_ni_syscall /* old old uname */ + .long _sys_umask /* 60 */ + .long _sys_chroot + .long _sys_ustat + .long _sys_dup2 + .long _sys_getppid + .long _sys_getpgrp /* 65 */ + .long _sys_setsid + .long _sys_ni_syscall /* old sys_sigaction */ + .long _sys_sgetmask + .long _sys_ssetmask + .long _sys_setreuid /* setreuid16 */ /* 70 */ + .long _sys_setregid /* setregid16 */ + .long _sys_ni_syscall /* old sys_sigsuspend */ + .long _sys_ni_syscall /* old sys_sigpending */ + .long _sys_sethostname + .long _sys_setrlimit /* 75 */ + .long _sys_ni_syscall /* old getrlimit */ + .long _sys_getrusage + .long _sys_gettimeofday + .long _sys_settimeofday + .long _sys_getgroups /* getgroups16 */ /* 80 */ + .long _sys_setgroups /* setgroups16 */ + .long _sys_ni_syscall /* old_select */ + .long _sys_symlink + .long _sys_ni_syscall /* old lstat */ + .long _sys_readlink /* 85 */ + .long _sys_uselib + .long _sys_ni_syscall /* sys_swapon */ + .long _sys_reboot + .long _sys_ni_syscall /* old_readdir */ + .long _sys_ni_syscall /* sys_mmap */ /* 90 */ + .long _sys_munmap + .long _sys_truncate + .long _sys_ftruncate + .long _sys_fchmod + .long _sys_fchown /* fchown16 */ /* 95 */ + .long _sys_getpriority + .long _sys_setpriority + .long _sys_ni_syscall /* old profil syscall holder */ + .long _sys_statfs + .long _sys_fstatfs /* 100 */ + .long _sys_ni_syscall + .long _sys_ni_syscall /* old sys_socketcall */ + .long _sys_syslog + .long _sys_setitimer + .long _sys_getitimer /* 105 */ + .long _sys_newstat + .long _sys_newlstat + .long _sys_newfstat + .long _sys_ni_syscall /* old uname */ + .long _sys_ni_syscall /* iopl for i386 */ /* 110 */ + .long _sys_vhangup + .long _sys_ni_syscall /* obsolete idle() syscall */ + .long _sys_ni_syscall /* vm86old for i386 */ + .long _sys_wait4 + .long _sys_ni_syscall /* 115 */ /* sys_swapoff */ + .long _sys_sysinfo + .long _sys_ni_syscall /* old sys_ipc */ + .long _sys_fsync + .long _sys_ni_syscall /* old sys_sigreturn */ + .long _sys_clone /* 120 */ + .long _sys_setdomainname + .long _sys_newuname + .long _sys_ni_syscall /* old sys_modify_ldt */ + .long _sys_adjtimex + .long _sys_ni_syscall /* 125 */ /* sys_mprotect */ + .long _sys_ni_syscall /* old sys_sigprocmask */ + .long _sys_ni_syscall /* old "creat_module" */ + .long _sys_init_module + .long _sys_delete_module + .long _sys_ni_syscall /* 130: old "get_kernel_syms" */ + .long _sys_quotactl + .long _sys_getpgid + .long _sys_fchdir + .long _sys_bdflush + .long _sys_ni_syscall /* 135 */ /* sys_sysfs */ + .long _sys_personality + .long _sys_ni_syscall /* for afs_syscall */ + .long _sys_setfsuid /* setfsuid16 */ + .long _sys_setfsgid /* setfsgid16 */ + .long _sys_llseek /* 140 */ + .long _sys_getdents + .long _sys_ni_syscall /* sys_select */ + .long _sys_flock + .long _sys_ni_syscall /* sys_msync */ + .long _sys_readv /* 145 */ + .long _sys_writev + .long _sys_getsid + .long _sys_fdatasync + .long _sys_sysctl + .long _sys_ni_syscall /* 150 */ /* sys_mlock */ + .long _sys_ni_syscall /* sys_munlock */ + .long _sys_ni_syscall /* sys_mlockall */ + .long _sys_ni_syscall /* sys_munlockall */ + .long _sys_sched_setparam + .long _sys_sched_getparam /* 155 */ + .long _sys_sched_setscheduler + .long _sys_sched_getscheduler + .long _sys_sched_yield + .long _sys_sched_get_priority_max + .long _sys_sched_get_priority_min /* 160 */ + .long _sys_sched_rr_get_interval + .long _sys_nanosleep + .long _sys_ni_syscall /* sys_mremap */ + .long _sys_setresuid /* setresuid16 */ + .long _sys_getresuid /* getresuid16 */ /* 165 */ + .long _sys_ni_syscall /* for vm86 */ + .long _sys_ni_syscall /* old "query_module" */ + .long _sys_ni_syscall /* sys_poll */ + .long _sys_ni_syscall /* sys_nfsservctl */ + .long _sys_setresgid /* setresgid16 */ /* 170 */ + .long _sys_getresgid /* getresgid16 */ + .long _sys_prctl + .long _sys_rt_sigreturn + .long _sys_rt_sigaction + .long _sys_rt_sigprocmask /* 175 */ + .long _sys_rt_sigpending + .long _sys_rt_sigtimedwait + .long _sys_rt_sigqueueinfo + .long _sys_rt_sigsuspend + .long _sys_pread64 /* 180 */ + .long _sys_pwrite64 + .long _sys_lchown /* lchown16 */ + .long _sys_getcwd + .long _sys_capget + .long _sys_capset /* 185 */ + .long _sys_sigaltstack + .long _sys_sendfile + .long _sys_ni_syscall /* streams1 */ + .long _sys_ni_syscall /* streams2 */ + .long _sys_vfork /* 190 */ + .long _sys_getrlimit + .long _sys_mmap2 + .long _sys_truncate64 + .long _sys_ftruncate64 + .long _sys_stat64 /* 195 */ + .long _sys_lstat64 + .long _sys_fstat64 + .long _sys_chown + .long _sys_getuid + .long _sys_getgid /* 200 */ + .long _sys_geteuid + .long _sys_getegid + .long _sys_setreuid + .long _sys_setregid + .long _sys_getgroups /* 205 */ + .long _sys_setgroups + .long _sys_fchown + .long _sys_setresuid + .long _sys_getresuid + .long _sys_setresgid /* 210 */ + .long _sys_getresgid + .long _sys_lchown + .long _sys_setuid + .long _sys_setgid + .long _sys_setfsuid /* 215 */ + .long _sys_setfsgid + .long _sys_pivot_root + .long _sys_ni_syscall /* sys_mincore */ + .long _sys_ni_syscall /* sys_madvise */ + .long _sys_getdents64 /* 220 */ + .long _sys_fcntl64 + .long _sys_ni_syscall /* reserved for TUX */ + .long _sys_ni_syscall + .long _sys_gettid + .long _sys_ni_syscall /* 225 */ /* sys_readahead */ + .long _sys_setxattr + .long _sys_lsetxattr + .long _sys_fsetxattr + .long _sys_getxattr + .long _sys_lgetxattr /* 230 */ + .long _sys_fgetxattr + .long _sys_listxattr + .long _sys_llistxattr + .long _sys_flistxattr + .long _sys_removexattr /* 235 */ + .long _sys_lremovexattr + .long _sys_fremovexattr + .long _sys_tkill + .long _sys_sendfile64 + .long _sys_futex /* 240 */ + .long _sys_sched_setaffinity + .long _sys_sched_getaffinity + .long _sys_ni_syscall /* sys_set_thread_area */ + .long _sys_ni_syscall /* sys_get_thread_area */ + .long _sys_io_setup /* 245 */ + .long _sys_io_destroy + .long _sys_io_getevents + .long _sys_io_submit + .long _sys_io_cancel + .long _sys_ni_syscall /* 250 */ /* sys_alloc_hugepages */ + .long _sys_ni_syscall /* sys_freec_hugepages */ + .long _sys_exit_group + .long _sys_lookup_dcookie + .long _sys_bfin_spinlock + .long _sys_epoll_create /* 255 */ + .long _sys_epoll_ctl + .long _sys_epoll_wait + .long _sys_ni_syscall /* remap_file_pages */ + .long _sys_set_tid_address + .long _sys_timer_create /* 260 */ + .long _sys_timer_settime + .long _sys_timer_gettime + .long _sys_timer_getoverrun + .long _sys_timer_delete + .long _sys_clock_settime /* 265 */ + .long _sys_clock_gettime + .long _sys_clock_getres + .long _sys_clock_nanosleep + .long _sys_statfs64 + .long _sys_fstatfs64 /* 270 */ + .long _sys_tgkill + .long _sys_utimes + .long _sys_fadvise64_64 + .long _sys_ni_syscall /* vserver */ + .long _sys_ni_syscall /* 275, mbind */ + .long _sys_ni_syscall /* get_mempolicy */ + .long _sys_ni_syscall /* set_mempolicy */ + .long _sys_mq_open + .long _sys_mq_unlink + .long _sys_mq_timedsend /* 280 */ + .long _sys_mq_timedreceive + .long _sys_mq_notify + .long _sys_mq_getsetattr + .long _sys_ni_syscall /* kexec_load */ + .long _sys_waitid /* 285 */ + .long _sys_add_key + .long _sys_request_key + .long _sys_keyctl + .long _sys_ioprio_set + .long _sys_ioprio_get /* 290 */ + .long _sys_inotify_init + .long _sys_inotify_add_watch + .long _sys_inotify_rm_watch + .long _sys_ni_syscall /* migrate_pages */ + .long _sys_openat /* 295 */ + .long _sys_mkdirat + .long _sys_mknodat + .long _sys_fchownat + .long _sys_futimesat + .long _sys_fstatat64 /* 300 */ + .long _sys_unlinkat + .long _sys_renameat + .long _sys_linkat + .long _sys_symlinkat + .long _sys_readlinkat /* 305 */ + .long _sys_fchmodat + .long _sys_faccessat + .long _sys_pselect6 + .long _sys_ppoll + .long _sys_unshare /* 310 */ + .long _sys_sram_alloc + .long _sys_sram_free + .long _sys_dma_memcpy + .long _sys_accept + .long _sys_bind /* 315 */ + .long _sys_connect + .long _sys_getpeername + .long _sys_getsockname + .long _sys_getsockopt + .long _sys_listen /* 320 */ + .long _sys_recv + .long _sys_recvfrom + .long _sys_recvmsg + .long _sys_send + .long _sys_sendmsg /* 325 */ + .long _sys_sendto + .long _sys_setsockopt + .long _sys_shutdown + .long _sys_socket + .long _sys_socketpair /* 330 */ + .long _sys_semctl + .long _sys_semget + .long _sys_semop + .long _sys_msgctl + .long _sys_msgget /* 335 */ + .long _sys_msgrcv + .long _sys_msgsnd + .long _sys_shmat + .long _sys_shmctl + .long _sys_shmdt /* 340 */ + .long _sys_shmget + .rept NR_syscalls-(.-_sys_call_table)/4 + .long _sys_ni_syscall + .endr +_excpt_saved_imask: + .long 0; + +_exception_stack: + .rept 1024 + .long 0; + .endr +_exception_stack_top: + +#if defined(ANOMALY_05000261) +/* Used by the assembly entry point to work around an anomaly. */ +_last_cplb_fault_retx: + .long 0; +#endif +/* + * Single instructions can have multiple faults, which need to be + * handled by traps.c, in irq5. We store the exception cause to ensure + * we don't miss a double fault condition + */ +ENTRY(_in_ptr_excause) + .long 0; +ENTRY(_out_ptr_excause) + .long 0; +ALIGN +ENTRY(_excause_circ_buf) + .rept 4 + .long 0 + .endr diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S new file mode 100644 index 000000000000..dd45664f0d02 --- /dev/null +++ b/arch/blackfin/mach-common/interrupt.S @@ -0,0 +1,253 @@ +/* + * File: arch/blackfin/mach-common/interrupt.S + * Based on: + * Author: D. Jeff Dionne + * Kenneth Albanowski + * + * Created: ? + * Description: Interrupt Entries + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef CONFIG_I_ENTRY_L1 +.section .l1.text +#else +.text +#endif + +.align 4 /* just in case */ + +/* + * initial interrupt handlers + */ + +#ifndef CONFIG_KGDB + /* interrupt routine for emulation - 0 */ + /* Currently used only if GDB stub is not in - invalid */ + /* gdb-stub set the evt itself */ + /* save registers for post-mortem only */ +ENTRY(_evt_emulation) + SAVE_ALL_SYS +#ifdef CONFIG_FRAME_POINTER + fp = 0; +#endif + r0 = IRQ_EMU; + r1 = sp; + SP += -12; + call _irq_panic; + SP += 12; + /* - GDB stub fills this in by itself (if defined) */ + rte; +#endif + +/* Common interrupt entry code. First we do CLI, then push + * RETI, to keep interrupts disabled, but to allow this state to be changed + * by local_bh_enable. + * R0 contains the interrupt number, while R1 may contain the value of IPEND, + * or garbage if IPEND won't be needed by the ISR. */ +__common_int_entry: + [--sp] = fp; + [--sp] = usp; + + [--sp] = i0; + [--sp] = i1; + [--sp] = i2; + [--sp] = i3; + + [--sp] = m0; + [--sp] = m1; + [--sp] = m2; + [--sp] = m3; + + [--sp] = l0; + [--sp] = l1; + [--sp] = l2; + [--sp] = l3; + + [--sp] = b0; + [--sp] = b1; + [--sp] = b2; + [--sp] = b3; + [--sp] = a0.x; + [--sp] = a0.w; + [--sp] = a1.x; + [--sp] = a1.w; + + [--sp] = LC0; + [--sp] = LC1; + [--sp] = LT0; + [--sp] = LT1; + [--sp] = LB0; + [--sp] = LB1; + + [--sp] = ASTAT; + + [--sp] = r0; /* Skip reserved */ + [--sp] = RETS; + r2 = RETI; + [--sp] = r2; + [--sp] = RETX; + [--sp] = RETN; + [--sp] = RETE; + [--sp] = SEQSTAT; + [--sp] = r1; /* IPEND - R1 may or may not be set up before jumping here. */ + + /* Switch to other method of keeping interrupts disabled. */ +#ifdef CONFIG_DEBUG_HWERR + r1 = 0x3f; + sti r1; +#else + cli r1; +#endif + [--sp] = RETI; /* orig_pc */ + /* Clear all L registers. */ + r1 = 0 (x); + l0 = r1; + l1 = r1; + l2 = r1; + l3 = r1; +#ifdef CONFIG_FRAME_POINTER + fp = 0; +#endif + +#ifdef ANOMALY_05000283 + cc = r7 == r7; + p5.h = 0xffc0; + p5.l = 0x0014; + if cc jump 1f; + r7.l = W[p5]; +1: +#endif + r1 = sp; + SP += -12; + call _do_irq; + SP += 12; + call _return_from_int; +.Lcommon_restore_context: + RESTORE_CONTEXT + rti; + +/* interrupt routine for ivhw - 5 */ +ENTRY(_evt_ivhw) + SAVE_CONTEXT +#ifdef CONFIG_FRAME_POINTER + fp = 0; +#endif +#ifdef ANOMALY_05000283 + cc = r7 == r7; + p5.h = 0xffc0; + p5.l = 0x0014; + if cc jump 1f; + r7.l = W[p5]; +1: +#endif + p0.l = lo(TBUFCTL); + p0.h = hi(TBUFCTL); + r0 = 1; + [p0] = r0; + r0 = IRQ_HWERR; + r1 = sp; + +#ifdef CONFIG_HARDWARE_PM + r7 = SEQSTAT; + r7 = r7 >>> 0xe; + r6 = 0x1F; + r7 = r7 & r6; + r5 = 0x12; + cc = r7 == r5; + if cc jump .Lcall_do_ovf; /* deal with performance counter overflow */ +#endif + + SP += -12; + call _irq_panic; + SP += 12; + rti; +#ifdef CONFIG_HARDWARE_PM +.Lcall_do_ovf: + + SP += -12; + call _pm_overflow; + SP += 12; + + jump .Lcommon_restore_context; +#endif + +/* interrupt routine for evt2 - 2. This is NMI. */ +ENTRY(_evt_evt2) + SAVE_CONTEXT +#ifdef CONFIG_FRAME_POINTER + fp = 0; +#endif +#ifdef ANOMALY_05000283 + cc = r7 == r7; + p5.h = 0xffc0; + p5.l = 0x0014; + if cc jump 1f; + r7.l = W[p5]; +1: +#endif + r0 = IRQ_NMI; + r1 = sp; + SP += -12; + call _asm_do_IRQ; + SP += 12; + RESTORE_CONTEXT + rtn; + +/* interrupt routine for core timer - 6 */ +ENTRY(_evt_timer) + TIMER_INTERRUPT_ENTRY(EVT_IVTMR_P) + +/* interrupt routine for evt7 - 7 */ +ENTRY(_evt_evt7) + INTERRUPT_ENTRY(EVT_IVG7_P) +ENTRY(_evt_evt8) + INTERRUPT_ENTRY(EVT_IVG8_P) +ENTRY(_evt_evt9) + INTERRUPT_ENTRY(EVT_IVG9_P) +ENTRY(_evt_evt10) + INTERRUPT_ENTRY(EVT_IVG10_P) +ENTRY(_evt_evt11) + INTERRUPT_ENTRY(EVT_IVG11_P) +ENTRY(_evt_evt12) + INTERRUPT_ENTRY(EVT_IVG12_P) +ENTRY(_evt_evt13) + INTERRUPT_ENTRY(EVT_IVG13_P) + + + /* interrupt routine for system_call - 15 */ +ENTRY(_evt_system_call) + SAVE_CONTEXT_SYSCALL +#ifdef CONFIG_FRAME_POINTER + fp = 0; +#endif + call _system_call; + jump .Lcommon_restore_context; diff --git a/arch/blackfin/mach-common/ints-priority-dc.c b/arch/blackfin/mach-common/ints-priority-dc.c new file mode 100644 index 000000000000..f3cf07036c2a --- /dev/null +++ b/arch/blackfin/mach-common/ints-priority-dc.c @@ -0,0 +1,476 @@ +/* + * File: arch/blackfin/mach-common/ints-priority-dc.c + * Based on: + * Author: + * + * Created: ? + * Description: Set up the interupt priorities + * + * Modified: + * 1996 Roman Zippel + * 1999 D. Jeff Dionne + * 2000-2001 Lineo, Inc. D. Jefff Dionne + * 2002 Arcturus Networks Inc. MaTed + * 2003 Metrowerks/Motorola + * 2003 Bas Vermeulen + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#ifdef CONFIG_KGDB +#include +#endif +#include +#include +#include +#include + +/* + * NOTES: + * - we have separated the physical Hardware interrupt from the + * levels that the LINUX kernel sees (see the description in irq.h) + * - + */ + +unsigned long irq_flags = 0; + +/* The number of spurious interrupts */ +atomic_t num_spurious; + +struct ivgx { + /* irq number for request_irq, available in mach-bf561/irq.h */ + int irqno; + /* corresponding bit in the SICA_ISR0 register */ + int isrflag0; + /* corresponding bit in the SICA_ISR1 register */ + int isrflag1; +} ivg_table[NR_PERI_INTS]; + +struct ivg_slice { + /* position of first irq in ivg_table for given ivg */ + struct ivgx *ifirst; + struct ivgx *istop; +} ivg7_13[IVG13 - IVG7 + 1]; + +static void search_IAR(void); + +/* + * Search SIC_IAR and fill tables with the irqvalues + * and their positions in the SIC_ISR register. + */ +static void __init search_IAR(void) +{ + unsigned ivg, irq_pos = 0; + for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) { + int irqn; + + ivg7_13[ivg].istop = ivg7_13[ivg].ifirst = &ivg_table[irq_pos]; + + for (irqn = 0; irqn < NR_PERI_INTS; irqn++) { + int iar_shift = (irqn & 7) * 4; + if (ivg == + (0xf & + bfin_read32((unsigned long *)SICA_IAR0 + + (irqn >> 3)) >> iar_shift)) { + ivg_table[irq_pos].irqno = IVG7 + irqn; + ivg_table[irq_pos].isrflag0 = + (irqn < 32 ? (1 << irqn) : 0); + ivg_table[irq_pos].isrflag1 = + (irqn < 32 ? 0 : (1 << (irqn - 32))); + ivg7_13[ivg].istop++; + irq_pos++; + } + } + } +} + +/* + * This is for BF561 internal IRQs + */ + +static void ack_noop(unsigned int irq) +{ + /* Dummy function. */ +} + +static void bf561_core_mask_irq(unsigned int irq) +{ + irq_flags &= ~(1 << irq); + if (!irqs_disabled()) + local_irq_enable(); +} + +static void bf561_core_unmask_irq(unsigned int irq) +{ + irq_flags |= 1 << irq; + /* + * If interrupts are enabled, IMASK must contain the same value + * as irq_flags. Make sure that invariant holds. If interrupts + * are currently disabled we need not do anything; one of the + * callers will take care of setting IMASK to the proper value + * when reenabling interrupts. + * local_irq_enable just does "STI irq_flags", so it's exactly + * what we need. + */ + if (!irqs_disabled()) + local_irq_enable(); + return; +} + +static void bf561_internal_mask_irq(unsigned int irq) +{ + unsigned long irq_mask; + if ((irq - (IRQ_CORETMR + 1)) < 32) { + irq_mask = (1 << (irq - (IRQ_CORETMR + 1))); + bfin_write_SICA_IMASK0(bfin_read_SICA_IMASK0() & ~irq_mask); + } else { + irq_mask = (1 << (irq - (IRQ_CORETMR + 1) - 32)); + bfin_write_SICA_IMASK1(bfin_read_SICA_IMASK1() & ~irq_mask); + } +} + +static void bf561_internal_unmask_irq(unsigned int irq) +{ + unsigned long irq_mask; + + if ((irq - (IRQ_CORETMR + 1)) < 32) { + irq_mask = (1 << (irq - (IRQ_CORETMR + 1))); + bfin_write_SICA_IMASK0(bfin_read_SICA_IMASK0() | irq_mask); + } else { + irq_mask = (1 << (irq - (IRQ_CORETMR + 1) - 32)); + bfin_write_SICA_IMASK1(bfin_read_SICA_IMASK1() | irq_mask); + } + SSYNC(); +} + +static struct irq_chip bf561_core_irqchip = { + .ack = ack_noop, + .mask = bf561_core_mask_irq, + .unmask = bf561_core_unmask_irq, +}; + +static struct irq_chip bf561_internal_irqchip = { + .ack = ack_noop, + .mask = bf561_internal_mask_irq, + .unmask = bf561_internal_unmask_irq, +}; + +#ifdef CONFIG_IRQCHIP_DEMUX_GPIO +static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; +static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; + +static void bf561_gpio_ack_irq(unsigned int irq) +{ + u16 gpionr = irq - IRQ_PF0; + + if(gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { + set_gpio_data(gpionr, 0); + SSYNC(); + } +} + +static void bf561_gpio_mask_ack_irq(unsigned int irq) +{ + u16 gpionr = irq - IRQ_PF0; + + if(gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { + set_gpio_data(gpionr, 0); + SSYNC(); + } + + set_gpio_maska(gpionr, 0); + SSYNC(); +} + +static void bf561_gpio_mask_irq(unsigned int irq) +{ + set_gpio_maska(irq - IRQ_PF0, 0); + SSYNC(); +} + +static void bf561_gpio_unmask_irq(unsigned int irq) +{ + set_gpio_maska(irq - IRQ_PF0, 1); + SSYNC(); +} + +static unsigned int bf561_gpio_irq_startup(unsigned int irq) +{ + unsigned int ret; + u16 gpionr = irq - IRQ_PF0; + + if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { + + ret = gpio_request(gpionr, NULL); + if(ret) + return ret; + + } + + gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); + bf561_gpio_unmask_irq(irq); + + return ret; + +} + +static void bf561_gpio_irq_shutdown(unsigned int irq) +{ + bf561_gpio_mask_irq(irq); + gpio_free(irq - IRQ_PF0); + gpio_enabled[gpio_bank(irq - IRQ_PF0)] &= ~gpio_bit(irq - IRQ_PF0); +} + +static int bf561_gpio_irq_type(unsigned int irq, unsigned int type) +{ + + unsigned int ret; + u16 gpionr = irq - IRQ_PF0; + + + if (type == IRQ_TYPE_PROBE) { + /* only probe unenabled GPIO interrupt lines */ + if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr)) + return 0; + type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; + + } + + if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | + IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { + + if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { + + ret = gpio_request(gpionr, NULL); + if(ret) + return ret; + + } + + gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); + } else { + gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); + return 0; + } + + + set_gpio_dir(gpionr, 0); + set_gpio_inen(gpionr, 1); + + + if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { + gpio_edge_triggered[gpio_bank(gpionr)] |= gpio_bit(gpionr); + set_gpio_edge(gpionr, 1); + } else { + set_gpio_edge(gpionr, 0); + gpio_edge_triggered[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); + } + + if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) + == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) + set_gpio_both(gpionr, 1); + else + set_gpio_both(gpionr, 0); + + if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) + set_gpio_polar(gpionr, 1); /* low or falling edge denoted by one */ + else + set_gpio_polar(gpionr, 0); /* high or rising edge denoted by zero */ + + SSYNC(); + + if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) + set_irq_handler(irq, handle_edge_irq); + else + set_irq_handler(irq, handle_level_irq); + + return 0; +} + +static struct irq_chip bf561_gpio_irqchip = { + .ack = bf561_gpio_ack_irq, + .mask = bf561_gpio_mask_irq, + .mask_ack = bf561_gpio_mask_ack_irq, + .unmask = bf561_gpio_unmask_irq, + .set_type = bf561_gpio_irq_type, + .startup = bf561_gpio_irq_startup, + .shutdown = bf561_gpio_irq_shutdown +}; + +static void bf561_demux_gpio_irq(unsigned int inta_irq, + struct irq_desc *intb_desc) +{ + int irq, flag_d, mask; + u16 gpio; + + switch (inta_irq) { + case IRQ_PROG0_INTA: + irq = IRQ_PF0; + break; + case IRQ_PROG1_INTA: + irq = IRQ_PF16; + break; + case IRQ_PROG2_INTA: + irq = IRQ_PF32; + break; + default: + dump_stack(); + return; + } + + gpio = irq - IRQ_PF0; + + flag_d = get_gpiop_data(gpio); + mask = flag_d & (gpio_enabled[gpio_bank(gpio)] & + get_gpiop_maska(gpio)); + + do { + if (mask & 1) { + struct irq_desc *desc = irq_desc + irq; + desc->handle_irq(irq, desc); + } + irq++; + mask >>= 1; + } while (mask); + + +} + +#endif /* CONFIG_IRQCHIP_DEMUX_GPIO */ + +/* + * This function should be called during kernel startup to initialize + * the BFin IRQ handling routines. + */ +int __init init_arch_irq(void) +{ + int irq; + unsigned long ilat = 0; + /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ + bfin_write_SICA_IMASK0(SIC_UNMASK_ALL); + bfin_write_SICA_IMASK1(SIC_UNMASK_ALL); + SSYNC(); + + local_irq_disable(); + + init_exception_buff(); + +#ifndef CONFIG_KGDB + bfin_write_EVT0(evt_emulation); +#endif + bfin_write_EVT2(evt_evt2); + bfin_write_EVT3(trap); + bfin_write_EVT5(evt_ivhw); + bfin_write_EVT6(evt_timer); + bfin_write_EVT7(evt_evt7); + bfin_write_EVT8(evt_evt8); + bfin_write_EVT9(evt_evt9); + bfin_write_EVT10(evt_evt10); + bfin_write_EVT11(evt_evt11); + bfin_write_EVT12(evt_evt12); + bfin_write_EVT13(evt_evt13); + bfin_write_EVT14(evt14_softirq); + bfin_write_EVT15(evt_system_call); + CSYNC(); + + for (irq = 0; irq < SYS_IRQS; irq++) { + if (irq <= IRQ_CORETMR) + set_irq_chip(irq, &bf561_core_irqchip); + else + set_irq_chip(irq, &bf561_internal_irqchip); +#ifdef CONFIG_IRQCHIP_DEMUX_GPIO + if ((irq != IRQ_PROG0_INTA) && + (irq != IRQ_PROG1_INTA) && (irq != IRQ_PROG2_INTA)) { +#endif + set_irq_handler(irq, handle_simple_irq); +#ifdef CONFIG_IRQCHIP_DEMUX_GPIO + } else { + set_irq_chained_handler(irq, bf561_demux_gpio_irq); + } +#endif + + } + +#ifdef CONFIG_IRQCHIP_DEMUX_GPIO + for (irq = IRQ_PF0; irq <= IRQ_PF47; irq++) { + set_irq_chip(irq, &bf561_gpio_irqchip); + /* if configured as edge, then will be changed to do_edge_IRQ */ + set_irq_handler(irq, handle_level_irq); + } +#endif + bfin_write_IMASK(0); + CSYNC(); + ilat = bfin_read_ILAT(); + CSYNC(); + bfin_write_ILAT(ilat); + CSYNC(); + + printk(KERN_INFO "Configuring Blackfin Priority Driven Interrupts\n"); + /* IMASK=xxx is equivalent to STI xx or irq_flags=xx, + * local_irq_enable() + */ + program_IAR(); + /* Therefore it's better to setup IARs before interrupts enabled */ + search_IAR(); + + /* Enable interrupts IVG7-15 */ + irq_flags = irq_flags | IMASK_IVG15 | + IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | + IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; + + return 0; +} + +#ifdef CONFIG_DO_IRQ_L1 +void do_irq(int vec, struct pt_regs *fp)__attribute__((l1_text)); +#endif + +void do_irq(int vec, struct pt_regs *fp) +{ + if (vec == EVT_IVTMR_P) { + vec = IRQ_CORETMR; + } else { + struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; + struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; + unsigned long sic_status0, sic_status1; + + SSYNC(); + sic_status0 = bfin_read_SICA_IMASK0() & bfin_read_SICA_ISR0(); + sic_status1 = bfin_read_SICA_IMASK1() & bfin_read_SICA_ISR1(); + + for (;; ivg++) { + if (ivg >= ivg_stop) { + atomic_inc(&num_spurious); + return; + } else if ((sic_status0 & ivg->isrflag0) || + (sic_status1 & ivg->isrflag1)) + break; + } + vec = ivg->irqno; + } + asm_do_IRQ(vec, fp); + +#ifdef CONFIG_KGDB + kgdb_process_breakpoint(); +#endif +} diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c new file mode 100644 index 000000000000..34b62288ec3c --- /dev/null +++ b/arch/blackfin/mach-common/ints-priority-sc.c @@ -0,0 +1,577 @@ +/* + * File: arch/blackfin/mach-common/ints-priority-sc.c + * Based on: + * Author: + * + * Created: ? + * Description: Set up the interupt priorities + * + * Modified: + * 1996 Roman Zippel + * 1999 D. Jeff Dionne + * 2000-2001 Lineo, Inc. D. Jefff Dionne + * 2002 Arcturus Networks Inc. MaTed + * 2003 Metrowerks/Motorola + * 2003 Bas Vermeulen + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#ifdef CONFIG_KGDB +#include +#endif +#include +#include +#include +#include + +#ifdef BF537_FAMILY +# define BF537_GENERIC_ERROR_INT_DEMUX +#else +# undef BF537_GENERIC_ERROR_INT_DEMUX +#endif + +/* + * NOTES: + * - we have separated the physical Hardware interrupt from the + * levels that the LINUX kernel sees (see the description in irq.h) + * - + */ + +unsigned long irq_flags = 0; + +/* The number of spurious interrupts */ +atomic_t num_spurious; + +struct ivgx { + /* irq number for request_irq, available in mach-bf533/irq.h */ + int irqno; + /* corresponding bit in the SIC_ISR register */ + int isrflag; +} ivg_table[NR_PERI_INTS]; + +struct ivg_slice { + /* position of first irq in ivg_table for given ivg */ + struct ivgx *ifirst; + struct ivgx *istop; +} ivg7_13[IVG13 - IVG7 + 1]; + +static void search_IAR(void); + +/* + * Search SIC_IAR and fill tables with the irqvalues + * and their positions in the SIC_ISR register. + */ +static void __init search_IAR(void) +{ + unsigned ivg, irq_pos = 0; + for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) { + int irqn; + + ivg7_13[ivg].istop = ivg7_13[ivg].ifirst = + &ivg_table[irq_pos]; + + for (irqn = 0; irqn < NR_PERI_INTS; irqn++) { + int iar_shift = (irqn & 7) * 4; + if (ivg == + (0xf & + bfin_read32((unsigned long *) SIC_IAR0 + + (irqn >> 3)) >> iar_shift)) { + ivg_table[irq_pos].irqno = IVG7 + irqn; + ivg_table[irq_pos].isrflag = 1 << irqn; + ivg7_13[ivg].istop++; + irq_pos++; + } + } + } +} + +/* + * This is for BF533 internal IRQs + */ + +static void ack_noop(unsigned int irq) +{ + /* Dummy function. */ +} + +static void bfin_core_mask_irq(unsigned int irq) +{ + irq_flags &= ~(1 << irq); + if (!irqs_disabled()) + local_irq_enable(); +} + +static void bfin_core_unmask_irq(unsigned int irq) +{ + irq_flags |= 1 << irq; + /* + * If interrupts are enabled, IMASK must contain the same value + * as irq_flags. Make sure that invariant holds. If interrupts + * are currently disabled we need not do anything; one of the + * callers will take care of setting IMASK to the proper value + * when reenabling interrupts. + * local_irq_enable just does "STI irq_flags", so it's exactly + * what we need. + */ + if (!irqs_disabled()) + local_irq_enable(); + return; +} + +static void bfin_internal_mask_irq(unsigned int irq) +{ + bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & + ~(1 << (irq - (IRQ_CORETMR + 1)))); + SSYNC(); +} + +static void bfin_internal_unmask_irq(unsigned int irq) +{ + bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | + (1 << (irq - (IRQ_CORETMR + 1)))); + SSYNC(); +} + +static struct irq_chip bfin_core_irqchip = { + .ack = ack_noop, + .mask = bfin_core_mask_irq, + .unmask = bfin_core_unmask_irq, +}; + +static struct irq_chip bfin_internal_irqchip = { + .ack = ack_noop, + .mask = bfin_internal_mask_irq, + .unmask = bfin_internal_unmask_irq, +}; + +#ifdef BF537_GENERIC_ERROR_INT_DEMUX +static int error_int_mask; + +static void bfin_generic_error_ack_irq(unsigned int irq) +{ + +} + +static void bfin_generic_error_mask_irq(unsigned int irq) +{ + error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR)); + + if (!error_int_mask) { + local_irq_disable(); + bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & + ~(1 << + (IRQ_GENERIC_ERROR - + (IRQ_CORETMR + 1)))); + SSYNC(); + local_irq_enable(); + } +} + +static void bfin_generic_error_unmask_irq(unsigned int irq) +{ + local_irq_disable(); + bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 1 << + (IRQ_GENERIC_ERROR - (IRQ_CORETMR + 1))); + SSYNC(); + local_irq_enable(); + + error_int_mask |= 1L << (irq - IRQ_PPI_ERROR); +} + +static struct irq_chip bfin_generic_error_irqchip = { + .ack = bfin_generic_error_ack_irq, + .mask = bfin_generic_error_mask_irq, + .unmask = bfin_generic_error_unmask_irq, +}; + +static void bfin_demux_error_irq(unsigned int int_err_irq, + struct irq_desc *intb_desc) +{ + int irq = 0; + + SSYNC(); + +#if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) + if (bfin_read_EMAC_SYSTAT() & EMAC_ERR_MASK) + irq = IRQ_MAC_ERROR; + else +#endif + if (bfin_read_SPORT0_STAT() & SPORT_ERR_MASK) + irq = IRQ_SPORT0_ERROR; + else if (bfin_read_SPORT1_STAT() & SPORT_ERR_MASK) + irq = IRQ_SPORT1_ERROR; + else if (bfin_read_PPI_STATUS() & PPI_ERR_MASK) + irq = IRQ_PPI_ERROR; + else if (bfin_read_CAN_GIF() & CAN_ERR_MASK) + irq = IRQ_CAN_ERROR; + else if (bfin_read_SPI_STAT() & SPI_ERR_MASK) + irq = IRQ_SPI_ERROR; + else if ((bfin_read_UART0_IIR() & UART_ERR_MASK_STAT1) && + (bfin_read_UART0_IIR() & UART_ERR_MASK_STAT0)) + irq = IRQ_UART0_ERROR; + else if ((bfin_read_UART1_IIR() & UART_ERR_MASK_STAT1) && + (bfin_read_UART1_IIR() & UART_ERR_MASK_STAT0)) + irq = IRQ_UART1_ERROR; + + if (irq) { + if (error_int_mask & (1L << (irq - IRQ_PPI_ERROR))) { + struct irq_desc *desc = irq_desc + irq; + desc->handle_irq(irq, desc); + } else { + + switch (irq) { + case IRQ_PPI_ERROR: + bfin_write_PPI_STATUS(PPI_ERR_MASK); + break; +#if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) + case IRQ_MAC_ERROR: + bfin_write_EMAC_SYSTAT(EMAC_ERR_MASK); + break; +#endif + case IRQ_SPORT0_ERROR: + bfin_write_SPORT0_STAT(SPORT_ERR_MASK); + break; + + case IRQ_SPORT1_ERROR: + bfin_write_SPORT1_STAT(SPORT_ERR_MASK); + break; + + case IRQ_CAN_ERROR: + bfin_write_CAN_GIS(CAN_ERR_MASK); + break; + + case IRQ_SPI_ERROR: + bfin_write_SPI_STAT(SPI_ERR_MASK); + break; + + default: + break; + } + + pr_debug("IRQ %d:" + " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n", + irq); + } + } else + printk(KERN_ERR + "%s : %s : LINE %d :\nIRQ ?: PERIPHERAL ERROR" + " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n", + __FUNCTION__, __FILE__, __LINE__); + + +} +#endif /* BF537_GENERIC_ERROR_INT_DEMUX */ + +#ifdef CONFIG_IRQCHIP_DEMUX_GPIO + +static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; +static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; + +static void bfin_gpio_ack_irq(unsigned int irq) +{ + u16 gpionr = irq - IRQ_PF0; + + if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { + set_gpio_data(gpionr, 0); + SSYNC(); + } +} + +static void bfin_gpio_mask_ack_irq(unsigned int irq) +{ + u16 gpionr = irq - IRQ_PF0; + + if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { + set_gpio_data(gpionr, 0); + SSYNC(); + } + + set_gpio_maska(gpionr, 0); + SSYNC(); +} + +static void bfin_gpio_mask_irq(unsigned int irq) +{ + set_gpio_maska(irq - IRQ_PF0, 0); + SSYNC(); +} + +static void bfin_gpio_unmask_irq(unsigned int irq) +{ + set_gpio_maska(irq - IRQ_PF0, 1); + SSYNC(); +} + +static unsigned int bfin_gpio_irq_startup(unsigned int irq) +{ + unsigned int ret; + u16 gpionr = irq - IRQ_PF0; + + if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { + ret = gpio_request(gpionr, NULL); + if (ret) + return ret; + } + + gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); + bfin_gpio_unmask_irq(irq); + + return ret; +} + +static void bfin_gpio_irq_shutdown(unsigned int irq) +{ + bfin_gpio_mask_irq(irq); + gpio_free(irq - IRQ_PF0); + gpio_enabled[gpio_bank(irq - IRQ_PF0)] &= ~gpio_bit(irq - IRQ_PF0); +} + +static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) +{ + + unsigned int ret; + u16 gpionr = irq - IRQ_PF0; + + if (type == IRQ_TYPE_PROBE) { + /* only probe unenabled GPIO interrupt lines */ + if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr)) + return 0; + type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; + } + + if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | + IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) + { + if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { + ret = gpio_request(gpionr, NULL); + if (ret) + return ret; + } + + gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); + } else { + gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); + return 0; + } + + set_gpio_dir(gpionr, 0); + set_gpio_inen(gpionr, 1); + + if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { + gpio_edge_triggered[gpio_bank(gpionr)] |= gpio_bit(gpionr); + set_gpio_edge(gpionr, 1); + } else { + set_gpio_edge(gpionr, 0); + gpio_edge_triggered[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); + } + + if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) + == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) + set_gpio_both(gpionr, 1); + else + set_gpio_both(gpionr, 0); + + if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) + set_gpio_polar(gpionr, 1); /* low or falling edge denoted by one */ + else + set_gpio_polar(gpionr, 0); /* high or rising edge denoted by zero */ + + SSYNC(); + + if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) + set_irq_handler(irq, handle_edge_irq); + else + set_irq_handler(irq, handle_level_irq); + + return 0; +} + + +static struct irq_chip bfin_gpio_irqchip = { + .ack = bfin_gpio_ack_irq, + .mask = bfin_gpio_mask_irq, + .mask_ack = bfin_gpio_mask_ack_irq, + .unmask = bfin_gpio_unmask_irq, + .set_type = bfin_gpio_irq_type, + .startup = bfin_gpio_irq_startup, + .shutdown = bfin_gpio_irq_shutdown +}; + +static void bfin_demux_gpio_irq(unsigned int intb_irq, + struct irq_desc *intb_desc) +{ + u16 i; + + for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=16) { + int irq = IRQ_PF0 + i; + int flag_d = get_gpiop_data(i); + int mask = + flag_d & (gpio_enabled[gpio_bank(i)] & + get_gpiop_maska(i)); + + while (mask) { + if (mask & 1) { + struct irq_desc *desc = irq_desc + irq; + desc->handle_irq(irq, desc); + } + irq++; + mask >>= 1; + } + } +} + +#endif /* CONFIG_IRQCHIP_DEMUX_GPIO */ + +/* + * This function should be called during kernel startup to initialize + * the BFin IRQ handling routines. + */ +int __init init_arch_irq(void) +{ + int irq; + unsigned long ilat = 0; + /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ + bfin_write_SIC_IMASK(SIC_UNMASK_ALL); + SSYNC(); + + local_irq_disable(); + +#ifndef CONFIG_KGDB + bfin_write_EVT0(evt_emulation); +#endif + bfin_write_EVT2(evt_evt2); + bfin_write_EVT3(trap); + bfin_write_EVT5(evt_ivhw); + bfin_write_EVT6(evt_timer); + bfin_write_EVT7(evt_evt7); + bfin_write_EVT8(evt_evt8); + bfin_write_EVT9(evt_evt9); + bfin_write_EVT10(evt_evt10); + bfin_write_EVT11(evt_evt11); + bfin_write_EVT12(evt_evt12); + bfin_write_EVT13(evt_evt13); + bfin_write_EVT14(evt14_softirq); + bfin_write_EVT15(evt_system_call); + CSYNC(); + + for (irq = 0; irq < SYS_IRQS; irq++) { + if (irq <= IRQ_CORETMR) + set_irq_chip(irq, &bfin_core_irqchip); + else + set_irq_chip(irq, &bfin_internal_irqchip); +#ifdef BF537_GENERIC_ERROR_INT_DEMUX + if (irq != IRQ_GENERIC_ERROR) { +#endif + +#ifdef CONFIG_IRQCHIP_DEMUX_GPIO + if ((irq != IRQ_PROG_INTA) /*PORT F & G MASK_A Interrupt*/ +# if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) + && (irq != IRQ_MAC_RX) /*PORT H MASK_A Interrupt*/ +# endif + ) { +#endif + set_irq_handler(irq, handle_simple_irq); +#ifdef CONFIG_IRQCHIP_DEMUX_GPIO + } else { + set_irq_chained_handler(irq, + bfin_demux_gpio_irq); + } +#endif + +#ifdef BF537_GENERIC_ERROR_INT_DEMUX + } else { + set_irq_handler(irq, bfin_demux_error_irq); + } +#endif + } +#ifdef BF537_GENERIC_ERROR_INT_DEMUX + for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) { + set_irq_chip(irq, &bfin_generic_error_irqchip); + set_irq_handler(irq, handle_level_irq); + } +#endif + +#ifdef CONFIG_IRQCHIP_DEMUX_GPIO + for (irq = IRQ_PF0; irq < NR_IRQS; irq++) { + set_irq_chip(irq, &bfin_gpio_irqchip); + /* if configured as edge, then will be changed to do_edge_IRQ */ + set_irq_handler(irq, handle_level_irq); + } +#endif + bfin_write_IMASK(0); + CSYNC(); + ilat = bfin_read_ILAT(); + CSYNC(); + bfin_write_ILAT(ilat); + CSYNC(); + + printk(KERN_INFO + "Configuring Blackfin Priority Driven Interrupts\n"); + /* IMASK=xxx is equivalent to STI xx or irq_flags=xx, + * local_irq_enable() + */ + program_IAR(); + /* Therefore it's better to setup IARs before interrupts enabled */ + search_IAR(); + + /* Enable interrupts IVG7-15 */ + irq_flags = irq_flags | IMASK_IVG15 | + IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | + IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | + IMASK_IVGHW; + + return 0; +} + +#ifdef CONFIG_DO_IRQ_L1 +void do_irq(int vec, struct pt_regs *fp)__attribute__((l1_text)); +#endif + +void do_irq(int vec, struct pt_regs *fp) +{ + if (vec == EVT_IVTMR_P) { + vec = IRQ_CORETMR; + } else { + struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; + struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; + unsigned long sic_status; + + SSYNC(); + sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); + + for (;; ivg++) { + if (ivg >= ivg_stop) { + atomic_inc(&num_spurious); + return; + } else if (sic_status & ivg->isrflag) + break; + } + vec = ivg->irqno; + } + asm_do_IRQ(vec, fp); + +#ifdef CONFIG_KGDB + kgdb_process_breakpoint(); +#endif +} diff --git a/arch/blackfin/mach-common/irqpanic.c b/arch/blackfin/mach-common/irqpanic.c new file mode 100644 index 000000000000..f05e3dadaf33 --- /dev/null +++ b/arch/blackfin/mach-common/irqpanic.c @@ -0,0 +1,194 @@ +/* + * File: arch/blackfin/mach-common/irqpanic.c + * Based on: + * Author: + * + * Created: ? + * Description: panic kernel with dump information + * + * Modified: rgetz - added cache checking code 14Feb06 + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +#include "../oprofile/op_blackfin.h" + +#ifdef CONFIG_DEBUG_ICACHE_CHECK +#define L1_ICACHE_START 0xffa10000 +#define L1_ICACHE_END 0xffa13fff +void irq_panic(int reason, struct pt_regs *regs) __attribute__ ((l1_text)); +#endif + +/* + * irq_panic - calls panic with string setup + */ +asmlinkage void irq_panic(int reason, struct pt_regs *regs) +{ + int sig = 0; + siginfo_t info; + +#ifdef CONFIG_DEBUG_ICACHE_CHECK + unsigned int cmd, tag, ca, cache_hi, cache_lo, *pa; + unsigned short i, j, die; + unsigned int bad[10][6]; + + /* check entire cache for coherency + * Since printk is in cacheable memory, + * don't call it until you have checked everything + */ + + die = 0; + i = 0; + + /* check icache */ + + for (ca = L1_ICACHE_START; ca <= L1_ICACHE_END && i < 10; ca += 32) { + + /* Grab various address bits for the itest_cmd fields */ + cmd = (((ca & 0x3000) << 4) | /* ca[13:12] for SBNK[1:0] */ + ((ca & 0x0c00) << 16) | /* ca[11:10] for WAYSEL[1:0] */ + ((ca & 0x3f8)) | /* ca[09:03] for SET[4:0] and DW[1:0] */ + 0); /* Access Tag, Read access */ + + SSYNC(); + bfin_write_ITEST_COMMAND(cmd); + SSYNC(); + tag = bfin_read_ITEST_DATA0(); + SSYNC(); + + /* if tag is marked as valid, check it */ + if (tag & 1) { + /* The icache is arranged in 4 groups of 64-bits */ + for (j = 0; j < 32; j += 8) { + cmd = ((((ca + j) & 0x3000) << 4) | /* ca[13:12] for SBNK[1:0] */ + (((ca + j) & 0x0c00) << 16) | /* ca[11:10] for WAYSEL[1:0] */ + (((ca + j) & 0x3f8)) | /* ca[09:03] for SET[4:0] and DW[1:0] */ + 4); /* Access Data, Read access */ + + SSYNC(); + bfin_write_ITEST_COMMAND(cmd); + SSYNC(); + + cache_hi = bfin_read_ITEST_DATA1(); + cache_lo = bfin_read_ITEST_DATA0(); + + pa = ((unsigned int *)((tag & 0xffffcc00) | + ((ca + j) & ~(0xffffcc00)))); + + /* + * Debugging this, enable + * + * printk("addr: %08x %08x%08x | %08x%08x\n", + * ((unsigned int *)((tag & 0xffffcc00) | ((ca+j) & ~(0xffffcc00)))), + * cache_hi, cache_lo, *(pa+1), *pa); + */ + + if (cache_hi != *(pa + 1) || cache_lo != *pa) { + /* Since icache is not working, stay out of it, by not printing */ + die = 1; + bad[i][0] = (ca + j); + bad[i][1] = cache_hi; + bad[i][2] = cache_lo; + bad[i][3] = ((tag & 0xffffcc00) | + ((ca + j) & ~(0xffffcc00))); + bad[i][4] = *(pa + 1); + bad[i][5] = *(pa); + i++; + } + } + } + } + if (die) { + printk(KERN_EMERG "icache coherency error\n"); + for (j = 0; j <= i; j++) { + printk(KERN_EMERG + "cache address : %08x cache value : %08x%08x\n", + bad[j][0], bad[j][1], bad[j][2]); + printk(KERN_EMERG + "physical address: %08x SDRAM value : %08x%08x\n", + bad[j][3], bad[j][4], bad[j][5]); + } + panic("icache coherency error"); + } else { + printk(KERN_EMERG "icache checked, and OK\n"); + } +#endif + + printk(KERN_EMERG "\n"); + printk(KERN_EMERG "Exception: IRQ 0x%x entered\n", reason); + printk(KERN_EMERG " code=[0x%08lx], stack frame=0x%08lx, " + " bad PC=0x%08lx\n", + (unsigned long)regs->seqstat, + (unsigned long)regs, + (unsigned long)regs->pc); + if (reason == 0x5) { + printk(KERN_EMERG "----------- HARDWARE ERROR -----------\n"); + + /* There is only need to check for Hardware Errors, since other + * EXCEPTIONS are handled in TRAPS.c (MH) + */ + switch (regs->seqstat & SEQSTAT_HWERRCAUSE) { + case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR): /* System MMR Error */ + info.si_code = BUS_ADRALN; + sig = SIGBUS; + printk(KERN_EMERG HWC_x2); + break; + case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR): /* External Memory Addressing Error */ + info.si_code = BUS_ADRERR; + sig = SIGBUS; + printk(KERN_EMERG HWC_x3); + break; + case (SEQSTAT_HWERRCAUSE_PERF_FLOW): /* Performance Monitor Overflow */ + printk(KERN_EMERG HWC_x12); + break; + case (SEQSTAT_HWERRCAUSE_RAISE_5): /* RAISE 5 instruction */ + printk(KERN_EMERG HWC_x18); + break; + default: /* Reserved */ + printk(KERN_EMERG HWC_default); + break; + } + } + + regs->ipend = bfin_read_IPEND(); + dump_bfin_regs(regs, (void *)regs->pc); + if (0 == (info.si_signo = sig) || 0 == user_mode(regs)) /* in kernelspace */ + panic("Unhandled IRQ or exceptions!\n"); + else { /* in userspace */ + info.si_errno = 0; + info.si_addr = (void *)regs->pc; + force_sig_info(sig, &info, current); + } +} + +#ifdef CONFIG_HARDWARE_PM +/* + * call the handler of Performance overflow + */ +asmlinkage void pm_overflow(int irq, struct pt_regs *regs) +{ + pm_overflow_handler(irq, regs); +} +#endif diff --git a/arch/blackfin/mach-common/lock.S b/arch/blackfin/mach-common/lock.S new file mode 100644 index 000000000000..2cbb15b33925 --- /dev/null +++ b/arch/blackfin/mach-common/lock.S @@ -0,0 +1,204 @@ +/* + * File: arch/blackfin/mach-common/lock.S + * Based on: + * Author: LG Soft India + * + * Created: ? + * Description: kernel locks + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +.text + +#ifdef CONFIG_BLKFIN_CACHE_LOCK + +/* When you come here, it is assumed that + * R0 - Which way to be locked + */ + +ENTRY(_cache_grab_lock) + + [--SP]=( R7:0,P5:0 ); + + P1.H = (IMEM_CONTROL >> 16); + P1.L = (IMEM_CONTROL & 0xFFFF); + P5.H = (ICPLB_ADDR0 >> 16); + P5.L = (ICPLB_ADDR0 & 0xFFFF); + P4.H = (ICPLB_DATA0 >> 16); + P4.L = (ICPLB_DATA0 & 0xFFFF); + R7 = R0; + + /* If the code of interest already resides in the cache + * invalidate the entire cache itself. + * invalidate_entire_icache; + */ + + SP += -12; + [--SP] = RETS; + CALL _invalidate_entire_icache; + RETS = [SP++]; + SP += 12; + + /* Disable the Interrupts*/ + + CLI R3; + +.LLOCK_WAY: + + /* Way0 - 0xFFA133E0 + * Way1 - 0xFFA137E0 + * Way2 - 0xFFA13BE0 Total Way Size = 4K + * Way3 - 0xFFA13FE0 + */ + + /* Procedure Ex. -Set the locks for other ways by setting ILOC[3:1] + * Only Way0 of the instruction cache can now be + * replaced by a new code + */ + + R5 = R7; + CC = BITTST(R7,0); + IF CC JUMP .LCLEAR1; + R7 = 0; + BITSET(R7,0); + JUMP .LDONE1; + +.LCLEAR1: + R7 = 0; + BITCLR(R7,0); +.LDONE1: R4 = R7 << 3; + R7 = [P1]; + R7 = R7 | R4; + SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ + .align 8; + [P1] = R7; + SSYNC; + + R7 = R5; + CC = BITTST(R7,1); + IF CC JUMP .LCLEAR2; + R7 = 0; + BITSET(R7,1); + JUMP .LDONE2; + +.LCLEAR2: + R7 = 0; + BITCLR(R7,1); +.LDONE2: R4 = R7 << 3; + R7 = [P1]; + R7 = R7 | R4; + SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ + .align 8; + [P1] = R7; + SSYNC; + + R7 = R5; + CC = BITTST(R7,2); + IF CC JUMP .LCLEAR3; + R7 = 0; + BITSET(R7,2); + JUMP .LDONE3; +.LCLEAR3: + R7 = 0; + BITCLR(R7,2); +.LDONE3: R4 = R7 << 3; + R7 = [P1]; + R7 = R7 | R4; + SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ + .align 8; + [P1] = R7; + SSYNC; + + + R7 = R5; + CC = BITTST(R7,3); + IF CC JUMP .LCLEAR4; + R7 = 0; + BITSET(R7,3); + JUMP .LDONE4; +.LCLEAR4: + R7 = 0; + BITCLR(R7,3); +.LDONE4: R4 = R7 << 3; + R7 = [P1]; + R7 = R7 | R4; + SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ + .align 8; + [P1] = R7; + SSYNC; + + STI R3; + + ( R7:0,P5:0 ) = [SP++]; + + RTS; + +/* After the execution of critical code, the code is now locked into + * the cache way. Now we need to set ILOC. + * + * R0 - Which way to be locked + */ + +ENTRY(_cache_lock) + + [--SP]=( R7:0,P5:0 ); + + P1.H = (IMEM_CONTROL >> 16); + P1.L = (IMEM_CONTROL & 0xFFFF); + + /* Disable the Interrupts*/ + CLI R3; + + R7 = [P1]; + R2 = 0xFFFFFF87 (X); + R7 = R7 & R2; + R0 = R0 << 3; + R7 = R0 | R7; + SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ + .align 8; + [P1] = R7; + SSYNC; + /* Renable the Interrupts */ + STI R3; + + ( R7:0,P5:0 ) = [SP++]; + RTS; + +#endif /* BLKFIN_CACHE_LOCK */ + +/* Return the ILOC bits of IMEM_CONTROL + */ + +ENTRY(_read_iloc) + + P1.H = (IMEM_CONTROL >> 16); + P1.L = (IMEM_CONTROL & 0xFFFF); + R1 = 0xF; + R0 = [P1]; + R0 = R0 >> 3; + R0 = R0 & R1; + + RTS; diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c new file mode 100644 index 000000000000..deb27272c658 --- /dev/null +++ b/arch/blackfin/mach-common/pm.c @@ -0,0 +1,181 @@ +/* + * File: arch/blackfin/mach-common/pm.c + * Based on: arm/mach-omap/pm.c + * Author: Cliff Brake Copyright (c) 2001 + * + * Created: 2001 + * Description: Power management for the bfin + * + * Modified: Nicolas Pitre - PXA250 support + * Copyright (c) 2002 Monta Vista Software, Inc. + * David Singleton - OMAP1510 + * Copyright (c) 2002 Monta Vista Software, Inc. + * Dirk Behme - OMAP1510/1610 + * Copyright 2004 + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include +#include +#include + + +#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_H +#define WAKEUP_TYPE PM_WAKE_HIGH +#endif + +#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_L +#define WAKEUP_TYPE PM_WAKE_LOW +#endif + +#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_F +#define WAKEUP_TYPE PM_WAKE_FALLING +#endif + +#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_R +#define WAKEUP_TYPE PM_WAKE_RISING +#endif + +#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_B +#define WAKEUP_TYPE PM_WAKE_BOTH_EDGES +#endif + +void bfin_pm_suspend_standby_enter(void) +{ +#ifdef CONFIG_PM_WAKEUP_BY_GPIO + gpio_pm_wakeup_request(CONFIG_PM_WAKEUP_GPIO_NUMBER, WAKEUP_TYPE); +#endif + +#if defined(CONFIG_PM_WAKEUP_BY_GPIO) || defined(CONFIG_PM_WAKEUP_GPIO_API) + { + u32 flags; + + local_irq_save(flags); + + sleep_deeper(gpio_pm_setup()); /*Goto Sleep*/ + + gpio_pm_restore(); + + bfin_write_SIC_IWR(IWR_ENABLE_ALL); + + local_irq_restore(flags); + } +#endif + +#if defined(CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR) + sleep_deeper(CONFIG_PM_WAKEUP_SIC_IWR); + bfin_write_SIC_IWR(IWR_ENABLE_ALL); +#endif /* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */ +} + + +/* + * bfin_pm_prepare - Do preliminary suspend work. + * @state: suspend state we're entering. + * + */ +static int bfin_pm_prepare(suspend_state_t state) +{ + int error = 0; + + switch (state) { + case PM_SUSPEND_STANDBY: + break; + case PM_SUSPEND_MEM: + return -ENOTSUPP; + + case PM_SUSPEND_DISK: + return -ENOTSUPP; + + default: + return -EINVAL; + } + + return error; +} + +/* + * bfin_pm_enter - Actually enter a sleep state. + * @state: State we're entering. + * + */ +static int bfin_pm_enter(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_STANDBY: + bfin_pm_suspend_standby_enter(); + break; + case PM_SUSPEND_MEM: + return -ENOTSUPP; + + case PM_SUSPEND_DISK: + return -ENOTSUPP; + + default: + return -EINVAL; + } + + return 0; +} + +/* + * bfin_pm_finish - Finish up suspend sequence. + * @state: State we're coming out of. + * + * This is called after we wake back up (or if entering the sleep state + * failed). + */ +static int bfin_pm_finish(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_STANDBY: + break; + + case PM_SUSPEND_MEM: + return -ENOTSUPP; + + case PM_SUSPEND_DISK: + return -ENOTSUPP; + + default: + return -EINVAL; + } + + return 0; +} + +struct pm_ops bfin_pm_ops = { + .pm_disk_mode = PM_DISK_PLATFORM, + .prepare = bfin_pm_prepare, + .enter = bfin_pm_enter, + .finish = bfin_pm_finish, +}; + +static int __init bfin_pm_init(void) +{ + pm_set_ops(&bfin_pm_ops); + return 0; +} + +__initcall(bfin_pm_init); diff --git a/arch/blackfin/mm/Makefile b/arch/blackfin/mm/Makefile new file mode 100644 index 000000000000..2a7202ce01fd --- /dev/null +++ b/arch/blackfin/mm/Makefile @@ -0,0 +1,5 @@ +# +# arch/blackfin/mm/Makefile +# + +obj-y := blackfin_sram.o init.o diff --git a/arch/blackfin/mm/blackfin_sram.c b/arch/blackfin/mm/blackfin_sram.c new file mode 100644 index 000000000000..dd0c6501c424 --- /dev/null +++ b/arch/blackfin/mm/blackfin_sram.c @@ -0,0 +1,540 @@ +/* + * File: arch/blackfin/mm/blackfin_sram.c + * Based on: + * Author: + * + * Created: + * Description: SRAM driver for Blackfin ADSP-BF5xx + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "blackfin_sram.h" + +spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock; + +#if CONFIG_L1_MAX_PIECE < 16 +#undef CONFIG_L1_MAX_PIECE +#define CONFIG_L1_MAX_PIECE 16 +#endif + +#if CONFIG_L1_MAX_PIECE > 1024 +#undef CONFIG_L1_MAX_PIECE +#define CONFIG_L1_MAX_PIECE 1024 +#endif + +#define SRAM_SLT_NULL 0 +#define SRAM_SLT_FREE 1 +#define SRAM_SLT_ALLOCATED 2 + +/* the data structure for L1 scratchpad and DATA SRAM */ +struct l1_sram_piece { + void *paddr; + int size; + int flag; +}; + +static struct l1_sram_piece l1_ssram[CONFIG_L1_MAX_PIECE]; + +#if L1_DATA_A_LENGTH != 0 +static struct l1_sram_piece l1_data_A_sram[CONFIG_L1_MAX_PIECE]; +#endif + +#if L1_DATA_B_LENGTH != 0 +static struct l1_sram_piece l1_data_B_sram[CONFIG_L1_MAX_PIECE]; +#endif + +#if L1_CODE_LENGTH != 0 +static struct l1_sram_piece l1_inst_sram[CONFIG_L1_MAX_PIECE]; +#endif + +/* L1 Scratchpad SRAM initialization function */ +void l1sram_init(void) +{ + printk(KERN_INFO "Blackfin Scratchpad data SRAM: %d KB\n", + L1_SCRATCH_LENGTH >> 10); + + memset(&l1_ssram, 0x00, sizeof(l1_ssram)); + l1_ssram[0].paddr = (void*)L1_SCRATCH_START; + l1_ssram[0].size = L1_SCRATCH_LENGTH; + l1_ssram[0].flag = SRAM_SLT_FREE; + + /* mutex initialize */ + spin_lock_init(&l1sram_lock); +} + +void l1_data_sram_init(void) +{ +#if L1_DATA_A_LENGTH != 0 + printk(KERN_INFO "Blackfin DATA_A SRAM: %d KB\n", + L1_DATA_A_LENGTH >> 10); + + memset(&l1_data_A_sram, 0x00, sizeof(l1_data_A_sram)); + l1_data_A_sram[0].paddr = (void*)L1_DATA_A_START + + (_ebss_l1 - _sdata_l1); + l1_data_A_sram[0].size = L1_DATA_A_LENGTH - (_ebss_l1 - _sdata_l1); + l1_data_A_sram[0].flag = SRAM_SLT_FREE; +#endif +#if L1_DATA_B_LENGTH != 0 + printk(KERN_INFO "Blackfin DATA_B SRAM: %d KB\n", + L1_DATA_B_LENGTH >> 10); + + memset(&l1_data_B_sram, 0x00, sizeof(l1_data_B_sram)); + l1_data_B_sram[0].paddr = (void*)L1_DATA_B_START; + l1_data_B_sram[0].size = L1_DATA_B_LENGTH; + l1_data_B_sram[0].flag = SRAM_SLT_FREE; +#endif + + /* mutex initialize */ + spin_lock_init(&l1_data_sram_lock); +} + +void l1_inst_sram_init(void) +{ +#if L1_CODE_LENGTH != 0 + printk(KERN_INFO "Blackfin Instruction SRAM: %d KB\n", + L1_CODE_LENGTH >> 10); + + memset(&l1_inst_sram, 0x00, sizeof(l1_inst_sram)); + l1_inst_sram[0].paddr = (void*)L1_CODE_START + (_etext_l1 - _stext_l1); + l1_inst_sram[0].size = L1_CODE_LENGTH - (_etext_l1 - _stext_l1); + l1_inst_sram[0].flag = SRAM_SLT_FREE; +#endif + + /* mutex initialize */ + spin_lock_init(&l1_inst_sram_lock); +} + +/* L1 memory allocate function */ +static void *_l1_sram_alloc(size_t size, struct l1_sram_piece *pfree, int count) +{ + int i, index = 0; + void *addr = NULL; + + if (size <= 0) + return NULL; + + /* Align the size */ + size = (size + 3) & ~3; + + /* not use the good method to match the best slot !!! */ + /* search an available memeory slot */ + for (i = 0; i < count; i++) { + if ((pfree[i].flag == SRAM_SLT_FREE) + && (pfree[i].size >= size)) { + addr = pfree[i].paddr; + pfree[i].flag = SRAM_SLT_ALLOCATED; + index = i; + break; + } + } + if (i >= count) + return NULL; + + /* updated the NULL memeory slot !!! */ + if (pfree[i].size > size) { + for (i = 0; i < count; i++) { + if (pfree[i].flag == SRAM_SLT_NULL) { + pfree[i].flag = SRAM_SLT_FREE; + pfree[i].paddr = addr + size; + pfree[i].size = pfree[index].size - size; + pfree[index].size = size; + break; + } + } + } + + return addr; +} + +/* Allocate the largest available block. */ +static void *_l1_sram_alloc_max(struct l1_sram_piece *pfree, int count, + unsigned long *psize) +{ + unsigned long best = 0; + int i, index = -1; + void *addr = NULL; + + /* search an available memeory slot */ + for (i = 0; i < count; i++) { + if (pfree[i].flag == SRAM_SLT_FREE && pfree[i].size > best) { + addr = pfree[i].paddr; + index = i; + best = pfree[i].size; + } + } + if (index < 0) + return NULL; + *psize = best; + + pfree[index].flag = SRAM_SLT_ALLOCATED; + return addr; +} + +/* L1 memory free function */ +static int _l1_sram_free(const void *addr, + struct l1_sram_piece *pfree, int count) +{ + int i, index = 0; + + /* search the relevant memory slot */ + for (i = 0; i < count; i++) { + if (pfree[i].paddr == addr) { + if (pfree[i].flag != SRAM_SLT_ALLOCATED) { + /* error log */ + return -1; + } + index = i; + break; + } + } + if (i >= count) + return -1; + + pfree[index].flag = SRAM_SLT_FREE; + + /* link the next address slot */ + for (i = 0; i < count; i++) { + if (((pfree[index].paddr + pfree[index].size) == pfree[i].paddr) + && (pfree[i].flag == SRAM_SLT_FREE)) { + pfree[i].flag = SRAM_SLT_NULL; + pfree[index].size += pfree[i].size; + pfree[index].flag = SRAM_SLT_FREE; + break; + } + } + + /* link the last address slot */ + for (i = 0; i < count; i++) { + if (((pfree[i].paddr + pfree[i].size) == pfree[index].paddr) && + (pfree[i].flag == SRAM_SLT_FREE)) { + pfree[index].flag = SRAM_SLT_NULL; + pfree[i].size += pfree[index].size; + break; + } + } + + return 0; +} + +int sram_free(const void *addr) +{ + if (0) {} +#if L1_CODE_LENGTH != 0 + else if (addr >= (void *)L1_CODE_START + && addr < (void *)(L1_CODE_START + L1_CODE_LENGTH)) + return l1_inst_sram_free(addr); +#endif +#if L1_DATA_A_LENGTH != 0 + else if (addr >= (void *)L1_DATA_A_START + && addr < (void *)(L1_DATA_A_START + L1_DATA_A_LENGTH)) + return l1_data_A_sram_free(addr); +#endif +#if L1_DATA_B_LENGTH != 0 + else if (addr >= (void *)L1_DATA_B_START + && addr < (void *)(L1_DATA_B_START + L1_DATA_B_LENGTH)) + return l1_data_B_sram_free(addr); +#endif + else + return -1; +} +EXPORT_SYMBOL(sram_free); + +void *l1_data_A_sram_alloc(size_t size) +{ + unsigned flags; + void *addr = NULL; + + /* add mutex operation */ + spin_lock_irqsave(&l1_data_sram_lock, flags); + +#if L1_DATA_A_LENGTH != 0 + addr = _l1_sram_alloc(size, l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram)); +#endif + + /* add mutex operation */ + spin_unlock_irqrestore(&l1_data_sram_lock, flags); + + pr_debug("Allocated address in l1_data_A_sram_alloc is 0x%lx+0x%lx\n", + (long unsigned int)addr, size); + + return addr; +} +EXPORT_SYMBOL(l1_data_A_sram_alloc); + +int l1_data_A_sram_free(const void *addr) +{ + unsigned flags; + int ret; + + /* add mutex operation */ + spin_lock_irqsave(&l1_data_sram_lock, flags); + +#if L1_DATA_A_LENGTH != 0 + ret = _l1_sram_free(addr, + l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram)); +#else + ret = -1; +#endif + + /* add mutex operation */ + spin_unlock_irqrestore(&l1_data_sram_lock, flags); + + return ret; +} +EXPORT_SYMBOL(l1_data_A_sram_free); + +void *l1_data_B_sram_alloc(size_t size) +{ +#if L1_DATA_B_LENGTH != 0 + unsigned flags; + void *addr; + + /* add mutex operation */ + spin_lock_irqsave(&l1_data_sram_lock, flags); + + addr = _l1_sram_alloc(size, l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram)); + + /* add mutex operation */ + spin_unlock_irqrestore(&l1_data_sram_lock, flags); + + pr_debug("Allocated address in l1_data_B_sram_alloc is 0x%lx+0x%lx\n", + (long unsigned int)addr, size); + + return addr; +#else + return NULL; +#endif +} +EXPORT_SYMBOL(l1_data_B_sram_alloc); + +int l1_data_B_sram_free(const void *addr) +{ +#if L1_DATA_B_LENGTH != 0 + unsigned flags; + int ret; + + /* add mutex operation */ + spin_lock_irqsave(&l1_data_sram_lock, flags); + + ret = _l1_sram_free(addr, l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram)); + + /* add mutex operation */ + spin_unlock_irqrestore(&l1_data_sram_lock, flags); + + return ret; +#else + return -1; +#endif +} +EXPORT_SYMBOL(l1_data_B_sram_free); + +void *l1_data_sram_alloc(size_t size) +{ + void *addr = l1_data_A_sram_alloc(size); + + if (!addr) + addr = l1_data_B_sram_alloc(size); + + return addr; +} +EXPORT_SYMBOL(l1_data_sram_alloc); + +void *l1_data_sram_zalloc(size_t size) +{ + void *addr = l1_data_sram_alloc(size); + + if (addr) + memset(addr, 0x00, size); + + return addr; +} +EXPORT_SYMBOL(l1_data_sram_zalloc); + +int l1_data_sram_free(const void *addr) +{ + int ret; + ret = l1_data_A_sram_free(addr); + if (ret == -1) + ret = l1_data_B_sram_free(addr); + return ret; +} +EXPORT_SYMBOL(l1_data_sram_free); + +void *l1_inst_sram_alloc(size_t size) +{ +#if L1_DATA_A_LENGTH != 0 + unsigned flags; + void *addr; + + /* add mutex operation */ + spin_lock_irqsave(&l1_inst_sram_lock, flags); + + addr = _l1_sram_alloc(size, l1_inst_sram, ARRAY_SIZE(l1_inst_sram)); + + /* add mutex operation */ + spin_unlock_irqrestore(&l1_inst_sram_lock, flags); + + pr_debug("Allocated address in l1_inst_sram_alloc is 0x%lx+0x%lx\n", + (long unsigned int)addr, size); + + return addr; +#else + return NULL; +#endif +} +EXPORT_SYMBOL(l1_inst_sram_alloc); + +int l1_inst_sram_free(const void *addr) +{ +#if L1_CODE_LENGTH != 0 + unsigned flags; + int ret; + + /* add mutex operation */ + spin_lock_irqsave(&l1_inst_sram_lock, flags); + + ret = _l1_sram_free(addr, l1_inst_sram, ARRAY_SIZE(l1_inst_sram)); + + /* add mutex operation */ + spin_unlock_irqrestore(&l1_inst_sram_lock, flags); + + return ret; +#else + return -1; +#endif +} +EXPORT_SYMBOL(l1_inst_sram_free); + +/* L1 Scratchpad memory allocate function */ +void *l1sram_alloc(size_t size) +{ + unsigned flags; + void *addr; + + /* add mutex operation */ + spin_lock_irqsave(&l1sram_lock, flags); + + addr = _l1_sram_alloc(size, l1_ssram, ARRAY_SIZE(l1_ssram)); + + /* add mutex operation */ + spin_unlock_irqrestore(&l1sram_lock, flags); + + return addr; +} + +/* L1 Scratchpad memory allocate function */ +void *l1sram_alloc_max(size_t *psize) +{ + unsigned flags; + void *addr; + + /* add mutex operation */ + spin_lock_irqsave(&l1sram_lock, flags); + + addr = _l1_sram_alloc_max(l1_ssram, ARRAY_SIZE(l1_ssram), psize); + + /* add mutex operation */ + spin_unlock_irqrestore(&l1sram_lock, flags); + + return addr; +} + +/* L1 Scratchpad memory free function */ +int l1sram_free(const void *addr) +{ + unsigned flags; + int ret; + + /* add mutex operation */ + spin_lock_irqsave(&l1sram_lock, flags); + + ret = _l1_sram_free(addr, l1_ssram, ARRAY_SIZE(l1_ssram)); + + /* add mutex operation */ + spin_unlock_irqrestore(&l1sram_lock, flags); + + return ret; +} + +int sram_free_with_lsl(const void *addr) +{ + struct sram_list_struct *lsl, **tmp; + struct mm_struct *mm = current->mm; + + for (tmp = &mm->context.sram_list; *tmp; tmp = &(*tmp)->next) + if ((*tmp)->addr == addr) + goto found; + return -1; +found: + lsl = *tmp; + sram_free(addr); + *tmp = lsl->next; + kfree(lsl); + + return 0; +} +EXPORT_SYMBOL(sram_free_with_lsl); + +void *sram_alloc_with_lsl(size_t size, unsigned long flags) +{ + void *addr = NULL; + struct sram_list_struct *lsl = NULL; + struct mm_struct *mm = current->mm; + + lsl = kmalloc(sizeof(struct sram_list_struct), GFP_KERNEL); + if (!lsl) + return NULL; + memset(lsl, 0, sizeof(*lsl)); + + if (flags & L1_INST_SRAM) + addr = l1_inst_sram_alloc(size); + + if (addr == NULL && (flags & L1_DATA_A_SRAM)) + addr = l1_data_A_sram_alloc(size); + + if (addr == NULL && (flags & L1_DATA_B_SRAM)) + addr = l1_data_B_sram_alloc(size); + + if (addr == NULL) { + kfree(lsl); + return NULL; + } + lsl->addr = addr; + lsl->length = size; + lsl->next = mm->context.sram_list; + mm->context.sram_list = lsl; + return addr; +} +EXPORT_SYMBOL(sram_alloc_with_lsl); diff --git a/arch/blackfin/mm/blackfin_sram.h b/arch/blackfin/mm/blackfin_sram.h new file mode 100644 index 000000000000..0fb73b78dd60 --- /dev/null +++ b/arch/blackfin/mm/blackfin_sram.h @@ -0,0 +1,38 @@ +/* + * File: arch/blackfin/mm/blackfin_sram.h + * Based on: arch/blackfin/mm/blackfin_sram.c + * Author: Mike Frysinger + * + * Created: Aug 2006 + * Description: Local prototypes meant for internal use only + * + * Modified: + * Copyright 2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __BLACKFIN_SRAM_H__ +#define __BLACKFIN_SRAM_H__ + +extern void l1sram_init(void); +extern void l1_inst_sram_init(void); +extern void l1_data_sram_init(void); +extern void *l1sram_alloc(size_t); + +#endif diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c new file mode 100644 index 000000000000..73f72abed432 --- /dev/null +++ b/arch/blackfin/mm/init.c @@ -0,0 +1,208 @@ +/* + * File: arch/blackfin/mm/init.c + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include "blackfin_sram.h" + +/* + * BAD_PAGE is the page that is used for page faults when linux + * is out-of-memory. Older versions of linux just did a + * do_exit(), but using this instead means there is less risk + * for a process dying in kernel mode, possibly leaving a inode + * unused etc.. + * + * BAD_PAGETABLE is the accompanying page-table: it is initialized + * to point to BAD_PAGE entries. + * + * ZERO_PAGE is a special page that is used for zero-initialized + * data and COW. + */ +static unsigned long empty_bad_page_table; + +static unsigned long empty_bad_page; + +unsigned long empty_zero_page; + +void show_mem(void) +{ + unsigned long i; + int free = 0, total = 0, reserved = 0, shared = 0; + + int cached = 0; + printk(KERN_INFO "Mem-info:\n"); + show_free_areas(); + i = max_mapnr; + while (i-- > 0) { + total++; + if (PageReserved(mem_map + i)) + reserved++; + else if (PageSwapCache(mem_map + i)) + cached++; + else if (!page_count(mem_map + i)) + free++; + else + shared += page_count(mem_map + i) - 1; + } + printk(KERN_INFO "%d pages of RAM\n", total); + printk(KERN_INFO "%d free pages\n", free); + printk(KERN_INFO "%d reserved pages\n", reserved); + printk(KERN_INFO "%d pages shared\n", shared); + printk(KERN_INFO "%d pages swap cached\n", cached); +} + +/* + * paging_init() continues the virtual memory environment setup which + * was begun by the code in arch/head.S. + * The parameters are pointers to where to stick the starting and ending + * addresses of available kernel virtual memory. + */ +void paging_init(void) +{ + /* + * make sure start_mem is page aligned, otherwise bootmem and + * page_alloc get different views og the world + */ + unsigned long end_mem = memory_end & PAGE_MASK; + + pr_debug("start_mem is %#lx virtual_end is %#lx\n", PAGE_ALIGN(memory_start), end_mem); + + /* + * initialize the bad page table and bad page to point + * to a couple of allocated pages + */ + empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); + empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); + empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); + memset((void *)empty_zero_page, 0, PAGE_SIZE); + + /* + * Set up SFC/DFC registers (user data space) + */ + set_fs(KERNEL_DS); + + pr_debug("free_area_init -> start_mem is %#lx virtual_end is %#lx\n", + PAGE_ALIGN(memory_start), end_mem); + + { + unsigned long zones_size[MAX_NR_ZONES] = { 0, }; + + zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT; +#ifdef CONFIG_HIGHMEM + zones_size[ZONE_HIGHMEM] = 0; +#endif + free_area_init(zones_size); + } +} + +void mem_init(void) +{ + unsigned int codek = 0, datak = 0, initk = 0; + unsigned long tmp; + unsigned int len = _ramend - _rambase; + unsigned long start_mem = memory_start; + unsigned long end_mem = memory_end; + + end_mem &= PAGE_MASK; + high_memory = (void *)end_mem; + + start_mem = PAGE_ALIGN(start_mem); + max_mapnr = num_physpages = MAP_NR(high_memory); + printk(KERN_INFO "Physical pages: %lx\n", num_physpages); + + /* This will put all memory onto the freelists. */ + totalram_pages = free_all_bootmem(); + + codek = (_etext - _stext) >> 10; + datak = (__bss_stop - __bss_start) >> 10; + initk = (__init_end - __init_begin) >> 10; + + tmp = nr_free_pages() << PAGE_SHIFT; + printk(KERN_INFO + "Memory available: %luk/%uk RAM, (%uk init code, %uk kernel code, %uk data, %uk dma)\n", + tmp >> 10, len >> 10, initk, codek, datak, DMA_UNCACHED_REGION >> 10); + + /* Initialize the blackfin L1 Memory. */ + l1sram_init(); + l1_data_sram_init(); + l1_inst_sram_init(); + + /* Allocate this once; never free it. We assume this gives us a + pointer to the start of L1 scratchpad memory; panic if it + doesn't. */ + tmp = (unsigned long)l1sram_alloc(sizeof(struct l1_scratch_task_info)); + if (tmp != (unsigned long)L1_SCRATCH_TASK_INFO) { + printk(KERN_EMERG "mem_init(): Did not get the right address from l1sram_alloc: %08lx != %08lx\n", + tmp, (unsigned long)L1_SCRATCH_TASK_INFO); + panic("No L1, time to give up\n"); + } +} + +#ifdef CONFIG_BLK_DEV_INITRD +void free_initrd_mem(unsigned long start, unsigned long end) +{ + int pages = 0; + for (; start < end; start += PAGE_SIZE) { + ClearPageReserved(virt_to_page(start)); + init_page_count(virt_to_page(start)); + free_page(start); + totalram_pages++; + pages++; + } + printk(KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages); +} +#endif + +void free_initmem(void) +{ +#ifdef CONFIG_RAMKERNEL + unsigned long addr; +/* + * the following code should be cool even if these sections + * are not page aligned. + */ + addr = PAGE_ALIGN((unsigned long)(__init_begin)); + /* next to check that the page we free is not a partial page */ + for (; addr + PAGE_SIZE < (unsigned long)(__init_end); + addr += PAGE_SIZE) { + ClearPageReserved(virt_to_page(addr)); + init_page_count(virt_to_page(addr)); + free_page(addr); + totalram_pages++; + } + printk(KERN_NOTICE + "Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n", + (addr - PAGE_ALIGN((long)__init_begin)) >> 10, + (int)(PAGE_ALIGN((unsigned long)(__init_begin))), + (int)(addr - PAGE_SIZE)); +#endif +} diff --git a/arch/blackfin/oprofile/Kconfig b/arch/blackfin/oprofile/Kconfig new file mode 100644 index 000000000000..0a2fd999c941 --- /dev/null +++ b/arch/blackfin/oprofile/Kconfig @@ -0,0 +1,29 @@ +menu "Profiling support" +depends on EXPERIMENTAL + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +config HARDWARE_PM + tristate "Hardware Performance Monitor Profiling" + depends on PROFILING + help + take use of hardware performance monitor to profiling the kernel + and application. + + If unsure, say N. + +endmenu diff --git a/arch/blackfin/oprofile/Makefile b/arch/blackfin/oprofile/Makefile new file mode 100644 index 000000000000..634e300d67e2 --- /dev/null +++ b/arch/blackfin/oprofile/Makefile @@ -0,0 +1,14 @@ +# +# arch/blackfin/oprofile/Makefile +# + +obj-$(CONFIG_OPROFILE) += oprofile.o + +DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ + oprof.o cpu_buffer.o buffer_sync.o \ + event_buffer.o oprofile_files.o \ + oprofilefs.o oprofile_stats.o \ + timer_int.o ) + +oprofile-y := $(DRIVER_OBJS) common.o +oprofile-$(CONFIG_HARDWARE_PM) += op_model_bf533.o diff --git a/arch/blackfin/oprofile/common.c b/arch/blackfin/oprofile/common.c new file mode 100644 index 000000000000..009a1700c854 --- /dev/null +++ b/arch/blackfin/oprofile/common.c @@ -0,0 +1,168 @@ +/* + * File: arch/blackfin/oprofile/common.c + * Based on: arch/alpha/oprofile/common.c + * Author: Anton Blanchard + * + * Created: + * Description: + * + * Modified: + * Copyright (C) 2004 Anton Blanchard , IBM + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "op_blackfin.h" + +#define BFIN_533_ID 0xE5040003 +#define BFIN_537_ID 0xE5040002 + +static int pfmon_enabled; +static struct mutex pfmon_lock; + +struct op_bfin533_model *model; + +struct op_counter_config ctr[OP_MAX_COUNTER]; + +static int op_bfin_setup(void) +{ + int ret; + + /* Pre-compute the values to stuff in the hardware registers. */ + spin_lock(&oprofilefs_lock); + ret = model->reg_setup(ctr); + spin_unlock(&oprofilefs_lock); + + return ret; +} + +static void op_bfin_shutdown(void) +{ +#if 0 + /* what is the difference between shutdown and stop? */ +#endif +} + +static int op_bfin_start(void) +{ + int ret = -EBUSY; + + printk(KERN_INFO "KSDBG:in %s\n", __FUNCTION__); + mutex_lock(&pfmon_lock); + if (!pfmon_enabled) { + ret = model->start(ctr); + pfmon_enabled = !ret; + } + mutex_unlock(&pfmon_lock); + + return ret; +} + +static void op_bfin_stop(void) +{ + mutex_lock(&pfmon_lock); + if (pfmon_enabled) { + model->stop(); + pfmon_enabled = 0; + } + mutex_unlock(&pfmon_lock); +} + +static int op_bfin_create_files(struct super_block *sb, struct dentry *root) +{ + int i; + + for (i = 0; i < model->num_counters; ++i) { + struct dentry *dir; + char buf[3]; + printk(KERN_INFO "Oprofile: creating files... \n"); + + snprintf(buf, sizeof buf, "%d", i); + dir = oprofilefs_mkdir(sb, root, buf); + + oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); + oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); + oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count); + /* + * We dont support per counter user/kernel selection, but + * we leave the entries because userspace expects them + */ + oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); + oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); + oprofilefs_create_ulong(sb, dir, "unit_mask", + &ctr[i].unit_mask); + } + + return 0; +} +int __init oprofile_arch_init(struct oprofile_operations *ops) +{ +#ifdef CONFIG_HARDWARE_PM + unsigned int dspid; + + mutex_init(&pfmon_lock); + + dspid = bfin_read_DSPID(); + + printk(KERN_INFO "Oprofile got the cpu id is 0x%x. \n", dspid); + + switch (dspid) { + case BFIN_533_ID: + model = &op_model_bfin533; + model->num_counters = 2; + break; + case BFIN_537_ID: + model = &op_model_bfin533; + model->num_counters = 2; + break; + default: + return -ENODEV; + } + + ops->cpu_type = model->name; + ops->create_files = op_bfin_create_files; + ops->setup = op_bfin_setup; + ops->shutdown = op_bfin_shutdown; + ops->start = op_bfin_start; + ops->stop = op_bfin_stop; + + printk(KERN_INFO "oprofile: using %s performance monitoring.\n", + ops->cpu_type); + + return 0; +#else + return -1; +#endif +} + +void oprofile_arch_exit(void) +{ +} diff --git a/arch/blackfin/oprofile/op_blackfin.h b/arch/blackfin/oprofile/op_blackfin.h new file mode 100644 index 000000000000..f88f446c814f --- /dev/null +++ b/arch/blackfin/oprofile/op_blackfin.h @@ -0,0 +1,98 @@ +/* + * File: arch/blackfin/oprofile/op_blackfin.h + * Based on: + * Author: Anton Blanchard + * + * Created: + * Description: + * + * Modified: + * Copyright (C) 2004 Anton Blanchard , IBM + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef OP_BLACKFIN_H +#define OP_BLACKFIN_H 1 + +#define OP_MAX_COUNTER 2 + +#include + +/* Per-counter configuration as set via oprofilefs. */ +struct op_counter_config { + unsigned long valid; + unsigned long enabled; + unsigned long event; + unsigned long count; + unsigned long kernel; + unsigned long user; + unsigned long unit_mask; +}; + +/* System-wide configuration as set via oprofilefs. */ +struct op_system_config { + unsigned long enable_kernel; + unsigned long enable_user; +}; + +/* Per-arch configuration */ +struct op_bfin533_model { + int (*reg_setup) (struct op_counter_config *); + int (*start) (struct op_counter_config *); + void (*stop) (void); + int num_counters; + char *name; +}; + +extern struct op_bfin533_model op_model_bfin533; + +static inline unsigned int ctr_read(void) +{ + unsigned int tmp; + + tmp = bfin_read_PFCTL(); + __builtin_bfin_csync(); + + return tmp; +} + +static inline void ctr_write(unsigned int val) +{ + bfin_write_PFCTL(val); + __builtin_bfin_csync(); +} + +static inline void count_read(unsigned int *count) +{ + count[0] = bfin_read_PFCNTR0(); + count[1] = bfin_read_PFCNTR1(); + __builtin_bfin_csync(); +} + +static inline void count_write(unsigned int *count) +{ + bfin_write_PFCNTR0(count[0]); + bfin_write_PFCNTR1(count[1]); + __builtin_bfin_csync(); +} + +extern int pm_overflow_handler(int irq, struct pt_regs *regs); + +#endif diff --git a/arch/blackfin/oprofile/op_model_bf533.c b/arch/blackfin/oprofile/op_model_bf533.c new file mode 100644 index 000000000000..b7a20a006b49 --- /dev/null +++ b/arch/blackfin/oprofile/op_model_bf533.c @@ -0,0 +1,161 @@ +/* + * File: arch/blackfin/oprofile/op_model_bf533.c + * Based on: + * Author: Anton Blanchard + * + * Created: + * Description: + * + * Modified: + * Copyright (C) 2004 Anton Blanchard , IBM + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "op_blackfin.h" + +#define PM_ENABLE 0x01; +#define PM_CTL1_ENABLE 0x18 +#define PM_CTL0_ENABLE 0xC000 +#define COUNT_EDGE_ONLY 0x3000000 + +static int oprofile_running; + +static unsigned curr_pfctl, curr_count[2]; + +static int bfin533_reg_setup(struct op_counter_config *ctr) +{ + unsigned int pfctl = ctr_read(); + unsigned int count[2]; + + /* set Blackfin perf monitor regs with ctr */ + if (ctr[0].enabled) { + pfctl |= (PM_CTL0_ENABLE | ((char)ctr[0].event << 5)); + count[0] = 0xFFFFFFFF - ctr[0].count; + curr_count[0] = count[0]; + } + if (ctr[1].enabled) { + pfctl |= (PM_CTL1_ENABLE | ((char)ctr[1].event << 16)); + count[1] = 0xFFFFFFFF - ctr[1].count; + curr_count[1] = count[1]; + } + + pr_debug("ctr[0].enabled=%d,ctr[1].enabled=%d,ctr[0].event<<5=0x%x,ctr[1].event<<16=0x%x\n", ctr[0].enabled, ctr[1].enabled, ctr[0].event << 5, ctr[1].event << 16); + pfctl |= COUNT_EDGE_ONLY; + curr_pfctl = pfctl; + + pr_debug("write 0x%x to pfctl\n", pfctl); + ctr_write(pfctl); + count_write(count); + + return 0; +} + +static int bfin533_start(struct op_counter_config *ctr) +{ + unsigned int pfctl = ctr_read(); + + pfctl |= PM_ENABLE; + curr_pfctl = pfctl; + + ctr_write(pfctl); + + oprofile_running = 1; + pr_debug("start oprofile counter \n"); + + return 0; +} + +static void bfin533_stop(void) +{ + int pfctl; + + pfctl = ctr_read(); + pfctl &= ~PM_ENABLE; + /* freeze counters */ + ctr_write(pfctl); + + oprofile_running = 0; + pr_debug("stop oprofile counter \n"); +} + +static int get_kernel(void) +{ + int ipend, is_kernel; + + ipend = bfin_read_IPEND(); + + /* test bit 15 */ + is_kernel = ((ipend & 0x8000) != 0); + + return is_kernel; +} + +int pm_overflow_handler(int irq, struct pt_regs *regs) +{ + int is_kernel; + int i, cpu; + unsigned int pc, pfctl; + unsigned int count[2]; + + pr_debug("get interrupt in %s\n", __FUNCTION__); + if (oprofile_running == 0) { + pr_debug("error: entering interrupt when oprofile is stopped.\n\r"); + return -1; + } + + is_kernel = get_kernel(); + cpu = smp_processor_id(); + pc = regs->pc; + pfctl = ctr_read(); + + /* read the two event counter regs */ + count_read(count); + + /* if the counter overflows, add sample to oprofile buffer */ + for (i = 0; i < 2; ++i) { + if (oprofile_running) { + oprofile_add_sample(regs, i); + } + } + + /* reset the perfmon counter */ + ctr_write(curr_pfctl); + count_write(curr_count); + return 0; +} + +struct op_bfin533_model op_model_bfin533 = { + .reg_setup = bfin533_reg_setup, + .start = bfin533_start, + .stop = bfin533_stop, + .num_counters = 2, + .name = "blackfin/bf533" +}; diff --git a/arch/blackfin/oprofile/timer_int.c b/arch/blackfin/oprofile/timer_int.c new file mode 100644 index 000000000000..8fba16c846c9 --- /dev/null +++ b/arch/blackfin/oprofile/timer_int.c @@ -0,0 +1,74 @@ +/* + * File: arch/blackfin/oprofile/timer_int.c + * Based on: + * Author: Michael Kang + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#include + +static void enable_sys_timer0() +{ +} +static void disable_sys_timer0() +{ +} + +static irqreturn_t sys_timer0_int_handler(int irq, void *dev_id, + struct pt_regs *regs) +{ + oprofile_add_sample(regs, 0); + return IRQ_HANDLED; +} + +static int sys_timer0_start(void) +{ + enable_sys_timer0(); + return request_irq(IVG11, sys_timer0_int_handler, 0, "sys_timer0", NULL); +} + +static void sys_timer0_stop(void) +{ + disable_sys_timer(); +} + +int __init sys_timer0_init(struct oprofile_operations *ops) +{ + extern int nmi_active; + + if (nmi_active <= 0) + return -ENODEV; + + ops->start = timer_start; + ops->stop = timer_stop; + ops->cpu_type = "timer"; + printk(KERN_INFO "oprofile: using NMI timer interrupt.\n"); + return 0; +} diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index f3d3d81eb7e9..74c64409ddbc 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt @@ -26,7 +26,7 @@ config BINFMT_ELF config BINFMT_ELF_FDPIC bool "Kernel support for FDPIC ELF binaries" default y - depends on FRV + depends on (FRV || BLACKFIN) help ELF FDPIC binaries are based on ELF, but allow the individual load segments of a binary to be located in memory independently of each diff --git a/include/asm-blackfin/Kbuild b/include/asm-blackfin/Kbuild new file mode 100644 index 000000000000..c68e1680da01 --- /dev/null +++ b/include/asm-blackfin/Kbuild @@ -0,0 +1 @@ +include include/asm-generic/Kbuild.asm diff --git a/include/asm-blackfin/a.out.h b/include/asm-blackfin/a.out.h new file mode 100644 index 000000000000..d37a6849bf74 --- /dev/null +++ b/include/asm-blackfin/a.out.h @@ -0,0 +1,25 @@ +#ifndef __BFIN_A_OUT_H__ +#define __BFIN_A_OUT_H__ + +struct exec { + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +#ifdef __KERNEL__ + +#define STACK_TOP TASK_SIZE + +#endif + +#endif /* __BFIN_A_OUT_H__ */ diff --git a/include/asm-blackfin/atomic.h b/include/asm-blackfin/atomic.h new file mode 100644 index 000000000000..7cf508718605 --- /dev/null +++ b/include/asm-blackfin/atomic.h @@ -0,0 +1,144 @@ +#ifndef __ARCH_BLACKFIN_ATOMIC__ +#define __ARCH_BLACKFIN_ATOMIC__ + +#include /* local_irq_XXX() */ + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + * + * Generally we do not concern about SMP BFIN systems, so we don't have + * to deal with that. + * + * Tony Kou (tonyko@lineo.ca) Lineo Inc. 2001 + */ + +typedef struct { + int counter; +} atomic_t; +#define ATOMIC_INIT(i) { (i) } + +#define atomic_read(v) ((v)->counter) +#define atomic_set(v, i) (((v)->counter) = i) + +static __inline__ void atomic_add(int i, atomic_t * v) +{ + long flags; + + local_irq_save(flags); + v->counter += i; + local_irq_restore(flags); +} + +static __inline__ void atomic_sub(int i, atomic_t * v) +{ + long flags; + + local_irq_save(flags); + v->counter -= i; + local_irq_restore(flags); + +} + +static inline int atomic_add_return(int i, atomic_t * v) +{ + int __temp = 0; + long flags; + + local_irq_save(flags); + v->counter += i; + __temp = v->counter; + local_irq_restore(flags); + + + return __temp; +} + +#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) +static inline int atomic_sub_return(int i, atomic_t * v) +{ + int __temp = 0; + long flags; + + local_irq_save(flags); + v->counter -= i; + __temp = v->counter; + local_irq_restore(flags); + + return __temp; +} + +static __inline__ void atomic_inc(volatile atomic_t * v) +{ + long flags; + + local_irq_save(flags); + v->counter++; + local_irq_restore(flags); +} + +#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) +#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) + +#define atomic_add_unless(v, a, u) \ +({ \ + int c, old; \ + c = atomic_read(v); \ + while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \ + c = old; \ + c != (u); \ +}) +#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) + +static __inline__ void atomic_dec(volatile atomic_t * v) +{ + long flags; + + local_irq_save(flags); + v->counter--; + local_irq_restore(flags); +} + +static __inline__ void atomic_clear_mask(unsigned int mask, atomic_t * v) +{ + long flags; + + local_irq_save(flags); + v->counter &= ~mask; + local_irq_restore(flags); +} + +static __inline__ void atomic_set_mask(unsigned int mask, atomic_t * v) +{ + long flags; + + local_irq_save(flags); + v->counter |= mask; + local_irq_restore(flags); +} + +/* Atomic operations are already serializing */ +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() + +#define atomic_dec_return(v) atomic_sub_return(1,(v)) +#define atomic_inc_return(v) atomic_add_return(1,(v)) + +/* + * atomic_inc_and_test - increment and test + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1 + * and returns true if the result is zero, or false for all + * other cases. + */ +#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) + +#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) +#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) + +#include + +#endif /* __ARCH_BLACKFIN_ATOMIC __ */ diff --git a/include/asm-blackfin/auxvec.h b/include/asm-blackfin/auxvec.h new file mode 100644 index 000000000000..215506cd87b7 --- /dev/null +++ b/include/asm-blackfin/auxvec.h @@ -0,0 +1,4 @@ +#ifndef __ASMBFIN_AUXVEC_H +#define __ASMBFIN_AUXVEC_H + +#endif diff --git a/include/asm-blackfin/bf5xx_timers.h b/include/asm-blackfin/bf5xx_timers.h new file mode 100644 index 000000000000..86c770321b61 --- /dev/null +++ b/include/asm-blackfin/bf5xx_timers.h @@ -0,0 +1,209 @@ +/* + * include/asm/bf5xx_timers.h + * + * This file contains the major Data structures and constants + * used for General Purpose Timer Implementation in BF5xx + * + * Copyright (C) 2005 John DeHority + * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de) + * + */ + +#ifndef _BLACKFIN_TIMERS_H_ +#define _BLACKFIN_TIMERS_H_ + +#undef MAX_BLACKFIN_GPTIMERS +/* + * BF537: 8 timers: + */ +#if defined(CONFIG_BF537) +# define MAX_BLACKFIN_GPTIMERS 8 +# define TIMER0_GROUP_REG TIMER_ENABLE +#endif +/* + * BF561: 12 timers: + */ +#if defined(CONFIG_BF561) +# define MAX_BLACKFIN_GPTIMERS 12 +# define TIMER0_GROUP_REG TMRS8_ENABLE +# define TIMER8_GROUP_REG TMRS4_ENABLE +#endif +/* + * All others: 3 timers: + */ +#if !defined(MAX_BLACKFIN_GPTIMERS) +# define MAX_BLACKFIN_GPTIMERS 3 +# define TIMER0_GROUP_REG TIMER_ENABLE +#endif + +#define BLACKFIN_GPTIMER_IDMASK ((1UL << MAX_BLACKFIN_GPTIMERS) - 1) +#define BFIN_TIMER_OCTET(x) ((x) >> 3) + +/* used in masks for timer_enable() and timer_disable() */ +#define TIMER0bit 0x0001 /* 0001b */ +#define TIMER1bit 0x0002 /* 0010b */ +#define TIMER2bit 0x0004 /* 0100b */ + +#if (MAX_BLACKFIN_GPTIMERS > 3) +# define TIMER3bit 0x0008 +# define TIMER4bit 0x0010 +# define TIMER5bit 0x0020 +# define TIMER6bit 0x0040 +# define TIMER7bit 0x0080 +#endif + +#if (MAX_BLACKFIN_GPTIMERS > 8) +# define TIMER8bit 0x0100 +# define TIMER9bit 0x0200 +# define TIMER10bit 0x0400 +# define TIMER11bit 0x0800 +#endif + +#define TIMER0_id 0 +#define TIMER1_id 1 +#define TIMER2_id 2 + +#if (MAX_BLACKFIN_GPTIMERS > 3) +# define TIMER3_id 3 +# define TIMER4_id 4 +# define TIMER5_id 5 +# define TIMER6_id 6 +# define TIMER7_id 7 +#endif + +#if (MAX_BLACKFIN_GPTIMERS > 8) +# define TIMER8_id 8 +# define TIMER9_id 9 +# define TIMER10_id 10 +# define TIMER11_id 11 +#endif + +/* associated timers for ppi framesync: */ + +#if defined(CONFIG_BF561) +# define FS0_1_TIMER_ID TIMER8_id +# define FS0_2_TIMER_ID TIMER9_id +# define FS1_1_TIMER_ID TIMER10_id +# define FS1_2_TIMER_ID TIMER11_id +# define FS0_1_TIMER_BIT TIMER8bit +# define FS0_2_TIMER_BIT TIMER9bit +# define FS1_1_TIMER_BIT TIMER10bit +# define FS1_2_TIMER_BIT TIMER11bit +# undef FS1_TIMER_ID +# undef FS2_TIMER_ID +# undef FS1_TIMER_BIT +# undef FS2_TIMER_BIT +#else +# define FS1_TIMER_ID TIMER0_id +# define FS2_TIMER_ID TIMER1_id +# define FS1_TIMER_BIT TIMER0bit +# define FS2_TIMER_BIT TIMER1bit +#endif + +/* +** Timer Configuration Register Bits +*/ +#define TIMER_ERR 0xC000 +#define TIMER_ERR_OVFL 0x4000 +#define TIMER_ERR_PROG_PER 0x8000 +#define TIMER_ERR_PROG_PW 0xC000 +#define TIMER_EMU_RUN 0x0200 +#define TIMER_TOGGLE_HI 0x0100 +#define TIMER_CLK_SEL 0x0080 +#define TIMER_OUT_DIS 0x0040 +#define TIMER_TIN_SEL 0x0020 +#define TIMER_IRQ_ENA 0x0010 +#define TIMER_PERIOD_CNT 0x0008 +#define TIMER_PULSE_HI 0x0004 +#define TIMER_MODE 0x0003 +#define TIMER_MODE_PWM 0x0001 +#define TIMER_MODE_WDTH 0x0002 +#define TIMER_MODE_EXT_CLK 0x0003 + +/* +** Timer Status Register Bits +*/ +#define TIMER_STATUS_TIMIL0 0x0001 +#define TIMER_STATUS_TIMIL1 0x0002 +#define TIMER_STATUS_TIMIL2 0x0004 +#if (MAX_BLACKFIN_GPTIMERS > 3) +# define TIMER_STATUS_TIMIL3 0x00000008 +# define TIMER_STATUS_TIMIL4 0x00010000 +# define TIMER_STATUS_TIMIL5 0x00020000 +# define TIMER_STATUS_TIMIL6 0x00040000 +# define TIMER_STATUS_TIMIL7 0x00080000 +# if (MAX_BLACKFIN_GPTIMERS > 8) +# define TIMER_STATUS_TIMIL8 0x0001 +# define TIMER_STATUS_TIMIL9 0x0002 +# define TIMER_STATUS_TIMIL10 0x0004 +# define TIMER_STATUS_TIMIL11 0x0008 +# endif +# define TIMER_STATUS_INTR 0x000F000F +#else +# define TIMER_STATUS_INTR 0x0007 /* any timer interrupt */ +#endif + +#define TIMER_STATUS_TOVF0 0x0010 /* timer 0 overflow error */ +#define TIMER_STATUS_TOVF1 0x0020 +#define TIMER_STATUS_TOVF2 0x0040 +#if (MAX_BLACKFIN_GPTIMERS > 3) +# define TIMER_STATUS_TOVF3 0x00000080 +# define TIMER_STATUS_TOVF4 0x00100000 +# define TIMER_STATUS_TOVF5 0x00200000 +# define TIMER_STATUS_TOVF6 0x00400000 +# define TIMER_STATUS_TOVF7 0x00800000 +# if (MAX_BLACKFIN_GPTIMERS > 8) +# define TIMER_STATUS_TOVF8 0x0010 +# define TIMER_STATUS_TOVF9 0x0020 +# define TIMER_STATUS_TOVF10 0x0040 +# define TIMER_STATUS_TOVF11 0x0080 +# endif +# define TIMER_STATUS_OFLOW 0x00F000F0 +#else +# define TIMER_STATUS_OFLOW 0x0070 /* any timer overflow */ +#endif + +/* +** Timer Slave Enable Status : write 1 to clear +*/ +#define TIMER_STATUS_TRUN0 0x1000 +#define TIMER_STATUS_TRUN1 0x2000 +#define TIMER_STATUS_TRUN2 0x4000 +#if (MAX_BLACKFIN_GPTIMERS > 3) +# define TIMER_STATUS_TRUN3 0x00008000 +# define TIMER_STATUS_TRUN4 0x10000000 +# define TIMER_STATUS_TRUN5 0x20000000 +# define TIMER_STATUS_TRUN6 0x40000000 +# define TIMER_STATUS_TRUN7 0x80000000 +# define TIMER_STATUS_TRUN 0xF000F000 +# if (MAX_BLACKFIN_GPTIMERS > 8) +# define TIMER_STATUS_TRUN8 0x1000 +# define TIMER_STATUS_TRUN9 0x2000 +# define TIMER_STATUS_TRUN10 0x4000 +# define TIMER_STATUS_TRUN11 0x8000 +# endif +#else +# define TIMER_STATUS_TRUN 0x7000 +#endif + +/******************************************************************************* +* GP_TIMER API's +*******************************************************************************/ + +void set_gptimer_pwidth (int timer_id, int width); +int get_gptimer_pwidth (int timer_id); +void set_gptimer_period (int timer_id, int period); +int get_gptimer_period (int timer_id); +int get_gptimer_count (int timer_id); +short get_gptimer_intr (int timer_id); +void set_gptimer_config (int timer_id, short config); +short get_gptimer_config (int timer_id); +void set_gptimer_pulse_hi (int timer_id); +void clear_gptimer_pulse_hi(int timer_id); +void enable_gptimers (short mask); +void disable_gptimers (short mask); +short get_enabled_timers (void); +int get_gptimer_status (int octet); +void set_gptimer_status (int octet, int value); + +#endif diff --git a/include/asm-blackfin/bfin-global.h b/include/asm-blackfin/bfin-global.h new file mode 100644 index 000000000000..e37f81609fc3 --- /dev/null +++ b/include/asm-blackfin/bfin-global.h @@ -0,0 +1,120 @@ +/* + * File: include/asm-blackfin/bfin-global.h + * Based on: + * Author: * + * Created: + * Description: Global extern defines for blackfin + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _BFIN_GLOBAL_H_ +#define _BFIN_GLOBAL_H_ + +#ifndef __ASSEMBLY__ + +#include +#include +#include +#include +#include + +#if defined(CONFIG_DMA_UNCACHED_2M) +# define DMA_UNCACHED_REGION (2 * 1024 * 1024) +#elif defined(CONFIG_DMA_UNCACHED_1M) +# define DMA_UNCACHED_REGION (1024 * 1024) +#else +# define DMA_UNCACHED_REGION (0) +#endif + +extern unsigned long get_cclk(void); +extern unsigned long get_sclk(void); + +extern void dump_thread(struct pt_regs *regs, struct user *dump); +extern void dump_bfin_regs(struct pt_regs *fp, void *retaddr); +extern void dump_bfin_trace_buffer(void); + +extern int init_arch_irq(void); +extern void bfin_reset(void); +extern void _cplb_hdr(void); +/* Blackfin cache functions */ +extern void bfin_icache_init(void); +extern void bfin_dcache_init(void); +extern int read_iloc(void); +extern int bfin_console_init(void); +extern asmlinkage void lower_to_irq14(void); +extern void init_dma(void); +extern void program_IAR(void); +extern void evt14_softirq(void); +extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs); +extern void bfin_gpio_interrupt_setup(int irq, int irq_pfx, int type); + +extern void *l1_data_A_sram_alloc(size_t); +extern void *l1_data_B_sram_alloc(size_t); +extern void *l1_inst_sram_alloc(size_t); +extern void *l1_data_sram_alloc(size_t); +extern void *l1_data_sram_zalloc(size_t); +extern int l1_data_A_sram_free(const void*); +extern int l1_data_B_sram_free(const void*); +extern int l1_inst_sram_free(const void*); +extern int l1_data_sram_free(const void*); +extern int sram_free(const void*); + +#define L1_INST_SRAM 0x00000001 +#define L1_DATA_A_SRAM 0x00000002 +#define L1_DATA_B_SRAM 0x00000004 +#define L1_DATA_SRAM 0x00000006 +extern void *sram_alloc_with_lsl(size_t, unsigned long); +extern int sram_free_with_lsl(const void*); + +extern void led_on(int); +extern void led_off(int); +extern void led_toggle(int); +extern void led_disp_num(int); +extern void led_toggle_num(int); +extern void init_leds(void); + +extern char *bfin_board_name __attribute__ ((weak)); +extern unsigned long wall_jiffies; +extern unsigned long ipdt_table[]; +extern unsigned long dpdt_table[]; +extern unsigned long icplb_table[]; +extern unsigned long dcplb_table[]; + +extern unsigned long ipdt_swapcount_table[]; +extern unsigned long dpdt_swapcount_table[]; + +extern unsigned long table_start, table_end; + +extern struct file_operations dpmc_fops; +extern char _start; +extern unsigned long _ramstart, _ramend, _rambase; +extern unsigned long memory_start, memory_end, physical_mem_end; +extern char _stext_l1[], _etext_l1[], _sdata_l1[], _edata_l1[], _sbss_l1[], + _ebss_l1[], _l1_lma_start[], _sdata_b_l1[], _ebss_b_l1[]; + +#ifdef CONFIG_MTD_UCLINUX +extern unsigned long memory_mtd_start, memory_mtd_end, mtd_size; +#endif + +#endif + +#endif /* _BLACKFIN_H_ */ diff --git a/include/asm-blackfin/bfin5xx_spi.h b/include/asm-blackfin/bfin5xx_spi.h new file mode 100644 index 000000000000..95c1c952e7c1 --- /dev/null +++ b/include/asm-blackfin/bfin5xx_spi.h @@ -0,0 +1,170 @@ +/************************************************************ +* +* Copyright (C) 2004, Analog Devices. All Rights Reserved +* +* FILE bfin5xx_spi.h +* PROGRAMMER(S): Luke Yang (Analog Devices Inc.) +* +* +* DATE OF CREATION: March. 10th 2006 +* +* SYNOPSIS: +* +* DESCRIPTION: header file for SPI controller driver for Blackfin5xx. +************************************************************** + +* MODIFICATION HISTORY: +* March 10, 2006 bfin5xx_spi.h Created. (Luke Yang) + +************************************************************/ + +#ifndef _SPI_CHANNEL_H_ +#define _SPI_CHANNEL_H_ + +#define SPI0_REGBASE 0xffc00500 + +#define SPI_READ 0 +#define SPI_WRITE 1 + +#define SPI_CTRL_OFF 0x0 +#define SPI_FLAG_OFF 0x4 +#define SPI_STAT_OFF 0x8 +#define SPI_TXBUFF_OFF 0xc +#define SPI_RXBUFF_OFF 0x10 +#define SPI_BAUD_OFF 0x14 +#define SPI_SHAW_OFF 0x18 + +#define CMD_SPI_OUT_ENABLE 1 +#define CMD_SPI_SET_BAUDRATE 2 +#define CMD_SPI_SET_POLAR 3 +#define CMD_SPI_SET_PHASE 4 +#define CMD_SPI_SET_MASTER 5 +#define CMD_SPI_SET_SENDOPT 6 +#define CMD_SPI_SET_RECVOPT 7 +#define CMD_SPI_SET_ORDER 8 +#define CMD_SPI_SET_LENGTH16 9 +#define CMD_SPI_GET_STAT 11 +#define CMD_SPI_GET_CFG 12 +#define CMD_SPI_SET_CSAVAIL 13 +#define CMD_SPI_SET_CSHIGH 14 /* CS unavail */ +#define CMD_SPI_SET_CSLOW 15 /* CS avail */ +#define CMD_SPI_MISO_ENABLE 16 +#define CMD_SPI_SET_CSENABLE 17 +#define CMD_SPI_SET_CSDISABLE 18 + +#define CMD_SPI_SET_TRIGGER_MODE 19 +#define CMD_SPI_SET_TRIGGER_SENSE 20 +#define CMD_SPI_SET_TRIGGER_EDGE 21 +#define CMD_SPI_SET_TRIGGER_LEVEL 22 + +#define CMD_SPI_SET_TIME_SPS 23 +#define CMD_SPI_SET_TIME_SAMPLES 24 +#define CMD_SPI_GET_SYSTEMCLOCK 25 + +#define CMD_SPI_SET_WRITECONTINUOUS 26 +#define CMD_SPI_SET_SKFS 27 + +#define CMD_SPI_GET_ALLCONFIG 32 /* For debug */ + +#define SPI_DEFAULT_BARD 0x0100 + +#define SPI0_IRQ_NUM IRQ_SPI +#define SPI_ERR_TRIG -1 + +#define BIT_CTL_ENABLE 0x4000 +#define BIT_CTL_OPENDRAIN 0x2000 +#define BIT_CTL_MASTER 0x1000 +#define BIT_CTL_POLAR 0x0800 +#define BIT_CTL_PHASE 0x0400 +#define BIT_CTL_BITORDER 0x0200 +#define BIT_CTL_WORDSIZE 0x0100 +#define BIT_CTL_MISOENABLE 0x0020 +#define BIT_CTL_RXMOD 0x0000 +#define BIT_CTL_TXMOD 0x0001 +#define BIT_CTL_TIMOD_DMA_TX 0x0003 +#define BIT_CTL_TIMOD_DMA_RX 0x0002 +#define BIT_CTL_SENDOPT 0x0004 +#define BIT_CTL_TIMOD 0x0003 + +#define BIT_STAT_SPIF 0x0001 +#define BIT_STAT_MODF 0x0002 +#define BIT_STAT_TXE 0x0004 +#define BIT_STAT_TXS 0x0008 +#define BIT_STAT_RBSY 0x0010 +#define BIT_STAT_RXS 0x0020 +#define BIT_STAT_TXCOL 0x0040 +#define BIT_STAT_CLR 0xFFFF + +#define BIT_STU_SENDOVER 0x0001 +#define BIT_STU_RECVFULL 0x0020 + +#define CFG_SPI_ENABLE 1 +#define CFG_SPI_DISABLE 0 + +#define CFG_SPI_OUTENABLE 1 +#define CFG_SPI_OUTDISABLE 0 + +#define CFG_SPI_ACTLOW 1 +#define CFG_SPI_ACTHIGH 0 + +#define CFG_SPI_PHASESTART 1 +#define CFG_SPI_PHASEMID 0 + +#define CFG_SPI_MASTER 1 +#define CFG_SPI_SLAVE 0 + +#define CFG_SPI_SENELAST 0 +#define CFG_SPI_SENDZERO 1 + +#define CFG_SPI_RCVFLUSH 1 +#define CFG_SPI_RCVDISCARD 0 + +#define CFG_SPI_LSBFIRST 1 +#define CFG_SPI_MSBFIRST 0 + +#define CFG_SPI_WORDSIZE16 1 +#define CFG_SPI_WORDSIZE8 0 + +#define CFG_SPI_MISOENABLE 1 +#define CFG_SPI_MISODISABLE 0 + +#define CFG_SPI_READ 0x00 +#define CFG_SPI_WRITE 0x01 +#define CFG_SPI_DMAREAD 0x02 +#define CFG_SPI_DMAWRITE 0x03 + +#define CFG_SPI_CSCLEARALL 0 +#define CFG_SPI_CHIPSEL1 1 +#define CFG_SPI_CHIPSEL2 2 +#define CFG_SPI_CHIPSEL3 3 +#define CFG_SPI_CHIPSEL4 4 +#define CFG_SPI_CHIPSEL5 5 +#define CFG_SPI_CHIPSEL6 6 +#define CFG_SPI_CHIPSEL7 7 + +#define CFG_SPI_CS1VALUE 1 +#define CFG_SPI_CS2VALUE 2 +#define CFG_SPI_CS3VALUE 3 +#define CFG_SPI_CS4VALUE 4 +#define CFG_SPI_CS5VALUE 5 +#define CFG_SPI_CS6VALUE 6 +#define CFG_SPI_CS7VALUE 7 + +/* device.platform_data for SSP controller devices */ +struct bfin5xx_spi_master { + u16 num_chipselect; + u8 enable_dma; +}; + +/* spi_board_info.controller_data for SPI slave devices, + * copied to spi_device.platform_data ... mostly for dma tuning + */ +struct bfin5xx_spi_chip { + u16 ctl_reg; + u8 enable_dma; + u8 bits_per_word; + u8 cs_change_per_word; + u8 cs_chg_udelay; +}; + +#endif /* _SPI_CHANNEL_H_ */ diff --git a/include/asm-blackfin/bfin_simple_timer.h b/include/asm-blackfin/bfin_simple_timer.h new file mode 100644 index 000000000000..fccbb595464a --- /dev/null +++ b/include/asm-blackfin/bfin_simple_timer.h @@ -0,0 +1,13 @@ +#ifndef _bfin_simple_timer_h_ +#define _bfin_simple_timer_h_ + +#include + +#define BFIN_SIMPLE_TIMER_IOCTL_MAGIC 't' + +#define BFIN_SIMPLE_TIMER_SET_PERIOD _IO (BFIN_SIMPLE_TIMER_IOCTL_MAGIC, 2) +#define BFIN_SIMPLE_TIMER_START _IO (BFIN_SIMPLE_TIMER_IOCTL_MAGIC, 6) +#define BFIN_SIMPLE_TIMER_STOP _IO (BFIN_SIMPLE_TIMER_IOCTL_MAGIC, 8) +#define BFIN_SIMPLE_TIMER_READ _IO (BFIN_SIMPLE_TIMER_IOCTL_MAGIC, 10) + +#endif diff --git a/include/asm-blackfin/bfin_sport.h b/include/asm-blackfin/bfin_sport.h new file mode 100644 index 000000000000..c76ed8def302 --- /dev/null +++ b/include/asm-blackfin/bfin_sport.h @@ -0,0 +1,175 @@ +/* + * File: include/asm-blackfin/bfin_sport.h + * Based on: + * Author: Roy Huang (roy.huang@analog.com) + * + * Created: Thu Aug. 24 2006 + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __BFIN_SPORT_H__ +#define __BFIN_SPORT_H__ + +#define SPORT_MAJOR 237 +#define SPORT_NR_DEVS 2 + +/* Sport mode: it can be set to TDM, i2s or others */ +#define NORM_MODE 0x0 +#define TDM_MODE 0x1 +#define I2S_MODE 0x2 + +/* Data format, normal, a-law or u-law */ +#define NORM_FORMAT 0x0 +#define ALAW_FORMAT 0x2 +#define ULAW_FORMAT 0x3 +struct sport_register; + +/* Function driver which use sport must initialize the structure */ +struct sport_config { + /*TDM (multichannels), I2S or other mode */ + unsigned int mode:3; + + /* if TDM mode is selected, channels must be set */ + int channels; /* Must be in 8 units */ + unsigned int frame_delay:4; /* Delay between frame sync pulse and first bit */ + + /* I2S mode */ + unsigned int right_first:1; /* Right stereo channel first */ + + /* In mormal mode, the following item need to be set */ + unsigned int lsb_first:1; /* order of transmit or receive data */ + unsigned int fsync:1; /* Frame sync required */ + unsigned int data_indep:1; /* data independent frame sync generated */ + unsigned int act_low:1; /* Active low TFS */ + unsigned int late_fsync:1; /* Late frame sync */ + unsigned int tckfe:1; + unsigned int sec_en:1; /* Secondary side enabled */ + + /* Choose clock source */ + unsigned int int_clk:1; /* Internal or external clock */ + + /* If external clock is used, the following fields are ignored */ + int serial_clk; + int fsync_clk; + + unsigned int data_format:2; /*Normal, u-law or a-law */ + + int word_len; /* How length of the word in bits, 3-32 bits */ + int dma_enabled; +}; + +struct sport_register { + unsigned short tcr1; + unsigned short reserved0; + unsigned short tcr2; + unsigned short reserved1; + unsigned short tclkdiv; + unsigned short reserved2; + unsigned short tfsdiv; + unsigned short reserved3; + unsigned long tx; + unsigned long reserved_l0; + unsigned long rx; + unsigned long reserved_l1; + unsigned short rcr1; + unsigned short reserved4; + unsigned short rcr2; + unsigned short reserved5; + unsigned short rclkdiv; + unsigned short reserved6; + unsigned short rfsdiv; + unsigned short reserved7; + unsigned short stat; + unsigned short reserved8; + unsigned short chnl; + unsigned short reserved9; + unsigned short mcmc1; + unsigned short reserved10; + unsigned short mcmc2; + unsigned short reserved11; + unsigned long mtcs0; + unsigned long mtcs1; + unsigned long mtcs2; + unsigned long mtcs3; + unsigned long mrcs0; + unsigned long mrcs1; + unsigned long mrcs2; + unsigned long mrcs3; +}; + +#define SPORT_IOC_MAGIC 'P' +#define SPORT_IOC_CONFIG _IOWR('P', 0x01, struct sport_config) + +/* Test purpose */ +#define ENABLE_AD73311 _IOWR('P', 0x02, int) + +struct sport_dev { + struct cdev cdev; /* Char device structure */ + + int sport_num; + + int dma_rx_chan; + int dma_tx_chan; + + int rx_irq; + unsigned char *rx_buf; /* Buffer store the received data */ + int rx_len; /* How many bytes will be received */ + int rx_received; /* How many bytes has been received */ + + int tx_irq; + const unsigned char *tx_buf; + int tx_len; + int tx_sent; + + int sport_err_irq; + + struct mutex mutex; /* mutual exclusion semaphore */ + struct task_struct *task; + + wait_queue_head_t waitq; + int wait_con; + struct sport_register *regs; + struct sport_config config; +}; + +#define SPORT_TCR1 0 +#define SPORT_TCR2 1 +#define SPORT_TCLKDIV 2 +#define SPORT_TFSDIV 3 +#define SPORT_RCR1 8 +#define SPORT_RCR2 9 +#define SPORT_RCLKDIV 10 +#define SPORT_RFSDIV 11 +#define SPORT_CHANNEL 13 +#define SPORT_MCMC1 14 +#define SPORT_MCMC2 15 +#define SPORT_MTCS0 16 +#define SPORT_MTCS1 17 +#define SPORT_MTCS2 18 +#define SPORT_MTCS3 19 +#define SPORT_MRCS0 20 +#define SPORT_MRCS1 21 +#define SPORT_MRCS2 22 +#define SPORT_MRCS3 23 + +#endif /*__BFIN_SPORT_H__*/ diff --git a/include/asm-blackfin/bitops.h b/include/asm-blackfin/bitops.h new file mode 100644 index 000000000000..27c2d0e48e1b --- /dev/null +++ b/include/asm-blackfin/bitops.h @@ -0,0 +1,213 @@ +#ifndef _BLACKFIN_BITOPS_H +#define _BLACKFIN_BITOPS_H + +/* + * Copyright 1992, Linus Torvalds. + */ + +#include +#include /* swab32 */ +#include /* save_flags */ + +#ifdef __KERNEL__ + +#include +#include +#include +#include + +static __inline__ void set_bit(int nr, volatile unsigned long *addr) +{ + int *a = (int *)addr; + int mask; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + local_irq_save(flags); + *a |= mask; + local_irq_restore(flags); +} + +static __inline__ void __set_bit(int nr, volatile unsigned long *addr) +{ + int *a = (int *)addr; + int mask; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + *a |= mask; +} + +/* + * clear_bit() doesn't provide any barrier for the compiler. + */ +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() + +static __inline__ void clear_bit(int nr, volatile unsigned long *addr) +{ + int *a = (int *)addr; + int mask; + unsigned long flags; + a += nr >> 5; + mask = 1 << (nr & 0x1f); + local_irq_save(flags); + *a &= ~mask; + local_irq_restore(flags); +} + +static __inline__ void __clear_bit(int nr, volatile unsigned long *addr) +{ + int *a = (int *)addr; + int mask; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + *a &= ~mask; +} + +static __inline__ void change_bit(int nr, volatile unsigned long *addr) +{ + int mask, flags; + unsigned long *ADDR = (unsigned long *)addr; + + ADDR += nr >> 5; + mask = 1 << (nr & 31); + local_irq_save(flags); + *ADDR ^= mask; + local_irq_restore(flags); +} + +static __inline__ void __change_bit(int nr, volatile unsigned long *addr) +{ + int mask; + unsigned long *ADDR = (unsigned long *)addr; + + ADDR += nr >> 5; + mask = 1 << (nr & 31); + *ADDR ^= mask; +} + +static __inline__ int test_and_set_bit(int nr, void *addr) +{ + int mask, retval; + volatile unsigned int *a = (volatile unsigned int *)addr; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + local_irq_save(flags); + retval = (mask & *a) != 0; + *a |= mask; + local_irq_restore(flags); + + return retval; +} + +static __inline__ int __test_and_set_bit(int nr, volatile unsigned long *addr) +{ + int mask, retval; + volatile unsigned int *a = (volatile unsigned int *)addr; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + retval = (mask & *a) != 0; + *a |= mask; + return retval; +} + +static __inline__ int test_and_clear_bit(int nr, volatile unsigned long *addr) +{ + int mask, retval; + volatile unsigned int *a = (volatile unsigned int *)addr; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + local_irq_save(flags); + retval = (mask & *a) != 0; + *a &= ~mask; + local_irq_restore(flags); + + return retval; +} + +static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long *addr) +{ + int mask, retval; + volatile unsigned int *a = (volatile unsigned int *)addr; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + retval = (mask & *a) != 0; + *a &= ~mask; + return retval; +} + +static __inline__ int test_and_change_bit(int nr, volatile unsigned long *addr) +{ + int mask, retval; + volatile unsigned int *a = (volatile unsigned int *)addr; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + local_irq_save(flags); + retval = (mask & *a) != 0; + *a ^= mask; + local_irq_restore(flags); + return retval; +} + +static __inline__ int __test_and_change_bit(int nr, + volatile unsigned long *addr) +{ + int mask, retval; + volatile unsigned int *a = (volatile unsigned int *)addr; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + retval = (mask & *a) != 0; + *a ^= mask; + return retval; +} + +/* + * This routine doesn't need to be atomic. + */ +static __inline__ int __constant_test_bit(int nr, const void *addr) +{ + return ((1UL << (nr & 31)) & + (((const volatile unsigned int *)addr)[nr >> 5])) != 0; +} + +static __inline__ int __test_bit(int nr, const void *addr) +{ + int *a = (int *)addr; + int mask; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + return ((mask & *a) != 0); +} + +#define test_bit(nr,addr) \ +(__builtin_constant_p(nr) ? \ + __constant_test_bit((nr),(addr)) : \ + __test_bit((nr),(addr))) + +#include +#include + +#include +#include + +#include + +#endif /* __KERNEL__ */ + +#include +#include + +#endif /* _BLACKFIN_BITOPS_H */ diff --git a/include/asm-blackfin/blackfin.h b/include/asm-blackfin/blackfin.h new file mode 100644 index 000000000000..14e58de73973 --- /dev/null +++ b/include/asm-blackfin/blackfin.h @@ -0,0 +1,81 @@ +/* + * Common header file for blackfin family of processors. + * + */ + +#ifndef _BLACKFIN_H_ +#define _BLACKFIN_H_ + +#include +#include +#include + +#ifndef __ASSEMBLY__ + +/* SSYNC implementation for C file */ +#if defined(ANOMALY_05000312) && defined(ANOMALY_05000244) +static inline void SSYNC (void) +{ + int _tmp; + __asm__ __volatile__ ("cli %0;\n\t" + "nop;nop;\n\t" + "ssync;\n\t" + "sti %0;\n\t" + :"=d"(_tmp):); +} +#elif defined(ANOMALY_05000312) && !defined(ANOMALY_05000244) +static inline void SSYNC (void) +{ + int _tmp; + __asm__ __volatile__ ("cli %0;\n\t" + "ssync;\n\t" + "sti %0;\n\t" + :"=d"(_tmp):); +} +#elif !defined(ANOMALY_05000312) && defined(ANOMALY_05000244) +static inline void SSYNC (void) +{ + __builtin_bfin_ssync(); +} +#elif !defined(ANOMALY_05000312) && !defined(ANOMALY_05000244) +static inline void SSYNC (void) +{ + __asm__ __volatile__ ("ssync;\n\t"); +} +#endif + +/* CSYNC implementation for C file */ +#if defined(ANOMALY_05000312) && defined(ANOMALY_05000244) +static inline void CSYNC (void) +{ + int _tmp; + __asm__ __volatile__ ("cli %0;\n\t" + "nop;nop;\n\t" + "csync;\n\t" + "sti %0;\n\t" + :"=d"(_tmp):); +} +#elif defined(ANOMALY_05000312) && !defined(ANOMALY_05000244) +static inline void CSYNC (void) +{ + int _tmp; + __asm__ __volatile__ ("cli %0;\n\t" + "csync;\n\t" + "sti %0;\n\t" + :"=d"(_tmp):); +} +#elif !defined(ANOMALY_05000312) && defined(ANOMALY_05000244) +static inline void CSYNC (void) +{ + __builtin_bfin_csync(); +} +#elif !defined(ANOMALY_05000312) && !defined(ANOMALY_05000244) +static inline void CSYNC (void) +{ + __asm__ __volatile__ ("csync;\n\t"); +} +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* _BLACKFIN_H_ */ diff --git a/include/asm-blackfin/bug.h b/include/asm-blackfin/bug.h new file mode 100644 index 000000000000..41e53b29f167 --- /dev/null +++ b/include/asm-blackfin/bug.h @@ -0,0 +1,4 @@ +#ifndef _BLACKFIN_BUG_H +#define _BLACKFIN_BUG_H +#include +#endif diff --git a/include/asm-blackfin/bugs.h b/include/asm-blackfin/bugs.h new file mode 100644 index 000000000000..9093c9c1fb81 --- /dev/null +++ b/include/asm-blackfin/bugs.h @@ -0,0 +1,16 @@ +/* + * include/asm-blackfin/bugs.h + * + * Copyright (C) 1994 Linus Torvalds + */ + +/* + * This is included by init/main.c to check for architecture-dependent bugs. + * + * Needs: + * void check_bugs(void); + */ + +static void check_bugs(void) +{ +} diff --git a/include/asm-blackfin/byteorder.h b/include/asm-blackfin/byteorder.h new file mode 100644 index 000000000000..6a673d42da18 --- /dev/null +++ b/include/asm-blackfin/byteorder.h @@ -0,0 +1,48 @@ +#ifndef _BLACKFIN_BYTEORDER_H +#define _BLACKFIN_BYTEORDER_H + +#include +#include + +#ifdef __GNUC__ + +static __inline__ __attribute_const__ __u32 ___arch__swahb32(__u32 xx) +{ + __u32 tmp; + __asm__("%1 = %0 >> 8 (V);\n\t" + "%0 = %0 << 8 (V);\n\t" + "%0 = %0 | %1;\n\t" + : "+d"(xx), "=&d"(tmp)); + return xx; +} + +static __inline__ __attribute_const__ __u32 ___arch__swahw32(__u32 xx) +{ + __u32 rv; + __asm__("%0 = PACK(%1.L, %1.H);\n\t": "=d"(rv): "d"(xx)); + return rv; +} + +#define __arch__swahb32(x) ___arch__swahb32(x) +#define __arch__swahw32(x) ___arch__swahw32(x) +#define __arch__swab32(x) ___arch__swahb32(___arch__swahw32(x)) + +static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 xx) +{ + __u32 xw = xx; + __asm__("%0 <<= 8;\n %0.L = %0.L + %0.H (NS);\n": "+d"(xw)); + return (__u16)xw; +} + +#define __arch__swab16(x) ___arch__swab16(x) + +#endif + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __BYTEORDER_HAS_U64__ +# define __SWAB_64_THRU_32__ +#endif + +#include + +#endif /* _BLACKFIN_BYTEORDER_H */ diff --git a/include/asm-blackfin/cache.h b/include/asm-blackfin/cache.h new file mode 100644 index 000000000000..023d72133b5a --- /dev/null +++ b/include/asm-blackfin/cache.h @@ -0,0 +1,29 @@ +/* + * include/asm-blackfin/cache.h + */ +#ifndef __ARCH_BLACKFIN_CACHE_H +#define __ARCH_BLACKFIN_CACHE_H + +/* + * Bytes per L1 cache line + * Blackfin loads 32 bytes for cache + */ +#define L1_CACHE_SHIFT 5 +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) +#define SMP_CACHE_BYTES L1_CACHE_BYTES + +/* + * Put cacheline_aliged data to L1 data memory + */ +#ifdef CONFIG_CACHELINE_ALIGNED_L1 +#define __cacheline_aligned \ + __attribute__((__aligned__(L1_CACHE_BYTES), \ + __section__(".data_l1.cacheline_aligned"))) +#endif + +/* + * largest L1 which this arch supports + */ +#define L1_CACHE_SHIFT_MAX 5 + +#endif diff --git a/include/asm-blackfin/cacheflush.h b/include/asm-blackfin/cacheflush.h new file mode 100644 index 000000000000..e5e000de3c36 --- /dev/null +++ b/include/asm-blackfin/cacheflush.h @@ -0,0 +1,90 @@ +/* + * File: include/asm-blackfin/cacheflush.h + * Based on: include/asm-m68knommu/cacheflush.h + * Author: LG Soft India + * Copyright (C) 2004 Analog Devices Inc. + * Created: Tue Sep 21 2004 + * Description: Blackfin low-level cache routines adapted from the i386 + * and PPC versions by Greg Ungerer (gerg@snapgear.com) + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _BLACKFIN_CACHEFLUSH_H +#define _BLACKFIN_CACHEFLUSH_H + +#include + +extern void blackfin_icache_dcache_flush_range(unsigned int, unsigned int); +extern void blackfin_icache_flush_range(unsigned int, unsigned int); +extern void blackfin_dcache_flush_range(unsigned int, unsigned int); +extern void blackfin_dcache_invalidate_range(unsigned int, unsigned int); +extern void blackfin_dflush_page(void *); + +#define flush_dcache_mmap_lock(mapping) do { } while (0) +#define flush_dcache_mmap_unlock(mapping) do { } while (0) +#define flush_cache_mm(mm) do { } while (0) +#define flush_cache_range(vma, start, end) do { } while (0) +#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_cache_vmap(start, end) do { } while (0) +#define flush_cache_vunmap(start, end) do { } while (0) + +static inline void flush_icache_range(unsigned start, unsigned end) +{ +#if defined(CONFIG_BLKFIN_DCACHE) && defined(CONFIG_BLKFIN_CACHE) + +# if defined(CONFIG_BLKFIN_WT) + blackfin_icache_flush_range((start), (end)); +# else + blackfin_icache_dcache_flush_range((start), (end)); +# endif + +#else + +# if defined(CONFIG_BLKFIN_CACHE) + blackfin_icache_flush_range((start), (end)); +# endif +# if defined(CONFIG_BLKFIN_DCACHE) + blackfin_dcache_flush_range((start), (end)); +# endif + +#endif +} + +#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ +do { memcpy(dst, src, len); \ + flush_icache_range ((unsigned) (dst), (unsigned) (dst) + (len)); \ +} while (0) +#define copy_from_user_page(vma, page, vaddr, dst, src, len) memcpy(dst, src, len) + +#if defined(CONFIG_BLKFIN_DCACHE) +# define invalidate_dcache_range(start,end) blackfin_dcache_invalidate_range((start), (end)) +#else +# define invalidate_dcache_range(start,end) do { } while (0) +#endif +#if defined(CONFIG_BLKFIN_DCACHE) && defined(CONFIG_BLKFIN_WB) +# define flush_dcache_range(start,end) blackfin_dcache_flush_range((start), (end)) +# define flush_dcache_page(page) blackfin_dflush_page(page_address(page)) +#else +# define flush_dcache_range(start,end) do { } while (0) +# define flush_dcache_page(page) do { } while (0) +#endif + +#endif /* _BLACKFIN_CACHEFLUSH_H */ diff --git a/include/asm-blackfin/checksum.h b/include/asm-blackfin/checksum.h new file mode 100644 index 000000000000..2638f2586d2f --- /dev/null +++ b/include/asm-blackfin/checksum.h @@ -0,0 +1,101 @@ +#ifndef _BFIN_CHECKSUM_H +#define _BFIN_CHECKSUM_H + +/* + * MODIFIED FOR BFIN April 30, 2001 akbar.hussain@lineo.com + * + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, + int len, int sum); + +/* + * the same as csum_partial_copy, but copies from user space. + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +extern unsigned int csum_partial_copy_from_user(const unsigned char *src, + unsigned char *dst, int len, + int sum, int *csum_err); + +#define csum_partial_copy_nocheck(src, dst, len, sum) \ + csum_partial_copy((src), (dst), (len), (sum)) + +unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl); + +/* + * Fold a partial checksum + */ + +static inline unsigned int csum_fold(unsigned int sum) +{ + while (sum >> 16) + sum = (sum & 0xffff) + (sum >> 16); + return ((~(sum << 16)) >> 16); +} + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ + +static inline unsigned int +csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len, + unsigned short proto, unsigned int sum) +{ + + __asm__ ("%0 = %0 + %1;\n\t" + "CC = AC0;\n\t" + "if !CC jump 4;\n\t" + "%0 = %0 + %4;\n\t" + "%0 = %0 + %2;\n\t" + "CC = AC0;\n\t" + "if !CC jump 4;\n\t" + "%0 = %0 + %4;\n\t" + "%0 = %0 + %3;\n\t" + "CC = AC0;\n\t" + "if !CC jump 4;\n\t" + "%0 = %0 + %4;\n\t" + "NOP;\n\t" + : "=d" (sum) + : "d" (daddr), "d" (saddr), "d" ((ntohs(len)<<16)+proto*256), "d" (1), "0"(sum)); + + return (sum); +} + +static inline unsigned short int +csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len, + unsigned short proto, unsigned int sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ + +extern unsigned short ip_compute_csum(const unsigned char *buff, int len); + +#endif /* _BFIN_CHECKSUM_H */ diff --git a/include/asm-blackfin/cplb.h b/include/asm-blackfin/cplb.h new file mode 100644 index 000000000000..e0dd56bfa4c7 --- /dev/null +++ b/include/asm-blackfin/cplb.h @@ -0,0 +1,51 @@ +/************************************************************************ + * + * cplb.h + * + * (c) Copyright 2002-2003 Analog Devices, Inc. All rights reserved. + * + ************************************************************************/ + +/* Defines necessary for cplb initialisation routines. */ + +#ifndef _CPLB_H +#define _CPLB_H + +# include + +#define CPLB_ENABLE_ICACHE_P 0 +#define CPLB_ENABLE_DCACHE_P 1 +#define CPLB_ENABLE_DCACHE2_P 2 +#define CPLB_ENABLE_CPLBS_P 3 /* Deprecated! */ +#define CPLB_ENABLE_ICPLBS_P 4 +#define CPLB_ENABLE_DCPLBS_P 5 + +#define CPLB_ENABLE_ICACHE (1< +#include + +#define INITIAL_T 0x1 +#define SWITCH_T 0x2 +#define I_CPLB 0x4 +#define D_CPLB 0x8 + +#define IN_KERNEL 1 + +enum +{ZERO_P, L1I_MEM, L1D_MEM, SDRAM_KERN , SDRAM_RAM_MTD, SDRAM_DMAZ, RES_MEM, ASYNC_MEM, L2_MEM}; + +struct cplb_desc { + u32 start; /* start address */ + u32 end; /* end address */ + u32 psize; /* prefered size if any otherwise 1MB or 4MB*/ + u16 attr;/* attributes */ + u16 i_conf;/* I-CPLB DATA */ + u16 d_conf;/* D-CPLB DATA */ + u16 valid;/* valid */ + const s8 name[30];/* name */ +}; + +struct cplb_tab { + u_long *tab; + u16 pos; + u16 size; +}; + +u_long icplb_table[MAX_CPLBS+1]; +u_long dcplb_table[MAX_CPLBS+1]; + +/* Till here we are discussing about the static memory management model. + * However, the operating envoronments commonly define more CPLB + * descriptors to cover the entire addressable memory than will fit into + * the available on-chip 16 CPLB MMRs. When this happens, the below table + * will be used which will hold all the potentially required CPLB descriptors + * + * This is how Page descriptor Table is implemented in uClinux/Blackfin. + */ + +#ifdef CONFIG_CPLB_SWITCH_TAB_L1 +u_long ipdt_table[MAX_SWITCH_I_CPLBS+1]__attribute__((l1_data)); +u_long dpdt_table[MAX_SWITCH_D_CPLBS+1]__attribute__((l1_data)); + +#ifdef CONFIG_CPLB_INFO +u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS]__attribute__((l1_data)); +u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS]__attribute__((l1_data)); +#endif /* CONFIG_CPLB_INFO */ + +#else + +u_long ipdt_table[MAX_SWITCH_I_CPLBS+1]; +u_long dpdt_table[MAX_SWITCH_D_CPLBS+1]; + +#ifdef CONFIG_CPLB_INFO +u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS]; +u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS]; +#endif /* CONFIG_CPLB_INFO */ + +#endif /*CONFIG_CPLB_SWITCH_TAB_L1*/ + +struct s_cplb { + struct cplb_tab init_i; + struct cplb_tab init_d; + struct cplb_tab switch_i; + struct cplb_tab switch_d; +}; + +#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE) +static struct cplb_desc cplb_data[] = { + { + .start = 0, + .end = SIZE_4K, + .psize = SIZE_4K, + .attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB, + .i_conf = SDRAM_OOPS, + .d_conf = SDRAM_OOPS, +#if defined(CONFIG_DEBUG_HUNT_FOR_ZERO) + .valid = 1, +#else + .valid = 0, +#endif + .name = "ZERO Pointer Saveguard", + }, + { + .start = L1_CODE_START, + .end = L1_CODE_START + L1_CODE_LENGTH, + .psize = SIZE_4M, + .attr = INITIAL_T | SWITCH_T | I_CPLB, + .i_conf = L1_IMEMORY, + .d_conf = 0, + .valid = 1, + .name = "L1 I-Memory", + }, + { + .start = L1_DATA_A_START, + .end = L1_DATA_B_START + L1_DATA_B_LENGTH, + .psize = SIZE_4M, + .attr = INITIAL_T | SWITCH_T | D_CPLB, + .i_conf = 0, + .d_conf = L1_DMEMORY, +#if ((L1_DATA_A_LENGTH > 0) || (L1_DATA_B_LENGTH > 0)) + .valid = 1, +#else + .valid = 0, +#endif + .name = "L1 D-Memory", + }, + { + .start = 0, + .end = 0, /* dynamic */ + .psize = 0, + .attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB, + .i_conf = SDRAM_IGENERIC, + .d_conf = SDRAM_DGENERIC, + .valid = 1, + .name = "SDRAM Kernel", + }, + { + .start = 0, /* dynamic */ + .end = 0, /* dynamic */ + .psize = 0, + .attr = INITIAL_T | SWITCH_T | D_CPLB, + .i_conf = SDRAM_IGENERIC, + .d_conf = SDRAM_DNON_CHBL, + .valid = 1, + .name = "SDRAM RAM MTD", + }, + { + .start = 0, /* dynamic */ + .end = 0, /* dynamic */ + .psize = SIZE_1M, + .attr = INITIAL_T | SWITCH_T | D_CPLB, + .d_conf = SDRAM_DNON_CHBL, + .valid = 1,//(DMA_UNCACHED_REGION > 0), + .name = "SDRAM Uncached DMA ZONE", + }, + { + .start = 0, /* dynamic */ + .end = 0, /* dynamic */ + .psize = 0, + .attr = SWITCH_T | D_CPLB, + .i_conf = 0, /* dynamic */ + .d_conf = 0, /* dynamic */ + .valid = 1, + .name = "SDRAM Reserved Memory", + }, + { + .start = ASYNC_BANK0_BASE, + .end = ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE, + .psize = 0, + .attr = SWITCH_T | D_CPLB, + .d_conf = SDRAM_EBIU, + .valid = 1, + .name = "ASYNC Memory", + }, + { +#if defined(CONFIG_BF561) + .start = L2_SRAM, + .end = L2_SRAM_END, + .psize = SIZE_1M, + .attr = SWITCH_T | D_CPLB, + .i_conf = L2_MEMORY, + .d_conf = L2_MEMORY, + .valid = 1, +#else + .valid = 0, +#endif + .name = "L2 Memory", + } +}; +#endif diff --git a/include/asm-blackfin/cpumask.h b/include/asm-blackfin/cpumask.h new file mode 100644 index 000000000000..b20a8e9012cb --- /dev/null +++ b/include/asm-blackfin/cpumask.h @@ -0,0 +1,6 @@ +#ifndef _ASM_BLACKFIN_CPUMASK_H +#define _ASM_BLACKFIN_CPUMASK_H + +#include + +#endif /* _ASM_BLACKFIN_CPUMASK_H */ diff --git a/include/asm-blackfin/cputime.h b/include/asm-blackfin/cputime.h new file mode 100644 index 000000000000..2b19705f9885 --- /dev/null +++ b/include/asm-blackfin/cputime.h @@ -0,0 +1,6 @@ +#ifndef __BLACKFIN_CPUTIME_H +#define __BLACKFIN_CPUTIME_H + +#include + +#endif /* __BLACKFIN_CPUTIME_H */ diff --git a/include/asm-blackfin/current.h b/include/asm-blackfin/current.h new file mode 100644 index 000000000000..31918d29122c --- /dev/null +++ b/include/asm-blackfin/current.h @@ -0,0 +1,23 @@ +#ifndef _BLACKFIN_CURRENT_H +#define _BLACKFIN_CURRENT_H +/* + * current.h + * (C) Copyright 2000, Lineo, David McCullough + * + * rather than dedicate a register (as the m68k source does), we + * just keep a global, we should probably just change it all to be + * current and lose _current_task. + */ +#include + +struct task_struct; + +static inline struct task_struct *get_current(void) __attribute__ ((__const__)); +static inline struct task_struct *get_current(void) +{ + return (current_thread_info()->task); +} + +#define current (get_current()) + +#endif /* _BLACKFIN_CURRENT_H */ diff --git a/include/asm-blackfin/delay.h b/include/asm-blackfin/delay.h new file mode 100644 index 000000000000..52e7a10d7ff8 --- /dev/null +++ b/include/asm-blackfin/delay.h @@ -0,0 +1,44 @@ +#ifndef _BLACKFIN_DELAY_H +#define _BLACKFIN_DELAY_H + +static inline void __delay(unsigned long loops) +{ + +/* FIXME: Currently the assembler doesn't recognize Loop Register Clobbers, + uncomment this as soon those are implemented */ +/* + __asm__ __volatile__ ( "\t LSETUP (1f,1f) LC0= %0\n\t" + "1:\t NOP;\n\t" + : :"a" (loops) + : "LT0","LB0","LC0"); + +*/ + + __asm__ __volatile__("[--SP] = LC0;\n\t" + "[--SP] = LT0;\n\t" + "[--SP] = LB0;\n\t" + "LSETUP (1f,1f) LC0 = %0;\n\t" + "1:\t NOP;\n\t" + "LB0 = [SP++];\n\t" + "LT0 = [SP++];\n\t" + "LC0 = [SP++];\n" + : + :"a" (loops)); +} + +#include /* needed for HZ */ + +/* + * Use only for very small delays ( < 1 msec). Should probably use a + * lookup table, really, as the multiplications take much too long with + * short delays. This is a "reasonable" implementation, though (and the + * first constant multiplications gets optimized away if the delay is + * a constant) + */ +static inline void udelay(unsigned long usecs) +{ + extern unsigned long loops_per_jiffy; + __delay(usecs * loops_per_jiffy / (1000000 / HZ)); +} + +#endif /* defined(_BLACKFIN_DELAY_H) */ diff --git a/include/asm-blackfin/device.h b/include/asm-blackfin/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-blackfin/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-blackfin/div64.h b/include/asm-blackfin/div64.h new file mode 100644 index 000000000000..6cd978cefb28 --- /dev/null +++ b/include/asm-blackfin/div64.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-blackfin/dma-mapping.h b/include/asm-blackfin/dma-mapping.h new file mode 100644 index 000000000000..7a77d7fe3a33 --- /dev/null +++ b/include/asm-blackfin/dma-mapping.h @@ -0,0 +1,66 @@ +#ifndef _BLACKFIN_DMA_MAPPING_H +#define _BLACKFIN_DMA_MAPPING_H + +#include + +void dma_alloc_init(unsigned long start, unsigned long end); +void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp); +void dma_free_coherent(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle); + +/* + * Now for the API extensions over the pci_ one + */ +#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) +#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) + +/* + * Map a single buffer of the indicated size for DMA in streaming mode. + * The 32-bit bus address to use is returned. + * + * Once the device is given the dma address, the device owns this memory + * until either pci_unmap_single or pci_dma_sync_single is performed. + */ +extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction); + +/* + * Unmap a single streaming mode DMA translation. The dma_addr and size + * must match what was provided for in a previous pci_map_single call. All + * other usages are undefined. + * + * After this call, reads by the cpu to the buffer are guarenteed to see + * whatever the device wrote there. + */ +extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction direction); + +/* + * Map a set of buffers described by scatterlist in streaming + * mode for DMA. This is the scather-gather version of the + * above pci_map_single interface. Here the scatter gather list + * elements are each tagged with the appropriate dma address + * and length. They are obtained via sg_dma_{address,length}(SG). + * + * NOTE: An implementation may be able to use a smaller number of + * DMA address/length pairs than there are SG table elements. + * (for example via virtual mapping capabilities) + * The routine returns the number of addr/length pairs actually + * used, at most nents. + * + * Device ownership issues as mentioned above for pci_map_single are + * the same here. + */ +extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction direction); + +/* + * Unmap a set of streaming mode DMA translations. + * Again, cpu read rules concerning calls here are the same as for + * pci_unmap_single() above. + */ +extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg, + int nhwentries, enum dma_data_direction direction); + +#endif /* _BLACKFIN_DMA_MAPPING_H */ diff --git a/include/asm-blackfin/dma.h b/include/asm-blackfin/dma.h new file mode 100644 index 000000000000..be0d913e5516 --- /dev/null +++ b/include/asm-blackfin/dma.h @@ -0,0 +1,188 @@ +/* + * File: include/asm-blackfin/simple_bf533_dma.h + * Based on: none - original work + * Author: LG Soft India + * Copyright (C) 2004-2005 Analog Devices Inc. + * Created: Tue Sep 21 2004 + * Description: This file contains the major Data structures and constants + * used for DMA Implementation in BF533 + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _BLACKFIN_DMA_H_ +#define _BLACKFIN_DMA_H_ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define MAX_DMA_ADDRESS PAGE_OFFSET + +/***************************************************************************** +* Generic DMA Declarations +* +****************************************************************************/ +enum dma_chan_status { + DMA_CHANNEL_FREE, + DMA_CHANNEL_REQUESTED, + DMA_CHANNEL_ENABLED, +}; + +/*------------------------- + * config reg bits value + *-------------------------*/ +#define DATA_SIZE_8 0 +#define DATA_SIZE_16 1 +#define DATA_SIZE_32 2 + +#define DMA_FLOW_STOP 0 +#define DMA_FLOW_AUTO 1 +#define DMA_FLOW_ARRAY 4 +#define DMA_FLOW_SMALL 6 +#define DMA_FLOW_LARGE 7 + +#define DIMENSION_LINEAR 0 +#define DIMENSION_2D 1 + +#define DIR_READ 0 +#define DIR_WRITE 1 + +#define INTR_DISABLE 0 +#define INTR_ON_BUF 2 +#define INTR_ON_ROW 3 + +struct dmasg { + unsigned long next_desc_addr; + unsigned long start_addr; + unsigned short cfg; + unsigned short x_count; + short x_modify; + unsigned short y_count; + short y_modify; +} __attribute__((packed)); + +struct dma_register { + unsigned long next_desc_ptr; /* DMA Next Descriptor Pointer register */ + unsigned long start_addr; /* DMA Start address register */ + + unsigned short cfg; /* DMA Configuration register */ + unsigned short dummy1; /* DMA Configuration register */ + + unsigned long reserved; + + unsigned short x_count; /* DMA x_count register */ + unsigned short dummy2; + + short x_modify; /* DMA x_modify register */ + unsigned short dummy3; + + unsigned short y_count; /* DMA y_count register */ + unsigned short dummy4; + + short y_modify; /* DMA y_modify register */ + unsigned short dummy5; + + unsigned long curr_desc_ptr; /* DMA Current Descriptor Pointer + register */ + unsigned short curr_addr_ptr_lo; /* DMA Current Address Pointer + register */ + unsigned short curr_addr_ptr_hi; /* DMA Current Address Pointer + register */ + unsigned short irq_status; /* DMA irq status register */ + unsigned short dummy6; + + unsigned short peripheral_map; /* DMA peripheral map register */ + unsigned short dummy7; + + unsigned short curr_x_count; /* DMA Current x-count register */ + unsigned short dummy8; + + unsigned long reserved2; + + unsigned short curr_y_count; /* DMA Current y-count register */ + unsigned short dummy9; + + unsigned long reserved3; + +}; + +typedef irqreturn_t(*dma_interrupt_t) (int irq, void *dev_id); + +struct dma_channel { + struct mutex dmalock; + char *device_id; + enum dma_chan_status chan_status; + struct dma_register *regs; + struct dmasg *sg; /* large mode descriptor */ + unsigned int ctrl_num; /* controller number */ + dma_interrupt_t irq_callback; + void *data; + unsigned int dma_enable_flag; + unsigned int loopback_flag; +}; + +/******************************************************************************* +* DMA API's +*******************************************************************************/ +/* functions to set register mode */ +void set_dma_start_addr(unsigned int channel, unsigned long addr); +void set_dma_next_desc_addr(unsigned int channel, unsigned long addr); +void set_dma_x_count(unsigned int channel, unsigned short x_count); +void set_dma_x_modify(unsigned int channel, short x_modify); +void set_dma_y_count(unsigned int channel, unsigned short y_count); +void set_dma_y_modify(unsigned int channel, short y_modify); +void set_dma_config(unsigned int channel, unsigned short config); +unsigned short set_bfin_dma_config(char direction, char flow_mode, + char intr_mode, char dma_mode, char width); + +/* get curr status for polling */ +unsigned short get_dma_curr_irqstat(unsigned int channel); +unsigned short get_dma_curr_xcount(unsigned int channel); +unsigned short get_dma_curr_ycount(unsigned int channel); + +/* set large DMA mode descriptor */ +void set_dma_sg(unsigned int channel, struct dmasg *sg, int nr_sg); + +/* check if current channel is in use */ +int dma_channel_active(unsigned int channel); + +/* common functions must be called in any mode */ +void free_dma(unsigned int channel); +int dma_channel_active(unsigned int channel); /* check if a channel is in use */ +void disable_dma(unsigned int channel); +void enable_dma(unsigned int channel); +int request_dma(unsigned int channel, char *device_id); +int set_dma_callback(unsigned int channel, dma_interrupt_t callback, + void *data); +void dma_disable_irq(unsigned int channel); +void dma_enable_irq(unsigned int channel); +void clear_dma_irqstat(unsigned int channel); +void *dma_memcpy(void *dest, const void *src, size_t count); +void *safe_dma_memcpy(void *dest, const void *src, size_t count); + +#endif diff --git a/include/asm-blackfin/dpmc.h b/include/asm-blackfin/dpmc.h new file mode 100644 index 000000000000..f162edb23033 --- /dev/null +++ b/include/asm-blackfin/dpmc.h @@ -0,0 +1,70 @@ +/* + * include/asm-blackfin/dpmc.h - Miscellaneous IOCTL commands for Dynamic Power + * Management Controller Driver. + * Copyright (C) 2004 Analog Device Inc. + * + */ +#ifndef _BLACKFIN_DPMC_H_ +#define _BLACKFIN_DPMC_H_ + +#define SLEEP_MODE 1 +#define DEEP_SLEEP_MODE 2 +#define ACTIVE_PLL_DISABLED 3 +#define FULLON_MODE 4 +#define ACTIVE_PLL_ENABLED 5 +#define HIBERNATE_MODE 6 + +#define IOCTL_FULL_ON_MODE _IO('s', 0xA0) +#define IOCTL_ACTIVE_MODE _IO('s', 0xA1) +#define IOCTL_SLEEP_MODE _IO('s', 0xA2) +#define IOCTL_DEEP_SLEEP_MODE _IO('s', 0xA3) +#define IOCTL_HIBERNATE_MODE _IO('s', 0xA4) +#define IOCTL_CHANGE_FREQUENCY _IOW('s', 0xA5, unsigned long) +#define IOCTL_CHANGE_VOLTAGE _IOW('s', 0xA6, unsigned long) +#define IOCTL_SET_CCLK _IOW('s', 0xA7, unsigned long) +#define IOCTL_SET_SCLK _IOW('s', 0xA8, unsigned long) +#define IOCTL_GET_PLLSTATUS _IOW('s', 0xA9, unsigned long) +#define IOCTL_GET_CORECLOCK _IOW('s', 0xAA, unsigned long) +#define IOCTL_GET_SYSTEMCLOCK _IOW('s', 0xAB, unsigned long) +#define IOCTL_GET_VCO _IOW('s', 0xAC, unsigned long) +#define IOCTL_DISABLE_WDOG_TIMER _IO('s', 0xAD) +#define IOCTL_UNMASK_WDOG_WAKEUP_EVENT _IO('s',0xAE) +#define IOCTL_PROGRAM_WDOG_TIMER _IOW('s',0xAF,unsigned long) +#define IOCTL_CLEAR_WDOG_WAKEUP_EVENT _IO('s',0xB0) +#define IOCTL_SLEEP_DEEPER_MODE _IO('s',0xB1) + +#define DPMC_MINOR 254 + +#define ON 0 +#define OFF 1 + +#ifdef __KERNEL__ + +unsigned long calc_volt(void); +int calc_vlev(int vlt); +unsigned long change_voltage(unsigned long volt); +int calc_msel(int vco_hz); +unsigned long change_frequency(unsigned long vco_mhz); +int set_pll_div(unsigned short sel, unsigned char flag); +int get_vco(void); +unsigned long change_system_clock(unsigned long clock); +unsigned long change_core_clock(unsigned long clock); +unsigned long get_pll_status(void); +void change_baud(int baud); +void fullon_mode(void); +void active_mode(void); +void sleep_mode(u32 sic_iwr); +void deep_sleep(u32 sic_iwr); +void hibernate_mode(u32 sic_iwr); +void sleep_deeper(u32 sic_iwr); +void program_wdog_timer(unsigned long); +void unmask_wdog_wakeup_evt(void); +void clear_wdog_wakeup_evt(void); +void disable_wdog_timer(void); + +extern unsigned long get_cclk(void); +extern unsigned long get_sclk(void); + +#endif /* __KERNEL__ */ + +#endif /*_BLACKFIN_DPMC_H_*/ diff --git a/include/asm-blackfin/elf.h b/include/asm-blackfin/elf.h new file mode 100644 index 000000000000..5264b5536a70 --- /dev/null +++ b/include/asm-blackfin/elf.h @@ -0,0 +1,127 @@ +/* Changes made by LG Soft Oct 2004*/ + +#ifndef __ASMBFIN_ELF_H +#define __ASMBFIN_ELF_H + +/* + * ELF register definitions.. + */ + +#include +#include + +/* Processor specific flags for the ELF header e_flags field. */ +#define EF_BFIN_PIC 0x00000001 /* -fpic */ +#define EF_BFIN_FDPIC 0x00000002 /* -mfdpic */ +#define EF_BFIN_CODE_IN_L1 0x00000010 /* --code-in-l1 */ +#define EF_BFIN_DATA_IN_L1 0x00000020 /* --data-in-l1 */ + +typedef unsigned long elf_greg_t; + +#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef struct user_bfinfp_struct elf_fpregset_t; +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ((x)->e_machine == EM_BLACKFIN) + +#define elf_check_fdpic(x) ((x)->e_flags & EF_BFIN_FDPIC /* && !((x)->e_flags & EF_FRV_NON_PIC_RELOCS) */) +#define elf_check_const_displacement(x) ((x)->e_flags & EF_BFIN_PIC) + +/* EM_BLACKFIN defined in linux/elf.h */ + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2LSB +#define ELF_ARCH EM_BLACKFIN + +#define ELF_PLAT_INIT(_r) _r->p1 = 0 + +#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map_addr, _interp_map_addr, _dynamic_addr) \ +do { \ + _regs->r7 = 0; \ + _regs->p0 = _exec_map_addr; \ + _regs->p1 = _interp_map_addr; \ + _regs->p2 = _dynamic_addr; \ +} while(0) + +#define USE_ELF_CORE_DUMP +#define ELF_FDPIC_CORE_EFLAGS EF_BFIN_FDPIC +#define ELF_EXEC_PAGESIZE 4096 + +#define R_unused0 0 /* relocation type 0 is not defined */ +#define R_pcrel5m2 1 /*LSETUP part a */ +#define R_unused1 2 /* relocation type 2 is not defined */ +#define R_pcrel10 3 /* type 3, if cc jump */ +#define R_pcrel12_jump 4 /* type 4, jump */ +#define R_rimm16 5 /* type 0x5, rN = */ +#define R_luimm16 6 /* # 0x6, preg.l= Load imm 16 to lower half */ +#define R_huimm16 7 /* # 0x7, preg.h= Load imm 16 to upper half */ +#define R_pcrel12_jump_s 8 /* # 0x8 jump.s */ +#define R_pcrel24_jump_x 9 /* # 0x9 jump.x */ +#define R_pcrel24 10 /* # 0xa call , not expandable */ +#define R_unusedb 11 /* # 0xb not generated */ +#define R_unusedc 12 /* # 0xc not used */ +#define R_pcrel24_jump_l 13 /*0xd jump.l */ +#define R_pcrel24_call_x 14 /* 0xE, call.x if is above 24 bit limit call through P1 */ +#define R_var_eq_symb 15 /* 0xf, linker should treat it same as 0x12 */ +#define R_byte_data 16 /* 0x10, .byte var = symbol */ +#define R_byte2_data 17 /* 0x11, .byte2 var = symbol */ +#define R_byte4_data 18 /* 0x12, .byte4 var = symbol and .var var=symbol */ +#define R_pcrel11 19 /* 0x13, lsetup part b */ +#define R_unused14 20 /* 0x14, undefined */ +#define R_unused15 21 /* not generated by VDSP 3.5 */ + +/* arithmetic relocations */ +#define R_push 0xE0 +#define R_const 0xE1 +#define R_add 0xE2 +#define R_sub 0xE3 +#define R_mult 0xE4 +#define R_div 0xE5 +#define R_mod 0xE6 +#define R_lshift 0xE7 +#define R_rshift 0xE8 +#define R_and 0xE9 +#define R_or 0xEA +#define R_xor 0xEB +#define R_land 0xEC +#define R_lor 0xED +#define R_len 0xEE +#define R_neg 0xEF +#define R_comp 0xF0 +#define R_page 0xF1 +#define R_hwpage 0xF2 +#define R_addr 0xF3 + +/* This is the location that an ET_DYN program is loaded if exec'ed. Typical + use of this is to invoke "./ld.so someprog" to test out a new version of + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +#define ELF_ET_DYN_BASE 0xD0000000UL + +#define ELF_CORE_COPY_REGS(pr_reg, regs) \ + memcpy((char *) &pr_reg, (char *)regs, \ + sizeof(struct pt_regs)); + +/* This yields a mask that user programs can use to figure out what + instruction set this cpu supports. */ + +#define ELF_HWCAP (0) + +/* This yields a string that ld.so will use to load implementation + specific libraries for optimization. This is more specific in + intent than poking at uname or /proc/cpuinfo. */ + +#define ELF_PLATFORM (NULL) + +#ifdef __KERNEL__ +#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) +#endif + +#endif diff --git a/include/asm-blackfin/emergency-restart.h b/include/asm-blackfin/emergency-restart.h new file mode 100644 index 000000000000..27f6c785d103 --- /dev/null +++ b/include/asm-blackfin/emergency-restart.h @@ -0,0 +1,6 @@ +#ifndef _ASM_EMERGENCY_RESTART_H +#define _ASM_EMERGENCY_RESTART_H + +#include + +#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/include/asm-blackfin/entry.h b/include/asm-blackfin/entry.h new file mode 100644 index 000000000000..562c6d3a3232 --- /dev/null +++ b/include/asm-blackfin/entry.h @@ -0,0 +1,56 @@ +#ifndef __BFIN_ENTRY_H +#define __BFIN_ENTRY_H + +#include +#include + +#ifdef __ASSEMBLY__ + +#define LFLUSH_I_AND_D 0x00000808 +#define LSIGTRAP 5 + +/* process bits for task_struct.flags */ +#define PF_TRACESYS_OFF 3 +#define PF_TRACESYS_BIT 5 +#define PF_PTRACED_OFF 3 +#define PF_PTRACED_BIT 4 +#define PF_DTRACE_OFF 1 +#define PF_DTRACE_BIT 5 + +/* This one is used for exceptions, emulation, and NMI. It doesn't push + RETI and doesn't do cli. */ +#define SAVE_ALL_SYS save_context_no_interrupts +/* This is used for all normal interrupts. It saves a minimum of registers + to the stack, loads the IRQ number, and jumps to common code. */ +#define INTERRUPT_ENTRY(N) \ + [--sp] = SYSCFG; \ + \ + [--sp] = P0; /*orig_p0*/ \ + [--sp] = R0; /*orig_r0*/ \ + [--sp] = (R7:0,P5:0); \ + R0 = (N); \ + jump __common_int_entry; + +/* For timer interrupts, we need to save IPEND, since the user_mode + macro accesses it to determine where to account time. */ +#define TIMER_INTERRUPT_ENTRY(N) \ + [--sp] = SYSCFG; \ + \ + [--sp] = P0; /*orig_p0*/ \ + [--sp] = R0; /*orig_r0*/ \ + [--sp] = (R7:0,P5:0); \ + p0.l = lo(IPEND); \ + p0.h = hi(IPEND); \ + r1 = [p0]; \ + R0 = (N); \ + jump __common_int_entry; + +/* This one pushes RETI without using CLI. Interrupts are enabled. */ +#define SAVE_CONTEXT_SYSCALL save_context_syscall +#define SAVE_CONTEXT save_context_with_interrupts + +#define RESTORE_ALL_SYS restore_context_no_interrupts +#define RESTORE_CONTEXT restore_context_with_interrupts + +#endif /* __ASSEMBLY__ */ +#endif /* __BFIN_ENTRY_H */ diff --git a/include/asm-blackfin/errno.h b/include/asm-blackfin/errno.h new file mode 100644 index 000000000000..164e4f39bb57 --- /dev/null +++ b/include/asm-blackfin/errno.h @@ -0,0 +1,6 @@ +#ifndef _BFIN_ERRNO_H +#define _BFIN_ERRNO_H + +#include + +#endif /* _BFIN_ERRNO_H */ diff --git a/include/asm-blackfin/fcntl.h b/include/asm-blackfin/fcntl.h new file mode 100644 index 000000000000..9c4037127857 --- /dev/null +++ b/include/asm-blackfin/fcntl.h @@ -0,0 +1,13 @@ +#ifndef _BFIN_FCNTL_H +#define _BFIN_FCNTL_H + +/* open/fcntl - O_SYNC is only implemented on blocks devices and on files + located on an ext2 file system */ +#define O_DIRECTORY 040000 /* must be a directory */ +#define O_NOFOLLOW 0100000 /* don't follow links */ +#define O_DIRECT 0200000 /* direct disk access hint - currently ignored */ +#define O_LARGEFILE 0400000 + +#include + +#endif diff --git a/include/asm-blackfin/flat.h b/include/asm-blackfin/flat.h new file mode 100644 index 000000000000..e70074e05f4e --- /dev/null +++ b/include/asm-blackfin/flat.h @@ -0,0 +1,58 @@ +/* + * include/asm-blackfin/flat.h -- uClinux flat-format executables + * + * Copyright (C) 2003, + * + */ + +#ifndef __BLACKFIN_FLAT_H__ +#define __BLACKFIN_FLAT_H__ + +#include + +#define flat_stack_align(sp) /* nothing needed */ +#define flat_argvp_envp_on_stack() 0 +#define flat_old_ram_flag(flags) (flags) + +extern unsigned long bfin_get_addr_from_rp (unsigned long *ptr, + unsigned long relval, + unsigned long flags, + unsigned long *persistent); + +extern void bfin_put_addr_at_rp(unsigned long *ptr, unsigned long addr, + unsigned long relval); + +/* The amount by which a relocation can exceed the program image limits + without being regarded as an error. */ + +#define flat_reloc_valid(reloc, size) ((reloc) <= (size)) + +#define flat_get_addr_from_rp(rp, relval, flags, persistent) \ + bfin_get_addr_from_rp(rp, relval, flags, persistent) +#define flat_put_addr_at_rp(rp, val, relval) \ + bfin_put_addr_at_rp(rp, val, relval) + +/* Convert a relocation entry into an address. */ +static inline unsigned long +flat_get_relocate_addr (unsigned long relval) +{ + return relval & 0x03ffffff; /* Mask out top 6 bits */ +} + +static inline int flat_set_persistent(unsigned long relval, + unsigned long *persistent) +{ + int type = (relval >> 26) & 7; + if (type == 3) { + *persistent = relval << 16; + return 1; + } + return 0; +} + +static inline int flat_addr_absolute(unsigned long relval) +{ + return (relval & (1 << 29)) != 0; +} + +#endif /* __BLACKFIN_FLAT_H__ */ diff --git a/include/asm-blackfin/futex.h b/include/asm-blackfin/futex.h new file mode 100644 index 000000000000..6a332a9f099c --- /dev/null +++ b/include/asm-blackfin/futex.h @@ -0,0 +1,6 @@ +#ifndef _ASM_FUTEX_H +#define _ASM_FUTEX_H + +#include + +#endif diff --git a/include/asm-blackfin/gpio.h b/include/asm-blackfin/gpio.h new file mode 100644 index 000000000000..d16fe3cd6135 --- /dev/null +++ b/include/asm-blackfin/gpio.h @@ -0,0 +1,367 @@ +/* + * File: arch/blackfin/kernel/bfin_gpio.h + * Based on: + * Author: Michael Hennerich (hennerich@blackfin.uclinux.org) + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* +* Number BF537/6/4 BF561 BF533/2/1 +* +* GPIO_0 PF0 PF0 PF0 +* GPIO_1 PF1 PF1 PF1 +* GPIO_2 PF2 PF2 PF2 +* GPIO_3 PF3 PF3 PF3 +* GPIO_4 PF4 PF4 PF4 +* GPIO_5 PF5 PF5 PF5 +* GPIO_6 PF6 PF6 PF6 +* GPIO_7 PF7 PF7 PF7 +* GPIO_8 PF8 PF8 PF8 +* GPIO_9 PF9 PF9 PF9 +* GPIO_10 PF10 PF10 PF10 +* GPIO_11 PF11 PF11 PF11 +* GPIO_12 PF12 PF12 PF12 +* GPIO_13 PF13 PF13 PF13 +* GPIO_14 PF14 PF14 PF14 +* GPIO_15 PF15 PF15 PF15 +* GPIO_16 PG0 PF16 +* GPIO_17 PG1 PF17 +* GPIO_18 PG2 PF18 +* GPIO_19 PG3 PF19 +* GPIO_20 PG4 PF20 +* GPIO_21 PG5 PF21 +* GPIO_22 PG6 PF22 +* GPIO_23 PG7 PF23 +* GPIO_24 PG8 PF24 +* GPIO_25 PG9 PF25 +* GPIO_26 PG10 PF26 +* GPIO_27 PG11 PF27 +* GPIO_28 PG12 PF28 +* GPIO_29 PG13 PF29 +* GPIO_30 PG14 PF30 +* GPIO_31 PG15 PF31 +* GPIO_32 PH0 PF32 +* GPIO_33 PH1 PF33 +* GPIO_34 PH2 PF34 +* GPIO_35 PH3 PF35 +* GPIO_36 PH4 PF36 +* GPIO_37 PH5 PF37 +* GPIO_38 PH6 PF38 +* GPIO_39 PH7 PF39 +* GPIO_40 PH8 PF40 +* GPIO_41 PH9 PF41 +* GPIO_42 PH10 PF42 +* GPIO_43 PH11 PF43 +* GPIO_44 PH12 PF44 +* GPIO_45 PH13 PF45 +* GPIO_46 PH14 PF46 +* GPIO_47 PH15 PF47 +*/ + +#ifndef __ARCH_BLACKFIN_GPIO_H__ +#define __ARCH_BLACKFIN_GPIO_H__ + +#define gpio_bank(x) ((x) >> 4) +#define gpio_bit(x) (1<<((x) & 0xF)) +#define gpio_sub_n(x) ((x) & 0xF) + +#define GPIO_BANKSIZE 16 + +#define GPIO_0 0 +#define GPIO_1 1 +#define GPIO_2 2 +#define GPIO_3 3 +#define GPIO_4 4 +#define GPIO_5 5 +#define GPIO_6 6 +#define GPIO_7 7 +#define GPIO_8 8 +#define GPIO_9 9 +#define GPIO_10 10 +#define GPIO_11 11 +#define GPIO_12 12 +#define GPIO_13 13 +#define GPIO_14 14 +#define GPIO_15 15 +#define GPIO_16 16 +#define GPIO_17 17 +#define GPIO_18 18 +#define GPIO_19 19 +#define GPIO_20 20 +#define GPIO_21 21 +#define GPIO_22 22 +#define GPIO_23 23 +#define GPIO_24 24 +#define GPIO_25 25 +#define GPIO_26 26 +#define GPIO_27 27 +#define GPIO_28 28 +#define GPIO_29 29 +#define GPIO_30 30 +#define GPIO_31 31 +#define GPIO_32 32 +#define GPIO_33 33 +#define GPIO_34 34 +#define GPIO_35 35 +#define GPIO_36 36 +#define GPIO_37 37 +#define GPIO_38 38 +#define GPIO_39 39 +#define GPIO_40 40 +#define GPIO_41 41 +#define GPIO_42 42 +#define GPIO_43 43 +#define GPIO_44 44 +#define GPIO_45 45 +#define GPIO_46 46 +#define GPIO_47 47 + + +#define PERIPHERAL_USAGE 1 +#define GPIO_USAGE 0 + +#ifdef BF533_FAMILY +#define MAX_BLACKFIN_GPIOS 16 +#endif + +#ifdef BF537_FAMILY +#define MAX_BLACKFIN_GPIOS 48 +#define PORT_F 0 +#define PORT_G 1 +#define PORT_H 2 +#define PORT_J 3 + +#define GPIO_PF0 0 +#define GPIO_PF1 1 +#define GPIO_PF2 2 +#define GPIO_PF3 3 +#define GPIO_PF4 4 +#define GPIO_PF5 5 +#define GPIO_PF6 6 +#define GPIO_PF7 7 +#define GPIO_PF8 8 +#define GPIO_PF9 9 +#define GPIO_PF10 10 +#define GPIO_PF11 11 +#define GPIO_PF12 12 +#define GPIO_PF13 13 +#define GPIO_PF14 14 +#define GPIO_PF15 15 +#define GPIO_PG0 16 +#define GPIO_PG1 17 +#define GPIO_PG2 18 +#define GPIO_PG3 19 +#define GPIO_PG4 20 +#define GPIO_PG5 21 +#define GPIO_PG6 22 +#define GPIO_PG7 23 +#define GPIO_PG8 24 +#define GPIO_PG9 25 +#define GPIO_PG10 26 +#define GPIO_PG11 27 +#define GPIO_PG12 28 +#define GPIO_PG13 29 +#define GPIO_PG14 30 +#define GPIO_PG15 31 +#define GPIO_PH0 32 +#define GPIO_PH1 33 +#define GPIO_PH2 34 +#define GPIO_PH3 35 +#define GPIO_PH4 36 +#define GPIO_PH5 37 +#define GPIO_PH6 38 +#define GPIO_PH7 39 +#define GPIO_PH8 40 +#define GPIO_PH9 41 +#define GPIO_PH10 42 +#define GPIO_PH11 43 +#define GPIO_PH12 44 +#define GPIO_PH13 45 +#define GPIO_PH14 46 +#define GPIO_PH15 47 + +#endif + +#ifdef BF561_FAMILY +#define MAX_BLACKFIN_GPIOS 48 +#define PORT_FIO0 0 +#define PORT_FIO1 1 +#define PORT_FIO2 2 +#endif + +#ifndef __ASSEMBLY__ + +/*********************************************************** +* +* FUNCTIONS: Blackfin General Purpose Ports Access Functions +* +* INPUTS/OUTPUTS: +* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS +* +* +* DESCRIPTION: These functions abstract direct register access +* to Blackfin processor General Purpose +* Ports Regsiters +* +* CAUTION: These functions do not belong to the GPIO Driver API +************************************************************* +* MODIFICATION HISTORY : +**************************************************************/ + +void set_gpio_dir(unsigned short, unsigned short); +void set_gpio_inen(unsigned short, unsigned short); +void set_gpio_polar(unsigned short, unsigned short); +void set_gpio_edge(unsigned short, unsigned short); +void set_gpio_both(unsigned short, unsigned short); +void set_gpio_data(unsigned short, unsigned short); +void set_gpio_maska(unsigned short, unsigned short); +void set_gpio_maskb(unsigned short, unsigned short); +void set_gpio_toggle(unsigned short); +void set_gpiop_dir(unsigned short, unsigned short); +void set_gpiop_inen(unsigned short, unsigned short); +void set_gpiop_polar(unsigned short, unsigned short); +void set_gpiop_edge(unsigned short, unsigned short); +void set_gpiop_both(unsigned short, unsigned short); +void set_gpiop_data(unsigned short, unsigned short); +void set_gpiop_maska(unsigned short, unsigned short); +void set_gpiop_maskb(unsigned short, unsigned short); +unsigned short get_gpio_dir(unsigned short); +unsigned short get_gpio_inen(unsigned short); +unsigned short get_gpio_polar(unsigned short); +unsigned short get_gpio_edge(unsigned short); +unsigned short get_gpio_both(unsigned short); +unsigned short get_gpio_maska(unsigned short); +unsigned short get_gpio_maskb(unsigned short); +unsigned short get_gpio_data(unsigned short); +unsigned short get_gpiop_dir(unsigned short); +unsigned short get_gpiop_inen(unsigned short); +unsigned short get_gpiop_polar(unsigned short); +unsigned short get_gpiop_edge(unsigned short); +unsigned short get_gpiop_both(unsigned short); +unsigned short get_gpiop_maska(unsigned short); +unsigned short get_gpiop_maskb(unsigned short); +unsigned short get_gpiop_data(unsigned short); + +struct gpio_port_t { + unsigned short data; + unsigned short dummy1; + unsigned short data_clear; + unsigned short dummy2; + unsigned short data_set; + unsigned short dummy3; + unsigned short toggle; + unsigned short dummy4; + unsigned short maska; + unsigned short dummy5; + unsigned short maska_clear; + unsigned short dummy6; + unsigned short maska_set; + unsigned short dummy7; + unsigned short maska_toggle; + unsigned short dummy8; + unsigned short maskb; + unsigned short dummy9; + unsigned short maskb_clear; + unsigned short dummy10; + unsigned short maskb_set; + unsigned short dummy11; + unsigned short maskb_toggle; + unsigned short dummy12; + unsigned short dir; + unsigned short dummy13; + unsigned short polar; + unsigned short dummy14; + unsigned short edge; + unsigned short dummy15; + unsigned short both; + unsigned short dummy16; + unsigned short inen; +}; + +#ifdef CONFIG_PM +#define PM_WAKE_RISING 0x1 +#define PM_WAKE_FALLING 0x2 +#define PM_WAKE_HIGH 0x4 +#define PM_WAKE_LOW 0x8 +#define PM_WAKE_BOTH_EDGES (PM_WAKE_RISING | PM_WAKE_FALLING) + +int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type); +void gpio_pm_wakeup_free(unsigned short gpio); +unsigned int gpio_pm_setup(void); +void gpio_pm_restore(void); + +struct gpio_port_s { + unsigned short data; + unsigned short data_clear; + unsigned short data_set; + unsigned short toggle; + unsigned short maska; + unsigned short maska_clear; + unsigned short maska_set; + unsigned short maska_toggle; + unsigned short maskb; + unsigned short maskb_clear; + unsigned short maskb_set; + unsigned short maskb_toggle; + unsigned short dir; + unsigned short polar; + unsigned short edge; + unsigned short both; + unsigned short inen; + + unsigned short fer; +}; +#endif /*CONFIG_PM*/ + +/*********************************************************** +* +* FUNCTIONS: Blackfin GPIO Driver +* +* INPUTS/OUTPUTS: +* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS +* +* +* DESCRIPTION: Blackfin GPIO Driver API +* +* CAUTION: +************************************************************* +* MODIFICATION HISTORY : +**************************************************************/ + +int gpio_request(unsigned short, const char *); +void gpio_free(unsigned short); + +void gpio_set_value(unsigned short gpio, unsigned short arg); +unsigned short gpio_get_value(unsigned short gpio); + +#define gpio_get_value(gpio) get_gpio_data(gpio) +#define gpio_set_value(gpio, value) set_gpio_data(gpio, value) + +void gpio_direction_input(unsigned short gpio); +void gpio_direction_output(unsigned short gpio); + +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_BLACKFIN_GPIO_H__ */ diff --git a/include/asm-blackfin/hardirq.h b/include/asm-blackfin/hardirq.h new file mode 100644 index 000000000000..0cab0d35badc --- /dev/null +++ b/include/asm-blackfin/hardirq.h @@ -0,0 +1,41 @@ +#ifndef __BFIN_HARDIRQ_H +#define __BFIN_HARDIRQ_H + +#include +#include +#include + +typedef struct { + unsigned int __softirq_pending; + unsigned int __syscall_count; + struct task_struct *__ksoftirqd_task; +} ____cacheline_aligned irq_cpustat_t; + +#include /* Standard mappings for irq_cpustat_t above */ + +/* + * We put the hardirq and softirq counter into the preemption + * counter. The bitmask has the following meaning: + * + * - bits 0-7 are the preemption count (max preemption depth: 256) + * - bits 8-15 are the softirq count (max # of softirqs: 256) + * - bits 16-23 are the hardirq count (max # of hardirqs: 256) + * + * - ( bit 26 is the PREEMPT_ACTIVE flag. ) + * + * PREEMPT_MASK: 0x000000ff + * HARDIRQ_MASK: 0x0000ff00 + * SOFTIRQ_MASK: 0x00ff0000 + */ + +#define HARDIRQ_BITS 8 + +#ifdef NR_IRQS +# if (1 << HARDIRQ_BITS) < NR_IRQS +# error HARDIRQ_BITS is too low! +# endif +#endif + +#define __ARCH_IRQ_EXIT_IRQS_DISABLED 1 + +#endif diff --git a/include/asm-blackfin/hw_irq.h b/include/asm-blackfin/hw_irq.h new file mode 100644 index 000000000000..5b51eaec012c --- /dev/null +++ b/include/asm-blackfin/hw_irq.h @@ -0,0 +1,6 @@ +#ifndef __ASM_BFIN_HW_IRQ_H +#define __ASM_BFIN_HW_IRQ_H + +/* Dummy include. */ + +#endif diff --git a/include/asm-blackfin/ide.h b/include/asm-blackfin/ide.h new file mode 100644 index 000000000000..41b2db46a168 --- /dev/null +++ b/include/asm-blackfin/ide.h @@ -0,0 +1,32 @@ +/****************************************************************************/ + +/* + * linux/include/asm-blackfin/ide.h + * + * Copyright (C) 1994-1996 Linus Torvalds & authors + * Copyright (C) 2001 Lineo Inc., davidm@snapgear.com + * Copyright (C) 2002 Greg Ungerer (gerg@snapgear.com) + * Copyright (C) 2002 Yoshinori Sato (ysato@users.sourceforge.jp) + * Copyright (C) 2005 Hennerich Michael (hennerich@blackfin.uclinux.org) + */ + +/****************************************************************************/ +#ifndef _BLACKFIN_IDE_H +#define _BLACKFIN_IDE_H +/****************************************************************************/ +#ifdef __KERNEL__ +/****************************************************************************/ + +#define MAX_HWIFS 1 + +/* Legacy ... BLK_DEV_IDECS */ +#define IDE_ARCH_OBSOLETE_INIT +#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */ + + +#include + +/****************************************************************************/ +#endif /* __KERNEL__ */ +#endif /* _BLACKFIN_IDE_H */ +/****************************************************************************/ diff --git a/include/asm-blackfin/io.h b/include/asm-blackfin/io.h new file mode 100644 index 000000000000..7e6995e80d97 --- /dev/null +++ b/include/asm-blackfin/io.h @@ -0,0 +1,207 @@ +#ifndef _BFIN_IO_H +#define _BFIN_IO_H + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ +#include +#endif +#include + +/* + * These are for ISA/PCI shared memory _only_ and should never be used + * on any other type of memory, including Zorro memory. They are meant to + * access the bus in the bus byte order which is little-endian!. + * + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the bfin architecture, we just read/write the + * memory location directly. + */ +#ifndef __ASSEMBLY__ + +static inline unsigned char readb(void __iomem *addr) +{ + unsigned int val; + int tmp; + + __asm__ __volatile__ ("cli %1;\n\t" + "NOP; NOP; SSYNC;\n\t" + "%0 = b [%2] (z);\n\t" + "sti %1;\n\t" + : "=d"(val), "=d"(tmp): "a"(addr) + ); + + return (unsigned char) val; +} + +static inline unsigned short readw(void __iomem *addr) +{ + unsigned int val; + int tmp; + + __asm__ __volatile__ ("cli %1;\n\t" + "NOP; NOP; SSYNC;\n\t" + "%0 = w [%2] (z);\n\t" + "sti %1;\n\t" + : "=d"(val), "=d"(tmp): "a"(addr) + ); + + return (unsigned short) val; +} + +static inline unsigned int readl(void __iomem *addr) +{ + unsigned int val; + int tmp; + + __asm__ __volatile__ ("cli %1;\n\t" + "NOP; NOP; SSYNC;\n\t" + "%0 = [%2];\n\t" + "sti %1;\n\t" + : "=d"(val), "=d"(tmp): "a"(addr) + ); + return val; +} + +#endif /* __ASSEMBLY__ */ + +#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b)) +#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b)) +#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b)) + +#define __raw_readb readb +#define __raw_readw readw +#define __raw_readl readl +#define __raw_writeb writeb +#define __raw_writew writew +#define __raw_writel writel +#define memset_io(a,b,c) memset((void *)(a),(b),(c)) +#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) +#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) + +#define inb(addr) readb(addr) +#define inw(addr) readw(addr) +#define inl(addr) readl(addr) +#define outb(x,addr) ((void) writeb(x,addr)) +#define outw(x,addr) ((void) writew(x,addr)) +#define outl(x,addr) ((void) writel(x,addr)) + +#define inb_p(addr) inb(addr) +#define inw_p(addr) inw(addr) +#define inl_p(addr) inl(addr) +#define outb_p(x,addr) outb(x,addr) +#define outw_p(x,addr) outw(x,addr) +#define outl_p(x,addr) outl(x,addr) + +#define ioread8_rep(a,d,c) insb(a,d,c) +#define ioread16_rep(a,d,c) insw(a,d,c) +#define ioread32_rep(a,d,c) insl(a,d,c) +#define iowrite8_rep(a,s,c) outsb(a,s,c) +#define iowrite16_rep(a,s,c) outsw(a,s,c) +#define iowrite32_rep(a,s,c) outsl(a,s,c) + +#define ioread8(X) readb(X) +#define ioread16(X) readw(X) +#define ioread32(X) readl(X) +#define iowrite8(val,X) writeb(val,X) +#define iowrite16(val,X) writew(val,X) +#define iowrite32(val,X) writel(val,X) + +#define IO_SPACE_LIMIT 0xffffffff + +/* Values for nocacheflag and cmode */ +#define IOMAP_NOCACHE_SER 1 + +#ifndef __ASSEMBLY__ + +extern void outsb(void __iomem *port, const void *addr, unsigned long count); +extern void outsw(void __iomem *port, const void *addr, unsigned long count); +extern void outsl(void __iomem *port, const void *addr, unsigned long count); + +extern void insb(const void __iomem *port, void *addr, unsigned long count); +extern void insw(const void __iomem *port, void *addr, unsigned long count); +extern void insl(const void __iomem *port, void *addr, unsigned long count); + +/* + * Map some physical address range into the kernel address space. + */ +static inline void __iomem *__ioremap(unsigned long physaddr, unsigned long size, + int cacheflag) +{ + return (void __iomem *)physaddr; +} + +/* + * Unmap a ioremap()ed region again + */ +static inline void iounmap(void *addr) +{ +} + +/* + * __iounmap unmaps nearly everything, so be careful + * it doesn't free currently pointer/page tables anymore but it + * wans't used anyway and might be added later. + */ +static inline void __iounmap(void *addr, unsigned long size) +{ +} + +/* + * Set new cache mode for some kernel address space. + * The caller must push data for that range itself, if such data may already + * be in the cache. + */ +static inline void kernel_set_cachemode(void *addr, unsigned long size, + int cmode) +{ +} + +static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} +static inline void __iomem *ioremap_nocache(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} + +extern void blkfin_inv_cache_all(void); + +#endif + +#define ioport_map(port, nr) ((void __iomem*)(port)) +#define ioport_unmap(addr) + +#define dma_cache_inv(_start,_size) do { blkfin_inv_cache_all();} while (0) +#define dma_cache_wback(_start,_size) do { } while (0) +#define dma_cache_wback_inv(_start,_size) do { blkfin_inv_cache_all();} while (0) + +/* Pages to physical address... */ +#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) +#define page_to_bus(page) ((page - mem_map) << PAGE_SHIFT) + +#define mm_ptov(vaddr) ((void *) (vaddr)) +#define mm_vtop(vaddr) ((unsigned long) (vaddr)) +#define phys_to_virt(vaddr) ((void *) (vaddr)) +#define virt_to_phys(vaddr) ((unsigned long) (vaddr)) + +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + +/* + * Convert a physical pointer to a virtual kernel pointer for /dev/mem + * access + */ +#define xlate_dev_mem_ptr(p) __va(p) + +/* + * Convert a virtual cached pointer to an uncached pointer + */ +#define xlate_dev_kmem_ptr(p) p + +#endif /* __KERNEL__ */ + +#endif /* _BFIN_IO_H */ diff --git a/include/asm-blackfin/ioctl.h b/include/asm-blackfin/ioctl.h new file mode 100644 index 000000000000..b279fe06dfe5 --- /dev/null +++ b/include/asm-blackfin/ioctl.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-blackfin/ioctls.h b/include/asm-blackfin/ioctls.h new file mode 100644 index 000000000000..8356204151db --- /dev/null +++ b/include/asm-blackfin/ioctls.h @@ -0,0 +1,82 @@ +#ifndef __ARCH_BFIN_IOCTLS_H__ +#define __ARCH_BFIN_IOCTLS_H__ + +#include + +/* 0x54 is just a magic number to make these relatively unique ('T') */ + +#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ +#define TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ +#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ + +#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ +#define FIOCLEX 0x5451 +#define FIOASYNC 0x5452 +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +#define FIOQSIZE 0x545E + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +#endif /* __ARCH_BFIN_IOCTLS_H__ */ diff --git a/include/asm-blackfin/ipc.h b/include/asm-blackfin/ipc.h new file mode 100644 index 000000000000..a46e3d9c2a3f --- /dev/null +++ b/include/asm-blackfin/ipc.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-blackfin/ipcbuf.h b/include/asm-blackfin/ipcbuf.h new file mode 100644 index 000000000000..8f0899cdf4d2 --- /dev/null +++ b/include/asm-blackfin/ipcbuf.h @@ -0,0 +1,30 @@ +/* Changes origined from m68k version. Lineo Inc. May 2001 */ + +#ifndef __BFIN_IPCBUF_H__ +#define __BFIN_IPCBUF_H__ + +/* + * The user_ipc_perm structure for m68k architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 32-bit mode_t and seq + * - 2 miscellaneous 32-bit values + */ + +struct ipc64_perm { + __kernel_key_t key; + __kernel_uid32_t uid; + __kernel_gid32_t gid; + __kernel_uid32_t cuid; + __kernel_gid32_t cgid; + __kernel_mode_t mode; + unsigned short __pad1; + unsigned short seq; + unsigned short __pad2; + unsigned long __unused1; + unsigned long __unused2; +}; + +#endif /* __BFIN_IPCBUF_H__ */ diff --git a/include/asm-blackfin/irq.h b/include/asm-blackfin/irq.h new file mode 100644 index 000000000000..65480dab244e --- /dev/null +++ b/include/asm-blackfin/irq.h @@ -0,0 +1,70 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Changed by HuTao Apr18, 2003 + * + * Copyright was missing when I got the code so took from MIPS arch ...MaTed--- + * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle + * Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001 by Ralf Baechle + * + * Adapted for BlackFin (ADI) by Ted Ma + * Copyright (c) 2002 Arcturus Networks Inc. (www.arcturusnetworks.com) + * Copyright (c) 2002 Lineo, Inc. + */ + +#ifndef _BFIN_IRQ_H_ +#define _BFIN_IRQ_H_ + +#include +#include + +/******************************************************************************* + ***** INTRODUCTION *********** + * On the Blackfin, the interrupt structure allows remmapping of the hardware + * levels. + * - I'm going to assume that the H/W level is going to stay at the default + * settings. If someone wants to go through and abstart this out, feel free + * to mod the interrupt numbering scheme. + * - I'm abstracting the interrupts so that uClinux does not know anything + * about the H/W levels. If you want to change the H/W AND keep the abstracted + * levels that uClinux sees, you should be able to do most of it here. + * - I've left the "abstract" numbering sparce in case someone wants to pull the + * interrupts apart (just the TX/RX for the various devices) + *******************************************************************************/ + +/* SYS_IRQS and NR_IRQS are defined in */ + +/* + * Machine specific interrupt sources. + * + * Adding an interrupt service routine for a source with this bit + * set indicates a special machine specific interrupt source. + * The machine specific files define these sources. + * + * The IRQ_MACHSPEC bit is now gone - the only thing it did was to + * introduce unnecessary overhead. + * + * All interrupt handling is actually machine specific so it is better + * to use function pointers, as used by the Sparc port, and select the + * interrupt handling functions when initializing the kernel. This way + * we save some unnecessary overhead at run-time. + * 01/11/97 - Jes + */ + +extern void ack_bad_irq(unsigned int irq); + +static __inline__ int irq_canonicalize(int irq) +{ + return irq; +} + +/* count of spurious interrupts */ +/* extern volatile unsigned int num_spurious; */ + +#ifndef NO_IRQ +#define NO_IRQ ((unsigned int)(-1)) +#endif + +#endif /* _BFIN_IRQ_H_ */ diff --git a/include/asm-blackfin/irq_handler.h b/include/asm-blackfin/irq_handler.h new file mode 100644 index 000000000000..d830f0a49a1c --- /dev/null +++ b/include/asm-blackfin/irq_handler.h @@ -0,0 +1,22 @@ +#ifndef _IRQ_HANDLER_H +#define _IRQ_HANDLER_H + +/* BASE LEVEL interrupt handler routines */ +asmlinkage void evt_emulation(void); +asmlinkage void evt_exception(void); +asmlinkage void trap(void); +asmlinkage void evt_ivhw(void); +asmlinkage void evt_timer(void); +asmlinkage void evt_evt2(void); +asmlinkage void evt_evt7(void); +asmlinkage void evt_evt8(void); +asmlinkage void evt_evt9(void); +asmlinkage void evt_evt10(void); +asmlinkage void evt_evt11(void); +asmlinkage void evt_evt12(void); +asmlinkage void evt_evt13(void); +asmlinkage void evt_soft_int1(void); +asmlinkage void evt_system_call(void); +asmlinkage void init_exception_buff(void); + +#endif diff --git a/include/asm-blackfin/irq_regs.h b/include/asm-blackfin/irq_regs.h new file mode 100644 index 000000000000..3dd9c0b70270 --- /dev/null +++ b/include/asm-blackfin/irq_regs.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-blackfin/kdebug.h b/include/asm-blackfin/kdebug.h new file mode 100644 index 000000000000..6ece1b037665 --- /dev/null +++ b/include/asm-blackfin/kdebug.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-blackfin/kmap_types.h b/include/asm-blackfin/kmap_types.h new file mode 100644 index 000000000000..e215f7104974 --- /dev/null +++ b/include/asm-blackfin/kmap_types.h @@ -0,0 +1,21 @@ +#ifndef _ASM_KMAP_TYPES_H +#define _ASM_KMAP_TYPES_H + +enum km_type { + KM_BOUNCE_READ, + KM_SKB_SUNRPC_DATA, + KM_SKB_DATA_SOFTIRQ, + KM_USER0, + KM_USER1, + KM_BIO_SRC_IRQ, + KM_BIO_DST_IRQ, + KM_PTE0, + KM_PTE1, + KM_IRQ0, + KM_IRQ1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, + KM_TYPE_NR +}; + +#endif diff --git a/include/asm-blackfin/l1layout.h b/include/asm-blackfin/l1layout.h new file mode 100644 index 000000000000..c13ded777828 --- /dev/null +++ b/include/asm-blackfin/l1layout.h @@ -0,0 +1,31 @@ +/* + * l1layout.h + * Defines a layout of L1 scratchpad memory that userspace can rely on. + */ + +#ifndef _L1LAYOUT_H_ +#define _L1LAYOUT_H_ + +#include + +#ifndef __ASSEMBLY__ + +/* Data that is "mapped" into the process VM at the start of the L1 scratch + memory, so that each process can access it at a fixed address. Used for + stack checking. */ +struct l1_scratch_task_info +{ + /* Points to the start of the stack. */ + void *stack_start; + /* Not updated by the kernel; a user process can modify this to + keep track of the lowest address of the stack pointer during its + runtime. */ + void *lowest_sp; +}; + +/* A pointer to the structure in memory. */ +#define L1_SCRATCH_TASK_INFO ((struct l1_scratch_task_info *)L1_SCRATCH_START) + +#endif + +#endif diff --git a/include/asm-blackfin/linkage.h b/include/asm-blackfin/linkage.h new file mode 100644 index 000000000000..5a822bb790f7 --- /dev/null +++ b/include/asm-blackfin/linkage.h @@ -0,0 +1,7 @@ +#ifndef __ASM_LINKAGE_H +#define __ASM_LINKAGE_H + +#define __ALIGN .align 4 +#define __ALIGN_STR ".align 4" + +#endif diff --git a/include/asm-blackfin/local.h b/include/asm-blackfin/local.h new file mode 100644 index 000000000000..75afffbc6421 --- /dev/null +++ b/include/asm-blackfin/local.h @@ -0,0 +1,6 @@ +#ifndef __BLACKFIN_LOCAL_H +#define __BLACKFIN_LOCAL_H + +#include + +#endif /* __BLACKFIN_LOCAL_H */ diff --git a/include/asm-blackfin/mach-bf533/anomaly.h b/include/asm-blackfin/mach-bf533/anomaly.h new file mode 100644 index 000000000000..a84d3909345e --- /dev/null +++ b/include/asm-blackfin/mach-bf533/anomaly.h @@ -0,0 +1,175 @@ +/* + * File: include/asm-blackfin/mach-bf533/anomaly.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Rev: + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* This file shoule be up to date with: + * - Revision U, May 17, 2006; ADSP-BF533 Blackfin Processor Anomaly List + * - Revision Y, May 17, 2006; ADSP-BF532 Blackfin Processor Anomaly List + * - Revision T, May 17, 2006; ADSP-BF531 Blackfin Processor Anomaly List + */ + +#ifndef _MACH_ANOMALY_H_ +#define _MACH_ANOMALY_H_ + +/* We do not support 0.1 or 0.2 silicon - sorry */ +#if (defined(CONFIG_BF_REV_0_1) || defined(CONFIG_BF_REV_0_2)) +#error Kernel will not work on BF533 Version 0.1 or 0.2 +#endif + +/* Issues that are common to 0.5, 0.4, and 0.3 silicon */ +#if (defined(CONFIG_BF_REV_0_5) || defined(CONFIG_BF_REV_0_4) || defined(CONFIG_BF_REV_0_3)) +#define ANOMALY_05000074 /* A multi issue instruction with dsp32shiftimm in + slot1 and store of a P register in slot 2 is not + supported */ +#define ANOMALY_05000105 /* Watchpoint Status Register (WPSTAT) bits are set on + every corresponding match */ +#define ANOMALY_05000119 /* DMA_RUN bit is not valid after a Peripheral Receive + Channel DMA stops */ +#define ANOMALY_05000122 /* Rx.H can not be used to access 16-bit System MMR + registers. */ +#define ANOMALY_05000166 /* PPI Data Lengths Between 8 and 16 do not zero out + upper bits*/ +#define ANOMALY_05000167 /* Turning Serial Ports on With External Frame Syncs */ +#define ANOMALY_05000180 /* PPI_DELAY not functional in PPI modes with 0 frame + syncs */ +#define ANOMALY_05000208 /* VSTAT status bit in PLL_STAT register is not + functional */ +#define ANOMALY_05000219 /* NMI event at boot time results in unpredictable + state */ +#define ANOMALY_05000229 /* SPI Slave Boot Mode modifies registers */ +#define ANOMALY_05000272 /* Certain data cache write through modes fail for + VDDint <=0.9V */ +#define ANOMALY_05000273 /* Writes to Synchronous SDRAM memory may be lost */ +#define ANOMALY_05000277 /* Writes to a flag data register one SCLK cycle after + an edge is detected may clear interrupt */ +#define ANOMALY_05000278 /* Disabling Peripherals with DMA running may cause + DMA system instability */ +#define ANOMALY_05000281 /* False Hardware Error Exception when ISR context is + not restored */ +#define ANOMALY_05000282 /* Memory DMA corruption with 32-bit data and traffic + control */ +#define ANOMALY_05000283 /* A system MMR write is stalled indefinitely when + killed in a particular stage*/ +#define ANOMALY_05000312 /* Errors when SSYNC, CSYNC, or loads to LT, LB and LC + registers are interrupted */ +#define ANOMALY_05000311 /* Erroneous flag pin operations under specific sequences*/ + +#endif + +/* These issues only occur on 0.3 or 0.4 BF533 */ +#if (defined(CONFIG_BF_REV_0_4) || defined(CONFIG_BF_REV_0_3)) +#define ANOMALY_05000099 /* UART Line Status Register (UART_LSR) bits are not + updated at the same time. */ +#define ANOMALY_05000158 /* Boot fails when data cache enabled: Data from a Data + Cache Fill can be corrupted after or during + Instruction DMA if certain core stalls exist */ +#define ANOMALY_05000179 /* PPI_COUNT cannot be programmed to 0 in General + Purpose TX or RX modes */ +#define ANOMALY_05000198 /* Failing SYSTEM MMR accesses when stalled by + preceding memory read */ +#define ANOMALY_05000200 /* SPORT TFS and DT are incorrectly driven during + inactive channels in certain conditions */ +#define ANOMALY_05000202 /* Possible infinite stall with specific dual dag + situation */ +#define ANOMALY_05000215 /* UART TX Interrupt masked erroneously */ +#define ANOMALY_05000225 /* Incorrect pulse-width of UART start-bit */ +#define ANOMALY_05000227 /* Scratchpad memory bank reads may return incorrect + data*/ +#define ANOMALY_05000230 /* UART Receiver is less robust against Baudrate + Differences in certain Conditions */ +#define ANOMALY_05000231 /* UART STB bit incorrectly affects receiver setting */ +#define ANOMALY_05000242 /* DF bit in PLL_CTL register does not respond to + hardware reset */ +#define ANOMALY_05000244 /* With instruction cache enabled, a CSYNC or SSYNC or + IDLE around a Change of Control causes + unpredictable results */ +#define ANOMALY_05000245 /* Spurious Hardware Error from an access in the + shadow of a conditional branch */ +#define ANOMALY_05000246 /* Data CPLB's should prevent spurious hardware + errors */ +#define ANOMALY_05000253 /* Maximum external clock speed for Timers */ +#define ANOMALY_05000255 /* Entering Hibernate Mode with RTC Seconds event + interrupt not functional */ +#define ANOMALY_05000257 /* An interrupt or exception during short Hardware + loops may cause the instruction fetch unit to + malfunction */ +#define ANOMALY_05000258 /* Instruction Cache is corrupted when bit 9 and 12 of + the ICPLB Data registers differ */ +#define ANOMALY_05000260 /* ICPLB_STATUS MMR register may be corrupted */ +#define ANOMALY_05000261 /* DCPLB_FAULT_ADDR MMR register may be corrupted */ +#define ANOMALY_05000262 /* Stores to data cache may be lost */ +#define ANOMALY_05000263 /* Hardware loop corrupted when taking an ICPLB exception */ +#define ANOMALY_05000264 /* A Sync instruction (CSYNC, SSYNC) or an IDLE + instruction will cause an infinite stall in the + second to last instruction in a hardware loop */ +#define ANOMALY_05000265 /* Sensitivity to noise with slow input edge rates on + SPORT external receive and transmit clocks. */ +#define ANOMALY_05000269 /* High I/O activity causes the output voltage of the + internal voltage regulator (VDDint) to increase. */ +#define ANOMALY_05000270 /* High I/O activity causes the output voltage of the + internal voltage regulator (VDDint) to decrease */ +#endif + +/* These issues are only on 0.4 silicon */ +#if (defined(CONFIG_BF_REV_0_4)) +#define ANOMALY_05000234 /* Incorrect Revision Number in DSPID Register */ +#define ANOMALY_05000250 /* Incorrect Bit-Shift of Data Word in Multichannel + (TDM) */ +#endif + +/* These issues are only on 0.3 silicon */ +#if defined(CONFIG_BF_REV_0_3) +#define ANOMALY_05000183 /* Timer Pin limitations for PPI TX Modes with + External Frame Syncs */ +#define ANOMALY_05000189 /* False Protection Exceptions caused by Speculative + Instruction or Data Fetches, or by Fetches at the + boundary of reserved memory space */ +#define ANOMALY_05000193 /* False Flag Pin Interrupts on Edge Sensitive Inputs + when polarity setting is changed */ +#define ANOMALY_05000194 /* Sport Restarting in specific modes may cause data + corruption */ +#define ANOMALY_05000199 /* DMA current address shows wrong value during carry + fix */ +#define ANOMALY_05000201 /* Receive frame sync not ignored during active + frames in sport MCM */ +#define ANOMALY_05000203 /* Specific sequence that can cause DMA error or DMA + stopping */ +#if defined(CONFIG_BF533) +#define ANOMALY_05000204 /* Incorrect data read with write-through cache and + allocate cache lines on reads only mode */ +#endif /* CONFIG_BF533 */ +#define ANOMALY_05000207 /* Recovery from "brown-out" condition */ +#define ANOMALY_05000209 /* Speed-Path in computational unit affects certain + instructions */ +#define ANOMALY_05000233 /* PPI_FS3 is not driven in 2 or 3 internal Frame + Sync Transmit Mode */ +#define ANOMALY_05000271 /* Spontaneous reset of Internal Voltage Regulator */ +#endif + +#endif /* _MACH_ANOMALY_H_ */ diff --git a/include/asm-blackfin/mach-bf533/bf533.h b/include/asm-blackfin/mach-bf533/bf533.h new file mode 100644 index 000000000000..185fc1284858 --- /dev/null +++ b/include/asm-blackfin/mach-bf533/bf533.h @@ -0,0 +1,306 @@ +/* + * File: include/asm-blackfin/mach-bf533/bf533.h + * Based on: + * Author: + * + * Created: + * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561 + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __MACH_BF533_H__ +#define __MACH_BF533_H__ + +#define SUPPORTED_REVID 2 + +#define OFFSET_(x) ((x) & 0x0000FFFF) + +/*some misc defines*/ +#define IMASK_IVG15 0x8000 +#define IMASK_IVG14 0x4000 +#define IMASK_IVG13 0x2000 +#define IMASK_IVG12 0x1000 + +#define IMASK_IVG11 0x0800 +#define IMASK_IVG10 0x0400 +#define IMASK_IVG9 0x0200 +#define IMASK_IVG8 0x0100 + +#define IMASK_IVG7 0x0080 +#define IMASK_IVGTMR 0x0040 +#define IMASK_IVGHW 0x0020 + +/***************************/ + + +#define BLKFIN_DSUBBANKS 4 +#define BLKFIN_DWAYS 2 +#define BLKFIN_DLINES 64 +#define BLKFIN_ISUBBANKS 4 +#define BLKFIN_IWAYS 4 +#define BLKFIN_ILINES 32 + +#define WAY0_L 0x1 +#define WAY1_L 0x2 +#define WAY01_L 0x3 +#define WAY2_L 0x4 +#define WAY02_L 0x5 +#define WAY12_L 0x6 +#define WAY012_L 0x7 + +#define WAY3_L 0x8 +#define WAY03_L 0x9 +#define WAY13_L 0xA +#define WAY013_L 0xB + +#define WAY32_L 0xC +#define WAY320_L 0xD +#define WAY321_L 0xE +#define WAYALL_L 0xF + +#define DMC_ENABLE (2<<2) /*yes, 2, not 1 */ + +/* IAR0 BIT FIELDS*/ +#define RTC_ERROR_BIT 0x0FFFFFFF +#define UART_ERROR_BIT 0xF0FFFFFF +#define SPORT1_ERROR_BIT 0xFF0FFFFF +#define SPI_ERROR_BIT 0xFFF0FFFF +#define SPORT0_ERROR_BIT 0xFFFF0FFF +#define PPI_ERROR_BIT 0xFFFFF0FF +#define DMA_ERROR_BIT 0xFFFFFF0F +#define PLLWAKE_ERROR_BIT 0xFFFFFFFF + +/* IAR1 BIT FIELDS*/ +#define DMA7_UARTTX_BIT 0x0FFFFFFF +#define DMA6_UARTRX_BIT 0xF0FFFFFF +#define DMA5_SPI_BIT 0xFF0FFFFF +#define DMA4_SPORT1TX_BIT 0xFFF0FFFF +#define DMA3_SPORT1RX_BIT 0xFFFF0FFF +#define DMA2_SPORT0TX_BIT 0xFFFFF0FF +#define DMA1_SPORT0RX_BIT 0xFFFFFF0F +#define DMA0_PPI_BIT 0xFFFFFFFF + +/* IAR2 BIT FIELDS*/ +#define WDTIMER_BIT 0x0FFFFFFF +#define MEMDMA1_BIT 0xF0FFFFFF +#define MEMDMA0_BIT 0xFF0FFFFF +#define PFB_BIT 0xFFF0FFFF +#define PFA_BIT 0xFFFF0FFF +#define TIMER2_BIT 0xFFFFF0FF +#define TIMER1_BIT 0xFFFFFF0F +#define TIMER0_BIT 0xFFFFFFFF + +/********************************* EBIU Settings ************************************/ +#define AMBCTL0VAL ((CONFIG_BANK_1 << 16) | CONFIG_BANK_0) +#define AMBCTL1VAL ((CONFIG_BANK_3 << 16) | CONFIG_BANK_2) + +#ifdef CONFIG_C_AMBEN_ALL +#define V_AMBEN AMBEN_ALL +#endif +#ifdef CONFIG_C_AMBEN +#define V_AMBEN 0x0 +#endif +#ifdef CONFIG_C_AMBEN_B0 +#define V_AMBEN AMBEN_B0 +#endif +#ifdef CONFIG_C_AMBEN_B0_B1 +#define V_AMBEN AMBEN_B0_B1 +#endif +#ifdef CONFIG_C_AMBEN_B0_B1_B2 +#define V_AMBEN AMBEN_B0_B1_B2 +#endif +#ifdef CONFIG_C_AMCKEN +#define V_AMCKEN AMCKEN +#else +#define V_AMCKEN 0x0 +#endif +#ifdef CONFIG_C_CDPRIO +#define V_CDPRIO 0x100 +#else +#define V_CDPRIO 0x0 +#endif + +#define AMGCTLVAL (V_AMBEN | V_AMCKEN | V_CDPRIO) + +#define MAX_VC 650000000 +#define MIN_VC 50000000 + +#ifdef CONFIG_BFIN_KERNEL_CLOCK +/********************************PLL Settings **************************************/ +#if (CONFIG_VCO_MULT < 0) +#error "VCO Multiplier is less than 0. Please select a different value" +#endif + +#if (CONFIG_VCO_MULT == 0) +#error "VCO Multiplier should be greater than 0. Please select a different value" +#endif + +#if (CONFIG_VCO_MULT > 64) +#error "VCO Multiplier is more than 64. Please select a different value" +#endif + +#ifndef CONFIG_CLKIN_HALF +#define CONFIG_VCO_HZ (CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) +#else +#define CONFIG_VCO_HZ ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)/2) +#endif + +#ifndef CONFIG_PLL_BYPASS +#define CONFIG_CCLK_HZ (CONFIG_VCO_HZ/CONFIG_CCLK_DIV) +#define CONFIG_SCLK_HZ (CONFIG_VCO_HZ/CONFIG_SCLK_DIV) +#else +#define CONFIG_CCLK_HZ CONFIG_CLKIN_HZ +#define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ +#endif + +#if (CONFIG_SCLK_DIV < 1) +#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value" +#endif + +#if (CONFIG_SCLK_DIV > 15) +#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value" +#endif + +#if (CONFIG_CCLK_DIV != 1) +#if (CONFIG_CCLK_DIV != 2) +#if (CONFIG_CCLK_DIV != 4) +#if (CONFIG_CCLK_DIV != 8) +#error "CCLK DIV can be 1,2,4 or 8 only. Please select a proper value" +#endif +#endif +#endif +#endif + +#if (CONFIG_VCO_HZ > MAX_VC) +#error "VCO selected is more than maximum value. Please change the VCO multipler" +#endif + +#if (CONFIG_SCLK_HZ > 133000000) +#error "Sclk value selected is more than maximum. Please select a proper value for SCLK multiplier" +#endif + +#if (CONFIG_SCLK_HZ < 27000000) +#error "Sclk value selected is less than minimum. Please select a proper value for SCLK multiplier" +#endif + +#if (CONFIG_SCLK_HZ > CONFIG_CCLK_HZ) +#if (CONFIG_SCLK_HZ != CONFIG_CLKIN_HZ) +#if (CONFIG_CCLK_HZ != CONFIG_CLKIN_HZ) +#error "Please select sclk less than cclk" +#endif +#endif +#endif + +#if (CONFIG_CCLK_DIV == 1) +#define CONFIG_CCLK_ACT_DIV CCLK_DIV1 +#endif +#if (CONFIG_CCLK_DIV == 2) +#define CONFIG_CCLK_ACT_DIV CCLK_DIV2 +#endif +#if (CONFIG_CCLK_DIV == 4) +#define CONFIG_CCLK_ACT_DIV CCLK_DIV4 +#endif +#if (CONFIG_CCLK_DIV == 8) +#define CONFIG_CCLK_ACT_DIV CCLK_DIV8 +#endif +#ifndef CONFIG_CCLK_ACT_DIV +#define CONFIG_CCLK_ACT_DIV CONFIG_CCLK_DIV_not_defined_properly +#endif + +#if defined(ANOMALY_05000273) && (CONFIG_CCLK_DIV == 1) +#error ANOMALY 05000273, please make sure CCLK is at least 2x SCLK +#endif + +#endif /* CONFIG_BFIN_KERNEL_CLOCK */ + +#ifdef CONFIG_BF533 +#define CPU "BF533" +#define CPUID 0x027a5000 +#endif +#ifdef CONFIG_BF532 +#define CPU "BF532" +#define CPUID 0x0275A000 +#endif +#ifdef CONFIG_BF531 +#define CPU "BF531" +#define CPUID 0x027a5000 +#endif +#ifndef CPU +#define CPU "UNKNOWN" +#define CPUID 0x0 +#endif + +#if (CONFIG_MEM_SIZE % 4) +#error "SDRAM mem size must be multible of 4MB" +#endif + +#define SDRAM_IGENERIC (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO) +#define SDRAM_IKERNEL (SDRAM_IGENERIC | CPLB_LOCK) +#define L1_IMEMORY ( CPLB_USER_RD | CPLB_VALID | CPLB_LOCK) +#define SDRAM_INON_CHBL ( CPLB_USER_RD | CPLB_VALID) + +/*Use the menuconfig cache policy here - CONFIG_BLKFIN_WT/CONFIG_BLKFIN_WB*/ + +#define ANOMALY_05000158_WORKAROUND 0x200 +#ifdef CONFIG_BLKFIN_WB /*Write Back Policy */ +#define SDRAM_DGENERIC (CPLB_L1_CHBL | CPLB_DIRTY \ + | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND) +#else /*Write Through */ +#define SDRAM_DGENERIC (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_DIRTY \ + | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND) +#endif + +#define L1_DMEMORY (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY) +#define SDRAM_DNON_CHBL (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY) +#define SDRAM_EBIU (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY) +#define SDRAM_OOPS (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY) + +#define SIZE_1K 0x00000400 /* 1K */ +#define SIZE_4K 0x00001000 /* 4K */ +#define SIZE_1M 0x00100000 /* 1M */ +#define SIZE_4M 0x00400000 /* 4M */ + +#define MAX_CPLBS (16 * 2) + +/* +* Number of required data CPLB switchtable entries +* MEMSIZE / 4 (we mostly install 4M page size CPLBs +* approx 16 for smaller 1MB page size CPLBs for allignment purposes +* 1 for L1 Data Memory +* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO +* 1 for ASYNC Memory +*/ + + +#define MAX_SWITCH_D_CPLBS (((CONFIG_MEM_SIZE / 4) + 16 + 1 + 1 + 1) * 2) + +/* +* Number of required instruction CPLB switchtable entries +* MEMSIZE / 4 (we mostly install 4M page size CPLBs +* approx 12 for smaller 1MB page size CPLBs for allignment purposes +* 1 for L1 Instruction Memory +* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO +*/ + +#define MAX_SWITCH_I_CPLBS (((CONFIG_MEM_SIZE / 4) + 12 + 1 + 1) * 2) + +#endif /* __MACH_BF533_H__ */ diff --git a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h new file mode 100644 index 000000000000..23bf76aa3451 --- /dev/null +++ b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h @@ -0,0 +1,108 @@ +#include +#include + +#define NR_PORTS 1 + +#define OFFSET_THR 0x00 /* Transmit Holding register */ +#define OFFSET_RBR 0x00 /* Receive Buffer register */ +#define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */ +#define OFFSET_IER 0x04 /* Interrupt Enable Register */ +#define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */ +#define OFFSET_IIR 0x08 /* Interrupt Identification Register */ +#define OFFSET_LCR 0x0C /* Line Control Register */ +#define OFFSET_MCR 0x10 /* Modem Control Register */ +#define OFFSET_LSR 0x14 /* Line Status Register */ +#define OFFSET_MSR 0x18 /* Modem Status Register */ +#define OFFSET_SCR 0x1C /* SCR Scratch Register */ +#define OFFSET_GCTL 0x24 /* Global Control Register */ + +#define UART_GET_CHAR(uart) bfin_read16(((uart)->port.membase + OFFSET_RBR)) +#define UART_GET_DLL(uart) bfin_read16(((uart)->port.membase + OFFSET_DLL)) +#define UART_GET_IER(uart) bfin_read16(((uart)->port.membase + OFFSET_IER)) +#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH)) +#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR)) +#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) +#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) +#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) + +#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) +#define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v) +#define UART_PUT_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER),v) +#define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v) +#define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v) +#define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v) + +#ifdef CONFIG_BFIN_UART0_CTSRTS +# define CONFIG_SERIAL_BFIN_CTSRTS +# ifndef CONFIG_UART0_CTS_PIN +# define CONFIG_UART0_CTS_PIN -1 +# endif +# ifndef CONFIG_UART0_RTS_PIN +# define CONFIG_UART0_RTS_PIN -1 +# endif +#endif + +struct bfin_serial_port { + struct uart_port port; + unsigned int old_status; +#ifdef CONFIG_SERIAL_BFIN_DMA + int tx_done; + int tx_count; + struct circ_buf rx_dma_buf; + struct timer_list rx_dma_timer; + int rx_dma_nrows; + unsigned int tx_dma_channel; + unsigned int rx_dma_channel; + struct work_struct tx_dma_workqueue; +#else + struct work_struct cts_workqueue; +#endif +#ifdef CONFIG_SERIAL_BFIN_CTSRTS + int cts_pin; + int rts_pin; +#endif +}; + +struct bfin_serial_port bfin_serial_ports[NR_PORTS]; +struct bfin_serial_res { + unsigned long uart_base_addr; + int uart_irq; +#ifdef CONFIG_SERIAL_BFIN_DMA + unsigned int uart_tx_dma_channel; + unsigned int uart_rx_dma_channel; +#endif +#ifdef CONFIG_SERIAL_BFIN_CTSRTS + int uart_cts_pin; + int uart_rts_pin; +#endif +}; + +struct bfin_serial_res bfin_serial_resource[] = { + 0xFFC00400, + IRQ_UART_RX, +#ifdef CONFIG_SERIAL_BFIN_DMA + CH_UART_TX, + CH_UART_RX, +#endif +#ifdef CONFIG_BFIN_UART0_CTSRTS + CONFIG_UART0_CTS_PIN, + CONFIG_UART0_RTS_PIN, +#endif +}; + + +int nr_ports = NR_PORTS; +static void bfin_serial_hw_init(struct bfin_serial_port *uart) +{ + +#ifdef CONFIG_SERIAL_BFIN_CTSRTS + if (uart->cts_pin >= 0) { + gpio_request(uart->cts_pin, NULL); + gpio_direction_input(uart->cts_pin); + } + if (uart->rts_pin >= 0) { + gpio_request(uart->rts_pin, NULL); + gpio_direction_input(uart->rts_pin); + } +#endif +} diff --git a/include/asm-blackfin/mach-bf533/blackfin.h b/include/asm-blackfin/mach-bf533/blackfin.h new file mode 100644 index 000000000000..e4384491e972 --- /dev/null +++ b/include/asm-blackfin/mach-bf533/blackfin.h @@ -0,0 +1,45 @@ +/* + * File: include/asm-blackfin/mach-bf533/blackfin.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Rev: + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _MACH_BLACKFIN_H_ +#define _MACH_BLACKFIN_H_ + +#define BF533_FAMILY + +#include "bf533.h" +#include "mem_map.h" +#include "defBF532.h" +#include "anomaly.h" + +#if !(defined(__ASSEMBLY__) || defined(ASSEMBLY)) +#include "cdefBF532.h" +#endif + +#endif /* _MACH_BLACKFIN_H_ */ diff --git a/include/asm-blackfin/mach-bf533/cdefBF532.h b/include/asm-blackfin/mach-bf533/cdefBF532.h new file mode 100644 index 000000000000..1d7c494ceb64 --- /dev/null +++ b/include/asm-blackfin/mach-bf533/cdefBF532.h @@ -0,0 +1,706 @@ +/* + * File: include/asm-blackfin/mach-bf533/cdefBF532.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Rev: + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _CDEF_BF532_H +#define _CDEF_BF532_H +/* +#if !defined(__ADSPLPBLACKFIN__) +#warning cdefBF532.h should only be included for 532 compatible chips. +#endif +*/ +/*include all Core registers and bit definitions*/ +#include "defBF532.h" + +/*include core specific register pointer definitions*/ +#include + +#include + +/* Clock and System Control (0xFFC0 0400-0xFFC0 07FF) */ +#define bfin_read_PLL_CTL() bfin_read16(PLL_CTL) +#define bfin_write_PLL_CTL(val) bfin_write16(PLL_CTL,val) +#define bfin_read_PLL_STAT() bfin_read16(PLL_STAT) +#define bfin_write_PLL_STAT(val) bfin_write16(PLL_STAT,val) +#define bfin_read_PLL_LOCKCNT() bfin_read16(PLL_LOCKCNT) +#define bfin_write_PLL_LOCKCNT(val) bfin_write16(PLL_LOCKCNT,val) +#define bfin_read_CHIPID() bfin_read32(CHIPID) +#define bfin_read_SWRST() bfin_read16(SWRST) +#define bfin_write_SWRST(val) bfin_write16(SWRST,val) +#define bfin_read_SYSCR() bfin_read16(SYSCR) +#define bfin_write_SYSCR(val) bfin_write16(SYSCR,val) +#define bfin_read_PLL_DIV() bfin_read16(PLL_DIV) +#define bfin_write_PLL_DIV(val) bfin_write16(PLL_DIV,val) +#define bfin_read_VR_CTL() bfin_read16(VR_CTL) +/* Writing to VR_CTL initiates a PLL relock sequence. */ +static __inline__ void bfin_write_VR_CTL(unsigned int val) +{ + unsigned long flags, iwr; + + bfin_write16(VR_CTL, val); + __builtin_bfin_ssync(); + /* Enable the PLL Wakeup bit in SIC IWR */ + iwr = bfin_read32(SIC_IWR); + /* Only allow PPL Wakeup) */ + bfin_write32(SIC_IWR, IWR_ENABLE(0)); + local_irq_save(flags); + asm("IDLE;"); + local_irq_restore(flags); + bfin_write32(SIC_IWR, iwr); +} + +/* System Interrupt Controller (0xFFC0 0C00-0xFFC0 0FFF) */ +#define bfin_read_SIC_IAR0() bfin_read32(SIC_IAR0) +#define bfin_write_SIC_IAR0(val) bfin_write32(SIC_IAR0,val) +#define bfin_read_SIC_IAR1() bfin_read32(SIC_IAR1) +#define bfin_write_SIC_IAR1(val) bfin_write32(SIC_IAR1,val) +#define bfin_read_SIC_IAR2() bfin_read32(SIC_IAR2) +#define bfin_write_SIC_IAR2(val) bfin_write32(SIC_IAR2,val) +#define bfin_read_SIC_IAR3() bfin_read32(SIC_IAR3) +#define bfin_write_SIC_IAR3(val) bfin_write32(SIC_IAR3,val) +#define bfin_read_SIC_IMASK() bfin_read32(SIC_IMASK) +#define bfin_write_SIC_IMASK(val) bfin_write32(SIC_IMASK,val) +#define bfin_read_SIC_ISR() bfin_read32(SIC_ISR) +#define bfin_write_SIC_ISR(val) bfin_write32(SIC_ISR,val) +#define bfin_read_SIC_IWR() bfin_read32(SIC_IWR) +#define bfin_write_SIC_IWR(val) bfin_write32(SIC_IWR,val) + +/* Watchdog Timer (0xFFC0 1000-0xFFC0 13FF) */ +#define bfin_read_WDOG_CTL() bfin_read16(WDOG_CTL) +#define bfin_write_WDOG_CTL(val) bfin_write16(WDOG_CTL,val) +#define bfin_read_WDOG_CNT() bfin_read32(WDOG_CNT) +#define bfin_write_WDOG_CNT(val) bfin_write32(WDOG_CNT,val) +#define bfin_read_WDOG_STAT() bfin_read32(WDOG_STAT) +#define bfin_write_WDOG_STAT(val) bfin_write32(WDOG_STAT,val) + +/* Real Time Clock (0xFFC0 1400-0xFFC0 17FF) */ +#define bfin_read_RTC_STAT() bfin_read32(RTC_STAT) +#define bfin_write_RTC_STAT(val) bfin_write32(RTC_STAT,val) +#define bfin_read_RTC_ICTL() bfin_read16(RTC_ICTL) +#define bfin_write_RTC_ICTL(val) bfin_write16(RTC_ICTL,val) +#define bfin_read_RTC_ISTAT() bfin_read16(RTC_ISTAT) +#define bfin_write_RTC_ISTAT(val) bfin_write16(RTC_ISTAT,val) +#define bfin_read_RTC_SWCNT() bfin_read16(RTC_SWCNT) +#define bfin_write_RTC_SWCNT(val) bfin_write16(RTC_SWCNT,val) +#define bfin_read_RTC_ALARM() bfin_read32(RTC_ALARM) +#define bfin_write_RTC_ALARM(val) bfin_write32(RTC_ALARM,val) +#define bfin_read_RTC_FAST() bfin_read16(RTC_FAST) +#define bfin_write_RTC_FAST(val) bfin_write16(RTC_FAST,val) +#define bfin_read_RTC_PREN() bfin_read16(RTC_PREN) +#define bfin_write_RTC_PREN(val) bfin_write16(RTC_PREN,val) + +/* General Purpose IO (0xFFC0 2400-0xFFC0 27FF) */ +#define bfin_read_FIO_DIR() bfin_read16(FIO_DIR) +#define bfin_write_FIO_DIR(val) bfin_write16(FIO_DIR,val) +#define bfin_read_FIO_FLAG_C() bfin_read16(FIO_FLAG_C) +#define bfin_write_FIO_FLAG_C(val) bfin_write16(FIO_FLAG_C,val) +#define bfin_read_FIO_FLAG_S() bfin_read16(FIO_FLAG_S) +#define bfin_write_FIO_FLAG_S(val) bfin_write16(FIO_FLAG_S,val) +#define bfin_read_FIO_MASKA_C() bfin_read16(FIO_MASKA_C) +#define bfin_write_FIO_MASKA_C(val) bfin_write16(FIO_MASKA_C,val) +#define bfin_read_FIO_MASKA_S() bfin_read16(FIO_MASKA_S) +#define bfin_write_FIO_MASKA_S(val) bfin_write16(FIO_MASKA_S,val) +#define bfin_read_FIO_MASKB_C() bfin_read16(FIO_MASKB_C) +#define bfin_write_FIO_MASKB_C(val) bfin_write16(FIO_MASKB_C,val) +#define bfin_read_FIO_MASKB_S() bfin_read16(FIO_MASKB_S) +#define bfin_write_FIO_MASKB_S(val) bfin_write16(FIO_MASKB_S,val) +#define bfin_read_FIO_POLAR() bfin_read16(FIO_POLAR) +#define bfin_write_FIO_POLAR(val) bfin_write16(FIO_POLAR,val) +#define bfin_read_FIO_EDGE() bfin_read16(FIO_EDGE) +#define bfin_write_FIO_EDGE(val) bfin_write16(FIO_EDGE,val) +#define bfin_read_FIO_BOTH() bfin_read16(FIO_BOTH) +#define bfin_write_FIO_BOTH(val) bfin_write16(FIO_BOTH,val) +#define bfin_read_FIO_INEN() bfin_read16(FIO_INEN) +#define bfin_write_FIO_INEN(val) bfin_write16(FIO_INEN,val) +#define bfin_read_FIO_FLAG_D() bfin_read16(FIO_FLAG_D) +#define bfin_write_FIO_FLAG_D(val) bfin_write16(FIO_FLAG_D,val) +#define bfin_read_FIO_FLAG_T() bfin_read16(FIO_FLAG_T) +#define bfin_write_FIO_FLAG_T(val) bfin_write16(FIO_FLAG_T,val) +#define bfin_read_FIO_MASKA_D() bfin_read16(FIO_MASKA_D) +#define bfin_write_FIO_MASKA_D(val) bfin_write16(FIO_MASKA_D,val) +#define bfin_read_FIO_MASKA_T() bfin_read16(FIO_MASKA_T) +#define bfin_write_FIO_MASKA_T(val) bfin_write16(FIO_MASKA_T,val) +#define bfin_read_FIO_MASKB_D() bfin_read16(FIO_MASKB_D) +#define bfin_write_FIO_MASKB_D(val) bfin_write16(FIO_MASKB_D,val) +#define bfin_read_FIO_MASKB_T() bfin_read16(FIO_MASKB_T) +#define bfin_write_FIO_MASKB_T(val) bfin_write16(FIO_MASKB_T,val) + +/* DMA Traffic controls */ +#define bfin_read_DMA_TCPER() bfin_read16(DMA_TCPER) +#define bfin_write_DMA_TCPER(val) bfin_write16(DMA_TCPER,val) +#define bfin_read_DMA_TCCNT() bfin_read16(DMA_TCCNT) +#define bfin_write_DMA_TCCNT(val) bfin_write16(DMA_TCCNT,val) +#define bfin_read_DMA_TC_PER() bfin_read16(DMA_TC_PER) +#define bfin_write_DMA_TC_PER(val) bfin_write16(DMA_TC_PER,val) +#define bfin_read_DMA_TC_CNT() bfin_read16(DMA_TC_CNT) +#define bfin_write_DMA_TC_CNT(val) bfin_write16(DMA_TC_CNT,val) + +/* DMA Controller */ +#define bfin_read_DMA0_CONFIG() bfin_read16(DMA0_CONFIG) +#define bfin_write_DMA0_CONFIG(val) bfin_write16(DMA0_CONFIG,val) +#define bfin_read_DMA0_NEXT_DESC_PTR() bfin_read32(DMA0_NEXT_DESC_PTR) +#define bfin_write_DMA0_NEXT_DESC_PTR(val) bfin_write32(DMA0_NEXT_DESC_PTR,val) +#define bfin_read_DMA0_START_ADDR() bfin_read32(DMA0_START_ADDR) +#define bfin_write_DMA0_START_ADDR(val) bfin_write32(DMA0_START_ADDR,val) +#define bfin_read_DMA0_X_COUNT() bfin_read16(DMA0_X_COUNT) +#define bfin_write_DMA0_X_COUNT(val) bfin_write16(DMA0_X_COUNT,val) +#define bfin_read_DMA0_Y_COUNT() bfin_read16(DMA0_Y_COUNT) +#define bfin_write_DMA0_Y_COUNT(val) bfin_write16(DMA0_Y_COUNT,val) +#define bfin_read_DMA0_X_MODIFY() bfin_read16(DMA0_X_MODIFY) +#define bfin_write_DMA0_X_MODIFY(val) bfin_write16(DMA0_X_MODIFY,val) +#define bfin_read_DMA0_Y_MODIFY() bfin_read16(DMA0_Y_MODIFY) +#define bfin_write_DMA0_Y_MODIFY(val) bfin_write16(DMA0_Y_MODIFY,val) +#define bfin_read_DMA0_CURR_DESC_PTR() bfin_read32(DMA0_CURR_DESC_PTR) +#define bfin_write_DMA0_CURR_DESC_PTR(val) bfin_write32(DMA0_CURR_DESC_PTR,val) +#define bfin_read_DMA0_CURR_ADDR() bfin_read32(DMA0_CURR_ADDR) +#define bfin_write_DMA0_CURR_ADDR(val) bfin_write32(DMA0_CURR_ADDR,val) +#define bfin_read_DMA0_CURR_X_COUNT() bfin_read16(DMA0_CURR_X_COUNT) +#define bfin_write_DMA0_CURR_X_COUNT(val) bfin_write16(DMA0_CURR_X_COUNT,val) +#define bfin_read_DMA0_CURR_Y_COUNT() bfin_read16(DMA0_CURR_Y_COUNT) +#define bfin_write_DMA0_CURR_Y_COUNT(val) bfin_write16(DMA0_CURR_Y_COUNT,val) +#define bfin_read_DMA0_IRQ_STATUS() bfin_read16(DMA0_IRQ_STATUS) +#define bfin_write_DMA0_IRQ_STATUS(val) bfin_write16(DMA0_IRQ_STATUS,val) +#define bfin_read_DMA0_PERIPHERAL_MAP() bfin_read16(DMA0_PERIPHERAL_MAP) +#define bfin_write_DMA0_PERIPHERAL_MAP(val) bfin_write16(DMA0_PERIPHERAL_MAP,val) + +#define bfin_read_DMA1_CONFIG() bfin_read16(DMA1_CONFIG) +#define bfin_write_DMA1_CONFIG(val) bfin_write16(DMA1_CONFIG,val) +#define bfin_read_DMA1_NEXT_DESC_PTR() bfin_read32(DMA1_NEXT_DESC_PTR) +#define bfin_write_DMA1_NEXT_DESC_PTR(val) bfin_write32(DMA1_NEXT_DESC_PTR,val) +#define bfin_read_DMA1_START_ADDR() bfin_read32(DMA1_START_ADDR) +#define bfin_write_DMA1_START_ADDR(val) bfin_write32(DMA1_START_ADDR,val) +#define bfin_read_DMA1_X_COUNT() bfin_read16(DMA1_X_COUNT) +#define bfin_write_DMA1_X_COUNT(val) bfin_write16(DMA1_X_COUNT,val) +#define bfin_read_DMA1_Y_COUNT() bfin_read16(DMA1_Y_COUNT) +#define bfin_write_DMA1_Y_COUNT(val) bfin_write16(DMA1_Y_COUNT,val) +#define bfin_read_DMA1_X_MODIFY() bfin_read16(DMA1_X_MODIFY) +#define bfin_write_DMA1_X_MODIFY(val) bfin_write16(DMA1_X_MODIFY,val) +#define bfin_read_DMA1_Y_MODIFY() bfin_read16(DMA1_Y_MODIFY) +#define bfin_write_DMA1_Y_MODIFY(val) bfin_write16(DMA1_Y_MODIFY,val) +#define bfin_read_DMA1_CURR_DESC_PTR() bfin_read32(DMA1_CURR_DESC_PTR) +#define bfin_write_DMA1_CURR_DESC_PTR(val) bfin_write32(DMA1_CURR_DESC_PTR,val) +#define bfin_read_DMA1_CURR_ADDR() bfin_read32(DMA1_CURR_ADDR) +#define bfin_write_DMA1_CURR_ADDR(val) bfin_write32(DMA1_CURR_ADDR,val) +#define bfin_read_DMA1_CURR_X_COUNT() bfin_read16(DMA1_CURR_X_COUNT) +#define bfin_write_DMA1_CURR_X_COUNT(val) bfin_write16(DMA1_CURR_X_COUNT,val) +#define bfin_read_DMA1_CURR_Y_COUNT() bfin_read16(DMA1_CURR_Y_COUNT) +#define bfin_write_DMA1_CURR_Y_COUNT(val) bfin_write16(DMA1_CURR_Y_COUNT,val) +#define bfin_read_DMA1_IRQ_STATUS() bfin_read16(DMA1_IRQ_STATUS) +#define bfin_write_DMA1_IRQ_STATUS(val) bfin_write16(DMA1_IRQ_STATUS,val) +#define bfin_read_DMA1_PERIPHERAL_MAP() bfin_read16(DMA1_PERIPHERAL_MAP) +#define bfin_write_DMA1_PERIPHERAL_MAP(val) bfin_write16(DMA1_PERIPHERAL_MAP,val) + +#define bfin_read_DMA2_CONFIG() bfin_read16(DMA2_CONFIG) +#define bfin_write_DMA2_CONFIG(val) bfin_write16(DMA2_CONFIG,val) +#define bfin_read_DMA2_NEXT_DESC_PTR() bfin_read32(DMA2_NEXT_DESC_PTR) +#define bfin_write_DMA2_NEXT_DESC_PTR(val) bfin_write32(DMA2_NEXT_DESC_PTR,val) +#define bfin_read_DMA2_START_ADDR() bfin_read32(DMA2_START_ADDR) +#define bfin_write_DMA2_START_ADDR(val) bfin_write32(DMA2_START_ADDR,val) +#define bfin_read_DMA2_X_COUNT() bfin_read16(DMA2_X_COUNT) +#define bfin_write_DMA2_X_COUNT(val) bfin_write16(DMA2_X_COUNT,val) +#define bfin_read_DMA2_Y_COUNT() bfin_read16(DMA2_Y_COUNT) +#define bfin_write_DMA2_Y_COUNT(val) bfin_write16(DMA2_Y_COUNT,val) +#define bfin_read_DMA2_X_MODIFY() bfin_read16(DMA2_X_MODIFY) +#define bfin_write_DMA2_X_MODIFY(val) bfin_write16(DMA2_X_MODIFY,val) +#define bfin_read_DMA2_Y_MODIFY() bfin_read16(DMA2_Y_MODIFY) +#define bfin_write_DMA2_Y_MODIFY(val) bfin_write16(DMA2_Y_MODIFY,val) +#define bfin_read_DMA2_CURR_DESC_PTR() bfin_read32(DMA2_CURR_DESC_PTR) +#define bfin_write_DMA2_CURR_DESC_PTR(val) bfin_write32(DMA2_CURR_DESC_PTR,val) +#define bfin_read_DMA2_CURR_ADDR() bfin_read32(DMA2_CURR_ADDR) +#define bfin_write_DMA2_CURR_ADDR(val) bfin_write32(DMA2_CURR_ADDR,val) +#define bfin_read_DMA2_CURR_X_COUNT() bfin_read16(DMA2_CURR_X_COUNT) +#define bfin_write_DMA2_CURR_X_COUNT(val) bfin_write16(DMA2_CURR_X_COUNT,val) +#define bfin_read_DMA2_CURR_Y_COUNT() bfin_read16(DMA2_CURR_Y_COUNT) +#define bfin_write_DMA2_CURR_Y_COUNT(val) bfin_write16(DMA2_CURR_Y_COUNT,val) +#define bfin_read_DMA2_IRQ_STATUS() bfin_read16(DMA2_IRQ_STATUS) +#define bfin_write_DMA2_IRQ_STATUS(val) bfin_write16(DMA2_IRQ_STATUS,val) +#define bfin_read_DMA2_PERIPHERAL_MAP() bfin_read16(DMA2_PERIPHERAL_MAP) +#define bfin_write_DMA2_PERIPHERAL_MAP(val) bfin_write16(DMA2_PERIPHERAL_MAP,val) + +#define bfin_read_DMA3_CONFIG() bfin_read16(DMA3_CONFIG) +#define bfin_write_DMA3_CONFIG(val) bfin_write16(DMA3_CONFIG,val) +#define bfin_read_DMA3_NEXT_DESC_PTR() bfin_read32(DMA3_NEXT_DESC_PTR) +#define bfin_write_DMA3_NEXT_DESC_PTR(val) bfin_write32(DMA3_NEXT_DESC_PTR,val) +#define bfin_read_DMA3_START_ADDR() bfin_read32(DMA3_START_ADDR) +#define bfin_write_DMA3_START_ADDR(val) bfin_write32(DMA3_START_ADDR,val) +#define bfin_read_DMA3_X_COUNT() bfin_read16(DMA3_X_COUNT) +#define bfin_write_DMA3_X_COUNT(val) bfin_write16(DMA3_X_COUNT,val) +#define bfin_read_DMA3_Y_COUNT() bfin_read16(DMA3_Y_COUNT) +#define bfin_write_DMA3_Y_COUNT(val) bfin_write16(DMA3_Y_COUNT,val) +#define bfin_read_DMA3_X_MODIFY() bfin_read16(DMA3_X_MODIFY) +#define bfin_write_DMA3_X_MODIFY(val) bfin_write16(DMA3_X_MODIFY,val) +#define bfin_read_DMA3_Y_MODIFY() bfin_read16(DMA3_Y_MODIFY) +#define bfin_write_DMA3_Y_MODIFY(val) bfin_write16(DMA3_Y_MODIFY,val) +#define bfin_read_DMA3_CURR_DESC_PTR() bfin_read32(DMA3_CURR_DESC_PTR) +#define bfin_write_DMA3_CURR_DESC_PTR(val) bfin_write32(DMA3_CURR_DESC_PTR,val) +#define bfin_read_DMA3_CURR_ADDR() bfin_read32(DMA3_CURR_ADDR) +#define bfin_write_DMA3_CURR_ADDR(val) bfin_write32(DMA3_CURR_ADDR,val) +#define bfin_read_DMA3_CURR_X_COUNT() bfin_read16(DMA3_CURR_X_COUNT) +#define bfin_write_DMA3_CURR_X_COUNT(val) bfin_write16(DMA3_CURR_X_COUNT,val) +#define bfin_read_DMA3_CURR_Y_COUNT() bfin_read16(DMA3_CURR_Y_COUNT) +#define bfin_write_DMA3_CURR_Y_COUNT(val) bfin_write16(DMA3_CURR_Y_COUNT,val) +#define bfin_read_DMA3_IRQ_STATUS() bfin_read16(DMA3_IRQ_STATUS) +#define bfin_write_DMA3_IRQ_STATUS(val) bfin_write16(DMA3_IRQ_STATUS,val) +#define bfin_read_DMA3_PERIPHERAL_MAP() bfin_read16(DMA3_PERIPHERAL_MAP) +#define bfin_write_DMA3_PERIPHERAL_MAP(val) bfin_write16(DMA3_PERIPHERAL_MAP,val) + +#define bfin_read_DMA4_CONFIG() bfin_read16(DMA4_CONFIG) +#define bfin_write_DMA4_CONFIG(val) bfin_write16(DMA4_CONFIG,val) +#define bfin_read_DMA4_NEXT_DESC_PTR() bfin_read32(DMA4_NEXT_DESC_PTR) +#define bfin_write_DMA4_NEXT_DESC_PTR(val) bfin_write32(DMA4_NEXT_DESC_PTR,val) +#define bfin_read_DMA4_START_ADDR() bfin_read32(DMA4_START_ADDR) +#define bfin_write_DMA4_START_ADDR(val) bfin_write32(DMA4_START_ADDR,val) +#define bfin_read_DMA4_X_COUNT() bfin_read16(DMA4_X_COUNT) +#define bfin_write_DMA4_X_COUNT(val) bfin_write16(DMA4_X_COUNT,val) +#define bfin_read_DMA4_Y_COUNT() bfin_read16(DMA4_Y_COUNT) +#define bfin_write_DMA4_Y_COUNT(val) bfin_write16(DMA4_Y_COUNT,val) +#define bfin_read_DMA4_X_MODIFY() bfin_read16(DMA4_X_MODIFY) +#define bfin_write_DMA4_X_MODIFY(val) bfin_write16(DMA4_X_MODIFY,val) +#define bfin_read_DMA4_Y_MODIFY() bfin_read16(DMA4_Y_MODIFY) +#define bfin_write_DMA4_Y_MODIFY(val) bfin_write16(DMA4_Y_MODIFY,val) +#define bfin_read_DMA4_CURR_DESC_PTR() bfin_read32(DMA4_CURR_DESC_PTR) +#define bfin_write_DMA4_CURR_DESC_PTR(val) bfin_write32(DMA4_CURR_DESC_PTR,val) +#define bfin_read_DMA4_CURR_ADDR() bfin_read32(DMA4_CURR_ADDR) +#define bfin_write_DMA4_CURR_ADDR(val) bfin_write32(DMA4_CURR_ADDR,val) +#define bfin_read_DMA4_CURR_X_COUNT() bfin_read16(DMA4_CURR_X_COUNT) +#define bfin_write_DMA4_CURR_X_COUNT(val) bfin_write16(DMA4_CURR_X_COUNT,val) +#define bfin_read_DMA4_CURR_Y_COUNT() bfin_read16(DMA4_CURR_Y_COUNT) +#define bfin_write_DMA4_CURR_Y_COUNT(val) bfin_write16(DMA4_CURR_Y_COUNT,val) +#define bfin_read_DMA4_IRQ_STATUS() bfin_read16(DMA4_IRQ_STATUS) +#define bfin_write_DMA4_IRQ_STATUS(val) bfin_write16(DMA4_IRQ_STATUS,val) +#define bfin_read_DMA4_PERIPHERAL_MAP() bfin_read16(DMA4_PERIPHERAL_MAP) +#define bfin_write_DMA4_PERIPHERAL_MAP(val) bfin_write16(DMA4_PERIPHERAL_MAP,val) + +#define bfin_read_DMA5_CONFIG() bfin_read16(DMA5_CONFIG) +#define bfin_write_DMA5_CONFIG(val) bfin_write16(DMA5_CONFIG,val) +#define bfin_read_DMA5_NEXT_DESC_PTR() bfin_read32(DMA5_NEXT_DESC_PTR) +#define bfin_write_DMA5_NEXT_DESC_PTR(val) bfin_write32(DMA5_NEXT_DESC_PTR,val) +#define bfin_read_DMA5_START_ADDR() bfin_read32(DMA5_START_ADDR) +#define bfin_write_DMA5_START_ADDR(val) bfin_write32(DMA5_START_ADDR,val) +#define bfin_read_DMA5_X_COUNT() bfin_read16(DMA5_X_COUNT) +#define bfin_write_DMA5_X_COUNT(val) bfin_write16(DMA5_X_COUNT,val) +#define bfin_read_DMA5_Y_COUNT() bfin_read16(DMA5_Y_COUNT) +#define bfin_write_DMA5_Y_COUNT(val) bfin_write16(DMA5_Y_COUNT,val) +#define bfin_read_DMA5_X_MODIFY() bfin_read16(DMA5_X_MODIFY) +#define bfin_write_DMA5_X_MODIFY(val) bfin_write16(DMA5_X_MODIFY,val) +#define bfin_read_DMA5_Y_MODIFY() bfin_read16(DMA5_Y_MODIFY) +#define bfin_write_DMA5_Y_MODIFY(val) bfin_write16(DMA5_Y_MODIFY,val) +#define bfin_read_DMA5_CURR_DESC_PTR() bfin_read32(DMA5_CURR_DESC_PTR) +#define bfin_write_DMA5_CURR_DESC_PTR(val) bfin_write32(DMA5_CURR_DESC_PTR,val) +#define bfin_read_DMA5_CURR_ADDR() bfin_read32(DMA5_CURR_ADDR) +#define bfin_write_DMA5_CURR_ADDR(val) bfin_write32(DMA5_CURR_ADDR,val) +#define bfin_read_DMA5_CURR_X_COUNT() bfin_read16(DMA5_CURR_X_COUNT) +#define bfin_write_DMA5_CURR_X_COUNT(val) bfin_write16(DMA5_CURR_X_COUNT,val) +#define bfin_read_DMA5_CURR_Y_COUNT() bfin_read16(DMA5_CURR_Y_COUNT) +#define bfin_write_DMA5_CURR_Y_COUNT(val) bfin_write16(DMA5_CURR_Y_COUNT,val) +#define bfin_read_DMA5_IRQ_STATUS() bfin_read16(DMA5_IRQ_STATUS) +#define bfin_write_DMA5_IRQ_STATUS(val) bfin_write16(DMA5_IRQ_STATUS,val) +#define bfin_read_DMA5_PERIPHERAL_MAP() bfin_read16(DMA5_PERIPHERAL_MAP) +#define bfin_write_DMA5_PERIPHERAL_MAP(val) bfin_write16(DMA5_PERIPHERAL_MAP,val) + +#define bfin_read_DMA6_CONFIG() bfin_read16(DMA6_CONFIG) +#define bfin_write_DMA6_CONFIG(val) bfin_write16(DMA6_CONFIG,val) +#define bfin_read_DMA6_NEXT_DESC_PTR() bfin_read32(DMA6_NEXT_DESC_PTR) +#define bfin_write_DMA6_NEXT_DESC_PTR(val) bfin_write32(DMA6_NEXT_DESC_PTR,val) +#define bfin_read_DMA6_START_ADDR() bfin_read32(DMA6_START_ADDR) +#define bfin_write_DMA6_START_ADDR(val) bfin_write32(DMA6_START_ADDR,val) +#define bfin_read_DMA6_X_COUNT() bfin_read16(DMA6_X_COUNT) +#define bfin_write_DMA6_X_COUNT(val) bfin_write16(DMA6_X_COUNT,val) +#define bfin_read_DMA6_Y_COUNT() bfin_read16(DMA6_Y_COUNT) +#define bfin_write_DMA6_Y_COUNT(val) bfin_write16(DMA6_Y_COUNT,val) +#define bfin_read_DMA6_X_MODIFY() bfin_read16(DMA6_X_MODIFY) +#define bfin_write_DMA6_X_MODIFY(val) bfin_write16(DMA6_X_MODIFY,val) +#define bfin_read_DMA6_Y_MODIFY() bfin_read16(DMA6_Y_MODIFY) +#define bfin_write_DMA6_Y_MODIFY(val) bfin_write16(DMA6_Y_MODIFY,val) +#define bfin_read_DMA6_CURR_DESC_PTR() bfin_read32(DMA6_CURR_DESC_PTR) +#define bfin_write_DMA6_CURR_DESC_PTR(val) bfin_write32(DMA6_CURR_DESC_PTR,val) +#define bfin_read_DMA6_CURR_ADDR() bfin_read32(DMA6_CURR_ADDR) +#define bfin_write_DMA6_CURR_ADDR(val) bfin_write32(DMA6_CURR_ADDR,val) +#define bfin_read_DMA6_CURR_X_COUNT() bfin_read16(DMA6_CURR_X_COUNT) +#define bfin_write_DMA6_CURR_X_COUNT(val) bfin_write16(DMA6_CURR_X_COUNT,val) +#define bfin_read_DMA6_CURR_Y_COUNT() bfin_read16(DMA6_CURR_Y_COUNT) +#define bfin_write_DMA6_CURR_Y_COUNT(val) bfin_write16(DMA6_CURR_Y_COUNT,val) +#define bfin_read_DMA6_IRQ_STATUS() bfin_read16(DMA6_IRQ_STATUS) +#define bfin_write_DMA6_IRQ_STATUS(val) bfin_write16(DMA6_IRQ_STATUS,val) +#define bfin_read_DMA6_PERIPHERAL_MAP() bfin_read16(DMA6_PERIPHERAL_MAP) +#define bfin_write_DMA6_PERIPHERAL_MAP(val) bfin_write16(DMA6_PERIPHERAL_MAP,val) + +#define bfin_read_DMA7_CONFIG() bfin_read16(DMA7_CONFIG) +#define bfin_write_DMA7_CONFIG(val) bfin_write16(DMA7_CONFIG,val) +#define bfin_read_DMA7_NEXT_DESC_PTR() bfin_read32(DMA7_NEXT_DESC_PTR) +#define bfin_write_DMA7_NEXT_DESC_PTR(val) bfin_write32(DMA7_NEXT_DESC_PTR,val) +#define bfin_read_DMA7_START_ADDR() bfin_read32(DMA7_START_ADDR) +#define bfin_write_DMA7_START_ADDR(val) bfin_write32(DMA7_START_ADDR,val) +#define bfin_read_DMA7_X_COUNT() bfin_read16(DMA7_X_COUNT) +#define bfin_write_DMA7_X_COUNT(val) bfin_write16(DMA7_X_COUNT,val) +#define bfin_read_DMA7_Y_COUNT() bfin_read16(DMA7_Y_COUNT) +#define bfin_write_DMA7_Y_COUNT(val) bfin_write16(DMA7_Y_COUNT,val) +#define bfin_read_DMA7_X_MODIFY() bfin_read16(DMA7_X_MODIFY) +#define bfin_write_DMA7_X_MODIFY(val) bfin_write16(DMA7_X_MODIFY,val) +#define bfin_read_DMA7_Y_MODIFY() bfin_read16(DMA7_Y_MODIFY) +#define bfin_write_DMA7_Y_MODIFY(val) bfin_write16(DMA7_Y_MODIFY,val) +#define bfin_read_DMA7_CURR_DESC_PTR() bfin_read32(DMA7_CURR_DESC_PTR) +#define bfin_write_DMA7_CURR_DESC_PTR(val) bfin_write32(DMA7_CURR_DESC_PTR,val) +#define bfin_read_DMA7_CURR_ADDR() bfin_read32(DMA7_CURR_ADDR) +#define bfin_write_DMA7_CURR_ADDR(val) bfin_write32(DMA7_CURR_ADDR,val) +#define bfin_read_DMA7_CURR_X_COUNT() bfin_read16(DMA7_CURR_X_COUNT) +#define bfin_write_DMA7_CURR_X_COUNT(val) bfin_write16(DMA7_CURR_X_COUNT,val) +#define bfin_read_DMA7_CURR_Y_COUNT() bfin_read16(DMA7_CURR_Y_COUNT) +#define bfin_write_DMA7_CURR_Y_COUNT(val) bfin_write16(DMA7_CURR_Y_COUNT,val) +#define bfin_read_DMA7_IRQ_STATUS() bfin_read16(DMA7_IRQ_STATUS) +#define bfin_write_DMA7_IRQ_STATUS(val) bfin_write16(DMA7_IRQ_STATUS,val) +#define bfin_read_DMA7_PERIPHERAL_MAP() bfin_read16(DMA7_PERIPHERAL_MAP) +#define bfin_write_DMA7_PERIPHERAL_MAP(val) bfin_write16(DMA7_PERIPHERAL_MAP,val) + +#define bfin_read_MDMA_D1_CONFIG() bfin_read16(MDMA_D1_CONFIG) +#define bfin_write_MDMA_D1_CONFIG(val) bfin_write16(MDMA_D1_CONFIG,val) +#define bfin_read_MDMA_D1_NEXT_DESC_PTR() bfin_read32(MDMA_D1_NEXT_DESC_PTR) +#define bfin_write_MDMA_D1_NEXT_DESC_PTR(val) bfin_write32(MDMA_D1_NEXT_DESC_PTR,val) +#define bfin_read_MDMA_D1_START_ADDR() bfin_read32(MDMA_D1_START_ADDR) +#define bfin_write_MDMA_D1_START_ADDR(val) bfin_write32(MDMA_D1_START_ADDR,val) +#define bfin_read_MDMA_D1_X_COUNT() bfin_read16(MDMA_D1_X_COUNT) +#define bfin_write_MDMA_D1_X_COUNT(val) bfin_write16(MDMA_D1_X_COUNT,val) +#define bfin_read_MDMA_D1_Y_COUNT() bfin_read16(MDMA_D1_Y_COUNT) +#define bfin_write_MDMA_D1_Y_COUNT(val) bfin_write16(MDMA_D1_Y_COUNT,val) +#define bfin_read_MDMA_D1_X_MODIFY() bfin_read16(MDMA_D1_X_MODIFY) +#define bfin_write_MDMA_D1_X_MODIFY(val) bfin_write16(MDMA_D1_X_MODIFY,val) +#define bfin_read_MDMA_D1_Y_MODIFY() bfin_read16(MDMA_D1_Y_MODIFY) +#define bfin_write_MDMA_D1_Y_MODIFY(val) bfin_write16(MDMA_D1_Y_MODIFY,val) +#define bfin_read_MDMA_D1_CURR_DESC_PTR() bfin_read32(MDMA_D1_CURR_DESC_PTR) +#define bfin_write_MDMA_D1_CURR_DESC_PTR(val) bfin_write32(MDMA_D1_CURR_DESC_PTR,val) +#define bfin_read_MDMA_D1_CURR_ADDR() bfin_read32(MDMA_D1_CURR_ADDR) +#define bfin_write_MDMA_D1_CURR_ADDR(val) bfin_write32(MDMA_D1_CURR_ADDR,val) +#define bfin_read_MDMA_D1_CURR_X_COUNT() bfin_read16(MDMA_D1_CURR_X_COUNT) +#define bfin_write_MDMA_D1_CURR_X_COUNT(val) bfin_write16(MDMA_D1_CURR_X_COUNT,val) +#define bfin_read_MDMA_D1_CURR_Y_COUNT() bfin_read16(MDMA_D1_CURR_Y_COUNT) +#define bfin_write_MDMA_D1_CURR_Y_COUNT(val) bfin_write16(MDMA_D1_CURR_Y_COUNT,val) +#define bfin_read_MDMA_D1_IRQ_STATUS() bfin_read16(MDMA_D1_IRQ_STATUS) +#define bfin_write_MDMA_D1_IRQ_STATUS(val) bfin_write16(MDMA_D1_IRQ_STATUS,val) +#define bfin_read_MDMA_D1_PERIPHERAL_MAP() bfin_read16(MDMA_D1_PERIPHERAL_MAP) +#define bfin_write_MDMA_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA_D1_PERIPHERAL_MAP,val) + +#define bfin_read_MDMA_S1_CONFIG() bfin_read16(MDMA_S1_CONFIG) +#define bfin_write_MDMA_S1_CONFIG(val) bfin_write16(MDMA_S1_CONFIG,val) +#define bfin_read_MDMA_S1_NEXT_DESC_PTR() bfin_read32(MDMA_S1_NEXT_DESC_PTR) +#define bfin_write_MDMA_S1_NEXT_DESC_PTR(val) bfin_write32(MDMA_S1_NEXT_DESC_PTR,val) +#define bfin_read_MDMA_S1_START_ADDR() bfin_read32(MDMA_S1_START_ADDR) +#define bfin_write_MDMA_S1_START_ADDR(val) bfin_write32(MDMA_S1_START_ADDR,val) +#define bfin_read_MDMA_S1_X_COUNT() bfin_read16(MDMA_S1_X_COUNT) +#define bfin_write_MDMA_S1_X_COUNT(val) bfin_write16(MDMA_S1_X_COUNT,val) +#define bfin_read_MDMA_S1_Y_COUNT() bfin_read16(MDMA_S1_Y_COUNT) +#define bfin_write_MDMA_S1_Y_COUNT(val) bfin_write16(MDMA_S1_Y_COUNT,val) +#define bfin_read_MDMA_S1_X_MODIFY() bfin_read16(MDMA_S1_X_MODIFY) +#define bfin_write_MDMA_S1_X_MODIFY(val) bfin_write16(MDMA_S1_X_MODIFY,val) +#define bfin_read_MDMA_S1_Y_MODIFY() bfin_read16(MDMA_S1_Y_MODIFY) +#define bfin_write_MDMA_S1_Y_MODIFY(val) bfin_write16(MDMA_S1_Y_MODIFY,val) +#define bfin_read_MDMA_S1_CURR_DESC_PTR() bfin_read32(MDMA_S1_CURR_DESC_PTR) +#define bfin_write_MDMA_S1_CURR_DESC_PTR(val) bfin_write32(MDMA_S1_CURR_DESC_PTR,val) +#define bfin_read_MDMA_S1_CURR_ADDR() bfin_read32(MDMA_S1_CURR_ADDR) +#define bfin_write_MDMA_S1_CURR_ADDR(val) bfin_write32(MDMA_S1_CURR_ADDR,val) +#define bfin_read_MDMA_S1_CURR_X_COUNT() bfin_read16(MDMA_S1_CURR_X_COUNT) +#define bfin_write_MDMA_S1_CURR_X_COUNT(val) bfin_write16(MDMA_S1_CURR_X_COUNT,val) +#define bfin_read_MDMA_S1_CURR_Y_COUNT() bfin_read16(MDMA_S1_CURR_Y_COUNT) +#define bfin_write_MDMA_S1_CURR_Y_COUNT(val) bfin_write16(MDMA_S1_CURR_Y_COUNT,val) +#define bfin_read_MDMA_S1_IRQ_STATUS() bfin_read16(MDMA_S1_IRQ_STATUS) +#define bfin_write_MDMA_S1_IRQ_STATUS(val) bfin_write16(MDMA_S1_IRQ_STATUS,val) +#define bfin_read_MDMA_S1_PERIPHERAL_MAP() bfin_read16(MDMA_S1_PERIPHERAL_MAP) +#define bfin_write_MDMA_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA_S1_PERIPHERAL_MAP,val) + +#define bfin_read_MDMA_D0_CONFIG() bfin_read16(MDMA_D0_CONFIG) +#define bfin_write_MDMA_D0_CONFIG(val) bfin_write16(MDMA_D0_CONFIG,val) +#define bfin_read_MDMA_D0_NEXT_DESC_PTR() bfin_read32(MDMA_D0_NEXT_DESC_PTR) +#define bfin_write_MDMA_D0_NEXT_DESC_PTR(val) bfin_write32(MDMA_D0_NEXT_DESC_PTR,val) +#define bfin_read_MDMA_D0_START_ADDR() bfin_read32(MDMA_D0_START_ADDR) +#define bfin_write_MDMA_D0_START_ADDR(val) bfin_write32(MDMA_D0_START_ADDR,val) +#define bfin_read_MDMA_D0_X_COUNT() bfin_read16(MDMA_D0_X_COUNT) +#define bfin_write_MDMA_D0_X_COUNT(val) bfin_write16(MDMA_D0_X_COUNT,val) +#define bfin_read_MDMA_D0_Y_COUNT() bfin_read16(MDMA_D0_Y_COUNT) +#define bfin_write_MDMA_D0_Y_COUNT(val) bfin_write16(MDMA_D0_Y_COUNT,val) +#define bfin_read_MDMA_D0_X_MODIFY() bfin_read16(MDMA_D0_X_MODIFY) +#define bfin_write_MDMA_D0_X_MODIFY(val) bfin_write16(MDMA_D0_X_MODIFY,val) +#define bfin_read_MDMA_D0_Y_MODIFY() bfin_read16(MDMA_D0_Y_MODIFY) +#define bfin_write_MDMA_D0_Y_MODIFY(val) bfin_write16(MDMA_D0_Y_MODIFY,val) +#define bfin_read_MDMA_D0_CURR_DESC_PTR() bfin_read32(MDMA_D0_CURR_DESC_PTR) +#define bfin_write_MDMA_D0_CURR_DESC_PTR(val) bfin_write32(MDMA_D0_CURR_DESC_PTR,val) +#define bfin_read_MDMA_D0_CURR_ADDR() bfin_read32(MDMA_D0_CURR_ADDR) +#define bfin_write_MDMA_D0_CURR_ADDR(val) bfin_write32(MDMA_D0_CURR_ADDR,val) +#define bfin_read_MDMA_D0_CURR_X_COUNT() bfin_read16(MDMA_D0_CURR_X_COUNT) +#define bfin_write_MDMA_D0_CURR_X_COUNT(val) bfin_write16(MDMA_D0_CURR_X_COUNT,val) +#define bfin_read_MDMA_D0_CURR_Y_COUNT() bfin_read16(MDMA_D0_CURR_Y_COUNT) +#define bfin_write_MDMA_D0_CURR_Y_COUNT(val) bfin_write16(MDMA_D0_CURR_Y_COUNT,val) +#define bfin_read_MDMA_D0_IRQ_STATUS() bfin_read16(MDMA_D0_IRQ_STATUS) +#define bfin_write_MDMA_D0_IRQ_STATUS(val) bfin_write16(MDMA_D0_IRQ_STATUS,val) +#define bfin_read_MDMA_D0_PERIPHERAL_MAP() bfin_read16(MDMA_D0_PERIPHERAL_MAP) +#define bfin_write_MDMA_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA_D0_PERIPHERAL_MAP,val) + +#define bfin_read_MDMA_S0_CONFIG() bfin_read16(MDMA_S0_CONFIG) +#define bfin_write_MDMA_S0_CONFIG(val) bfin_write16(MDMA_S0_CONFIG,val) +#define bfin_read_MDMA_S0_NEXT_DESC_PTR() bfin_read32(MDMA_S0_NEXT_DESC_PTR) +#define bfin_write_MDMA_S0_NEXT_DESC_PTR(val) bfin_write32(MDMA_S0_NEXT_DESC_PTR,val) +#define bfin_read_MDMA_S0_START_ADDR() bfin_read32(MDMA_S0_START_ADDR) +#define bfin_write_MDMA_S0_START_ADDR(val) bfin_write32(MDMA_S0_START_ADDR,val) +#define bfin_read_MDMA_S0_X_COUNT() bfin_read16(MDMA_S0_X_COUNT) +#define bfin_write_MDMA_S0_X_COUNT(val) bfin_write16(MDMA_S0_X_COUNT,val) +#define bfin_read_MDMA_S0_Y_COUNT() bfin_read16(MDMA_S0_Y_COUNT) +#define bfin_write_MDMA_S0_Y_COUNT(val) bfin_write16(MDMA_S0_Y_COUNT,val) +#define bfin_read_MDMA_S0_X_MODIFY() bfin_read16(MDMA_S0_X_MODIFY) +#define bfin_write_MDMA_S0_X_MODIFY(val) bfin_write16(MDMA_S0_X_MODIFY,val) +#define bfin_read_MDMA_S0_Y_MODIFY() bfin_read16(MDMA_S0_Y_MODIFY) +#define bfin_write_MDMA_S0_Y_MODIFY(val) bfin_write16(MDMA_S0_Y_MODIFY,val) +#define bfin_read_MDMA_S0_CURR_DESC_PTR() bfin_read32(MDMA_S0_CURR_DESC_PTR) +#define bfin_write_MDMA_S0_CURR_DESC_PTR(val) bfin_write32(MDMA_S0_CURR_DESC_PTR,val) +#define bfin_read_MDMA_S0_CURR_ADDR() bfin_read32(MDMA_S0_CURR_ADDR) +#define bfin_write_MDMA_S0_CURR_ADDR(val) bfin_write32(MDMA_S0_CURR_ADDR,val) +#define bfin_read_MDMA_S0_CURR_X_COUNT() bfin_read16(MDMA_S0_CURR_X_COUNT) +#define bfin_write_MDMA_S0_CURR_X_COUNT(val) bfin_write16(MDMA_S0_CURR_X_COUNT,val) +#define bfin_read_MDMA_S0_CURR_Y_COUNT() bfin_read16(MDMA_S0_CURR_Y_COUNT) +#define bfin_write_MDMA_S0_CURR_Y_COUNT(val) bfin_write16(MDMA_S0_CURR_Y_COUNT,val) +#define bfin_read_MDMA_S0_IRQ_STATUS() bfin_read16(MDMA_S0_IRQ_STATUS) +#define bfin_write_MDMA_S0_IRQ_STATUS(val) bfin_write16(MDMA_S0_IRQ_STATUS,val) +#define bfin_read_MDMA_S0_PERIPHERAL_MAP() bfin_read16(MDMA_S0_PERIPHERAL_MAP) +#define bfin_write_MDMA_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA_S0_PERIPHERAL_MAP,val) + +/* Aysnchronous Memory Controller - External Bus Interface Unit (0xFFC0 3C00-0xFFC0 3FFF) */ +#define bfin_read_EBIU_AMGCTL() bfin_read16(EBIU_AMGCTL) +#define bfin_write_EBIU_AMGCTL(val) bfin_write16(EBIU_AMGCTL,val) +#define bfin_read_EBIU_AMBCTL0() bfin_read32(EBIU_AMBCTL0) +#define bfin_write_EBIU_AMBCTL0(val) bfin_write32(EBIU_AMBCTL0,val) +#define bfin_read_EBIU_AMBCTL1() bfin_read32(EBIU_AMBCTL1) +#define bfin_write_EBIU_AMBCTL1(val) bfin_write32(EBIU_AMBCTL1,val) + +/* SDRAM Controller External Bus Interface Unit (0xFFC0 4C00-0xFFC0 4FFF) */ +#define bfin_read_EBIU_SDGCTL() bfin_read32(EBIU_SDGCTL) +#define bfin_write_EBIU_SDGCTL(val) bfin_write32(EBIU_SDGCTL,val) +#define bfin_read_EBIU_SDRRC() bfin_read16(EBIU_SDRRC) +#define bfin_write_EBIU_SDRRC(val) bfin_write16(EBIU_SDRRC,val) +#define bfin_read_EBIU_SDSTAT() bfin_read16(EBIU_SDSTAT) +#define bfin_write_EBIU_SDSTAT(val) bfin_write16(EBIU_SDSTAT,val) +#define bfin_read_EBIU_SDBCTL() bfin_read16(EBIU_SDBCTL) +#define bfin_write_EBIU_SDBCTL(val) bfin_write16(EBIU_SDBCTL,val) + +/* UART Controller */ +#define bfin_read_UART_THR() bfin_read16(UART_THR) +#define bfin_write_UART_THR(val) bfin_write16(UART_THR,val) +#define bfin_read_UART_RBR() bfin_read16(UART_RBR) +#define bfin_write_UART_RBR(val) bfin_write16(UART_RBR,val) +#define bfin_read_UART_DLL() bfin_read16(UART_DLL) +#define bfin_write_UART_DLL(val) bfin_write16(UART_DLL,val) +#define bfin_read_UART_IER() bfin_read16(UART_IER) +#define bfin_write_UART_IER(val) bfin_write16(UART_IER,val) +#define bfin_read_UART_DLH() bfin_read16(UART_DLH) +#define bfin_write_UART_DLH(val) bfin_write16(UART_DLH,val) +#define bfin_read_UART_IIR() bfin_read16(UART_IIR) +#define bfin_write_UART_IIR(val) bfin_write16(UART_IIR,val) +#define bfin_read_UART_LCR() bfin_read16(UART_LCR) +#define bfin_write_UART_LCR(val) bfin_write16(UART_LCR,val) +#define bfin_read_UART_MCR() bfin_read16(UART_MCR) +#define bfin_write_UART_MCR(val) bfin_write16(UART_MCR,val) +#define bfin_read_UART_LSR() bfin_read16(UART_LSR) +#define bfin_write_UART_LSR(val) bfin_write16(UART_LSR,val) +/* +#define UART_MSR +*/ +#define bfin_read_UART_SCR() bfin_read16(UART_SCR) +#define bfin_write_UART_SCR(val) bfin_write16(UART_SCR,val) +#define bfin_read_UART_GCTL() bfin_read16(UART_GCTL) +#define bfin_write_UART_GCTL(val) bfin_write16(UART_GCTL,val) + +/* SPI Controller */ +#define bfin_read_SPI_CTL() bfin_read16(SPI_CTL) +#define bfin_write_SPI_CTL(val) bfin_write16(SPI_CTL,val) +#define bfin_read_SPI_FLG() bfin_read16(SPI_FLG) +#define bfin_write_SPI_FLG(val) bfin_write16(SPI_FLG,val) +#define bfin_read_SPI_STAT() bfin_read16(SPI_STAT) +#define bfin_write_SPI_STAT(val) bfin_write16(SPI_STAT,val) +#define bfin_read_SPI_TDBR() bfin_read16(SPI_TDBR) +#define bfin_write_SPI_TDBR(val) bfin_write16(SPI_TDBR,val) +#define bfin_read_SPI_RDBR() bfin_read16(SPI_RDBR) +#define bfin_write_SPI_RDBR(val) bfin_write16(SPI_RDBR,val) +#define bfin_read_SPI_BAUD() bfin_read16(SPI_BAUD) +#define bfin_write_SPI_BAUD(val) bfin_write16(SPI_BAUD,val) +#define bfin_read_SPI_SHADOW() bfin_read16(SPI_SHADOW) +#define bfin_write_SPI_SHADOW(val) bfin_write16(SPI_SHADOW,val) + +/* TIMER 0, 1, 2 Registers */ +#define bfin_read_TIMER0_CONFIG() bfin_read16(TIMER0_CONFIG) +#define bfin_write_TIMER0_CONFIG(val) bfin_write16(TIMER0_CONFIG,val) +#define bfin_read_TIMER0_COUNTER() bfin_read32(TIMER0_COUNTER) +#define bfin_write_TIMER0_COUNTER(val) bfin_write32(TIMER0_COUNTER,val) +#define bfin_read_TIMER0_PERIOD() bfin_read32(TIMER0_PERIOD) +#define bfin_write_TIMER0_PERIOD(val) bfin_write32(TIMER0_PERIOD,val) +#define bfin_read_TIMER0_WIDTH() bfin_read32(TIMER0_WIDTH) +#define bfin_write_TIMER0_WIDTH(val) bfin_write32(TIMER0_WIDTH,val) + +#define bfin_read_TIMER1_CONFIG() bfin_read16(TIMER1_CONFIG) +#define bfin_write_TIMER1_CONFIG(val) bfin_write16(TIMER1_CONFIG,val) +#define bfin_read_TIMER1_COUNTER() bfin_read32(TIMER1_COUNTER) +#define bfin_write_TIMER1_COUNTER(val) bfin_write32(TIMER1_COUNTER,val) +#define bfin_read_TIMER1_PERIOD() bfin_read32(TIMER1_PERIOD) +#define bfin_write_TIMER1_PERIOD(val) bfin_write32(TIMER1_PERIOD,val) +#define bfin_read_TIMER1_WIDTH() bfin_read32(TIMER1_WIDTH) +#define bfin_write_TIMER1_WIDTH(val) bfin_write32(TIMER1_WIDTH,val) + +#define bfin_read_TIMER2_CONFIG() bfin_read16(TIMER2_CONFIG) +#define bfin_write_TIMER2_CONFIG(val) bfin_write16(TIMER2_CONFIG,val) +#define bfin_read_TIMER2_COUNTER() bfin_read32(TIMER2_COUNTER) +#define bfin_write_TIMER2_COUNTER(val) bfin_write32(TIMER2_COUNTER,val) +#define bfin_read_TIMER2_PERIOD() bfin_read32(TIMER2_PERIOD) +#define bfin_write_TIMER2_PERIOD(val) bfin_write32(TIMER2_PERIOD,val) +#define bfin_read_TIMER2_WIDTH() bfin_read32(TIMER2_WIDTH) +#define bfin_write_TIMER2_WIDTH(val) bfin_write32(TIMER2_WIDTH,val) + +#define bfin_read_TIMER_ENABLE() bfin_read16(TIMER_ENABLE) +#define bfin_write_TIMER_ENABLE(val) bfin_write16(TIMER_ENABLE,val) +#define bfin_read_TIMER_DISABLE() bfin_read16(TIMER_DISABLE) +#define bfin_write_TIMER_DISABLE(val) bfin_write16(TIMER_DISABLE,val) +#define bfin_read_TIMER_STATUS() bfin_read16(TIMER_STATUS) +#define bfin_write_TIMER_STATUS(val) bfin_write16(TIMER_STATUS,val) + +/* SPORT0 Controller */ +#define bfin_read_SPORT0_TCR1() bfin_read16(SPORT0_TCR1) +#define bfin_write_SPORT0_TCR1(val) bfin_write16(SPORT0_TCR1,val) +#define bfin_read_SPORT0_TCR2() bfin_read16(SPORT0_TCR2) +#define bfin_write_SPORT0_TCR2(val) bfin_write16(SPORT0_TCR2,val) +#define bfin_read_SPORT0_TCLKDIV() bfin_read16(SPORT0_TCLKDIV) +#define bfin_write_SPORT0_TCLKDIV(val) bfin_write16(SPORT0_TCLKDIV,val) +#define bfin_read_SPORT0_TFSDIV() bfin_read16(SPORT0_TFSDIV) +#define bfin_write_SPORT0_TFSDIV(val) bfin_write16(SPORT0_TFSDIV,val) +#define bfin_read_SPORT0_TX() bfin_read32(SPORT0_TX) +#define bfin_write_SPORT0_TX(val) bfin_write32(SPORT0_TX,val) +#define bfin_read_SPORT0_RX() bfin_read32(SPORT0_RX) +#define bfin_write_SPORT0_RX(val) bfin_write32(SPORT0_RX,val) +#define bfin_read_SPORT0_TX32() bfin_read32(SPORT0_TX) +#define bfin_write_SPORT0_TX32(val) bfin_write32(SPORT0_TX,val) +#define bfin_read_SPORT0_RX32() bfin_read32(SPORT0_RX) +#define bfin_write_SPORT0_RX32(val) bfin_write32(SPORT0_RX,val) +#define bfin_read_SPORT0_TX16() bfin_read16(SPORT0_TX) +#define bfin_write_SPORT0_TX16(val) bfin_write16(SPORT0_TX,val) +#define bfin_read_SPORT0_RX16() bfin_read16(SPORT0_RX) +#define bfin_write_SPORT0_RX16(val) bfin_write16(SPORT0_RX,val) +#define bfin_read_SPORT0_RCR1() bfin_read16(SPORT0_RCR1) +#define bfin_write_SPORT0_RCR1(val) bfin_write16(SPORT0_RCR1,val) +#define bfin_read_SPORT0_RCR2() bfin_read16(SPORT0_RCR2) +#define bfin_write_SPORT0_RCR2(val) bfin_write16(SPORT0_RCR2,val) +#define bfin_read_SPORT0_RCLKDIV() bfin_read16(SPORT0_RCLKDIV) +#define bfin_write_SPORT0_RCLKDIV(val) bfin_write16(SPORT0_RCLKDIV,val) +#define bfin_read_SPORT0_RFSDIV() bfin_read16(SPORT0_RFSDIV) +#define bfin_write_SPORT0_RFSDIV(val) bfin_write16(SPORT0_RFSDIV,val) +#define bfin_read_SPORT0_STAT() bfin_read16(SPORT0_STAT) +#define bfin_write_SPORT0_STAT(val) bfin_write16(SPORT0_STAT,val) +#define bfin_read_SPORT0_CHNL() bfin_read16(SPORT0_CHNL) +#define bfin_write_SPORT0_CHNL(val) bfin_write16(SPORT0_CHNL,val) +#define bfin_read_SPORT0_MCMC1() bfin_read16(SPORT0_MCMC1) +#define bfin_write_SPORT0_MCMC1(val) bfin_write16(SPORT0_MCMC1,val) +#define bfin_read_SPORT0_MCMC2() bfin_read16(SPORT0_MCMC2) +#define bfin_write_SPORT0_MCMC2(val) bfin_write16(SPORT0_MCMC2,val) +#define bfin_read_SPORT0_MTCS0() bfin_read32(SPORT0_MTCS0) +#define bfin_write_SPORT0_MTCS0(val) bfin_write32(SPORT0_MTCS0,val) +#define bfin_read_SPORT0_MTCS1() bfin_read32(SPORT0_MTCS1) +#define bfin_write_SPORT0_MTCS1(val) bfin_write32(SPORT0_MTCS1,val) +#define bfin_read_SPORT0_MTCS2() bfin_read32(SPORT0_MTCS2) +#define bfin_write_SPORT0_MTCS2(val) bfin_write32(SPORT0_MTCS2,val) +#define bfin_read_SPORT0_MTCS3() bfin_read32(SPORT0_MTCS3) +#define bfin_write_SPORT0_MTCS3(val) bfin_write32(SPORT0_MTCS3,val) +#define bfin_read_SPORT0_MRCS0() bfin_read32(SPORT0_MRCS0) +#define bfin_write_SPORT0_MRCS0(val) bfin_write32(SPORT0_MRCS0,val) +#define bfin_read_SPORT0_MRCS1() bfin_read32(SPORT0_MRCS1) +#define bfin_write_SPORT0_MRCS1(val) bfin_write32(SPORT0_MRCS1,val) +#define bfin_read_SPORT0_MRCS2() bfin_read32(SPORT0_MRCS2) +#define bfin_write_SPORT0_MRCS2(val) bfin_write32(SPORT0_MRCS2,val) +#define bfin_read_SPORT0_MRCS3() bfin_read32(SPORT0_MRCS3) +#define bfin_write_SPORT0_MRCS3(val) bfin_write32(SPORT0_MRCS3,val) + +/* SPORT1 Controller */ +#define bfin_read_SPORT1_TCR1() bfin_read16(SPORT1_TCR1) +#define bfin_write_SPORT1_TCR1(val) bfin_write16(SPORT1_TCR1,val) +#define bfin_read_SPORT1_TCR2() bfin_read16(SPORT1_TCR2) +#define bfin_write_SPORT1_TCR2(val) bfin_write16(SPORT1_TCR2,val) +#define bfin_read_SPORT1_TCLKDIV() bfin_read16(SPORT1_TCLKDIV) +#define bfin_write_SPORT1_TCLKDIV(val) bfin_write16(SPORT1_TCLKDIV,val) +#define bfin_read_SPORT1_TFSDIV() bfin_read16(SPORT1_TFSDIV) +#define bfin_write_SPORT1_TFSDIV(val) bfin_write16(SPORT1_TFSDIV,val) +#define bfin_read_SPORT1_TX() bfin_read32(SPORT1_TX) +#define bfin_write_SPORT1_TX(val) bfin_write32(SPORT1_TX,val) +#define bfin_read_SPORT1_RX() bfin_read32(SPORT1_RX) +#define bfin_write_SPORT1_RX(val) bfin_write32(SPORT1_RX,val) +#define bfin_read_SPORT1_TX32() bfin_read32(SPORT1_TX) +#define bfin_write_SPORT1_TX32(val) bfin_write32(SPORT1_TX,val) +#define bfin_read_SPORT1_RX32() bfin_read32(SPORT1_RX) +#define bfin_write_SPORT1_RX32(val) bfin_write32(SPORT1_RX,val) +#define bfin_read_SPORT1_TX16() bfin_read16(SPORT1_TX) +#define bfin_write_SPORT1_TX16(val) bfin_write16(SPORT1_TX,val) +#define bfin_read_SPORT1_RX16() bfin_read16(SPORT1_RX) +#define bfin_write_SPORT1_RX16(val) bfin_write16(SPORT1_RX,val) +#define bfin_read_SPORT1_RCR1() bfin_read16(SPORT1_RCR1) +#define bfin_write_SPORT1_RCR1(val) bfin_write16(SPORT1_RCR1,val) +#define bfin_read_SPORT1_RCR2() bfin_read16(SPORT1_RCR2) +#define bfin_write_SPORT1_RCR2(val) bfin_write16(SPORT1_RCR2,val) +#define bfin_read_SPORT1_RCLKDIV() bfin_read16(SPORT1_RCLKDIV) +#define bfin_write_SPORT1_RCLKDIV(val) bfin_write16(SPORT1_RCLKDIV,val) +#define bfin_read_SPORT1_RFSDIV() bfin_read16(SPORT1_RFSDIV) +#define bfin_write_SPORT1_RFSDIV(val) bfin_write16(SPORT1_RFSDIV,val) +#define bfin_read_SPORT1_STAT() bfin_read16(SPORT1_STAT) +#define bfin_write_SPORT1_STAT(val) bfin_write16(SPORT1_STAT,val) +#define bfin_read_SPORT1_CHNL() bfin_read16(SPORT1_CHNL) +#define bfin_write_SPORT1_CHNL(val) bfin_write16(SPORT1_CHNL,val) +#define bfin_read_SPORT1_MCMC1() bfin_read16(SPORT1_MCMC1) +#define bfin_write_SPORT1_MCMC1(val) bfin_write16(SPORT1_MCMC1,val) +#define bfin_read_SPORT1_MCMC2() bfin_read16(SPORT1_MCMC2) +#define bfin_write_SPORT1_MCMC2(val) bfin_write16(SPORT1_MCMC2,val) +#define bfin_read_SPORT1_MTCS0() bfin_read32(SPORT1_MTCS0) +#define bfin_write_SPORT1_MTCS0(val) bfin_write32(SPORT1_MTCS0,val) +#define bfin_read_SPORT1_MTCS1() bfin_read32(SPORT1_MTCS1) +#define bfin_write_SPORT1_MTCS1(val) bfin_write32(SPORT1_MTCS1,val) +#define bfin_read_SPORT1_MTCS2() bfin_read32(SPORT1_MTCS2) +#define bfin_write_SPORT1_MTCS2(val) bfin_write32(SPORT1_MTCS2,val) +#define bfin_read_SPORT1_MTCS3() bfin_read32(SPORT1_MTCS3) +#define bfin_write_SPORT1_MTCS3(val) bfin_write32(SPORT1_MTCS3,val) +#define bfin_read_SPORT1_MRCS0() bfin_read32(SPORT1_MRCS0) +#define bfin_write_SPORT1_MRCS0(val) bfin_write32(SPORT1_MRCS0,val) +#define bfin_read_SPORT1_MRCS1() bfin_read32(SPORT1_MRCS1) +#define bfin_write_SPORT1_MRCS1(val) bfin_write32(SPORT1_MRCS1,val) +#define bfin_read_SPORT1_MRCS2() bfin_read32(SPORT1_MRCS2) +#define bfin_write_SPORT1_MRCS2(val) bfin_write32(SPORT1_MRCS2,val) +#define bfin_read_SPORT1_MRCS3() bfin_read32(SPORT1_MRCS3) +#define bfin_write_SPORT1_MRCS3(val) bfin_write32(SPORT1_MRCS3,val) + +/* Parallel Peripheral Interface (PPI) */ +#define bfin_read_PPI_CONTROL() bfin_read16(PPI_CONTROL) +#define bfin_write_PPI_CONTROL(val) bfin_write16(PPI_CONTROL,val) +#define bfin_read_PPI_STATUS() bfin_read16(PPI_STATUS) +#define bfin_write_PPI_STATUS(val) bfin_write16(PPI_STATUS,val) +#define bfin_clear_PPI_STATUS() bfin_read_PPI_STATUS() +#define bfin_read_PPI_DELAY() bfin_read16(PPI_DELAY) +#define bfin_write_PPI_DELAY(val) bfin_write16(PPI_DELAY,val) +#define bfin_read_PPI_COUNT() bfin_read16(PPI_COUNT) +#define bfin_write_PPI_COUNT(val) bfin_write16(PPI_COUNT,val) +#define bfin_read_PPI_FRAME() bfin_read16(PPI_FRAME) +#define bfin_write_PPI_FRAME(val) bfin_write16(PPI_FRAME,val) + +#endif /* _CDEF_BF532_H */ diff --git a/include/asm-blackfin/mach-bf533/defBF532.h b/include/asm-blackfin/mach-bf533/defBF532.h new file mode 100644 index 000000000000..b240a082aa09 --- /dev/null +++ b/include/asm-blackfin/mach-bf533/defBF532.h @@ -0,0 +1,1175 @@ +/************************************************************************ + * + * This file is subject to the terms and conditions of the GNU Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Non-GPL License also available as part of VisualDSP++ + * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html + * + * (c) Copyright 2001-2005 Analog Devices, Inc. All rights reserved + * + * This file under source code control, please send bugs or changes to: + * dsptools.support@analog.com + * + ************************************************************************/ +/* + * File: include/asm-blackfin/mach-bf533/defBF532.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Rev: + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +/* SYSTEM & MM REGISTER BIT & ADDRESS DEFINITIONS FOR ADSP-BF532 */ + +#ifndef _DEF_BF532_H +#define _DEF_BF532_H +/* +#if !defined(__ADSPLPBLACKFIN__) +#warning defBF532.h should only be included for 532 compatible chips +#endif +*/ +/* include all Core registers and bit definitions */ +#include + +/*********************************************************************************** */ +/* System MMR Register Map */ +/*********************************************************************************** */ +/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */ + +#define PLL_CTL 0xFFC00000 /* PLL Control register (16-bit) */ +#define PLL_DIV 0xFFC00004 /* PLL Divide Register (16-bit) */ +#define VR_CTL 0xFFC00008 /* Voltage Regulator Control Register (16-bit) */ +#define PLL_STAT 0xFFC0000C /* PLL Status register (16-bit) */ +#define PLL_LOCKCNT 0xFFC00010 /* PLL Lock Count register (16-bit) */ +#define CHIPID 0xFFC00014 /* Chip ID Register */ +#define SWRST 0xFFC00100 /* Software Reset Register (16-bit) */ +#define SYSCR 0xFFC00104 /* System Configuration registe */ + +/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */ +#define SIC_RVECT 0xFFC00108 /* Interrupt Reset Vector Address Register */ +#define SIC_IMASK 0xFFC0010C /* Interrupt Mask Register */ +#define SIC_IAR0 0xFFC00110 /* Interrupt Assignment Register 0 */ +#define SIC_IAR1 0xFFC00114 /* Interrupt Assignment Register 1 */ +#define SIC_IAR2 0xFFC00118 /* Interrupt Assignment Register 2 */ +#define SIC_ISR 0xFFC00120 /* Interrupt Status Register */ +#define SIC_IWR 0xFFC00124 /* Interrupt Wakeup Register */ + +/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */ +#define WDOG_CTL 0xFFC00200 /* Watchdog Control Register */ +#define WDOG_CNT 0xFFC00204 /* Watchdog Count Register */ +#define WDOG_STAT 0xFFC00208 /* Watchdog Status Register */ + +/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */ +#define RTC_STAT 0xFFC00300 /* RTC Status Register */ +#define RTC_ICTL 0xFFC00304 /* RTC Interrupt Control Register */ +#define RTC_ISTAT 0xFFC00308 /* RTC Interrupt Status Register */ +#define RTC_SWCNT 0xFFC0030C /* RTC Stopwatch Count Register */ +#define RTC_ALARM 0xFFC00310 /* RTC Alarm Time Register */ +#define RTC_FAST 0xFFC00314 /* RTC Prescaler Enable Register */ +#define RTC_PREN 0xFFC00314 /* RTC Prescaler Enable Register (alternate macro) */ + +/* UART Controller (0xFFC00400 - 0xFFC004FF) */ +#define UART_THR 0xFFC00400 /* Transmit Holding register */ +#define UART_RBR 0xFFC00400 /* Receive Buffer register */ +#define UART_DLL 0xFFC00400 /* Divisor Latch (Low-Byte) */ +#define UART_IER 0xFFC00404 /* Interrupt Enable Register */ +#define UART_DLH 0xFFC00404 /* Divisor Latch (High-Byte) */ +#define UART_IIR 0xFFC00408 /* Interrupt Identification Register */ +#define UART_LCR 0xFFC0040C /* Line Control Register */ +#define UART_MCR 0xFFC00410 /* Modem Control Register */ +#define UART_LSR 0xFFC00414 /* Line Status Register */ +#if 0 +#define UART_MSR 0xFFC00418 /* Modem Status Register (UNUSED in ADSP-BF532) */ +#endif +#define UART_SCR 0xFFC0041C /* SCR Scratch Register */ +#define UART_GCTL 0xFFC00424 /* Global Control Register */ + +/* SPI Controller (0xFFC00500 - 0xFFC005FF) */ +#define SPI_CTL 0xFFC00500 /* SPI Control Register */ +#define SPI_FLG 0xFFC00504 /* SPI Flag register */ +#define SPI_STAT 0xFFC00508 /* SPI Status register */ +#define SPI_TDBR 0xFFC0050C /* SPI Transmit Data Buffer Register */ +#define SPI_RDBR 0xFFC00510 /* SPI Receive Data Buffer Register */ +#define SPI_BAUD 0xFFC00514 /* SPI Baud rate Register */ +#define SPI_SHADOW 0xFFC00518 /* SPI_RDBR Shadow Register */ + +/* TIMER 0, 1, 2 Registers (0xFFC00600 - 0xFFC006FF) */ + +#define TIMER0_CONFIG 0xFFC00600 /* Timer 0 Configuration Register */ +#define TIMER0_COUNTER 0xFFC00604 /* Timer 0 Counter Register */ +#define TIMER0_PERIOD 0xFFC00608 /* Timer 0 Period Register */ +#define TIMER0_WIDTH 0xFFC0060C /* Timer 0 Width Register */ + +#define TIMER1_CONFIG 0xFFC00610 /* Timer 1 Configuration Register */ +#define TIMER1_COUNTER 0xFFC00614 /* Timer 1 Counter Register */ +#define TIMER1_PERIOD 0xFFC00618 /* Timer 1 Period Register */ +#define TIMER1_WIDTH 0xFFC0061C /* Timer 1 Width Register */ + +#define TIMER2_CONFIG 0xFFC00620 /* Timer 2 Configuration Register */ +#define TIMER2_COUNTER 0xFFC00624 /* Timer 2 Counter Register */ +#define TIMER2_PERIOD 0xFFC00628 /* Timer 2 Period Register */ +#define TIMER2_WIDTH 0xFFC0062C /* Timer 2 Width Register */ + +#define TIMER_ENABLE 0xFFC00640 /* Timer Enable Register */ +#define TIMER_DISABLE 0xFFC00644 /* Timer Disable Register */ +#define TIMER_STATUS 0xFFC00648 /* Timer Status Register */ + +/* General Purpose IO (0xFFC00700 - 0xFFC007FF) */ + +#define FIO_FLAG_D 0xFFC00700 /* Flag Mask to directly specify state of pins */ +#define FIO_FLAG_C 0xFFC00704 /* Peripheral Interrupt Flag Register (clear) */ +#define FIO_FLAG_S 0xFFC00708 /* Peripheral Interrupt Flag Register (set) */ +#define FIO_FLAG_T 0xFFC0070C /* Flag Mask to directly toggle state of pins */ +#define FIO_MASKA_D 0xFFC00710 /* Flag Mask Interrupt A Register (set directly) */ +#define FIO_MASKA_C 0xFFC00714 /* Flag Mask Interrupt A Register (clear) */ +#define FIO_MASKA_S 0xFFC00718 /* Flag Mask Interrupt A Register (set) */ +#define FIO_MASKA_T 0xFFC0071C /* Flag Mask Interrupt A Register (toggle) */ +#define FIO_MASKB_D 0xFFC00720 /* Flag Mask Interrupt B Register (set directly) */ +#define FIO_MASKB_C 0xFFC00724 /* Flag Mask Interrupt B Register (clear) */ +#define FIO_MASKB_S 0xFFC00728 /* Flag Mask Interrupt B Register (set) */ +#define FIO_MASKB_T 0xFFC0072C /* Flag Mask Interrupt B Register (toggle) */ +#define FIO_DIR 0xFFC00730 /* Peripheral Flag Direction Register */ +#define FIO_POLAR 0xFFC00734 /* Flag Source Polarity Register */ +#define FIO_EDGE 0xFFC00738 /* Flag Source Sensitivity Register */ +#define FIO_BOTH 0xFFC0073C /* Flag Set on BOTH Edges Register */ +#define FIO_INEN 0xFFC00740 /* Flag Input Enable Register */ + +/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */ +#define SPORT0_TCR1 0xFFC00800 /* SPORT0 Transmit Configuration 1 Register */ +#define SPORT0_TCR2 0xFFC00804 /* SPORT0 Transmit Configuration 2 Register */ +#define SPORT0_TCLKDIV 0xFFC00808 /* SPORT0 Transmit Clock Divider */ +#define SPORT0_TFSDIV 0xFFC0080C /* SPORT0 Transmit Frame Sync Divider */ +#define SPORT0_TX 0xFFC00810 /* SPORT0 TX Data Register */ +#define SPORT0_RX 0xFFC00818 /* SPORT0 RX Data Register */ +#define SPORT0_RCR1 0xFFC00820 /* SPORT0 Transmit Configuration 1 Register */ +#define SPORT0_RCR2 0xFFC00824 /* SPORT0 Transmit Configuration 2 Register */ +#define SPORT0_RCLKDIV 0xFFC00828 /* SPORT0 Receive Clock Divider */ +#define SPORT0_RFSDIV 0xFFC0082C /* SPORT0 Receive Frame Sync Divider */ +#define SPORT0_STAT 0xFFC00830 /* SPORT0 Status Register */ +#define SPORT0_CHNL 0xFFC00834 /* SPORT0 Current Channel Register */ +#define SPORT0_MCMC1 0xFFC00838 /* SPORT0 Multi-Channel Configuration Register 1 */ +#define SPORT0_MCMC2 0xFFC0083C /* SPORT0 Multi-Channel Configuration Register 2 */ +#define SPORT0_MTCS0 0xFFC00840 /* SPORT0 Multi-Channel Transmit Select Register 0 */ +#define SPORT0_MTCS1 0xFFC00844 /* SPORT0 Multi-Channel Transmit Select Register 1 */ +#define SPORT0_MTCS2 0xFFC00848 /* SPORT0 Multi-Channel Transmit Select Register 2 */ +#define SPORT0_MTCS3 0xFFC0084C /* SPORT0 Multi-Channel Transmit Select Register 3 */ +#define SPORT0_MRCS0 0xFFC00850 /* SPORT0 Multi-Channel Receive Select Register 0 */ +#define SPORT0_MRCS1 0xFFC00854 /* SPORT0 Multi-Channel Receive Select Register 1 */ +#define SPORT0_MRCS2 0xFFC00858 /* SPORT0 Multi-Channel Receive Select Register 2 */ +#define SPORT0_MRCS3 0xFFC0085C /* SPORT0 Multi-Channel Receive Select Register 3 */ + +/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */ +#define SPORT1_TCR1 0xFFC00900 /* SPORT1 Transmit Configuration 1 Register */ +#define SPORT1_TCR2 0xFFC00904 /* SPORT1 Transmit Configuration 2 Register */ +#define SPORT1_TCLKDIV 0xFFC00908 /* SPORT1 Transmit Clock Divider */ +#define SPORT1_TFSDIV 0xFFC0090C /* SPORT1 Transmit Frame Sync Divider */ +#define SPORT1_TX 0xFFC00910 /* SPORT1 TX Data Register */ +#define SPORT1_RX 0xFFC00918 /* SPORT1 RX Data Register */ +#define SPORT1_RCR1 0xFFC00920 /* SPORT1 Transmit Configuration 1 Register */ +#define SPORT1_RCR2 0xFFC00924 /* SPORT1 Transmit Configuration 2 Register */ +#define SPORT1_RCLKDIV 0xFFC00928 /* SPORT1 Receive Clock Divider */ +#define SPORT1_RFSDIV 0xFFC0092C /* SPORT1 Receive Frame Sync Divider */ +#define SPORT1_STAT 0xFFC00930 /* SPORT1 Status Register */ +#define SPORT1_CHNL 0xFFC00934 /* SPORT1 Current Channel Register */ +#define SPORT1_MCMC1 0xFFC00938 /* SPORT1 Multi-Channel Configuration Register 1 */ +#define SPORT1_MCMC2 0xFFC0093C /* SPORT1 Multi-Channel Configuration Register 2 */ +#define SPORT1_MTCS0 0xFFC00940 /* SPORT1 Multi-Channel Transmit Select Register 0 */ +#define SPORT1_MTCS1 0xFFC00944 /* SPORT1 Multi-Channel Transmit Select Register 1 */ +#define SPORT1_MTCS2 0xFFC00948 /* SPORT1 Multi-Channel Transmit Select Register 2 */ +#define SPORT1_MTCS3 0xFFC0094C /* SPORT1 Multi-Channel Transmit Select Register 3 */ +#define SPORT1_MRCS0 0xFFC00950 /* SPORT1 Multi-Channel Receive Select Register 0 */ +#define SPORT1_MRCS1 0xFFC00954 /* SPORT1 Multi-Channel Receive Select Register 1 */ +#define SPORT1_MRCS2 0xFFC00958 /* SPORT1 Multi-Channel Receive Select Register 2 */ +#define SPORT1_MRCS3 0xFFC0095C /* SPORT1 Multi-Channel Receive Select Register 3 */ + +/* Asynchronous Memory Controller - External Bus Interface Unit */ +#define EBIU_AMGCTL 0xFFC00A00 /* Asynchronous Memory Global Control Register */ +#define EBIU_AMBCTL0 0xFFC00A04 /* Asynchronous Memory Bank Control Register 0 */ +#define EBIU_AMBCTL1 0xFFC00A08 /* Asynchronous Memory Bank Control Register 1 */ + +/* SDRAM Controller External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */ + +#define EBIU_SDGCTL 0xFFC00A10 /* SDRAM Global Control Register */ +#define EBIU_SDBCTL 0xFFC00A14 /* SDRAM Bank Control Register */ +#define EBIU_SDRRC 0xFFC00A18 /* SDRAM Refresh Rate Control Register */ +#define EBIU_SDSTAT 0xFFC00A1C /* SDRAM Status Register */ + +/* DMA Traffic controls */ +#define DMA_TCPER 0xFFC00B0C /* Traffic Control Periods Register */ +#define DMA_TCCNT 0xFFC00B10 /* Traffic Control Current Counts Register */ +#define DMA_TC_PER 0xFFC00B0C /* Traffic Control Periods Register */ +#define DMA_TC_CNT 0xFFC00B10 /* Traffic Control Current Counts Register */ + +/* DMA Controller (0xFFC00C00 - 0xFFC00FFF) */ +#define DMA0_CONFIG 0xFFC00C08 /* DMA Channel 0 Configuration Register */ +#define DMA0_NEXT_DESC_PTR 0xFFC00C00 /* DMA Channel 0 Next Descriptor Pointer Register */ +#define DMA0_START_ADDR 0xFFC00C04 /* DMA Channel 0 Start Address Register */ +#define DMA0_X_COUNT 0xFFC00C10 /* DMA Channel 0 X Count Register */ +#define DMA0_Y_COUNT 0xFFC00C18 /* DMA Channel 0 Y Count Register */ +#define DMA0_X_MODIFY 0xFFC00C14 /* DMA Channel 0 X Modify Register */ +#define DMA0_Y_MODIFY 0xFFC00C1C /* DMA Channel 0 Y Modify Register */ +#define DMA0_CURR_DESC_PTR 0xFFC00C20 /* DMA Channel 0 Current Descriptor Pointer Register */ +#define DMA0_CURR_ADDR 0xFFC00C24 /* DMA Channel 0 Current Address Register */ +#define DMA0_CURR_X_COUNT 0xFFC00C30 /* DMA Channel 0 Current X Count Register */ +#define DMA0_CURR_Y_COUNT 0xFFC00C38 /* DMA Channel 0 Current Y Count Register */ +#define DMA0_IRQ_STATUS 0xFFC00C28 /* DMA Channel 0 Interrupt/Status Register */ +#define DMA0_PERIPHERAL_MAP 0xFFC00C2C /* DMA Channel 0 Peripheral Map Register */ + +#define DMA1_CONFIG 0xFFC00C48 /* DMA Channel 1 Configuration Register */ +#define DMA1_NEXT_DESC_PTR 0xFFC00C40 /* DMA Channel 1 Next Descriptor Pointer Register */ +#define DMA1_START_ADDR 0xFFC00C44 /* DMA Channel 1 Start Address Register */ +#define DMA1_X_COUNT 0xFFC00C50 /* DMA Channel 1 X Count Register */ +#define DMA1_Y_COUNT 0xFFC00C58 /* DMA Channel 1 Y Count Register */ +#define DMA1_X_MODIFY 0xFFC00C54 /* DMA Channel 1 X Modify Register */ +#define DMA1_Y_MODIFY 0xFFC00C5C /* DMA Channel 1 Y Modify Register */ +#define DMA1_CURR_DESC_PTR 0xFFC00C60 /* DMA Channel 1 Current Descriptor Pointer Register */ +#define DMA1_CURR_ADDR 0xFFC00C64 /* DMA Channel 1 Current Address Register */ +#define DMA1_CURR_X_COUNT 0xFFC00C70 /* DMA Channel 1 Current X Count Register */ +#define DMA1_CURR_Y_COUNT 0xFFC00C78 /* DMA Channel 1 Current Y Count Register */ +#define DMA1_IRQ_STATUS 0xFFC00C68 /* DMA Channel 1 Interrupt/Status Register */ +#define DMA1_PERIPHERAL_MAP 0xFFC00C6C /* DMA Channel 1 Peripheral Map Register */ + +#define DMA2_CONFIG 0xFFC00C88 /* DMA Channel 2 Configuration Register */ +#define DMA2_NEXT_DESC_PTR 0xFFC00C80 /* DMA Channel 2 Next Descriptor Pointer Register */ +#define DMA2_START_ADDR 0xFFC00C84 /* DMA Channel 2 Start Address Register */ +#define DMA2_X_COUNT 0xFFC00C90 /* DMA Channel 2 X Count Register */ +#define DMA2_Y_COUNT 0xFFC00C98 /* DMA Channel 2 Y Count Register */ +#define DMA2_X_MODIFY 0xFFC00C94 /* DMA Channel 2 X Modify Register */ +#define DMA2_Y_MODIFY 0xFFC00C9C /* DMA Channel 2 Y Modify Register */ +#define DMA2_CURR_DESC_PTR 0xFFC00CA0 /* DMA Channel 2 Current Descriptor Pointer Register */ +#define DMA2_CURR_ADDR 0xFFC00CA4 /* DMA Channel 2 Current Address Register */ +#define DMA2_CURR_X_COUNT 0xFFC00CB0 /* DMA Channel 2 Current X Count Register */ +#define DMA2_CURR_Y_COUNT 0xFFC00CB8 /* DMA Channel 2 Current Y Count Register */ +#define DMA2_IRQ_STATUS 0xFFC00CA8 /* DMA Channel 2 Interrupt/Status Register */ +#define DMA2_PERIPHERAL_MAP 0xFFC00CAC /* DMA Channel 2 Peripheral Map Register */ + +#define DMA3_CONFIG 0xFFC00CC8 /* DMA Channel 3 Configuration Register */ +#define DMA3_NEXT_DESC_PTR 0xFFC00CC0 /* DMA Channel 3 Next Descriptor Pointer Register */ +#define DMA3_START_ADDR 0xFFC00CC4 /* DMA Channel 3 Start Address Register */ +#define DMA3_X_COUNT 0xFFC00CD0 /* DMA Channel 3 X Count Register */ +#define DMA3_Y_COUNT 0xFFC00CD8 /* DMA Channel 3 Y Count Register */ +#define DMA3_X_MODIFY 0xFFC00CD4 /* DMA Channel 3 X Modify Register */ +#define DMA3_Y_MODIFY 0xFFC00CDC /* DMA Channel 3 Y Modify Register */ +#define DMA3_CURR_DESC_PTR 0xFFC00CE0 /* DMA Channel 3 Current Descriptor Pointer Register */ +#define DMA3_CURR_ADDR 0xFFC00CE4 /* DMA Channel 3 Current Address Register */ +#define DMA3_CURR_X_COUNT 0xFFC00CF0 /* DMA Channel 3 Current X Count Register */ +#define DMA3_CURR_Y_COUNT 0xFFC00CF8 /* DMA Channel 3 Current Y Count Register */ +#define DMA3_IRQ_STATUS 0xFFC00CE8 /* DMA Channel 3 Interrupt/Status Register */ +#define DMA3_PERIPHERAL_MAP 0xFFC00CEC /* DMA Channel 3 Peripheral Map Register */ + +#define DMA4_CONFIG 0xFFC00D08 /* DMA Channel 4 Configuration Register */ +#define DMA4_NEXT_DESC_PTR 0xFFC00D00 /* DMA Channel 4 Next Descriptor Pointer Register */ +#define DMA4_START_ADDR 0xFFC00D04 /* DMA Channel 4 Start Address Register */ +#define DMA4_X_COUNT 0xFFC00D10 /* DMA Channel 4 X Count Register */ +#define DMA4_Y_COUNT 0xFFC00D18 /* DMA Channel 4 Y Count Register */ +#define DMA4_X_MODIFY 0xFFC00D14 /* DMA Channel 4 X Modify Register */ +#define DMA4_Y_MODIFY 0xFFC00D1C /* DMA Channel 4 Y Modify Register */ +#define DMA4_CURR_DESC_PTR 0xFFC00D20 /* DMA Channel 4 Current Descriptor Pointer Register */ +#define DMA4_CURR_ADDR 0xFFC00D24 /* DMA Channel 4 Current Address Register */ +#define DMA4_CURR_X_COUNT 0xFFC00D30 /* DMA Channel 4 Current X Count Register */ +#define DMA4_CURR_Y_COUNT 0xFFC00D38 /* DMA Channel 4 Current Y Count Register */ +#define DMA4_IRQ_STATUS 0xFFC00D28 /* DMA Channel 4 Interrupt/Status Register */ +#define DMA4_PERIPHERAL_MAP 0xFFC00D2C /* DMA Channel 4 Peripheral Map Register */ + +#define DMA5_CONFIG 0xFFC00D48 /* DMA Channel 5 Configuration Register */ +#define DMA5_NEXT_DESC_PTR 0xFFC00D40 /* DMA Channel 5 Next Descriptor Pointer Register */ +#define DMA5_START_ADDR 0xFFC00D44 /* DMA Channel 5 Start Address Register */ +#define DMA5_X_COUNT 0xFFC00D50 /* DMA Channel 5 X Count Register */ +#define DMA5_Y_COUNT 0xFFC00D58 /* DMA Channel 5 Y Count Register */ +#define DMA5_X_MODIFY 0xFFC00D54 /* DMA Channel 5 X Modify Register */ +#define DMA5_Y_MODIFY 0xFFC00D5C /* DMA Channel 5 Y Modify Register */ +#define DMA5_CURR_DESC_PTR 0xFFC00D60 /* DMA Channel 5 Current Descriptor Pointer Register */ +#define DMA5_CURR_ADDR 0xFFC00D64 /* DMA Channel 5 Current Address Register */ +#define DMA5_CURR_X_COUNT 0xFFC00D70 /* DMA Channel 5 Current X Count Register */ +#define DMA5_CURR_Y_COUNT 0xFFC00D78 /* DMA Channel 5 Current Y Count Register */ +#define DMA5_IRQ_STATUS 0xFFC00D68 /* DMA Channel 5 Interrupt/Status Register */ +#define DMA5_PERIPHERAL_MAP 0xFFC00D6C /* DMA Channel 5 Peripheral Map Register */ + +#define DMA6_CONFIG 0xFFC00D88 /* DMA Channel 6 Configuration Register */ +#define DMA6_NEXT_DESC_PTR 0xFFC00D80 /* DMA Channel 6 Next Descriptor Pointer Register */ +#define DMA6_START_ADDR 0xFFC00D84 /* DMA Channel 6 Start Address Register */ +#define DMA6_X_COUNT 0xFFC00D90 /* DMA Channel 6 X Count Register */ +#define DMA6_Y_COUNT 0xFFC00D98 /* DMA Channel 6 Y Count Register */ +#define DMA6_X_MODIFY 0xFFC00D94 /* DMA Channel 6 X Modify Register */ +#define DMA6_Y_MODIFY 0xFFC00D9C /* DMA Channel 6 Y Modify Register */ +#define DMA6_CURR_DESC_PTR 0xFFC00DA0 /* DMA Channel 6 Current Descriptor Pointer Register */ +#define DMA6_CURR_ADDR 0xFFC00DA4 /* DMA Channel 6 Current Address Register */ +#define DMA6_CURR_X_COUNT 0xFFC00DB0 /* DMA Channel 6 Current X Count Register */ +#define DMA6_CURR_Y_COUNT 0xFFC00DB8 /* DMA Channel 6 Current Y Count Register */ +#define DMA6_IRQ_STATUS 0xFFC00DA8 /* DMA Channel 6 Interrupt/Status Register */ +#define DMA6_PERIPHERAL_MAP 0xFFC00DAC /* DMA Channel 6 Peripheral Map Register */ + +#define DMA7_CONFIG 0xFFC00DC8 /* DMA Channel 7 Configuration Register */ +#define DMA7_NEXT_DESC_PTR 0xFFC00DC0 /* DMA Channel 7 Next Descriptor Pointer Register */ +#define DMA7_START_ADDR 0xFFC00DC4 /* DMA Channel 7 Start Address Register */ +#define DMA7_X_COUNT 0xFFC00DD0 /* DMA Channel 7 X Count Register */ +#define DMA7_Y_COUNT 0xFFC00DD8 /* DMA Channel 7 Y Count Register */ +#define DMA7_X_MODIFY 0xFFC00DD4 /* DMA Channel 7 X Modify Register */ +#define DMA7_Y_MODIFY 0xFFC00DDC /* DMA Channel 7 Y Modify Register */ +#define DMA7_CURR_DESC_PTR 0xFFC00DE0 /* DMA Channel 7 Current Descriptor Pointer Register */ +#define DMA7_CURR_ADDR 0xFFC00DE4 /* DMA Channel 7 Current Address Register */ +#define DMA7_CURR_X_COUNT 0xFFC00DF0 /* DMA Channel 7 Current X Count Register */ +#define DMA7_CURR_Y_COUNT 0xFFC00DF8 /* DMA Channel 7 Current Y Count Register */ +#define DMA7_IRQ_STATUS 0xFFC00DE8 /* DMA Channel 7 Interrupt/Status Register */ +#define DMA7_PERIPHERAL_MAP 0xFFC00DEC /* DMA Channel 7 Peripheral Map Register */ + +#define MDMA_D1_CONFIG 0xFFC00E88 /* MemDMA Stream 1 Destination Configuration Register */ +#define MDMA_D1_NEXT_DESC_PTR 0xFFC00E80 /* MemDMA Stream 1 Destination Next Descriptor Pointer Register */ +#define MDMA_D1_START_ADDR 0xFFC00E84 /* MemDMA Stream 1 Destination Start Address Register */ +#define MDMA_D1_X_COUNT 0xFFC00E90 /* MemDMA Stream 1 Destination X Count Register */ +#define MDMA_D1_Y_COUNT 0xFFC00E98 /* MemDMA Stream 1 Destination Y Count Register */ +#define MDMA_D1_X_MODIFY 0xFFC00E94 /* MemDMA Stream 1 Destination X Modify Register */ +#define MDMA_D1_Y_MODIFY 0xFFC00E9C /* MemDMA Stream 1 Destination Y Modify Register */ +#define MDMA_D1_CURR_DESC_PTR 0xFFC00EA0 /* MemDMA Stream 1 Destination Current Descriptor Pointer Register */ +#define MDMA_D1_CURR_ADDR 0xFFC00EA4 /* MemDMA Stream 1 Destination Current Address Register */ +#define MDMA_D1_CURR_X_COUNT 0xFFC00EB0 /* MemDMA Stream 1 Destination Current X Count Register */ +#define MDMA_D1_CURR_Y_COUNT 0xFFC00EB8 /* MemDMA Stream 1 Destination Current Y Count Register */ +#define MDMA_D1_IRQ_STATUS 0xFFC00EA8 /* MemDMA Stream 1 Destination Interrupt/Status Register */ +#define MDMA_D1_PERIPHERAL_MAP 0xFFC00EAC /* MemDMA Stream 1 Destination Peripheral Map Register */ + +#define MDMA_S1_CONFIG 0xFFC00EC8 /* MemDMA Stream 1 Source Configuration Register */ +#define MDMA_S1_NEXT_DESC_PTR 0xFFC00EC0 /* MemDMA Stream 1 Source Next Descriptor Pointer Register */ +#define MDMA_S1_START_ADDR 0xFFC00EC4 /* MemDMA Stream 1 Source Start Address Register */ +#define MDMA_S1_X_COUNT 0xFFC00ED0 /* MemDMA Stream 1 Source X Count Register */ +#define MDMA_S1_Y_COUNT 0xFFC00ED8 /* MemDMA Stream 1 Source Y Count Register */ +#define MDMA_S1_X_MODIFY 0xFFC00ED4 /* MemDMA Stream 1 Source X Modify Register */ +#define MDMA_S1_Y_MODIFY 0xFFC00EDC /* MemDMA Stream 1 Source Y Modify Register */ +#define MDMA_S1_CURR_DESC_PTR 0xFFC00EE0 /* MemDMA Stream 1 Source Current Descriptor Pointer Register */ +#define MDMA_S1_CURR_ADDR 0xFFC00EE4 /* MemDMA Stream 1 Source Current Address Register */ +#define MDMA_S1_CURR_X_COUNT 0xFFC00EF0 /* MemDMA Stream 1 Source Current X Count Register */ +#define MDMA_S1_CURR_Y_COUNT 0xFFC00EF8 /* MemDMA Stream 1 Source Current Y Count Register */ +#define MDMA_S1_IRQ_STATUS 0xFFC00EE8 /* MemDMA Stream 1 Source Interrupt/Status Register */ +#define MDMA_S1_PERIPHERAL_MAP 0xFFC00EEC /* MemDMA Stream 1 Source Peripheral Map Register */ + +#define MDMA_D0_CONFIG 0xFFC00E08 /* MemDMA Stream 0 Destination Configuration Register */ +#define MDMA_D0_NEXT_DESC_PTR 0xFFC00E00 /* MemDMA Stream 0 Destination Next Descriptor Pointer Register */ +#define MDMA_D0_START_ADDR 0xFFC00E04 /* MemDMA Stream 0 Destination Start Address Register */ +#define MDMA_D0_X_COUNT 0xFFC00E10 /* MemDMA Stream 0 Destination X Count Register */ +#define MDMA_D0_Y_COUNT 0xFFC00E18 /* MemDMA Stream 0 Destination Y Count Register */ +#define MDMA_D0_X_MODIFY 0xFFC00E14 /* MemDMA Stream 0 Destination X Modify Register */ +#define MDMA_D0_Y_MODIFY 0xFFC00E1C /* MemDMA Stream 0 Destination Y Modify Register */ +#define MDMA_D0_CURR_DESC_PTR 0xFFC00E20 /* MemDMA Stream 0 Destination Current Descriptor Pointer Register */ +#define MDMA_D0_CURR_ADDR 0xFFC00E24 /* MemDMA Stream 0 Destination Current Address Register */ +#define MDMA_D0_CURR_X_COUNT 0xFFC00E30 /* MemDMA Stream 0 Destination Current X Count Register */ +#define MDMA_D0_CURR_Y_COUNT 0xFFC00E38 /* MemDMA Stream 0 Destination Current Y Count Register */ +#define MDMA_D0_IRQ_STATUS 0xFFC00E28 /* MemDMA Stream 0 Destination Interrupt/Status Register */ +#define MDMA_D0_PERIPHERAL_MAP 0xFFC00E2C /* MemDMA Stream 0 Destination Peripheral Map Register */ + +#define MDMA_S0_CONFIG 0xFFC00E48 /* MemDMA Stream 0 Source Configuration Register */ +#define MDMA_S0_NEXT_DESC_PTR 0xFFC00E40 /* MemDMA Stream 0 Source Next Descriptor Pointer Register */ +#define MDMA_S0_START_ADDR 0xFFC00E44 /* MemDMA Stream 0 Source Start Address Register */ +#define MDMA_S0_X_COUNT 0xFFC00E50 /* MemDMA Stream 0 Source X Count Register */ +#define MDMA_S0_Y_COUNT 0xFFC00E58 /* MemDMA Stream 0 Source Y Count Register */ +#define MDMA_S0_X_MODIFY 0xFFC00E54 /* MemDMA Stream 0 Source X Modify Register */ +#define MDMA_S0_Y_MODIFY 0xFFC00E5C /* MemDMA Stream 0 Source Y Modify Register */ +#define MDMA_S0_CURR_DESC_PTR 0xFFC00E60 /* MemDMA Stream 0 Source Current Descriptor Pointer Register */ +#define MDMA_S0_CURR_ADDR 0xFFC00E64 /* MemDMA Stream 0 Source Current Address Register */ +#define MDMA_S0_CURR_X_COUNT 0xFFC00E70 /* MemDMA Stream 0 Source Current X Count Register */ +#define MDMA_S0_CURR_Y_COUNT 0xFFC00E78 /* MemDMA Stream 0 Source Current Y Count Register */ +#define MDMA_S0_IRQ_STATUS 0xFFC00E68 /* MemDMA Stream 0 Source Interrupt/Status Register */ +#define MDMA_S0_PERIPHERAL_MAP 0xFFC00E6C /* MemDMA Stream 0 Source Peripheral Map Register */ + +/* Parallel Peripheral Interface (PPI) (0xFFC01000 - 0xFFC010FF) */ + +#define PPI_CONTROL 0xFFC01000 /* PPI Control Register */ +#define PPI_STATUS 0xFFC01004 /* PPI Status Register */ +#define PPI_COUNT 0xFFC01008 /* PPI Transfer Count Register */ +#define PPI_DELAY 0xFFC0100C /* PPI Delay Count Register */ +#define PPI_FRAME 0xFFC01010 /* PPI Frame Length Register */ + +/*********************************************************************************** */ +/* System MMR Register Bits */ +/******************************************************************************* */ + +/* ********************* PLL AND RESET MASKS ************************ */ + +/* PLL_CTL Masks */ +#define PLL_CLKIN 0x00000000 /* Pass CLKIN to PLL */ +#define PLL_CLKIN_DIV2 0x00000001 /* Pass CLKIN/2 to PLL */ +#define PLL_OFF 0x00000002 /* Shut off PLL clocks */ +#define STOPCK_OFF 0x00000008 /* Core clock off */ +#define PDWN 0x00000020 /* Put the PLL in a Deep Sleep state */ +#define BYPASS 0x00000100 /* Bypass the PLL */ + +/* PLL_DIV Masks */ + +#define SCLK_DIV(x) (x) /* SCLK = VCO / x */ + +#define CCLK_DIV1 0x00000000 /* CCLK = VCO / 1 */ +#define CCLK_DIV2 0x00000010 /* CCLK = VCO / 2 */ +#define CCLK_DIV4 0x00000020 /* CCLK = VCO / 4 */ +#define CCLK_DIV8 0x00000030 /* CCLK = VCO / 8 */ + +/* PLL_STAT Masks */ +#define ACTIVE_PLLENABLED 0x0001 /* Processor In Active Mode With PLL Enabled */ +#define FULL_ON 0x0002 /* Processor In Full On Mode */ +#define ACTIVE_PLLDISABLED 0x0004 /* Processor In Active Mode With PLL Disabled */ +#define PLL_LOCKED 0x0020 /* PLL_LOCKCNT Has Been Reached */ + +/* CHIPID Masks */ +#define CHIPID_VERSION 0xF0000000 +#define CHIPID_FAMILY 0x0FFFF000 +#define CHIPID_MANUFACTURE 0x00000FFE + +/* SWRST Mask */ +#define SYSTEM_RESET 0x00000007 /* Initiates a system software reset */ + +/* ************* SYSTEM INTERRUPT CONTROLLER MASKS ***************** */ + + /* SIC_IAR0 Masks */ + +#define P0_IVG(x) ((x)-7) /* Peripheral #0 assigned IVG #x */ +#define P1_IVG(x) ((x)-7) << 0x4 /* Peripheral #1 assigned IVG #x */ +#define P2_IVG(x) ((x)-7) << 0x8 /* Peripheral #2 assigned IVG #x */ +#define P3_IVG(x) ((x)-7) << 0xC /* Peripheral #3 assigned IVG #x */ +#define P4_IVG(x) ((x)-7) << 0x10 /* Peripheral #4 assigned IVG #x */ +#define P5_IVG(x) ((x)-7) << 0x14 /* Peripheral #5 assigned IVG #x */ +#define P6_IVG(x) ((x)-7) << 0x18 /* Peripheral #6 assigned IVG #x */ +#define P7_IVG(x) ((x)-7) << 0x1C /* Peripheral #7 assigned IVG #x */ + +/* SIC_IAR1 Masks */ + +#define P8_IVG(x) ((x)-7) /* Peripheral #8 assigned IVG #x */ +#define P9_IVG(x) ((x)-7) << 0x4 /* Peripheral #9 assigned IVG #x */ +#define P10_IVG(x) ((x)-7) << 0x8 /* Peripheral #10 assigned IVG #x */ +#define P11_IVG(x) ((x)-7) << 0xC /* Peripheral #11 assigned IVG #x */ +#define P12_IVG(x) ((x)-7) << 0x10 /* Peripheral #12 assigned IVG #x */ +#define P13_IVG(x) ((x)-7) << 0x14 /* Peripheral #13 assigned IVG #x */ +#define P14_IVG(x) ((x)-7) << 0x18 /* Peripheral #14 assigned IVG #x */ +#define P15_IVG(x) ((x)-7) << 0x1C /* Peripheral #15 assigned IVG #x */ + +/* SIC_IAR2 Masks */ +#define P16_IVG(x) ((x)-7) /* Peripheral #16 assigned IVG #x */ +#define P17_IVG(x) ((x)-7) << 0x4 /* Peripheral #17 assigned IVG #x */ +#define P18_IVG(x) ((x)-7) << 0x8 /* Peripheral #18 assigned IVG #x */ +#define P19_IVG(x) ((x)-7) << 0xC /* Peripheral #19 assigned IVG #x */ +#define P20_IVG(x) ((x)-7) << 0x10 /* Peripheral #20 assigned IVG #x */ +#define P21_IVG(x) ((x)-7) << 0x14 /* Peripheral #21 assigned IVG #x */ +#define P22_IVG(x) ((x)-7) << 0x18 /* Peripheral #22 assigned IVG #x */ +#define P23_IVG(x) ((x)-7) << 0x1C /* Peripheral #23 assigned IVG #x */ + +/* SIC_IMASK Masks */ +#define SIC_UNMASK_ALL 0x00000000 /* Unmask all peripheral interrupts */ +#define SIC_MASK_ALL 0xFFFFFFFF /* Mask all peripheral interrupts */ +#define SIC_MASK(x) (1 << (x)) /* Mask Peripheral #x interrupt */ +#define SIC_UNMASK(x) (0xFFFFFFFF ^ (1 << (x))) /* Unmask Peripheral #x interrupt */ + +/* SIC_IWR Masks */ +#define IWR_DISABLE_ALL 0x00000000 /* Wakeup Disable all peripherals */ +#define IWR_ENABLE_ALL 0xFFFFFFFF /* Wakeup Enable all peripherals */ +#define IWR_ENABLE(x) (1 << (x)) /* Wakeup Enable Peripheral #x */ +#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << (x))) /* Wakeup Disable Peripheral #x */ + +/* ********* WATCHDOG TIMER MASKS ********************8 */ + +/* Watchdog Timer WDOG_CTL Register */ +#define ICTL(x) ((x<<1) & 0x0006) +#define ENABLE_RESET 0x00000000 /* Set Watchdog Timer to generate reset */ +#define ENABLE_NMI 0x00000002 /* Set Watchdog Timer to generate non-maskable interrupt */ +#define ENABLE_GPI 0x00000004 /* Set Watchdog Timer to generate general-purpose interrupt */ +#define DISABLE_EVT 0x00000006 /* Disable Watchdog Timer interrupts */ + +#define TMR_EN 0x0000 +#define TMR_DIS 0x0AD0 +#define TRO 0x8000 + +#define ICTL_P0 0x01 +#define ICTL_P1 0x02 +#define TRO_P 0x0F + +/* ***************************** UART CONTROLLER MASKS ********************** */ + +/* UART_LCR Register */ + +#define DLAB 0x80 +#define SB 0x40 +#define STP 0x20 +#define EPS 0x10 +#define PEN 0x08 +#define STB 0x04 +#define WLS(x) ((x-5) & 0x03) + +#define DLAB_P 0x07 +#define SB_P 0x06 +#define STP_P 0x05 +#define EPS_P 0x04 +#define PEN_P 0x03 +#define STB_P 0x02 +#define WLS_P1 0x01 +#define WLS_P0 0x00 + +/* UART_MCR Register */ +#define LOOP_ENA 0x10 +#define LOOP_ENA_P 0x04 + +/* UART_LSR Register */ +#define TEMT 0x40 +#define THRE 0x20 +#define BI 0x10 +#define FE 0x08 +#define PE 0x04 +#define OE 0x02 +#define DR 0x01 + +#define TEMP_P 0x06 +#define THRE_P 0x05 +#define BI_P 0x04 +#define FE_P 0x03 +#define PE_P 0x02 +#define OE_P 0x01 +#define DR_P 0x00 + +/* UART_IER Register */ +#define ELSI 0x04 +#define ETBEI 0x02 +#define ERBFI 0x01 + +#define ELSI_P 0x02 +#define ETBEI_P 0x01 +#define ERBFI_P 0x00 + +/* UART_IIR Register */ +#define STATUS(x) ((x << 1) & 0x06) +#define NINT 0x01 +#define STATUS_P1 0x02 +#define STATUS_P0 0x01 +#define NINT_P 0x00 +#define IIR_TX_READY 0x02 /* UART_THR empty */ +#define IIR_RX_READY 0x04 /* Receive data ready */ +#define IIR_LINE_CHANGE 0x06 /* Receive line status */ +#define IIR_STATUS 0x06 + +/* UART_GCTL Register */ +#define FFE 0x20 +#define FPE 0x10 +#define RPOLC 0x08 +#define TPOLC 0x04 +#define IREN 0x02 +#define UCEN 0x01 + +#define FFE_P 0x05 +#define FPE_P 0x04 +#define RPOLC_P 0x03 +#define TPOLC_P 0x02 +#define IREN_P 0x01 +#define UCEN_P 0x00 + +/* ********** SERIAL PORT MASKS ********************** */ + +/* SPORTx_TCR1 Masks */ +#define TSPEN 0x0001 /* TX enable */ +#define ITCLK 0x0002 /* Internal TX Clock Select */ +#define TDTYPE 0x000C /* TX Data Formatting Select */ +#define TLSBIT 0x0010 /* TX Bit Order */ +#define ITFS 0x0200 /* Internal TX Frame Sync Select */ +#define TFSR 0x0400 /* TX Frame Sync Required Select */ +#define DITFS 0x0800 /* Data Independent TX Frame Sync Select */ +#define LTFS 0x1000 /* Low TX Frame Sync Select */ +#define LATFS 0x2000 /* Late TX Frame Sync Select */ +#define TCKFE 0x4000 /* TX Clock Falling Edge Select */ + +/* SPORTx_TCR2 Masks */ +#define SLEN 0x001F /*TX Word Length */ +#define TXSE 0x0100 /*TX Secondary Enable */ +#define TSFSE 0x0200 /*TX Stereo Frame Sync Enable */ +#define TRFST 0x0400 /*TX Right-First Data Order */ + +/* SPORTx_RCR1 Masks */ +#define RSPEN 0x0001 /* RX enable */ +#define IRCLK 0x0002 /* Internal RX Clock Select */ +#define RDTYPE 0x000C /* RX Data Formatting Select */ +#define RULAW 0x0008 /* u-Law enable */ +#define RALAW 0x000C /* A-Law enable */ +#define RLSBIT 0x0010 /* RX Bit Order */ +#define IRFS 0x0200 /* Internal RX Frame Sync Select */ +#define RFSR 0x0400 /* RX Frame Sync Required Select */ +#define LRFS 0x1000 /* Low RX Frame Sync Select */ +#define LARFS 0x2000 /* Late RX Frame Sync Select */ +#define RCKFE 0x4000 /* RX Clock Falling Edge Select */ + +/* SPORTx_RCR2 Masks */ +#define SLEN 0x001F /*RX Word Length */ +#define RXSE 0x0100 /*RX Secondary Enable */ +#define RSFSE 0x0200 /*RX Stereo Frame Sync Enable */ +#define RRFST 0x0400 /*Right-First Data Order */ + +/*SPORTx_STAT Masks */ +#define RXNE 0x0001 /*RX FIFO Not Empty Status */ +#define RUVF 0x0002 /*RX Underflow Status */ +#define ROVF 0x0004 /*RX Overflow Status */ +#define TXF 0x0008 /*TX FIFO Full Status */ +#define TUVF 0x0010 /*TX Underflow Status */ +#define TOVF 0x0020 /*TX Overflow Status */ +#define TXHRE 0x0040 /*TX Hold Register Empty */ + +/*SPORTx_MCMC1 Masks */ +#define SP_WSIZE 0x0000F000 /*Multichannel Window Size Field */ +#define SP_WOFF 0x000003FF /*Multichannel Window Offset Field */ + +/*SPORTx_MCMC2 Masks */ +#define MCCRM 0x00000003 /*Multichannel Clock Recovery Mode */ +#define MCDTXPE 0x00000004 /*Multichannel DMA Transmit Packing */ +#define MCDRXPE 0x00000008 /*Multichannel DMA Receive Packing */ +#define MCMEN 0x00000010 /*Multichannel Frame Mode Enable */ +#define FSDR 0x00000080 /*Multichannel Frame Sync to Data Relationship */ +#define MFD 0x0000F000 /*Multichannel Frame Delay */ + +/* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */ + +/* PPI_CONTROL Masks */ +#define PORT_EN 0x00000001 /* PPI Port Enable */ +#define PORT_DIR 0x00000002 /* PPI Port Direction */ +#define XFR_TYPE 0x0000000C /* PPI Transfer Type */ +#define PORT_CFG 0x00000030 /* PPI Port Configuration */ +#define FLD_SEL 0x00000040 /* PPI Active Field Select */ +#define PACK_EN 0x00000080 /* PPI Packing Mode */ +#define DMA32 0x00000100 /* PPI 32-bit DMA Enable */ +#define SKIP_EN 0x00000200 /* PPI Skip Element Enable */ +#define SKIP_EO 0x00000400 /* PPI Skip Even/Odd Elements */ +#define DLENGTH 0x00003800 /* PPI Data Length */ +#define DLEN_8 0x0000 /* Data Length = 8 Bits */ +#define DLEN_10 0x0800 /* Data Length = 10 Bits */ +#define DLEN_11 0x1000 /* Data Length = 11 Bits */ +#define DLEN_12 0x1800 /* Data Length = 12 Bits */ +#define DLEN_13 0x2000 /* Data Length = 13 Bits */ +#define DLEN_14 0x2800 /* Data Length = 14 Bits */ +#define DLEN_15 0x3000 /* Data Length = 15 Bits */ +#define DLEN_16 0x3800 /* Data Length = 16 Bits */ +#define DLEN(x) (((x-9) & 0x07) << 11) /* PPI Data Length (only works for x=10-->x=16) */ +#define POL 0x0000C000 /* PPI Signal Polarities */ + +/* PPI_STATUS Masks */ +#define FLD 0x00000400 /* Field Indicator */ +#define FT_ERR 0x00000800 /* Frame Track Error */ +#define OVR 0x00001000 /* FIFO Overflow Error */ +#define UNDR 0x00002000 /* FIFO Underrun Error */ +#define ERR_DET 0x00004000 /* Error Detected Indicator */ +#define ERR_NCOR 0x00008000 /* Error Not Corrected Indicator */ + +/* ********** DMA CONTROLLER MASKS *********************8 */ + +/*DMAx_CONFIG, MDMA_yy_CONFIG Masks */ +#define DMAEN 0x00000001 /* Channel Enable */ +#define WNR 0x00000002 /* Channel Direction (W/R*) */ +#define WDSIZE_8 0x00000000 /* Word Size 8 bits */ +#define WDSIZE_16 0x00000004 /* Word Size 16 bits */ +#define WDSIZE_32 0x00000008 /* Word Size 32 bits */ +#define DMA2D 0x00000010 /* 2D/1D* Mode */ +#define RESTART 0x00000020 /* Restart */ +#define DI_SEL 0x00000040 /* Data Interrupt Select */ +#define DI_EN 0x00000080 /* Data Interrupt Enable */ +#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */ +#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */ +#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */ +#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */ +#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */ +#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */ +#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */ +#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */ +#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */ +#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */ +#define NDSIZE 0x00000900 /* Next Descriptor Size */ +#define DMAFLOW 0x00007000 /* Flow Control */ +#define DMAFLOW_STOP 0x0000 /* Stop Mode */ +#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */ +#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */ +#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */ +#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */ + +#define DMAEN_P 0 /* Channel Enable */ +#define WNR_P 1 /* Channel Direction (W/R*) */ +#define DMA2D_P 4 /* 2D/1D* Mode */ +#define RESTART_P 5 /* Restart */ +#define DI_SEL_P 6 /* Data Interrupt Select */ +#define DI_EN_P 7 /* Data Interrupt Enable */ + +/*DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS Masks */ + +#define DMA_DONE 0x00000001 /* DMA Done Indicator */ +#define DMA_ERR 0x00000002 /* DMA Error Indicator */ +#define DFETCH 0x00000004 /* Descriptor Fetch Indicator */ +#define DMA_RUN 0x00000008 /* DMA Running Indicator */ + +#define DMA_DONE_P 0 /* DMA Done Indicator */ +#define DMA_ERR_P 1 /* DMA Error Indicator */ +#define DFETCH_P 2 /* Descriptor Fetch Indicator */ +#define DMA_RUN_P 3 /* DMA Running Indicator */ + +/*DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */ + +#define CTYPE 0x00000040 /* DMA Channel Type Indicator */ +#define CTYPE_P 6 /* DMA Channel Type Indicator BIT POSITION */ +#define PCAP8 0x00000080 /* DMA 8-bit Operation Indicator */ +#define PCAP16 0x00000100 /* DMA 16-bit Operation Indicator */ +#define PCAP32 0x00000200 /* DMA 32-bit Operation Indicator */ +#define PCAPWR 0x00000400 /* DMA Write Operation Indicator */ +#define PCAPRD 0x00000800 /* DMA Read Operation Indicator */ +#define PMAP 0x00007000 /* DMA Peripheral Map Field */ + +/* ************* GENERAL PURPOSE TIMER MASKS ******************** */ + +/* PWM Timer bit definitions */ + +/* TIMER_ENABLE Register */ +#define TIMEN0 0x0001 +#define TIMEN1 0x0002 +#define TIMEN2 0x0004 + +#define TIMEN0_P 0x00 +#define TIMEN1_P 0x01 +#define TIMEN2_P 0x02 + +/* TIMER_DISABLE Register */ +#define TIMDIS0 0x0001 +#define TIMDIS1 0x0002 +#define TIMDIS2 0x0004 + +#define TIMDIS0_P 0x00 +#define TIMDIS1_P 0x01 +#define TIMDIS2_P 0x02 + +/* TIMER_STATUS Register */ +#define TIMIL0 0x0001 +#define TIMIL1 0x0002 +#define TIMIL2 0x0004 +#define TOVL_ERR0 0x0010 +#define TOVL_ERR1 0x0020 +#define TOVL_ERR2 0x0040 +#define TRUN0 0x1000 +#define TRUN1 0x2000 +#define TRUN2 0x4000 + +#define TIMIL0_P 0x00 +#define TIMIL1_P 0x01 +#define TIMIL2_P 0x02 +#define TOVL_ERR0_P 0x04 +#define TOVL_ERR1_P 0x05 +#define TOVL_ERR2_P 0x06 +#define TRUN0_P 0x0C +#define TRUN1_P 0x0D +#define TRUN2_P 0x0E + +/* TIMERx_CONFIG Registers */ +#define PWM_OUT 0x0001 +#define WDTH_CAP 0x0002 +#define EXT_CLK 0x0003 +#define PULSE_HI 0x0004 +#define PERIOD_CNT 0x0008 +#define IRQ_ENA 0x0010 +#define TIN_SEL 0x0020 +#define OUT_DIS 0x0040 +#define CLK_SEL 0x0080 +#define TOGGLE_HI 0x0100 +#define EMU_RUN 0x0200 +#define ERR_TYP(x) ((x & 0x03) << 14) + +#define TMODE_P0 0x00 +#define TMODE_P1 0x01 +#define PULSE_HI_P 0x02 +#define PERIOD_CNT_P 0x03 +#define IRQ_ENA_P 0x04 +#define TIN_SEL_P 0x05 +#define OUT_DIS_P 0x06 +#define CLK_SEL_P 0x07 +#define TOGGLE_HI_P 0x08 +#define EMU_RUN_P 0x09 +#define ERR_TYP_P0 0x0E +#define ERR_TYP_P1 0x0F + +/*/ ****************** PROGRAMMABLE FLAG MASKS ********************* */ + +/* General Purpose IO (0xFFC00700 - 0xFFC007FF) Masks */ +#define PF0 0x0001 +#define PF1 0x0002 +#define PF2 0x0004 +#define PF3 0x0008 +#define PF4 0x0010 +#define PF5 0x0020 +#define PF6 0x0040 +#define PF7 0x0080 +#define PF8 0x0100 +#define PF9 0x0200 +#define PF10 0x0400 +#define PF11 0x0800 +#define PF12 0x1000 +#define PF13 0x2000 +#define PF14 0x4000 +#define PF15 0x8000 + +/* General Purpose IO (0xFFC00700 - 0xFFC007FF) BIT POSITIONS */ +#define PF0_P 0 +#define PF1_P 1 +#define PF2_P 2 +#define PF3_P 3 +#define PF4_P 4 +#define PF5_P 5 +#define PF6_P 6 +#define PF7_P 7 +#define PF8_P 8 +#define PF9_P 9 +#define PF10_P 10 +#define PF11_P 11 +#define PF12_P 12 +#define PF13_P 13 +#define PF14_P 14 +#define PF15_P 15 + +/* *********** SERIAL PERIPHERAL INTERFACE (SPI) MASKS **************** */ + +/* SPI_CTL Masks */ +#define TIMOD 0x00000003 /* Transfer initiation mode and interrupt generation */ +#define SZ 0x00000004 /* Send Zero (=0) or last (=1) word when TDBR empty. */ +#define GM 0x00000008 /* When RDBR full, get more (=1) data or discard (=0) incoming Data */ +#define PSSE 0x00000010 /* Enable (=1) Slave-Select input for Master. */ +#define EMISO 0x00000020 /* Enable (=1) MISO pin as an output. */ +#define SPI_LEN 0x00000100 /* Word length (0 => 8 bits, 1 => 16 bits) */ +#define LSBF 0x00000200 /* Data format (0 => MSB sent/received first 1 => LSB sent/received first) */ +#define CPHA 0x00000400 /* Clock phase (0 => SPICLK starts toggling in middle of xfer, 1 => SPICLK toggles at the beginning of xfer. */ +#define CPOL 0x00000800 /* Clock polarity (0 => active-high, 1 => active-low) */ +#define MSTR 0x00001000 /* Configures SPI as master (=1) or slave (=0) */ +#define WOM 0x00002000 /* Open drain (=1) data output enable (for MOSI and MISO) */ +#define SPE 0x00004000 /* SPI module enable (=1), disable (=0) */ + +/* SPI_FLG Masks */ +#define FLS1 0x00000002 /* Enables (=1) SPI_FLOUT1 as flag output for SPI Slave-select */ +#define FLS2 0x00000004 /* Enables (=1) SPI_FLOUT2 as flag output for SPI Slave-select */ +#define FLS3 0x00000008 /* Enables (=1) SPI_FLOUT3 as flag output for SPI Slave-select */ +#define FLS4 0x00000010 /* Enables (=1) SPI_FLOUT4 as flag output for SPI Slave-select */ +#define FLS5 0x00000020 /* Enables (=1) SPI_FLOUT5 as flag output for SPI Slave-select */ +#define FLS6 0x00000040 /* Enables (=1) SPI_FLOUT6 as flag output for SPI Slave-select */ +#define FLS7 0x00000080 /* Enables (=1) SPI_FLOUT7 as flag output for SPI Slave-select */ +#define FLG1 0x00000200 /* Activates (=0) SPI_FLOUT1 as flag output for SPI Slave-select */ +#define FLG2 0x00000400 /* Activates (=0) SPI_FLOUT2 as flag output for SPI Slave-select */ +#define FLG3 0x00000800 /* Activates (=0) SPI_FLOUT3 as flag output for SPI Slave-select */ +#define FLG4 0x00001000 /* Activates (=0) SPI_FLOUT4 as flag output for SPI Slave-select */ +#define FLG5 0x00002000 /* Activates (=0) SPI_FLOUT5 as flag output for SPI Slave-select */ +#define FLG6 0x00004000 /* Activates (=0) SPI_FLOUT6 as flag output for SPI Slave-select */ +#define FLG7 0x00008000 /* Activates (=0) SPI_FLOUT7 as flag output for SPI Slave-select */ + +/* SPI_FLG Bit Positions */ +#define FLS1_P 0x00000001 /* Enables (=1) SPI_FLOUT1 as flag output for SPI Slave-select */ +#define FLS2_P 0x00000002 /* Enables (=1) SPI_FLOUT2 as flag output for SPI Slave-select */ +#define FLS3_P 0x00000003 /* Enables (=1) SPI_FLOUT3 as flag output for SPI Slave-select */ +#define FLS4_P 0x00000004 /* Enables (=1) SPI_FLOUT4 as flag output for SPI Slave-select */ +#define FLS5_P 0x00000005 /* Enables (=1) SPI_FLOUT5 as flag output for SPI Slave-select */ +#define FLS6_P 0x00000006 /* Enables (=1) SPI_FLOUT6 as flag output for SPI Slave-select */ +#define FLS7_P 0x00000007 /* Enables (=1) SPI_FLOUT7 as flag output for SPI Slave-select */ +#define FLG1_P 0x00000009 /* Activates (=0) SPI_FLOUT1 as flag output for SPI Slave-select */ +#define FLG2_P 0x0000000A /* Activates (=0) SPI_FLOUT2 as flag output for SPI Slave-select */ +#define FLG3_P 0x0000000B /* Activates (=0) SPI_FLOUT3 as flag output for SPI Slave-select */ +#define FLG4_P 0x0000000C /* Activates (=0) SPI_FLOUT4 as flag output for SPI Slave-select */ +#define FLG5_P 0x0000000D /* Activates (=0) SPI_FLOUT5 as flag output for SPI Slave-select */ +#define FLG6_P 0x0000000E /* Activates (=0) SPI_FLOUT6 as flag output for SPI Slave-select */ +#define FLG7_P 0x0000000F /* Activates (=0) SPI_FLOUT7 as flag output for SPI Slave-select */ + +/* SPI_STAT Masks */ +#define SPIF 0x00000001 /* Set (=1) when SPI single-word transfer complete */ +#define MODF 0x00000002 /* Set (=1) in a master device when some other device tries to become master */ +#define TXE 0x00000004 /* Set (=1) when transmission occurs with no new data in SPI_TDBR */ +#define TXS 0x00000008 /* SPI_TDBR Data Buffer Status (0=Empty, 1=Full) */ +#define RBSY 0x00000010 /* Set (=1) when data is received with RDBR full */ +#define RXS 0x00000020 /* SPI_RDBR Data Buffer Status (0=Empty, 1=Full) */ +#define TXCOL 0x00000040 /* When set (=1), corrupt data may have been transmitted */ + +/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS ************* */ + +/* AMGCTL Masks */ +#define AMCKEN 0x00000001 /* Enable CLKOUT */ +#define AMBEN_B0 0x00000002 /* Enable Asynchronous Memory Bank 0 only */ +#define AMBEN_B0_B1 0x00000004 /* Enable Asynchronous Memory Banks 0 & 1 only */ +#define AMBEN_B0_B1_B2 0x00000006 /* Enable Asynchronous Memory Banks 0, 1, and 2 */ +#define AMBEN_ALL 0x00000008 /* Enable Asynchronous Memory Banks (all) 0, 1, 2, and 3 */ + +/* AMGCTL Bit Positions */ +#define AMCKEN_P 0x00000000 /* Enable CLKOUT */ +#define AMBEN_P0 0x00000001 /* Asynchronous Memory Enable, 000 - banks 0-3 disabled, 001 - Bank 0 enabled */ +#define AMBEN_P1 0x00000002 /* Asynchronous Memory Enable, 010 - banks 0&1 enabled, 011 - banks 0-3 enabled */ +#define AMBEN_P2 0x00000003 /* Asynchronous Memory Enable, 1xx - All banks (bank 0, 1, 2, and 3) enabled */ + +/* AMBCTL0 Masks */ +#define B0RDYEN 0x00000001 /* Bank 0 RDY Enable, 0=disable, 1=enable */ +#define B0RDYPOL 0x00000002 /* Bank 0 RDY Active high, 0=active low, 1=active high */ +#define B0TT_1 0x00000004 /* Bank 0 Transition Time from Read to Write = 1 cycle */ +#define B0TT_2 0x00000008 /* Bank 0 Transition Time from Read to Write = 2 cycles */ +#define B0TT_3 0x0000000C /* Bank 0 Transition Time from Read to Write = 3 cycles */ +#define B0TT_4 0x00000000 /* Bank 0 Transition Time from Read to Write = 4 cycles */ +#define B0ST_1 0x00000010 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=1 cycle */ +#define B0ST_2 0x00000020 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=2 cycles */ +#define B0ST_3 0x00000030 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=3 cycles */ +#define B0ST_4 0x00000000 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=4 cycles */ +#define B0HT_1 0x00000040 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 1 cycle */ +#define B0HT_2 0x00000080 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 2 cycles */ +#define B0HT_3 0x000000C0 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 3 cycles */ +#define B0HT_0 0x00000000 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 0 cycles */ +#define B0RAT_1 0x00000100 /* Bank 0 Read Access Time = 1 cycle */ +#define B0RAT_2 0x00000200 /* Bank 0 Read Access Time = 2 cycles */ +#define B0RAT_3 0x00000300 /* Bank 0 Read Access Time = 3 cycles */ +#define B0RAT_4 0x00000400 /* Bank 0 Read Access Time = 4 cycles */ +#define B0RAT_5 0x00000500 /* Bank 0 Read Access Time = 5 cycles */ +#define B0RAT_6 0x00000600 /* Bank 0 Read Access Time = 6 cycles */ +#define B0RAT_7 0x00000700 /* Bank 0 Read Access Time = 7 cycles */ +#define B0RAT_8 0x00000800 /* Bank 0 Read Access Time = 8 cycles */ +#define B0RAT_9 0x00000900 /* Bank 0 Read Access Time = 9 cycles */ +#define B0RAT_10 0x00000A00 /* Bank 0 Read Access Time = 10 cycles */ +#define B0RAT_11 0x00000B00 /* Bank 0 Read Access Time = 11 cycles */ +#define B0RAT_12 0x00000C00 /* Bank 0 Read Access Time = 12 cycles */ +#define B0RAT_13 0x00000D00 /* Bank 0 Read Access Time = 13 cycles */ +#define B0RAT_14 0x00000E00 /* Bank 0 Read Access Time = 14 cycles */ +#define B0RAT_15 0x00000F00 /* Bank 0 Read Access Time = 15 cycles */ +#define B0WAT_1 0x00001000 /* Bank 0 Write Access Time = 1 cycle */ +#define B0WAT_2 0x00002000 /* Bank 0 Write Access Time = 2 cycles */ +#define B0WAT_3 0x00003000 /* Bank 0 Write Access Time = 3 cycles */ +#define B0WAT_4 0x00004000 /* Bank 0 Write Access Time = 4 cycles */ +#define B0WAT_5 0x00005000 /* Bank 0 Write Access Time = 5 cycles */ +#define B0WAT_6 0x00006000 /* Bank 0 Write Access Time = 6 cycles */ +#define B0WAT_7 0x00007000 /* Bank 0 Write Access Time = 7 cycles */ +#define B0WAT_8 0x00008000 /* Bank 0 Write Access Time = 8 cycles */ +#define B0WAT_9 0x00009000 /* Bank 0 Write Access Time = 9 cycles */ +#define B0WAT_10 0x0000A000 /* Bank 0 Write Access Time = 10 cycles */ +#define B0WAT_11 0x0000B000 /* Bank 0 Write Access Time = 11 cycles */ +#define B0WAT_12 0x0000C000 /* Bank 0 Write Access Time = 12 cycles */ +#define B0WAT_13 0x0000D000 /* Bank 0 Write Access Time = 13 cycles */ +#define B0WAT_14 0x0000E000 /* Bank 0 Write Access Time = 14 cycles */ +#define B0WAT_15 0x0000F000 /* Bank 0 Write Access Time = 15 cycles */ +#define B1RDYEN 0x00010000 /* Bank 1 RDY enable, 0=disable, 1=enable */ +#define B1RDYPOL 0x00020000 /* Bank 1 RDY Active high, 0=active low, 1=active high */ +#define B1TT_1 0x00040000 /* Bank 1 Transition Time from Read to Write = 1 cycle */ +#define B1TT_2 0x00080000 /* Bank 1 Transition Time from Read to Write = 2 cycles */ +#define B1TT_3 0x000C0000 /* Bank 1 Transition Time from Read to Write = 3 cycles */ +#define B1TT_4 0x00000000 /* Bank 1 Transition Time from Read to Write = 4 cycles */ +#define B1ST_1 0x00100000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */ +#define B1ST_2 0x00200000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */ +#define B1ST_3 0x00300000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */ +#define B1ST_4 0x00000000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */ +#define B1HT_1 0x00400000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */ +#define B1HT_2 0x00800000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */ +#define B1HT_3 0x00C00000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */ +#define B1HT_0 0x00000000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */ +#define B1RAT_1 0x01000000 /* Bank 1 Read Access Time = 1 cycle */ +#define B1RAT_2 0x02000000 /* Bank 1 Read Access Time = 2 cycles */ +#define B1RAT_3 0x03000000 /* Bank 1 Read Access Time = 3 cycles */ +#define B1RAT_4 0x04000000 /* Bank 1 Read Access Time = 4 cycles */ +#define B1RAT_5 0x05000000 /* Bank 1 Read Access Time = 5 cycles */ +#define B1RAT_6 0x06000000 /* Bank 1 Read Access Time = 6 cycles */ +#define B1RAT_7 0x07000000 /* Bank 1 Read Access Time = 7 cycles */ +#define B1RAT_8 0x08000000 /* Bank 1 Read Access Time = 8 cycles */ +#define B1RAT_9 0x09000000 /* Bank 1 Read Access Time = 9 cycles */ +#define B1RAT_10 0x0A000000 /* Bank 1 Read Access Time = 10 cycles */ +#define B1RAT_11 0x0B000000 /* Bank 1 Read Access Time = 11 cycles */ +#define B1RAT_12 0x0C000000 /* Bank 1 Read Access Time = 12 cycles */ +#define B1RAT_13 0x0D000000 /* Bank 1 Read Access Time = 13 cycles */ +#define B1RAT_14 0x0E000000 /* Bank 1 Read Access Time = 14 cycles */ +#define B1RAT_15 0x0F000000 /* Bank 1 Read Access Time = 15 cycles */ +#define B1WAT_1 0x10000000 /* Bank 1 Write Access Time = 1 cycle */ +#define B1WAT_2 0x20000000 /* Bank 1 Write Access Time = 2 cycles */ +#define B1WAT_3 0x30000000 /* Bank 1 Write Access Time = 3 cycles */ +#define B1WAT_4 0x40000000 /* Bank 1 Write Access Time = 4 cycles */ +#define B1WAT_5 0x50000000 /* Bank 1 Write Access Time = 5 cycles */ +#define B1WAT_6 0x60000000 /* Bank 1 Write Access Time = 6 cycles */ +#define B1WAT_7 0x70000000 /* Bank 1 Write Access Time = 7 cycles */ +#define B1WAT_8 0x80000000 /* Bank 1 Write Access Time = 8 cycles */ +#define B1WAT_9 0x90000000 /* Bank 1 Write Access Time = 9 cycles */ +#define B1WAT_10 0xA0000000 /* Bank 1 Write Access Time = 10 cycles */ +#define B1WAT_11 0xB0000000 /* Bank 1 Write Access Time = 11 cycles */ +#define B1WAT_12 0xC0000000 /* Bank 1 Write Access Time = 12 cycles */ +#define B1WAT_13 0xD0000000 /* Bank 1 Write Access Time = 13 cycles */ +#define B1WAT_14 0xE0000000 /* Bank 1 Write Access Time = 14 cycles */ +#define B1WAT_15 0xF0000000 /* Bank 1 Write Access Time = 15 cycles */ + +/* AMBCTL1 Masks */ +#define B2RDYEN 0x00000001 /* Bank 2 RDY Enable, 0=disable, 1=enable */ +#define B2RDYPOL 0x00000002 /* Bank 2 RDY Active high, 0=active low, 1=active high */ +#define B2TT_1 0x00000004 /* Bank 2 Transition Time from Read to Write = 1 cycle */ +#define B2TT_2 0x00000008 /* Bank 2 Transition Time from Read to Write = 2 cycles */ +#define B2TT_3 0x0000000C /* Bank 2 Transition Time from Read to Write = 3 cycles */ +#define B2TT_4 0x00000000 /* Bank 2 Transition Time from Read to Write = 4 cycles */ +#define B2ST_1 0x00000010 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */ +#define B2ST_2 0x00000020 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */ +#define B2ST_3 0x00000030 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */ +#define B2ST_4 0x00000000 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */ +#define B2HT_1 0x00000040 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */ +#define B2HT_2 0x00000080 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */ +#define B2HT_3 0x000000C0 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */ +#define B2HT_0 0x00000000 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */ +#define B2RAT_1 0x00000100 /* Bank 2 Read Access Time = 1 cycle */ +#define B2RAT_2 0x00000200 /* Bank 2 Read Access Time = 2 cycles */ +#define B2RAT_3 0x00000300 /* Bank 2 Read Access Time = 3 cycles */ +#define B2RAT_4 0x00000400 /* Bank 2 Read Access Time = 4 cycles */ +#define B2RAT_5 0x00000500 /* Bank 2 Read Access Time = 5 cycles */ +#define B2RAT_6 0x00000600 /* Bank 2 Read Access Time = 6 cycles */ +#define B2RAT_7 0x00000700 /* Bank 2 Read Access Time = 7 cycles */ +#define B2RAT_8 0x00000800 /* Bank 2 Read Access Time = 8 cycles */ +#define B2RAT_9 0x00000900 /* Bank 2 Read Access Time = 9 cycles */ +#define B2RAT_10 0x00000A00 /* Bank 2 Read Access Time = 10 cycles */ +#define B2RAT_11 0x00000B00 /* Bank 2 Read Access Time = 11 cycles */ +#define B2RAT_12 0x00000C00 /* Bank 2 Read Access Time = 12 cycles */ +#define B2RAT_13 0x00000D00 /* Bank 2 Read Access Time = 13 cycles */ +#define B2RAT_14 0x00000E00 /* Bank 2 Read Access Time = 14 cycles */ +#define B2RAT_15 0x00000F00 /* Bank 2 Read Access Time = 15 cycles */ +#define B2WAT_1 0x00001000 /* Bank 2 Write Access Time = 1 cycle */ +#define B2WAT_2 0x00002000 /* Bank 2 Write Access Time = 2 cycles */ +#define B2WAT_3 0x00003000 /* Bank 2 Write Access Time = 3 cycles */ +#define B2WAT_4 0x00004000 /* Bank 2 Write Access Time = 4 cycles */ +#define B2WAT_5 0x00005000 /* Bank 2 Write Access Time = 5 cycles */ +#define B2WAT_6 0x00006000 /* Bank 2 Write Access Time = 6 cycles */ +#define B2WAT_7 0x00007000 /* Bank 2 Write Access Time = 7 cycles */ +#define B2WAT_8 0x00008000 /* Bank 2 Write Access Time = 8 cycles */ +#define B2WAT_9 0x00009000 /* Bank 2 Write Access Time = 9 cycles */ +#define B2WAT_10 0x0000A000 /* Bank 2 Write Access Time = 10 cycles */ +#define B2WAT_11 0x0000B000 /* Bank 2 Write Access Time = 11 cycles */ +#define B2WAT_12 0x0000C000 /* Bank 2 Write Access Time = 12 cycles */ +#define B2WAT_13 0x0000D000 /* Bank 2 Write Access Time = 13 cycles */ +#define B2WAT_14 0x0000E000 /* Bank 2 Write Access Time = 14 cycles */ +#define B2WAT_15 0x0000F000 /* Bank 2 Write Access Time = 15 cycles */ +#define B3RDYEN 0x00010000 /* Bank 3 RDY enable, 0=disable, 1=enable */ +#define B3RDYPOL 0x00020000 /* Bank 3 RDY Active high, 0=active low, 1=active high */ +#define B3TT_1 0x00040000 /* Bank 3 Transition Time from Read to Write = 1 cycle */ +#define B3TT_2 0x00080000 /* Bank 3 Transition Time from Read to Write = 2 cycles */ +#define B3TT_3 0x000C0000 /* Bank 3 Transition Time from Read to Write = 3 cycles */ +#define B3TT_4 0x00000000 /* Bank 3 Transition Time from Read to Write = 4 cycles */ +#define B3ST_1 0x00100000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */ +#define B3ST_2 0x00200000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */ +#define B3ST_3 0x00300000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */ +#define B3ST_4 0x00000000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */ +#define B3HT_1 0x00400000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */ +#define B3HT_2 0x00800000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */ +#define B3HT_3 0x00C00000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */ +#define B3HT_0 0x00000000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */ +#define B3RAT_1 0x01000000 /* Bank 3 Read Access Time = 1 cycle */ +#define B3RAT_2 0x02000000 /* Bank 3 Read Access Time = 2 cycles */ +#define B3RAT_3 0x03000000 /* Bank 3 Read Access Time = 3 cycles */ +#define B3RAT_4 0x04000000 /* Bank 3 Read Access Time = 4 cycles */ +#define B3RAT_5 0x05000000 /* Bank 3 Read Access Time = 5 cycles */ +#define B3RAT_6 0x06000000 /* Bank 3 Read Access Time = 6 cycles */ +#define B3RAT_7 0x07000000 /* Bank 3 Read Access Time = 7 cycles */ +#define B3RAT_8 0x08000000 /* Bank 3 Read Access Time = 8 cycles */ +#define B3RAT_9 0x09000000 /* Bank 3 Read Access Time = 9 cycles */ +#define B3RAT_10 0x0A000000 /* Bank 3 Read Access Time = 10 cycles */ +#define B3RAT_11 0x0B000000 /* Bank 3 Read Access Time = 11 cycles */ +#define B3RAT_12 0x0C000000 /* Bank 3 Read Access Time = 12 cycles */ +#define B3RAT_13 0x0D000000 /* Bank 3 Read Access Time = 13 cycles */ +#define B3RAT_14 0x0E000000 /* Bank 3 Read Access Time = 14 cycles */ +#define B3RAT_15 0x0F000000 /* Bank 3 Read Access Time = 15 cycles */ +#define B3WAT_1 0x10000000 /* Bank 3 Write Access Time = 1 cycle */ +#define B3WAT_2 0x20000000 /* Bank 3 Write Access Time = 2 cycles */ +#define B3WAT_3 0x30000000 /* Bank 3 Write Access Time = 3 cycles */ +#define B3WAT_4 0x40000000 /* Bank 3 Write Access Time = 4 cycles */ +#define B3WAT_5 0x50000000 /* Bank 3 Write Access Time = 5 cycles */ +#define B3WAT_6 0x60000000 /* Bank 3 Write Access Time = 6 cycles */ +#define B3WAT_7 0x70000000 /* Bank 3 Write Access Time = 7 cycles */ +#define B3WAT_8 0x80000000 /* Bank 3 Write Access Time = 8 cycles */ +#define B3WAT_9 0x90000000 /* Bank 3 Write Access Time = 9 cycles */ +#define B3WAT_10 0xA0000000 /* Bank 3 Write Access Time = 10 cycles */ +#define B3WAT_11 0xB0000000 /* Bank 3 Write Access Time = 11 cycles */ +#define B3WAT_12 0xC0000000 /* Bank 3 Write Access Time = 12 cycles */ +#define B3WAT_13 0xD0000000 /* Bank 3 Write Access Time = 13 cycles */ +#define B3WAT_14 0xE0000000 /* Bank 3 Write Access Time = 14 cycles */ +#define B3WAT_15 0xF0000000 /* Bank 3 Write Access Time = 15 cycles */ + +/* ********************** SDRAM CONTROLLER MASKS *************************** */ + +/* SDGCTL Masks */ +#define SCTLE 0x00000001 /* Enable SCLK[0], /SRAS, /SCAS, /SWE, SDQM[3:0] */ +#define CL_2 0x00000008 /* SDRAM CAS latency = 2 cycles */ +#define CL_3 0x0000000C /* SDRAM CAS latency = 3 cycles */ +#define PFE 0x00000010 /* Enable SDRAM prefetch */ +#define PFP 0x00000020 /* Prefetch has priority over AMC requests */ +#define TRAS_1 0x00000040 /* SDRAM tRAS = 1 cycle */ +#define TRAS_2 0x00000080 /* SDRAM tRAS = 2 cycles */ +#define TRAS_3 0x000000C0 /* SDRAM tRAS = 3 cycles */ +#define TRAS_4 0x00000100 /* SDRAM tRAS = 4 cycles */ +#define TRAS_5 0x00000140 /* SDRAM tRAS = 5 cycles */ +#define TRAS_6 0x00000180 /* SDRAM tRAS = 6 cycles */ +#define TRAS_7 0x000001C0 /* SDRAM tRAS = 7 cycles */ +#define TRAS_8 0x00000200 /* SDRAM tRAS = 8 cycles */ +#define TRAS_9 0x00000240 /* SDRAM tRAS = 9 cycles */ +#define TRAS_10 0x00000280 /* SDRAM tRAS = 10 cycles */ +#define TRAS_11 0x000002C0 /* SDRAM tRAS = 11 cycles */ +#define TRAS_12 0x00000300 /* SDRAM tRAS = 12 cycles */ +#define TRAS_13 0x00000340 /* SDRAM tRAS = 13 cycles */ +#define TRAS_14 0x00000380 /* SDRAM tRAS = 14 cycles */ +#define TRAS_15 0x000003C0 /* SDRAM tRAS = 15 cycles */ +#define TRP_1 0x00000800 /* SDRAM tRP = 1 cycle */ +#define TRP_2 0x00001000 /* SDRAM tRP = 2 cycles */ +#define TRP_3 0x00001800 /* SDRAM tRP = 3 cycles */ +#define TRP_4 0x00002000 /* SDRAM tRP = 4 cycles */ +#define TRP_5 0x00002800 /* SDRAM tRP = 5 cycles */ +#define TRP_6 0x00003000 /* SDRAM tRP = 6 cycles */ +#define TRP_7 0x00003800 /* SDRAM tRP = 7 cycles */ +#define TRCD_1 0x00008000 /* SDRAM tRCD = 1 cycle */ +#define TRCD_2 0x00010000 /* SDRAM tRCD = 2 cycles */ +#define TRCD_3 0x00018000 /* SDRAM tRCD = 3 cycles */ +#define TRCD_4 0x00020000 /* SDRAM tRCD = 4 cycles */ +#define TRCD_5 0x00028000 /* SDRAM tRCD = 5 cycles */ +#define TRCD_6 0x00030000 /* SDRAM tRCD = 6 cycles */ +#define TRCD_7 0x00038000 /* SDRAM tRCD = 7 cycles */ +#define TWR_1 0x00080000 /* SDRAM tWR = 1 cycle */ +#define TWR_2 0x00100000 /* SDRAM tWR = 2 cycles */ +#define TWR_3 0x00180000 /* SDRAM tWR = 3 cycles */ +#define PUPSD 0x00200000 /*Power-up start delay */ +#define PSM 0x00400000 /* SDRAM power-up sequence = Precharge, mode register set, 8 CBR refresh cycles */ +#define PSS 0x00800000 /* enable SDRAM power-up sequence on next SDRAM access */ +#define SRFS 0x01000000 /* Start SDRAM self-refresh mode */ +#define EBUFE 0x02000000 /* Enable external buffering timing */ +#define FBBRW 0x04000000 /* Fast back-to-back read write enable */ +#define EMREN 0x10000000 /* Extended mode register enable */ +#define TCSR 0x20000000 /* Temp compensated self refresh value 85 deg C */ +#define CDDBG 0x40000000 /* Tristate SDRAM controls during bus grant */ + +/* EBIU_SDBCTL Masks */ +#define EBE 0x00000001 /* Enable SDRAM external bank */ +#define EBSZ_16 0x00000000 /* SDRAM external bank size = 16MB */ +#define EBSZ_32 0x00000002 /* SDRAM external bank size = 32MB */ +#define EBSZ_64 0x00000004 /* SDRAM external bank size = 64MB */ +#define EBSZ_128 0x00000006 /* SDRAM external bank size = 128MB */ +#define EBCAW_8 0x00000000 /* SDRAM external bank column address width = 8 bits */ +#define EBCAW_9 0x00000010 /* SDRAM external bank column address width = 9 bits */ +#define EBCAW_10 0x00000020 /* SDRAM external bank column address width = 9 bits */ +#define EBCAW_11 0x00000030 /* SDRAM external bank column address width = 9 bits */ + +/* EBIU_SDSTAT Masks */ +#define SDCI 0x00000001 /* SDRAM controller is idle */ +#define SDSRA 0x00000002 /* SDRAM SDRAM self refresh is active */ +#define SDPUA 0x00000004 /* SDRAM power up active */ +#define SDRS 0x00000008 /* SDRAM is in reset state */ +#define SDEASE 0x00000010 /* SDRAM EAB sticky error status - W1C */ +#define BGSTAT 0x00000020 /* Bus granted */ + +/*VR_CTL Masks*/ +#define WAKE 0x100 +#define VLEV_6 0x60 +#define VLEV_7 0x70 +#define VLEV_8 0x80 +#define VLEV_9 0x90 +#define VLEV_10 0xA0 +#define VLEV_11 0xB0 +#define VLEV_12 0xC0 +#define VLEV_13 0xD0 +#define VLEV_14 0xE0 +#define VLEV_15 0xF0 +#define FREQ_3 0x03 + +#endif /* _DEF_BF532_H */ diff --git a/include/asm-blackfin/mach-bf533/dma.h b/include/asm-blackfin/mach-bf533/dma.h new file mode 100644 index 000000000000..bd9d5e94307d --- /dev/null +++ b/include/asm-blackfin/mach-bf533/dma.h @@ -0,0 +1,54 @@ +/***************************************************************************** +* +* BF-533/2/1 Specific Declarations +* +****************************************************************************/ +/* + * File: include/asm-blackfin/mach-bf533/dma.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Rev: + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _MACH_DMA_H_ +#define _MACH_DMA_H_ + +#define MAX_BLACKFIN_DMA_CHANNEL 12 + +#define CH_PPI 0 +#define CH_SPORT0_RX 1 +#define CH_SPORT0_TX 2 +#define CH_SPORT1_RX 3 +#define CH_SPORT1_TX 4 +#define CH_SPI 5 +#define CH_UART_RX 6 +#define CH_UART_TX 7 +#define CH_MEM_STREAM0_DEST 8 /* TX */ +#define CH_MEM_STREAM0_SRC 9 /* RX */ +#define CH_MEM_STREAM1_DEST 10 /* TX */ +#define CH_MEM_STREAM1_SRC 11 /* RX */ + +#endif diff --git a/include/asm-blackfin/mach-bf533/irq.h b/include/asm-blackfin/mach-bf533/irq.h new file mode 100644 index 000000000000..9879e68e315c --- /dev/null +++ b/include/asm-blackfin/mach-bf533/irq.h @@ -0,0 +1,177 @@ +/* + * File: include/asm-blackfin/mach-bf533/defBF532.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Rev: + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _BF533_IRQ_H_ +#define _BF533_IRQ_H_ + +/* + * Interrupt source definitions + Event Source Core Event Name +Core Emulation ** + Events (highest priority) EMU 0 + Reset RST 1 + NMI NMI 2 + Exception EVX 3 + Reserved -- 4 + Hardware Error IVHW 5 + Core Timer IVTMR 6 * + PLL Wakeup Interrupt IVG7 7 + DMA Error (generic) IVG7 8 + PPI Error Interrupt IVG7 9 + SPORT0 Error Interrupt IVG7 10 + SPORT1 Error Interrupt IVG7 11 + SPI Error Interrupt IVG7 12 + UART Error Interrupt IVG7 13 + RTC Interrupt IVG8 14 + DMA0 Interrupt (PPI) IVG8 15 + DMA1 (SPORT0 RX) IVG9 16 + DMA2 (SPORT0 TX) IVG9 17 + DMA3 (SPORT1 RX) IVG9 18 + DMA4 (SPORT1 TX) IVG9 19 + DMA5 (PPI) IVG10 20 + DMA6 (UART RX) IVG10 21 + DMA7 (UART TX) IVG10 22 + Timer0 IVG11 23 + Timer1 IVG11 24 + Timer2 IVG11 25 + PF Interrupt A IVG12 26 + PF Interrupt B IVG12 27 + DMA8/9 Interrupt IVG13 28 + DMA10/11 Interrupt IVG13 29 + Watchdog Timer IVG13 30 + Software Interrupt 1 IVG14 31 + Software Interrupt 2 -- + (lowest priority) IVG15 32 * + */ +#define SYS_IRQS 32 +#define NR_PERI_INTS 24 + +/* The ABSTRACT IRQ definitions */ +/** the first seven of the following are fixed, the rest you change if you need to **/ +#define IRQ_EMU 0 /*Emulation */ +#define IRQ_RST 1 /*reset */ +#define IRQ_NMI 2 /*Non Maskable */ +#define IRQ_EVX 3 /*Exception */ +#define IRQ_UNUSED 4 /*- unused interrupt*/ +#define IRQ_HWERR 5 /*Hardware Error */ +#define IRQ_CORETMR 6 /*Core timer */ + +#define IRQ_PLL_WAKEUP 7 /*PLL Wakeup Interrupt */ +#define IRQ_DMA_ERROR 8 /*DMA Error (general) */ +#define IRQ_PPI_ERROR 9 /*PPI Error Interrupt */ +#define IRQ_SPORT0_ERROR 10 /*SPORT0 Error Interrupt */ +#define IRQ_SPORT1_ERROR 11 /*SPORT1 Error Interrupt */ +#define IRQ_SPI_ERROR 12 /*SPI Error Interrupt */ +#define IRQ_UART_ERROR 13 /*UART Error Interrupt */ +#define IRQ_RTC 14 /*RTC Interrupt */ +#define IRQ_PPI 15 /*DMA0 Interrupt (PPI) */ +#define IRQ_SPORT0_RX 16 /*DMA1 Interrupt (SPORT0 RX) */ +#define IRQ_SPORT0_TX 17 /*DMA2 Interrupt (SPORT0 TX) */ +#define IRQ_SPORT1_RX 18 /*DMA3 Interrupt (SPORT1 RX) */ +#define IRQ_SPORT1_TX 19 /*DMA4 Interrupt (SPORT1 TX) */ +#define IRQ_SPI 20 /*DMA5 Interrupt (SPI) */ +#define IRQ_UART_RX 21 /*DMA6 Interrupt (UART RX) */ +#define IRQ_UART_TX 22 /*DMA7 Interrupt (UART TX) */ +#define IRQ_TMR0 23 /*Timer 0 */ +#define IRQ_TMR1 24 /*Timer 1 */ +#define IRQ_TMR2 25 /*Timer 2 */ +#define IRQ_PROG_INTA 26 /*Programmable Flags A (8) */ +#define IRQ_PROG_INTB 27 /*Programmable Flags B (8) */ +#define IRQ_MEM_DMA0 28 /*DMA8/9 Interrupt (Memory DMA Stream 0) */ +#define IRQ_MEM_DMA1 29 /*DMA10/11 Interrupt (Memory DMA Stream 1) */ +#define IRQ_WATCH 30 /*Watch Dog Timer */ + +#define IRQ_SW_INT1 31 /*Software Int 1 */ +#define IRQ_SW_INT2 32 /*Software Int 2 (reserved for SYSCALL) */ + +#define IRQ_PF0 33 +#define IRQ_PF1 34 +#define IRQ_PF2 35 +#define IRQ_PF3 36 +#define IRQ_PF4 37 +#define IRQ_PF5 38 +#define IRQ_PF6 39 +#define IRQ_PF7 40 +#define IRQ_PF8 41 +#define IRQ_PF9 42 +#define IRQ_PF10 43 +#define IRQ_PF11 44 +#define IRQ_PF12 45 +#define IRQ_PF13 46 +#define IRQ_PF14 47 +#define IRQ_PF15 48 + +#ifdef CONFIG_IRQCHIP_DEMUX_GPIO +#define NR_IRQS (IRQ_PF15+1) +#else +#define NR_IRQS SYS_IRQS +#endif + +#define IVG7 7 +#define IVG8 8 +#define IVG9 9 +#define IVG10 10 +#define IVG11 11 +#define IVG12 12 +#define IVG13 13 +#define IVG14 14 +#define IVG15 15 + +/* IAR0 BIT FIELDS*/ +#define RTC_ERROR_POS 28 +#define UART_ERROR_POS 24 +#define SPORT1_ERROR_POS 20 +#define SPI_ERROR_POS 16 +#define SPORT0_ERROR_POS 12 +#define PPI_ERROR_POS 8 +#define DMA_ERROR_POS 4 +#define PLLWAKE_ERROR_POS 0 + +/* IAR1 BIT FIELDS*/ +#define DMA7_UARTTX_POS 28 +#define DMA6_UARTRX_POS 24 +#define DMA5_SPI_POS 20 +#define DMA4_SPORT1TX_POS 16 +#define DMA3_SPORT1RX_POS 12 +#define DMA2_SPORT0TX_POS 8 +#define DMA1_SPORT0RX_POS 4 +#define DMA0_PPI_POS 0 + +/* IAR2 BIT FIELDS*/ +#define WDTIMER_POS 28 +#define MEMDMA1_POS 24 +#define MEMDMA0_POS 20 +#define PFB_POS 16 +#define PFA_POS 12 +#define TIMER2_POS 8 +#define TIMER1_POS 4 +#define TIMER0_POS 0 + +#endif /* _BF533_IRQ_H_ */ diff --git a/include/asm-blackfin/mach-bf533/mem_init.h b/include/asm-blackfin/mach-bf533/mem_init.h new file mode 100644 index 000000000000..1620dae5254d --- /dev/null +++ b/include/asm-blackfin/mach-bf533/mem_init.h @@ -0,0 +1,316 @@ +/* + * File: include/asm-blackfin/mach-bf533/mem_init.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Rev: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#if (CONFIG_MEM_MT48LC16M16A2TG_75 || CONFIG_MEM_MT48LC64M4A2FB_7E || CONFIG_MEM_GENERIC_BOARD) +#if (CONFIG_SCLK_HZ > 119402985) +#define SDRAM_tRP TRP_2 +#define SDRAM_tRP_num 2 +#define SDRAM_tRAS TRAS_7 +#define SDRAM_tRAS_num 7 +#define SDRAM_tRCD TRCD_2 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 104477612) && (CONFIG_SCLK_HZ <= 119402985) +#define SDRAM_tRP TRP_2 +#define SDRAM_tRP_num 2 +#define SDRAM_tRAS TRAS_6 +#define SDRAM_tRAS_num 6 +#define SDRAM_tRCD TRCD_2 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 8955223) && (CONFIG_SCLK_HZ <= 104477612) +#define SDRAM_tRP TRP_2 +#define SDRAM_tRP_num 2 +#define SDRAM_tRAS TRAS_5 +#define SDRAM_tRAS_num 5 +#define SDRAM_tRCD TRCD_2 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 74626866) && (CONFIG_SCLK_HZ <= 89552239) +#define SDRAM_tRP TRP_2 +#define SDRAM_tRP_num 2 +#define SDRAM_tRAS TRAS_4 +#define SDRAM_tRAS_num 4 +#define SDRAM_tRCD TRCD_2 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 66666667) && (CONFIG_SCLK_HZ <= 74626866) +#define SDRAM_tRP TRP_2 +#define SDRAM_tRP_num 2 +#define SDRAM_tRAS TRAS_3 +#define SDRAM_tRAS_num 3 +#define SDRAM_tRCD TRCD_2 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 59701493) && (CONFIG_SCLK_HZ <= 66666667) +#define SDRAM_tRP TRP_1 +#define SDRAM_tRP_num 1 +#define SDRAM_tRAS TRAS_4 +#define SDRAM_tRAS_num 3 +#define SDRAM_tRCD TRCD_1 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 44776119) && (CONFIG_SCLK_HZ <= 59701493) +#define SDRAM_tRP TRP_1 +#define SDRAM_tRP_num 1 +#define SDRAM_tRAS TRAS_3 +#define SDRAM_tRAS_num 3 +#define SDRAM_tRCD TRCD_1 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 29850746) && (CONFIG_SCLK_HZ <= 44776119) +#define SDRAM_tRP TRP_1 +#define SDRAM_tRP_num 1 +#define SDRAM_tRAS TRAS_2 +#define SDRAM_tRAS_num 2 +#define SDRAM_tRCD TRCD_1 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ <= 29850746) +#define SDRAM_tRP TRP_1 +#define SDRAM_tRP_num 1 +#define SDRAM_tRAS TRAS_1 +#define SDRAM_tRAS_num 1 +#define SDRAM_tRCD TRCD_1 +#define SDRAM_tWR TWR_2 +#endif +#endif + +#if (CONFIG_MEM_MT48LC16M16A2TG_75) + /*SDRAM INFORMATION: */ +#define SDRAM_Tref 64 /* Refresh period in milliseconds */ +#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */ +#define SDRAM_CL CL_3 +#endif + +#if (CONFIG_MEM_MT48LC64M4A2FB_7E) + /*SDRAM INFORMATION: */ +#define SDRAM_Tref 64 /* Refresh period in milliseconds */ +#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */ +#define SDRAM_CL CL_3 +#endif + +#if (CONFIG_MEM_GENERIC_BOARD) + /*SDRAM INFORMATION: Modify this for your board */ +#define SDRAM_Tref 64 /* Refresh period in milliseconds */ +#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */ +#define SDRAM_CL CL_3 +#endif + +#if (CONFIG_MEM_SIZE == 128) +#define SDRAM_SIZE EBSZ_128 +#endif +#if (CONFIG_MEM_SIZE == 64) +#define SDRAM_SIZE EBSZ_64 +#endif +#if (CONFIG_MEM_SIZE == 32) +#define SDRAM_SIZE EBSZ_32 +#endif +#if (CONFIG_MEM_SIZE == 16) +#define SDRAM_SIZE EBSZ_16 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 11) +#define SDRAM_WIDTH EBCAW_11 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 10) +#define SDRAM_WIDTH EBCAW_10 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 9) +#define SDRAM_WIDTH EBCAW_9 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 8) +#define SDRAM_WIDTH EBCAW_8 +#endif + +#define mem_SDBCTL (SDRAM_WIDTH | SDRAM_SIZE | EBE) + +/* Equation from section 17 (p17-46) of BF533 HRM */ +#define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num) + +/* Enable SCLK Out */ +#define mem_SDGCTL (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR | PSS) + +#if defined CONFIG_CLKIN_HALF +#define CLKIN_HALF 1 +#else +#define CLKIN_HALF 0 +#endif + +#if defined CONFIG_PLL_BYPASS +#define PLL_BYPASS 1 +#else +#define PLL_BYPASS 0 +#endif + +/***************************************Currently Not Being Used *********************************/ +#define flash_EBIU_AMBCTL_WAT ((CONFIG_FLASH_SPEED_BWAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1 +#define flash_EBIU_AMBCTL_RAT ((CONFIG_FLASH_SPEED_BRAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1 +#define flash_EBIU_AMBCTL_HT ((CONFIG_FLASH_SPEED_BHT * 4) / (4000000000 / CONFIG_SCLK_HZ)) +#define flash_EBIU_AMBCTL_ST ((CONFIG_FLASH_SPEED_BST * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1 +#define flash_EBIU_AMBCTL_TT ((CONFIG_FLASH_SPEED_BTT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1 + +#if (flash_EBIU_AMBCTL_TT > 3) +#define flash_EBIU_AMBCTL0_TT B0TT_4 +#endif +#if (flash_EBIU_AMBCTL_TT == 3) +#define flash_EBIU_AMBCTL0_TT B0TT_3 +#endif +#if (flash_EBIU_AMBCTL_TT == 2) +#define flash_EBIU_AMBCTL0_TT B0TT_2 +#endif +#if (flash_EBIU_AMBCTL_TT < 2) +#define flash_EBIU_AMBCTL0_TT B0TT_1 +#endif + +#if (flash_EBIU_AMBCTL_ST > 3) +#define flash_EBIU_AMBCTL0_ST B0ST_4 +#endif +#if (flash_EBIU_AMBCTL_ST == 3) +#define flash_EBIU_AMBCTL0_ST B0ST_3 +#endif +#if (flash_EBIU_AMBCTL_ST == 2) +#define flash_EBIU_AMBCTL0_ST B0ST_2 +#endif +#if (flash_EBIU_AMBCTL_ST < 2) +#define flash_EBIU_AMBCTL0_ST B0ST_1 +#endif + +#if (flash_EBIU_AMBCTL_HT > 2) +#define flash_EBIU_AMBCTL0_HT B0HT_3 +#endif +#if (flash_EBIU_AMBCTL_HT == 2) +#define flash_EBIU_AMBCTL0_HT B0HT_2 +#endif +#if (flash_EBIU_AMBCTL_HT == 1) +#define flash_EBIU_AMBCTL0_HT B0HT_1 +#endif +#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT == 0) +#define flash_EBIU_AMBCTL0_HT B0HT_0 +#endif +#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT != 0) +#define flash_EBIU_AMBCTL0_HT B0HT_1 +#endif + +#if (flash_EBIU_AMBCTL_WAT > 14) +#define flash_EBIU_AMBCTL0_WAT B0WAT_15 +#endif +#if (flash_EBIU_AMBCTL_WAT == 14) +#define flash_EBIU_AMBCTL0_WAT B0WAT_14 +#endif +#if (flash_EBIU_AMBCTL_WAT == 13) +#define flash_EBIU_AMBCTL0_WAT B0WAT_13 +#endif +#if (flash_EBIU_AMBCTL_WAT == 12) +#define flash_EBIU_AMBCTL0_WAT B0WAT_12 +#endif +#if (flash_EBIU_AMBCTL_WAT == 11) +#define flash_EBIU_AMBCTL0_WAT B0WAT_11 +#endif +#if (flash_EBIU_AMBCTL_WAT == 10) +#define flash_EBIU_AMBCTL0_WAT B0WAT_10 +#endif +#if (flash_EBIU_AMBCTL_WAT == 9) +#define flash_EBIU_AMBCTL0_WAT B0WAT_9 +#endif +#if (flash_EBIU_AMBCTL_WAT == 8) +#define flash_EBIU_AMBCTL0_WAT B0WAT_8 +#endif +#if (flash_EBIU_AMBCTL_WAT == 7) +#define flash_EBIU_AMBCTL0_WAT B0WAT_7 +#endif +#if (flash_EBIU_AMBCTL_WAT == 6) +#define flash_EBIU_AMBCTL0_WAT B0WAT_6 +#endif +#if (flash_EBIU_AMBCTL_WAT == 5) +#define flash_EBIU_AMBCTL0_WAT B0WAT_5 +#endif +#if (flash_EBIU_AMBCTL_WAT == 4) +#define flash_EBIU_AMBCTL0_WAT B0WAT_4 +#endif +#if (flash_EBIU_AMBCTL_WAT == 3) +#define flash_EBIU_AMBCTL0_WAT B0WAT_3 +#endif +#if (flash_EBIU_AMBCTL_WAT == 2) +#define flash_EBIU_AMBCTL0_WAT B0WAT_2 +#endif +#if (flash_EBIU_AMBCTL_WAT == 1) +#define flash_EBIU_AMBCTL0_WAT B0WAT_1 +#endif + +#if (flash_EBIU_AMBCTL_RAT > 14) +#define flash_EBIU_AMBCTL0_RAT B0RAT_15 +#endif +#if (flash_EBIU_AMBCTL_RAT == 14) +#define flash_EBIU_AMBCTL0_RAT B0RAT_14 +#endif +#if (flash_EBIU_AMBCTL_RAT == 13) +#define flash_EBIU_AMBCTL0_RAT B0RAT_13 +#endif +#if (flash_EBIU_AMBCTL_RAT == 12) +#define flash_EBIU_AMBCTL0_RAT B0RAT_12 +#endif +#if (flash_EBIU_AMBCTL_RAT == 11) +#define flash_EBIU_AMBCTL0_RAT B0RAT_11 +#endif +#if (flash_EBIU_AMBCTL_RAT == 10) +#define flash_EBIU_AMBCTL0_RAT B0RAT_10 +#endif +#if (flash_EBIU_AMBCTL_RAT == 9) +#define flash_EBIU_AMBCTL0_RAT B0RAT_9 +#endif +#if (flash_EBIU_AMBCTL_RAT == 8) +#define flash_EBIU_AMBCTL0_RAT B0RAT_8 +#endif +#if (flash_EBIU_AMBCTL_RAT == 7) +#define flash_EBIU_AMBCTL0_RAT B0RAT_7 +#endif +#if (flash_EBIU_AMBCTL_RAT == 6) +#define flash_EBIU_AMBCTL0_RAT B0RAT_6 +#endif +#if (flash_EBIU_AMBCTL_RAT == 5) +#define flash_EBIU_AMBCTL0_RAT B0RAT_5 +#endif +#if (flash_EBIU_AMBCTL_RAT == 4) +#define flash_EBIU_AMBCTL0_RAT B0RAT_4 +#endif +#if (flash_EBIU_AMBCTL_RAT == 3) +#define flash_EBIU_AMBCTL0_RAT B0RAT_3 +#endif +#if (flash_EBIU_AMBCTL_RAT == 2) +#define flash_EBIU_AMBCTL0_RAT B0RAT_2 +#endif +#if (flash_EBIU_AMBCTL_RAT == 1) +#define flash_EBIU_AMBCTL0_RAT B0RAT_1 +#endif + +#define flash_EBIU_AMBCTL0 \ + (flash_EBIU_AMBCTL0_WAT | flash_EBIU_AMBCTL0_RAT | flash_EBIU_AMBCTL0_HT | \ + flash_EBIU_AMBCTL0_ST | flash_EBIU_AMBCTL0_TT | CONFIG_FLASH_SPEED_RDYEN) diff --git a/include/asm-blackfin/mach-bf533/mem_map.h b/include/asm-blackfin/mach-bf533/mem_map.h new file mode 100644 index 000000000000..e84baa3e939d --- /dev/null +++ b/include/asm-blackfin/mach-bf533/mem_map.h @@ -0,0 +1,168 @@ + +/* + * File: include/asm-blackfin/mach-bf533/mem_map.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Rev: + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _MEM_MAP_533_H_ +#define _MEM_MAP_533_H_ + +#define COREMMR_BASE 0xFFE00000 /* Core MMRs */ +#define SYSMMR_BASE 0xFFC00000 /* System MMRs */ + +/* Async Memory Banks */ +#define ASYNC_BANK3_BASE 0x20300000 /* Async Bank 3 */ +#define ASYNC_BANK3_SIZE 0x00100000 /* 1M */ +#define ASYNC_BANK2_BASE 0x20200000 /* Async Bank 2 */ +#define ASYNC_BANK2_SIZE 0x00100000 /* 1M */ +#define ASYNC_BANK1_BASE 0x20100000 /* Async Bank 1 */ +#define ASYNC_BANK1_SIZE 0x00100000 /* 1M */ +#define ASYNC_BANK0_BASE 0x20000000 /* Async Bank 0 */ +#define ASYNC_BANK0_SIZE 0x00100000 /* 1M */ + +/* Boot ROM Memory */ + +#define BOOT_ROM_START 0xEF000000 + +/* Level 1 Memory */ + +#ifdef CONFIG_BLKFIN_CACHE +#define BLKFIN_ICACHESIZE (16*1024) +#else +#define BLKFIN_ICACHESIZE (0*1024) +#endif + +/* Memory Map for ADSP-BF533 processors */ + +#ifdef CONFIG_BF533 +#define L1_CODE_START 0xFFA00000 +#define L1_DATA_A_START 0xFF800000 +#define L1_DATA_B_START 0xFF900000 + +#ifdef CONFIG_BLKFIN_CACHE +#define L1_CODE_LENGTH (0x14000 - 0x4000) +#else +#define L1_CODE_LENGTH 0x14000 +#endif + +#ifdef CONFIG_BLKFIN_DCACHE + +#ifdef CONFIG_BLKFIN_DCACHE_BANKA +#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH (0x8000 - 0x4000) +#define L1_DATA_B_LENGTH 0x8000 +#define BLKFIN_DCACHESIZE (16*1024) +#define BLKFIN_DSUPBANKS 1 +#else +#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH (0x8000 - 0x4000) +#define L1_DATA_B_LENGTH (0x8000 - 0x4000) +#define BLKFIN_DCACHESIZE (32*1024) +#define BLKFIN_DSUPBANKS 2 +#endif + +#else +#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH 0x8000 +#define L1_DATA_B_LENGTH 0x8000 +#define BLKFIN_DCACHESIZE (0*1024) +#define BLKFIN_DSUPBANKS 0 +#endif /*CONFIG_BLKFIN_DCACHE*/ +#endif + +/* Memory Map for ADSP-BF532 processors */ + +#ifdef CONFIG_BF532 +#define L1_CODE_START 0xFFA08000 +#define L1_DATA_A_START 0xFF804000 +#define L1_DATA_B_START 0xFF904000 + +#ifdef CONFIG_BLKFIN_CACHE +#define L1_CODE_LENGTH (0xC000 - 0x4000) +#else +#define L1_CODE_LENGTH 0xC000 +#endif + +#ifdef CONFIG_BLKFIN_DCACHE + +#ifdef CONFIG_BLKFIN_DCACHE_BANKA +#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH (0x4000 - 0x4000) +#define L1_DATA_B_LENGTH 0x4000 +#define BLKFIN_DCACHESIZE (16*1024) +#define BLKFIN_DSUPBANKS 1 + +#else +#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH (0x4000 - 0x4000) +#define L1_DATA_B_LENGTH (0x4000 - 0x4000) +#define BLKFIN_DCACHESIZE (32*1024) +#define BLKFIN_DSUPBANKS 2 +#endif + +#else +#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH 0x4000 +#define L1_DATA_B_LENGTH 0x4000 +#define BLKFIN_DCACHESIZE (0*1024) +#define BLKFIN_DSUPBANKS 0 +#endif /*CONFIG_BLKFIN_DCACHE*/ +#endif + +/* Memory Map for ADSP-BF531 processors */ + +#ifdef CONFIG_BF531 +#define L1_CODE_START 0xFFA08000 +#define L1_DATA_A_START 0xFF804000 +#define L1_DATA_B_START 0xFF904000 +#define L1_CODE_LENGTH 0x4000 +#define L1_DATA_B_LENGTH 0x0000 + + +#ifdef CONFIG_BLKFIN_DCACHE +#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH (0x4000 - 0x4000) +#define BLKFIN_DCACHESIZE (16*1024) +#define BLKFIN_DSUPBANKS 1 +#else +#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH 0x4000 +#define BLKFIN_DCACHESIZE (0*1024) +#define BLKFIN_DSUPBANKS 0 +#endif + +#endif + +/* Scratch Pad Memory */ + +#if defined(CONFIG_BF533) || defined(CONFIG_BF532) || defined(CONFIG_BF531) +#define L1_SCRATCH_START 0xFFB00000 +#define L1_SCRATCH_LENGTH 0x1000 +#endif + +#endif /* _MEM_MAP_533_H_ */ diff --git a/include/asm-blackfin/mach-bf537/anomaly.h b/include/asm-blackfin/mach-bf537/anomaly.h new file mode 100644 index 000000000000..7f040f5ba018 --- /dev/null +++ b/include/asm-blackfin/mach-bf537/anomaly.h @@ -0,0 +1,120 @@ + +/* + * File: include/asm-blackfin/mach-bf537/anomaly.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Rev: + * + * Modified: + * + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* This file shoule be up to date with: + * - Revision J, June 1, 2006; ADSP-BF537 Blackfin Processor Anomaly List + * - Revision I, June 1, 2006; ADSP-BF536 Blackfin Processor Anomaly List + * - Revision J, June 1, 2006; ADSP-BF534 Blackfin Processor Anomaly List + */ + +#ifndef _MACH_ANOMALY_H_ +#define _MACH_ANOMALY_H_ + +/* We do not support 0.1 silicon - sorry */ +#if (defined(CONFIG_BF_REV_0_1)) +#error Kernel will not work on BF537/6/4 Version 0.1 +#endif + +#if (defined(CONFIG_BF_REV_0_3) || defined(CONFIG_BF_REV_0_2)) +#define ANOMALY_05000074 /* A multi issue instruction with dsp32shiftimm in + slot1 and store of a P register in slot 2 is not + supported */ +#define ANOMALY_05000119 /* DMA_RUN bit is not valid after a Peripheral Receive + Channel DMA stops */ +#define ANOMALY_05000122 /* Rx.H can not be used to access 16-bit System MMR + registers. */ +#define ANOMALY_05000166 /* PPI Data Lengths Between 8 and 16 do not zero out + upper bits*/ +#define ANOMALY_05000180 /* PPI_DELAY not functional in PPI modes with 0 frame + syncs */ +#if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) +#define ANOMALY_05000247 /* CLKIN Buffer Output Enable Reset Behavior Is + Changed */ +#endif +#define ANOMALY_05000265 /* Sensitivity to noise with slow input edge rates on + SPORT external receive and transmit clocks. */ +#define ANOMALY_05000272 /* Certain data cache write through modes fail for + VDDint <=0.9V */ +#define ANOMALY_05000273 /* Writes to Synchronous SDRAM memory may be lost */ +#define ANOMALY_05000277 /* Writes to a flag data register one SCLK cycle after + an edge is detected may clear interrupt */ +#define ANOMALY_05000281 /* False Hardware Error Exception when ISR context is + not restored */ +#define ANOMALY_05000282 /* Memory DMA corruption with 32-bit data and traffic + control */ +#define ANOMALY_05000283 /* A system MMR write is stalled indefinitely when + killed in a particular stage*/ +#define ANOMALY_05000312 /* Errors when SSYNC, CSYNC, or loads to LT, LB and LC + registers are interrupted */ +#endif + +#if defined(CONFIG_BF_REV_0_2) +#define ANOMALY_05000244 /* With instruction cache enabled, a CSYNC or SSYNC or + IDLE around a Change of Control causes + unpredictable results */ +#define ANOMALY_05000250 /* Incorrect Bit-Shift of Data Word in Multichannel + (TDM) */ +#if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) +#define ANOMALY_05000252 /* EMAC Tx DMA error after an early frame abort */ +#endif +#define ANOMALY_05000253 /* Maximum external clock speed for Timers */ +#define ANOMALY_05000255 /* Entering Hibernate Mode with RTC Seconds event + interrupt not functional */ +#if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) +#define ANOMALY_05000256 /* EMAC MDIO input latched on wrong MDC edge */ +#endif +#define ANOMALY_05000257 /* An interrupt or exception during short Hardware + loops may cause the instruction fetch unit to + malfunction */ +#define ANOMALY_05000258 /* Instruction Cache is corrupted when bit 9 and 12 of + the ICPLB Data registers differ */ +#define ANOMALY_05000260 /* ICPLB_STATUS MMR register may be corrupted */ +#define ANOMALY_05000261 /* DCPLB_FAULT_ADDR MMR register may be corrupted */ +#define ANOMALY_05000262 /* Stores to data cache may be lost */ +#define ANOMALY_05000263 /* Hardware loop corrupted when taking an ICPLB exception */ +#define ANOMALY_05000264 /* A Sync instruction (CSYNC, SSYNC) or an IDLE + instruction will cause an infinite stall in the + second to last instruction in a hardware loop */ +#define ANOMALY_05000268 /* Memory DMA error when peripheral DMA is running + and non-zero DEB_TRAFFIC_PERIOD value */ +#define ANOMALY_05000270 /* High I/O activity causes the output voltage of the + internal voltage regulator (VDDint) to decrease */ +#define ANOMALY_05000277 /* Writes to a flag data register one SCLK cycle after + an edge is detected may clear interrupt */ +#define ANOMALY_05000278 /* Disabling Peripherals with DMA running may cause + DMA system instability */ +#define ANOMALY_05000280 /* SPI Master boot mode does not work well with + Atmel Dataflash devices */ + +#endif /* CONFIG_BF_REV_0_2 */ + +#endif /* _MACH_ANOMALY_H_ */ diff --git a/include/asm-blackfin/mach-bf537/bf537.h b/include/asm-blackfin/mach-bf537/bf537.h new file mode 100644 index 000000000000..b8924cd7730c --- /dev/null +++ b/include/asm-blackfin/mach-bf537/bf537.h @@ -0,0 +1,287 @@ +/* + * File: include/asm-blackfin/mach-bf537/bf537.h + * Based on: + * Author: + * + * Created: + * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF537 + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __MACH_BF537_H__ +#define __MACH_BF537_H__ + +#define SUPPORTED_REVID 2 + +/* Masks for generic ERROR IRQ demultiplexing used in int-priority-sc.c */ + +#define SPI_ERR_MASK (TXCOL | RBSY | MODF | TXE) /* SPI_STAT */ +#define SPORT_ERR_MASK (ROVF | RUVF | TOVF | TUVF) /* SPORTx_STAT */ +#define PPI_ERR_MASK (0xFFFF & ~FLD) /* PPI_STATUS */ +#define EMAC_ERR_MASK (PHYINT | MMCINT | RXFSINT | TXFSINT | WAKEDET | RXDMAERR | TXDMAERR | STMDONE) /* EMAC_SYSTAT */ +#define UART_ERR_MASK_STAT1 (0x4) /* UARTx_IIR */ +#define UART_ERR_MASK_STAT0 (0x2) /* UARTx_IIR */ +#define CAN_ERR_MASK (EWTIF | EWRIF | EPIF | BOIF | WUIF | UIAIF | AAIF | RMLIF | UCEIF | EXTIF | ADIF) /* CAN_GIF */ + +#define OFFSET_(x) ((x) & 0x0000FFFF) + +/*some misc defines*/ +#define IMASK_IVG15 0x8000 +#define IMASK_IVG14 0x4000 +#define IMASK_IVG13 0x2000 +#define IMASK_IVG12 0x1000 + +#define IMASK_IVG11 0x0800 +#define IMASK_IVG10 0x0400 +#define IMASK_IVG9 0x0200 +#define IMASK_IVG8 0x0100 + +#define IMASK_IVG7 0x0080 +#define IMASK_IVGTMR 0x0040 +#define IMASK_IVGHW 0x0020 + +/***************************/ + + +#define BLKFIN_DSUBBANKS 4 +#define BLKFIN_DWAYS 2 +#define BLKFIN_DLINES 64 +#define BLKFIN_ISUBBANKS 4 +#define BLKFIN_IWAYS 4 +#define BLKFIN_ILINES 32 + +#define WAY0_L 0x1 +#define WAY1_L 0x2 +#define WAY01_L 0x3 +#define WAY2_L 0x4 +#define WAY02_L 0x5 +#define WAY12_L 0x6 +#define WAY012_L 0x7 + +#define WAY3_L 0x8 +#define WAY03_L 0x9 +#define WAY13_L 0xA +#define WAY013_L 0xB + +#define WAY32_L 0xC +#define WAY320_L 0xD +#define WAY321_L 0xE +#define WAYALL_L 0xF + +#define DMC_ENABLE (2<<2) /*yes, 2, not 1 */ + +/********************************* EBIU Settings ************************************/ +#define AMBCTL0VAL ((CONFIG_BANK_1 << 16) | CONFIG_BANK_0) +#define AMBCTL1VAL ((CONFIG_BANK_3 << 16) | CONFIG_BANK_2) + +#ifdef CONFIG_C_AMBEN_ALL +#define V_AMBEN AMBEN_ALL +#endif +#ifdef CONFIG_C_AMBEN +#define V_AMBEN 0x0 +#endif +#ifdef CONFIG_C_AMBEN_B0 +#define V_AMBEN AMBEN_B0 +#endif +#ifdef CONFIG_C_AMBEN_B0_B1 +#define V_AMBEN AMBEN_B0_B1 +#endif +#ifdef CONFIG_C_AMBEN_B0_B1_B2 +#define V_AMBEN AMBEN_B0_B1_B2 +#endif +#ifdef CONFIG_C_AMCKEN +#define V_AMCKEN AMCKEN +#else +#define V_AMCKEN 0x0 +#endif +#ifdef CONFIG_C_CDPRIO +#define V_CDPRIO 0x100 +#else +#define V_CDPRIO 0x0 +#endif + +#define AMGCTLVAL (V_AMBEN | V_AMCKEN | V_CDPRIO) + +#define MAX_VC 650000000 +#define MIN_VC 50000000 + +/********************************PLL Settings **************************************/ +#ifdef CONFIG_BFIN_KERNEL_CLOCK +#if (CONFIG_VCO_MULT < 0) +#error "VCO Multiplier is less than 0. Please select a different value" +#endif + +#if (CONFIG_VCO_MULT == 0) +#error "VCO Multiplier should be greater than 0. Please select a different value" +#endif + +#if (CONFIG_VCO_MULT > 64) +#error "VCO Multiplier is more than 64. Please select a different value" +#endif + +#ifndef CONFIG_CLKIN_HALF +#define CONFIG_VCO_HZ (CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) +#else +#define CONFIG_VCO_HZ ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)/2) +#endif + +#ifndef CONFIG_PLL_BYPASS +#define CONFIG_CCLK_HZ (CONFIG_VCO_HZ/CONFIG_CCLK_DIV) +#define CONFIG_SCLK_HZ (CONFIG_VCO_HZ/CONFIG_SCLK_DIV) +#else +#define CONFIG_CCLK_HZ CONFIG_CLKIN_HZ +#define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ +#endif + +#if (CONFIG_SCLK_DIV < 1) +#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value" +#endif + +#if (CONFIG_SCLK_DIV > 15) +#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value" +#endif + +#if (CONFIG_CCLK_DIV != 1) +#if (CONFIG_CCLK_DIV != 2) +#if (CONFIG_CCLK_DIV != 4) +#if (CONFIG_CCLK_DIV != 8) +#error "CCLK DIV can be 1,2,4 or 8 only. Please select a proper value" +#endif +#endif +#endif +#endif + +#if (CONFIG_VCO_HZ > MAX_VC) +#error "VCO selected is more than maximum value. Please change the VCO multipler" +#endif + +#if (CONFIG_SCLK_HZ > 133000000) +#error "Sclk value selected is more than maximum. Please select a proper value for SCLK multiplier" +#endif + +#if (CONFIG_SCLK_HZ < 27000000) +#error "Sclk value selected is less than minimum. Please select a proper value for SCLK multiplier" +#endif + +#if (CONFIG_SCLK_HZ >= CONFIG_CCLK_HZ) +#if (CONFIG_SCLK_HZ != CONFIG_CLKIN_HZ) +#if (CONFIG_CCLK_HZ != CONFIG_CLKIN_HZ) +#error "Please select sclk less than cclk" +#endif +#endif +#endif + +#if (CONFIG_CCLK_DIV == 1) +#define CONFIG_CCLK_ACT_DIV CCLK_DIV1 +#endif +#if (CONFIG_CCLK_DIV == 2) +#define CONFIG_CCLK_ACT_DIV CCLK_DIV2 +#endif +#if (CONFIG_CCLK_DIV == 4) +#define CONFIG_CCLK_ACT_DIV CCLK_DIV4 +#endif +#if (CONFIG_CCLK_DIV == 8) +#define CONFIG_CCLK_ACT_DIV CCLK_DIV8 +#endif +#ifndef CONFIG_CCLK_ACT_DIV +#define CONFIG_CCLK_ACT_DIV CONFIG_CCLK_DIV_not_defined_properly +#endif + +#if defined(ANOMALY_05000273) && (CONFIG_CCLK_DIV == 1) +#error ANOMALY 05000273, please make sure CCLK is at least 2x SCLK +#endif + +#endif /* CONFIG_BFIN_KERNEL_CLOCK */ + +#ifdef CONFIG_BF537 +#define CPU "BF537" +#define CPUID 0x027c8000 +#endif +#ifdef CONFIG_BF536 +#define CPU "BF536" +#define CPUID 0x027c8000 +#endif +#ifdef CONFIG_BF534 +#define CPU "BF534" +#define CPUID 0x027c6000 +#endif +#ifndef CPU +#define CPU "UNKNOWN" +#define CPUID 0x0 +#endif + +#if (CONFIG_MEM_SIZE % 4) +#error "SDRAM mem size must be multible of 4MB" +#endif + +#define SDRAM_IGENERIC (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO) +#define SDRAM_IKERNEL (SDRAM_IGENERIC | CPLB_LOCK) +#define L1_IMEMORY ( CPLB_USER_RD | CPLB_VALID | CPLB_LOCK) +#define SDRAM_INON_CHBL ( CPLB_USER_RD | CPLB_VALID) + +/*Use the menuconfig cache policy here - CONFIG_BLKFIN_WT/CONFIG_BLKFIN_WB*/ + +#define ANOMALY_05000158_WORKAROUND 0x200 +#ifdef CONFIG_BLKFIN_WB /*Write Back Policy */ +#define SDRAM_DGENERIC (CPLB_L1_CHBL | CPLB_DIRTY \ + | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND) +#else /*Write Through */ +#define SDRAM_DGENERIC (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW \ + | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY ) +#endif + + +#define L1_DMEMORY (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY ) +#define SDRAM_DNON_CHBL (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY ) +#define SDRAM_EBIU (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY ) +#define SDRAM_OOPS (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY ) + +#define SIZE_1K 0x00000400 /* 1K */ +#define SIZE_4K 0x00001000 /* 4K */ +#define SIZE_1M 0x00100000 /* 1M */ +#define SIZE_4M 0x00400000 /* 4M */ + +#define MAX_CPLBS (16 * 2) + +/* +* Number of required data CPLB switchtable entries +* MEMSIZE / 4 (we mostly install 4M page size CPLBs +* approx 16 for smaller 1MB page size CPLBs for allignment purposes +* 1 for L1 Data Memory +* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO +* 1 for ASYNC Memory +*/ + + +#define MAX_SWITCH_D_CPLBS (((CONFIG_MEM_SIZE / 4) + 16 + 1 + 1 + 1) * 2) + +/* +* Number of required instruction CPLB switchtable entries +* MEMSIZE / 4 (we mostly install 4M page size CPLBs +* approx 12 for smaller 1MB page size CPLBs for allignment purposes +* 1 for L1 Instruction Memory +* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO +*/ + +#define MAX_SWITCH_I_CPLBS (((CONFIG_MEM_SIZE / 4) + 12 + 1 + 1) * 2) + +#endif /* __MACH_BF537_H__ */ diff --git a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h new file mode 100644 index 000000000000..8f5d9c4d8d5b --- /dev/null +++ b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h @@ -0,0 +1,147 @@ +#include +#include + +#define NR_PORTS 2 + +#define OFFSET_THR 0x00 /* Transmit Holding register */ +#define OFFSET_RBR 0x00 /* Receive Buffer register */ +#define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */ +#define OFFSET_IER 0x04 /* Interrupt Enable Register */ +#define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */ +#define OFFSET_IIR 0x08 /* Interrupt Identification Register */ +#define OFFSET_LCR 0x0C /* Line Control Register */ +#define OFFSET_MCR 0x10 /* Modem Control Register */ +#define OFFSET_LSR 0x14 /* Line Status Register */ +#define OFFSET_MSR 0x18 /* Modem Status Register */ +#define OFFSET_SCR 0x1C /* SCR Scratch Register */ +#define OFFSET_GCTL 0x24 /* Global Control Register */ + +#define UART_GET_CHAR(uart) bfin_read16(((uart)->port.membase + OFFSET_RBR)) +#define UART_GET_DLL(uart) bfin_read16(((uart)->port.membase + OFFSET_DLL)) +#define UART_GET_IER(uart) bfin_read16(((uart)->port.membase + OFFSET_IER)) +#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH)) +#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR)) +#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) +#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) +#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) + +#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) +#define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v) +#define UART_PUT_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER),v) +#define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v) +#define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v) +#define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v) + +#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) +# define CONFIG_SERIAL_BFIN_CTSRTS + +# ifndef CONFIG_UART0_CTS_PIN +# define CONFIG_UART0_CTS_PIN -1 +# endif + +# ifndef CONFIG_UART0_RTS_PIN +# define CONFIG_UART0_RTS_PIN -1 +# endif + +# ifndef CONFIG_UART1_CTS_PIN +# define CONFIG_UART1_CTS_PIN -1 +# endif + +# ifndef CONFIG_UART1_RTS_PIN +# define CONFIG_UART1_RTS_PIN -1 +# endif +#endif +/* + * The pin configuration is different from schematic + */ +struct bfin_serial_port { + struct uart_port port; + unsigned int old_status; +#ifdef CONFIG_SERIAL_BFIN_DMA + int tx_done; + int tx_count; + struct circ_buf rx_dma_buf; + struct timer_list rx_dma_timer; + int rx_dma_nrows; + unsigned int tx_dma_channel; + unsigned int rx_dma_channel; + struct work_struct tx_dma_workqueue; +#else + struct work_struct cts_workqueue; +#endif +#ifdef CONFIG_SERIAL_BFIN_CTSRTS + int cts_pin; + int rts_pin; +#endif +}; + +struct bfin_serial_port bfin_serial_ports[NR_PORTS]; +struct bfin_serial_res { + unsigned long uart_base_addr; + int uart_irq; +#ifdef CONFIG_SERIAL_BFIN_DMA + unsigned int uart_tx_dma_channel; + unsigned int uart_rx_dma_channel; +#endif +#ifdef CONFIG_SERIAL_BFIN_CTSRTS + int uart_cts_pin; + int uart_rts_pin; +#endif +}; + +struct bfin_serial_res bfin_serial_resource[] = { +#ifdef CONFIG_SERIAL_BFIN_UART0 + { + 0xFFC00400, + IRQ_UART0_RX, +#ifdef CONFIG_SERIAL_BFIN_DMA + CH_UART0_TX, + CH_UART0_RX, +#endif +#ifdef CONFIG_BFIN_UART0_CTSRTS + CONFIG_UART0_CTS_PIN, + CONFIG_UART0_RTS_PIN, +#endif + }, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + { + 0xFFC02000, + IRQ_UART1_RX, +#ifdef CONFIG_SERIAL_BFIN_DMA + CH_UART1_TX, + CH_UART1_RX, +#endif +#ifdef CONFIG_BFIN_UART1_CTSRTS + CONFIG_UART1_CTS_PIN, + CONFIG_UART1_RTS_PIN, +#endif + }, +#endif +}; + +int nr_ports = ARRAY_SIZE(bfin_serial_resource); + +static void bfin_serial_hw_init(struct bfin_serial_port *uart) +{ + unsigned short val; + val = bfin_read16(BFIN_PORT_MUX); + val &= ~(PFDE | PFTE); + bfin_write16(BFIN_PORT_MUX, val); + + val = bfin_read16(PORTF_FER); + val |= 0xF; + bfin_write16(PORTF_FER, val); + +#ifdef CONFIG_SERIAL_BFIN_CTSRTS + if (uart->cts_pin >= 0) { + gpio_request(uart->cts_pin, NULL); + gpio_direction_input(uart->cts_pin); + } + + if (uart->rts_pin >= 0) { + gpio_request(uart->rts_pin, NULL); + gpio_direction_output(uart->rts_pin); + } +#endif +} diff --git a/include/asm-blackfin/mach-bf537/blackfin.h b/include/asm-blackfin/mach-bf537/blackfin.h new file mode 100644 index 000000000000..bbd97051ec9c --- /dev/null +++ b/include/asm-blackfin/mach-bf537/blackfin.h @@ -0,0 +1,430 @@ +/* + * File: include/asm-blackfin/mach-bf537/blackfin.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Rev: + * + * Modified: + * + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _MACH_BLACKFIN_H_ +#define _MACH_BLACKFIN_H_ + +#define BF537_FAMILY + +#include "bf537.h" +#include "mem_map.h" +#include "defBF534.h" +#include "anomaly.h" + +#if defined(CONFIG_BF537) || defined(CONFIG_BF536) +#include "defBF537.h" +#endif + +#if !(defined(__ASSEMBLY__) || defined(ASSEMBLY)) +#include "cdefBF534.h" + +/* UART 0*/ +#define bfin_read_UART_THR() bfin_read_UART0_THR() +#define bfin_write_UART_THR(val) bfin_write_UART0_THR(val) +#define bfin_read_UART_RBR() bfin_read_UART0_RBR() +#define bfin_write_UART_RBR(val) bfin_write_UART0_RBR(val) +#define bfin_read_UART_DLL() bfin_read_UART0_DLL() +#define bfin_write_UART_DLL(val) bfin_write_UART0_DLL(val) +#define bfin_read_UART_IER() bfin_read_UART0_IER() +#define bfin_write_UART_IER(val) bfin_write_UART0_IER(val) +#define bfin_read_UART_DLH() bfin_read_UART0_DLH() +#define bfin_write_UART_DLH(val) bfin_write_UART0_DLH(val) +#define bfin_read_UART_IIR() bfin_read_UART0_IIR() +#define bfin_write_UART_IIR(val) bfin_write_UART0_IIR(val) +#define bfin_read_UART_LCR() bfin_read_UART0_LCR() +#define bfin_write_UART_LCR(val) bfin_write_UART0_LCR(val) +#define bfin_read_UART_MCR() bfin_read_UART0_MCR() +#define bfin_write_UART_MCR(val) bfin_write_UART0_MCR(val) +#define bfin_read_UART_LSR() bfin_read_UART0_LSR() +#define bfin_write_UART_LSR(val) bfin_write_UART0_LSR(val) +#define bfin_read_UART_SCR() bfin_read_UART0_SCR() +#define bfin_write_UART_SCR(val) bfin_write_UART0_SCR(val) +#define bfin_read_UART_GCTL() bfin_read_UART0_GCTL() +#define bfin_write_UART_GCTL(val) bfin_write_UART0_GCTL(val) + +#if defined(CONFIG_BF537) || defined(CONFIG_BF536) +#include "cdefBF537.h" +#endif +#endif + +/* MAP used DEFINES from BF533 to BF537 - so we don't need to change them in the driver, kernel, etc. */ + +/* UART_IIR Register */ +#define STATUS(x) ((x << 1) & 0x06) +#define STATUS_P1 0x02 +#define STATUS_P0 0x01 + +/* UART 0*/ + +/* DMA Channnel */ +#define bfin_read_CH_UART_RX() bfin_read_CH_UART0_RX() +#define bfin_write_CH_UART_RX(val) bfin_write_CH_UART0_RX(val) +#define CH_UART_RX CH_UART0_RX +#define bfin_read_CH_UART_TX() bfin_read_CH_UART0_TX() +#define bfin_write_CH_UART_TX(val) bfin_write_CH_UART0_TX(val) +#define CH_UART_TX CH_UART0_TX + +/* System Interrupt Controller */ +#define bfin_read_IRQ_UART_RX() bfin_read_IRQ_UART0_RX() +#define bfin_write_IRQ_UART_RX(val) bfin_write_IRQ_UART0_RX(val) +#define IRQ_UART_RX IRQ_UART0_RX +#define bfin_read_IRQ_UART_TX() bfin_read_IRQ_UART0_TX() +#define bfin_write_IRQ_UART_TX(val) bfin_write_IRQ_UART0_TX(val) +#define IRQ_UART_TX IRQ_UART0_TX +#define bfin_read_IRQ_UART_ERROR() bfin_read_IRQ_UART0_ERROR() +#define bfin_write_IRQ_UART_ERROR(val) bfin_write_IRQ_UART0_ERROR(val) +#define IRQ_UART_ERROR IRQ_UART0_ERROR + +/* MMR Registers*/ +#define bfin_read_UART_THR() bfin_read_UART0_THR() +#define bfin_write_UART_THR(val) bfin_write_UART0_THR(val) +#define UART_THR UART0_THR +#define bfin_read_UART_RBR() bfin_read_UART0_RBR() +#define bfin_write_UART_RBR(val) bfin_write_UART0_RBR(val) +#define UART_RBR UART0_RBR +#define bfin_read_UART_DLL() bfin_read_UART0_DLL() +#define bfin_write_UART_DLL(val) bfin_write_UART0_DLL(val) +#define UART_DLL UART0_DLL +#define bfin_read_UART_IER() bfin_read_UART0_IER() +#define bfin_write_UART_IER(val) bfin_write_UART0_IER(val) +#define UART_IER UART0_IER +#define bfin_read_UART_DLH() bfin_read_UART0_DLH() +#define bfin_write_UART_DLH(val) bfin_write_UART0_DLH(val) +#define UART_DLH UART0_DLH +#define bfin_read_UART_IIR() bfin_read_UART0_IIR() +#define bfin_write_UART_IIR(val) bfin_write_UART0_IIR(val) +#define UART_IIR UART0_IIR +#define bfin_read_UART_LCR() bfin_read_UART0_LCR() +#define bfin_write_UART_LCR(val) bfin_write_UART0_LCR(val) +#define UART_LCR UART0_LCR +#define bfin_read_UART_MCR() bfin_read_UART0_MCR() +#define bfin_write_UART_MCR(val) bfin_write_UART0_MCR(val) +#define UART_MCR UART0_MCR +#define bfin_read_UART_LSR() bfin_read_UART0_LSR() +#define bfin_write_UART_LSR(val) bfin_write_UART0_LSR(val) +#define UART_LSR UART0_LSR +#define bfin_read_UART_SCR() bfin_read_UART0_SCR() +#define bfin_write_UART_SCR(val) bfin_write_UART0_SCR(val) +#define UART_SCR UART0_SCR +#define bfin_read_UART_GCTL() bfin_read_UART0_GCTL() +#define bfin_write_UART_GCTL(val) bfin_write_UART0_GCTL(val) +#define UART_GCTL UART0_GCTL + +/* DPMC*/ +#define bfin_read_STOPCK_OFF() bfin_read_STOPCK() +#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val) +#define STOPCK_OFF STOPCK + +/* FIO USE PORT F*/ +#ifdef CONFIG_BF537_PORT_F +#define bfin_read_PORT_FER() bfin_read_PORTF_FER() +#define bfin_write_PORT_FER(val) bfin_write_PORTF_FER(val) +#define bfin_read_FIO_FLAG_D() bfin_read_PORTFIO() +#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTFIO(val) +#define bfin_read_FIO_FLAG_C() bfin_read_PORTFIO_CLEAR() +#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTFIO_CLEAR(val) +#define bfin_read_FIO_FLAG_S() bfin_read_PORTFIO_SET() +#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTFIO_SET(val) +#define bfin_read_FIO_FLAG_T() bfin_read_PORTFIO_TOGGLE() +#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTFIO_TOGGLE(val) +#define bfin_read_FIO_MASKA_D() bfin_read_PORTFIO_MASKA() +#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTFIO_MASKA(val) +#define bfin_read_FIO_MASKA_C() bfin_read_PORTFIO_MASKA_CLEAR() +#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTFIO_MASKA_CLEAR(val) +#define bfin_read_FIO_MASKA_S() bfin_read_PORTFIO_MASKA_SET() +#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTFIO_MASKA_SET(val) +#define bfin_read_FIO_MASKA_T() bfin_read_PORTFIO_MASKA_TOGGLE() +#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTFIO_MASKA_TOGGLE(val) +#define bfin_read_FIO_MASKB_D() bfin_read_PORTFIO_MASKB() +#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTFIO_MASKB(val) +#define bfin_read_FIO_MASKB_C() bfin_read_PORTFIO_MASKB_CLEAR() +#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTFIO_MASKB_CLEAR(val) +#define bfin_read_FIO_MASKB_S() bfin_read_PORTFIO_MASKB_SET() +#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTFIO_MASKB_SET(val) +#define bfin_read_FIO_MASKB_T() bfin_read_PORTFIO_MASKB_TOGGLE() +#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTFIO_MASKB_TOGGLE(val) +#define bfin_read_FIO_DIR() bfin_read_PORTFIO_DIR() +#define bfin_write_FIO_DIR(val) bfin_write_PORTFIO_DIR(val) +#define bfin_read_FIO_POLAR() bfin_read_PORTFIO_POLAR() +#define bfin_write_FIO_POLAR(val) bfin_write_PORTFIO_POLAR(val) +#define bfin_read_FIO_EDGE() bfin_read_PORTFIO_EDGE() +#define bfin_write_FIO_EDGE(val) bfin_write_PORTFIO_EDGE(val) +#define bfin_read_FIO_BOTH() bfin_read_PORTFIO_BOTH() +#define bfin_write_FIO_BOTH(val) bfin_write_PORTFIO_BOTH(val) +#define bfin_read_FIO_INEN() bfin_read_PORTFIO_INEN() +#define bfin_write_FIO_INEN(val) bfin_write_PORTFIO_INEN(val) + +#define bfin_read_FIO_FLAG_D() bfin_read_PORTFIO() +#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTFIO(val) +#define FIO_FLAG_D PORTFIO +#define bfin_read_FIO_FLAG_C() bfin_read_PORTFIO_CLEAR() +#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTFIO_CLEAR(val) +#define FIO_FLAG_C PORTFIO_CLEAR +#define bfin_read_FIO_FLAG_S() bfin_read_PORTFIO_SET() +#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTFIO_SET(val) +#define FIO_FLAG_S PORTFIO_SET +#define bfin_read_FIO_FLAG_T() bfin_read_PORTFIO_TOGGLE() +#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTFIO_TOGGLE(val) +#define FIO_FLAG_T PORTFIO_TOGGLE +#define bfin_read_FIO_MASKA_D() bfin_read_PORTFIO_MASKA() +#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTFIO_MASKA(val) +#define FIO_MASKA_D PORTFIO_MASKA +#define bfin_read_FIO_MASKA_C() bfin_read_PORTFIO_MASKA_CLEAR() +#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTFIO_MASKA_CLEAR(val) +#define FIO_MASKA_C PORTFIO_MASKA_CLEAR +#define bfin_read_FIO_MASKA_S() bfin_read_PORTFIO_MASKA_SET() +#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTFIO_MASKA_SET(val) +#define FIO_MASKA_S PORTFIO_MASKA_SET +#define bfin_read_FIO_MASKA_T() bfin_read_PORTFIO_MASKA_TOGGLE() +#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTFIO_MASKA_TOGGLE(val) +#define FIO_MASKA_T PORTFIO_MASKA_TOGGLE +#define bfin_read_FIO_MASKB_D() bfin_read_PORTFIO_MASKB() +#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTFIO_MASKB(val) +#define FIO_MASKB_D PORTFIO_MASKB +#define bfin_read_FIO_MASKB_C() bfin_read_PORTFIO_MASKB_CLEAR() +#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTFIO_MASKB_CLEAR(val) +#define FIO_MASKB_C PORTFIO_MASKB_CLEAR +#define bfin_read_FIO_MASKB_S() bfin_read_PORTFIO_MASKB_SET() +#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTFIO_MASKB_SET(val) +#define FIO_MASKB_S PORTFIO_MASKB_SET +#define bfin_read_FIO_MASKB_T() bfin_read_PORTFIO_MASKB_TOGGLE() +#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTFIO_MASKB_TOGGLE(val) +#define FIO_MASKB_T PORTFIO_MASKB_TOGGLE +#define bfin_read_FIO_DIR() bfin_read_PORTFIO_DIR() +#define bfin_write_FIO_DIR(val) bfin_write_PORTFIO_DIR(val) +#define FIO_DIR PORTFIO_DIR +#define bfin_read_FIO_POLAR() bfin_read_PORTFIO_POLAR() +#define bfin_write_FIO_POLAR(val) bfin_write_PORTFIO_POLAR(val) +#define FIO_POLAR PORTFIO_POLAR +#define bfin_read_FIO_EDGE() bfin_read_PORTFIO_EDGE() +#define bfin_write_FIO_EDGE(val) bfin_write_PORTFIO_EDGE(val) +#define FIO_EDGE PORTFIO_EDGE +#define bfin_read_FIO_BOTH() bfin_read_PORTFIO_BOTH() +#define bfin_write_FIO_BOTH(val) bfin_write_PORTFIO_BOTH(val) +#define FIO_BOTH PORTFIO_BOTH +#define bfin_read_FIO_INEN() bfin_read_PORTFIO_INEN() +#define bfin_write_FIO_INEN(val) bfin_write_PORTFIO_INEN(val) +#define FIO_INEN PORTFIO_INEN +#endif + +/* FIO USE PORT G*/ +#ifdef CONFIG_BF537_PORT_G +#define bfin_read_PORT_FER() bfin_read_PORTG_FER() +#define bfin_write_PORT_FER(val) bfin_write_PORTG_FER(val) +#define bfin_read_FIO_FLAG_D() bfin_read_PORTGIO() +#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTGIO(val) +#define bfin_read_FIO_FLAG_C() bfin_read_PORTGIO_CLEAR() +#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTGIO_CLEAR(val) +#define bfin_read_FIO_FLAG_S() bfin_read_PORTGIO_SET() +#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTGIO_SET(val) +#define bfin_read_FIO_FLAG_T() bfin_read_PORTGIO_TOGGLE() +#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTGIO_TOGGLE(val) +#define bfin_read_FIO_MASKA_D() bfin_read_PORTGIO_MASKA() +#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTGIO_MASKA(val) +#define bfin_read_FIO_MASKA_C() bfin_read_PORTGIO_MASKA_CLEAR() +#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTGIO_MASKA_CLEAR(val) +#define bfin_read_FIO_MASKA_S() bfin_read_PORTGIO_MASKA_SET() +#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTGIO_MASKA_SET(val) +#define bfin_read_FIO_MASKA_T() bfin_read_PORTGIO_MASKA_TOGGLE() +#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTGIO_MASKA_TOGGLE(val) +#define bfin_read_FIO_MASKB_D() bfin_read_PORTGIO_MASKB() +#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTGIO_MASKB(val) +#define bfin_read_FIO_MASKB_C() bfin_read_PORTGIO_MASKB_CLEAR() +#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTGIO_MASKB_CLEAR(val) +#define bfin_read_FIO_MASKB_S() bfin_read_PORTGIO_MASKB_SET() +#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTGIO_MASKB_SET(val) +#define bfin_read_FIO_MASKB_T() bfin_read_PORTGIO_MASKB_TOGGLE() +#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTGIO_MASKB_TOGGLE(val) +#define bfin_read_FIO_DIR() bfin_read_PORTGIO_DIR() +#define bfin_write_FIO_DIR(val) bfin_write_PORTGIO_DIR(val) +#define bfin_read_FIO_POLAR() bfin_read_PORTGIO_POLAR() +#define bfin_write_FIO_POLAR(val) bfin_write_PORTGIO_POLAR(val) +#define bfin_read_FIO_EDGE() bfin_read_PORTGIO_EDGE() +#define bfin_write_FIO_EDGE(val) bfin_write_PORTGIO_EDGE(val) +#define bfin_read_FIO_BOTH() bfin_read_PORTGIO_BOTH() +#define bfin_write_FIO_BOTH(val) bfin_write_PORTGIO_BOTH(val) +#define bfin_read_FIO_INEN() bfin_read_PORTGIO_INEN() +#define bfin_write_FIO_INEN(val) bfin_write_PORTGIO_INEN(val) + +#define bfin_read_FIO_FLAG_D() bfin_read_PORTGIO() +#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTGIO(val) +#define FIO_FLAG_D PORTGIO +#define bfin_read_FIO_FLAG_C() bfin_read_PORTGIO_CLEAR() +#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTGIO_CLEAR(val) +#define FIO_FLAG_C PORTGIO_CLEAR +#define bfin_read_FIO_FLAG_S() bfin_read_PORTGIO_SET() +#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTGIO_SET(val) +#define FIO_FLAG_S PORTGIO_SET +#define bfin_read_FIO_FLAG_T() bfin_read_PORTGIO_TOGGLE() +#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTGIO_TOGGLE(val) +#define FIO_FLAG_T PORTGIO_TOGGLE +#define bfin_read_FIO_MASKA_D() bfin_read_PORTGIO_MASKA() +#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTGIO_MASKA(val) +#define FIO_MASKA_D PORTGIO_MASKA +#define bfin_read_FIO_MASKA_C() bfin_read_PORTGIO_MASKA_CLEAR() +#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTGIO_MASKA_CLEAR(val) +#define FIO_MASKA_C PORTGIO_MASKA_CLEAR +#define bfin_read_FIO_MASKA_S() bfin_read_PORTGIO_MASKA_SET() +#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTGIO_MASKA_SET(val) +#define FIO_MASKA_S PORTGIO_MASKA_SET +#define bfin_read_FIO_MASKA_T() bfin_read_PORTGIO_MASKA_TOGGLE() +#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTGIO_MASKA_TOGGLE(val) +#define FIO_MASKA_T PORTGIO_MASKA_TOGGLE +#define bfin_read_FIO_MASKB_D() bfin_read_PORTGIO_MASKB() +#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTGIO_MASKB(val) +#define FIO_MASKB_D PORTGIO_MASKB +#define bfin_read_FIO_MASKB_C() bfin_read_PORTGIO_MASKB_CLEAR() +#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTGIO_MASKB_CLEAR(val) +#define FIO_MASKB_C PORTGIO_MASKB_CLEAR +#define bfin_read_FIO_MASKB_S() bfin_read_PORTGIO_MASKB_SET() +#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTGIO_MASKB_SET(val) +#define FIO_MASKB_S PORTGIO_MASKB_SET +#define bfin_read_FIO_MASKB_T() bfin_read_PORTGIO_MASKB_TOGGLE() +#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTGIO_MASKB_TOGGLE(val) +#define FIO_MASKB_T PORTGIO_MASKB_TOGGLE +#define bfin_read_FIO_DIR() bfin_read_PORTGIO_DIR() +#define bfin_write_FIO_DIR(val) bfin_write_PORTGIO_DIR(val) +#define FIO_DIR PORTGIO_DIR +#define bfin_read_FIO_POLAR() bfin_read_PORTGIO_POLAR() +#define bfin_write_FIO_POLAR(val) bfin_write_PORTGIO_POLAR(val) +#define FIO_POLAR PORTGIO_POLAR +#define bfin_read_FIO_EDGE() bfin_read_PORTGIO_EDGE() +#define bfin_write_FIO_EDGE(val) bfin_write_PORTGIO_EDGE(val) +#define FIO_EDGE PORTGIO_EDGE +#define bfin_read_FIO_BOTH() bfin_read_PORTGIO_BOTH() +#define bfin_write_FIO_BOTH(val) bfin_write_PORTGIO_BOTH(val) +#define FIO_BOTH PORTGIO_BOTH +#define bfin_read_FIO_INEN() bfin_read_PORTGIO_INEN() +#define bfin_write_FIO_INEN(val) bfin_write_PORTGIO_INEN(val) +#define FIO_INEN PORTGIO_INEN + +#endif + +/* FIO USE PORT H*/ +#ifdef CONFIG_BF537_PORT_H +#define bfin_read_PORT_FER() bfin_read_PORTH_FER() +#define bfin_write_PORT_FER(val) bfin_write_PORTH_FER(val) +#define bfin_read_FIO_FLAG_D() bfin_read_PORTHIO() +#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTHIO(val) +#define bfin_read_FIO_FLAG_C() bfin_read_PORTHIO_CLEAR() +#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTHIO_CLEAR(val) +#define bfin_read_FIO_FLAG_S() bfin_read_PORTHIO_SET() +#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTHIO_SET(val) +#define bfin_read_FIO_FLAG_T() bfin_read_PORTHIO_TOGGLE() +#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTHIO_TOGGLE(val) +#define bfin_read_FIO_MASKA_D() bfin_read_PORTHIO_MASKA() +#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTHIO_MASKA(val) +#define bfin_read_FIO_MASKA_C() bfin_read_PORTHIO_MASKA_CLEAR() +#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTHIO_MASKA_CLEAR(val) +#define bfin_read_FIO_MASKA_S() bfin_read_PORTHIO_MASKA_SET() +#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTHIO_MASKA_SET(val) +#define bfin_read_FIO_MASKA_T() bfin_read_PORTHIO_MASKA_TOGGLE() +#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTHIO_MASKA_TOGGLE(val) +#define bfin_read_FIO_MASKB_D() bfin_read_PORTHIO_MASKB() +#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTHIO_MASKB(val) +#define bfin_read_FIO_MASKB_C() bfin_read_PORTHIO_MASKB_CLEAR() +#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTHIO_MASKB_CLEAR(val) +#define bfin_read_FIO_MASKB_S() bfin_read_PORTHIO_MASKB_SET() +#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTHIO_MASKB_SET(val) +#define bfin_read_FIO_MASKB_T() bfin_read_PORTHIO_MASKB_TOGGLE() +#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTHIO_MASKB_TOGGLE(val) +#define bfin_read_FIO_DIR() bfin_read_PORTHIO_DIR() +#define bfin_write_FIO_DIR(val) bfin_write_PORTHIO_DIR(val) +#define bfin_read_FIO_POLAR() bfin_read_PORTHIO_POLAR() +#define bfin_write_FIO_POLAR(val) bfin_write_PORTHIO_POLAR(val) +#define bfin_read_FIO_EDGE() bfin_read_PORTHIO_EDGE() +#define bfin_write_FIO_EDGE(val) bfin_write_PORTHIO_EDGE(val) +#define bfin_read_FIO_BOTH() bfin_read_PORTHIO_BOTH() +#define bfin_write_FIO_BOTH(val) bfin_write_PORTHIO_BOTH(val) +#define bfin_read_FIO_INEN() bfin_read_PORTHIO_INEN() +#define bfin_write_FIO_INEN(val) bfin_write_PORTHIO_INEN(val) + +#define bfin_read_FIO_FLAG_D() bfin_read_PORTHIO() +#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTHIO(val) +#define FIO_FLAG_D PORTHIO +#define bfin_read_FIO_FLAG_C() bfin_read_PORTHIO_CLEAR() +#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTHIO_CLEAR(val) +#define FIO_FLAG_C PORTHIO_CLEAR +#define bfin_read_FIO_FLAG_S() bfin_read_PORTHIO_SET() +#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTHIO_SET(val) +#define FIO_FLAG_S PORTHIO_SET +#define bfin_read_FIO_FLAG_T() bfin_read_PORTHIO_TOGGLE() +#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTHIO_TOGGLE(val) +#define FIO_FLAG_T PORTHIO_TOGGLE +#define bfin_read_FIO_MASKA_D() bfin_read_PORTHIO_MASKA() +#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTHIO_MASKA(val) +#define FIO_MASKA_D PORTHIO_MASKA +#define bfin_read_FIO_MASKA_C() bfin_read_PORTHIO_MASKA_CLEAR() +#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTHIO_MASKA_CLEAR(val) +#define FIO_MASKA_C PORTHIO_MASKA_CLEAR +#define bfin_read_FIO_MASKA_S() bfin_read_PORTHIO_MASKA_SET() +#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTHIO_MASKA_SET(val) +#define FIO_MASKA_S PORTHIO_MASKA_SET +#define bfin_read_FIO_MASKA_T() bfin_read_PORTHIO_MASKA_TOGGLE() +#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTHIO_MASKA_TOGGLE(val) +#define FIO_MASKA_T PORTHIO_MASKA_TOGGLE +#define bfin_read_FIO_MASKB_D() bfin_read_PORTHIO_MASKB() +#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTHIO_MASKB(val) +#define FIO_MASKB_D PORTHIO_MASKB +#define bfin_read_FIO_MASKB_C() bfin_read_PORTHIO_MASKB_CLEAR() +#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTHIO_MASKB_CLEAR(val) +#define FIO_MASKB_C PORTHIO_MASKB_CLEAR +#define bfin_read_FIO_MASKB_S() bfin_read_PORTHIO_MASKB_SET() +#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTHIO_MASKB_SET(val) +#define FIO_MASKB_S PORTHIO_MASKB_SET +#define bfin_read_FIO_MASKB_T() bfin_read_PORTHIO_MASKB_TOGGLE() +#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTHIO_MASKB_TOGGLE(val) +#define FIO_MASKB_T PORTHIO_MASKB_TOGGLE +#define bfin_read_FIO_DIR() bfin_read_PORTHIO_DIR() +#define bfin_write_FIO_DIR(val) bfin_write_PORTHIO_DIR(val) +#define FIO_DIR PORTHIO_DIR +#define bfin_read_FIO_POLAR() bfin_read_PORTHIO_POLAR() +#define bfin_write_FIO_POLAR(val) bfin_write_PORTHIO_POLAR(val) +#define FIO_POLAR PORTHIO_POLAR +#define bfin_read_FIO_EDGE() bfin_read_PORTHIO_EDGE() +#define bfin_write_FIO_EDGE(val) bfin_write_PORTHIO_EDGE(val) +#define FIO_EDGE PORTHIO_EDGE +#define bfin_read_FIO_BOTH() bfin_read_PORTHIO_BOTH() +#define bfin_write_FIO_BOTH(val) bfin_write_PORTHIO_BOTH(val) +#define FIO_BOTH PORTHIO_BOTH +#define bfin_read_FIO_INEN() bfin_read_PORTHIO_INEN() +#define bfin_write_FIO_INEN(val) bfin_write_PORTHIO_INEN(val) +#define FIO_INEN PORTHIO_INEN + +#endif + +/* PLL_DIV Masks */ +#define CCLK_DIV1 CSEL_DIV1 /* CCLK = VCO / 1 */ +#define CCLK_DIV2 CSEL_DIV2 /* CCLK = VCO / 2 */ +#define CCLK_DIV4 CSEL_DIV4 /* CCLK = VCO / 4 */ +#define CCLK_DIV8 CSEL_DIV8 /* CCLK = VCO / 8 */ + +#endif diff --git a/include/asm-blackfin/mach-bf537/cdefBF534.h b/include/asm-blackfin/mach-bf537/cdefBF534.h new file mode 100644 index 000000000000..7b658c175f85 --- /dev/null +++ b/include/asm-blackfin/mach-bf537/cdefBF534.h @@ -0,0 +1,1823 @@ +/* + * File: include/asm-blackfin/mach-bf537/cdefbf534.h + * Based on: + * Author: + * + * Created: + * Description: system mmr register map + * + * Rev: + * + * Modified: + * + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _CDEF_BF534_H +#define _CDEF_BF534_H + +/* Include all Core registers and bit definitions */ +#include "defBF534.h" + +/* Include core specific register pointer definitions */ +#include + +#include + +/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */ +#define bfin_read_PLL_CTL() bfin_read16(PLL_CTL) +#define bfin_write_PLL_CTL(val) bfin_write16(PLL_CTL,val) +#define bfin_read_PLL_DIV() bfin_read16(PLL_DIV) +#define bfin_write_PLL_DIV(val) bfin_write16(PLL_DIV,val) +#define bfin_read_VR_CTL() bfin_read16(VR_CTL) +/* Writing to VR_CTL initiates a PLL relock sequence. */ +static __inline__ void bfin_write_VR_CTL(unsigned int val) +{ + unsigned long flags, iwr; + + bfin_write16(VR_CTL, val); + __builtin_bfin_ssync(); + /* Enable the PLL Wakeup bit in SIC IWR */ + iwr = bfin_read32(SIC_IWR); + /* Only allow PPL Wakeup) */ + bfin_write32(SIC_IWR, IWR_ENABLE(0)); + local_irq_save(flags); + asm("IDLE;"); + local_irq_restore(flags); + bfin_write32(SIC_IWR, iwr); +} +#define bfin_read_PLL_STAT() bfin_read16(PLL_STAT) +#define bfin_write_PLL_STAT(val) bfin_write16(PLL_STAT,val) +#define bfin_read_PLL_LOCKCNT() bfin_read16(PLL_LOCKCNT) +#define bfin_write_PLL_LOCKCNT(val) bfin_write16(PLL_LOCKCNT,val) +#define bfin_read_CHIPID() bfin_read32(CHIPID) + +/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */ +#define bfin_read_SWRST() bfin_read16(SWRST) +#define bfin_write_SWRST(val) bfin_write16(SWRST,val) +#define bfin_read_SYSCR() bfin_read16(SYSCR) +#define bfin_write_SYSCR(val) bfin_write16(SYSCR,val) +#define pSIC_RVECT ((void * volatile *)SIC_RVECT) +#define bfin_read_SIC_RVECT() bfin_read32(SIC_RVECT) +#define bfin_write_SIC_RVECT(val) bfin_write32(SIC_RVECT,val) +#define bfin_read_SIC_IMASK() bfin_read32(SIC_IMASK) +#define bfin_write_SIC_IMASK(val) bfin_write32(SIC_IMASK,val) +#define bfin_read_SIC_IAR0() bfin_read32(SIC_IAR0) +#define bfin_write_SIC_IAR0(val) bfin_write32(SIC_IAR0,val) +#define bfin_read_SIC_IAR1() bfin_read32(SIC_IAR1) +#define bfin_write_SIC_IAR1(val) bfin_write32(SIC_IAR1,val) +#define bfin_read_SIC_IAR2() bfin_read32(SIC_IAR2) +#define bfin_write_SIC_IAR2(val) bfin_write32(SIC_IAR2,val) +#define bfin_read_SIC_IAR3() bfin_read32(SIC_IAR3) +#define bfin_write_SIC_IAR3(val) bfin_write32(SIC_IAR3,val) +#define bfin_read_SIC_ISR() bfin_read32(SIC_ISR) +#define bfin_write_SIC_ISR(val) bfin_write32(SIC_ISR,val) +#define bfin_read_SIC_IWR() bfin_read32(SIC_IWR) +#define bfin_write_SIC_IWR(val) bfin_write32(SIC_IWR,val) + +/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */ +#define bfin_read_WDOG_CTL() bfin_read16(WDOG_CTL) +#define bfin_write_WDOG_CTL(val) bfin_write16(WDOG_CTL,val) +#define bfin_read_WDOG_CNT() bfin_read32(WDOG_CNT) +#define bfin_write_WDOG_CNT(val) bfin_write32(WDOG_CNT,val) +#define bfin_read_WDOG_STAT() bfin_read32(WDOG_STAT) +#define bfin_write_WDOG_STAT(val) bfin_write32(WDOG_STAT,val) + +/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */ +#define bfin_read_RTC_STAT() bfin_read32(RTC_STAT) +#define bfin_write_RTC_STAT(val) bfin_write32(RTC_STAT,val) +#define bfin_read_RTC_ICTL() bfin_read16(RTC_ICTL) +#define bfin_write_RTC_ICTL(val) bfin_write16(RTC_ICTL,val) +#define bfin_read_RTC_ISTAT() bfin_read16(RTC_ISTAT) +#define bfin_write_RTC_ISTAT(val) bfin_write16(RTC_ISTAT,val) +#define bfin_read_RTC_SWCNT() bfin_read16(RTC_SWCNT) +#define bfin_write_RTC_SWCNT(val) bfin_write16(RTC_SWCNT,val) +#define bfin_read_RTC_ALARM() bfin_read32(RTC_ALARM) +#define bfin_write_RTC_ALARM(val) bfin_write32(RTC_ALARM,val) +#define bfin_read_RTC_FAST() bfin_read16(RTC_FAST) +#define bfin_write_RTC_FAST(val) bfin_write16(RTC_FAST,val) +#define bfin_read_RTC_PREN() bfin_read16(RTC_PREN) +#define bfin_write_RTC_PREN(val) bfin_write16(RTC_PREN,val) + +/* UART0 Controller (0xFFC00400 - 0xFFC004FF) */ +#define bfin_read_UART0_THR() bfin_read16(UART0_THR) +#define bfin_write_UART0_THR(val) bfin_write16(UART0_THR,val) +#define bfin_read_UART0_RBR() bfin_read16(UART0_RBR) +#define bfin_write_UART0_RBR(val) bfin_write16(UART0_RBR,val) +#define bfin_read_UART0_DLL() bfin_read16(UART0_DLL) +#define bfin_write_UART0_DLL(val) bfin_write16(UART0_DLL,val) +#define bfin_read_UART0_IER() bfin_read16(UART0_IER) +#define bfin_write_UART0_IER(val) bfin_write16(UART0_IER,val) +#define bfin_read_UART0_DLH() bfin_read16(UART0_DLH) +#define bfin_write_UART0_DLH(val) bfin_write16(UART0_DLH,val) +#define bfin_read_UART0_IIR() bfin_read16(UART0_IIR) +#define bfin_write_UART0_IIR(val) bfin_write16(UART0_IIR,val) +#define bfin_read_UART0_LCR() bfin_read16(UART0_LCR) +#define bfin_write_UART0_LCR(val) bfin_write16(UART0_LCR,val) +#define bfin_read_UART0_MCR() bfin_read16(UART0_MCR) +#define bfin_write_UART0_MCR(val) bfin_write16(UART0_MCR,val) +#define bfin_read_UART0_LSR() bfin_read16(UART0_LSR) +#define bfin_write_UART0_LSR(val) bfin_write16(UART0_LSR,val) +#define bfin_read_UART0_MSR() bfin_read16(UART0_MSR) +#define bfin_write_UART0_MSR(val) bfin_write16(UART0_MSR,val) +#define bfin_read_UART0_SCR() bfin_read16(UART0_SCR) +#define bfin_write_UART0_SCR(val) bfin_write16(UART0_SCR,val) +#define bfin_read_UART0_GCTL() bfin_read16(UART0_GCTL) +#define bfin_write_UART0_GCTL(val) bfin_write16(UART0_GCTL,val) + +/* SPI Controller (0xFFC00500 - 0xFFC005FF) */ +#define bfin_read_SPI_CTL() bfin_read16(SPI_CTL) +#define bfin_write_SPI_CTL(val) bfin_write16(SPI_CTL,val) +#define bfin_read_SPI_FLG() bfin_read16(SPI_FLG) +#define bfin_write_SPI_FLG(val) bfin_write16(SPI_FLG,val) +#define bfin_read_SPI_STAT() bfin_read16(SPI_STAT) +#define bfin_write_SPI_STAT(val) bfin_write16(SPI_STAT,val) +#define bfin_read_SPI_TDBR() bfin_read16(SPI_TDBR) +#define bfin_write_SPI_TDBR(val) bfin_write16(SPI_TDBR,val) +#define bfin_read_SPI_RDBR() bfin_read16(SPI_RDBR) +#define bfin_write_SPI_RDBR(val) bfin_write16(SPI_RDBR,val) +#define bfin_read_SPI_BAUD() bfin_read16(SPI_BAUD) +#define bfin_write_SPI_BAUD(val) bfin_write16(SPI_BAUD,val) +#define bfin_read_SPI_SHADOW() bfin_read16(SPI_SHADOW) +#define bfin_write_SPI_SHADOW(val) bfin_write16(SPI_SHADOW,val) + +/* TIMER0-7 Registers (0xFFC00600 - 0xFFC006FF) */ +#define bfin_read_TIMER0_CONFIG() bfin_read16(TIMER0_CONFIG) +#define bfin_write_TIMER0_CONFIG(val) bfin_write16(TIMER0_CONFIG,val) +#define bfin_read_TIMER0_COUNTER() bfin_read32(TIMER0_COUNTER) +#define bfin_write_TIMER0_COUNTER(val) bfin_write32(TIMER0_COUNTER,val) +#define bfin_read_TIMER0_PERIOD() bfin_read32(TIMER0_PERIOD) +#define bfin_write_TIMER0_PERIOD(val) bfin_write32(TIMER0_PERIOD,val) +#define bfin_read_TIMER0_WIDTH() bfin_read32(TIMER0_WIDTH) +#define bfin_write_TIMER0_WIDTH(val) bfin_write32(TIMER0_WIDTH,val) + +#define bfin_read_TIMER1_CONFIG() bfin_read16(TIMER1_CONFIG) +#define bfin_write_TIMER1_CONFIG(val) bfin_write16(TIMER1_CONFIG,val) +#define bfin_read_TIMER1_COUNTER() bfin_read32(TIMER1_COUNTER) +#define bfin_write_TIMER1_COUNTER(val) bfin_write32(TIMER1_COUNTER,val) +#define bfin_read_TIMER1_PERIOD() bfin_read32(TIMER1_PERIOD) +#define bfin_write_TIMER1_PERIOD(val) bfin_write32(TIMER1_PERIOD,val) +#define bfin_read_TIMER1_WIDTH() bfin_read32(TIMER1_WIDTH) +#define bfin_write_TIMER1_WIDTH(val) bfin_write32(TIMER1_WIDTH,val) + +#define bfin_read_TIMER2_CONFIG() bfin_read16(TIMER2_CONFIG) +#define bfin_write_TIMER2_CONFIG(val) bfin_write16(TIMER2_CONFIG,val) +#define bfin_read_TIMER2_COUNTER() bfin_read32(TIMER2_COUNTER) +#define bfin_write_TIMER2_COUNTER(val) bfin_write32(TIMER2_COUNTER,val) +#define bfin_read_TIMER2_PERIOD() bfin_read32(TIMER2_PERIOD) +#define bfin_write_TIMER2_PERIOD(val) bfin_write32(TIMER2_PERIOD,val) +#define bfin_read_TIMER2_WIDTH() bfin_read32(TIMER2_WIDTH) +#define bfin_write_TIMER2_WIDTH(val) bfin_write32(TIMER2_WIDTH,val) + +#define bfin_read_TIMER3_CONFIG() bfin_read16(TIMER3_CONFIG) +#define bfin_write_TIMER3_CONFIG(val) bfin_write16(TIMER3_CONFIG,val) +#define bfin_read_TIMER3_COUNTER() bfin_read32(TIMER3_COUNTER) +#define bfin_write_TIMER3_COUNTER(val) bfin_write32(TIMER3_COUNTER,val) +#define bfin_read_TIMER3_PERIOD() bfin_read32(TIMER3_PERIOD) +#define bfin_write_TIMER3_PERIOD(val) bfin_write32(TIMER3_PERIOD,val) +#define bfin_read_TIMER3_WIDTH() bfin_read32(TIMER3_WIDTH) +#define bfin_write_TIMER3_WIDTH(val) bfin_write32(TIMER3_WIDTH,val) + +#define bfin_read_TIMER4_CONFIG() bfin_read16(TIMER4_CONFIG) +#define bfin_write_TIMER4_CONFIG(val) bfin_write16(TIMER4_CONFIG,val) +#define bfin_read_TIMER4_COUNTER() bfin_read32(TIMER4_COUNTER) +#define bfin_write_TIMER4_COUNTER(val) bfin_write32(TIMER4_COUNTER,val) +#define bfin_read_TIMER4_PERIOD() bfin_read32(TIMER4_PERIOD) +#define bfin_write_TIMER4_PERIOD(val) bfin_write32(TIMER4_PERIOD,val) +#define bfin_read_TIMER4_WIDTH() bfin_read32(TIMER4_WIDTH) +#define bfin_write_TIMER4_WIDTH(val) bfin_write32(TIMER4_WIDTH,val) + +#define bfin_read_TIMER5_CONFIG() bfin_read16(TIMER5_CONFIG) +#define bfin_write_TIMER5_CONFIG(val) bfin_write16(TIMER5_CONFIG,val) +#define bfin_read_TIMER5_COUNTER() bfin_read32(TIMER5_COUNTER) +#define bfin_write_TIMER5_COUNTER(val) bfin_write32(TIMER5_COUNTER,val) +#define bfin_read_TIMER5_PERIOD() bfin_read32(TIMER5_PERIOD) +#define bfin_write_TIMER5_PERIOD(val) bfin_write32(TIMER5_PERIOD,val) +#define bfin_read_TIMER5_WIDTH() bfin_read32(TIMER5_WIDTH) +#define bfin_write_TIMER5_WIDTH(val) bfin_write32(TIMER5_WIDTH,val) + +#define bfin_read_TIMER6_CONFIG() bfin_read16(TIMER6_CONFIG) +#define bfin_write_TIMER6_CONFIG(val) bfin_write16(TIMER6_CONFIG,val) +#define bfin_read_TIMER6_COUNTER() bfin_read32(TIMER6_COUNTER) +#define bfin_write_TIMER6_COUNTER(val) bfin_write32(TIMER6_COUNTER,val) +#define bfin_read_TIMER6_PERIOD() bfin_read32(TIMER6_PERIOD) +#define bfin_write_TIMER6_PERIOD(val) bfin_write32(TIMER6_PERIOD,val) +#define bfin_read_TIMER6_WIDTH() bfin_read32(TIMER6_WIDTH) +#define bfin_write_TIMER6_WIDTH(val) bfin_write32(TIMER6_WIDTH,val) + +#define bfin_read_TIMER7_CONFIG() bfin_read16(TIMER7_CONFIG) +#define bfin_write_TIMER7_CONFIG(val) bfin_write16(TIMER7_CONFIG,val) +#define bfin_read_TIMER7_COUNTER() bfin_read32(TIMER7_COUNTER) +#define bfin_write_TIMER7_COUNTER(val) bfin_write32(TIMER7_COUNTER,val) +#define bfin_read_TIMER7_PERIOD() bfin_read32(TIMER7_PERIOD) +#define bfin_write_TIMER7_PERIOD(val) bfin_write32(TIMER7_PERIOD,val) +#define bfin_read_TIMER7_WIDTH() bfin_read32(TIMER7_WIDTH) +#define bfin_write_TIMER7_WIDTH(val) bfin_write32(TIMER7_WIDTH,val) + +#define bfin_read_TIMER_ENABLE() bfin_read16(TIMER_ENABLE) +#define bfin_write_TIMER_ENABLE(val) bfin_write16(TIMER_ENABLE,val) +#define bfin_read_TIMER_DISABLE() bfin_read16(TIMER_DISABLE) +#define bfin_write_TIMER_DISABLE(val) bfin_write16(TIMER_DISABLE,val) +#define bfin_read_TIMER_STATUS() bfin_read32(TIMER_STATUS) +#define bfin_write_TIMER_STATUS(val) bfin_write32(TIMER_STATUS,val) + +/* General Purpose I/O Port F (0xFFC00700 - 0xFFC007FF) */ +#define bfin_read_PORTFIO() bfin_read16(PORTFIO) +#define bfin_write_PORTFIO(val) bfin_write16(PORTFIO,val) +#define bfin_read_PORTFIO_CLEAR() bfin_read16(PORTFIO_CLEAR) +#define bfin_write_PORTFIO_CLEAR(val) bfin_write16(PORTFIO_CLEAR,val) +#define bfin_read_PORTFIO_SET() bfin_read16(PORTFIO_SET) +#define bfin_write_PORTFIO_SET(val) bfin_write16(PORTFIO_SET,val) +#define bfin_read_PORTFIO_TOGGLE() bfin_read16(PORTFIO_TOGGLE) +#define bfin_write_PORTFIO_TOGGLE(val) bfin_write16(PORTFIO_TOGGLE,val) +#define bfin_read_PORTFIO_MASKA() bfin_read16(PORTFIO_MASKA) +#define bfin_write_PORTFIO_MASKA(val) bfin_write16(PORTFIO_MASKA,val) +#define bfin_read_PORTFIO_MASKA_CLEAR() bfin_read16(PORTFIO_MASKA_CLEAR) +#define bfin_write_PORTFIO_MASKA_CLEAR(val) bfin_write16(PORTFIO_MASKA_CLEAR,val) +#define bfin_read_PORTFIO_MASKA_SET() bfin_read16(PORTFIO_MASKA_SET) +#define bfin_write_PORTFIO_MASKA_SET(val) bfin_write16(PORTFIO_MASKA_SET,val) +#define bfin_read_PORTFIO_MASKA_TOGGLE() bfin_read16(PORTFIO_MASKA_TOGGLE) +#define bfin_write_PORTFIO_MASKA_TOGGLE(val) bfin_write16(PORTFIO_MASKA_TOGGLE,val) +#define bfin_read_PORTFIO_MASKB() bfin_read16(PORTFIO_MASKB) +#define bfin_write_PORTFIO_MASKB(val) bfin_write16(PORTFIO_MASKB,val) +#define bfin_read_PORTFIO_MASKB_CLEAR() bfin_read16(PORTFIO_MASKB_CLEAR) +#define bfin_write_PORTFIO_MASKB_CLEAR(val) bfin_write16(PORTFIO_MASKB_CLEAR,val) +#define bfin_read_PORTFIO_MASKB_SET() bfin_read16(PORTFIO_MASKB_SET) +#define bfin_write_PORTFIO_MASKB_SET(val) bfin_write16(PORTFIO_MASKB_SET,val) +#define bfin_read_PORTFIO_MASKB_TOGGLE() bfin_read16(PORTFIO_MASKB_TOGGLE) +#define bfin_write_PORTFIO_MASKB_TOGGLE(val) bfin_write16(PORTFIO_MASKB_TOGGLE,val) +#define bfin_read_PORTFIO_DIR() bfin_read16(PORTFIO_DIR) +#define bfin_write_PORTFIO_DIR(val) bfin_write16(PORTFIO_DIR,val) +#define bfin_read_PORTFIO_POLAR() bfin_read16(PORTFIO_POLAR) +#define bfin_write_PORTFIO_POLAR(val) bfin_write16(PORTFIO_POLAR,val) +#define bfin_read_PORTFIO_EDGE() bfin_read16(PORTFIO_EDGE) +#define bfin_write_PORTFIO_EDGE(val) bfin_write16(PORTFIO_EDGE,val) +#define bfin_read_PORTFIO_BOTH() bfin_read16(PORTFIO_BOTH) +#define bfin_write_PORTFIO_BOTH(val) bfin_write16(PORTFIO_BOTH,val) +#define bfin_read_PORTFIO_INEN() bfin_read16(PORTFIO_INEN) +#define bfin_write_PORTFIO_INEN(val) bfin_write16(PORTFIO_INEN,val) + +/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */ +#define bfin_read_SPORT0_TCR1() bfin_read16(SPORT0_TCR1) +#define bfin_write_SPORT0_TCR1(val) bfin_write16(SPORT0_TCR1,val) +#define bfin_read_SPORT0_TCR2() bfin_read16(SPORT0_TCR2) +#define bfin_write_SPORT0_TCR2(val) bfin_write16(SPORT0_TCR2,val) +#define bfin_read_SPORT0_TCLKDIV() bfin_read16(SPORT0_TCLKDIV) +#define bfin_write_SPORT0_TCLKDIV(val) bfin_write16(SPORT0_TCLKDIV,val) +#define bfin_read_SPORT0_TFSDIV() bfin_read16(SPORT0_TFSDIV) +#define bfin_write_SPORT0_TFSDIV(val) bfin_write16(SPORT0_TFSDIV,val) +#define bfin_read_SPORT0_TX() bfin_read32(SPORT0_TX) +#define bfin_write_SPORT0_TX(val) bfin_write32(SPORT0_TX,val) +#define bfin_read_SPORT0_RX() bfin_read32(SPORT0_RX) +#define bfin_write_SPORT0_RX(val) bfin_write32(SPORT0_RX,val) +#define bfin_read_SPORT0_TX32() bfin_read32(SPORT0_TX) +#define bfin_write_SPORT0_TX32(val) bfin_write32(SPORT0_TX,val) +#define bfin_read_SPORT0_RX32() bfin_read32(SPORT0_RX) +#define bfin_write_SPORT0_RX32(val) bfin_write32(SPORT0_RX,val) +#define bfin_read_SPORT0_TX16() bfin_read16(SPORT0_TX) +#define bfin_write_SPORT0_TX16(val) bfin_write16(SPORT0_TX,val) +#define bfin_read_SPORT0_RX16() bfin_read16(SPORT0_RX) +#define bfin_write_SPORT0_RX16(val) bfin_write16(SPORT0_RX,val) +#define bfin_read_SPORT0_RCR1() bfin_read16(SPORT0_RCR1) +#define bfin_write_SPORT0_RCR1(val) bfin_write16(SPORT0_RCR1,val) +#define bfin_read_SPORT0_RCR2() bfin_read16(SPORT0_RCR2) +#define bfin_write_SPORT0_RCR2(val) bfin_write16(SPORT0_RCR2,val) +#define bfin_read_SPORT0_RCLKDIV() bfin_read16(SPORT0_RCLKDIV) +#define bfin_write_SPORT0_RCLKDIV(val) bfin_write16(SPORT0_RCLKDIV,val) +#define bfin_read_SPORT0_RFSDIV() bfin_read16(SPORT0_RFSDIV) +#define bfin_write_SPORT0_RFSDIV(val) bfin_write16(SPORT0_RFSDIV,val) +#define bfin_read_SPORT0_STAT() bfin_read16(SPORT0_STAT) +#define bfin_write_SPORT0_STAT(val) bfin_write16(SPORT0_STAT,val) +#define bfin_read_SPORT0_CHNL() bfin_read16(SPORT0_CHNL) +#define bfin_write_SPORT0_CHNL(val) bfin_write16(SPORT0_CHNL,val) +#define bfin_read_SPORT0_MCMC1() bfin_read16(SPORT0_MCMC1) +#define bfin_write_SPORT0_MCMC1(val) bfin_write16(SPORT0_MCMC1,val) +#define bfin_read_SPORT0_MCMC2() bfin_read16(SPORT0_MCMC2) +#define bfin_write_SPORT0_MCMC2(val) bfin_write16(SPORT0_MCMC2,val) +#define bfin_read_SPORT0_MTCS0() bfin_read32(SPORT0_MTCS0) +#define bfin_write_SPORT0_MTCS0(val) bfin_write32(SPORT0_MTCS0,val) +#define bfin_read_SPORT0_MTCS1() bfin_read32(SPORT0_MTCS1) +#define bfin_write_SPORT0_MTCS1(val) bfin_write32(SPORT0_MTCS1,val) +#define bfin_read_SPORT0_MTCS2() bfin_read32(SPORT0_MTCS2) +#define bfin_write_SPORT0_MTCS2(val) bfin_write32(SPORT0_MTCS2,val) +#define bfin_read_SPORT0_MTCS3() bfin_read32(SPORT0_MTCS3) +#define bfin_write_SPORT0_MTCS3(val) bfin_write32(SPORT0_MTCS3,val) +#define bfin_read_SPORT0_MRCS0() bfin_read32(SPORT0_MRCS0) +#define bfin_write_SPORT0_MRCS0(val) bfin_write32(SPORT0_MRCS0,val) +#define bfin_read_SPORT0_MRCS1() bfin_read32(SPORT0_MRCS1) +#define bfin_write_SPORT0_MRCS1(val) bfin_write32(SPORT0_MRCS1,val) +#define bfin_read_SPORT0_MRCS2() bfin_read32(SPORT0_MRCS2) +#define bfin_write_SPORT0_MRCS2(val) bfin_write32(SPORT0_MRCS2,val) +#define bfin_read_SPORT0_MRCS3() bfin_read32(SPORT0_MRCS3) +#define bfin_write_SPORT0_MRCS3(val) bfin_write32(SPORT0_MRCS3,val) + +/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */ +#define bfin_read_SPORT1_TCR1() bfin_read16(SPORT1_TCR1) +#define bfin_write_SPORT1_TCR1(val) bfin_write16(SPORT1_TCR1,val) +#define bfin_read_SPORT1_TCR2() bfin_read16(SPORT1_TCR2) +#define bfin_write_SPORT1_TCR2(val) bfin_write16(SPORT1_TCR2,val) +#define bfin_read_SPORT1_TCLKDIV() bfin_read16(SPORT1_TCLKDIV) +#define bfin_write_SPORT1_TCLKDIV(val) bfin_write16(SPORT1_TCLKDIV,val) +#define bfin_read_SPORT1_TFSDIV() bfin_read16(SPORT1_TFSDIV) +#define bfin_write_SPORT1_TFSDIV(val) bfin_write16(SPORT1_TFSDIV,val) +#define bfin_read_SPORT1_TX() bfin_read32(SPORT1_TX) +#define bfin_write_SPORT1_TX(val) bfin_write32(SPORT1_TX,val) +#define bfin_read_SPORT1_RX() bfin_read32(SPORT1_RX) +#define bfin_write_SPORT1_RX(val) bfin_write32(SPORT1_RX,val) +#define bfin_read_SPORT1_TX32() bfin_read32(SPORT1_TX) +#define bfin_write_SPORT1_TX32(val) bfin_write32(SPORT1_TX,val) +#define bfin_read_SPORT1_RX32() bfin_read32(SPORT1_RX) +#define bfin_write_SPORT1_RX32(val) bfin_write32(SPORT1_RX,val) +#define bfin_read_SPORT1_TX16() bfin_read16(SPORT1_TX) +#define bfin_write_SPORT1_TX16(val) bfin_write16(SPORT1_TX,val) +#define bfin_read_SPORT1_RX16() bfin_read16(SPORT1_RX) +#define bfin_write_SPORT1_RX16(val) bfin_write16(SPORT1_RX,val) +#define bfin_read_SPORT1_RCR1() bfin_read16(SPORT1_RCR1) +#define bfin_write_SPORT1_RCR1(val) bfin_write16(SPORT1_RCR1,val) +#define bfin_read_SPORT1_RCR2() bfin_read16(SPORT1_RCR2) +#define bfin_write_SPORT1_RCR2(val) bfin_write16(SPORT1_RCR2,val) +#define bfin_read_SPORT1_RCLKDIV() bfin_read16(SPORT1_RCLKDIV) +#define bfin_write_SPORT1_RCLKDIV(val) bfin_write16(SPORT1_RCLKDIV,val) +#define bfin_read_SPORT1_RFSDIV() bfin_read16(SPORT1_RFSDIV) +#define bfin_write_SPORT1_RFSDIV(val) bfin_write16(SPORT1_RFSDIV,val) +#define bfin_read_SPORT1_STAT() bfin_read16(SPORT1_STAT) +#define bfin_write_SPORT1_STAT(val) bfin_write16(SPORT1_STAT,val) +#define bfin_read_SPORT1_CHNL() bfin_read16(SPORT1_CHNL) +#define bfin_write_SPORT1_CHNL(val) bfin_write16(SPORT1_CHNL,val) +#define bfin_read_SPORT1_MCMC1() bfin_read16(SPORT1_MCMC1) +#define bfin_write_SPORT1_MCMC1(val) bfin_write16(SPORT1_MCMC1,val) +#define bfin_read_SPORT1_MCMC2() bfin_read16(SPORT1_MCMC2) +#define bfin_write_SPORT1_MCMC2(val) bfin_write16(SPORT1_MCMC2,val) +#define bfin_read_SPORT1_MTCS0() bfin_read32(SPORT1_MTCS0) +#define bfin_write_SPORT1_MTCS0(val) bfin_write32(SPORT1_MTCS0,val) +#define bfin_read_SPORT1_MTCS1() bfin_read32(SPORT1_MTCS1) +#define bfin_write_SPORT1_MTCS1(val) bfin_write32(SPORT1_MTCS1,val) +#define bfin_read_SPORT1_MTCS2() bfin_read32(SPORT1_MTCS2) +#define bfin_write_SPORT1_MTCS2(val) bfin_write32(SPORT1_MTCS2,val) +#define bfin_read_SPORT1_MTCS3() bfin_read32(SPORT1_MTCS3) +#define bfin_write_SPORT1_MTCS3(val) bfin_write32(SPORT1_MTCS3,val) +#define bfin_read_SPORT1_MRCS0() bfin_read32(SPORT1_MRCS0) +#define bfin_write_SPORT1_MRCS0(val) bfin_write32(SPORT1_MRCS0,val) +#define bfin_read_SPORT1_MRCS1() bfin_read32(SPORT1_MRCS1) +#define bfin_write_SPORT1_MRCS1(val) bfin_write32(SPORT1_MRCS1,val) +#define bfin_read_SPORT1_MRCS2() bfin_read32(SPORT1_MRCS2) +#define bfin_write_SPORT1_MRCS2(val) bfin_write32(SPORT1_MRCS2,val) +#define bfin_read_SPORT1_MRCS3() bfin_read32(SPORT1_MRCS3) +#define bfin_write_SPORT1_MRCS3(val) bfin_write32(SPORT1_MRCS3,val) + +/* External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */ +#define bfin_read_EBIU_AMGCTL() bfin_read16(EBIU_AMGCTL) +#define bfin_write_EBIU_AMGCTL(val) bfin_write16(EBIU_AMGCTL,val) +#define bfin_read_EBIU_AMBCTL0() bfin_read32(EBIU_AMBCTL0) +#define bfin_write_EBIU_AMBCTL0(val) bfin_write32(EBIU_AMBCTL0,val) +#define bfin_read_EBIU_AMBCTL1() bfin_read32(EBIU_AMBCTL1) +#define bfin_write_EBIU_AMBCTL1(val) bfin_write32(EBIU_AMBCTL1,val) +#define bfin_read_EBIU_SDGCTL() bfin_read32(EBIU_SDGCTL) +#define bfin_write_EBIU_SDGCTL(val) bfin_write32(EBIU_SDGCTL,val) +#define bfin_read_EBIU_SDBCTL() bfin_read16(EBIU_SDBCTL) +#define bfin_write_EBIU_SDBCTL(val) bfin_write16(EBIU_SDBCTL,val) +#define bfin_read_EBIU_SDRRC() bfin_read16(EBIU_SDRRC) +#define bfin_write_EBIU_SDRRC(val) bfin_write16(EBIU_SDRRC,val) +#define bfin_read_EBIU_SDSTAT() bfin_read16(EBIU_SDSTAT) +#define bfin_write_EBIU_SDSTAT(val) bfin_write16(EBIU_SDSTAT,val) + +/* DMA Traffic Control Registers */ +#define pDMA_TCPER ((volatile unsigned short *)DMA_TCPER) +#define bfin_read_DMA_TCPER() bfin_read16(DMA_TCPER) +#define bfin_write_DMA_TCPER(val) bfin_write16(DMA_TCPER,val) +#define pDMA_TCCNT ((volatile unsigned short *)DMA_TCCNT) +#define bfin_read_DMA_TCCNT() bfin_read16(DMA_TCCNT) +#define bfin_write_DMA_TCCNT(val) bfin_write16(DMA_TCCNT,val) + +/* DMA Controller */ +#define bfin_read_DMA0_CONFIG() bfin_read16(DMA0_CONFIG) +#define bfin_write_DMA0_CONFIG(val) bfin_write16(DMA0_CONFIG,val) +#define bfin_read_DMA0_NEXT_DESC_PTR() bfin_read32(DMA0_NEXT_DESC_PTR) +#define bfin_write_DMA0_NEXT_DESC_PTR(val) bfin_write32(DMA0_NEXT_DESC_PTR,val) +#define bfin_read_DMA0_START_ADDR() bfin_read32(DMA0_START_ADDR) +#define bfin_write_DMA0_START_ADDR(val) bfin_write32(DMA0_START_ADDR,val) +#define bfin_read_DMA0_X_COUNT() bfin_read16(DMA0_X_COUNT) +#define bfin_write_DMA0_X_COUNT(val) bfin_write16(DMA0_X_COUNT,val) +#define bfin_read_DMA0_Y_COUNT() bfin_read16(DMA0_Y_COUNT) +#define bfin_write_DMA0_Y_COUNT(val) bfin_write16(DMA0_Y_COUNT,val) +#define bfin_read_DMA0_X_MODIFY() bfin_read16(DMA0_X_MODIFY) +#define bfin_write_DMA0_X_MODIFY(val) bfin_write16(DMA0_X_MODIFY,val) +#define bfin_read_DMA0_Y_MODIFY() bfin_read16(DMA0_Y_MODIFY) +#define bfin_write_DMA0_Y_MODIFY(val) bfin_write16(DMA0_Y_MODIFY,val) +#define bfin_read_DMA0_CURR_DESC_PTR() bfin_read32(DMA0_CURR_DESC_PTR) +#define bfin_write_DMA0_CURR_DESC_PTR(val) bfin_write32(DMA0_CURR_DESC_PTR,val) +#define bfin_read_DMA0_CURR_ADDR() bfin_read32(DMA0_CURR_ADDR) +#define bfin_write_DMA0_CURR_ADDR(val) bfin_write32(DMA0_CURR_ADDR,val) +#define bfin_read_DMA0_CURR_X_COUNT() bfin_read16(DMA0_CURR_X_COUNT) +#define bfin_write_DMA0_CURR_X_COUNT(val) bfin_write16(DMA0_CURR_X_COUNT,val) +#define bfin_read_DMA0_CURR_Y_COUNT() bfin_read16(DMA0_CURR_Y_COUNT) +#define bfin_write_DMA0_CURR_Y_COUNT(val) bfin_write16(DMA0_CURR_Y_COUNT,val) +#define bfin_read_DMA0_IRQ_STATUS() bfin_read16(DMA0_IRQ_STATUS) +#define bfin_write_DMA0_IRQ_STATUS(val) bfin_write16(DMA0_IRQ_STATUS,val) +#define bfin_read_DMA0_PERIPHERAL_MAP() bfin_read16(DMA0_PERIPHERAL_MAP) +#define bfin_write_DMA0_PERIPHERAL_MAP(val) bfin_write16(DMA0_PERIPHERAL_MAP,val) + +#define bfin_read_DMA1_CONFIG() bfin_read16(DMA1_CONFIG) +#define bfin_write_DMA1_CONFIG(val) bfin_write16(DMA1_CONFIG,val) +#define bfin_read_DMA1_NEXT_DESC_PTR() bfin_read32(DMA1_NEXT_DESC_PTR) +#define bfin_write_DMA1_NEXT_DESC_PTR(val) bfin_write32(DMA1_NEXT_DESC_PTR,val) +#define bfin_read_DMA1_START_ADDR() bfin_read32(DMA1_START_ADDR) +#define bfin_write_DMA1_START_ADDR(val) bfin_write32(DMA1_START_ADDR,val) +#define bfin_read_DMA1_X_COUNT() bfin_read16(DMA1_X_COUNT) +#define bfin_write_DMA1_X_COUNT(val) bfin_write16(DMA1_X_COUNT,val) +#define bfin_read_DMA1_Y_COUNT() bfin_read16(DMA1_Y_COUNT) +#define bfin_write_DMA1_Y_COUNT(val) bfin_write16(DMA1_Y_COUNT,val) +#define bfin_read_DMA1_X_MODIFY() bfin_read16(DMA1_X_MODIFY) +#define bfin_write_DMA1_X_MODIFY(val) bfin_write16(DMA1_X_MODIFY,val) +#define bfin_read_DMA1_Y_MODIFY() bfin_read16(DMA1_Y_MODIFY) +#define bfin_write_DMA1_Y_MODIFY(val) bfin_write16(DMA1_Y_MODIFY,val) +#define bfin_read_DMA1_CURR_DESC_PTR() bfin_read32(DMA1_CURR_DESC_PTR) +#define bfin_write_DMA1_CURR_DESC_PTR(val) bfin_write32(DMA1_CURR_DESC_PTR,val) +#define bfin_read_DMA1_CURR_ADDR() bfin_read32(DMA1_CURR_ADDR) +#define bfin_write_DMA1_CURR_ADDR(val) bfin_write32(DMA1_CURR_ADDR,val) +#define bfin_read_DMA1_CURR_X_COUNT() bfin_read16(DMA1_CURR_X_COUNT) +#define bfin_write_DMA1_CURR_X_COUNT(val) bfin_write16(DMA1_CURR_X_COUNT,val) +#define bfin_read_DMA1_CURR_Y_COUNT() bfin_read16(DMA1_CURR_Y_COUNT) +#define bfin_write_DMA1_CURR_Y_COUNT(val) bfin_write16(DMA1_CURR_Y_COUNT,val) +#define bfin_read_DMA1_IRQ_STATUS() bfin_read16(DMA1_IRQ_STATUS) +#define bfin_write_DMA1_IRQ_STATUS(val) bfin_write16(DMA1_IRQ_STATUS,val) +#define bfin_read_DMA1_PERIPHERAL_MAP() bfin_read16(DMA1_PERIPHERAL_MAP) +#define bfin_write_DMA1_PERIPHERAL_MAP(val) bfin_write16(DMA1_PERIPHERAL_MAP,val) + +#define bfin_read_DMA2_CONFIG() bfin_read16(DMA2_CONFIG) +#define bfin_write_DMA2_CONFIG(val) bfin_write16(DMA2_CONFIG,val) +#define bfin_read_DMA2_NEXT_DESC_PTR() bfin_read32(DMA2_NEXT_DESC_PTR) +#define bfin_write_DMA2_NEXT_DESC_PTR(val) bfin_write32(DMA2_NEXT_DESC_PTR,val) +#define bfin_read_DMA2_START_ADDR() bfin_read32(DMA2_START_ADDR) +#define bfin_write_DMA2_START_ADDR(val) bfin_write32(DMA2_START_ADDR,val) +#define bfin_read_DMA2_X_COUNT() bfin_read16(DMA2_X_COUNT) +#define bfin_write_DMA2_X_COUNT(val) bfin_write16(DMA2_X_COUNT,val) +#define bfin_read_DMA2_Y_COUNT() bfin_read16(DMA2_Y_COUNT) +#define bfin_write_DMA2_Y_COUNT(val) bfin_write16(DMA2_Y_COUNT,val) +#define bfin_read_DMA2_X_MODIFY() bfin_read16(DMA2_X_MODIFY) +#define bfin_write_DMA2_X_MODIFY(val) bfin_write16(DMA2_X_MODIFY,val) +#define bfin_read_DMA2_Y_MODIFY() bfin_read16(DMA2_Y_MODIFY) +#define bfin_write_DMA2_Y_MODIFY(val) bfin_write16(DMA2_Y_MODIFY,val) +#define bfin_read_DMA2_CURR_DESC_PTR() bfin_read32(DMA2_CURR_DESC_PTR) +#define bfin_write_DMA2_CURR_DESC_PTR(val) bfin_write32(DMA2_CURR_DESC_PTR,val) +#define bfin_read_DMA2_CURR_ADDR() bfin_read32(DMA2_CURR_ADDR) +#define bfin_write_DMA2_CURR_ADDR(val) bfin_write32(DMA2_CURR_ADDR,val) +#define bfin_read_DMA2_CURR_X_COUNT() bfin_read16(DMA2_CURR_X_COUNT) +#define bfin_write_DMA2_CURR_X_COUNT(val) bfin_write16(DMA2_CURR_X_COUNT,val) +#define bfin_read_DMA2_CURR_Y_COUNT() bfin_read16(DMA2_CURR_Y_COUNT) +#define bfin_write_DMA2_CURR_Y_COUNT(val) bfin_write16(DMA2_CURR_Y_COUNT,val) +#define bfin_read_DMA2_IRQ_STATUS() bfin_read16(DMA2_IRQ_STATUS) +#define bfin_write_DMA2_IRQ_STATUS(val) bfin_write16(DMA2_IRQ_STATUS,val) +#define bfin_read_DMA2_PERIPHERAL_MAP() bfin_read16(DMA2_PERIPHERAL_MAP) +#define bfin_write_DMA2_PERIPHERAL_MAP(val) bfin_write16(DMA2_PERIPHERAL_MAP,val) + +#define bfin_read_DMA3_CONFIG() bfin_read16(DMA3_CONFIG) +#define bfin_write_DMA3_CONFIG(val) bfin_write16(DMA3_CONFIG,val) +#define bfin_read_DMA3_NEXT_DESC_PTR() bfin_read32(DMA3_NEXT_DESC_PTR) +#define bfin_write_DMA3_NEXT_DESC_PTR(val) bfin_write32(DMA3_NEXT_DESC_PTR,val) +#define bfin_read_DMA3_START_ADDR() bfin_read32(DMA3_START_ADDR) +#define bfin_write_DMA3_START_ADDR(val) bfin_write32(DMA3_START_ADDR,val) +#define bfin_read_DMA3_X_COUNT() bfin_read16(DMA3_X_COUNT) +#define bfin_write_DMA3_X_COUNT(val) bfin_write16(DMA3_X_COUNT,val) +#define bfin_read_DMA3_Y_COUNT() bfin_read16(DMA3_Y_COUNT) +#define bfin_write_DMA3_Y_COUNT(val) bfin_write16(DMA3_Y_COUNT,val) +#define bfin_read_DMA3_X_MODIFY() bfin_read16(DMA3_X_MODIFY) +#define bfin_write_DMA3_X_MODIFY(val) bfin_write16(DMA3_X_MODIFY,val) +#define bfin_read_DMA3_Y_MODIFY() bfin_read16(DMA3_Y_MODIFY) +#define bfin_write_DMA3_Y_MODIFY(val) bfin_write16(DMA3_Y_MODIFY,val) +#define bfin_read_DMA3_CURR_DESC_PTR() bfin_read32(DMA3_CURR_DESC_PTR) +#define bfin_write_DMA3_CURR_DESC_PTR(val) bfin_write32(DMA3_CURR_DESC_PTR,val) +#define bfin_read_DMA3_CURR_ADDR() bfin_read32(DMA3_CURR_ADDR) +#define bfin_write_DMA3_CURR_ADDR(val) bfin_write32(DMA3_CURR_ADDR,val) +#define bfin_read_DMA3_CURR_X_COUNT() bfin_read16(DMA3_CURR_X_COUNT) +#define bfin_write_DMA3_CURR_X_COUNT(val) bfin_write16(DMA3_CURR_X_COUNT,val) +#define bfin_read_DMA3_CURR_Y_COUNT() bfin_read16(DMA3_CURR_Y_COUNT) +#define bfin_write_DMA3_CURR_Y_COUNT(val) bfin_write16(DMA3_CURR_Y_COUNT,val) +#define bfin_read_DMA3_IRQ_STATUS() bfin_read16(DMA3_IRQ_STATUS) +#define bfin_write_DMA3_IRQ_STATUS(val) bfin_write16(DMA3_IRQ_STATUS,val) +#define bfin_read_DMA3_PERIPHERAL_MAP() bfin_read16(DMA3_PERIPHERAL_MAP) +#define bfin_write_DMA3_PERIPHERAL_MAP(val) bfin_write16(DMA3_PERIPHERAL_MAP,val) + +#define bfin_read_DMA4_CONFIG() bfin_read16(DMA4_CONFIG) +#define bfin_write_DMA4_CONFIG(val) bfin_write16(DMA4_CONFIG,val) +#define bfin_read_DMA4_NEXT_DESC_PTR() bfin_read32(DMA4_NEXT_DESC_PTR) +#define bfin_write_DMA4_NEXT_DESC_PTR(val) bfin_write32(DMA4_NEXT_DESC_PTR,val) +#define bfin_read_DMA4_START_ADDR() bfin_read32(DMA4_START_ADDR) +#define bfin_write_DMA4_START_ADDR(val) bfin_write32(DMA4_START_ADDR,val) +#define bfin_read_DMA4_X_COUNT() bfin_read16(DMA4_X_COUNT) +#define bfin_write_DMA4_X_COUNT(val) bfin_write16(DMA4_X_COUNT,val) +#define bfin_read_DMA4_Y_COUNT() bfin_read16(DMA4_Y_COUNT) +#define bfin_write_DMA4_Y_COUNT(val) bfin_write16(DMA4_Y_COUNT,val) +#define bfin_read_DMA4_X_MODIFY() bfin_read16(DMA4_X_MODIFY) +#define bfin_write_DMA4_X_MODIFY(val) bfin_write16(DMA4_X_MODIFY,val) +#define bfin_read_DMA4_Y_MODIFY() bfin_read16(DMA4_Y_MODIFY) +#define bfin_write_DMA4_Y_MODIFY(val) bfin_write16(DMA4_Y_MODIFY,val) +#define bfin_read_DMA4_CURR_DESC_PTR() bfin_read32(DMA4_CURR_DESC_PTR) +#define bfin_write_DMA4_CURR_DESC_PTR(val) bfin_write32(DMA4_CURR_DESC_PTR,val) +#define bfin_read_DMA4_CURR_ADDR() bfin_read32(DMA4_CURR_ADDR) +#define bfin_write_DMA4_CURR_ADDR(val) bfin_write32(DMA4_CURR_ADDR,val) +#define bfin_read_DMA4_CURR_X_COUNT() bfin_read16(DMA4_CURR_X_COUNT) +#define bfin_write_DMA4_CURR_X_COUNT(val) bfin_write16(DMA4_CURR_X_COUNT,val) +#define bfin_read_DMA4_CURR_Y_COUNT() bfin_read16(DMA4_CURR_Y_COUNT) +#define bfin_write_DMA4_CURR_Y_COUNT(val) bfin_write16(DMA4_CURR_Y_COUNT,val) +#define bfin_read_DMA4_IRQ_STATUS() bfin_read16(DMA4_IRQ_STATUS) +#define bfin_write_DMA4_IRQ_STATUS(val) bfin_write16(DMA4_IRQ_STATUS,val) +#define bfin_read_DMA4_PERIPHERAL_MAP() bfin_read16(DMA4_PERIPHERAL_MAP) +#define bfin_write_DMA4_PERIPHERAL_MAP(val) bfin_write16(DMA4_PERIPHERAL_MAP,val) + +#define bfin_read_DMA5_CONFIG() bfin_read16(DMA5_CONFIG) +#define bfin_write_DMA5_CONFIG(val) bfin_write16(DMA5_CONFIG,val) +#define bfin_read_DMA5_NEXT_DESC_PTR() bfin_read32(DMA5_NEXT_DESC_PTR) +#define bfin_write_DMA5_NEXT_DESC_PTR(val) bfin_write32(DMA5_NEXT_DESC_PTR,val) +#define bfin_read_DMA5_START_ADDR() bfin_read32(DMA5_START_ADDR) +#define bfin_write_DMA5_START_ADDR(val) bfin_write32(DMA5_START_ADDR,val) +#define bfin_read_DMA5_X_COUNT() bfin_read16(DMA5_X_COUNT) +#define bfin_write_DMA5_X_COUNT(val) bfin_write16(DMA5_X_COUNT,val) +#define bfin_read_DMA5_Y_COUNT() bfin_read16(DMA5_Y_COUNT) +#define bfin_write_DMA5_Y_COUNT(val) bfin_write16(DMA5_Y_COUNT,val) +#define bfin_read_DMA5_X_MODIFY() bfin_read16(DMA5_X_MODIFY) +#define bfin_write_DMA5_X_MODIFY(val) bfin_write16(DMA5_X_MODIFY,val) +#define bfin_read_DMA5_Y_MODIFY() bfin_read16(DMA5_Y_MODIFY) +#define bfin_write_DMA5_Y_MODIFY(val) bfin_write16(DMA5_Y_MODIFY,val) +#define bfin_read_DMA5_CURR_DESC_PTR() bfin_read32(DMA5_CURR_DESC_PTR) +#define bfin_write_DMA5_CURR_DESC_PTR(val) bfin_write32(DMA5_CURR_DESC_PTR,val) +#define bfin_read_DMA5_CURR_ADDR() bfin_read32(DMA5_CURR_ADDR) +#define bfin_write_DMA5_CURR_ADDR(val) bfin_write32(DMA5_CURR_ADDR,val) +#define bfin_read_DMA5_CURR_X_COUNT() bfin_read16(DMA5_CURR_X_COUNT) +#define bfin_write_DMA5_CURR_X_COUNT(val) bfin_write16(DMA5_CURR_X_COUNT,val) +#define bfin_read_DMA5_CURR_Y_COUNT() bfin_read16(DMA5_CURR_Y_COUNT) +#define bfin_write_DMA5_CURR_Y_COUNT(val) bfin_write16(DMA5_CURR_Y_COUNT,val) +#define bfin_read_DMA5_IRQ_STATUS() bfin_read16(DMA5_IRQ_STATUS) +#define bfin_write_DMA5_IRQ_STATUS(val) bfin_write16(DMA5_IRQ_STATUS,val) +#define bfin_read_DMA5_PERIPHERAL_MAP() bfin_read16(DMA5_PERIPHERAL_MAP) +#define bfin_write_DMA5_PERIPHERAL_MAP(val) bfin_write16(DMA5_PERIPHERAL_MAP,val) + +#define bfin_read_DMA6_CONFIG() bfin_read16(DMA6_CONFIG) +#define bfin_write_DMA6_CONFIG(val) bfin_write16(DMA6_CONFIG,val) +#define bfin_read_DMA6_NEXT_DESC_PTR() bfin_read32(DMA6_NEXT_DESC_PTR) +#define bfin_write_DMA6_NEXT_DESC_PTR(val) bfin_write32(DMA6_NEXT_DESC_PTR,val) +#define bfin_read_DMA6_START_ADDR() bfin_read32(DMA6_START_ADDR) +#define bfin_write_DMA6_START_ADDR(val) bfin_write32(DMA6_START_ADDR,val) +#define bfin_read_DMA6_X_COUNT() bfin_read16(DMA6_X_COUNT) +#define bfin_write_DMA6_X_COUNT(val) bfin_write16(DMA6_X_COUNT,val) +#define bfin_read_DMA6_Y_COUNT() bfin_read16(DMA6_Y_COUNT) +#define bfin_write_DMA6_Y_COUNT(val) bfin_write16(DMA6_Y_COUNT,val) +#define bfin_read_DMA6_X_MODIFY() bfin_read16(DMA6_X_MODIFY) +#define bfin_write_DMA6_X_MODIFY(val) bfin_write16(DMA6_X_MODIFY,val) +#define bfin_read_DMA6_Y_MODIFY() bfin_read16(DMA6_Y_MODIFY) +#define bfin_write_DMA6_Y_MODIFY(val) bfin_write16(DMA6_Y_MODIFY,val) +#define bfin_read_DMA6_CURR_DESC_PTR() bfin_read32(DMA6_CURR_DESC_PTR) +#define bfin_write_DMA6_CURR_DESC_PTR(val) bfin_write32(DMA6_CURR_DESC_PTR,val) +#define bfin_read_DMA6_CURR_ADDR() bfin_read32(DMA6_CURR_ADDR) +#define bfin_write_DMA6_CURR_ADDR(val) bfin_write32(DMA6_CURR_ADDR,val) +#define bfin_read_DMA6_CURR_X_COUNT() bfin_read16(DMA6_CURR_X_COUNT) +#define bfin_write_DMA6_CURR_X_COUNT(val) bfin_write16(DMA6_CURR_X_COUNT,val) +#define bfin_read_DMA6_CURR_Y_COUNT() bfin_read16(DMA6_CURR_Y_COUNT) +#define bfin_write_DMA6_CURR_Y_COUNT(val) bfin_write16(DMA6_CURR_Y_COUNT,val) +#define bfin_read_DMA6_IRQ_STATUS() bfin_read16(DMA6_IRQ_STATUS) +#define bfin_write_DMA6_IRQ_STATUS(val) bfin_write16(DMA6_IRQ_STATUS,val) +#define bfin_read_DMA6_PERIPHERAL_MAP() bfin_read16(DMA6_PERIPHERAL_MAP) +#define bfin_write_DMA6_PERIPHERAL_MAP(val) bfin_write16(DMA6_PERIPHERAL_MAP,val) + +#define bfin_read_DMA7_CONFIG() bfin_read16(DMA7_CONFIG) +#define bfin_write_DMA7_CONFIG(val) bfin_write16(DMA7_CONFIG,val) +#define bfin_read_DMA7_NEXT_DESC_PTR() bfin_read32(DMA7_NEXT_DESC_PTR) +#define bfin_write_DMA7_NEXT_DESC_PTR(val) bfin_write32(DMA7_NEXT_DESC_PTR,val) +#define bfin_read_DMA7_START_ADDR() bfin_read32(DMA7_START_ADDR) +#define bfin_write_DMA7_START_ADDR(val) bfin_write32(DMA7_START_ADDR,val) +#define bfin_read_DMA7_X_COUNT() bfin_read16(DMA7_X_COUNT) +#define bfin_write_DMA7_X_COUNT(val) bfin_write16(DMA7_X_COUNT,val) +#define bfin_read_DMA7_Y_COUNT() bfin_read16(DMA7_Y_COUNT) +#define bfin_write_DMA7_Y_COUNT(val) bfin_write16(DMA7_Y_COUNT,val) +#define bfin_read_DMA7_X_MODIFY() bfin_read16(DMA7_X_MODIFY) +#define bfin_write_DMA7_X_MODIFY(val) bfin_write16(DMA7_X_MODIFY,val) +#define bfin_read_DMA7_Y_MODIFY() bfin_read16(DMA7_Y_MODIFY) +#define bfin_write_DMA7_Y_MODIFY(val) bfin_write16(DMA7_Y_MODIFY,val) +#define bfin_read_DMA7_CURR_DESC_PTR() bfin_read32(DMA7_CURR_DESC_PTR) +#define bfin_write_DMA7_CURR_DESC_PTR(val) bfin_write32(DMA7_CURR_DESC_PTR,val) +#define bfin_read_DMA7_CURR_ADDR() bfin_read32(DMA7_CURR_ADDR) +#define bfin_write_DMA7_CURR_ADDR(val) bfin_write32(DMA7_CURR_ADDR,val) +#define bfin_read_DMA7_CURR_X_COUNT() bfin_read16(DMA7_CURR_X_COUNT) +#define bfin_write_DMA7_CURR_X_COUNT(val) bfin_write16(DMA7_CURR_X_COUNT,val) +#define bfin_read_DMA7_CURR_Y_COUNT() bfin_read16(DMA7_CURR_Y_COUNT) +#define bfin_write_DMA7_CURR_Y_COUNT(val) bfin_write16(DMA7_CURR_Y_COUNT,val) +#define bfin_read_DMA7_IRQ_STATUS() bfin_read16(DMA7_IRQ_STATUS) +#define bfin_write_DMA7_IRQ_STATUS(val) bfin_write16(DMA7_IRQ_STATUS,val) +#define bfin_read_DMA7_PERIPHERAL_MAP() bfin_read16(DMA7_PERIPHERAL_MAP) +#define bfin_write_DMA7_PERIPHERAL_MAP(val) bfin_write16(DMA7_PERIPHERAL_MAP,val) + +#define bfin_read_DMA8_CONFIG() bfin_read16(DMA8_CONFIG) +#define bfin_write_DMA8_CONFIG(val) bfin_write16(DMA8_CONFIG,val) +#define bfin_read_DMA8_NEXT_DESC_PTR() bfin_read32(DMA8_NEXT_DESC_PTR) +#define bfin_write_DMA8_NEXT_DESC_PTR(val) bfin_write32(DMA8_NEXT_DESC_PTR,val) +#define bfin_read_DMA8_START_ADDR() bfin_read32(DMA8_START_ADDR) +#define bfin_write_DMA8_START_ADDR(val) bfin_write32(DMA8_START_ADDR,val) +#define bfin_read_DMA8_X_COUNT() bfin_read16(DMA8_X_COUNT) +#define bfin_write_DMA8_X_COUNT(val) bfin_write16(DMA8_X_COUNT,val) +#define bfin_read_DMA8_Y_COUNT() bfin_read16(DMA8_Y_COUNT) +#define bfin_write_DMA8_Y_COUNT(val) bfin_write16(DMA8_Y_COUNT,val) +#define bfin_read_DMA8_X_MODIFY() bfin_read16(DMA8_X_MODIFY) +#define bfin_write_DMA8_X_MODIFY(val) bfin_write16(DMA8_X_MODIFY,val) +#define bfin_read_DMA8_Y_MODIFY() bfin_read16(DMA8_Y_MODIFY) +#define bfin_write_DMA8_Y_MODIFY(val) bfin_write16(DMA8_Y_MODIFY,val) +#define bfin_read_DMA8_CURR_DESC_PTR() bfin_read32(DMA8_CURR_DESC_PTR) +#define bfin_write_DMA8_CURR_DESC_PTR(val) bfin_write32(DMA8_CURR_DESC_PTR,val) +#define bfin_read_DMA8_CURR_ADDR() bfin_read32(DMA8_CURR_ADDR) +#define bfin_write_DMA8_CURR_ADDR(val) bfin_write32(DMA8_CURR_ADDR,val) +#define bfin_read_DMA8_CURR_X_COUNT() bfin_read16(DMA8_CURR_X_COUNT) +#define bfin_write_DMA8_CURR_X_COUNT(val) bfin_write16(DMA8_CURR_X_COUNT,val) +#define bfin_read_DMA8_CURR_Y_COUNT() bfin_read16(DMA8_CURR_Y_COUNT) +#define bfin_write_DMA8_CURR_Y_COUNT(val) bfin_write16(DMA8_CURR_Y_COUNT,val) +#define bfin_read_DMA8_IRQ_STATUS() bfin_read16(DMA8_IRQ_STATUS) +#define bfin_write_DMA8_IRQ_STATUS(val) bfin_write16(DMA8_IRQ_STATUS,val) +#define bfin_read_DMA8_PERIPHERAL_MAP() bfin_read16(DMA8_PERIPHERAL_MAP) +#define bfin_write_DMA8_PERIPHERAL_MAP(val) bfin_write16(DMA8_PERIPHERAL_MAP,val) + +#define bfin_read_DMA9_CONFIG() bfin_read16(DMA9_CONFIG) +#define bfin_write_DMA9_CONFIG(val) bfin_write16(DMA9_CONFIG,val) +#define bfin_read_DMA9_NEXT_DESC_PTR() bfin_read32(DMA9_NEXT_DESC_PTR) +#define bfin_write_DMA9_NEXT_DESC_PTR(val) bfin_write32(DMA9_NEXT_DESC_PTR,val) +#define bfin_read_DMA9_START_ADDR() bfin_read32(DMA9_START_ADDR) +#define bfin_write_DMA9_START_ADDR(val) bfin_write32(DMA9_START_ADDR,val) +#define bfin_read_DMA9_X_COUNT() bfin_read16(DMA9_X_COUNT) +#define bfin_write_DMA9_X_COUNT(val) bfin_write16(DMA9_X_COUNT,val) +#define bfin_read_DMA9_Y_COUNT() bfin_read16(DMA9_Y_COUNT) +#define bfin_write_DMA9_Y_COUNT(val) bfin_write16(DMA9_Y_COUNT,val) +#define bfin_read_DMA9_X_MODIFY() bfin_read16(DMA9_X_MODIFY) +#define bfin_write_DMA9_X_MODIFY(val) bfin_write16(DMA9_X_MODIFY,val) +#define bfin_read_DMA9_Y_MODIFY() bfin_read16(DMA9_Y_MODIFY) +#define bfin_write_DMA9_Y_MODIFY(val) bfin_write16(DMA9_Y_MODIFY,val) +#define bfin_read_DMA9_CURR_DESC_PTR() bfin_read32(DMA9_CURR_DESC_PTR) +#define bfin_write_DMA9_CURR_DESC_PTR(val) bfin_write32(DMA9_CURR_DESC_PTR,val) +#define bfin_read_DMA9_CURR_ADDR() bfin_read32(DMA9_CURR_ADDR) +#define bfin_write_DMA9_CURR_ADDR(val) bfin_write32(DMA9_CURR_ADDR,val) +#define bfin_read_DMA9_CURR_X_COUNT() bfin_read16(DMA9_CURR_X_COUNT) +#define bfin_write_DMA9_CURR_X_COUNT(val) bfin_write16(DMA9_CURR_X_COUNT,val) +#define bfin_read_DMA9_CURR_Y_COUNT() bfin_read16(DMA9_CURR_Y_COUNT) +#define bfin_write_DMA9_CURR_Y_COUNT(val) bfin_write16(DMA9_CURR_Y_COUNT,val) +#define bfin_read_DMA9_IRQ_STATUS() bfin_read16(DMA9_IRQ_STATUS) +#define bfin_write_DMA9_IRQ_STATUS(val) bfin_write16(DMA9_IRQ_STATUS,val) +#define bfin_read_DMA9_PERIPHERAL_MAP() bfin_read16(DMA9_PERIPHERAL_MAP) +#define bfin_write_DMA9_PERIPHERAL_MAP(val) bfin_write16(DMA9_PERIPHERAL_MAP,val) + +#define bfin_read_DMA10_CONFIG() bfin_read16(DMA10_CONFIG) +#define bfin_write_DMA10_CONFIG(val) bfin_write16(DMA10_CONFIG,val) +#define bfin_read_DMA10_NEXT_DESC_PTR() bfin_read32(DMA10_NEXT_DESC_PTR) +#define bfin_write_DMA10_NEXT_DESC_PTR(val) bfin_write32(DMA10_NEXT_DESC_PTR,val) +#define bfin_read_DMA10_START_ADDR() bfin_read32(DMA10_START_ADDR) +#define bfin_write_DMA10_START_ADDR(val) bfin_write32(DMA10_START_ADDR,val) +#define bfin_read_DMA10_X_COUNT() bfin_read16(DMA10_X_COUNT) +#define bfin_write_DMA10_X_COUNT(val) bfin_write16(DMA10_X_COUNT,val) +#define bfin_read_DMA10_Y_COUNT() bfin_read16(DMA10_Y_COUNT) +#define bfin_write_DMA10_Y_COUNT(val) bfin_write16(DMA10_Y_COUNT,val) +#define bfin_read_DMA10_X_MODIFY() bfin_read16(DMA10_X_MODIFY) +#define bfin_write_DMA10_X_MODIFY(val) bfin_write16(DMA10_X_MODIFY,val) +#define bfin_read_DMA10_Y_MODIFY() bfin_read16(DMA10_Y_MODIFY) +#define bfin_write_DMA10_Y_MODIFY(val) bfin_write16(DMA10_Y_MODIFY,val) +#define bfin_read_DMA10_CURR_DESC_PTR() bfin_read32(DMA10_CURR_DESC_PTR) +#define bfin_write_DMA10_CURR_DESC_PTR(val) bfin_write32(DMA10_CURR_DESC_PTR,val) +#define bfin_read_DMA10_CURR_ADDR() bfin_read32(DMA10_CURR_ADDR) +#define bfin_write_DMA10_CURR_ADDR(val) bfin_write32(DMA10_CURR_ADDR,val) +#define bfin_read_DMA10_CURR_X_COUNT() bfin_read16(DMA10_CURR_X_COUNT) +#define bfin_write_DMA10_CURR_X_COUNT(val) bfin_write16(DMA10_CURR_X_COUNT,val) +#define bfin_read_DMA10_CURR_Y_COUNT() bfin_read16(DMA10_CURR_Y_COUNT) +#define bfin_write_DMA10_CURR_Y_COUNT(val) bfin_write16(DMA10_CURR_Y_COUNT,val) +#define bfin_read_DMA10_IRQ_STATUS() bfin_read16(DMA10_IRQ_STATUS) +#define bfin_write_DMA10_IRQ_STATUS(val) bfin_write16(DMA10_IRQ_STATUS,val) +#define bfin_read_DMA10_PERIPHERAL_MAP() bfin_read16(DMA10_PERIPHERAL_MAP) +#define bfin_write_DMA10_PERIPHERAL_MAP(val) bfin_write16(DMA10_PERIPHERAL_MAP,val) + +#define bfin_read_DMA11_CONFIG() bfin_read16(DMA11_CONFIG) +#define bfin_write_DMA11_CONFIG(val) bfin_write16(DMA11_CONFIG,val) +#define bfin_read_DMA11_NEXT_DESC_PTR() bfin_read32(DMA11_NEXT_DESC_PTR) +#define bfin_write_DMA11_NEXT_DESC_PTR(val) bfin_write32(DMA11_NEXT_DESC_PTR,val) +#define bfin_read_DMA11_START_ADDR() bfin_read32(DMA11_START_ADDR) +#define bfin_write_DMA11_START_ADDR(val) bfin_write32(DMA11_START_ADDR,val) +#define bfin_read_DMA11_X_COUNT() bfin_read16(DMA11_X_COUNT) +#define bfin_write_DMA11_X_COUNT(val) bfin_write16(DMA11_X_COUNT,val) +#define bfin_read_DMA11_Y_COUNT() bfin_read16(DMA11_Y_COUNT) +#define bfin_write_DMA11_Y_COUNT(val) bfin_write16(DMA11_Y_COUNT,val) +#define bfin_read_DMA11_X_MODIFY() bfin_read16(DMA11_X_MODIFY) +#define bfin_write_DMA11_X_MODIFY(val) bfin_write16(DMA11_X_MODIFY,val) +#define bfin_read_DMA11_Y_MODIFY() bfin_read16(DMA11_Y_MODIFY) +#define bfin_write_DMA11_Y_MODIFY(val) bfin_write16(DMA11_Y_MODIFY,val) +#define bfin_read_DMA11_CURR_DESC_PTR() bfin_read32(DMA11_CURR_DESC_PTR) +#define bfin_write_DMA11_CURR_DESC_PTR(val) bfin_write32(DMA11_CURR_DESC_PTR,val) +#define bfin_read_DMA11_CURR_ADDR() bfin_read32(DMA11_CURR_ADDR) +#define bfin_write_DMA11_CURR_ADDR(val) bfin_write32(DMA11_CURR_ADDR,val) +#define bfin_read_DMA11_CURR_X_COUNT() bfin_read16(DMA11_CURR_X_COUNT) +#define bfin_write_DMA11_CURR_X_COUNT(val) bfin_write16(DMA11_CURR_X_COUNT,val) +#define bfin_read_DMA11_CURR_Y_COUNT() bfin_read16(DMA11_CURR_Y_COUNT) +#define bfin_write_DMA11_CURR_Y_COUNT(val) bfin_write16(DMA11_CURR_Y_COUNT,val) +#define bfin_read_DMA11_IRQ_STATUS() bfin_read16(DMA11_IRQ_STATUS) +#define bfin_write_DMA11_IRQ_STATUS(val) bfin_write16(DMA11_IRQ_STATUS,val) +#define bfin_read_DMA11_PERIPHERAL_MAP() bfin_read16(DMA11_PERIPHERAL_MAP) +#define bfin_write_DMA11_PERIPHERAL_MAP(val) bfin_write16(DMA11_PERIPHERAL_MAP,val) + +#define bfin_read_MDMA_D0_CONFIG() bfin_read16(MDMA_D0_CONFIG) +#define bfin_write_MDMA_D0_CONFIG(val) bfin_write16(MDMA_D0_CONFIG,val) +#define bfin_read_MDMA_D0_NEXT_DESC_PTR() bfin_read32(MDMA_D0_NEXT_DESC_PTR) +#define bfin_write_MDMA_D0_NEXT_DESC_PTR(val) bfin_write32(MDMA_D0_NEXT_DESC_PTR,val) +#define bfin_read_MDMA_D0_START_ADDR() bfin_read32(MDMA_D0_START_ADDR) +#define bfin_write_MDMA_D0_START_ADDR(val) bfin_write32(MDMA_D0_START_ADDR,val) +#define bfin_read_MDMA_D0_X_COUNT() bfin_read16(MDMA_D0_X_COUNT) +#define bfin_write_MDMA_D0_X_COUNT(val) bfin_write16(MDMA_D0_X_COUNT,val) +#define bfin_read_MDMA_D0_Y_COUNT() bfin_read16(MDMA_D0_Y_COUNT) +#define bfin_write_MDMA_D0_Y_COUNT(val) bfin_write16(MDMA_D0_Y_COUNT,val) +#define bfin_read_MDMA_D0_X_MODIFY() bfin_read16(MDMA_D0_X_MODIFY) +#define bfin_write_MDMA_D0_X_MODIFY(val) bfin_write16(MDMA_D0_X_MODIFY,val) +#define bfin_read_MDMA_D0_Y_MODIFY() bfin_read16(MDMA_D0_Y_MODIFY) +#define bfin_write_MDMA_D0_Y_MODIFY(val) bfin_write16(MDMA_D0_Y_MODIFY,val) +#define bfin_read_MDMA_D0_CURR_DESC_PTR() bfin_read32(MDMA_D0_CURR_DESC_PTR) +#define bfin_write_MDMA_D0_CURR_DESC_PTR(val) bfin_write32(MDMA_D0_CURR_DESC_PTR,val) +#define bfin_read_MDMA_D0_CURR_ADDR() bfin_read32(MDMA_D0_CURR_ADDR) +#define bfin_write_MDMA_D0_CURR_ADDR(val) bfin_write32(MDMA_D0_CURR_ADDR,val) +#define bfin_read_MDMA_D0_CURR_X_COUNT() bfin_read16(MDMA_D0_CURR_X_COUNT) +#define bfin_write_MDMA_D0_CURR_X_COUNT(val) bfin_write16(MDMA_D0_CURR_X_COUNT,val) +#define bfin_read_MDMA_D0_CURR_Y_COUNT() bfin_read16(MDMA_D0_CURR_Y_COUNT) +#define bfin_write_MDMA_D0_CURR_Y_COUNT(val) bfin_write16(MDMA_D0_CURR_Y_COUNT,val) +#define bfin_read_MDMA_D0_IRQ_STATUS() bfin_read16(MDMA_D0_IRQ_STATUS) +#define bfin_write_MDMA_D0_IRQ_STATUS(val) bfin_write16(MDMA_D0_IRQ_STATUS,val) +#define bfin_read_MDMA_D0_PERIPHERAL_MAP() bfin_read16(MDMA_D0_PERIPHERAL_MAP) +#define bfin_write_MDMA_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA_D0_PERIPHERAL_MAP,val) + +#define bfin_read_MDMA_S0_CONFIG() bfin_read16(MDMA_S0_CONFIG) +#define bfin_write_MDMA_S0_CONFIG(val) bfin_write16(MDMA_S0_CONFIG,val) +#define bfin_read_MDMA_S0_NEXT_DESC_PTR() bfin_read32(MDMA_S0_NEXT_DESC_PTR) +#define bfin_write_MDMA_S0_NEXT_DESC_PTR(val) bfin_write32(MDMA_S0_NEXT_DESC_PTR,val) +#define bfin_read_MDMA_S0_START_ADDR() bfin_read32(MDMA_S0_START_ADDR) +#define bfin_write_MDMA_S0_START_ADDR(val) bfin_write32(MDMA_S0_START_ADDR,val) +#define bfin_read_MDMA_S0_X_COUNT() bfin_read16(MDMA_S0_X_COUNT) +#define bfin_write_MDMA_S0_X_COUNT(val) bfin_write16(MDMA_S0_X_COUNT,val) +#define bfin_read_MDMA_S0_Y_COUNT() bfin_read16(MDMA_S0_Y_COUNT) +#define bfin_write_MDMA_S0_Y_COUNT(val) bfin_write16(MDMA_S0_Y_COUNT,val) +#define bfin_read_MDMA_S0_X_MODIFY() bfin_read16(MDMA_S0_X_MODIFY) +#define bfin_write_MDMA_S0_X_MODIFY(val) bfin_write16(MDMA_S0_X_MODIFY,val) +#define bfin_read_MDMA_S0_Y_MODIFY() bfin_read16(MDMA_S0_Y_MODIFY) +#define bfin_write_MDMA_S0_Y_MODIFY(val) bfin_write16(MDMA_S0_Y_MODIFY,val) +#define bfin_read_MDMA_S0_CURR_DESC_PTR() bfin_read32(MDMA_S0_CURR_DESC_PTR) +#define bfin_write_MDMA_S0_CURR_DESC_PTR(val) bfin_write32(MDMA_S0_CURR_DESC_PTR,val) +#define bfin_read_MDMA_S0_CURR_ADDR() bfin_read32(MDMA_S0_CURR_ADDR) +#define bfin_write_MDMA_S0_CURR_ADDR(val) bfin_write32(MDMA_S0_CURR_ADDR,val) +#define bfin_read_MDMA_S0_CURR_X_COUNT() bfin_read16(MDMA_S0_CURR_X_COUNT) +#define bfin_write_MDMA_S0_CURR_X_COUNT(val) bfin_write16(MDMA_S0_CURR_X_COUNT,val) +#define bfin_read_MDMA_S0_CURR_Y_COUNT() bfin_read16(MDMA_S0_CURR_Y_COUNT) +#define bfin_write_MDMA_S0_CURR_Y_COUNT(val) bfin_write16(MDMA_S0_CURR_Y_COUNT,val) +#define bfin_read_MDMA_S0_IRQ_STATUS() bfin_read16(MDMA_S0_IRQ_STATUS) +#define bfin_write_MDMA_S0_IRQ_STATUS(val) bfin_write16(MDMA_S0_IRQ_STATUS,val) +#define bfin_read_MDMA_S0_PERIPHERAL_MAP() bfin_read16(MDMA_S0_PERIPHERAL_MAP) +#define bfin_write_MDMA_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA_S0_PERIPHERAL_MAP,val) + +#define bfin_read_MDMA_D1_CONFIG() bfin_read16(MDMA_D1_CONFIG) +#define bfin_write_MDMA_D1_CONFIG(val) bfin_write16(MDMA_D1_CONFIG,val) +#define bfin_read_MDMA_D1_NEXT_DESC_PTR() bfin_read32(MDMA_D1_NEXT_DESC_PTR) +#define bfin_write_MDMA_D1_NEXT_DESC_PTR(val) bfin_write32(MDMA_D1_NEXT_DESC_PTR,val) +#define bfin_read_MDMA_D1_START_ADDR() bfin_read32(MDMA_D1_START_ADDR) +#define bfin_write_MDMA_D1_START_ADDR(val) bfin_write32(MDMA_D1_START_ADDR,val) +#define bfin_read_MDMA_D1_X_COUNT() bfin_read16(MDMA_D1_X_COUNT) +#define bfin_write_MDMA_D1_X_COUNT(val) bfin_write16(MDMA_D1_X_COUNT,val) +#define bfin_read_MDMA_D1_Y_COUNT() bfin_read16(MDMA_D1_Y_COUNT) +#define bfin_write_MDMA_D1_Y_COUNT(val) bfin_write16(MDMA_D1_Y_COUNT,val) +#define bfin_read_MDMA_D1_X_MODIFY() bfin_read16(MDMA_D1_X_MODIFY) +#define bfin_write_MDMA_D1_X_MODIFY(val) bfin_write16(MDMA_D1_X_MODIFY,val) +#define bfin_read_MDMA_D1_Y_MODIFY() bfin_read16(MDMA_D1_Y_MODIFY) +#define bfin_write_MDMA_D1_Y_MODIFY(val) bfin_write16(MDMA_D1_Y_MODIFY,val) +#define bfin_read_MDMA_D1_CURR_DESC_PTR() bfin_read32(MDMA_D1_CURR_DESC_PTR) +#define bfin_write_MDMA_D1_CURR_DESC_PTR(val) bfin_write32(MDMA_D1_CURR_DESC_PTR,val) +#define bfin_read_MDMA_D1_CURR_ADDR() bfin_read32(MDMA_D1_CURR_ADDR) +#define bfin_write_MDMA_D1_CURR_ADDR(val) bfin_write32(MDMA_D1_CURR_ADDR,val) +#define bfin_read_MDMA_D1_CURR_X_COUNT() bfin_read16(MDMA_D1_CURR_X_COUNT) +#define bfin_write_MDMA_D1_CURR_X_COUNT(val) bfin_write16(MDMA_D1_CURR_X_COUNT,val) +#define bfin_read_MDMA_D1_CURR_Y_COUNT() bfin_read16(MDMA_D1_CURR_Y_COUNT) +#define bfin_write_MDMA_D1_CURR_Y_COUNT(val) bfin_write16(MDMA_D1_CURR_Y_COUNT,val) +#define bfin_read_MDMA_D1_IRQ_STATUS() bfin_read16(MDMA_D1_IRQ_STATUS) +#define bfin_write_MDMA_D1_IRQ_STATUS(val) bfin_write16(MDMA_D1_IRQ_STATUS,val) +#define bfin_read_MDMA_D1_PERIPHERAL_MAP() bfin_read16(MDMA_D1_PERIPHERAL_MAP) +#define bfin_write_MDMA_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA_D1_PERIPHERAL_MAP,val) + +#define bfin_read_MDMA_S1_CONFIG() bfin_read16(MDMA_S1_CONFIG) +#define bfin_write_MDMA_S1_CONFIG(val) bfin_write16(MDMA_S1_CONFIG,val) +#define bfin_read_MDMA_S1_NEXT_DESC_PTR() bfin_read32(MDMA_S1_NEXT_DESC_PTR) +#define bfin_write_MDMA_S1_NEXT_DESC_PTR(val) bfin_write32(MDMA_S1_NEXT_DESC_PTR,val) +#define bfin_read_MDMA_S1_START_ADDR() bfin_read32(MDMA_S1_START_ADDR) +#define bfin_write_MDMA_S1_START_ADDR(val) bfin_write32(MDMA_S1_START_ADDR,val) +#define bfin_read_MDMA_S1_X_COUNT() bfin_read16(MDMA_S1_X_COUNT) +#define bfin_write_MDMA_S1_X_COUNT(val) bfin_write16(MDMA_S1_X_COUNT,val) +#define bfin_read_MDMA_S1_Y_COUNT() bfin_read16(MDMA_S1_Y_COUNT) +#define bfin_write_MDMA_S1_Y_COUNT(val) bfin_write16(MDMA_S1_Y_COUNT,val) +#define bfin_read_MDMA_S1_X_MODIFY() bfin_read16(MDMA_S1_X_MODIFY) +#define bfin_write_MDMA_S1_X_MODIFY(val) bfin_write16(MDMA_S1_X_MODIFY,val) +#define bfin_read_MDMA_S1_Y_MODIFY() bfin_read16(MDMA_S1_Y_MODIFY) +#define bfin_write_MDMA_S1_Y_MODIFY(val) bfin_write16(MDMA_S1_Y_MODIFY,val) +#define bfin_read_MDMA_S1_CURR_DESC_PTR() bfin_read32(MDMA_S1_CURR_DESC_PTR) +#define bfin_write_MDMA_S1_CURR_DESC_PTR(val) bfin_write32(MDMA_S1_CURR_DESC_PTR,val) +#define bfin_read_MDMA_S1_CURR_ADDR() bfin_read32(MDMA_S1_CURR_ADDR) +#define bfin_write_MDMA_S1_CURR_ADDR(val) bfin_write32(MDMA_S1_CURR_ADDR,val) +#define bfin_read_MDMA_S1_CURR_X_COUNT() bfin_read16(MDMA_S1_CURR_X_COUNT) +#define bfin_write_MDMA_S1_CURR_X_COUNT(val) bfin_write16(MDMA_S1_CURR_X_COUNT,val) +#define bfin_read_MDMA_S1_CURR_Y_COUNT() bfin_read16(MDMA_S1_CURR_Y_COUNT) +#define bfin_write_MDMA_S1_CURR_Y_COUNT(val) bfin_write16(MDMA_S1_CURR_Y_COUNT,val) +#define bfin_read_MDMA_S1_IRQ_STATUS() bfin_read16(MDMA_S1_IRQ_STATUS) +#define bfin_write_MDMA_S1_IRQ_STATUS(val) bfin_write16(MDMA_S1_IRQ_STATUS,val) +#define bfin_read_MDMA_S1_PERIPHERAL_MAP() bfin_read16(MDMA_S1_PERIPHERAL_MAP) +#define bfin_write_MDMA_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA_S1_PERIPHERAL_MAP,val) + +/* Parallel Peripheral Interface (0xFFC01000 - 0xFFC010FF) */ +#define bfin_read_PPI_CONTROL() bfin_read16(PPI_CONTROL) +#define bfin_write_PPI_CONTROL(val) bfin_write16(PPI_CONTROL,val) +#define bfin_read_PPI_STATUS() bfin_read16(PPI_STATUS) +#define bfin_write_PPI_STATUS(val) bfin_write16(PPI_STATUS,val) +#define bfin_clear_PPI_STATUS() bfin_write_PPI_STATUS(0xFFFF) +#define bfin_read_PPI_DELAY() bfin_read16(PPI_DELAY) +#define bfin_write_PPI_DELAY(val) bfin_write16(PPI_DELAY,val) +#define bfin_read_PPI_COUNT() bfin_read16(PPI_COUNT) +#define bfin_write_PPI_COUNT(val) bfin_write16(PPI_COUNT,val) +#define bfin_read_PPI_FRAME() bfin_read16(PPI_FRAME) +#define bfin_write_PPI_FRAME(val) bfin_write16(PPI_FRAME,val) + +/* Two-Wire Interface (0xFFC01400 - 0xFFC014FF) */ +#define bfin_read_TWI_CLKDIV() bfin_read16(TWI_CLKDIV) +#define bfin_write_TWI_CLKDIV(val) bfin_write16(TWI_CLKDIV,val) +#define bfin_read_TWI_CONTROL() bfin_read16(TWI_CONTROL) +#define bfin_write_TWI_CONTROL(val) bfin_write16(TWI_CONTROL,val) +#define bfin_read_TWI_SLAVE_CTL() bfin_read16(TWI_SLAVE_CTL) +#define bfin_write_TWI_SLAVE_CTL(val) bfin_write16(TWI_SLAVE_CTL,val) +#define bfin_read_TWI_SLAVE_STAT() bfin_read16(TWI_SLAVE_STAT) +#define bfin_write_TWI_SLAVE_STAT(val) bfin_write16(TWI_SLAVE_STAT,val) +#define bfin_read_TWI_SLAVE_ADDR() bfin_read16(TWI_SLAVE_ADDR) +#define bfin_write_TWI_SLAVE_ADDR(val) bfin_write16(TWI_SLAVE_ADDR,val) +#define bfin_read_TWI_MASTER_CTL() bfin_read16(TWI_MASTER_CTL) +#define bfin_write_TWI_MASTER_CTL(val) bfin_write16(TWI_MASTER_CTL,val) +#define bfin_read_TWI_MASTER_STAT() bfin_read16(TWI_MASTER_STAT) +#define bfin_write_TWI_MASTER_STAT(val) bfin_write16(TWI_MASTER_STAT,val) +#define bfin_read_TWI_MASTER_ADDR() bfin_read16(TWI_MASTER_ADDR) +#define bfin_write_TWI_MASTER_ADDR(val) bfin_write16(TWI_MASTER_ADDR,val) +#define bfin_read_TWI_INT_STAT() bfin_read16(TWI_INT_STAT) +#define bfin_write_TWI_INT_STAT(val) bfin_write16(TWI_INT_STAT,val) +#define bfin_read_TWI_INT_MASK() bfin_read16(TWI_INT_MASK) +#define bfin_write_TWI_INT_MASK(val) bfin_write16(TWI_INT_MASK,val) +#define bfin_read_TWI_FIFO_CTL() bfin_read16(TWI_FIFO_CTL) +#define bfin_write_TWI_FIFO_CTL(val) bfin_write16(TWI_FIFO_CTL,val) +#define bfin_read_TWI_FIFO_STAT() bfin_read16(TWI_FIFO_STAT) +#define bfin_write_TWI_FIFO_STAT(val) bfin_write16(TWI_FIFO_STAT,val) +#define bfin_read_TWI_XMT_DATA8() bfin_read16(TWI_XMT_DATA8) +#define bfin_write_TWI_XMT_DATA8(val) bfin_write16(TWI_XMT_DATA8,val) +#define bfin_read_TWI_XMT_DATA16() bfin_read16(TWI_XMT_DATA16) +#define bfin_write_TWI_XMT_DATA16(val) bfin_write16(TWI_XMT_DATA16,val) +#define bfin_read_TWI_RCV_DATA8() bfin_read16(TWI_RCV_DATA8) +#define bfin_write_TWI_RCV_DATA8(val) bfin_write16(TWI_RCV_DATA8,val) +#define bfin_read_TWI_RCV_DATA16() bfin_read16(TWI_RCV_DATA16) +#define bfin_write_TWI_RCV_DATA16(val) bfin_write16(TWI_RCV_DATA16,val) + +/* General Purpose I/O Port G (0xFFC01500 - 0xFFC015FF) */ +#define bfin_read_PORTGIO() bfin_read16(PORTGIO) +#define bfin_write_PORTGIO(val) bfin_write16(PORTGIO,val) +#define bfin_read_PORTGIO_CLEAR() bfin_read16(PORTGIO_CLEAR) +#define bfin_write_PORTGIO_CLEAR(val) bfin_write16(PORTGIO_CLEAR,val) +#define bfin_read_PORTGIO_SET() bfin_read16(PORTGIO_SET) +#define bfin_write_PORTGIO_SET(val) bfin_write16(PORTGIO_SET,val) +#define bfin_read_PORTGIO_TOGGLE() bfin_read16(PORTGIO_TOGGLE) +#define bfin_write_PORTGIO_TOGGLE(val) bfin_write16(PORTGIO_TOGGLE,val) +#define bfin_read_PORTGIO_MASKA() bfin_read16(PORTGIO_MASKA) +#define bfin_write_PORTGIO_MASKA(val) bfin_write16(PORTGIO_MASKA,val) +#define bfin_read_PORTGIO_MASKA_CLEAR() bfin_read16(PORTGIO_MASKA_CLEAR) +#define bfin_write_PORTGIO_MASKA_CLEAR(val) bfin_write16(PORTGIO_MASKA_CLEAR,val) +#define bfin_read_PORTGIO_MASKA_SET() bfin_read16(PORTGIO_MASKA_SET) +#define bfin_write_PORTGIO_MASKA_SET(val) bfin_write16(PORTGIO_MASKA_SET,val) +#define bfin_read_PORTGIO_MASKA_TOGGLE() bfin_read16(PORTGIO_MASKA_TOGGLE) +#define bfin_write_PORTGIO_MASKA_TOGGLE(val) bfin_write16(PORTGIO_MASKA_TOGGLE,val) +#define bfin_read_PORTGIO_MASKB() bfin_read16(PORTGIO_MASKB) +#define bfin_write_PORTGIO_MASKB(val) bfin_write16(PORTGIO_MASKB,val) +#define bfin_read_PORTGIO_MASKB_CLEAR() bfin_read16(PORTGIO_MASKB_CLEAR) +#define bfin_write_PORTGIO_MASKB_CLEAR(val) bfin_write16(PORTGIO_MASKB_CLEAR,val) +#define bfin_read_PORTGIO_MASKB_SET() bfin_read16(PORTGIO_MASKB_SET) +#define bfin_write_PORTGIO_MASKB_SET(val) bfin_write16(PORTGIO_MASKB_SET,val) +#define bfin_read_PORTGIO_MASKB_TOGGLE() bfin_read16(PORTGIO_MASKB_TOGGLE) +#define bfin_write_PORTGIO_MASKB_TOGGLE(val) bfin_write16(PORTGIO_MASKB_TOGGLE,val) +#define bfin_read_PORTGIO_DIR() bfin_read16(PORTGIO_DIR) +#define bfin_write_PORTGIO_DIR(val) bfin_write16(PORTGIO_DIR,val) +#define bfin_read_PORTGIO_POLAR() bfin_read16(PORTGIO_POLAR) +#define bfin_write_PORTGIO_POLAR(val) bfin_write16(PORTGIO_POLAR,val) +#define bfin_read_PORTGIO_EDGE() bfin_read16(PORTGIO_EDGE) +#define bfin_write_PORTGIO_EDGE(val) bfin_write16(PORTGIO_EDGE,val) +#define bfin_read_PORTGIO_BOTH() bfin_read16(PORTGIO_BOTH) +#define bfin_write_PORTGIO_BOTH(val) bfin_write16(PORTGIO_BOTH,val) +#define bfin_read_PORTGIO_INEN() bfin_read16(PORTGIO_INEN) +#define bfin_write_PORTGIO_INEN(val) bfin_write16(PORTGIO_INEN,val) + +/* General Purpose I/O Port H (0xFFC01700 - 0xFFC017FF) */ +#define bfin_read_PORTHIO() bfin_read16(PORTHIO) +#define bfin_write_PORTHIO(val) bfin_write16(PORTHIO,val) +#define bfin_read_PORTHIO_CLEAR() bfin_read16(PORTHIO_CLEAR) +#define bfin_write_PORTHIO_CLEAR(val) bfin_write16(PORTHIO_CLEAR,val) +#define bfin_read_PORTHIO_SET() bfin_read16(PORTHIO_SET) +#define bfin_write_PORTHIO_SET(val) bfin_write16(PORTHIO_SET,val) +#define bfin_read_PORTHIO_TOGGLE() bfin_read16(PORTHIO_TOGGLE) +#define bfin_write_PORTHIO_TOGGLE(val) bfin_write16(PORTHIO_TOGGLE,val) +#define bfin_read_PORTHIO_MASKA() bfin_read16(PORTHIO_MASKA) +#define bfin_write_PORTHIO_MASKA(val) bfin_write16(PORTHIO_MASKA,val) +#define bfin_read_PORTHIO_MASKA_CLEAR() bfin_read16(PORTHIO_MASKA_CLEAR) +#define bfin_write_PORTHIO_MASKA_CLEAR(val) bfin_write16(PORTHIO_MASKA_CLEAR,val) +#define bfin_read_PORTHIO_MASKA_SET() bfin_read16(PORTHIO_MASKA_SET) +#define bfin_write_PORTHIO_MASKA_SET(val) bfin_write16(PORTHIO_MASKA_SET,val) +#define bfin_read_PORTHIO_MASKA_TOGGLE() bfin_read16(PORTHIO_MASKA_TOGGLE) +#define bfin_write_PORTHIO_MASKA_TOGGLE(val) bfin_write16(PORTHIO_MASKA_TOGGLE,val) +#define bfin_read_PORTHIO_MASKB() bfin_read16(PORTHIO_MASKB) +#define bfin_write_PORTHIO_MASKB(val) bfin_write16(PORTHIO_MASKB,val) +#define bfin_read_PORTHIO_MASKB_CLEAR() bfin_read16(PORTHIO_MASKB_CLEAR) +#define bfin_write_PORTHIO_MASKB_CLEAR(val) bfin_write16(PORTHIO_MASKB_CLEAR,val) +#define bfin_read_PORTHIO_MASKB_SET() bfin_read16(PORTHIO_MASKB_SET) +#define bfin_write_PORTHIO_MASKB_SET(val) bfin_write16(PORTHIO_MASKB_SET,val) +#define bfin_read_PORTHIO_MASKB_TOGGLE() bfin_read16(PORTHIO_MASKB_TOGGLE) +#define bfin_write_PORTHIO_MASKB_TOGGLE(val) bfin_write16(PORTHIO_MASKB_TOGGLE,val) +#define bfin_read_PORTHIO_DIR() bfin_read16(PORTHIO_DIR) +#define bfin_write_PORTHIO_DIR(val) bfin_write16(PORTHIO_DIR,val) +#define bfin_read_PORTHIO_POLAR() bfin_read16(PORTHIO_POLAR) +#define bfin_write_PORTHIO_POLAR(val) bfin_write16(PORTHIO_POLAR,val) +#define bfin_read_PORTHIO_EDGE() bfin_read16(PORTHIO_EDGE) +#define bfin_write_PORTHIO_EDGE(val) bfin_write16(PORTHIO_EDGE,val) +#define bfin_read_PORTHIO_BOTH() bfin_read16(PORTHIO_BOTH) +#define bfin_write_PORTHIO_BOTH(val) bfin_write16(PORTHIO_BOTH,val) +#define bfin_read_PORTHIO_INEN() bfin_read16(PORTHIO_INEN) +#define bfin_write_PORTHIO_INEN(val) bfin_write16(PORTHIO_INEN,val) + +/* UART1 Controller (0xFFC02000 - 0xFFC020FF) */ +#define bfin_read_UART1_THR() bfin_read16(UART1_THR) +#define bfin_write_UART1_THR(val) bfin_write16(UART1_THR,val) +#define bfin_read_UART1_RBR() bfin_read16(UART1_RBR) +#define bfin_write_UART1_RBR(val) bfin_write16(UART1_RBR,val) +#define bfin_read_UART1_DLL() bfin_read16(UART1_DLL) +#define bfin_write_UART1_DLL(val) bfin_write16(UART1_DLL,val) +#define bfin_read_UART1_IER() bfin_read16(UART1_IER) +#define bfin_write_UART1_IER(val) bfin_write16(UART1_IER,val) +#define bfin_read_UART1_DLH() bfin_read16(UART1_DLH) +#define bfin_write_UART1_DLH(val) bfin_write16(UART1_DLH,val) +#define bfin_read_UART1_IIR() bfin_read16(UART1_IIR) +#define bfin_write_UART1_IIR(val) bfin_write16(UART1_IIR,val) +#define bfin_read_UART1_LCR() bfin_read16(UART1_LCR) +#define bfin_write_UART1_LCR(val) bfin_write16(UART1_LCR,val) +#define bfin_read_UART1_MCR() bfin_read16(UART1_MCR) +#define bfin_write_UART1_MCR(val) bfin_write16(UART1_MCR,val) +#define bfin_read_UART1_LSR() bfin_read16(UART1_LSR) +#define bfin_write_UART1_LSR(val) bfin_write16(UART1_LSR,val) +#define bfin_read_UART1_MSR() bfin_read16(UART1_MSR) +#define bfin_write_UART1_MSR(val) bfin_write16(UART1_MSR,val) +#define bfin_read_UART1_SCR() bfin_read16(UART1_SCR) +#define bfin_write_UART1_SCR(val) bfin_write16(UART1_SCR,val) +#define bfin_read_UART1_GCTL() bfin_read16(UART1_GCTL) +#define bfin_write_UART1_GCTL(val) bfin_write16(UART1_GCTL,val) + +/* CAN Controller (0xFFC02A00 - 0xFFC02FFF) */ +/* For Mailboxes 0-15 */ +#define bfin_read_CAN_MC1() bfin_read16(CAN_MC1) +#define bfin_write_CAN_MC1(val) bfin_write16(CAN_MC1,val) +#define bfin_read_CAN_MD1() bfin_read16(CAN_MD1) +#define bfin_write_CAN_MD1(val) bfin_write16(CAN_MD1,val) +#define bfin_read_CAN_TRS1() bfin_read16(CAN_TRS1) +#define bfin_write_CAN_TRS1(val) bfin_write16(CAN_TRS1,val) +#define bfin_read_CAN_TRR1() bfin_read16(CAN_TRR1) +#define bfin_write_CAN_TRR1(val) bfin_write16(CAN_TRR1,val) +#define bfin_read_CAN_TA1() bfin_read16(CAN_TA1) +#define bfin_write_CAN_TA1(val) bfin_write16(CAN_TA1,val) +#define bfin_read_CAN_AA1() bfin_read16(CAN_AA1) +#define bfin_write_CAN_AA1(val) bfin_write16(CAN_AA1,val) +#define bfin_read_CAN_RMP1() bfin_read16(CAN_RMP1) +#define bfin_write_CAN_RMP1(val) bfin_write16(CAN_RMP1,val) +#define bfin_read_CAN_RML1() bfin_read16(CAN_RML1) +#define bfin_write_CAN_RML1(val) bfin_write16(CAN_RML1,val) +#define bfin_read_CAN_MBTIF1() bfin_read16(CAN_MBTIF1) +#define bfin_write_CAN_MBTIF1(val) bfin_write16(CAN_MBTIF1,val) +#define bfin_read_CAN_MBRIF1() bfin_read16(CAN_MBRIF1) +#define bfin_write_CAN_MBRIF1(val) bfin_write16(CAN_MBRIF1,val) +#define bfin_read_CAN_MBIM1() bfin_read16(CAN_MBIM1) +#define bfin_write_CAN_MBIM1(val) bfin_write16(CAN_MBIM1,val) +#define bfin_read_CAN_RFH1() bfin_read16(CAN_RFH1) +#define bfin_write_CAN_RFH1(val) bfin_write16(CAN_RFH1,val) +#define bfin_read_CAN_OPSS1() bfin_read16(CAN_OPSS1) +#define bfin_write_CAN_OPSS1(val) bfin_write16(CAN_OPSS1,val) + +/* For Mailboxes 16-31 */ +#define bfin_read_CAN_MC2() bfin_read16(CAN_MC2) +#define bfin_write_CAN_MC2(val) bfin_write16(CAN_MC2,val) +#define bfin_read_CAN_MD2() bfin_read16(CAN_MD2) +#define bfin_write_CAN_MD2(val) bfin_write16(CAN_MD2,val) +#define bfin_read_CAN_TRS2() bfin_read16(CAN_TRS2) +#define bfin_write_CAN_TRS2(val) bfin_write16(CAN_TRS2,val) +#define bfin_read_CAN_TRR2() bfin_read16(CAN_TRR2) +#define bfin_write_CAN_TRR2(val) bfin_write16(CAN_TRR2,val) +#define bfin_read_CAN_TA2() bfin_read16(CAN_TA2) +#define bfin_write_CAN_TA2(val) bfin_write16(CAN_TA2,val) +#define bfin_read_CAN_AA2() bfin_read16(CAN_AA2) +#define bfin_write_CAN_AA2(val) bfin_write16(CAN_AA2,val) +#define bfin_read_CAN_RMP2() bfin_read16(CAN_RMP2) +#define bfin_write_CAN_RMP2(val) bfin_write16(CAN_RMP2,val) +#define bfin_read_CAN_RML2() bfin_read16(CAN_RML2) +#define bfin_write_CAN_RML2(val) bfin_write16(CAN_RML2,val) +#define bfin_read_CAN_MBTIF2() bfin_read16(CAN_MBTIF2) +#define bfin_write_CAN_MBTIF2(val) bfin_write16(CAN_MBTIF2,val) +#define bfin_read_CAN_MBRIF2() bfin_read16(CAN_MBRIF2) +#define bfin_write_CAN_MBRIF2(val) bfin_write16(CAN_MBRIF2,val) +#define bfin_read_CAN_MBIM2() bfin_read16(CAN_MBIM2) +#define bfin_write_CAN_MBIM2(val) bfin_write16(CAN_MBIM2,val) +#define bfin_read_CAN_RFH2() bfin_read16(CAN_RFH2) +#define bfin_write_CAN_RFH2(val) bfin_write16(CAN_RFH2,val) +#define bfin_read_CAN_OPSS2() bfin_read16(CAN_OPSS2) +#define bfin_write_CAN_OPSS2(val) bfin_write16(CAN_OPSS2,val) + +#define bfin_read_CAN_CLOCK() bfin_read16(CAN_CLOCK) +#define bfin_write_CAN_CLOCK(val) bfin_write16(CAN_CLOCK,val) +#define bfin_read_CAN_TIMING() bfin_read16(CAN_TIMING) +#define bfin_write_CAN_TIMING(val) bfin_write16(CAN_TIMING,val) +#define bfin_read_CAN_DEBUG() bfin_read16(CAN_DEBUG) +#define bfin_write_CAN_DEBUG(val) bfin_write16(CAN_DEBUG,val) +#define bfin_read_CAN_STATUS() bfin_read16(CAN_STATUS) +#define bfin_write_CAN_STATUS(val) bfin_write16(CAN_STATUS,val) +#define bfin_read_CAN_CEC() bfin_read16(CAN_CEC) +#define bfin_write_CAN_CEC(val) bfin_write16(CAN_CEC,val) +#define bfin_read_CAN_GIS() bfin_read16(CAN_GIS) +#define bfin_write_CAN_GIS(val) bfin_write16(CAN_GIS,val) +#define bfin_read_CAN_GIM() bfin_read16(CAN_GIM) +#define bfin_write_CAN_GIM(val) bfin_write16(CAN_GIM,val) +#define bfin_read_CAN_GIF() bfin_read16(CAN_GIF) +#define bfin_write_CAN_GIF(val) bfin_write16(CAN_GIF,val) +#define bfin_read_CAN_CONTROL() bfin_read16(CAN_CONTROL) +#define bfin_write_CAN_CONTROL(val) bfin_write16(CAN_CONTROL,val) +#define bfin_read_CAN_INTR() bfin_read16(CAN_INTR) +#define bfin_write_CAN_INTR(val) bfin_write16(CAN_INTR,val) +#define bfin_read_CAN_SFCMVER() bfin_read16(CAN_SFCMVER) +#define bfin_write_CAN_SFCMVER(val) bfin_write16(CAN_SFCMVER,val) +#define bfin_read_CAN_MBTD() bfin_read16(CAN_MBTD) +#define bfin_write_CAN_MBTD(val) bfin_write16(CAN_MBTD,val) +#define bfin_read_CAN_EWR() bfin_read16(CAN_EWR) +#define bfin_write_CAN_EWR(val) bfin_write16(CAN_EWR,val) +#define bfin_read_CAN_ESR() bfin_read16(CAN_ESR) +#define bfin_write_CAN_ESR(val) bfin_write16(CAN_ESR,val) +#define bfin_read_CAN_UCREG() bfin_read16(CAN_UCREG) +#define bfin_write_CAN_UCREG(val) bfin_write16(CAN_UCREG,val) +#define bfin_read_CAN_UCCNT() bfin_read16(CAN_UCCNT) +#define bfin_write_CAN_UCCNT(val) bfin_write16(CAN_UCCNT,val) +#define bfin_read_CAN_UCRC() bfin_read16(CAN_UCRC) +#define bfin_write_CAN_UCRC(val) bfin_write16(CAN_UCRC,val) +#define bfin_read_CAN_UCCNF() bfin_read16(CAN_UCCNF) +#define bfin_write_CAN_UCCNF(val) bfin_write16(CAN_UCCNF,val) +#define bfin_read_CAN_SFCMVER2() bfin_read16(CAN_SFCMVER2) +#define bfin_write_CAN_SFCMVER2(val) bfin_write16(CAN_SFCMVER2,val) + +/* Mailbox Acceptance Masks */ +#define bfin_read_CAN_AM00L() bfin_read16(CAN_AM00L) +#define bfin_write_CAN_AM00L(val) bfin_write16(CAN_AM00L,val) +#define bfin_read_CAN_AM00H() bfin_read16(CAN_AM00H) +#define bfin_write_CAN_AM00H(val) bfin_write16(CAN_AM00H,val) +#define bfin_read_CAN_AM01L() bfin_read16(CAN_AM01L) +#define bfin_write_CAN_AM01L(val) bfin_write16(CAN_AM01L,val) +#define bfin_read_CAN_AM01H() bfin_read16(CAN_AM01H) +#define bfin_write_CAN_AM01H(val) bfin_write16(CAN_AM01H,val) +#define bfin_read_CAN_AM02L() bfin_read16(CAN_AM02L) +#define bfin_write_CAN_AM02L(val) bfin_write16(CAN_AM02L,val) +#define bfin_read_CAN_AM02H() bfin_read16(CAN_AM02H) +#define bfin_write_CAN_AM02H(val) bfin_write16(CAN_AM02H,val) +#define bfin_read_CAN_AM03L() bfin_read16(CAN_AM03L) +#define bfin_write_CAN_AM03L(val) bfin_write16(CAN_AM03L,val) +#define bfin_read_CAN_AM03H() bfin_read16(CAN_AM03H) +#define bfin_write_CAN_AM03H(val) bfin_write16(CAN_AM03H,val) +#define bfin_read_CAN_AM04L() bfin_read16(CAN_AM04L) +#define bfin_write_CAN_AM04L(val) bfin_write16(CAN_AM04L,val) +#define bfin_read_CAN_AM04H() bfin_read16(CAN_AM04H) +#define bfin_write_CAN_AM04H(val) bfin_write16(CAN_AM04H,val) +#define bfin_read_CAN_AM05L() bfin_read16(CAN_AM05L) +#define bfin_write_CAN_AM05L(val) bfin_write16(CAN_AM05L,val) +#define bfin_read_CAN_AM05H() bfin_read16(CAN_AM05H) +#define bfin_write_CAN_AM05H(val) bfin_write16(CAN_AM05H,val) +#define bfin_read_CAN_AM06L() bfin_read16(CAN_AM06L) +#define bfin_write_CAN_AM06L(val) bfin_write16(CAN_AM06L,val) +#define bfin_read_CAN_AM06H() bfin_read16(CAN_AM06H) +#define bfin_write_CAN_AM06H(val) bfin_write16(CAN_AM06H,val) +#define bfin_read_CAN_AM07L() bfin_read16(CAN_AM07L) +#define bfin_write_CAN_AM07L(val) bfin_write16(CAN_AM07L,val) +#define bfin_read_CAN_AM07H() bfin_read16(CAN_AM07H) +#define bfin_write_CAN_AM07H(val) bfin_write16(CAN_AM07H,val) +#define bfin_read_CAN_AM08L() bfin_read16(CAN_AM08L) +#define bfin_write_CAN_AM08L(val) bfin_write16(CAN_AM08L,val) +#define bfin_read_CAN_AM08H() bfin_read16(CAN_AM08H) +#define bfin_write_CAN_AM08H(val) bfin_write16(CAN_AM08H,val) +#define bfin_read_CAN_AM09L() bfin_read16(CAN_AM09L) +#define bfin_write_CAN_AM09L(val) bfin_write16(CAN_AM09L,val) +#define bfin_read_CAN_AM09H() bfin_read16(CAN_AM09H) +#define bfin_write_CAN_AM09H(val) bfin_write16(CAN_AM09H,val) +#define bfin_read_CAN_AM10L() bfin_read16(CAN_AM10L) +#define bfin_write_CAN_AM10L(val) bfin_write16(CAN_AM10L,val) +#define bfin_read_CAN_AM10H() bfin_read16(CAN_AM10H) +#define bfin_write_CAN_AM10H(val) bfin_write16(CAN_AM10H,val) +#define bfin_read_CAN_AM11L() bfin_read16(CAN_AM11L) +#define bfin_write_CAN_AM11L(val) bfin_write16(CAN_AM11L,val) +#define bfin_read_CAN_AM11H() bfin_read16(CAN_AM11H) +#define bfin_write_CAN_AM11H(val) bfin_write16(CAN_AM11H,val) +#define bfin_read_CAN_AM12L() bfin_read16(CAN_AM12L) +#define bfin_write_CAN_AM12L(val) bfin_write16(CAN_AM12L,val) +#define bfin_read_CAN_AM12H() bfin_read16(CAN_AM12H) +#define bfin_write_CAN_AM12H(val) bfin_write16(CAN_AM12H,val) +#define bfin_read_CAN_AM13L() bfin_read16(CAN_AM13L) +#define bfin_write_CAN_AM13L(val) bfin_write16(CAN_AM13L,val) +#define bfin_read_CAN_AM13H() bfin_read16(CAN_AM13H) +#define bfin_write_CAN_AM13H(val) bfin_write16(CAN_AM13H,val) +#define bfin_read_CAN_AM14L() bfin_read16(CAN_AM14L) +#define bfin_write_CAN_AM14L(val) bfin_write16(CAN_AM14L,val) +#define bfin_read_CAN_AM14H() bfin_read16(CAN_AM14H) +#define bfin_write_CAN_AM14H(val) bfin_write16(CAN_AM14H,val) +#define bfin_read_CAN_AM15L() bfin_read16(CAN_AM15L) +#define bfin_write_CAN_AM15L(val) bfin_write16(CAN_AM15L,val) +#define bfin_read_CAN_AM15H() bfin_read16(CAN_AM15H) +#define bfin_write_CAN_AM15H(val) bfin_write16(CAN_AM15H,val) + +#define bfin_read_CAN_AM16L() bfin_read16(CAN_AM16L) +#define bfin_write_CAN_AM16L(val) bfin_write16(CAN_AM16L,val) +#define bfin_read_CAN_AM16H() bfin_read16(CAN_AM16H) +#define bfin_write_CAN_AM16H(val) bfin_write16(CAN_AM16H,val) +#define bfin_read_CAN_AM17L() bfin_read16(CAN_AM17L) +#define bfin_write_CAN_AM17L(val) bfin_write16(CAN_AM17L,val) +#define bfin_read_CAN_AM17H() bfin_read16(CAN_AM17H) +#define bfin_write_CAN_AM17H(val) bfin_write16(CAN_AM17H,val) +#define bfin_read_CAN_AM18L() bfin_read16(CAN_AM18L) +#define bfin_write_CAN_AM18L(val) bfin_write16(CAN_AM18L,val) +#define bfin_read_CAN_AM18H() bfin_read16(CAN_AM18H) +#define bfin_write_CAN_AM18H(val) bfin_write16(CAN_AM18H,val) +#define bfin_read_CAN_AM19L() bfin_read16(CAN_AM19L) +#define bfin_write_CAN_AM19L(val) bfin_write16(CAN_AM19L,val) +#define bfin_read_CAN_AM19H() bfin_read16(CAN_AM19H) +#define bfin_write_CAN_AM19H(val) bfin_write16(CAN_AM19H,val) +#define bfin_read_CAN_AM20L() bfin_read16(CAN_AM20L) +#define bfin_write_CAN_AM20L(val) bfin_write16(CAN_AM20L,val) +#define bfin_read_CAN_AM20H() bfin_read16(CAN_AM20H) +#define bfin_write_CAN_AM20H(val) bfin_write16(CAN_AM20H,val) +#define bfin_read_CAN_AM21L() bfin_read16(CAN_AM21L) +#define bfin_write_CAN_AM21L(val) bfin_write16(CAN_AM21L,val) +#define bfin_read_CAN_AM21H() bfin_read16(CAN_AM21H) +#define bfin_write_CAN_AM21H(val) bfin_write16(CAN_AM21H,val) +#define bfin_read_CAN_AM22L() bfin_read16(CAN_AM22L) +#define bfin_write_CAN_AM22L(val) bfin_write16(CAN_AM22L,val) +#define bfin_read_CAN_AM22H() bfin_read16(CAN_AM22H) +#define bfin_write_CAN_AM22H(val) bfin_write16(CAN_AM22H,val) +#define bfin_read_CAN_AM23L() bfin_read16(CAN_AM23L) +#define bfin_write_CAN_AM23L(val) bfin_write16(CAN_AM23L,val) +#define bfin_read_CAN_AM23H() bfin_read16(CAN_AM23H) +#define bfin_write_CAN_AM23H(val) bfin_write16(CAN_AM23H,val) +#define bfin_read_CAN_AM24L() bfin_read16(CAN_AM24L) +#define bfin_write_CAN_AM24L(val) bfin_write16(CAN_AM24L,val) +#define bfin_read_CAN_AM24H() bfin_read16(CAN_AM24H) +#define bfin_write_CAN_AM24H(val) bfin_write16(CAN_AM24H,val) +#define bfin_read_CAN_AM25L() bfin_read16(CAN_AM25L) +#define bfin_write_CAN_AM25L(val) bfin_write16(CAN_AM25L,val) +#define bfin_read_CAN_AM25H() bfin_read16(CAN_AM25H) +#define bfin_write_CAN_AM25H(val) bfin_write16(CAN_AM25H,val) +#define bfin_read_CAN_AM26L() bfin_read16(CAN_AM26L) +#define bfin_write_CAN_AM26L(val) bfin_write16(CAN_AM26L,val) +#define bfin_read_CAN_AM26H() bfin_read16(CAN_AM26H) +#define bfin_write_CAN_AM26H(val) bfin_write16(CAN_AM26H,val) +#define bfin_read_CAN_AM27L() bfin_read16(CAN_AM27L) +#define bfin_write_CAN_AM27L(val) bfin_write16(CAN_AM27L,val) +#define bfin_read_CAN_AM27H() bfin_read16(CAN_AM27H) +#define bfin_write_CAN_AM27H(val) bfin_write16(CAN_AM27H,val) +#define bfin_read_CAN_AM28L() bfin_read16(CAN_AM28L) +#define bfin_write_CAN_AM28L(val) bfin_write16(CAN_AM28L,val) +#define bfin_read_CAN_AM28H() bfin_read16(CAN_AM28H) +#define bfin_write_CAN_AM28H(val) bfin_write16(CAN_AM28H,val) +#define bfin_read_CAN_AM29L() bfin_read16(CAN_AM29L) +#define bfin_write_CAN_AM29L(val) bfin_write16(CAN_AM29L,val) +#define bfin_read_CAN_AM29H() bfin_read16(CAN_AM29H) +#define bfin_write_CAN_AM29H(val) bfin_write16(CAN_AM29H,val) +#define bfin_read_CAN_AM30L() bfin_read16(CAN_AM30L) +#define bfin_write_CAN_AM30L(val) bfin_write16(CAN_AM30L,val) +#define bfin_read_CAN_AM30H() bfin_read16(CAN_AM30H) +#define bfin_write_CAN_AM30H(val) bfin_write16(CAN_AM30H,val) +#define bfin_read_CAN_AM31L() bfin_read16(CAN_AM31L) +#define bfin_write_CAN_AM31L(val) bfin_write16(CAN_AM31L,val) +#define bfin_read_CAN_AM31H() bfin_read16(CAN_AM31H) +#define bfin_write_CAN_AM31H(val) bfin_write16(CAN_AM31H,val) + +/* CAN Acceptance Mask Area Macros */ +#define bfin_read_CAN_AM_L(x)() bfin_read16(CAN_AM_L(x)) +#define bfin_write_CAN_AM_L(x)(val) bfin_write16(CAN_AM_L(x),val) +#define bfin_read_CAN_AM_H(x)() bfin_read16(CAN_AM_H(x)) +#define bfin_write_CAN_AM_H(x)(val) bfin_write16(CAN_AM_H(x),val) + +/* Mailbox Registers */ +#define bfin_read_CAN_MB00_ID1() bfin_read16(CAN_MB00_ID1) +#define bfin_write_CAN_MB00_ID1(val) bfin_write16(CAN_MB00_ID1,val) +#define bfin_read_CAN_MB00_ID0() bfin_read16(CAN_MB00_ID0) +#define bfin_write_CAN_MB00_ID0(val) bfin_write16(CAN_MB00_ID0,val) +#define bfin_read_CAN_MB00_TIMESTAMP() bfin_read16(CAN_MB00_TIMESTAMP) +#define bfin_write_CAN_MB00_TIMESTAMP(val) bfin_write16(CAN_MB00_TIMESTAMP,val) +#define bfin_read_CAN_MB00_LENGTH() bfin_read16(CAN_MB00_LENGTH) +#define bfin_write_CAN_MB00_LENGTH(val) bfin_write16(CAN_MB00_LENGTH,val) +#define bfin_read_CAN_MB00_DATA3() bfin_read16(CAN_MB00_DATA3) +#define bfin_write_CAN_MB00_DATA3(val) bfin_write16(CAN_MB00_DATA3,val) +#define bfin_read_CAN_MB00_DATA2() bfin_read16(CAN_MB00_DATA2) +#define bfin_write_CAN_MB00_DATA2(val) bfin_write16(CAN_MB00_DATA2,val) +#define bfin_read_CAN_MB00_DATA1() bfin_read16(CAN_MB00_DATA1) +#define bfin_write_CAN_MB00_DATA1(val) bfin_write16(CAN_MB00_DATA1,val) +#define bfin_read_CAN_MB00_DATA0() bfin_read16(CAN_MB00_DATA0) +#define bfin_write_CAN_MB00_DATA0(val) bfin_write16(CAN_MB00_DATA0,val) + +#define bfin_read_CAN_MB01_ID1() bfin_read16(CAN_MB01_ID1) +#define bfin_write_CAN_MB01_ID1(val) bfin_write16(CAN_MB01_ID1,val) +#define bfin_read_CAN_MB01_ID0() bfin_read16(CAN_MB01_ID0) +#define bfin_write_CAN_MB01_ID0(val) bfin_write16(CAN_MB01_ID0,val) +#define bfin_read_CAN_MB01_TIMESTAMP() bfin_read16(CAN_MB01_TIMESTAMP) +#define bfin_write_CAN_MB01_TIMESTAMP(val) bfin_write16(CAN_MB01_TIMESTAMP,val) +#define bfin_read_CAN_MB01_LENGTH() bfin_read16(CAN_MB01_LENGTH) +#define bfin_write_CAN_MB01_LENGTH(val) bfin_write16(CAN_MB01_LENGTH,val) +#define bfin_read_CAN_MB01_DATA3() bfin_read16(CAN_MB01_DATA3) +#define bfin_write_CAN_MB01_DATA3(val) bfin_write16(CAN_MB01_DATA3,val) +#define bfin_read_CAN_MB01_DATA2() bfin_read16(CAN_MB01_DATA2) +#define bfin_write_CAN_MB01_DATA2(val) bfin_write16(CAN_MB01_DATA2,val) +#define bfin_read_CAN_MB01_DATA1() bfin_read16(CAN_MB01_DATA1) +#define bfin_write_CAN_MB01_DATA1(val) bfin_write16(CAN_MB01_DATA1,val) +#define bfin_read_CAN_MB01_DATA0() bfin_read16(CAN_MB01_DATA0) +#define bfin_write_CAN_MB01_DATA0(val) bfin_write16(CAN_MB01_DATA0,val) + +#define bfin_read_CAN_MB02_ID1() bfin_read16(CAN_MB02_ID1) +#define bfin_write_CAN_MB02_ID1(val) bfin_write16(CAN_MB02_ID1,val) +#define bfin_read_CAN_MB02_ID0() bfin_read16(CAN_MB02_ID0) +#define bfin_write_CAN_MB02_ID0(val) bfin_write16(CAN_MB02_ID0,val) +#define bfin_read_CAN_MB02_TIMESTAMP() bfin_read16(CAN_MB02_TIMESTAMP) +#define bfin_write_CAN_MB02_TIMESTAMP(val) bfin_write16(CAN_MB02_TIMESTAMP,val) +#define bfin_read_CAN_MB02_LENGTH() bfin_read16(CAN_MB02_LENGTH) +#define bfin_write_CAN_MB02_LENGTH(val) bfin_write16(CAN_MB02_LENGTH,val) +#define bfin_read_CAN_MB02_DATA3() bfin_read16(CAN_MB02_DATA3) +#define bfin_write_CAN_MB02_DATA3(val) bfin_write16(CAN_MB02_DATA3,val) +#define bfin_read_CAN_MB02_DATA2() bfin_read16(CAN_MB02_DATA2) +#define bfin_write_CAN_MB02_DATA2(val) bfin_write16(CAN_MB02_DATA2,val) +#define bfin_read_CAN_MB02_DATA1() bfin_read16(CAN_MB02_DATA1) +#define bfin_write_CAN_MB02_DATA1(val) bfin_write16(CAN_MB02_DATA1,val) +#define bfin_read_CAN_MB02_DATA0() bfin_read16(CAN_MB02_DATA0) +#define bfin_write_CAN_MB02_DATA0(val) bfin_write16(CAN_MB02_DATA0,val) + +#define bfin_read_CAN_MB03_ID1() bfin_read16(CAN_MB03_ID1) +#define bfin_write_CAN_MB03_ID1(val) bfin_write16(CAN_MB03_ID1,val) +#define bfin_read_CAN_MB03_ID0() bfin_read16(CAN_MB03_ID0) +#define bfin_write_CAN_MB03_ID0(val) bfin_write16(CAN_MB03_ID0,val) +#define bfin_read_CAN_MB03_TIMESTAMP() bfin_read16(CAN_MB03_TIMESTAMP) +#define bfin_write_CAN_MB03_TIMESTAMP(val) bfin_write16(CAN_MB03_TIMESTAMP,val) +#define bfin_read_CAN_MB03_LENGTH() bfin_read16(CAN_MB03_LENGTH) +#define bfin_write_CAN_MB03_LENGTH(val) bfin_write16(CAN_MB03_LENGTH,val) +#define bfin_read_CAN_MB03_DATA3() bfin_read16(CAN_MB03_DATA3) +#define bfin_write_CAN_MB03_DATA3(val) bfin_write16(CAN_MB03_DATA3,val) +#define bfin_read_CAN_MB03_DATA2() bfin_read16(CAN_MB03_DATA2) +#define bfin_write_CAN_MB03_DATA2(val) bfin_write16(CAN_MB03_DATA2,val) +#define bfin_read_CAN_MB03_DATA1() bfin_read16(CAN_MB03_DATA1) +#define bfin_write_CAN_MB03_DATA1(val) bfin_write16(CAN_MB03_DATA1,val) +#define bfin_read_CAN_MB03_DATA0() bfin_read16(CAN_MB03_DATA0) +#define bfin_write_CAN_MB03_DATA0(val) bfin_write16(CAN_MB03_DATA0,val) + +#define bfin_read_CAN_MB04_ID1() bfin_read16(CAN_MB04_ID1) +#define bfin_write_CAN_MB04_ID1(val) bfin_write16(CAN_MB04_ID1,val) +#define bfin_read_CAN_MB04_ID0() bfin_read16(CAN_MB04_ID0) +#define bfin_write_CAN_MB04_ID0(val) bfin_write16(CAN_MB04_ID0,val) +#define bfin_read_CAN_MB04_TIMESTAMP() bfin_read16(CAN_MB04_TIMESTAMP) +#define bfin_write_CAN_MB04_TIMESTAMP(val) bfin_write16(CAN_MB04_TIMESTAMP,val) +#define bfin_read_CAN_MB04_LENGTH() bfin_read16(CAN_MB04_LENGTH) +#define bfin_write_CAN_MB04_LENGTH(val) bfin_write16(CAN_MB04_LENGTH,val) +#define bfin_read_CAN_MB04_DATA3() bfin_read16(CAN_MB04_DATA3) +#define bfin_write_CAN_MB04_DATA3(val) bfin_write16(CAN_MB04_DATA3,val) +#define bfin_read_CAN_MB04_DATA2() bfin_read16(CAN_MB04_DATA2) +#define bfin_write_CAN_MB04_DATA2(val) bfin_write16(CAN_MB04_DATA2,val) +#define bfin_read_CAN_MB04_DATA1() bfin_read16(CAN_MB04_DATA1) +#define bfin_write_CAN_MB04_DATA1(val) bfin_write16(CAN_MB04_DATA1,val) +#define bfin_read_CAN_MB04_DATA0() bfin_read16(CAN_MB04_DATA0) +#define bfin_write_CAN_MB04_DATA0(val) bfin_write16(CAN_MB04_DATA0,val) + +#define bfin_read_CAN_MB05_ID1() bfin_read16(CAN_MB05_ID1) +#define bfin_write_CAN_MB05_ID1(val) bfin_write16(CAN_MB05_ID1,val) +#define bfin_read_CAN_MB05_ID0() bfin_read16(CAN_MB05_ID0) +#define bfin_write_CAN_MB05_ID0(val) bfin_write16(CAN_MB05_ID0,val) +#define bfin_read_CAN_MB05_TIMESTAMP() bfin_read16(CAN_MB05_TIMESTAMP) +#define bfin_write_CAN_MB05_TIMESTAMP(val) bfin_write16(CAN_MB05_TIMESTAMP,val) +#define bfin_read_CAN_MB05_LENGTH() bfin_read16(CAN_MB05_LENGTH) +#define bfin_write_CAN_MB05_LENGTH(val) bfin_write16(CAN_MB05_LENGTH,val) +#define bfin_read_CAN_MB05_DATA3() bfin_read16(CAN_MB05_DATA3) +#define bfin_write_CAN_MB05_DATA3(val) bfin_write16(CAN_MB05_DATA3,val) +#define bfin_read_CAN_MB05_DATA2() bfin_read16(CAN_MB05_DATA2) +#define bfin_write_CAN_MB05_DATA2(val) bfin_write16(CAN_MB05_DATA2,val) +#define bfin_read_CAN_MB05_DATA1() bfin_read16(CAN_MB05_DATA1) +#define bfin_write_CAN_MB05_DATA1(val) bfin_write16(CAN_MB05_DATA1,val) +#define bfin_read_CAN_MB05_DATA0() bfin_read16(CAN_MB05_DATA0) +#define bfin_write_CAN_MB05_DATA0(val) bfin_write16(CAN_MB05_DATA0,val) + +#define bfin_read_CAN_MB06_ID1() bfin_read16(CAN_MB06_ID1) +#define bfin_write_CAN_MB06_ID1(val) bfin_write16(CAN_MB06_ID1,val) +#define bfin_read_CAN_MB06_ID0() bfin_read16(CAN_MB06_ID0) +#define bfin_write_CAN_MB06_ID0(val) bfin_write16(CAN_MB06_ID0,val) +#define bfin_read_CAN_MB06_TIMESTAMP() bfin_read16(CAN_MB06_TIMESTAMP) +#define bfin_write_CAN_MB06_TIMESTAMP(val) bfin_write16(CAN_MB06_TIMESTAMP,val) +#define bfin_read_CAN_MB06_LENGTH() bfin_read16(CAN_MB06_LENGTH) +#define bfin_write_CAN_MB06_LENGTH(val) bfin_write16(CAN_MB06_LENGTH,val) +#define bfin_read_CAN_MB06_DATA3() bfin_read16(CAN_MB06_DATA3) +#define bfin_write_CAN_MB06_DATA3(val) bfin_write16(CAN_MB06_DATA3,val) +#define bfin_read_CAN_MB06_DATA2() bfin_read16(CAN_MB06_DATA2) +#define bfin_write_CAN_MB06_DATA2(val) bfin_write16(CAN_MB06_DATA2,val) +#define bfin_read_CAN_MB06_DATA1() bfin_read16(CAN_MB06_DATA1) +#define bfin_write_CAN_MB06_DATA1(val) bfin_write16(CAN_MB06_DATA1,val) +#define bfin_read_CAN_MB06_DATA0() bfin_read16(CAN_MB06_DATA0) +#define bfin_write_CAN_MB06_DATA0(val) bfin_write16(CAN_MB06_DATA0,val) + +#define bfin_read_CAN_MB07_ID1() bfin_read16(CAN_MB07_ID1) +#define bfin_write_CAN_MB07_ID1(val) bfin_write16(CAN_MB07_ID1,val) +#define bfin_read_CAN_MB07_ID0() bfin_read16(CAN_MB07_ID0) +#define bfin_write_CAN_MB07_ID0(val) bfin_write16(CAN_MB07_ID0,val) +#define bfin_read_CAN_MB07_TIMESTAMP() bfin_read16(CAN_MB07_TIMESTAMP) +#define bfin_write_CAN_MB07_TIMESTAMP(val) bfin_write16(CAN_MB07_TIMESTAMP,val) +#define bfin_read_CAN_MB07_LENGTH() bfin_read16(CAN_MB07_LENGTH) +#define bfin_write_CAN_MB07_LENGTH(val) bfin_write16(CAN_MB07_LENGTH,val) +#define bfin_read_CAN_MB07_DATA3() bfin_read16(CAN_MB07_DATA3) +#define bfin_write_CAN_MB07_DATA3(val) bfin_write16(CAN_MB07_DATA3,val) +#define bfin_read_CAN_MB07_DATA2() bfin_read16(CAN_MB07_DATA2) +#define bfin_write_CAN_MB07_DATA2(val) bfin_write16(CAN_MB07_DATA2,val) +#define bfin_read_CAN_MB07_DATA1() bfin_read16(CAN_MB07_DATA1) +#define bfin_write_CAN_MB07_DATA1(val) bfin_write16(CAN_MB07_DATA1,val) +#define bfin_read_CAN_MB07_DATA0() bfin_read16(CAN_MB07_DATA0) +#define bfin_write_CAN_MB07_DATA0(val) bfin_write16(CAN_MB07_DATA0,val) + +#define bfin_read_CAN_MB08_ID1() bfin_read16(CAN_MB08_ID1) +#define bfin_write_CAN_MB08_ID1(val) bfin_write16(CAN_MB08_ID1,val) +#define bfin_read_CAN_MB08_ID0() bfin_read16(CAN_MB08_ID0) +#define bfin_write_CAN_MB08_ID0(val) bfin_write16(CAN_MB08_ID0,val) +#define bfin_read_CAN_MB08_TIMESTAMP() bfin_read16(CAN_MB08_TIMESTAMP) +#define bfin_write_CAN_MB08_TIMESTAMP(val) bfin_write16(CAN_MB08_TIMESTAMP,val) +#define bfin_read_CAN_MB08_LENGTH() bfin_read16(CAN_MB08_LENGTH) +#define bfin_write_CAN_MB08_LENGTH(val) bfin_write16(CAN_MB08_LENGTH,val) +#define bfin_read_CAN_MB08_DATA3() bfin_read16(CAN_MB08_DATA3) +#define bfin_write_CAN_MB08_DATA3(val) bfin_write16(CAN_MB08_DATA3,val) +#define bfin_read_CAN_MB08_DATA2() bfin_read16(CAN_MB08_DATA2) +#define bfin_write_CAN_MB08_DATA2(val) bfin_write16(CAN_MB08_DATA2,val) +#define bfin_read_CAN_MB08_DATA1() bfin_read16(CAN_MB08_DATA1) +#define bfin_write_CAN_MB08_DATA1(val) bfin_write16(CAN_MB08_DATA1,val) +#define bfin_read_CAN_MB08_DATA0() bfin_read16(CAN_MB08_DATA0) +#define bfin_write_CAN_MB08_DATA0(val) bfin_write16(CAN_MB08_DATA0,val) + +#define bfin_read_CAN_MB09_ID1() bfin_read16(CAN_MB09_ID1) +#define bfin_write_CAN_MB09_ID1(val) bfin_write16(CAN_MB09_ID1,val) +#define bfin_read_CAN_MB09_ID0() bfin_read16(CAN_MB09_ID0) +#define bfin_write_CAN_MB09_ID0(val) bfin_write16(CAN_MB09_ID0,val) +#define bfin_read_CAN_MB09_TIMESTAMP() bfin_read16(CAN_MB09_TIMESTAMP) +#define bfin_write_CAN_MB09_TIMESTAMP(val) bfin_write16(CAN_MB09_TIMESTAMP,val) +#define bfin_read_CAN_MB09_LENGTH() bfin_read16(CAN_MB09_LENGTH) +#define bfin_write_CAN_MB09_LENGTH(val) bfin_write16(CAN_MB09_LENGTH,val) +#define bfin_read_CAN_MB09_DATA3() bfin_read16(CAN_MB09_DATA3) +#define bfin_write_CAN_MB09_DATA3(val) bfin_write16(CAN_MB09_DATA3,val) +#define bfin_read_CAN_MB09_DATA2() bfin_read16(CAN_MB09_DATA2) +#define bfin_write_CAN_MB09_DATA2(val) bfin_write16(CAN_MB09_DATA2,val) +#define bfin_read_CAN_MB09_DATA1() bfin_read16(CAN_MB09_DATA1) +#define bfin_write_CAN_MB09_DATA1(val) bfin_write16(CAN_MB09_DATA1,val) +#define bfin_read_CAN_MB09_DATA0() bfin_read16(CAN_MB09_DATA0) +#define bfin_write_CAN_MB09_DATA0(val) bfin_write16(CAN_MB09_DATA0,val) + +#define bfin_read_CAN_MB10_ID1() bfin_read16(CAN_MB10_ID1) +#define bfin_write_CAN_MB10_ID1(val) bfin_write16(CAN_MB10_ID1,val) +#define bfin_read_CAN_MB10_ID0() bfin_read16(CAN_MB10_ID0) +#define bfin_write_CAN_MB10_ID0(val) bfin_write16(CAN_MB10_ID0,val) +#define bfin_read_CAN_MB10_TIMESTAMP() bfin_read16(CAN_MB10_TIMESTAMP) +#define bfin_write_CAN_MB10_TIMESTAMP(val) bfin_write16(CAN_MB10_TIMESTAMP,val) +#define bfin_read_CAN_MB10_LENGTH() bfin_read16(CAN_MB10_LENGTH) +#define bfin_write_CAN_MB10_LENGTH(val) bfin_write16(CAN_MB10_LENGTH,val) +#define bfin_read_CAN_MB10_DATA3() bfin_read16(CAN_MB10_DATA3) +#define bfin_write_CAN_MB10_DATA3(val) bfin_write16(CAN_MB10_DATA3,val) +#define bfin_read_CAN_MB10_DATA2() bfin_read16(CAN_MB10_DATA2) +#define bfin_write_CAN_MB10_DATA2(val) bfin_write16(CAN_MB10_DATA2,val) +#define bfin_read_CAN_MB10_DATA1() bfin_read16(CAN_MB10_DATA1) +#define bfin_write_CAN_MB10_DATA1(val) bfin_write16(CAN_MB10_DATA1,val) +#define bfin_read_CAN_MB10_DATA0() bfin_read16(CAN_MB10_DATA0) +#define bfin_write_CAN_MB10_DATA0(val) bfin_write16(CAN_MB10_DATA0,val) + +#define bfin_read_CAN_MB11_ID1() bfin_read16(CAN_MB11_ID1) +#define bfin_write_CAN_MB11_ID1(val) bfin_write16(CAN_MB11_ID1,val) +#define bfin_read_CAN_MB11_ID0() bfin_read16(CAN_MB11_ID0) +#define bfin_write_CAN_MB11_ID0(val) bfin_write16(CAN_MB11_ID0,val) +#define bfin_read_CAN_MB11_TIMESTAMP() bfin_read16(CAN_MB11_TIMESTAMP) +#define bfin_write_CAN_MB11_TIMESTAMP(val) bfin_write16(CAN_MB11_TIMESTAMP,val) +#define bfin_read_CAN_MB11_LENGTH() bfin_read16(CAN_MB11_LENGTH) +#define bfin_write_CAN_MB11_LENGTH(val) bfin_write16(CAN_MB11_LENGTH,val) +#define bfin_read_CAN_MB11_DATA3() bfin_read16(CAN_MB11_DATA3) +#define bfin_write_CAN_MB11_DATA3(val) bfin_write16(CAN_MB11_DATA3,val) +#define bfin_read_CAN_MB11_DATA2() bfin_read16(CAN_MB11_DATA2) +#define bfin_write_CAN_MB11_DATA2(val) bfin_write16(CAN_MB11_DATA2,val) +#define bfin_read_CAN_MB11_DATA1() bfin_read16(CAN_MB11_DATA1) +#define bfin_write_CAN_MB11_DATA1(val) bfin_write16(CAN_MB11_DATA1,val) +#define bfin_read_CAN_MB11_DATA0() bfin_read16(CAN_MB11_DATA0) +#define bfin_write_CAN_MB11_DATA0(val) bfin_write16(CAN_MB11_DATA0,val) + +#define bfin_read_CAN_MB12_ID1() bfin_read16(CAN_MB12_ID1) +#define bfin_write_CAN_MB12_ID1(val) bfin_write16(CAN_MB12_ID1,val) +#define bfin_read_CAN_MB12_ID0() bfin_read16(CAN_MB12_ID0) +#define bfin_write_CAN_MB12_ID0(val) bfin_write16(CAN_MB12_ID0,val) +#define bfin_read_CAN_MB12_TIMESTAMP() bfin_read16(CAN_MB12_TIMESTAMP) +#define bfin_write_CAN_MB12_TIMESTAMP(val) bfin_write16(CAN_MB12_TIMESTAMP,val) +#define bfin_read_CAN_MB12_LENGTH() bfin_read16(CAN_MB12_LENGTH) +#define bfin_write_CAN_MB12_LENGTH(val) bfin_write16(CAN_MB12_LENGTH,val) +#define bfin_read_CAN_MB12_DATA3() bfin_read16(CAN_MB12_DATA3) +#define bfin_write_CAN_MB12_DATA3(val) bfin_write16(CAN_MB12_DATA3,val) +#define bfin_read_CAN_MB12_DATA2() bfin_read16(CAN_MB12_DATA2) +#define bfin_write_CAN_MB12_DATA2(val) bfin_write16(CAN_MB12_DATA2,val) +#define bfin_read_CAN_MB12_DATA1() bfin_read16(CAN_MB12_DATA1) +#define bfin_write_CAN_MB12_DATA1(val) bfin_write16(CAN_MB12_DATA1,val) +#define bfin_read_CAN_MB12_DATA0() bfin_read16(CAN_MB12_DATA0) +#define bfin_write_CAN_MB12_DATA0(val) bfin_write16(CAN_MB12_DATA0,val) + +#define bfin_read_CAN_MB13_ID1() bfin_read16(CAN_MB13_ID1) +#define bfin_write_CAN_MB13_ID1(val) bfin_write16(CAN_MB13_ID1,val) +#define bfin_read_CAN_MB13_ID0() bfin_read16(CAN_MB13_ID0) +#define bfin_write_CAN_MB13_ID0(val) bfin_write16(CAN_MB13_ID0,val) +#define bfin_read_CAN_MB13_TIMESTAMP() bfin_read16(CAN_MB13_TIMESTAMP) +#define bfin_write_CAN_MB13_TIMESTAMP(val) bfin_write16(CAN_MB13_TIMESTAMP,val) +#define bfin_read_CAN_MB13_LENGTH() bfin_read16(CAN_MB13_LENGTH) +#define bfin_write_CAN_MB13_LENGTH(val) bfin_write16(CAN_MB13_LENGTH,val) +#define bfin_read_CAN_MB13_DATA3() bfin_read16(CAN_MB13_DATA3) +#define bfin_write_CAN_MB13_DATA3(val) bfin_write16(CAN_MB13_DATA3,val) +#define bfin_read_CAN_MB13_DATA2() bfin_read16(CAN_MB13_DATA2) +#define bfin_write_CAN_MB13_DATA2(val) bfin_write16(CAN_MB13_DATA2,val) +#define bfin_read_CAN_MB13_DATA1() bfin_read16(CAN_MB13_DATA1) +#define bfin_write_CAN_MB13_DATA1(val) bfin_write16(CAN_MB13_DATA1,val) +#define bfin_read_CAN_MB13_DATA0() bfin_read16(CAN_MB13_DATA0) +#define bfin_write_CAN_MB13_DATA0(val) bfin_write16(CAN_MB13_DATA0,val) + +#define bfin_read_CAN_MB14_ID1() bfin_read16(CAN_MB14_ID1) +#define bfin_write_CAN_MB14_ID1(val) bfin_write16(CAN_MB14_ID1,val) +#define bfin_read_CAN_MB14_ID0() bfin_read16(CAN_MB14_ID0) +#define bfin_write_CAN_MB14_ID0(val) bfin_write16(CAN_MB14_ID0,val) +#define bfin_read_CAN_MB14_TIMESTAMP() bfin_read16(CAN_MB14_TIMESTAMP) +#define bfin_write_CAN_MB14_TIMESTAMP(val) bfin_write16(CAN_MB14_TIMESTAMP,val) +#define bfin_read_CAN_MB14_LENGTH() bfin_read16(CAN_MB14_LENGTH) +#define bfin_write_CAN_MB14_LENGTH(val) bfin_write16(CAN_MB14_LENGTH,val) +#define bfin_read_CAN_MB14_DATA3() bfin_read16(CAN_MB14_DATA3) +#define bfin_write_CAN_MB14_DATA3(val) bfin_write16(CAN_MB14_DATA3,val) +#define bfin_read_CAN_MB14_DATA2() bfin_read16(CAN_MB14_DATA2) +#define bfin_write_CAN_MB14_DATA2(val) bfin_write16(CAN_MB14_DATA2,val) +#define bfin_read_CAN_MB14_DATA1() bfin_read16(CAN_MB14_DATA1) +#define bfin_write_CAN_MB14_DATA1(val) bfin_write16(CAN_MB14_DATA1,val) +#define bfin_read_CAN_MB14_DATA0() bfin_read16(CAN_MB14_DATA0) +#define bfin_write_CAN_MB14_DATA0(val) bfin_write16(CAN_MB14_DATA0,val) + +#define bfin_read_CAN_MB15_ID1() bfin_read16(CAN_MB15_ID1) +#define bfin_write_CAN_MB15_ID1(val) bfin_write16(CAN_MB15_ID1,val) +#define bfin_read_CAN_MB15_ID0() bfin_read16(CAN_MB15_ID0) +#define bfin_write_CAN_MB15_ID0(val) bfin_write16(CAN_MB15_ID0,val) +#define bfin_read_CAN_MB15_TIMESTAMP() bfin_read16(CAN_MB15_TIMESTAMP) +#define bfin_write_CAN_MB15_TIMESTAMP(val) bfin_write16(CAN_MB15_TIMESTAMP,val) +#define bfin_read_CAN_MB15_LENGTH() bfin_read16(CAN_MB15_LENGTH) +#define bfin_write_CAN_MB15_LENGTH(val) bfin_write16(CAN_MB15_LENGTH,val) +#define bfin_read_CAN_MB15_DATA3() bfin_read16(CAN_MB15_DATA3) +#define bfin_write_CAN_MB15_DATA3(val) bfin_write16(CAN_MB15_DATA3,val) +#define bfin_read_CAN_MB15_DATA2() bfin_read16(CAN_MB15_DATA2) +#define bfin_write_CAN_MB15_DATA2(val) bfin_write16(CAN_MB15_DATA2,val) +#define bfin_read_CAN_MB15_DATA1() bfin_read16(CAN_MB15_DATA1) +#define bfin_write_CAN_MB15_DATA1(val) bfin_write16(CAN_MB15_DATA1,val) +#define bfin_read_CAN_MB15_DATA0() bfin_read16(CAN_MB15_DATA0) +#define bfin_write_CAN_MB15_DATA0(val) bfin_write16(CAN_MB15_DATA0,val) + +#define bfin_read_CAN_MB16_ID1() bfin_read16(CAN_MB16_ID1) +#define bfin_write_CAN_MB16_ID1(val) bfin_write16(CAN_MB16_ID1,val) +#define bfin_read_CAN_MB16_ID0() bfin_read16(CAN_MB16_ID0) +#define bfin_write_CAN_MB16_ID0(val) bfin_write16(CAN_MB16_ID0,val) +#define bfin_read_CAN_MB16_TIMESTAMP() bfin_read16(CAN_MB16_TIMESTAMP) +#define bfin_write_CAN_MB16_TIMESTAMP(val) bfin_write16(CAN_MB16_TIMESTAMP,val) +#define bfin_read_CAN_MB16_LENGTH() bfin_read16(CAN_MB16_LENGTH) +#define bfin_write_CAN_MB16_LENGTH(val) bfin_write16(CAN_MB16_LENGTH,val) +#define bfin_read_CAN_MB16_DATA3() bfin_read16(CAN_MB16_DATA3) +#define bfin_write_CAN_MB16_DATA3(val) bfin_write16(CAN_MB16_DATA3,val) +#define bfin_read_CAN_MB16_DATA2() bfin_read16(CAN_MB16_DATA2) +#define bfin_write_CAN_MB16_DATA2(val) bfin_write16(CAN_MB16_DATA2,val) +#define bfin_read_CAN_MB16_DATA1() bfin_read16(CAN_MB16_DATA1) +#define bfin_write_CAN_MB16_DATA1(val) bfin_write16(CAN_MB16_DATA1,val) +#define bfin_read_CAN_MB16_DATA0() bfin_read16(CAN_MB16_DATA0) +#define bfin_write_CAN_MB16_DATA0(val) bfin_write16(CAN_MB16_DATA0,val) + +#define bfin_read_CAN_MB17_ID1() bfin_read16(CAN_MB17_ID1) +#define bfin_write_CAN_MB17_ID1(val) bfin_write16(CAN_MB17_ID1,val) +#define bfin_read_CAN_MB17_ID0() bfin_read16(CAN_MB17_ID0) +#define bfin_write_CAN_MB17_ID0(val) bfin_write16(CAN_MB17_ID0,val) +#define bfin_read_CAN_MB17_TIMESTAMP() bfin_read16(CAN_MB17_TIMESTAMP) +#define bfin_write_CAN_MB17_TIMESTAMP(val) bfin_write16(CAN_MB17_TIMESTAMP,val) +#define bfin_read_CAN_MB17_LENGTH() bfin_read16(CAN_MB17_LENGTH) +#define bfin_write_CAN_MB17_LENGTH(val) bfin_write16(CAN_MB17_LENGTH,val) +#define bfin_read_CAN_MB17_DATA3() bfin_read16(CAN_MB17_DATA3) +#define bfin_write_CAN_MB17_DATA3(val) bfin_write16(CAN_MB17_DATA3,val) +#define bfin_read_CAN_MB17_DATA2() bfin_read16(CAN_MB17_DATA2) +#define bfin_write_CAN_MB17_DATA2(val) bfin_write16(CAN_MB17_DATA2,val) +#define bfin_read_CAN_MB17_DATA1() bfin_read16(CAN_MB17_DATA1) +#define bfin_write_CAN_MB17_DATA1(val) bfin_write16(CAN_MB17_DATA1,val) +#define bfin_read_CAN_MB17_DATA0() bfin_read16(CAN_MB17_DATA0) +#define bfin_write_CAN_MB17_DATA0(val) bfin_write16(CAN_MB17_DATA0,val) + +#define bfin_read_CAN_MB18_ID1() bfin_read16(CAN_MB18_ID1) +#define bfin_write_CAN_MB18_ID1(val) bfin_write16(CAN_MB18_ID1,val) +#define bfin_read_CAN_MB18_ID0() bfin_read16(CAN_MB18_ID0) +#define bfin_write_CAN_MB18_ID0(val) bfin_write16(CAN_MB18_ID0,val) +#define bfin_read_CAN_MB18_TIMESTAMP() bfin_read16(CAN_MB18_TIMESTAMP) +#define bfin_write_CAN_MB18_TIMESTAMP(val) bfin_write16(CAN_MB18_TIMESTAMP,val) +#define bfin_read_CAN_MB18_LENGTH() bfin_read16(CAN_MB18_LENGTH) +#define bfin_write_CAN_MB18_LENGTH(val) bfin_write16(CAN_MB18_LENGTH,val) +#define bfin_read_CAN_MB18_DATA3() bfin_read16(CAN_MB18_DATA3) +#define bfin_write_CAN_MB18_DATA3(val) bfin_write16(CAN_MB18_DATA3,val) +#define bfin_read_CAN_MB18_DATA2() bfin_read16(CAN_MB18_DATA2) +#define bfin_write_CAN_MB18_DATA2(val) bfin_write16(CAN_MB18_DATA2,val) +#define bfin_read_CAN_MB18_DATA1() bfin_read16(CAN_MB18_DATA1) +#define bfin_write_CAN_MB18_DATA1(val) bfin_write16(CAN_MB18_DATA1,val) +#define bfin_read_CAN_MB18_DATA0() bfin_read16(CAN_MB18_DATA0) +#define bfin_write_CAN_MB18_DATA0(val) bfin_write16(CAN_MB18_DATA0,val) + +#define bfin_read_CAN_MB19_ID1() bfin_read16(CAN_MB19_ID1) +#define bfin_write_CAN_MB19_ID1(val) bfin_write16(CAN_MB19_ID1,val) +#define bfin_read_CAN_MB19_ID0() bfin_read16(CAN_MB19_ID0) +#define bfin_write_CAN_MB19_ID0(val) bfin_write16(CAN_MB19_ID0,val) +#define bfin_read_CAN_MB19_TIMESTAMP() bfin_read16(CAN_MB19_TIMESTAMP) +#define bfin_write_CAN_MB19_TIMESTAMP(val) bfin_write16(CAN_MB19_TIMESTAMP,val) +#define bfin_read_CAN_MB19_LENGTH() bfin_read16(CAN_MB19_LENGTH) +#define bfin_write_CAN_MB19_LENGTH(val) bfin_write16(CAN_MB19_LENGTH,val) +#define bfin_read_CAN_MB19_DATA3() bfin_read16(CAN_MB19_DATA3) +#define bfin_write_CAN_MB19_DATA3(val) bfin_write16(CAN_MB19_DATA3,val) +#define bfin_read_CAN_MB19_DATA2() bfin_read16(CAN_MB19_DATA2) +#define bfin_write_CAN_MB19_DATA2(val) bfin_write16(CAN_MB19_DATA2,val) +#define bfin_read_CAN_MB19_DATA1() bfin_read16(CAN_MB19_DATA1) +#define bfin_write_CAN_MB19_DATA1(val) bfin_write16(CAN_MB19_DATA1,val) +#define bfin_read_CAN_MB19_DATA0() bfin_read16(CAN_MB19_DATA0) +#define bfin_write_CAN_MB19_DATA0(val) bfin_write16(CAN_MB19_DATA0,val) + +#define bfin_read_CAN_MB20_ID1() bfin_read16(CAN_MB20_ID1) +#define bfin_write_CAN_MB20_ID1(val) bfin_write16(CAN_MB20_ID1,val) +#define bfin_read_CAN_MB20_ID0() bfin_read16(CAN_MB20_ID0) +#define bfin_write_CAN_MB20_ID0(val) bfin_write16(CAN_MB20_ID0,val) +#define bfin_read_CAN_MB20_TIMESTAMP() bfin_read16(CAN_MB20_TIMESTAMP) +#define bfin_write_CAN_MB20_TIMESTAMP(val) bfin_write16(CAN_MB20_TIMESTAMP,val) +#define bfin_read_CAN_MB20_LENGTH() bfin_read16(CAN_MB20_LENGTH) +#define bfin_write_CAN_MB20_LENGTH(val) bfin_write16(CAN_MB20_LENGTH,val) +#define bfin_read_CAN_MB20_DATA3() bfin_read16(CAN_MB20_DATA3) +#define bfin_write_CAN_MB20_DATA3(val) bfin_write16(CAN_MB20_DATA3,val) +#define bfin_read_CAN_MB20_DATA2() bfin_read16(CAN_MB20_DATA2) +#define bfin_write_CAN_MB20_DATA2(val) bfin_write16(CAN_MB20_DATA2,val) +#define bfin_read_CAN_MB20_DATA1() bfin_read16(CAN_MB20_DATA1) +#define bfin_write_CAN_MB20_DATA1(val) bfin_write16(CAN_MB20_DATA1,val) +#define bfin_read_CAN_MB20_DATA0() bfin_read16(CAN_MB20_DATA0) +#define bfin_write_CAN_MB20_DATA0(val) bfin_write16(CAN_MB20_DATA0,val) + +#define bfin_read_CAN_MB21_ID1() bfin_read16(CAN_MB21_ID1) +#define bfin_write_CAN_MB21_ID1(val) bfin_write16(CAN_MB21_ID1,val) +#define bfin_read_CAN_MB21_ID0() bfin_read16(CAN_MB21_ID0) +#define bfin_write_CAN_MB21_ID0(val) bfin_write16(CAN_MB21_ID0,val) +#define bfin_read_CAN_MB21_TIMESTAMP() bfin_read16(CAN_MB21_TIMESTAMP) +#define bfin_write_CAN_MB21_TIMESTAMP(val) bfin_write16(CAN_MB21_TIMESTAMP,val) +#define bfin_read_CAN_MB21_LENGTH() bfin_read16(CAN_MB21_LENGTH) +#define bfin_write_CAN_MB21_LENGTH(val) bfin_write16(CAN_MB21_LENGTH,val) +#define bfin_read_CAN_MB21_DATA3() bfin_read16(CAN_MB21_DATA3) +#define bfin_write_CAN_MB21_DATA3(val) bfin_write16(CAN_MB21_DATA3,val) +#define bfin_read_CAN_MB21_DATA2() bfin_read16(CAN_MB21_DATA2) +#define bfin_write_CAN_MB21_DATA2(val) bfin_write16(CAN_MB21_DATA2,val) +#define bfin_read_CAN_MB21_DATA1() bfin_read16(CAN_MB21_DATA1) +#define bfin_write_CAN_MB21_DATA1(val) bfin_write16(CAN_MB21_DATA1,val) +#define bfin_read_CAN_MB21_DATA0() bfin_read16(CAN_MB21_DATA0) +#define bfin_write_CAN_MB21_DATA0(val) bfin_write16(CAN_MB21_DATA0,val) + +#define bfin_read_CAN_MB22_ID1() bfin_read16(CAN_MB22_ID1) +#define bfin_write_CAN_MB22_ID1(val) bfin_write16(CAN_MB22_ID1,val) +#define bfin_read_CAN_MB22_ID0() bfin_read16(CAN_MB22_ID0) +#define bfin_write_CAN_MB22_ID0(val) bfin_write16(CAN_MB22_ID0,val) +#define bfin_read_CAN_MB22_TIMESTAMP() bfin_read16(CAN_MB22_TIMESTAMP) +#define bfin_write_CAN_MB22_TIMESTAMP(val) bfin_write16(CAN_MB22_TIMESTAMP,val) +#define bfin_read_CAN_MB22_LENGTH() bfin_read16(CAN_MB22_LENGTH) +#define bfin_write_CAN_MB22_LENGTH(val) bfin_write16(CAN_MB22_LENGTH,val) +#define bfin_read_CAN_MB22_DATA3() bfin_read16(CAN_MB22_DATA3) +#define bfin_write_CAN_MB22_DATA3(val) bfin_write16(CAN_MB22_DATA3,val) +#define bfin_read_CAN_MB22_DATA2() bfin_read16(CAN_MB22_DATA2) +#define bfin_write_CAN_MB22_DATA2(val) bfin_write16(CAN_MB22_DATA2,val) +#define bfin_read_CAN_MB22_DATA1() bfin_read16(CAN_MB22_DATA1) +#define bfin_write_CAN_MB22_DATA1(val) bfin_write16(CAN_MB22_DATA1,val) +#define bfin_read_CAN_MB22_DATA0() bfin_read16(CAN_MB22_DATA0) +#define bfin_write_CAN_MB22_DATA0(val) bfin_write16(CAN_MB22_DATA0,val) + +#define bfin_read_CAN_MB23_ID1() bfin_read16(CAN_MB23_ID1) +#define bfin_write_CAN_MB23_ID1(val) bfin_write16(CAN_MB23_ID1,val) +#define bfin_read_CAN_MB23_ID0() bfin_read16(CAN_MB23_ID0) +#define bfin_write_CAN_MB23_ID0(val) bfin_write16(CAN_MB23_ID0,val) +#define bfin_read_CAN_MB23_TIMESTAMP() bfin_read16(CAN_MB23_TIMESTAMP) +#define bfin_write_CAN_MB23_TIMESTAMP(val) bfin_write16(CAN_MB23_TIMESTAMP,val) +#define bfin_read_CAN_MB23_LENGTH() bfin_read16(CAN_MB23_LENGTH) +#define bfin_write_CAN_MB23_LENGTH(val) bfin_write16(CAN_MB23_LENGTH,val) +#define bfin_read_CAN_MB23_DATA3() bfin_read16(CAN_MB23_DATA3) +#define bfin_write_CAN_MB23_DATA3(val) bfin_write16(CAN_MB23_DATA3,val) +#define bfin_read_CAN_MB23_DATA2() bfin_read16(CAN_MB23_DATA2) +#define bfin_write_CAN_MB23_DATA2(val) bfin_write16(CAN_MB23_DATA2,val) +#define bfin_read_CAN_MB23_DATA1() bfin_read16(CAN_MB23_DATA1) +#define bfin_write_CAN_MB23_DATA1(val) bfin_write16(CAN_MB23_DATA1,val) +#define bfin_read_CAN_MB23_DATA0() bfin_read16(CAN_MB23_DATA0) +#define bfin_write_CAN_MB23_DATA0(val) bfin_write16(CAN_MB23_DATA0,val) + +#define bfin_read_CAN_MB24_ID1() bfin_read16(CAN_MB24_ID1) +#define bfin_write_CAN_MB24_ID1(val) bfin_write16(CAN_MB24_ID1,val) +#define bfin_read_CAN_MB24_ID0() bfin_read16(CAN_MB24_ID0) +#define bfin_write_CAN_MB24_ID0(val) bfin_write16(CAN_MB24_ID0,val) +#define bfin_read_CAN_MB24_TIMESTAMP() bfin_read16(CAN_MB24_TIMESTAMP) +#define bfin_write_CAN_MB24_TIMESTAMP(val) bfin_write16(CAN_MB24_TIMESTAMP,val) +#define bfin_read_CAN_MB24_LENGTH() bfin_read16(CAN_MB24_LENGTH) +#define bfin_write_CAN_MB24_LENGTH(val) bfin_write16(CAN_MB24_LENGTH,val) +#define bfin_read_CAN_MB24_DATA3() bfin_read16(CAN_MB24_DATA3) +#define bfin_write_CAN_MB24_DATA3(val) bfin_write16(CAN_MB24_DATA3,val) +#define bfin_read_CAN_MB24_DATA2() bfin_read16(CAN_MB24_DATA2) +#define bfin_write_CAN_MB24_DATA2(val) bfin_write16(CAN_MB24_DATA2,val) +#define bfin_read_CAN_MB24_DATA1() bfin_read16(CAN_MB24_DATA1) +#define bfin_write_CAN_MB24_DATA1(val) bfin_write16(CAN_MB24_DATA1,val) +#define bfin_read_CAN_MB24_DATA0() bfin_read16(CAN_MB24_DATA0) +#define bfin_write_CAN_MB24_DATA0(val) bfin_write16(CAN_MB24_DATA0,val) + +#define bfin_read_CAN_MB25_ID1() bfin_read16(CAN_MB25_ID1) +#define bfin_write_CAN_MB25_ID1(val) bfin_write16(CAN_MB25_ID1,val) +#define bfin_read_CAN_MB25_ID0() bfin_read16(CAN_MB25_ID0) +#define bfin_write_CAN_MB25_ID0(val) bfin_write16(CAN_MB25_ID0,val) +#define bfin_read_CAN_MB25_TIMESTAMP() bfin_read16(CAN_MB25_TIMESTAMP) +#define bfin_write_CAN_MB25_TIMESTAMP(val) bfin_write16(CAN_MB25_TIMESTAMP,val) +#define bfin_read_CAN_MB25_LENGTH() bfin_read16(CAN_MB25_LENGTH) +#define bfin_write_CAN_MB25_LENGTH(val) bfin_write16(CAN_MB25_LENGTH,val) +#define bfin_read_CAN_MB25_DATA3() bfin_read16(CAN_MB25_DATA3) +#define bfin_write_CAN_MB25_DATA3(val) bfin_write16(CAN_MB25_DATA3,val) +#define bfin_read_CAN_MB25_DATA2() bfin_read16(CAN_MB25_DATA2) +#define bfin_write_CAN_MB25_DATA2(val) bfin_write16(CAN_MB25_DATA2,val) +#define bfin_read_CAN_MB25_DATA1() bfin_read16(CAN_MB25_DATA1) +#define bfin_write_CAN_MB25_DATA1(val) bfin_write16(CAN_MB25_DATA1,val) +#define bfin_read_CAN_MB25_DATA0() bfin_read16(CAN_MB25_DATA0) +#define bfin_write_CAN_MB25_DATA0(val) bfin_write16(CAN_MB25_DATA0,val) + +#define bfin_read_CAN_MB26_ID1() bfin_read16(CAN_MB26_ID1) +#define bfin_write_CAN_MB26_ID1(val) bfin_write16(CAN_MB26_ID1,val) +#define bfin_read_CAN_MB26_ID0() bfin_read16(CAN_MB26_ID0) +#define bfin_write_CAN_MB26_ID0(val) bfin_write16(CAN_MB26_ID0,val) +#define bfin_read_CAN_MB26_TIMESTAMP() bfin_read16(CAN_MB26_TIMESTAMP) +#define bfin_write_CAN_MB26_TIMESTAMP(val) bfin_write16(CAN_MB26_TIMESTAMP,val) +#define bfin_read_CAN_MB26_LENGTH() bfin_read16(CAN_MB26_LENGTH) +#define bfin_write_CAN_MB26_LENGTH(val) bfin_write16(CAN_MB26_LENGTH,val) +#define bfin_read_CAN_MB26_DATA3() bfin_read16(CAN_MB26_DATA3) +#define bfin_write_CAN_MB26_DATA3(val) bfin_write16(CAN_MB26_DATA3,val) +#define bfin_read_CAN_MB26_DATA2() bfin_read16(CAN_MB26_DATA2) +#define bfin_write_CAN_MB26_DATA2(val) bfin_write16(CAN_MB26_DATA2,val) +#define bfin_read_CAN_MB26_DATA1() bfin_read16(CAN_MB26_DATA1) +#define bfin_write_CAN_MB26_DATA1(val) bfin_write16(CAN_MB26_DATA1,val) +#define bfin_read_CAN_MB26_DATA0() bfin_read16(CAN_MB26_DATA0) +#define bfin_write_CAN_MB26_DATA0(val) bfin_write16(CAN_MB26_DATA0,val) + +#define bfin_read_CAN_MB27_ID1() bfin_read16(CAN_MB27_ID1) +#define bfin_write_CAN_MB27_ID1(val) bfin_write16(CAN_MB27_ID1,val) +#define bfin_read_CAN_MB27_ID0() bfin_read16(CAN_MB27_ID0) +#define bfin_write_CAN_MB27_ID0(val) bfin_write16(CAN_MB27_ID0,val) +#define bfin_read_CAN_MB27_TIMESTAMP() bfin_read16(CAN_MB27_TIMESTAMP) +#define bfin_write_CAN_MB27_TIMESTAMP(val) bfin_write16(CAN_MB27_TIMESTAMP,val) +#define bfin_read_CAN_MB27_LENGTH() bfin_read16(CAN_MB27_LENGTH) +#define bfin_write_CAN_MB27_LENGTH(val) bfin_write16(CAN_MB27_LENGTH,val) +#define bfin_read_CAN_MB27_DATA3() bfin_read16(CAN_MB27_DATA3) +#define bfin_write_CAN_MB27_DATA3(val) bfin_write16(CAN_MB27_DATA3,val) +#define bfin_read_CAN_MB27_DATA2() bfin_read16(CAN_MB27_DATA2) +#define bfin_write_CAN_MB27_DATA2(val) bfin_write16(CAN_MB27_DATA2,val) +#define bfin_read_CAN_MB27_DATA1() bfin_read16(CAN_MB27_DATA1) +#define bfin_write_CAN_MB27_DATA1(val) bfin_write16(CAN_MB27_DATA1,val) +#define bfin_read_CAN_MB27_DATA0() bfin_read16(CAN_MB27_DATA0) +#define bfin_write_CAN_MB27_DATA0(val) bfin_write16(CAN_MB27_DATA0,val) + +#define bfin_read_CAN_MB28_ID1() bfin_read16(CAN_MB28_ID1) +#define bfin_write_CAN_MB28_ID1(val) bfin_write16(CAN_MB28_ID1,val) +#define bfin_read_CAN_MB28_ID0() bfin_read16(CAN_MB28_ID0) +#define bfin_write_CAN_MB28_ID0(val) bfin_write16(CAN_MB28_ID0,val) +#define bfin_read_CAN_MB28_TIMESTAMP() bfin_read16(CAN_MB28_TIMESTAMP) +#define bfin_write_CAN_MB28_TIMESTAMP(val) bfin_write16(CAN_MB28_TIMESTAMP,val) +#define bfin_read_CAN_MB28_LENGTH() bfin_read16(CAN_MB28_LENGTH) +#define bfin_write_CAN_MB28_LENGTH(val) bfin_write16(CAN_MB28_LENGTH,val) +#define bfin_read_CAN_MB28_DATA3() bfin_read16(CAN_MB28_DATA3) +#define bfin_write_CAN_MB28_DATA3(val) bfin_write16(CAN_MB28_DATA3,val) +#define bfin_read_CAN_MB28_DATA2() bfin_read16(CAN_MB28_DATA2) +#define bfin_write_CAN_MB28_DATA2(val) bfin_write16(CAN_MB28_DATA2,val) +#define bfin_read_CAN_MB28_DATA1() bfin_read16(CAN_MB28_DATA1) +#define bfin_write_CAN_MB28_DATA1(val) bfin_write16(CAN_MB28_DATA1,val) +#define bfin_read_CAN_MB28_DATA0() bfin_read16(CAN_MB28_DATA0) +#define bfin_write_CAN_MB28_DATA0(val) bfin_write16(CAN_MB28_DATA0,val) + +#define bfin_read_CAN_MB29_ID1() bfin_read16(CAN_MB29_ID1) +#define bfin_write_CAN_MB29_ID1(val) bfin_write16(CAN_MB29_ID1,val) +#define bfin_read_CAN_MB29_ID0() bfin_read16(CAN_MB29_ID0) +#define bfin_write_CAN_MB29_ID0(val) bfin_write16(CAN_MB29_ID0,val) +#define bfin_read_CAN_MB29_TIMESTAMP() bfin_read16(CAN_MB29_TIMESTAMP) +#define bfin_write_CAN_MB29_TIMESTAMP(val) bfin_write16(CAN_MB29_TIMESTAMP,val) +#define bfin_read_CAN_MB29_LENGTH() bfin_read16(CAN_MB29_LENGTH) +#define bfin_write_CAN_MB29_LENGTH(val) bfin_write16(CAN_MB29_LENGTH,val) +#define bfin_read_CAN_MB29_DATA3() bfin_read16(CAN_MB29_DATA3) +#define bfin_write_CAN_MB29_DATA3(val) bfin_write16(CAN_MB29_DATA3,val) +#define bfin_read_CAN_MB29_DATA2() bfin_read16(CAN_MB29_DATA2) +#define bfin_write_CAN_MB29_DATA2(val) bfin_write16(CAN_MB29_DATA2,val) +#define bfin_read_CAN_MB29_DATA1() bfin_read16(CAN_MB29_DATA1) +#define bfin_write_CAN_MB29_DATA1(val) bfin_write16(CAN_MB29_DATA1,val) +#define bfin_read_CAN_MB29_DATA0() bfin_read16(CAN_MB29_DATA0) +#define bfin_write_CAN_MB29_DATA0(val) bfin_write16(CAN_MB29_DATA0,val) + +#define bfin_read_CAN_MB30_ID1() bfin_read16(CAN_MB30_ID1) +#define bfin_write_CAN_MB30_ID1(val) bfin_write16(CAN_MB30_ID1,val) +#define bfin_read_CAN_MB30_ID0() bfin_read16(CAN_MB30_ID0) +#define bfin_write_CAN_MB30_ID0(val) bfin_write16(CAN_MB30_ID0,val) +#define bfin_read_CAN_MB30_TIMESTAMP() bfin_read16(CAN_MB30_TIMESTAMP) +#define bfin_write_CAN_MB30_TIMESTAMP(val) bfin_write16(CAN_MB30_TIMESTAMP,val) +#define bfin_read_CAN_MB30_LENGTH() bfin_read16(CAN_MB30_LENGTH) +#define bfin_write_CAN_MB30_LENGTH(val) bfin_write16(CAN_MB30_LENGTH,val) +#define bfin_read_CAN_MB30_DATA3() bfin_read16(CAN_MB30_DATA3) +#define bfin_write_CAN_MB30_DATA3(val) bfin_write16(CAN_MB30_DATA3,val) +#define bfin_read_CAN_MB30_DATA2() bfin_read16(CAN_MB30_DATA2) +#define bfin_write_CAN_MB30_DATA2(val) bfin_write16(CAN_MB30_DATA2,val) +#define bfin_read_CAN_MB30_DATA1() bfin_read16(CAN_MB30_DATA1) +#define bfin_write_CAN_MB30_DATA1(val) bfin_write16(CAN_MB30_DATA1,val) +#define bfin_read_CAN_MB30_DATA0() bfin_read16(CAN_MB30_DATA0) +#define bfin_write_CAN_MB30_DATA0(val) bfin_write16(CAN_MB30_DATA0,val) + +#define bfin_read_CAN_MB31_ID1() bfin_read16(CAN_MB31_ID1) +#define bfin_write_CAN_MB31_ID1(val) bfin_write16(CAN_MB31_ID1,val) +#define bfin_read_CAN_MB31_ID0() bfin_read16(CAN_MB31_ID0) +#define bfin_write_CAN_MB31_ID0(val) bfin_write16(CAN_MB31_ID0,val) +#define bfin_read_CAN_MB31_TIMESTAMP() bfin_read16(CAN_MB31_TIMESTAMP) +#define bfin_write_CAN_MB31_TIMESTAMP(val) bfin_write16(CAN_MB31_TIMESTAMP,val) +#define bfin_read_CAN_MB31_LENGTH() bfin_read16(CAN_MB31_LENGTH) +#define bfin_write_CAN_MB31_LENGTH(val) bfin_write16(CAN_MB31_LENGTH,val) +#define bfin_read_CAN_MB31_DATA3() bfin_read16(CAN_MB31_DATA3) +#define bfin_write_CAN_MB31_DATA3(val) bfin_write16(CAN_MB31_DATA3,val) +#define bfin_read_CAN_MB31_DATA2() bfin_read16(CAN_MB31_DATA2) +#define bfin_write_CAN_MB31_DATA2(val) bfin_write16(CAN_MB31_DATA2,val) +#define bfin_read_CAN_MB31_DATA1() bfin_read16(CAN_MB31_DATA1) +#define bfin_write_CAN_MB31_DATA1(val) bfin_write16(CAN_MB31_DATA1,val) +#define bfin_read_CAN_MB31_DATA0() bfin_read16(CAN_MB31_DATA0) +#define bfin_write_CAN_MB31_DATA0(val) bfin_write16(CAN_MB31_DATA0,val) + +/* CAN Mailbox Area Macros */ +#define bfin_read_CAN_MB_ID1(x)() bfin_read16(CAN_MB_ID1(x)) +#define bfin_write_CAN_MB_ID1(x)(val) bfin_write16(CAN_MB_ID1(x),val) +#define bfin_read_CAN_MB_ID0(x)() bfin_read16(CAN_MB_ID0(x)) +#define bfin_write_CAN_MB_ID0(x)(val) bfin_write16(CAN_MB_ID0(x),val) +#define bfin_read_CAN_MB_TIMESTAMP(x)() bfin_read16(CAN_MB_TIMESTAMP(x)) +#define bfin_write_CAN_MB_TIMESTAMP(x)(val) bfin_write16(CAN_MB_TIMESTAMP(x),val) +#define bfin_read_CAN_MB_LENGTH(x)() bfin_read16(CAN_MB_LENGTH(x)) +#define bfin_write_CAN_MB_LENGTH(x)(val) bfin_write16(CAN_MB_LENGTH(x),val) +#define bfin_read_CAN_MB_DATA3(x)() bfin_read16(CAN_MB_DATA3(x)) +#define bfin_write_CAN_MB_DATA3(x)(val) bfin_write16(CAN_MB_DATA3(x),val) +#define bfin_read_CAN_MB_DATA2(x)() bfin_read16(CAN_MB_DATA2(x)) +#define bfin_write_CAN_MB_DATA2(x)(val) bfin_write16(CAN_MB_DATA2(x),val) +#define bfin_read_CAN_MB_DATA1(x)() bfin_read16(CAN_MB_DATA1(x)) +#define bfin_write_CAN_MB_DATA1(x)(val) bfin_write16(CAN_MB_DATA1(x),val) +#define bfin_read_CAN_MB_DATA0(x)() bfin_read16(CAN_MB_DATA0(x)) +#define bfin_write_CAN_MB_DATA0(x)(val) bfin_write16(CAN_MB_DATA0(x),val) + +/* Pin Control Registers (0xFFC03200 - 0xFFC032FF) */ +#define bfin_read_PORTF_FER() bfin_read16(PORTF_FER) +#define bfin_write_PORTF_FER(val) bfin_write16(PORTF_FER,val) +#define bfin_read_PORTG_FER() bfin_read16(PORTG_FER) +#define bfin_write_PORTG_FER(val) bfin_write16(PORTG_FER,val) +#define bfin_read_PORTH_FER() bfin_read16(PORTH_FER) +#define bfin_write_PORTH_FER(val) bfin_write16(PORTH_FER,val) +#define bfin_read_PORT_MUX() bfin_read16(BFIN_PORT_MUX) +#define bfin_write_PORT_MUX(val) bfin_write16(BFIN_PORT_MUX,val) + +/* Handshake MDMA Registers (0xFFC03300 - 0xFFC033FF) */ +#define bfin_read_HMDMA0_CONTROL() bfin_read16(HMDMA0_CONTROL) +#define bfin_write_HMDMA0_CONTROL(val) bfin_write16(HMDMA0_CONTROL,val) +#define bfin_read_HMDMA0_ECINIT() bfin_read16(HMDMA0_ECINIT) +#define bfin_write_HMDMA0_ECINIT(val) bfin_write16(HMDMA0_ECINIT,val) +#define bfin_read_HMDMA0_BCINIT() bfin_read16(HMDMA0_BCINIT) +#define bfin_write_HMDMA0_BCINIT(val) bfin_write16(HMDMA0_BCINIT,val) +#define bfin_read_HMDMA0_ECURGENT() bfin_read16(HMDMA0_ECURGENT) +#define bfin_write_HMDMA0_ECURGENT(val) bfin_write16(HMDMA0_ECURGENT,val) +#define bfin_read_HMDMA0_ECOVERFLOW() bfin_read16(HMDMA0_ECOVERFLOW) +#define bfin_write_HMDMA0_ECOVERFLOW(val) bfin_write16(HMDMA0_ECOVERFLOW,val) +#define bfin_read_HMDMA0_ECOUNT() bfin_read16(HMDMA0_ECOUNT) +#define bfin_write_HMDMA0_ECOUNT(val) bfin_write16(HMDMA0_ECOUNT,val) +#define bfin_read_HMDMA0_BCOUNT() bfin_read16(HMDMA0_BCOUNT) +#define bfin_write_HMDMA0_BCOUNT(val) bfin_write16(HMDMA0_BCOUNT,val) + +#define bfin_read_HMDMA1_CONTROL() bfin_read16(HMDMA1_CONTROL) +#define bfin_write_HMDMA1_CONTROL(val) bfin_write16(HMDMA1_CONTROL,val) +#define bfin_read_HMDMA1_ECINIT() bfin_read16(HMDMA1_ECINIT) +#define bfin_write_HMDMA1_ECINIT(val) bfin_write16(HMDMA1_ECINIT,val) +#define bfin_read_HMDMA1_BCINIT() bfin_read16(HMDMA1_BCINIT) +#define bfin_write_HMDMA1_BCINIT(val) bfin_write16(HMDMA1_BCINIT,val) +#define bfin_read_HMDMA1_ECURGENT() bfin_read16(HMDMA1_ECURGENT) +#define bfin_write_HMDMA1_ECURGENT(val) bfin_write16(HMDMA1_ECURGENT,val) +#define bfin_read_HMDMA1_ECOVERFLOW() bfin_read16(HMDMA1_ECOVERFLOW) +#define bfin_write_HMDMA1_ECOVERFLOW(val) bfin_write16(HMDMA1_ECOVERFLOW,val) +#define bfin_read_HMDMA1_ECOUNT() bfin_read16(HMDMA1_ECOUNT) +#define bfin_write_HMDMA1_ECOUNT(val) bfin_write16(HMDMA1_ECOUNT,val) +#define bfin_read_HMDMA1_BCOUNT() bfin_read16(HMDMA1_BCOUNT) +#define bfin_write_HMDMA1_BCOUNT(val) bfin_write16(HMDMA1_BCOUNT,val) + +#endif /* _CDEF_BF534_H */ diff --git a/include/asm-blackfin/mach-bf537/cdefBF537.h b/include/asm-blackfin/mach-bf537/cdefBF537.h new file mode 100644 index 000000000000..932a1b6b5d14 --- /dev/null +++ b/include/asm-blackfin/mach-bf537/cdefBF537.h @@ -0,0 +1,209 @@ +/* + * File: include/asm-blackfin/mach-bf537/cdefBF537.h + * Based on: + * Author: + * + * Created: + * Description: + * System MMR Register Map + * Rev: + * + * Modified: + * + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _CDEF_BF537_H +#define _CDEF_BF537_H + +/* Include MMRs Common to BF534 */ +#include "cdefBF534.h" + +/* Include all Core registers and bit definitions */ +#include "defBF537.h" + +/* Include Macro "Defines" For EMAC (Unique to BF536/BF537 */ +/* 10/100 Ethernet Controller (0xFFC03000 - 0xFFC031FF) */ +#define pEMAC_OPMODE ((volatile unsigned long *)EMAC_OPMODE) +#define bfin_read_EMAC_OPMODE() bfin_read32(EMAC_OPMODE) +#define bfin_write_EMAC_OPMODE(val) bfin_write32(EMAC_OPMODE,val) +#define bfin_read_EMAC_ADDRLO() bfin_read32(EMAC_ADDRLO) +#define bfin_write_EMAC_ADDRLO(val) bfin_write32(EMAC_ADDRLO,val) +#define bfin_read_EMAC_ADDRHI() bfin_read32(EMAC_ADDRHI) +#define bfin_write_EMAC_ADDRHI(val) bfin_write32(EMAC_ADDRHI,val) +#define bfin_read_EMAC_HASHLO() bfin_read32(EMAC_HASHLO) +#define bfin_write_EMAC_HASHLO(val) bfin_write32(EMAC_HASHLO,val) +#define bfin_read_EMAC_HASHHI() bfin_read32(EMAC_HASHHI) +#define bfin_write_EMAC_HASHHI(val) bfin_write32(EMAC_HASHHI,val) +#define bfin_read_EMAC_STAADD() bfin_read32(EMAC_STAADD) +#define bfin_write_EMAC_STAADD(val) bfin_write32(EMAC_STAADD,val) +#define bfin_read_EMAC_STADAT() bfin_read32(EMAC_STADAT) +#define bfin_write_EMAC_STADAT(val) bfin_write32(EMAC_STADAT,val) +#define bfin_read_EMAC_FLC() bfin_read32(EMAC_FLC) +#define bfin_write_EMAC_FLC(val) bfin_write32(EMAC_FLC,val) +#define bfin_read_EMAC_VLAN1() bfin_read32(EMAC_VLAN1) +#define bfin_write_EMAC_VLAN1(val) bfin_write32(EMAC_VLAN1,val) +#define bfin_read_EMAC_VLAN2() bfin_read32(EMAC_VLAN2) +#define bfin_write_EMAC_VLAN2(val) bfin_write32(EMAC_VLAN2,val) +#define bfin_read_EMAC_WKUP_CTL() bfin_read32(EMAC_WKUP_CTL) +#define bfin_write_EMAC_WKUP_CTL(val) bfin_write32(EMAC_WKUP_CTL,val) +#define bfin_read_EMAC_WKUP_FFMSK0() bfin_read32(EMAC_WKUP_FFMSK0) +#define bfin_write_EMAC_WKUP_FFMSK0(val) bfin_write32(EMAC_WKUP_FFMSK0,val) +#define bfin_read_EMAC_WKUP_FFMSK1() bfin_read32(EMAC_WKUP_FFMSK1) +#define bfin_write_EMAC_WKUP_FFMSK1(val) bfin_write32(EMAC_WKUP_FFMSK1,val) +#define bfin_read_EMAC_WKUP_FFMSK2() bfin_read32(EMAC_WKUP_FFMSK2) +#define bfin_write_EMAC_WKUP_FFMSK2(val) bfin_write32(EMAC_WKUP_FFMSK2,val) +#define bfin_read_EMAC_WKUP_FFMSK3() bfin_read32(EMAC_WKUP_FFMSK3) +#define bfin_write_EMAC_WKUP_FFMSK3(val) bfin_write32(EMAC_WKUP_FFMSK3,val) +#define bfin_read_EMAC_WKUP_FFCMD() bfin_read32(EMAC_WKUP_FFCMD) +#define bfin_write_EMAC_WKUP_FFCMD(val) bfin_write32(EMAC_WKUP_FFCMD,val) +#define bfin_read_EMAC_WKUP_FFOFF() bfin_read32(EMAC_WKUP_FFOFF) +#define bfin_write_EMAC_WKUP_FFOFF(val) bfin_write32(EMAC_WKUP_FFOFF,val) +#define bfin_read_EMAC_WKUP_FFCRC0() bfin_read32(EMAC_WKUP_FFCRC0) +#define bfin_write_EMAC_WKUP_FFCRC0(val) bfin_write32(EMAC_WKUP_FFCRC0,val) +#define bfin_read_EMAC_WKUP_FFCRC1() bfin_read32(EMAC_WKUP_FFCRC1) +#define bfin_write_EMAC_WKUP_FFCRC1(val) bfin_write32(EMAC_WKUP_FFCRC1,val) + +#define pEMAC_SYSCTL ((volatile unsigned long *)EMAC_SYSCTL) +#define bfin_read_EMAC_SYSCTL() bfin_read32(EMAC_SYSCTL) +#define bfin_write_EMAC_SYSCTL(val) bfin_write32(EMAC_SYSCTL,val) +#define bfin_read_EMAC_SYSTAT() bfin_read32(EMAC_SYSTAT) +#define bfin_write_EMAC_SYSTAT(val) bfin_write32(EMAC_SYSTAT,val) +#define bfin_read_EMAC_RX_STAT() bfin_read32(EMAC_RX_STAT) +#define bfin_write_EMAC_RX_STAT(val) bfin_write32(EMAC_RX_STAT,val) +#define bfin_read_EMAC_RX_STKY() bfin_read32(EMAC_RX_STKY) +#define bfin_write_EMAC_RX_STKY(val) bfin_write32(EMAC_RX_STKY,val) +#define bfin_read_EMAC_RX_IRQE() bfin_read32(EMAC_RX_IRQE) +#define bfin_write_EMAC_RX_IRQE(val) bfin_write32(EMAC_RX_IRQE,val) +#define bfin_read_EMAC_TX_STAT() bfin_read32(EMAC_TX_STAT) +#define bfin_write_EMAC_TX_STAT(val) bfin_write32(EMAC_TX_STAT,val) +#define bfin_read_EMAC_TX_STKY() bfin_read32(EMAC_TX_STKY) +#define bfin_write_EMAC_TX_STKY(val) bfin_write32(EMAC_TX_STKY,val) +#define bfin_read_EMAC_TX_IRQE() bfin_read32(EMAC_TX_IRQE) +#define bfin_write_EMAC_TX_IRQE(val) bfin_write32(EMAC_TX_IRQE,val) + +#define bfin_read_EMAC_MMC_CTL() bfin_read32(EMAC_MMC_CTL) +#define bfin_write_EMAC_MMC_CTL(val) bfin_write32(EMAC_MMC_CTL,val) +#define bfin_read_EMAC_MMC_RIRQS() bfin_read32(EMAC_MMC_RIRQS) +#define bfin_write_EMAC_MMC_RIRQS(val) bfin_write32(EMAC_MMC_RIRQS,val) +#define bfin_read_EMAC_MMC_RIRQE() bfin_read32(EMAC_MMC_RIRQE) +#define bfin_write_EMAC_MMC_RIRQE(val) bfin_write32(EMAC_MMC_RIRQE,val) +#define bfin_read_EMAC_MMC_TIRQS() bfin_read32(EMAC_MMC_TIRQS) +#define bfin_write_EMAC_MMC_TIRQS(val) bfin_write32(EMAC_MMC_TIRQS,val) +#define bfin_read_EMAC_MMC_TIRQE() bfin_read32(EMAC_MMC_TIRQE) +#define bfin_write_EMAC_MMC_TIRQE(val) bfin_write32(EMAC_MMC_TIRQE,val) + +#define bfin_read_EMAC_RXC_OK() bfin_read32(EMAC_RXC_OK) +#define bfin_write_EMAC_RXC_OK(val) bfin_write32(EMAC_RXC_OK,val) +#define bfin_read_EMAC_RXC_FCS() bfin_read32(EMAC_RXC_FCS) +#define bfin_write_EMAC_RXC_FCS(val) bfin_write32(EMAC_RXC_FCS,val) +#define bfin_read_EMAC_RXC_ALIGN() bfin_read32(EMAC_RXC_ALIGN) +#define bfin_write_EMAC_RXC_ALIGN(val) bfin_write32(EMAC_RXC_ALIGN,val) +#define bfin_read_EMAC_RXC_OCTET() bfin_read32(EMAC_RXC_OCTET) +#define bfin_write_EMAC_RXC_OCTET(val) bfin_write32(EMAC_RXC_OCTET,val) +#define bfin_read_EMAC_RXC_DMAOVF() bfin_read32(EMAC_RXC_DMAOVF) +#define bfin_write_EMAC_RXC_DMAOVF(val) bfin_write32(EMAC_RXC_DMAOVF,val) +#define bfin_read_EMAC_RXC_UNICST() bfin_read32(EMAC_RXC_UNICST) +#define bfin_write_EMAC_RXC_UNICST(val) bfin_write32(EMAC_RXC_UNICST,val) +#define bfin_read_EMAC_RXC_MULTI() bfin_read32(EMAC_RXC_MULTI) +#define bfin_write_EMAC_RXC_MULTI(val) bfin_write32(EMAC_RXC_MULTI,val) +#define bfin_read_EMAC_RXC_BROAD() bfin_read32(EMAC_RXC_BROAD) +#define bfin_write_EMAC_RXC_BROAD(val) bfin_write32(EMAC_RXC_BROAD,val) +#define bfin_read_EMAC_RXC_LNERRI() bfin_read32(EMAC_RXC_LNERRI) +#define bfin_write_EMAC_RXC_LNERRI(val) bfin_write32(EMAC_RXC_LNERRI,val) +#define bfin_read_EMAC_RXC_LNERRO() bfin_read32(EMAC_RXC_LNERRO) +#define bfin_write_EMAC_RXC_LNERRO(val) bfin_write32(EMAC_RXC_LNERRO,val) +#define bfin_read_EMAC_RXC_LONG() bfin_read32(EMAC_RXC_LONG) +#define bfin_write_EMAC_RXC_LONG(val) bfin_write32(EMAC_RXC_LONG,val) +#define bfin_read_EMAC_RXC_MACCTL() bfin_read32(EMAC_RXC_MACCTL) +#define bfin_write_EMAC_RXC_MACCTL(val) bfin_write32(EMAC_RXC_MACCTL,val) +#define bfin_read_EMAC_RXC_OPCODE() bfin_read32(EMAC_RXC_OPCODE) +#define bfin_write_EMAC_RXC_OPCODE(val) bfin_write32(EMAC_RXC_OPCODE,val) +#define bfin_read_EMAC_RXC_PAUSE() bfin_read32(EMAC_RXC_PAUSE) +#define bfin_write_EMAC_RXC_PAUSE(val) bfin_write32(EMAC_RXC_PAUSE,val) +#define bfin_read_EMAC_RXC_ALLFRM() bfin_read32(EMAC_RXC_ALLFRM) +#define bfin_write_EMAC_RXC_ALLFRM(val) bfin_write32(EMAC_RXC_ALLFRM,val) +#define bfin_read_EMAC_RXC_ALLOCT() bfin_read32(EMAC_RXC_ALLOCT) +#define bfin_write_EMAC_RXC_ALLOCT(val) bfin_write32(EMAC_RXC_ALLOCT,val) +#define bfin_read_EMAC_RXC_TYPED() bfin_read32(EMAC_RXC_TYPED) +#define bfin_write_EMAC_RXC_TYPED(val) bfin_write32(EMAC_RXC_TYPED,val) +#define bfin_read_EMAC_RXC_SHORT() bfin_read32(EMAC_RXC_SHORT) +#define bfin_write_EMAC_RXC_SHORT(val) bfin_write32(EMAC_RXC_SHORT,val) +#define bfin_read_EMAC_RXC_EQ64() bfin_read32(EMAC_RXC_EQ64) +#define bfin_write_EMAC_RXC_EQ64(val) bfin_write32(EMAC_RXC_EQ64,val) +#define pEMAC_RXC_LT128 ((volatile unsigned long *)EMAC_RXC_LT128) +#define bfin_read_EMAC_RXC_LT128() bfin_read32(EMAC_RXC_LT128) +#define bfin_write_EMAC_RXC_LT128(val) bfin_write32(EMAC_RXC_LT128,val) +#define bfin_read_EMAC_RXC_LT256() bfin_read32(EMAC_RXC_LT256) +#define bfin_write_EMAC_RXC_LT256(val) bfin_write32(EMAC_RXC_LT256,val) +#define bfin_read_EMAC_RXC_LT512() bfin_read32(EMAC_RXC_LT512) +#define bfin_write_EMAC_RXC_LT512(val) bfin_write32(EMAC_RXC_LT512,val) +#define bfin_read_EMAC_RXC_LT1024() bfin_read32(EMAC_RXC_LT1024) +#define bfin_write_EMAC_RXC_LT1024(val) bfin_write32(EMAC_RXC_LT1024,val) +#define bfin_read_EMAC_RXC_GE1024() bfin_read32(EMAC_RXC_GE1024) +#define bfin_write_EMAC_RXC_GE1024(val) bfin_write32(EMAC_RXC_GE1024,val) + +#define bfin_read_EMAC_TXC_OK() bfin_read32(EMAC_TXC_OK) +#define bfin_write_EMAC_TXC_OK(val) bfin_write32(EMAC_TXC_OK,val) +#define bfin_read_EMAC_TXC_1COL() bfin_read32(EMAC_TXC_1COL) +#define bfin_write_EMAC_TXC_1COL(val) bfin_write32(EMAC_TXC_1COL,val) +#define bfin_read_EMAC_TXC_GT1COL() bfin_read32(EMAC_TXC_GT1COL) +#define bfin_write_EMAC_TXC_GT1COL(val) bfin_write32(EMAC_TXC_GT1COL,val) +#define bfin_read_EMAC_TXC_OCTET() bfin_read32(EMAC_TXC_OCTET) +#define bfin_write_EMAC_TXC_OCTET(val) bfin_write32(EMAC_TXC_OCTET,val) +#define bfin_read_EMAC_TXC_DEFER() bfin_read32(EMAC_TXC_DEFER) +#define bfin_write_EMAC_TXC_DEFER(val) bfin_write32(EMAC_TXC_DEFER,val) +#define bfin_read_EMAC_TXC_LATECL() bfin_read32(EMAC_TXC_LATECL) +#define bfin_write_EMAC_TXC_LATECL(val) bfin_write32(EMAC_TXC_LATECL,val) +#define bfin_read_EMAC_TXC_XS_COL() bfin_read32(EMAC_TXC_XS_COL) +#define bfin_write_EMAC_TXC_XS_COL(val) bfin_write32(EMAC_TXC_XS_COL,val) +#define bfin_read_EMAC_TXC_DMAUND() bfin_read32(EMAC_TXC_DMAUND) +#define bfin_write_EMAC_TXC_DMAUND(val) bfin_write32(EMAC_TXC_DMAUND,val) +#define bfin_read_EMAC_TXC_CRSERR() bfin_read32(EMAC_TXC_CRSERR) +#define bfin_write_EMAC_TXC_CRSERR(val) bfin_write32(EMAC_TXC_CRSERR,val) +#define bfin_read_EMAC_TXC_UNICST() bfin_read32(EMAC_TXC_UNICST) +#define bfin_write_EMAC_TXC_UNICST(val) bfin_write32(EMAC_TXC_UNICST,val) +#define bfin_read_EMAC_TXC_MULTI() bfin_read32(EMAC_TXC_MULTI) +#define bfin_write_EMAC_TXC_MULTI(val) bfin_write32(EMAC_TXC_MULTI,val) +#define bfin_read_EMAC_TXC_BROAD() bfin_read32(EMAC_TXC_BROAD) +#define bfin_write_EMAC_TXC_BROAD(val) bfin_write32(EMAC_TXC_BROAD,val) +#define bfin_read_EMAC_TXC_XS_DFR() bfin_read32(EMAC_TXC_XS_DFR) +#define bfin_write_EMAC_TXC_XS_DFR(val) bfin_write32(EMAC_TXC_XS_DFR,val) +#define bfin_read_EMAC_TXC_MACCTL() bfin_read32(EMAC_TXC_MACCTL) +#define bfin_write_EMAC_TXC_MACCTL(val) bfin_write32(EMAC_TXC_MACCTL,val) +#define bfin_read_EMAC_TXC_ALLFRM() bfin_read32(EMAC_TXC_ALLFRM) +#define bfin_write_EMAC_TXC_ALLFRM(val) bfin_write32(EMAC_TXC_ALLFRM,val) +#define bfin_read_EMAC_TXC_ALLOCT() bfin_read32(EMAC_TXC_ALLOCT) +#define bfin_write_EMAC_TXC_ALLOCT(val) bfin_write32(EMAC_TXC_ALLOCT,val) +#define bfin_read_EMAC_TXC_EQ64() bfin_read32(EMAC_TXC_EQ64) +#define bfin_write_EMAC_TXC_EQ64(val) bfin_write32(EMAC_TXC_EQ64,val) +#define bfin_read_EMAC_TXC_LT128() bfin_read32(EMAC_TXC_LT128) +#define bfin_write_EMAC_TXC_LT128(val) bfin_write32(EMAC_TXC_LT128,val) +#define bfin_read_EMAC_TXC_LT256() bfin_read32(EMAC_TXC_LT256) +#define bfin_write_EMAC_TXC_LT256(val) bfin_write32(EMAC_TXC_LT256,val) +#define bfin_read_EMAC_TXC_LT512() bfin_read32(EMAC_TXC_LT512) +#define bfin_write_EMAC_TXC_LT512(val) bfin_write32(EMAC_TXC_LT512,val) +#define bfin_read_EMAC_TXC_LT1024() bfin_read32(EMAC_TXC_LT1024) +#define bfin_write_EMAC_TXC_LT1024(val) bfin_write32(EMAC_TXC_LT1024,val) +#define bfin_read_EMAC_TXC_GE1024() bfin_read32(EMAC_TXC_GE1024) +#define bfin_write_EMAC_TXC_GE1024(val) bfin_write32(EMAC_TXC_GE1024,val) +#define bfin_read_EMAC_TXC_ABORT() bfin_read32(EMAC_TXC_ABORT) +#define bfin_write_EMAC_TXC_ABORT(val) bfin_write32(EMAC_TXC_ABORT,val) + +#endif /* _CDEF_BF537_H */ diff --git a/include/asm-blackfin/mach-bf537/defBF534.h b/include/asm-blackfin/mach-bf537/defBF534.h new file mode 100644 index 000000000000..e605e9709004 --- /dev/null +++ b/include/asm-blackfin/mach-bf537/defBF534.h @@ -0,0 +1,2501 @@ +/* + * File: include/asm-blackfin/mach-bf537/cdefBF537.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Rev: + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _DEF_BF534_H +#define _DEF_BF534_H + +/* Include all Core registers and bit definitions */ +#include + +/************************************************************************************ +** System MMR Register Map +*************************************************************************************/ +/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */ +#define PLL_CTL 0xFFC00000 /* PLL Control Register */ +#define PLL_DIV 0xFFC00004 /* PLL Divide Register */ +#define VR_CTL 0xFFC00008 /* Voltage Regulator Control Register */ +#define PLL_STAT 0xFFC0000C /* PLL Status Register */ +#define PLL_LOCKCNT 0xFFC00010 /* PLL Lock Count Register */ +#define CHIPID 0xFFC00014 /* Chip ID Register */ + +/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */ +#define SWRST 0xFFC00100 /* Software Reset Register */ +#define SYSCR 0xFFC00104 /* System Configuration Register */ +#define SIC_RVECT 0xFFC00108 /* Interrupt Reset Vector Address Register */ +#define SIC_IMASK 0xFFC0010C /* Interrupt Mask Register */ +#define SIC_IAR0 0xFFC00110 /* Interrupt Assignment Register 0 */ +#define SIC_IAR1 0xFFC00114 /* Interrupt Assignment Register 1 */ +#define SIC_IAR2 0xFFC00118 /* Interrupt Assignment Register 2 */ +#define SIC_IAR3 0xFFC0011C /* Interrupt Assignment Register 3 */ +#define SIC_ISR 0xFFC00120 /* Interrupt Status Register */ +#define SIC_IWR 0xFFC00124 /* Interrupt Wakeup Register */ + +/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */ +#define WDOG_CTL 0xFFC00200 /* Watchdog Control Register */ +#define WDOG_CNT 0xFFC00204 /* Watchdog Count Register */ +#define WDOG_STAT 0xFFC00208 /* Watchdog Status Register */ + +/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */ +#define RTC_STAT 0xFFC00300 /* RTC Status Register */ +#define RTC_ICTL 0xFFC00304 /* RTC Interrupt Control Register */ +#define RTC_ISTAT 0xFFC00308 /* RTC Interrupt Status Register */ +#define RTC_SWCNT 0xFFC0030C /* RTC Stopwatch Count Register */ +#define RTC_ALARM 0xFFC00310 /* RTC Alarm Time Register */ +#define RTC_FAST 0xFFC00314 /* RTC Prescaler Enable Register */ +#define RTC_PREN 0xFFC00314 /* RTC Prescaler Enable Alternate Macro */ + +/* UART0 Controller (0xFFC00400 - 0xFFC004FF) */ +#define UART0_THR 0xFFC00400 /* Transmit Holding register */ +#define UART0_RBR 0xFFC00400 /* Receive Buffer register */ +#define UART0_DLL 0xFFC00400 /* Divisor Latch (Low-Byte) */ +#define UART0_IER 0xFFC00404 /* Interrupt Enable Register */ +#define UART0_DLH 0xFFC00404 /* Divisor Latch (High-Byte) */ +#define UART0_IIR 0xFFC00408 /* Interrupt Identification Register */ +#define UART0_LCR 0xFFC0040C /* Line Control Register */ +#define UART0_MCR 0xFFC00410 /* Modem Control Register */ +#define UART0_LSR 0xFFC00414 /* Line Status Register */ +#define UART0_MSR 0xFFC00418 /* Modem Status Register */ +#define UART0_SCR 0xFFC0041C /* SCR Scratch Register */ +#define UART0_GCTL 0xFFC00424 /* Global Control Register */ + +/* SPI Controller (0xFFC00500 - 0xFFC005FF) */ +#define SPI_CTL 0xFFC00500 /* SPI Control Register */ +#define SPI_FLG 0xFFC00504 /* SPI Flag register */ +#define SPI_STAT 0xFFC00508 /* SPI Status register */ +#define SPI_TDBR 0xFFC0050C /* SPI Transmit Data Buffer Register */ +#define SPI_RDBR 0xFFC00510 /* SPI Receive Data Buffer Register */ +#define SPI_BAUD 0xFFC00514 /* SPI Baud rate Register */ +#define SPI_SHADOW 0xFFC00518 /* SPI_RDBR Shadow Register */ + +/* TIMER0-7 Registers (0xFFC00600 - 0xFFC006FF) */ +#define TIMER0_CONFIG 0xFFC00600 /* Timer 0 Configuration Register */ +#define TIMER0_COUNTER 0xFFC00604 /* Timer 0 Counter Register */ +#define TIMER0_PERIOD 0xFFC00608 /* Timer 0 Period Register */ +#define TIMER0_WIDTH 0xFFC0060C /* Timer 0 Width Register */ + +#define TIMER1_CONFIG 0xFFC00610 /* Timer 1 Configuration Register */ +#define TIMER1_COUNTER 0xFFC00614 /* Timer 1 Counter Register */ +#define TIMER1_PERIOD 0xFFC00618 /* Timer 1 Period Register */ +#define TIMER1_WIDTH 0xFFC0061C /* Timer 1 Width Register */ + +#define TIMER2_CONFIG 0xFFC00620 /* Timer 2 Configuration Register */ +#define TIMER2_COUNTER 0xFFC00624 /* Timer 2 Counter Register */ +#define TIMER2_PERIOD 0xFFC00628 /* Timer 2 Period Register */ +#define TIMER2_WIDTH 0xFFC0062C /* Timer 2 Width Register */ + +#define TIMER3_CONFIG 0xFFC00630 /* Timer 3 Configuration Register */ +#define TIMER3_COUNTER 0xFFC00634 /* Timer 3 Counter Register */ +#define TIMER3_PERIOD 0xFFC00638 /* Timer 3 Period Register */ +#define TIMER3_WIDTH 0xFFC0063C /* Timer 3 Width Register */ + +#define TIMER4_CONFIG 0xFFC00640 /* Timer 4 Configuration Register */ +#define TIMER4_COUNTER 0xFFC00644 /* Timer 4 Counter Register */ +#define TIMER4_PERIOD 0xFFC00648 /* Timer 4 Period Register */ +#define TIMER4_WIDTH 0xFFC0064C /* Timer 4 Width Register */ + +#define TIMER5_CONFIG 0xFFC00650 /* Timer 5 Configuration Register */ +#define TIMER5_COUNTER 0xFFC00654 /* Timer 5 Counter Register */ +#define TIMER5_PERIOD 0xFFC00658 /* Timer 5 Period Register */ +#define TIMER5_WIDTH 0xFFC0065C /* Timer 5 Width Register */ + +#define TIMER6_CONFIG 0xFFC00660 /* Timer 6 Configuration Register */ +#define TIMER6_COUNTER 0xFFC00664 /* Timer 6 Counter Register */ +#define TIMER6_PERIOD 0xFFC00668 /* Timer 6 Period Register */ +#define TIMER6_WIDTH 0xFFC0066C /* Timer 6 Width Register */ + +#define TIMER7_CONFIG 0xFFC00670 /* Timer 7 Configuration Register */ +#define TIMER7_COUNTER 0xFFC00674 /* Timer 7 Counter Register */ +#define TIMER7_PERIOD 0xFFC00678 /* Timer 7 Period Register */ +#define TIMER7_WIDTH 0xFFC0067C /* Timer 7 Width Register */ + +#define TIMER_ENABLE 0xFFC00680 /* Timer Enable Register */ +#define TIMER_DISABLE 0xFFC00684 /* Timer Disable Register */ +#define TIMER_STATUS 0xFFC00688 /* Timer Status Register */ + +/* General Purpose I/O Port F (0xFFC00700 - 0xFFC007FF) */ +#define PORTFIO 0xFFC00700 /* Port F I/O Pin State Specify Register */ +#define PORTFIO_CLEAR 0xFFC00704 /* Port F I/O Peripheral Interrupt Clear Register */ +#define PORTFIO_SET 0xFFC00708 /* Port F I/O Peripheral Interrupt Set Register */ +#define PORTFIO_TOGGLE 0xFFC0070C /* Port F I/O Pin State Toggle Register */ +#define PORTFIO_MASKA 0xFFC00710 /* Port F I/O Mask State Specify Interrupt A Register */ +#define PORTFIO_MASKA_CLEAR 0xFFC00714 /* Port F I/O Mask Disable Interrupt A Register */ +#define PORTFIO_MASKA_SET 0xFFC00718 /* Port F I/O Mask Enable Interrupt A Register */ +#define PORTFIO_MASKA_TOGGLE 0xFFC0071C /* Port F I/O Mask Toggle Enable Interrupt A Register */ +#define PORTFIO_MASKB 0xFFC00720 /* Port F I/O Mask State Specify Interrupt B Register */ +#define PORTFIO_MASKB_CLEAR 0xFFC00724 /* Port F I/O Mask Disable Interrupt B Register */ +#define PORTFIO_MASKB_SET 0xFFC00728 /* Port F I/O Mask Enable Interrupt B Register */ +#define PORTFIO_MASKB_TOGGLE 0xFFC0072C /* Port F I/O Mask Toggle Enable Interrupt B Register */ +#define PORTFIO_DIR 0xFFC00730 /* Port F I/O Direction Register */ +#define PORTFIO_POLAR 0xFFC00734 /* Port F I/O Source Polarity Register */ +#define PORTFIO_EDGE 0xFFC00738 /* Port F I/O Source Sensitivity Register */ +#define PORTFIO_BOTH 0xFFC0073C /* Port F I/O Set on BOTH Edges Register */ +#define PORTFIO_INEN 0xFFC00740 /* Port F I/O Input Enable Register */ + +/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */ +#define SPORT0_TCR1 0xFFC00800 /* SPORT0 Transmit Configuration 1 Register */ +#define SPORT0_TCR2 0xFFC00804 /* SPORT0 Transmit Configuration 2 Register */ +#define SPORT0_TCLKDIV 0xFFC00808 /* SPORT0 Transmit Clock Divider */ +#define SPORT0_TFSDIV 0xFFC0080C /* SPORT0 Transmit Frame Sync Divider */ +#define SPORT0_TX 0xFFC00810 /* SPORT0 TX Data Register */ +#define SPORT0_RX 0xFFC00818 /* SPORT0 RX Data Register */ +#define SPORT0_RCR1 0xFFC00820 /* SPORT0 Transmit Configuration 1 Register */ +#define SPORT0_RCR2 0xFFC00824 /* SPORT0 Transmit Configuration 2 Register */ +#define SPORT0_RCLKDIV 0xFFC00828 /* SPORT0 Receive Clock Divider */ +#define SPORT0_RFSDIV 0xFFC0082C /* SPORT0 Receive Frame Sync Divider */ +#define SPORT0_STAT 0xFFC00830 /* SPORT0 Status Register */ +#define SPORT0_CHNL 0xFFC00834 /* SPORT0 Current Channel Register */ +#define SPORT0_MCMC1 0xFFC00838 /* SPORT0 Multi-Channel Configuration Register 1 */ +#define SPORT0_MCMC2 0xFFC0083C /* SPORT0 Multi-Channel Configuration Register 2 */ +#define SPORT0_MTCS0 0xFFC00840 /* SPORT0 Multi-Channel Transmit Select Register 0 */ +#define SPORT0_MTCS1 0xFFC00844 /* SPORT0 Multi-Channel Transmit Select Register 1 */ +#define SPORT0_MTCS2 0xFFC00848 /* SPORT0 Multi-Channel Transmit Select Register 2 */ +#define SPORT0_MTCS3 0xFFC0084C /* SPORT0 Multi-Channel Transmit Select Register 3 */ +#define SPORT0_MRCS0 0xFFC00850 /* SPORT0 Multi-Channel Receive Select Register 0 */ +#define SPORT0_MRCS1 0xFFC00854 /* SPORT0 Multi-Channel Receive Select Register 1 */ +#define SPORT0_MRCS2 0xFFC00858 /* SPORT0 Multi-Channel Receive Select Register 2 */ +#define SPORT0_MRCS3 0xFFC0085C /* SPORT0 Multi-Channel Receive Select Register 3 */ + +/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */ +#define SPORT1_TCR1 0xFFC00900 /* SPORT1 Transmit Configuration 1 Register */ +#define SPORT1_TCR2 0xFFC00904 /* SPORT1 Transmit Configuration 2 Register */ +#define SPORT1_TCLKDIV 0xFFC00908 /* SPORT1 Transmit Clock Divider */ +#define SPORT1_TFSDIV 0xFFC0090C /* SPORT1 Transmit Frame Sync Divider */ +#define SPORT1_TX 0xFFC00910 /* SPORT1 TX Data Register */ +#define SPORT1_RX 0xFFC00918 /* SPORT1 RX Data Register */ +#define SPORT1_RCR1 0xFFC00920 /* SPORT1 Transmit Configuration 1 Register */ +#define SPORT1_RCR2 0xFFC00924 /* SPORT1 Transmit Configuration 2 Register */ +#define SPORT1_RCLKDIV 0xFFC00928 /* SPORT1 Receive Clock Divider */ +#define SPORT1_RFSDIV 0xFFC0092C /* SPORT1 Receive Frame Sync Divider */ +#define SPORT1_STAT 0xFFC00930 /* SPORT1 Status Register */ +#define SPORT1_CHNL 0xFFC00934 /* SPORT1 Current Channel Register */ +#define SPORT1_MCMC1 0xFFC00938 /* SPORT1 Multi-Channel Configuration Register 1 */ +#define SPORT1_MCMC2 0xFFC0093C /* SPORT1 Multi-Channel Configuration Register 2 */ +#define SPORT1_MTCS0 0xFFC00940 /* SPORT1 Multi-Channel Transmit Select Register 0 */ +#define SPORT1_MTCS1 0xFFC00944 /* SPORT1 Multi-Channel Transmit Select Register 1 */ +#define SPORT1_MTCS2 0xFFC00948 /* SPORT1 Multi-Channel Transmit Select Register 2 */ +#define SPORT1_MTCS3 0xFFC0094C /* SPORT1 Multi-Channel Transmit Select Register 3 */ +#define SPORT1_MRCS0 0xFFC00950 /* SPORT1 Multi-Channel Receive Select Register 0 */ +#define SPORT1_MRCS1 0xFFC00954 /* SPORT1 Multi-Channel Receive Select Register 1 */ +#define SPORT1_MRCS2 0xFFC00958 /* SPORT1 Multi-Channel Receive Select Register 2 */ +#define SPORT1_MRCS3 0xFFC0095C /* SPORT1 Multi-Channel Receive Select Register 3 */ + +/* External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */ +#define EBIU_AMGCTL 0xFFC00A00 /* Asynchronous Memory Global Control Register */ +#define EBIU_AMBCTL0 0xFFC00A04 /* Asynchronous Memory Bank Control Register 0 */ +#define EBIU_AMBCTL1 0xFFC00A08 /* Asynchronous Memory Bank Control Register 1 */ +#define EBIU_SDGCTL 0xFFC00A10 /* SDRAM Global Control Register */ +#define EBIU_SDBCTL 0xFFC00A14 /* SDRAM Bank Control Register */ +#define EBIU_SDRRC 0xFFC00A18 /* SDRAM Refresh Rate Control Register */ +#define EBIU_SDSTAT 0xFFC00A1C /* SDRAM Status Register */ + +/* DMA Traffic Control Registers */ +#define DMA_TCPER 0xFFC00B0C /* Traffic Control Periods Register */ +#define DMA_TCCNT 0xFFC00B10 /* Traffic Control Current Counts Register */ + +/* DMA Controller (0xFFC00C00 - 0xFFC00FFF) */ +#define DMA0_NEXT_DESC_PTR 0xFFC00C00 /* DMA Channel 0 Next Descriptor Pointer Register */ +#define DMA0_START_ADDR 0xFFC00C04 /* DMA Channel 0 Start Address Register */ +#define DMA0_CONFIG 0xFFC00C08 /* DMA Channel 0 Configuration Register */ +#define DMA0_X_COUNT 0xFFC00C10 /* DMA Channel 0 X Count Register */ +#define DMA0_X_MODIFY 0xFFC00C14 /* DMA Channel 0 X Modify Register */ +#define DMA0_Y_COUNT 0xFFC00C18 /* DMA Channel 0 Y Count Register */ +#define DMA0_Y_MODIFY 0xFFC00C1C /* DMA Channel 0 Y Modify Register */ +#define DMA0_CURR_DESC_PTR 0xFFC00C20 /* DMA Channel 0 Current Descriptor Pointer Register */ +#define DMA0_CURR_ADDR 0xFFC00C24 /* DMA Channel 0 Current Address Register */ +#define DMA0_IRQ_STATUS 0xFFC00C28 /* DMA Channel 0 Interrupt/Status Register */ +#define DMA0_PERIPHERAL_MAP 0xFFC00C2C /* DMA Channel 0 Peripheral Map Register */ +#define DMA0_CURR_X_COUNT 0xFFC00C30 /* DMA Channel 0 Current X Count Register */ +#define DMA0_CURR_Y_COUNT 0xFFC00C38 /* DMA Channel 0 Current Y Count Register */ + +#define DMA1_NEXT_DESC_PTR 0xFFC00C40 /* DMA Channel 1 Next Descriptor Pointer Register */ +#define DMA1_START_ADDR 0xFFC00C44 /* DMA Channel 1 Start Address Register */ +#define DMA1_CONFIG 0xFFC00C48 /* DMA Channel 1 Configuration Register */ +#define DMA1_X_COUNT 0xFFC00C50 /* DMA Channel 1 X Count Register */ +#define DMA1_X_MODIFY 0xFFC00C54 /* DMA Channel 1 X Modify Register */ +#define DMA1_Y_COUNT 0xFFC00C58 /* DMA Channel 1 Y Count Register */ +#define DMA1_Y_MODIFY 0xFFC00C5C /* DMA Channel 1 Y Modify Register */ +#define DMA1_CURR_DESC_PTR 0xFFC00C60 /* DMA Channel 1 Current Descriptor Pointer Register */ +#define DMA1_CURR_ADDR 0xFFC00C64 /* DMA Channel 1 Current Address Register */ +#define DMA1_IRQ_STATUS 0xFFC00C68 /* DMA Channel 1 Interrupt/Status Register */ +#define DMA1_PERIPHERAL_MAP 0xFFC00C6C /* DMA Channel 1 Peripheral Map Register */ +#define DMA1_CURR_X_COUNT 0xFFC00C70 /* DMA Channel 1 Current X Count Register */ +#define DMA1_CURR_Y_COUNT 0xFFC00C78 /* DMA Channel 1 Current Y Count Register */ + +#define DMA2_NEXT_DESC_PTR 0xFFC00C80 /* DMA Channel 2 Next Descriptor Pointer Register */ +#define DMA2_START_ADDR 0xFFC00C84 /* DMA Channel 2 Start Address Register */ +#define DMA2_CONFIG 0xFFC00C88 /* DMA Channel 2 Configuration Register */ +#define DMA2_X_COUNT 0xFFC00C90 /* DMA Channel 2 X Count Register */ +#define DMA2_X_MODIFY 0xFFC00C94 /* DMA Channel 2 X Modify Register */ +#define DMA2_Y_COUNT 0xFFC00C98 /* DMA Channel 2 Y Count Register */ +#define DMA2_Y_MODIFY 0xFFC00C9C /* DMA Channel 2 Y Modify Register */ +#define DMA2_CURR_DESC_PTR 0xFFC00CA0 /* DMA Channel 2 Current Descriptor Pointer Register */ +#define DMA2_CURR_ADDR 0xFFC00CA4 /* DMA Channel 2 Current Address Register */ +#define DMA2_IRQ_STATUS 0xFFC00CA8 /* DMA Channel 2 Interrupt/Status Register */ +#define DMA2_PERIPHERAL_MAP 0xFFC00CAC /* DMA Channel 2 Peripheral Map Register */ +#define DMA2_CURR_X_COUNT 0xFFC00CB0 /* DMA Channel 2 Current X Count Register */ +#define DMA2_CURR_Y_COUNT 0xFFC00CB8 /* DMA Channel 2 Current Y Count Register */ + +#define DMA3_NEXT_DESC_PTR 0xFFC00CC0 /* DMA Channel 3 Next Descriptor Pointer Register */ +#define DMA3_START_ADDR 0xFFC00CC4 /* DMA Channel 3 Start Address Register */ +#define DMA3_CONFIG 0xFFC00CC8 /* DMA Channel 3 Configuration Register */ +#define DMA3_X_COUNT 0xFFC00CD0 /* DMA Channel 3 X Count Register */ +#define DMA3_X_MODIFY 0xFFC00CD4 /* DMA Channel 3 X Modify Register */ +#define DMA3_Y_COUNT 0xFFC00CD8 /* DMA Channel 3 Y Count Register */ +#define DMA3_Y_MODIFY 0xFFC00CDC /* DMA Channel 3 Y Modify Register */ +#define DMA3_CURR_DESC_PTR 0xFFC00CE0 /* DMA Channel 3 Current Descriptor Pointer Register */ +#define DMA3_CURR_ADDR 0xFFC00CE4 /* DMA Channel 3 Current Address Register */ +#define DMA3_IRQ_STATUS 0xFFC00CE8 /* DMA Channel 3 Interrupt/Status Register */ +#define DMA3_PERIPHERAL_MAP 0xFFC00CEC /* DMA Channel 3 Peripheral Map Register */ +#define DMA3_CURR_X_COUNT 0xFFC00CF0 /* DMA Channel 3 Current X Count Register */ +#define DMA3_CURR_Y_COUNT 0xFFC00CF8 /* DMA Channel 3 Current Y Count Register */ + +#define DMA4_NEXT_DESC_PTR 0xFFC00D00 /* DMA Channel 4 Next Descriptor Pointer Register */ +#define DMA4_START_ADDR 0xFFC00D04 /* DMA Channel 4 Start Address Register */ +#define DMA4_CONFIG 0xFFC00D08 /* DMA Channel 4 Configuration Register */ +#define DMA4_X_COUNT 0xFFC00D10 /* DMA Channel 4 X Count Register */ +#define DMA4_X_MODIFY 0xFFC00D14 /* DMA Channel 4 X Modify Register */ +#define DMA4_Y_COUNT 0xFFC00D18 /* DMA Channel 4 Y Count Register */ +#define DMA4_Y_MODIFY 0xFFC00D1C /* DMA Channel 4 Y Modify Register */ +#define DMA4_CURR_DESC_PTR 0xFFC00D20 /* DMA Channel 4 Current Descriptor Pointer Register */ +#define DMA4_CURR_ADDR 0xFFC00D24 /* DMA Channel 4 Current Address Register */ +#define DMA4_IRQ_STATUS 0xFFC00D28 /* DMA Channel 4 Interrupt/Status Register */ +#define DMA4_PERIPHERAL_MAP 0xFFC00D2C /* DMA Channel 4 Peripheral Map Register */ +#define DMA4_CURR_X_COUNT 0xFFC00D30 /* DMA Channel 4 Current X Count Register */ +#define DMA4_CURR_Y_COUNT 0xFFC00D38 /* DMA Channel 4 Current Y Count Register */ + +#define DMA5_NEXT_DESC_PTR 0xFFC00D40 /* DMA Channel 5 Next Descriptor Pointer Register */ +#define DMA5_START_ADDR 0xFFC00D44 /* DMA Channel 5 Start Address Register */ +#define DMA5_CONFIG 0xFFC00D48 /* DMA Channel 5 Configuration Register */ +#define DMA5_X_COUNT 0xFFC00D50 /* DMA Channel 5 X Count Register */ +#define DMA5_X_MODIFY 0xFFC00D54 /* DMA Channel 5 X Modify Register */ +#define DMA5_Y_COUNT 0xFFC00D58 /* DMA Channel 5 Y Count Register */ +#define DMA5_Y_MODIFY 0xFFC00D5C /* DMA Channel 5 Y Modify Register */ +#define DMA5_CURR_DESC_PTR 0xFFC00D60 /* DMA Channel 5 Current Descriptor Pointer Register */ +#define DMA5_CURR_ADDR 0xFFC00D64 /* DMA Channel 5 Current Address Register */ +#define DMA5_IRQ_STATUS 0xFFC00D68 /* DMA Channel 5 Interrupt/Status Register */ +#define DMA5_PERIPHERAL_MAP 0xFFC00D6C /* DMA Channel 5 Peripheral Map Register */ +#define DMA5_CURR_X_COUNT 0xFFC00D70 /* DMA Channel 5 Current X Count Register */ +#define DMA5_CURR_Y_COUNT 0xFFC00D78 /* DMA Channel 5 Current Y Count Register */ + +#define DMA6_NEXT_DESC_PTR 0xFFC00D80 /* DMA Channel 6 Next Descriptor Pointer Register */ +#define DMA6_START_ADDR 0xFFC00D84 /* DMA Channel 6 Start Address Register */ +#define DMA6_CONFIG 0xFFC00D88 /* DMA Channel 6 Configuration Register */ +#define DMA6_X_COUNT 0xFFC00D90 /* DMA Channel 6 X Count Register */ +#define DMA6_X_MODIFY 0xFFC00D94 /* DMA Channel 6 X Modify Register */ +#define DMA6_Y_COUNT 0xFFC00D98 /* DMA Channel 6 Y Count Register */ +#define DMA6_Y_MODIFY 0xFFC00D9C /* DMA Channel 6 Y Modify Register */ +#define DMA6_CURR_DESC_PTR 0xFFC00DA0 /* DMA Channel 6 Current Descriptor Pointer Register */ +#define DMA6_CURR_ADDR 0xFFC00DA4 /* DMA Channel 6 Current Address Register */ +#define DMA6_IRQ_STATUS 0xFFC00DA8 /* DMA Channel 6 Interrupt/Status Register */ +#define DMA6_PERIPHERAL_MAP 0xFFC00DAC /* DMA Channel 6 Peripheral Map Register */ +#define DMA6_CURR_X_COUNT 0xFFC00DB0 /* DMA Channel 6 Current X Count Register */ +#define DMA6_CURR_Y_COUNT 0xFFC00DB8 /* DMA Channel 6 Current Y Count Register */ + +#define DMA7_NEXT_DESC_PTR 0xFFC00DC0 /* DMA Channel 7 Next Descriptor Pointer Register */ +#define DMA7_START_ADDR 0xFFC00DC4 /* DMA Channel 7 Start Address Register */ +#define DMA7_CONFIG 0xFFC00DC8 /* DMA Channel 7 Configuration Register */ +#define DMA7_X_COUNT 0xFFC00DD0 /* DMA Channel 7 X Count Register */ +#define DMA7_X_MODIFY 0xFFC00DD4 /* DMA Channel 7 X Modify Register */ +#define DMA7_Y_COUNT 0xFFC00DD8 /* DMA Channel 7 Y Count Register */ +#define DMA7_Y_MODIFY 0xFFC00DDC /* DMA Channel 7 Y Modify Register */ +#define DMA7_CURR_DESC_PTR 0xFFC00DE0 /* DMA Channel 7 Current Descriptor Pointer Register */ +#define DMA7_CURR_ADDR 0xFFC00DE4 /* DMA Channel 7 Current Address Register */ +#define DMA7_IRQ_STATUS 0xFFC00DE8 /* DMA Channel 7 Interrupt/Status Register */ +#define DMA7_PERIPHERAL_MAP 0xFFC00DEC /* DMA Channel 7 Peripheral Map Register */ +#define DMA7_CURR_X_COUNT 0xFFC00DF0 /* DMA Channel 7 Current X Count Register */ +#define DMA7_CURR_Y_COUNT 0xFFC00DF8 /* DMA Channel 7 Current Y Count Register */ + +#define DMA8_NEXT_DESC_PTR 0xFFC00E00 /* DMA Channel 8 Next Descriptor Pointer Register */ +#define DMA8_START_ADDR 0xFFC00E04 /* DMA Channel 8 Start Address Register */ +#define DMA8_CONFIG 0xFFC00E08 /* DMA Channel 8 Configuration Register */ +#define DMA8_X_COUNT 0xFFC00E10 /* DMA Channel 8 X Count Register */ +#define DMA8_X_MODIFY 0xFFC00E14 /* DMA Channel 8 X Modify Register */ +#define DMA8_Y_COUNT 0xFFC00E18 /* DMA Channel 8 Y Count Register */ +#define DMA8_Y_MODIFY 0xFFC00E1C /* DMA Channel 8 Y Modify Register */ +#define DMA8_CURR_DESC_PTR 0xFFC00E20 /* DMA Channel 8 Current Descriptor Pointer Register */ +#define DMA8_CURR_ADDR 0xFFC00E24 /* DMA Channel 8 Current Address Register */ +#define DMA8_IRQ_STATUS 0xFFC00E28 /* DMA Channel 8 Interrupt/Status Register */ +#define DMA8_PERIPHERAL_MAP 0xFFC00E2C /* DMA Channel 8 Peripheral Map Register */ +#define DMA8_CURR_X_COUNT 0xFFC00E30 /* DMA Channel 8 Current X Count Register */ +#define DMA8_CURR_Y_COUNT 0xFFC00E38 /* DMA Channel 8 Current Y Count Register */ + +#define DMA9_NEXT_DESC_PTR 0xFFC00E40 /* DMA Channel 9 Next Descriptor Pointer Register */ +#define DMA9_START_ADDR 0xFFC00E44 /* DMA Channel 9 Start Address Register */ +#define DMA9_CONFIG 0xFFC00E48 /* DMA Channel 9 Configuration Register */ +#define DMA9_X_COUNT 0xFFC00E50 /* DMA Channel 9 X Count Register */ +#define DMA9_X_MODIFY 0xFFC00E54 /* DMA Channel 9 X Modify Register */ +#define DMA9_Y_COUNT 0xFFC00E58 /* DMA Channel 9 Y Count Register */ +#define DMA9_Y_MODIFY 0xFFC00E5C /* DMA Channel 9 Y Modify Register */ +#define DMA9_CURR_DESC_PTR 0xFFC00E60 /* DMA Channel 9 Current Descriptor Pointer Register */ +#define DMA9_CURR_ADDR 0xFFC00E64 /* DMA Channel 9 Current Address Register */ +#define DMA9_IRQ_STATUS 0xFFC00E68 /* DMA Channel 9 Interrupt/Status Register */ +#define DMA9_PERIPHERAL_MAP 0xFFC00E6C /* DMA Channel 9 Peripheral Map Register */ +#define DMA9_CURR_X_COUNT 0xFFC00E70 /* DMA Channel 9 Current X Count Register */ +#define DMA9_CURR_Y_COUNT 0xFFC00E78 /* DMA Channel 9 Current Y Count Register */ + +#define DMA10_NEXT_DESC_PTR 0xFFC00E80 /* DMA Channel 10 Next Descriptor Pointer Register */ +#define DMA10_START_ADDR 0xFFC00E84 /* DMA Channel 10 Start Address Register */ +#define DMA10_CONFIG 0xFFC00E88 /* DMA Channel 10 Configuration Register */ +#define DMA10_X_COUNT 0xFFC00E90 /* DMA Channel 10 X Count Register */ +#define DMA10_X_MODIFY 0xFFC00E94 /* DMA Channel 10 X Modify Register */ +#define DMA10_Y_COUNT 0xFFC00E98 /* DMA Channel 10 Y Count Register */ +#define DMA10_Y_MODIFY 0xFFC00E9C /* DMA Channel 10 Y Modify Register */ +#define DMA10_CURR_DESC_PTR 0xFFC00EA0 /* DMA Channel 10 Current Descriptor Pointer Register */ +#define DMA10_CURR_ADDR 0xFFC00EA4 /* DMA Channel 10 Current Address Register */ +#define DMA10_IRQ_STATUS 0xFFC00EA8 /* DMA Channel 10 Interrupt/Status Register */ +#define DMA10_PERIPHERAL_MAP 0xFFC00EAC /* DMA Channel 10 Peripheral Map Register */ +#define DMA10_CURR_X_COUNT 0xFFC00EB0 /* DMA Channel 10 Current X Count Register */ +#define DMA10_CURR_Y_COUNT 0xFFC00EB8 /* DMA Channel 10 Current Y Count Register */ + +#define DMA11_NEXT_DESC_PTR 0xFFC00EC0 /* DMA Channel 11 Next Descriptor Pointer Register */ +#define DMA11_START_ADDR 0xFFC00EC4 /* DMA Channel 11 Start Address Register */ +#define DMA11_CONFIG 0xFFC00EC8 /* DMA Channel 11 Configuration Register */ +#define DMA11_X_COUNT 0xFFC00ED0 /* DMA Channel 11 X Count Register */ +#define DMA11_X_MODIFY 0xFFC00ED4 /* DMA Channel 11 X Modify Register */ +#define DMA11_Y_COUNT 0xFFC00ED8 /* DMA Channel 11 Y Count Register */ +#define DMA11_Y_MODIFY 0xFFC00EDC /* DMA Channel 11 Y Modify Register */ +#define DMA11_CURR_DESC_PTR 0xFFC00EE0 /* DMA Channel 11 Current Descriptor Pointer Register */ +#define DMA11_CURR_ADDR 0xFFC00EE4 /* DMA Channel 11 Current Address Register */ +#define DMA11_IRQ_STATUS 0xFFC00EE8 /* DMA Channel 11 Interrupt/Status Register */ +#define DMA11_PERIPHERAL_MAP 0xFFC00EEC /* DMA Channel 11 Peripheral Map Register */ +#define DMA11_CURR_X_COUNT 0xFFC00EF0 /* DMA Channel 11 Current X Count Register */ +#define DMA11_CURR_Y_COUNT 0xFFC00EF8 /* DMA Channel 11 Current Y Count Register */ + +#define MDMA_D0_NEXT_DESC_PTR 0xFFC00F00 /* MemDMA Stream 0 Destination Next Descriptor Pointer Register */ +#define MDMA_D0_START_ADDR 0xFFC00F04 /* MemDMA Stream 0 Destination Start Address Register */ +#define MDMA_D0_CONFIG 0xFFC00F08 /* MemDMA Stream 0 Destination Configuration Register */ +#define MDMA_D0_X_COUNT 0xFFC00F10 /* MemDMA Stream 0 Destination X Count Register */ +#define MDMA_D0_X_MODIFY 0xFFC00F14 /* MemDMA Stream 0 Destination X Modify Register */ +#define MDMA_D0_Y_COUNT 0xFFC00F18 /* MemDMA Stream 0 Destination Y Count Register */ +#define MDMA_D0_Y_MODIFY 0xFFC00F1C /* MemDMA Stream 0 Destination Y Modify Register */ +#define MDMA_D0_CURR_DESC_PTR 0xFFC00F20 /* MemDMA Stream 0 Destination Current Descriptor Pointer Register */ +#define MDMA_D0_CURR_ADDR 0xFFC00F24 /* MemDMA Stream 0 Destination Current Address Register */ +#define MDMA_D0_IRQ_STATUS 0xFFC00F28 /* MemDMA Stream 0 Destination Interrupt/Status Register */ +#define MDMA_D0_PERIPHERAL_MAP 0xFFC00F2C /* MemDMA Stream 0 Destination Peripheral Map Register */ +#define MDMA_D0_CURR_X_COUNT 0xFFC00F30 /* MemDMA Stream 0 Destination Current X Count Register */ +#define MDMA_D0_CURR_Y_COUNT 0xFFC00F38 /* MemDMA Stream 0 Destination Current Y Count Register */ + +#define MDMA_S0_NEXT_DESC_PTR 0xFFC00F40 /* MemDMA Stream 0 Source Next Descriptor Pointer Register */ +#define MDMA_S0_START_ADDR 0xFFC00F44 /* MemDMA Stream 0 Source Start Address Register */ +#define MDMA_S0_CONFIG 0xFFC00F48 /* MemDMA Stream 0 Source Configuration Register */ +#define MDMA_S0_X_COUNT 0xFFC00F50 /* MemDMA Stream 0 Source X Count Register */ +#define MDMA_S0_X_MODIFY 0xFFC00F54 /* MemDMA Stream 0 Source X Modify Register */ +#define MDMA_S0_Y_COUNT 0xFFC00F58 /* MemDMA Stream 0 Source Y Count Register */ +#define MDMA_S0_Y_MODIFY 0xFFC00F5C /* MemDMA Stream 0 Source Y Modify Register */ +#define MDMA_S0_CURR_DESC_PTR 0xFFC00F60 /* MemDMA Stream 0 Source Current Descriptor Pointer Register */ +#define MDMA_S0_CURR_ADDR 0xFFC00F64 /* MemDMA Stream 0 Source Current Address Register */ +#define MDMA_S0_IRQ_STATUS 0xFFC00F68 /* MemDMA Stream 0 Source Interrupt/Status Register */ +#define MDMA_S0_PERIPHERAL_MAP 0xFFC00F6C /* MemDMA Stream 0 Source Peripheral Map Register */ +#define MDMA_S0_CURR_X_COUNT 0xFFC00F70 /* MemDMA Stream 0 Source Current X Count Register */ +#define MDMA_S0_CURR_Y_COUNT 0xFFC00F78 /* MemDMA Stream 0 Source Current Y Count Register */ + +#define MDMA_D1_NEXT_DESC_PTR 0xFFC00F80 /* MemDMA Stream 1 Destination Next Descriptor Pointer Register */ +#define MDMA_D1_START_ADDR 0xFFC00F84 /* MemDMA Stream 1 Destination Start Address Register */ +#define MDMA_D1_CONFIG 0xFFC00F88 /* MemDMA Stream 1 Destination Configuration Register */ +#define MDMA_D1_X_COUNT 0xFFC00F90 /* MemDMA Stream 1 Destination X Count Register */ +#define MDMA_D1_X_MODIFY 0xFFC00F94 /* MemDMA Stream 1 Destination X Modify Register */ +#define MDMA_D1_Y_COUNT 0xFFC00F98 /* MemDMA Stream 1 Destination Y Count Register */ +#define MDMA_D1_Y_MODIFY 0xFFC00F9C /* MemDMA Stream 1 Destination Y Modify Register */ +#define MDMA_D1_CURR_DESC_PTR 0xFFC00FA0 /* MemDMA Stream 1 Destination Current Descriptor Pointer Register */ +#define MDMA_D1_CURR_ADDR 0xFFC00FA4 /* MemDMA Stream 1 Destination Current Address Register */ +#define MDMA_D1_IRQ_STATUS 0xFFC00FA8 /* MemDMA Stream 1 Destination Interrupt/Status Register */ +#define MDMA_D1_PERIPHERAL_MAP 0xFFC00FAC /* MemDMA Stream 1 Destination Peripheral Map Register */ +#define MDMA_D1_CURR_X_COUNT 0xFFC00FB0 /* MemDMA Stream 1 Destination Current X Count Register */ +#define MDMA_D1_CURR_Y_COUNT 0xFFC00FB8 /* MemDMA Stream 1 Destination Current Y Count Register */ + +#define MDMA_S1_NEXT_DESC_PTR 0xFFC00FC0 /* MemDMA Stream 1 Source Next Descriptor Pointer Register */ +#define MDMA_S1_START_ADDR 0xFFC00FC4 /* MemDMA Stream 1 Source Start Address Register */ +#define MDMA_S1_CONFIG 0xFFC00FC8 /* MemDMA Stream 1 Source Configuration Register */ +#define MDMA_S1_X_COUNT 0xFFC00FD0 /* MemDMA Stream 1 Source X Count Register */ +#define MDMA_S1_X_MODIFY 0xFFC00FD4 /* MemDMA Stream 1 Source X Modify Register */ +#define MDMA_S1_Y_COUNT 0xFFC00FD8 /* MemDMA Stream 1 Source Y Count Register */ +#define MDMA_S1_Y_MODIFY 0xFFC00FDC /* MemDMA Stream 1 Source Y Modify Register */ +#define MDMA_S1_CURR_DESC_PTR 0xFFC00FE0 /* MemDMA Stream 1 Source Current Descriptor Pointer Register */ +#define MDMA_S1_CURR_ADDR 0xFFC00FE4 /* MemDMA Stream 1 Source Current Address Register */ +#define MDMA_S1_IRQ_STATUS 0xFFC00FE8 /* MemDMA Stream 1 Source Interrupt/Status Register */ +#define MDMA_S1_PERIPHERAL_MAP 0xFFC00FEC /* MemDMA Stream 1 Source Peripheral Map Register */ +#define MDMA_S1_CURR_X_COUNT 0xFFC00FF0 /* MemDMA Stream 1 Source Current X Count Register */ +#define MDMA_S1_CURR_Y_COUNT 0xFFC00FF8 /* MemDMA Stream 1 Source Current Y Count Register */ + +/* Parallel Peripheral Interface (0xFFC01000 - 0xFFC010FF) */ +#define PPI_CONTROL 0xFFC01000 /* PPI Control Register */ +#define PPI_STATUS 0xFFC01004 /* PPI Status Register */ +#define PPI_COUNT 0xFFC01008 /* PPI Transfer Count Register */ +#define PPI_DELAY 0xFFC0100C /* PPI Delay Count Register */ +#define PPI_FRAME 0xFFC01010 /* PPI Frame Length Register */ + +/* Two-Wire Interface (0xFFC01400 - 0xFFC014FF) */ +#define TWI_CLKDIV 0xFFC01400 /* Serial Clock Divider Register */ +#define TWI_CONTROL 0xFFC01404 /* TWI Control Register */ +#define TWI_SLAVE_CTL 0xFFC01408 /* Slave Mode Control Register */ +#define TWI_SLAVE_STAT 0xFFC0140C /* Slave Mode Status Register */ +#define TWI_SLAVE_ADDR 0xFFC01410 /* Slave Mode Address Register */ +#define TWI_MASTER_CTL 0xFFC01414 /* Master Mode Control Register */ +#define TWI_MASTER_STAT 0xFFC01418 /* Master Mode Status Register */ +#define TWI_MASTER_ADDR 0xFFC0141C /* Master Mode Address Register */ +#define TWI_INT_STAT 0xFFC01420 /* TWI Interrupt Status Register */ +#define TWI_INT_MASK 0xFFC01424 /* TWI Master Interrupt Mask Register */ +#define TWI_FIFO_CTL 0xFFC01428 /* FIFO Control Register */ +#define TWI_FIFO_STAT 0xFFC0142C /* FIFO Status Register */ +#define TWI_XMT_DATA8 0xFFC01480 /* FIFO Transmit Data Single Byte Register */ +#define TWI_XMT_DATA16 0xFFC01484 /* FIFO Transmit Data Double Byte Register */ +#define TWI_RCV_DATA8 0xFFC01488 /* FIFO Receive Data Single Byte Register */ +#define TWI_RCV_DATA16 0xFFC0148C /* FIFO Receive Data Double Byte Register */ + +/* General Purpose I/O Port G (0xFFC01500 - 0xFFC015FF) */ +#define PORTGIO 0xFFC01500 /* Port G I/O Pin State Specify Register */ +#define PORTGIO_CLEAR 0xFFC01504 /* Port G I/O Peripheral Interrupt Clear Register */ +#define PORTGIO_SET 0xFFC01508 /* Port G I/O Peripheral Interrupt Set Register */ +#define PORTGIO_TOGGLE 0xFFC0150C /* Port G I/O Pin State Toggle Register */ +#define PORTGIO_MASKA 0xFFC01510 /* Port G I/O Mask State Specify Interrupt A Register */ +#define PORTGIO_MASKA_CLEAR 0xFFC01514 /* Port G I/O Mask Disable Interrupt A Register */ +#define PORTGIO_MASKA_SET 0xFFC01518 /* Port G I/O Mask Enable Interrupt A Register */ +#define PORTGIO_MASKA_TOGGLE 0xFFC0151C /* Port G I/O Mask Toggle Enable Interrupt A Register */ +#define PORTGIO_MASKB 0xFFC01520 /* Port G I/O Mask State Specify Interrupt B Register */ +#define PORTGIO_MASKB_CLEAR 0xFFC01524 /* Port G I/O Mask Disable Interrupt B Register */ +#define PORTGIO_MASKB_SET 0xFFC01528 /* Port G I/O Mask Enable Interrupt B Register */ +#define PORTGIO_MASKB_TOGGLE 0xFFC0152C /* Port G I/O Mask Toggle Enable Interrupt B Register */ +#define PORTGIO_DIR 0xFFC01530 /* Port G I/O Direction Register */ +#define PORTGIO_POLAR 0xFFC01534 /* Port G I/O Source Polarity Register */ +#define PORTGIO_EDGE 0xFFC01538 /* Port G I/O Source Sensitivity Register */ +#define PORTGIO_BOTH 0xFFC0153C /* Port G I/O Set on BOTH Edges Register */ +#define PORTGIO_INEN 0xFFC01540 /* Port G I/O Input Enable Register */ + +/* General Purpose I/O Port H (0xFFC01700 - 0xFFC017FF) */ +#define PORTHIO 0xFFC01700 /* Port H I/O Pin State Specify Register */ +#define PORTHIO_CLEAR 0xFFC01704 /* Port H I/O Peripheral Interrupt Clear Register */ +#define PORTHIO_SET 0xFFC01708 /* Port H I/O Peripheral Interrupt Set Register */ +#define PORTHIO_TOGGLE 0xFFC0170C /* Port H I/O Pin State Toggle Register */ +#define PORTHIO_MASKA 0xFFC01710 /* Port H I/O Mask State Specify Interrupt A Register */ +#define PORTHIO_MASKA_CLEAR 0xFFC01714 /* Port H I/O Mask Disable Interrupt A Register */ +#define PORTHIO_MASKA_SET 0xFFC01718 /* Port H I/O Mask Enable Interrupt A Register */ +#define PORTHIO_MASKA_TOGGLE 0xFFC0171C /* Port H I/O Mask Toggle Enable Interrupt A Register */ +#define PORTHIO_MASKB 0xFFC01720 /* Port H I/O Mask State Specify Interrupt B Register */ +#define PORTHIO_MASKB_CLEAR 0xFFC01724 /* Port H I/O Mask Disable Interrupt B Register */ +#define PORTHIO_MASKB_SET 0xFFC01728 /* Port H I/O Mask Enable Interrupt B Register */ +#define PORTHIO_MASKB_TOGGLE 0xFFC0172C /* Port H I/O Mask Toggle Enable Interrupt B Register */ +#define PORTHIO_DIR 0xFFC01730 /* Port H I/O Direction Register */ +#define PORTHIO_POLAR 0xFFC01734 /* Port H I/O Source Polarity Register */ +#define PORTHIO_EDGE 0xFFC01738 /* Port H I/O Source Sensitivity Register */ +#define PORTHIO_BOTH 0xFFC0173C /* Port H I/O Set on BOTH Edges Register */ +#define PORTHIO_INEN 0xFFC01740 /* Port H I/O Input Enable Register */ + +/* UART1 Controller (0xFFC02000 - 0xFFC020FF) */ +#define UART1_THR 0xFFC02000 /* Transmit Holding register */ +#define UART1_RBR 0xFFC02000 /* Receive Buffer register */ +#define UART1_DLL 0xFFC02000 /* Divisor Latch (Low-Byte) */ +#define UART1_IER 0xFFC02004 /* Interrupt Enable Register */ +#define UART1_DLH 0xFFC02004 /* Divisor Latch (High-Byte) */ +#define UART1_IIR 0xFFC02008 /* Interrupt Identification Register */ +#define UART1_LCR 0xFFC0200C /* Line Control Register */ +#define UART1_MCR 0xFFC02010 /* Modem Control Register */ +#define UART1_LSR 0xFFC02014 /* Line Status Register */ +#define UART1_MSR 0xFFC02018 /* Modem Status Register */ +#define UART1_SCR 0xFFC0201C /* SCR Scratch Register */ +#define UART1_GCTL 0xFFC02024 /* Global Control Register */ + +/* CAN Controller (0xFFC02A00 - 0xFFC02FFF) */ +/* For Mailboxes 0-15 */ +#define CAN_MC1 0xFFC02A00 /* Mailbox config reg 1 */ +#define CAN_MD1 0xFFC02A04 /* Mailbox direction reg 1 */ +#define CAN_TRS1 0xFFC02A08 /* Transmit Request Set reg 1 */ +#define CAN_TRR1 0xFFC02A0C /* Transmit Request Reset reg 1 */ +#define CAN_TA1 0xFFC02A10 /* Transmit Acknowledge reg 1 */ +#define CAN_AA1 0xFFC02A14 /* Transmit Abort Acknowledge reg 1 */ +#define CAN_RMP1 0xFFC02A18 /* Receive Message Pending reg 1 */ +#define CAN_RML1 0xFFC02A1C /* Receive Message Lost reg 1 */ +#define CAN_MBTIF1 0xFFC02A20 /* Mailbox Transmit Interrupt Flag reg 1 */ +#define CAN_MBRIF1 0xFFC02A24 /* Mailbox Receive Interrupt Flag reg 1 */ +#define CAN_MBIM1 0xFFC02A28 /* Mailbox Interrupt Mask reg 1 */ +#define CAN_RFH1 0xFFC02A2C /* Remote Frame Handling reg 1 */ +#define CAN_OPSS1 0xFFC02A30 /* Overwrite Protection Single Shot Xmit reg 1 */ + +/* For Mailboxes 16-31 */ +#define CAN_MC2 0xFFC02A40 /* Mailbox config reg 2 */ +#define CAN_MD2 0xFFC02A44 /* Mailbox direction reg 2 */ +#define CAN_TRS2 0xFFC02A48 /* Transmit Request Set reg 2 */ +#define CAN_TRR2 0xFFC02A4C /* Transmit Request Reset reg 2 */ +#define CAN_TA2 0xFFC02A50 /* Transmit Acknowledge reg 2 */ +#define CAN_AA2 0xFFC02A54 /* Transmit Abort Acknowledge reg 2 */ +#define CAN_RMP2 0xFFC02A58 /* Receive Message Pending reg 2 */ +#define CAN_RML2 0xFFC02A5C /* Receive Message Lost reg 2 */ +#define CAN_MBTIF2 0xFFC02A60 /* Mailbox Transmit Interrupt Flag reg 2 */ +#define CAN_MBRIF2 0xFFC02A64 /* Mailbox Receive Interrupt Flag reg 2 */ +#define CAN_MBIM2 0xFFC02A68 /* Mailbox Interrupt Mask reg 2 */ +#define CAN_RFH2 0xFFC02A6C /* Remote Frame Handling reg 2 */ +#define CAN_OPSS2 0xFFC02A70 /* Overwrite Protection Single Shot Xmit reg 2 */ + +/* CAN Configuration, Control, and Status Registers */ +#define CAN_CLOCK 0xFFC02A80 /* Bit Timing Configuration register 0 */ +#define CAN_TIMING 0xFFC02A84 /* Bit Timing Configuration register 1 */ +#define CAN_DEBUG 0xFFC02A88 /* Debug Register */ +#define CAN_STATUS 0xFFC02A8C /* Global Status Register */ +#define CAN_CEC 0xFFC02A90 /* Error Counter Register */ +#define CAN_GIS 0xFFC02A94 /* Global Interrupt Status Register */ +#define CAN_GIM 0xFFC02A98 /* Global Interrupt Mask Register */ +#define CAN_GIF 0xFFC02A9C /* Global Interrupt Flag Register */ +#define CAN_CONTROL 0xFFC02AA0 /* Master Control Register */ +#define CAN_INTR 0xFFC02AA4 /* Interrupt Pending Register */ +#define CAN_SFCMVER 0xFFC02AA8 /* Version Code Register */ +#define CAN_MBTD 0xFFC02AAC /* Mailbox Temporary Disable Feature */ +#define CAN_EWR 0xFFC02AB0 /* Programmable Warning Level */ +#define CAN_ESR 0xFFC02AB4 /* Error Status Register */ +#define CAN_UCREG 0xFFC02AC0 /* Universal Counter Register/Capture Register */ +#define CAN_UCCNT 0xFFC02AC4 /* Universal Counter */ +#define CAN_UCRC 0xFFC02AC8 /* Universal Counter Force Reload Register */ +#define CAN_UCCNF 0xFFC02ACC /* Universal Counter Configuration Register */ + +/* Mailbox Acceptance Masks */ +#define CAN_AM00L 0xFFC02B00 /* Mailbox 0 Low Acceptance Mask */ +#define CAN_AM00H 0xFFC02B04 /* Mailbox 0 High Acceptance Mask */ +#define CAN_AM01L 0xFFC02B08 /* Mailbox 1 Low Acceptance Mask */ +#define CAN_AM01H 0xFFC02B0C /* Mailbox 1 High Acceptance Mask */ +#define CAN_AM02L 0xFFC02B10 /* Mailbox 2 Low Acceptance Mask */ +#define CAN_AM02H 0xFFC02B14 /* Mailbox 2 High Acceptance Mask */ +#define CAN_AM03L 0xFFC02B18 /* Mailbox 3 Low Acceptance Mask */ +#define CAN_AM03H 0xFFC02B1C /* Mailbox 3 High Acceptance Mask */ +#define CAN_AM04L 0xFFC02B20 /* Mailbox 4 Low Acceptance Mask */ +#define CAN_AM04H 0xFFC02B24 /* Mailbox 4 High Acceptance Mask */ +#define CAN_AM05L 0xFFC02B28 /* Mailbox 5 Low Acceptance Mask */ +#define CAN_AM05H 0xFFC02B2C /* Mailbox 5 High Acceptance Mask */ +#define CAN_AM06L 0xFFC02B30 /* Mailbox 6 Low Acceptance Mask */ +#define CAN_AM06H 0xFFC02B34 /* Mailbox 6 High Acceptance Mask */ +#define CAN_AM07L 0xFFC02B38 /* Mailbox 7 Low Acceptance Mask */ +#define CAN_AM07H 0xFFC02B3C /* Mailbox 7 High Acceptance Mask */ +#define CAN_AM08L 0xFFC02B40 /* Mailbox 8 Low Acceptance Mask */ +#define CAN_AM08H 0xFFC02B44 /* Mailbox 8 High Acceptance Mask */ +#define CAN_AM09L 0xFFC02B48 /* Mailbox 9 Low Acceptance Mask */ +#define CAN_AM09H 0xFFC02B4C /* Mailbox 9 High Acceptance Mask */ +#define CAN_AM10L 0xFFC02B50 /* Mailbox 10 Low Acceptance Mask */ +#define CAN_AM10H 0xFFC02B54 /* Mailbox 10 High Acceptance Mask */ +#define CAN_AM11L 0xFFC02B58 /* Mailbox 11 Low Acceptance Mask */ +#define CAN_AM11H 0xFFC02B5C /* Mailbox 11 High Acceptance Mask */ +#define CAN_AM12L 0xFFC02B60 /* Mailbox 12 Low Acceptance Mask */ +#define CAN_AM12H 0xFFC02B64 /* Mailbox 12 High Acceptance Mask */ +#define CAN_AM13L 0xFFC02B68 /* Mailbox 13 Low Acceptance Mask */ +#define CAN_AM13H 0xFFC02B6C /* Mailbox 13 High Acceptance Mask */ +#define CAN_AM14L 0xFFC02B70 /* Mailbox 14 Low Acceptance Mask */ +#define CAN_AM14H 0xFFC02B74 /* Mailbox 14 High Acceptance Mask */ +#define CAN_AM15L 0xFFC02B78 /* Mailbox 15 Low Acceptance Mask */ +#define CAN_AM15H 0xFFC02B7C /* Mailbox 15 High Acceptance Mask */ + +#define CAN_AM16L 0xFFC02B80 /* Mailbox 16 Low Acceptance Mask */ +#define CAN_AM16H 0xFFC02B84 /* Mailbox 16 High Acceptance Mask */ +#define CAN_AM17L 0xFFC02B88 /* Mailbox 17 Low Acceptance Mask */ +#define CAN_AM17H 0xFFC02B8C /* Mailbox 17 High Acceptance Mask */ +#define CAN_AM18L 0xFFC02B90 /* Mailbox 18 Low Acceptance Mask */ +#define CAN_AM18H 0xFFC02B94 /* Mailbox 18 High Acceptance Mask */ +#define CAN_AM19L 0xFFC02B98 /* Mailbox 19 Low Acceptance Mask */ +#define CAN_AM19H 0xFFC02B9C /* Mailbox 19 High Acceptance Mask */ +#define CAN_AM20L 0xFFC02BA0 /* Mailbox 20 Low Acceptance Mask */ +#define CAN_AM20H 0xFFC02BA4 /* Mailbox 20 High Acceptance Mask */ +#define CAN_AM21L 0xFFC02BA8 /* Mailbox 21 Low Acceptance Mask */ +#define CAN_AM21H 0xFFC02BAC /* Mailbox 21 High Acceptance Mask */ +#define CAN_AM22L 0xFFC02BB0 /* Mailbox 22 Low Acceptance Mask */ +#define CAN_AM22H 0xFFC02BB4 /* Mailbox 22 High Acceptance Mask */ +#define CAN_AM23L 0xFFC02BB8 /* Mailbox 23 Low Acceptance Mask */ +#define CAN_AM23H 0xFFC02BBC /* Mailbox 23 High Acceptance Mask */ +#define CAN_AM24L 0xFFC02BC0 /* Mailbox 24 Low Acceptance Mask */ +#define CAN_AM24H 0xFFC02BC4 /* Mailbox 24 High Acceptance Mask */ +#define CAN_AM25L 0xFFC02BC8 /* Mailbox 25 Low Acceptance Mask */ +#define CAN_AM25H 0xFFC02BCC /* Mailbox 25 High Acceptance Mask */ +#define CAN_AM26L 0xFFC02BD0 /* Mailbox 26 Low Acceptance Mask */ +#define CAN_AM26H 0xFFC02BD4 /* Mailbox 26 High Acceptance Mask */ +#define CAN_AM27L 0xFFC02BD8 /* Mailbox 27 Low Acceptance Mask */ +#define CAN_AM27H 0xFFC02BDC /* Mailbox 27 High Acceptance Mask */ +#define CAN_AM28L 0xFFC02BE0 /* Mailbox 28 Low Acceptance Mask */ +#define CAN_AM28H 0xFFC02BE4 /* Mailbox 28 High Acceptance Mask */ +#define CAN_AM29L 0xFFC02BE8 /* Mailbox 29 Low Acceptance Mask */ +#define CAN_AM29H 0xFFC02BEC /* Mailbox 29 High Acceptance Mask */ +#define CAN_AM30L 0xFFC02BF0 /* Mailbox 30 Low Acceptance Mask */ +#define CAN_AM30H 0xFFC02BF4 /* Mailbox 30 High Acceptance Mask */ +#define CAN_AM31L 0xFFC02BF8 /* Mailbox 31 Low Acceptance Mask */ +#define CAN_AM31H 0xFFC02BFC /* Mailbox 31 High Acceptance Mask */ + +/* CAN Acceptance Mask Macros */ +#define CAN_AM_L(x) (CAN_AM00L+((x)*0x8)) +#define CAN_AM_H(x) (CAN_AM00H+((x)*0x8)) + +/* Mailbox Registers */ +#define CAN_MB00_DATA0 0xFFC02C00 /* Mailbox 0 Data Word 0 [15:0] Register */ +#define CAN_MB00_DATA1 0xFFC02C04 /* Mailbox 0 Data Word 1 [31:16] Register */ +#define CAN_MB00_DATA2 0xFFC02C08 /* Mailbox 0 Data Word 2 [47:32] Register */ +#define CAN_MB00_DATA3 0xFFC02C0C /* Mailbox 0 Data Word 3 [63:48] Register */ +#define CAN_MB00_LENGTH 0xFFC02C10 /* Mailbox 0 Data Length Code Register */ +#define CAN_MB00_TIMESTAMP 0xFFC02C14 /* Mailbox 0 Time Stamp Value Register */ +#define CAN_MB00_ID0 0xFFC02C18 /* Mailbox 0 Identifier Low Register */ +#define CAN_MB00_ID1 0xFFC02C1C /* Mailbox 0 Identifier High Register */ + +#define CAN_MB01_DATA0 0xFFC02C20 /* Mailbox 1 Data Word 0 [15:0] Register */ +#define CAN_MB01_DATA1 0xFFC02C24 /* Mailbox 1 Data Word 1 [31:16] Register */ +#define CAN_MB01_DATA2 0xFFC02C28 /* Mailbox 1 Data Word 2 [47:32] Register */ +#define CAN_MB01_DATA3 0xFFC02C2C /* Mailbox 1 Data Word 3 [63:48] Register */ +#define CAN_MB01_LENGTH 0xFFC02C30 /* Mailbox 1 Data Length Code Register */ +#define CAN_MB01_TIMESTAMP 0xFFC02C34 /* Mailbox 1 Time Stamp Value Register */ +#define CAN_MB01_ID0 0xFFC02C38 /* Mailbox 1 Identifier Low Register */ +#define CAN_MB01_ID1 0xFFC02C3C /* Mailbox 1 Identifier High Register */ + +#define CAN_MB02_DATA0 0xFFC02C40 /* Mailbox 2 Data Word 0 [15:0] Register */ +#define CAN_MB02_DATA1 0xFFC02C44 /* Mailbox 2 Data Word 1 [31:16] Register */ +#define CAN_MB02_DATA2 0xFFC02C48 /* Mailbox 2 Data Word 2 [47:32] Register */ +#define CAN_MB02_DATA3 0xFFC02C4C /* Mailbox 2 Data Word 3 [63:48] Register */ +#define CAN_MB02_LENGTH 0xFFC02C50 /* Mailbox 2 Data Length Code Register */ +#define CAN_MB02_TIMESTAMP 0xFFC02C54 /* Mailbox 2 Time Stamp Value Register */ +#define CAN_MB02_ID0 0xFFC02C58 /* Mailbox 2 Identifier Low Register */ +#define CAN_MB02_ID1 0xFFC02C5C /* Mailbox 2 Identifier High Register */ + +#define CAN_MB03_DATA0 0xFFC02C60 /* Mailbox 3 Data Word 0 [15:0] Register */ +#define CAN_MB03_DATA1 0xFFC02C64 /* Mailbox 3 Data Word 1 [31:16] Register */ +#define CAN_MB03_DATA2 0xFFC02C68 /* Mailbox 3 Data Word 2 [47:32] Register */ +#define CAN_MB03_DATA3 0xFFC02C6C /* Mailbox 3 Data Word 3 [63:48] Register */ +#define CAN_MB03_LENGTH 0xFFC02C70 /* Mailbox 3 Data Length Code Register */ +#define CAN_MB03_TIMESTAMP 0xFFC02C74 /* Mailbox 3 Time Stamp Value Register */ +#define CAN_MB03_ID0 0xFFC02C78 /* Mailbox 3 Identifier Low Register */ +#define CAN_MB03_ID1 0xFFC02C7C /* Mailbox 3 Identifier High Register */ + +#define CAN_MB04_DATA0 0xFFC02C80 /* Mailbox 4 Data Word 0 [15:0] Register */ +#define CAN_MB04_DATA1 0xFFC02C84 /* Mailbox 4 Data Word 1 [31:16] Register */ +#define CAN_MB04_DATA2 0xFFC02C88 /* Mailbox 4 Data Word 2 [47:32] Register */ +#define CAN_MB04_DATA3 0xFFC02C8C /* Mailbox 4 Data Word 3 [63:48] Register */ +#define CAN_MB04_LENGTH 0xFFC02C90 /* Mailbox 4 Data Length Code Register */ +#define CAN_MB04_TIMESTAMP 0xFFC02C94 /* Mailbox 4 Time Stamp Value Register */ +#define CAN_MB04_ID0 0xFFC02C98 /* Mailbox 4 Identifier Low Register */ +#define CAN_MB04_ID1 0xFFC02C9C /* Mailbox 4 Identifier High Register */ + +#define CAN_MB05_DATA0 0xFFC02CA0 /* Mailbox 5 Data Word 0 [15:0] Register */ +#define CAN_MB05_DATA1 0xFFC02CA4 /* Mailbox 5 Data Word 1 [31:16] Register */ +#define CAN_MB05_DATA2 0xFFC02CA8 /* Mailbox 5 Data Word 2 [47:32] Register */ +#define CAN_MB05_DATA3 0xFFC02CAC /* Mailbox 5 Data Word 3 [63:48] Register */ +#define CAN_MB05_LENGTH 0xFFC02CB0 /* Mailbox 5 Data Length Code Register */ +#define CAN_MB05_TIMESTAMP 0xFFC02CB4 /* Mailbox 5 Time Stamp Value Register */ +#define CAN_MB05_ID0 0xFFC02CB8 /* Mailbox 5 Identifier Low Register */ +#define CAN_MB05_ID1 0xFFC02CBC /* Mailbox 5 Identifier High Register */ + +#define CAN_MB06_DATA0 0xFFC02CC0 /* Mailbox 6 Data Word 0 [15:0] Register */ +#define CAN_MB06_DATA1 0xFFC02CC4 /* Mailbox 6 Data Word 1 [31:16] Register */ +#define CAN_MB06_DATA2 0xFFC02CC8 /* Mailbox 6 Data Word 2 [47:32] Register */ +#define CAN_MB06_DATA3 0xFFC02CCC /* Mailbox 6 Data Word 3 [63:48] Register */ +#define CAN_MB06_LENGTH 0xFFC02CD0 /* Mailbox 6 Data Length Code Register */ +#define CAN_MB06_TIMESTAMP 0xFFC02CD4 /* Mailbox 6 Time Stamp Value Register */ +#define CAN_MB06_ID0 0xFFC02CD8 /* Mailbox 6 Identifier Low Register */ +#define CAN_MB06_ID1 0xFFC02CDC /* Mailbox 6 Identifier High Register */ + +#define CAN_MB07_DATA0 0xFFC02CE0 /* Mailbox 7 Data Word 0 [15:0] Register */ +#define CAN_MB07_DATA1 0xFFC02CE4 /* Mailbox 7 Data Word 1 [31:16] Register */ +#define CAN_MB07_DATA2 0xFFC02CE8 /* Mailbox 7 Data Word 2 [47:32] Register */ +#define CAN_MB07_DATA3 0xFFC02CEC /* Mailbox 7 Data Word 3 [63:48] Register */ +#define CAN_MB07_LENGTH 0xFFC02CF0 /* Mailbox 7 Data Length Code Register */ +#define CAN_MB07_TIMESTAMP 0xFFC02CF4 /* Mailbox 7 Time Stamp Value Register */ +#define CAN_MB07_ID0 0xFFC02CF8 /* Mailbox 7 Identifier Low Register */ +#define CAN_MB07_ID1 0xFFC02CFC /* Mailbox 7 Identifier High Register */ + +#define CAN_MB08_DATA0 0xFFC02D00 /* Mailbox 8 Data Word 0 [15:0] Register */ +#define CAN_MB08_DATA1 0xFFC02D04 /* Mailbox 8 Data Word 1 [31:16] Register */ +#define CAN_MB08_DATA2 0xFFC02D08 /* Mailbox 8 Data Word 2 [47:32] Register */ +#define CAN_MB08_DATA3 0xFFC02D0C /* Mailbox 8 Data Word 3 [63:48] Register */ +#define CAN_MB08_LENGTH 0xFFC02D10 /* Mailbox 8 Data Length Code Register */ +#define CAN_MB08_TIMESTAMP 0xFFC02D14 /* Mailbox 8 Time Stamp Value Register */ +#define CAN_MB08_ID0 0xFFC02D18 /* Mailbox 8 Identifier Low Register */ +#define CAN_MB08_ID1 0xFFC02D1C /* Mailbox 8 Identifier High Register */ + +#define CAN_MB09_DATA0 0xFFC02D20 /* Mailbox 9 Data Word 0 [15:0] Register */ +#define CAN_MB09_DATA1 0xFFC02D24 /* Mailbox 9 Data Word 1 [31:16] Register */ +#define CAN_MB09_DATA2 0xFFC02D28 /* Mailbox 9 Data Word 2 [47:32] Register */ +#define CAN_MB09_DATA3 0xFFC02D2C /* Mailbox 9 Data Word 3 [63:48] Register */ +#define CAN_MB09_LENGTH 0xFFC02D30 /* Mailbox 9 Data Length Code Register */ +#define CAN_MB09_TIMESTAMP 0xFFC02D34 /* Mailbox 9 Time Stamp Value Register */ +#define CAN_MB09_ID0 0xFFC02D38 /* Mailbox 9 Identifier Low Register */ +#define CAN_MB09_ID1 0xFFC02D3C /* Mailbox 9 Identifier High Register */ + +#define CAN_MB10_DATA0 0xFFC02D40 /* Mailbox 10 Data Word 0 [15:0] Register */ +#define CAN_MB10_DATA1 0xFFC02D44 /* Mailbox 10 Data Word 1 [31:16] Register */ +#define CAN_MB10_DATA2 0xFFC02D48 /* Mailbox 10 Data Word 2 [47:32] Register */ +#define CAN_MB10_DATA3 0xFFC02D4C /* Mailbox 10 Data Word 3 [63:48] Register */ +#define CAN_MB10_LENGTH 0xFFC02D50 /* Mailbox 10 Data Length Code Register */ +#define CAN_MB10_TIMESTAMP 0xFFC02D54 /* Mailbox 10 Time Stamp Value Register */ +#define CAN_MB10_ID0 0xFFC02D58 /* Mailbox 10 Identifier Low Register */ +#define CAN_MB10_ID1 0xFFC02D5C /* Mailbox 10 Identifier High Register */ + +#define CAN_MB11_DATA0 0xFFC02D60 /* Mailbox 11 Data Word 0 [15:0] Register */ +#define CAN_MB11_DATA1 0xFFC02D64 /* Mailbox 11 Data Word 1 [31:16] Register */ +#define CAN_MB11_DATA2 0xFFC02D68 /* Mailbox 11 Data Word 2 [47:32] Register */ +#define CAN_MB11_DATA3 0xFFC02D6C /* Mailbox 11 Data Word 3 [63:48] Register */ +#define CAN_MB11_LENGTH 0xFFC02D70 /* Mailbox 11 Data Length Code Register */ +#define CAN_MB11_TIMESTAMP 0xFFC02D74 /* Mailbox 11 Time Stamp Value Register */ +#define CAN_MB11_ID0 0xFFC02D78 /* Mailbox 11 Identifier Low Register */ +#define CAN_MB11_ID1 0xFFC02D7C /* Mailbox 11 Identifier High Register */ + +#define CAN_MB12_DATA0 0xFFC02D80 /* Mailbox 12 Data Word 0 [15:0] Register */ +#define CAN_MB12_DATA1 0xFFC02D84 /* Mailbox 12 Data Word 1 [31:16] Register */ +#define CAN_MB12_DATA2 0xFFC02D88 /* Mailbox 12 Data Word 2 [47:32] Register */ +#define CAN_MB12_DATA3 0xFFC02D8C /* Mailbox 12 Data Word 3 [63:48] Register */ +#define CAN_MB12_LENGTH 0xFFC02D90 /* Mailbox 12 Data Length Code Register */ +#define CAN_MB12_TIMESTAMP 0xFFC02D94 /* Mailbox 12 Time Stamp Value Register */ +#define CAN_MB12_ID0 0xFFC02D98 /* Mailbox 12 Identifier Low Register */ +#define CAN_MB12_ID1 0xFFC02D9C /* Mailbox 12 Identifier High Register */ + +#define CAN_MB13_DATA0 0xFFC02DA0 /* Mailbox 13 Data Word 0 [15:0] Register */ +#define CAN_MB13_DATA1 0xFFC02DA4 /* Mailbox 13 Data Word 1 [31:16] Register */ +#define CAN_MB13_DATA2 0xFFC02DA8 /* Mailbox 13 Data Word 2 [47:32] Register */ +#define CAN_MB13_DATA3 0xFFC02DAC /* Mailbox 13 Data Word 3 [63:48] Register */ +#define CAN_MB13_LENGTH 0xFFC02DB0 /* Mailbox 13 Data Length Code Register */ +#define CAN_MB13_TIMESTAMP 0xFFC02DB4 /* Mailbox 13 Time Stamp Value Register */ +#define CAN_MB13_ID0 0xFFC02DB8 /* Mailbox 13 Identifier Low Register */ +#define CAN_MB13_ID1 0xFFC02DBC /* Mailbox 13 Identifier High Register */ + +#define CAN_MB14_DATA0 0xFFC02DC0 /* Mailbox 14 Data Word 0 [15:0] Register */ +#define CAN_MB14_DATA1 0xFFC02DC4 /* Mailbox 14 Data Word 1 [31:16] Register */ +#define CAN_MB14_DATA2 0xFFC02DC8 /* Mailbox 14 Data Word 2 [47:32] Register */ +#define CAN_MB14_DATA3 0xFFC02DCC /* Mailbox 14 Data Word 3 [63:48] Register */ +#define CAN_MB14_LENGTH 0xFFC02DD0 /* Mailbox 14 Data Length Code Register */ +#define CAN_MB14_TIMESTAMP 0xFFC02DD4 /* Mailbox 14 Time Stamp Value Register */ +#define CAN_MB14_ID0 0xFFC02DD8 /* Mailbox 14 Identifier Low Register */ +#define CAN_MB14_ID1 0xFFC02DDC /* Mailbox 14 Identifier High Register */ + +#define CAN_MB15_DATA0 0xFFC02DE0 /* Mailbox 15 Data Word 0 [15:0] Register */ +#define CAN_MB15_DATA1 0xFFC02DE4 /* Mailbox 15 Data Word 1 [31:16] Register */ +#define CAN_MB15_DATA2 0xFFC02DE8 /* Mailbox 15 Data Word 2 [47:32] Register */ +#define CAN_MB15_DATA3 0xFFC02DEC /* Mailbox 15 Data Word 3 [63:48] Register */ +#define CAN_MB15_LENGTH 0xFFC02DF0 /* Mailbox 15 Data Length Code Register */ +#define CAN_MB15_TIMESTAMP 0xFFC02DF4 /* Mailbox 15 Time Stamp Value Register */ +#define CAN_MB15_ID0 0xFFC02DF8 /* Mailbox 15 Identifier Low Register */ +#define CAN_MB15_ID1 0xFFC02DFC /* Mailbox 15 Identifier High Register */ + +#define CAN_MB16_DATA0 0xFFC02E00 /* Mailbox 16 Data Word 0 [15:0] Register */ +#define CAN_MB16_DATA1 0xFFC02E04 /* Mailbox 16 Data Word 1 [31:16] Register */ +#define CAN_MB16_DATA2 0xFFC02E08 /* Mailbox 16 Data Word 2 [47:32] Register */ +#define CAN_MB16_DATA3 0xFFC02E0C /* Mailbox 16 Data Word 3 [63:48] Register */ +#define CAN_MB16_LENGTH 0xFFC02E10 /* Mailbox 16 Data Length Code Register */ +#define CAN_MB16_TIMESTAMP 0xFFC02E14 /* Mailbox 16 Time Stamp Value Register */ +#define CAN_MB16_ID0 0xFFC02E18 /* Mailbox 16 Identifier Low Register */ +#define CAN_MB16_ID1 0xFFC02E1C /* Mailbox 16 Identifier High Register */ + +#define CAN_MB17_DATA0 0xFFC02E20 /* Mailbox 17 Data Word 0 [15:0] Register */ +#define CAN_MB17_DATA1 0xFFC02E24 /* Mailbox 17 Data Word 1 [31:16] Register */ +#define CAN_MB17_DATA2 0xFFC02E28 /* Mailbox 17 Data Word 2 [47:32] Register */ +#define CAN_MB17_DATA3 0xFFC02E2C /* Mailbox 17 Data Word 3 [63:48] Register */ +#define CAN_MB17_LENGTH 0xFFC02E30 /* Mailbox 17 Data Length Code Register */ +#define CAN_MB17_TIMESTAMP 0xFFC02E34 /* Mailbox 17 Time Stamp Value Register */ +#define CAN_MB17_ID0 0xFFC02E38 /* Mailbox 17 Identifier Low Register */ +#define CAN_MB17_ID1 0xFFC02E3C /* Mailbox 17 Identifier High Register */ + +#define CAN_MB18_DATA0 0xFFC02E40 /* Mailbox 18 Data Word 0 [15:0] Register */ +#define CAN_MB18_DATA1 0xFFC02E44 /* Mailbox 18 Data Word 1 [31:16] Register */ +#define CAN_MB18_DATA2 0xFFC02E48 /* Mailbox 18 Data Word 2 [47:32] Register */ +#define CAN_MB18_DATA3 0xFFC02E4C /* Mailbox 18 Data Word 3 [63:48] Register */ +#define CAN_MB18_LENGTH 0xFFC02E50 /* Mailbox 18 Data Length Code Register */ +#define CAN_MB18_TIMESTAMP 0xFFC02E54 /* Mailbox 18 Time Stamp Value Register */ +#define CAN_MB18_ID0 0xFFC02E58 /* Mailbox 18 Identifier Low Register */ +#define CAN_MB18_ID1 0xFFC02E5C /* Mailbox 18 Identifier High Register */ + +#define CAN_MB19_DATA0 0xFFC02E60 /* Mailbox 19 Data Word 0 [15:0] Register */ +#define CAN_MB19_DATA1 0xFFC02E64 /* Mailbox 19 Data Word 1 [31:16] Register */ +#define CAN_MB19_DATA2 0xFFC02E68 /* Mailbox 19 Data Word 2 [47:32] Register */ +#define CAN_MB19_DATA3 0xFFC02E6C /* Mailbox 19 Data Word 3 [63:48] Register */ +#define CAN_MB19_LENGTH 0xFFC02E70 /* Mailbox 19 Data Length Code Register */ +#define CAN_MB19_TIMESTAMP 0xFFC02E74 /* Mailbox 19 Time Stamp Value Register */ +#define CAN_MB19_ID0 0xFFC02E78 /* Mailbox 19 Identifier Low Register */ +#define CAN_MB19_ID1 0xFFC02E7C /* Mailbox 19 Identifier High Register */ + +#define CAN_MB20_DATA0 0xFFC02E80 /* Mailbox 20 Data Word 0 [15:0] Register */ +#define CAN_MB20_DATA1 0xFFC02E84 /* Mailbox 20 Data Word 1 [31:16] Register */ +#define CAN_MB20_DATA2 0xFFC02E88 /* Mailbox 20 Data Word 2 [47:32] Register */ +#define CAN_MB20_DATA3 0xFFC02E8C /* Mailbox 20 Data Word 3 [63:48] Register */ +#define CAN_MB20_LENGTH 0xFFC02E90 /* Mailbox 20 Data Length Code Register */ +#define CAN_MB20_TIMESTAMP 0xFFC02E94 /* Mailbox 20 Time Stamp Value Register */ +#define CAN_MB20_ID0 0xFFC02E98 /* Mailbox 20 Identifier Low Register */ +#define CAN_MB20_ID1 0xFFC02E9C /* Mailbox 20 Identifier High Register */ + +#define CAN_MB21_DATA0 0xFFC02EA0 /* Mailbox 21 Data Word 0 [15:0] Register */ +#define CAN_MB21_DATA1 0xFFC02EA4 /* Mailbox 21 Data Word 1 [31:16] Register */ +#define CAN_MB21_DATA2 0xFFC02EA8 /* Mailbox 21 Data Word 2 [47:32] Register */ +#define CAN_MB21_DATA3 0xFFC02EAC /* Mailbox 21 Data Word 3 [63:48] Register */ +#define CAN_MB21_LENGTH 0xFFC02EB0 /* Mailbox 21 Data Length Code Register */ +#define CAN_MB21_TIMESTAMP 0xFFC02EB4 /* Mailbox 21 Time Stamp Value Register */ +#define CAN_MB21_ID0 0xFFC02EB8 /* Mailbox 21 Identifier Low Register */ +#define CAN_MB21_ID1 0xFFC02EBC /* Mailbox 21 Identifier High Register */ + +#define CAN_MB22_DATA0 0xFFC02EC0 /* Mailbox 22 Data Word 0 [15:0] Register */ +#define CAN_MB22_DATA1 0xFFC02EC4 /* Mailbox 22 Data Word 1 [31:16] Register */ +#define CAN_MB22_DATA2 0xFFC02EC8 /* Mailbox 22 Data Word 2 [47:32] Register */ +#define CAN_MB22_DATA3 0xFFC02ECC /* Mailbox 22 Data Word 3 [63:48] Register */ +#define CAN_MB22_LENGTH 0xFFC02ED0 /* Mailbox 22 Data Length Code Register */ +#define CAN_MB22_TIMESTAMP 0xFFC02ED4 /* Mailbox 22 Time Stamp Value Register */ +#define CAN_MB22_ID0 0xFFC02ED8 /* Mailbox 22 Identifier Low Register */ +#define CAN_MB22_ID1 0xFFC02EDC /* Mailbox 22 Identifier High Register */ + +#define CAN_MB23_DATA0 0xFFC02EE0 /* Mailbox 23 Data Word 0 [15:0] Register */ +#define CAN_MB23_DATA1 0xFFC02EE4 /* Mailbox 23 Data Word 1 [31:16] Register */ +#define CAN_MB23_DATA2 0xFFC02EE8 /* Mailbox 23 Data Word 2 [47:32] Register */ +#define CAN_MB23_DATA3 0xFFC02EEC /* Mailbox 23 Data Word 3 [63:48] Register */ +#define CAN_MB23_LENGTH 0xFFC02EF0 /* Mailbox 23 Data Length Code Register */ +#define CAN_MB23_TIMESTAMP 0xFFC02EF4 /* Mailbox 23 Time Stamp Value Register */ +#define CAN_MB23_ID0 0xFFC02EF8 /* Mailbox 23 Identifier Low Register */ +#define CAN_MB23_ID1 0xFFC02EFC /* Mailbox 23 Identifier High Register */ + +#define CAN_MB24_DATA0 0xFFC02F00 /* Mailbox 24 Data Word 0 [15:0] Register */ +#define CAN_MB24_DATA1 0xFFC02F04 /* Mailbox 24 Data Word 1 [31:16] Register */ +#define CAN_MB24_DATA2 0xFFC02F08 /* Mailbox 24 Data Word 2 [47:32] Register */ +#define CAN_MB24_DATA3 0xFFC02F0C /* Mailbox 24 Data Word 3 [63:48] Register */ +#define CAN_MB24_LENGTH 0xFFC02F10 /* Mailbox 24 Data Length Code Register */ +#define CAN_MB24_TIMESTAMP 0xFFC02F14 /* Mailbox 24 Time Stamp Value Register */ +#define CAN_MB24_ID0 0xFFC02F18 /* Mailbox 24 Identifier Low Register */ +#define CAN_MB24_ID1 0xFFC02F1C /* Mailbox 24 Identifier High Register */ + +#define CAN_MB25_DATA0 0xFFC02F20 /* Mailbox 25 Data Word 0 [15:0] Register */ +#define CAN_MB25_DATA1 0xFFC02F24 /* Mailbox 25 Data Word 1 [31:16] Register */ +#define CAN_MB25_DATA2 0xFFC02F28 /* Mailbox 25 Data Word 2 [47:32] Register */ +#define CAN_MB25_DATA3 0xFFC02F2C /* Mailbox 25 Data Word 3 [63:48] Register */ +#define CAN_MB25_LENGTH 0xFFC02F30 /* Mailbox 25 Data Length Code Register */ +#define CAN_MB25_TIMESTAMP 0xFFC02F34 /* Mailbox 25 Time Stamp Value Register */ +#define CAN_MB25_ID0 0xFFC02F38 /* Mailbox 25 Identifier Low Register */ +#define CAN_MB25_ID1 0xFFC02F3C /* Mailbox 25 Identifier High Register */ + +#define CAN_MB26_DATA0 0xFFC02F40 /* Mailbox 26 Data Word 0 [15:0] Register */ +#define CAN_MB26_DATA1 0xFFC02F44 /* Mailbox 26 Data Word 1 [31:16] Register */ +#define CAN_MB26_DATA2 0xFFC02F48 /* Mailbox 26 Data Word 2 [47:32] Register */ +#define CAN_MB26_DATA3 0xFFC02F4C /* Mailbox 26 Data Word 3 [63:48] Register */ +#define CAN_MB26_LENGTH 0xFFC02F50 /* Mailbox 26 Data Length Code Register */ +#define CAN_MB26_TIMESTAMP 0xFFC02F54 /* Mailbox 26 Time Stamp Value Register */ +#define CAN_MB26_ID0 0xFFC02F58 /* Mailbox 26 Identifier Low Register */ +#define CAN_MB26_ID1 0xFFC02F5C /* Mailbox 26 Identifier High Register */ + +#define CAN_MB27_DATA0 0xFFC02F60 /* Mailbox 27 Data Word 0 [15:0] Register */ +#define CAN_MB27_DATA1 0xFFC02F64 /* Mailbox 27 Data Word 1 [31:16] Register */ +#define CAN_MB27_DATA2 0xFFC02F68 /* Mailbox 27 Data Word 2 [47:32] Register */ +#define CAN_MB27_DATA3 0xFFC02F6C /* Mailbox 27 Data Word 3 [63:48] Register */ +#define CAN_MB27_LENGTH 0xFFC02F70 /* Mailbox 27 Data Length Code Register */ +#define CAN_MB27_TIMESTAMP 0xFFC02F74 /* Mailbox 27 Time Stamp Value Register */ +#define CAN_MB27_ID0 0xFFC02F78 /* Mailbox 27 Identifier Low Register */ +#define CAN_MB27_ID1 0xFFC02F7C /* Mailbox 27 Identifier High Register */ + +#define CAN_MB28_DATA0 0xFFC02F80 /* Mailbox 28 Data Word 0 [15:0] Register */ +#define CAN_MB28_DATA1 0xFFC02F84 /* Mailbox 28 Data Word 1 [31:16] Register */ +#define CAN_MB28_DATA2 0xFFC02F88 /* Mailbox 28 Data Word 2 [47:32] Register */ +#define CAN_MB28_DATA3 0xFFC02F8C /* Mailbox 28 Data Word 3 [63:48] Register */ +#define CAN_MB28_LENGTH 0xFFC02F90 /* Mailbox 28 Data Length Code Register */ +#define CAN_MB28_TIMESTAMP 0xFFC02F94 /* Mailbox 28 Time Stamp Value Register */ +#define CAN_MB28_ID0 0xFFC02F98 /* Mailbox 28 Identifier Low Register */ +#define CAN_MB28_ID1 0xFFC02F9C /* Mailbox 28 Identifier High Register */ + +#define CAN_MB29_DATA0 0xFFC02FA0 /* Mailbox 29 Data Word 0 [15:0] Register */ +#define CAN_MB29_DATA1 0xFFC02FA4 /* Mailbox 29 Data Word 1 [31:16] Register */ +#define CAN_MB29_DATA2 0xFFC02FA8 /* Mailbox 29 Data Word 2 [47:32] Register */ +#define CAN_MB29_DATA3 0xFFC02FAC /* Mailbox 29 Data Word 3 [63:48] Register */ +#define CAN_MB29_LENGTH 0xFFC02FB0 /* Mailbox 29 Data Length Code Register */ +#define CAN_MB29_TIMESTAMP 0xFFC02FB4 /* Mailbox 29 Time Stamp Value Register */ +#define CAN_MB29_ID0 0xFFC02FB8 /* Mailbox 29 Identifier Low Register */ +#define CAN_MB29_ID1 0xFFC02FBC /* Mailbox 29 Identifier High Register */ + +#define CAN_MB30_DATA0 0xFFC02FC0 /* Mailbox 30 Data Word 0 [15:0] Register */ +#define CAN_MB30_DATA1 0xFFC02FC4 /* Mailbox 30 Data Word 1 [31:16] Register */ +#define CAN_MB30_DATA2 0xFFC02FC8 /* Mailbox 30 Data Word 2 [47:32] Register */ +#define CAN_MB30_DATA3 0xFFC02FCC /* Mailbox 30 Data Word 3 [63:48] Register */ +#define CAN_MB30_LENGTH 0xFFC02FD0 /* Mailbox 30 Data Length Code Register */ +#define CAN_MB30_TIMESTAMP 0xFFC02FD4 /* Mailbox 30 Time Stamp Value Register */ +#define CAN_MB30_ID0 0xFFC02FD8 /* Mailbox 30 Identifier Low Register */ +#define CAN_MB30_ID1 0xFFC02FDC /* Mailbox 30 Identifier High Register */ + +#define CAN_MB31_DATA0 0xFFC02FE0 /* Mailbox 31 Data Word 0 [15:0] Register */ +#define CAN_MB31_DATA1 0xFFC02FE4 /* Mailbox 31 Data Word 1 [31:16] Register */ +#define CAN_MB31_DATA2 0xFFC02FE8 /* Mailbox 31 Data Word 2 [47:32] Register */ +#define CAN_MB31_DATA3 0xFFC02FEC /* Mailbox 31 Data Word 3 [63:48] Register */ +#define CAN_MB31_LENGTH 0xFFC02FF0 /* Mailbox 31 Data Length Code Register */ +#define CAN_MB31_TIMESTAMP 0xFFC02FF4 /* Mailbox 31 Time Stamp Value Register */ +#define CAN_MB31_ID0 0xFFC02FF8 /* Mailbox 31 Identifier Low Register */ +#define CAN_MB31_ID1 0xFFC02FFC /* Mailbox 31 Identifier High Register */ + +/* CAN Mailbox Area Macros */ +#define CAN_MB_ID1(x) (CAN_MB00_ID1+((x)*0x20)) +#define CAN_MB_ID0(x) (CAN_MB00_ID0+((x)*0x20)) +#define CAN_MB_TIMESTAMP(x) (CAN_MB00_TIMESTAMP+((x)*0x20)) +#define CAN_MB_LENGTH(x) (CAN_MB00_LENGTH+((x)*0x20)) +#define CAN_MB_DATA3(x) (CAN_MB00_DATA3+((x)*0x20)) +#define CAN_MB_DATA2(x) (CAN_MB00_DATA2+((x)*0x20)) +#define CAN_MB_DATA1(x) (CAN_MB00_DATA1+((x)*0x20)) +#define CAN_MB_DATA0(x) (CAN_MB00_DATA0+((x)*0x20)) + +/* Pin Control Registers (0xFFC03200 - 0xFFC032FF) */ +#define PORTF_FER 0xFFC03200 /* Port F Function Enable Register (Alternate/Flag*) */ +#define PORTG_FER 0xFFC03204 /* Port G Function Enable Register (Alternate/Flag*) */ +#define PORTH_FER 0xFFC03208 /* Port H Function Enable Register (Alternate/Flag*) */ +#define BFIN_PORT_MUX 0xFFC0320C /* Port Multiplexer Control Register */ + +/* Handshake MDMA Registers (0xFFC03300 - 0xFFC033FF) */ +#define HMDMA0_CONTROL 0xFFC03300 /* Handshake MDMA0 Control Register */ +#define HMDMA0_ECINIT 0xFFC03304 /* HMDMA0 Initial Edge Count Register */ +#define HMDMA0_BCINIT 0xFFC03308 /* HMDMA0 Initial Block Count Register */ +#define HMDMA0_ECURGENT 0xFFC0330C /* HMDMA0 Urgent Edge Count Threshhold Register */ +#define HMDMA0_ECOVERFLOW 0xFFC03310 /* HMDMA0 Edge Count Overflow Interrupt Register */ +#define HMDMA0_ECOUNT 0xFFC03314 /* HMDMA0 Current Edge Count Register */ +#define HMDMA0_BCOUNT 0xFFC03318 /* HMDMA0 Current Block Count Register */ + +#define HMDMA1_CONTROL 0xFFC03340 /* Handshake MDMA1 Control Register */ +#define HMDMA1_ECINIT 0xFFC03344 /* HMDMA1 Initial Edge Count Register */ +#define HMDMA1_BCINIT 0xFFC03348 /* HMDMA1 Initial Block Count Register */ +#define HMDMA1_ECURGENT 0xFFC0334C /* HMDMA1 Urgent Edge Count Threshhold Register */ +#define HMDMA1_ECOVERFLOW 0xFFC03350 /* HMDMA1 Edge Count Overflow Interrupt Register */ +#define HMDMA1_ECOUNT 0xFFC03354 /* HMDMA1 Current Edge Count Register */ +#define HMDMA1_BCOUNT 0xFFC03358 /* HMDMA1 Current Block Count Register */ + +/*********************************************************************************** +** System MMR Register Bits And Macros +** +** Disclaimer: All macros are intended to make C and Assembly code more readable. +** Use these macros carefully, as any that do left shifts for field +** depositing will result in the lower order bits being destroyed. Any +** macro that shifts left to properly position the bit-field should be +** used as part of an OR to initialize a register and NOT as a dynamic +** modifier UNLESS the lower order bits are saved and ORed back in when +** the macro is used. +*************************************************************************************/ +/* +** ********************* PLL AND RESET MASKS ****************************************/ +/* PLL_CTL Masks */ +#define DF 0x0001 /* 0: PLL = CLKIN, 1: PLL = CLKIN/2 */ +#define PLL_OFF 0x0002 /* PLL Not Powered */ +#define STOPCK 0x0008 /* Core Clock Off */ +#define PDWN 0x0020 /* Enter Deep Sleep Mode */ +#define IN_DELAY 0x0040 /* Add 200ps Delay To EBIU Input Latches */ +#define OUT_DELAY 0x0080 /* Add 200ps Delay To EBIU Output Signals */ +#define BYPASS 0x0100 /* Bypass the PLL */ +#define MSEL 0x7E00 /* Multiplier Select For CCLK/VCO Factors */ +/* PLL_CTL Macros (Only Use With Logic OR While Setting Lower Order Bits) */ +#define SET_MSEL(x) (((x)&0x3F) << 0x9) /* Set MSEL = 0-63 --> VCO = CLKIN*MSEL */ + +/* PLL_DIV Masks */ +#define SSEL 0x000F /* System Select */ +#define CSEL 0x0030 /* Core Select */ +#define CSEL_DIV1 0x0000 /* CCLK = VCO / 1 */ +#define CSEL_DIV2 0x0010 /* CCLK = VCO / 2 */ +#define CSEL_DIV4 0x0020 /* CCLK = VCO / 4 */ +#define CSEL_DIV8 0x0030 /* CCLK = VCO / 8 */ +/* PLL_DIV Macros */ +#define SET_SSEL(x) ((x)&0xF) /* Set SSEL = 0-15 --> SCLK = VCO/SSEL */ + +/* VR_CTL Masks */ +#define FREQ 0x0003 /* Switching Oscillator Frequency For Regulator */ +#define HIBERNATE 0x0000 /* Powerdown/Bypass On-Board Regulation */ +#define FREQ_333 0x0001 /* Switching Frequency Is 333 kHz */ +#define FREQ_667 0x0002 /* Switching Frequency Is 667 kHz */ +#define FREQ_1000 0x0003 /* Switching Frequency Is 1 MHz */ + +#define GAIN 0x000C /* Voltage Level Gain */ +#define GAIN_5 0x0000 /* GAIN = 5 */ +#define GAIN_10 0x0004 /* GAIN = 10 */ +#define GAIN_20 0x0008 /* GAIN = 20 */ +#define GAIN_50 0x000C /* GAIN = 50 */ + +#define VLEV 0x00F0 /* Internal Voltage Level */ +#define VLEV_085 0x0060 /* VLEV = 0.85 V (-5% - +10% Accuracy) */ +#define VLEV_090 0x0070 /* VLEV = 0.90 V (-5% - +10% Accuracy) */ +#define VLEV_095 0x0080 /* VLEV = 0.95 V (-5% - +10% Accuracy) */ +#define VLEV_100 0x0090 /* VLEV = 1.00 V (-5% - +10% Accuracy) */ +#define VLEV_105 0x00A0 /* VLEV = 1.05 V (-5% - +10% Accuracy) */ +#define VLEV_110 0x00B0 /* VLEV = 1.10 V (-5% - +10% Accuracy) */ +#define VLEV_115 0x00C0 /* VLEV = 1.15 V (-5% - +10% Accuracy) */ +#define VLEV_120 0x00D0 /* VLEV = 1.20 V (-5% - +10% Accuracy) */ +#define VLEV_125 0x00E0 /* VLEV = 1.25 V (-5% - +10% Accuracy) */ +#define VLEV_130 0x00F0 /* VLEV = 1.30 V (-5% - +10% Accuracy) */ + +#define WAKE 0x0100 /* Enable RTC/Reset Wakeup From Hibernate */ +#define PHYWE 0x0200 /* Enable PHY Wakeup From Hibernate */ +#define CANWE 0x0400 /* Enable CAN Wakeup From Hibernate */ +#define PHYCLKOE 0x4000 /* PHY Clock Output Enable */ +#define CKELOW 0x8000 /* Enable Drive CKE Low During Reset */ + +/* PLL_STAT Masks */ +#define ACTIVE_PLLENABLED 0x0001 /* Processor In Active Mode With PLL Enabled */ +#define FULL_ON 0x0002 /* Processor In Full On Mode */ +#define ACTIVE_PLLDISABLED 0x0004 /* Processor In Active Mode With PLL Disabled */ +#define PLL_LOCKED 0x0020 /* PLL_LOCKCNT Has Been Reached */ + +/* CHIPID Masks */ +#define CHIPID_VERSION 0xF0000000 +#define CHIPID_FAMILY 0x0FFFF000 +#define CHIPID_MANUFACTURE 0x00000FFE + +/* SWRST Masks */ +#define SYSTEM_RESET 0x0007 /* Initiates A System Software Reset */ +#define DOUBLE_FAULT 0x0008 /* Core Double Fault Causes Reset */ +#define RESET_DOUBLE 0x2000 /* SW Reset Generated By Core Double-Fault */ +#define RESET_WDOG 0x4000 /* SW Reset Generated By Watchdog Timer */ +#define RESET_SOFTWARE 0x8000 /* SW Reset Occurred Since Last Read Of SWRST */ + +/* SYSCR Masks */ +#define BMODE 0x0006 /* Boot Mode - Latched During HW Reset From Mode Pins */ +#define NOBOOT 0x0010 /* Execute From L1 or ASYNC Bank 0 When BMODE = 0 */ + +/* ************* SYSTEM INTERRUPT CONTROLLER MASKS *************************************/ + +/* SIC_IAR0 Macros */ +#define P0_IVG(x) (((x)&0xF)-7) /* Peripheral #0 assigned IVG #x */ +#define P1_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #1 assigned IVG #x */ +#define P2_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #2 assigned IVG #x */ +#define P3_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #3 assigned IVG #x */ +#define P4_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #4 assigned IVG #x */ +#define P5_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #5 assigned IVG #x */ +#define P6_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #6 assigned IVG #x */ +#define P7_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #7 assigned IVG #x */ + +/* SIC_IAR1 Macros */ +#define P8_IVG(x) (((x)&0xF)-7) /* Peripheral #8 assigned IVG #x */ +#define P9_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #9 assigned IVG #x */ +#define P10_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #10 assigned IVG #x */ +#define P11_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #11 assigned IVG #x */ +#define P12_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #12 assigned IVG #x */ +#define P13_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #13 assigned IVG #x */ +#define P14_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #14 assigned IVG #x */ +#define P15_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #15 assigned IVG #x */ + +/* SIC_IAR2 Macros */ +#define P16_IVG(x) (((x)&0xF)-7) /* Peripheral #16 assigned IVG #x */ +#define P17_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #17 assigned IVG #x */ +#define P18_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #18 assigned IVG #x */ +#define P19_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #19 assigned IVG #x */ +#define P20_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #20 assigned IVG #x */ +#define P21_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #21 assigned IVG #x */ +#define P22_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #22 assigned IVG #x */ +#define P23_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #23 assigned IVG #x */ + +/* SIC_IAR3 Macros */ +#define P24_IVG(x) (((x)&0xF)-7) /* Peripheral #24 assigned IVG #x */ +#define P25_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #25 assigned IVG #x */ +#define P26_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #26 assigned IVG #x */ +#define P27_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #27 assigned IVG #x */ +#define P28_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #28 assigned IVG #x */ +#define P29_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #29 assigned IVG #x */ +#define P30_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #30 assigned IVG #x */ +#define P31_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #31 assigned IVG #x */ + +/* SIC_IMASK Masks */ +#define SIC_UNMASK_ALL 0x00000000 /* Unmask all peripheral interrupts */ +#define SIC_MASK_ALL 0xFFFFFFFF /* Mask all peripheral interrupts */ +#define SIC_MASK(x) (1 << ((x)&0x1F)) /* Mask Peripheral #x interrupt */ +#define SIC_UNMASK(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Unmask Peripheral #x interrupt */ + +/* SIC_IWR Masks */ +#define IWR_DISABLE_ALL 0x00000000 /* Wakeup Disable all peripherals */ +#define IWR_ENABLE_ALL 0xFFFFFFFF /* Wakeup Enable all peripherals */ +#define IWR_ENABLE(x) (1 << ((x)&0x1F)) /* Wakeup Enable Peripheral #x */ +#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Wakeup Disable Peripheral #x */ + +/* *************** WATCHDOG TIMER MASKS *******************************************/ +/* WDOG_CTL Masks */ +#define WDOG_RESET 0x0000 /* Generate Reset Event */ +#define WDOG_NMI 0x0002 /* Generate Non-Maskable Interrupt (NMI) Event */ +#define WDOG_GPI 0x0004 /* Generate General Purpose (GP) Interrupt */ +#define WDOG_NONE 0x0006 /* Disable Watchdog Timer Interrupts */ +#define TMR_EN 0x0FF0 /* Watchdog Counter Enable */ +#define TMR_DIS 0x0AD0 /* Watchdog Counter Disable */ +#define TRO 0x8000 /* Watchdog Expired */ + +/* ************** UART CONTROLLER MASKS *************************/ +/* UARTx_LCR Masks */ +#define WLS(x) ((((x)&0x3)-5) & 0x03) /* Word Length Select */ +#define STB 0x04 /* Stop Bits */ +#define PEN 0x08 /* Parity Enable */ +#define EPS 0x10 /* Even Parity Select */ +#define STP 0x20 /* Stick Parity */ +#define SB 0x40 /* Set Break */ +#define DLAB 0x80 /* Divisor Latch Access */ + +/* UARTx_MCR Mask */ +#define LOOP 0x10 /* Loopback Mode Enable */ + +/* UARTx_LSR Masks */ +#define DR 0x01 /* Data Ready */ +#define OE 0x02 /* Overrun Error */ +#define PE 0x04 /* Parity Error */ +#define FE 0x08 /* Framing Error */ +#define BI 0x10 /* Break Interrupt */ +#define THRE 0x20 /* THR Empty */ +#define TEMT 0x40 /* TSR and UART_THR Empty */ + +/* UARTx_IER Masks */ +#define ERBFI 0x01 /* Enable Receive Buffer Full Interrupt */ +#define ETBEI 0x02 /* Enable Transmit Buffer Empty Interrupt */ +#define ELSI 0x04 /* Enable RX Status Interrupt */ + +/* UARTx_IIR Masks */ +#define NINT 0x01 /* Pending Interrupt */ +#define IIR_TX_READY 0x02 /* UART_THR empty */ +#define IIR_RX_READY 0x04 /* Receive data ready */ +#define IIR_LINE_CHANGE 0x06 /* Receive line status */ +#define IIR_STATUS 0x06 + +/* UARTx_GCTL Masks */ +#define UCEN 0x01 /* Enable UARTx Clocks */ +#define IREN 0x02 /* Enable IrDA Mode */ +#define TPOLC 0x04 /* IrDA TX Polarity Change */ +#define RPOLC 0x08 /* IrDA RX Polarity Change */ +#define FPE 0x10 /* Force Parity Error On Transmit */ +#define FFE 0x20 /* Force Framing Error On Transmit */ + +/* *********** SERIAL PERIPHERAL INTERFACE (SPI) MASKS ****************************/ +/* SPI_CTL Masks */ +#define TIMOD 0x0003 /* Transfer Initiate Mode */ +#define RDBR_CORE 0x0000 /* RDBR Read Initiates, IRQ When RDBR Full */ +#define TDBR_CORE 0x0001 /* TDBR Write Initiates, IRQ When TDBR Empty */ +#define RDBR_DMA 0x0002 /* DMA Read, DMA Until FIFO Empty */ +#define TDBR_DMA 0x0003 /* DMA Write, DMA Until FIFO Full */ +#define SZ 0x0004 /* Send Zero (When TDBR Empty, Send Zero/Last*) */ +#define GM 0x0008 /* Get More (When RDBR Full, Overwrite/Discard*) */ +#define PSSE 0x0010 /* Slave-Select Input Enable */ +#define EMISO 0x0020 /* Enable MISO As Output */ +#define SPI_SIZE 0x0100 /* Size of Words (16/8* Bits) */ +#define LSBF 0x0200 /* LSB First */ +#define CPHA 0x0400 /* Clock Phase */ +#define CPOL 0x0800 /* Clock Polarity */ +#define MSTR 0x1000 /* Master/Slave* */ +#define WOM 0x2000 /* Write Open Drain Master */ +#define SPE 0x4000 /* SPI Enable */ + +/* SPI_FLG Masks */ +#define FLS1 0x0002 /* Enables SPI_FLOUT1 as SPI Slave-Select Output */ +#define FLS2 0x0004 /* Enables SPI_FLOUT2 as SPI Slave-Select Output */ +#define FLS3 0x0008 /* Enables SPI_FLOUT3 as SPI Slave-Select Output */ +#define FLS4 0x0010 /* Enables SPI_FLOUT4 as SPI Slave-Select Output */ +#define FLS5 0x0020 /* Enables SPI_FLOUT5 as SPI Slave-Select Output */ +#define FLS6 0x0040 /* Enables SPI_FLOUT6 as SPI Slave-Select Output */ +#define FLS7 0x0080 /* Enables SPI_FLOUT7 as SPI Slave-Select Output */ +#define FLG1 0xFDFF /* Activates SPI_FLOUT1 */ +#define FLG2 0xFBFF /* Activates SPI_FLOUT2 */ +#define FLG3 0xF7FF /* Activates SPI_FLOUT3 */ +#define FLG4 0xEFFF /* Activates SPI_FLOUT4 */ +#define FLG5 0xDFFF /* Activates SPI_FLOUT5 */ +#define FLG6 0xBFFF /* Activates SPI_FLOUT6 */ +#define FLG7 0x7FFF /* Activates SPI_FLOUT7 */ + +/* SPI_STAT Masks */ +#define SPIF 0x0001 /* SPI Finished (Single-Word Transfer Complete) */ +#define MODF 0x0002 /* Mode Fault Error (Another Device Tried To Become Master) */ +#define TXE 0x0004 /* Transmission Error (Data Sent With No New Data In TDBR) */ +#define TXS 0x0008 /* SPI_TDBR Data Buffer Status (Full/Empty*) */ +#define RBSY 0x0010 /* Receive Error (Data Received With RDBR Full) */ +#define RXS 0x0020 /* SPI_RDBR Data Buffer Status (Full/Empty*) */ +#define TXCOL 0x0040 /* Transmit Collision Error (Corrupt Data May Have Been Sent) */ + +/* **************** GENERAL PURPOSE TIMER MASKS **********************/ +/* TIMER_ENABLE Masks */ +#define TIMEN0 0x0001 /* Enable Timer 0 */ +#define TIMEN1 0x0002 /* Enable Timer 1 */ +#define TIMEN2 0x0004 /* Enable Timer 2 */ +#define TIMEN3 0x0008 /* Enable Timer 3 */ +#define TIMEN4 0x0010 /* Enable Timer 4 */ +#define TIMEN5 0x0020 /* Enable Timer 5 */ +#define TIMEN6 0x0040 /* Enable Timer 6 */ +#define TIMEN7 0x0080 /* Enable Timer 7 */ + +/* TIMER_DISABLE Masks */ +#define TIMDIS0 TIMEN0 /* Disable Timer 0 */ +#define TIMDIS1 TIMEN1 /* Disable Timer 1 */ +#define TIMDIS2 TIMEN2 /* Disable Timer 2 */ +#define TIMDIS3 TIMEN3 /* Disable Timer 3 */ +#define TIMDIS4 TIMEN4 /* Disable Timer 4 */ +#define TIMDIS5 TIMEN5 /* Disable Timer 5 */ +#define TIMDIS6 TIMEN6 /* Disable Timer 6 */ +#define TIMDIS7 TIMEN7 /* Disable Timer 7 */ + +/* TIMER_STATUS Masks */ +#define TIMIL0 0x00000001 /* Timer 0 Interrupt */ +#define TIMIL1 0x00000002 /* Timer 1 Interrupt */ +#define TIMIL2 0x00000004 /* Timer 2 Interrupt */ +#define TIMIL3 0x00000008 /* Timer 3 Interrupt */ +#define TOVL_ERR0 0x00000010 /* Timer 0 Counter Overflow */ +#define TOVL_ERR1 0x00000020 /* Timer 1 Counter Overflow */ +#define TOVL_ERR2 0x00000040 /* Timer 2 Counter Overflow */ +#define TOVL_ERR3 0x00000080 /* Timer 3 Counter Overflow */ +#define TRUN0 0x00001000 /* Timer 0 Slave Enable Status */ +#define TRUN1 0x00002000 /* Timer 1 Slave Enable Status */ +#define TRUN2 0x00004000 /* Timer 2 Slave Enable Status */ +#define TRUN3 0x00008000 /* Timer 3 Slave Enable Status */ +#define TIMIL4 0x00010000 /* Timer 4 Interrupt */ +#define TIMIL5 0x00020000 /* Timer 5 Interrupt */ +#define TIMIL6 0x00040000 /* Timer 6 Interrupt */ +#define TIMIL7 0x00080000 /* Timer 7 Interrupt */ +#define TOVL_ERR4 0x00100000 /* Timer 4 Counter Overflow */ +#define TOVL_ERR5 0x00200000 /* Timer 5 Counter Overflow */ +#define TOVL_ERR6 0x00400000 /* Timer 6 Counter Overflow */ +#define TOVL_ERR7 0x00800000 /* Timer 7 Counter Overflow */ +#define TRUN4 0x10000000 /* Timer 4 Slave Enable Status */ +#define TRUN5 0x20000000 /* Timer 5 Slave Enable Status */ +#define TRUN6 0x40000000 /* Timer 6 Slave Enable Status */ +#define TRUN7 0x80000000 /* Timer 7 Slave Enable Status */ + +/* TIMERx_CONFIG Masks */ +#define PWM_OUT 0x0001 /* Pulse-Width Modulation Output Mode */ +#define WDTH_CAP 0x0002 /* Width Capture Input Mode */ +#define EXT_CLK 0x0003 /* External Clock Mode */ +#define PULSE_HI 0x0004 /* Action Pulse (Positive/Negative*) */ +#define PERIOD_CNT 0x0008 /* Period Count */ +#define IRQ_ENA 0x0010 /* Interrupt Request Enable */ +#define TIN_SEL 0x0020 /* Timer Input Select */ +#define OUT_DIS 0x0040 /* Output Pad Disable */ +#define CLK_SEL 0x0080 /* Timer Clock Select */ +#define TOGGLE_HI 0x0100 /* PWM_OUT PULSE_HI Toggle Mode */ +#define EMU_RUN 0x0200 /* Emulation Behavior Select */ +#define ERR_TYP 0xC000 /* Error Type */ + +/* ****************** GPIO PORTS F, G, H MASKS ***********************/ +/* General Purpose IO (0xFFC00700 - 0xFFC007FF) Masks */ +/* Port F Masks */ +#define PF0 0x0001 +#define PF1 0x0002 +#define PF2 0x0004 +#define PF3 0x0008 +#define PF4 0x0010 +#define PF5 0x0020 +#define PF6 0x0040 +#define PF7 0x0080 +#define PF8 0x0100 +#define PF9 0x0200 +#define PF10 0x0400 +#define PF11 0x0800 +#define PF12 0x1000 +#define PF13 0x2000 +#define PF14 0x4000 +#define PF15 0x8000 + +/* Port G Masks */ +#define PG0 0x0001 +#define PG1 0x0002 +#define PG2 0x0004 +#define PG3 0x0008 +#define PG4 0x0010 +#define PG5 0x0020 +#define PG6 0x0040 +#define PG7 0x0080 +#define PG8 0x0100 +#define PG9 0x0200 +#define PG10 0x0400 +#define PG11 0x0800 +#define PG12 0x1000 +#define PG13 0x2000 +#define PG14 0x4000 +#define PG15 0x8000 + +/* Port H Masks */ +#define PH0 0x0001 +#define PH1 0x0002 +#define PH2 0x0004 +#define PH3 0x0008 +#define PH4 0x0010 +#define PH5 0x0020 +#define PH6 0x0040 +#define PH7 0x0080 +#define PH8 0x0100 +#define PH9 0x0200 +#define PH10 0x0400 +#define PH11 0x0800 +#define PH12 0x1000 +#define PH13 0x2000 +#define PH14 0x4000 +#define PH15 0x8000 + +/* ******************* SERIAL PORT MASKS **************************************/ +/* SPORTx_TCR1 Masks */ +#define TSPEN 0x0001 /* Transmit Enable */ +#define ITCLK 0x0002 /* Internal Transmit Clock Select */ +#define DTYPE_NORM 0x0004 /* Data Format Normal */ +#define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ +#define DTYPE_ALAW 0x000C /* Compand Using A-Law */ +#define TLSBIT 0x0010 /* Transmit Bit Order */ +#define ITFS 0x0200 /* Internal Transmit Frame Sync Select */ +#define TFSR 0x0400 /* Transmit Frame Sync Required Select */ +#define DITFS 0x0800 /* Data-Independent Transmit Frame Sync Select */ +#define LTFS 0x1000 /* Low Transmit Frame Sync Select */ +#define LATFS 0x2000 /* Late Transmit Frame Sync Select */ +#define TCKFE 0x4000 /* Clock Falling Edge Select */ + +/* SPORTx_TCR2 Masks and Macro */ +#define SLEN(x) ((x)&0x1F) /* SPORT TX Word Length (2 - 31) */ +#define TXSE 0x0100 /* TX Secondary Enable */ +#define TSFSE 0x0200 /* Transmit Stereo Frame Sync Enable */ +#define TRFST 0x0400 /* Left/Right Order (1 = Right Channel 1st) */ + +/* SPORTx_RCR1 Masks */ +#define RSPEN 0x0001 /* Receive Enable */ +#define IRCLK 0x0002 /* Internal Receive Clock Select */ +#define DTYPE_NORM 0x0004 /* Data Format Normal */ +#define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ +#define DTYPE_ALAW 0x000C /* Compand Using A-Law */ +#define RLSBIT 0x0010 /* Receive Bit Order */ +#define IRFS 0x0200 /* Internal Receive Frame Sync Select */ +#define RFSR 0x0400 /* Receive Frame Sync Required Select */ +#define LRFS 0x1000 /* Low Receive Frame Sync Select */ +#define LARFS 0x2000 /* Late Receive Frame Sync Select */ +#define RCKFE 0x4000 /* Clock Falling Edge Select */ + +/* SPORTx_RCR2 Masks */ +#define SLEN(x) ((x)&0x1F) /* SPORT RX Word Length (2 - 31) */ +#define RXSE 0x0100 /* RX Secondary Enable */ +#define RSFSE 0x0200 /* RX Stereo Frame Sync Enable */ +#define RRFST 0x0400 /* Right-First Data Order */ + +/* SPORTx_STAT Masks */ +#define RXNE 0x0001 /* Receive FIFO Not Empty Status */ +#define RUVF 0x0002 /* Sticky Receive Underflow Status */ +#define ROVF 0x0004 /* Sticky Receive Overflow Status */ +#define TXF 0x0008 /* Transmit FIFO Full Status */ +#define TUVF 0x0010 /* Sticky Transmit Underflow Status */ +#define TOVF 0x0020 /* Sticky Transmit Overflow Status */ +#define TXHRE 0x0040 /* Transmit Hold Register Empty */ + +/* SPORTx_MCMC1 Macros */ +#define SP_WOFF(x) ((x) & 0x3FF) /* Multichannel Window Offset Field */ + +/* Only use WSIZE Macro With Logic OR While Setting Lower Order Bits */ +#define SP_WSIZE(x) (((((x)>>0x3)-1)&0xF) << 0xC) /* Multichannel Window Size = (x/8)-1 */ + +/* SPORTx_MCMC2 Masks */ +#define REC_BYPASS 0x0000 /* Bypass Mode (No Clock Recovery) */ +#define REC_2FROM4 0x0002 /* Recover 2 MHz Clock from 4 MHz Clock */ +#define REC_8FROM16 0x0003 /* Recover 8 MHz Clock from 16 MHz Clock */ +#define MCDTXPE 0x0004 /* Multichannel DMA Transmit Packing */ +#define MCDRXPE 0x0008 /* Multichannel DMA Receive Packing */ +#define MCMEN 0x0010 /* Multichannel Frame Mode Enable */ +#define FSDR 0x0080 /* Multichannel Frame Sync to Data Relationship */ +#define MFD_0 0x0000 /* Multichannel Frame Delay = 0 */ +#define MFD_1 0x1000 /* Multichannel Frame Delay = 1 */ +#define MFD_2 0x2000 /* Multichannel Frame Delay = 2 */ +#define MFD_3 0x3000 /* Multichannel Frame Delay = 3 */ +#define MFD_4 0x4000 /* Multichannel Frame Delay = 4 */ +#define MFD_5 0x5000 /* Multichannel Frame Delay = 5 */ +#define MFD_6 0x6000 /* Multichannel Frame Delay = 6 */ +#define MFD_7 0x7000 /* Multichannel Frame Delay = 7 */ +#define MFD_8 0x8000 /* Multichannel Frame Delay = 8 */ +#define MFD_9 0x9000 /* Multichannel Frame Delay = 9 */ +#define MFD_10 0xA000 /* Multichannel Frame Delay = 10 */ +#define MFD_11 0xB000 /* Multichannel Frame Delay = 11 */ +#define MFD_12 0xC000 /* Multichannel Frame Delay = 12 */ +#define MFD_13 0xD000 /* Multichannel Frame Delay = 13 */ +#define MFD_14 0xE000 /* Multichannel Frame Delay = 14 */ +#define MFD_15 0xF000 /* Multichannel Frame Delay = 15 */ + +/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/ +/* EBIU_AMGCTL Masks */ +#define AMCKEN 0x0001 /* Enable CLKOUT */ +#define AMBEN_NONE 0x0000 /* All Banks Disabled */ +#define AMBEN_B0 0x0002 /* Enable Async Memory Bank 0 only */ +#define AMBEN_B0_B1 0x0004 /* Enable Async Memory Banks 0 & 1 only */ +#define AMBEN_B0_B1_B2 0x0006 /* Enable Async Memory Banks 0, 1, and 2 */ +#define AMBEN_ALL 0x0008 /* Enable Async Memory Banks (all) 0, 1, 2, and 3 */ + +/* EBIU_AMBCTL0 Masks */ +#define B0RDYEN 0x00000001 /* Bank 0 (B0) RDY Enable */ +#define B0RDYPOL 0x00000002 /* B0 RDY Active High */ +#define B0TT_1 0x00000004 /* B0 Transition Time (Read to Write) = 1 cycle */ +#define B0TT_2 0x00000008 /* B0 Transition Time (Read to Write) = 2 cycles */ +#define B0TT_3 0x0000000C /* B0 Transition Time (Read to Write) = 3 cycles */ +#define B0TT_4 0x00000000 /* B0 Transition Time (Read to Write) = 4 cycles */ +#define B0ST_1 0x00000010 /* B0 Setup Time (AOE to Read/Write) = 1 cycle */ +#define B0ST_2 0x00000020 /* B0 Setup Time (AOE to Read/Write) = 2 cycles */ +#define B0ST_3 0x00000030 /* B0 Setup Time (AOE to Read/Write) = 3 cycles */ +#define B0ST_4 0x00000000 /* B0 Setup Time (AOE to Read/Write) = 4 cycles */ +#define B0HT_1 0x00000040 /* B0 Hold Time (~Read/Write to ~AOE) = 1 cycle */ +#define B0HT_2 0x00000080 /* B0 Hold Time (~Read/Write to ~AOE) = 2 cycles */ +#define B0HT_3 0x000000C0 /* B0 Hold Time (~Read/Write to ~AOE) = 3 cycles */ +#define B0HT_0 0x00000000 /* B0 Hold Time (~Read/Write to ~AOE) = 0 cycles */ +#define B0RAT_1 0x00000100 /* B0 Read Access Time = 1 cycle */ +#define B0RAT_2 0x00000200 /* B0 Read Access Time = 2 cycles */ +#define B0RAT_3 0x00000300 /* B0 Read Access Time = 3 cycles */ +#define B0RAT_4 0x00000400 /* B0 Read Access Time = 4 cycles */ +#define B0RAT_5 0x00000500 /* B0 Read Access Time = 5 cycles */ +#define B0RAT_6 0x00000600 /* B0 Read Access Time = 6 cycles */ +#define B0RAT_7 0x00000700 /* B0 Read Access Time = 7 cycles */ +#define B0RAT_8 0x00000800 /* B0 Read Access Time = 8 cycles */ +#define B0RAT_9 0x00000900 /* B0 Read Access Time = 9 cycles */ +#define B0RAT_10 0x00000A00 /* B0 Read Access Time = 10 cycles */ +#define B0RAT_11 0x00000B00 /* B0 Read Access Time = 11 cycles */ +#define B0RAT_12 0x00000C00 /* B0 Read Access Time = 12 cycles */ +#define B0RAT_13 0x00000D00 /* B0 Read Access Time = 13 cycles */ +#define B0RAT_14 0x00000E00 /* B0 Read Access Time = 14 cycles */ +#define B0RAT_15 0x00000F00 /* B0 Read Access Time = 15 cycles */ +#define B0WAT_1 0x00001000 /* B0 Write Access Time = 1 cycle */ +#define B0WAT_2 0x00002000 /* B0 Write Access Time = 2 cycles */ +#define B0WAT_3 0x00003000 /* B0 Write Access Time = 3 cycles */ +#define B0WAT_4 0x00004000 /* B0 Write Access Time = 4 cycles */ +#define B0WAT_5 0x00005000 /* B0 Write Access Time = 5 cycles */ +#define B0WAT_6 0x00006000 /* B0 Write Access Time = 6 cycles */ +#define B0WAT_7 0x00007000 /* B0 Write Access Time = 7 cycles */ +#define B0WAT_8 0x00008000 /* B0 Write Access Time = 8 cycles */ +#define B0WAT_9 0x00009000 /* B0 Write Access Time = 9 cycles */ +#define B0WAT_10 0x0000A000 /* B0 Write Access Time = 10 cycles */ +#define B0WAT_11 0x0000B000 /* B0 Write Access Time = 11 cycles */ +#define B0WAT_12 0x0000C000 /* B0 Write Access Time = 12 cycles */ +#define B0WAT_13 0x0000D000 /* B0 Write Access Time = 13 cycles */ +#define B0WAT_14 0x0000E000 /* B0 Write Access Time = 14 cycles */ +#define B0WAT_15 0x0000F000 /* B0 Write Access Time = 15 cycles */ + +#define B1RDYEN 0x00010000 /* Bank 1 (B1) RDY Enable */ +#define B1RDYPOL 0x00020000 /* B1 RDY Active High */ +#define B1TT_1 0x00040000 /* B1 Transition Time (Read to Write) = 1 cycle */ +#define B1TT_2 0x00080000 /* B1 Transition Time (Read to Write) = 2 cycles */ +#define B1TT_3 0x000C0000 /* B1 Transition Time (Read to Write) = 3 cycles */ +#define B1TT_4 0x00000000 /* B1 Transition Time (Read to Write) = 4 cycles */ +#define B1ST_1 0x00100000 /* B1 Setup Time (AOE to Read/Write) = 1 cycle */ +#define B1ST_2 0x00200000 /* B1 Setup Time (AOE to Read/Write) = 2 cycles */ +#define B1ST_3 0x00300000 /* B1 Setup Time (AOE to Read/Write) = 3 cycles */ +#define B1ST_4 0x00000000 /* B1 Setup Time (AOE to Read/Write) = 4 cycles */ +#define B1HT_1 0x00400000 /* B1 Hold Time (~Read/Write to ~AOE) = 1 cycle */ +#define B1HT_2 0x00800000 /* B1 Hold Time (~Read/Write to ~AOE) = 2 cycles */ +#define B1HT_3 0x00C00000 /* B1 Hold Time (~Read/Write to ~AOE) = 3 cycles */ +#define B1HT_0 0x00000000 /* B1 Hold Time (~Read/Write to ~AOE) = 0 cycles */ +#define B1RAT_1 0x01000000 /* B1 Read Access Time = 1 cycle */ +#define B1RAT_2 0x02000000 /* B1 Read Access Time = 2 cycles */ +#define B1RAT_3 0x03000000 /* B1 Read Access Time = 3 cycles */ +#define B1RAT_4 0x04000000 /* B1 Read Access Time = 4 cycles */ +#define B1RAT_5 0x05000000 /* B1 Read Access Time = 5 cycles */ +#define B1RAT_6 0x06000000 /* B1 Read Access Time = 6 cycles */ +#define B1RAT_7 0x07000000 /* B1 Read Access Time = 7 cycles */ +#define B1RAT_8 0x08000000 /* B1 Read Access Time = 8 cycles */ +#define B1RAT_9 0x09000000 /* B1 Read Access Time = 9 cycles */ +#define B1RAT_10 0x0A000000 /* B1 Read Access Time = 10 cycles */ +#define B1RAT_11 0x0B000000 /* B1 Read Access Time = 11 cycles */ +#define B1RAT_12 0x0C000000 /* B1 Read Access Time = 12 cycles */ +#define B1RAT_13 0x0D000000 /* B1 Read Access Time = 13 cycles */ +#define B1RAT_14 0x0E000000 /* B1 Read Access Time = 14 cycles */ +#define B1RAT_15 0x0F000000 /* B1 Read Access Time = 15 cycles */ +#define B1WAT_1 0x10000000 /* B1 Write Access Time = 1 cycle */ +#define B1WAT_2 0x20000000 /* B1 Write Access Time = 2 cycles */ +#define B1WAT_3 0x30000000 /* B1 Write Access Time = 3 cycles */ +#define B1WAT_4 0x40000000 /* B1 Write Access Time = 4 cycles */ +#define B1WAT_5 0x50000000 /* B1 Write Access Time = 5 cycles */ +#define B1WAT_6 0x60000000 /* B1 Write Access Time = 6 cycles */ +#define B1WAT_7 0x70000000 /* B1 Write Access Time = 7 cycles */ +#define B1WAT_8 0x80000000 /* B1 Write Access Time = 8 cycles */ +#define B1WAT_9 0x90000000 /* B1 Write Access Time = 9 cycles */ +#define B1WAT_10 0xA0000000 /* B1 Write Access Time = 10 cycles */ +#define B1WAT_11 0xB0000000 /* B1 Write Access Time = 11 cycles */ +#define B1WAT_12 0xC0000000 /* B1 Write Access Time = 12 cycles */ +#define B1WAT_13 0xD0000000 /* B1 Write Access Time = 13 cycles */ +#define B1WAT_14 0xE0000000 /* B1 Write Access Time = 14 cycles */ +#define B1WAT_15 0xF0000000 /* B1 Write Access Time = 15 cycles */ + +/* EBIU_AMBCTL1 Masks */ +#define B2RDYEN 0x00000001 /* Bank 2 (B2) RDY Enable */ +#define B2RDYPOL 0x00000002 /* B2 RDY Active High */ +#define B2TT_1 0x00000004 /* B2 Transition Time (Read to Write) = 1 cycle */ +#define B2TT_2 0x00000008 /* B2 Transition Time (Read to Write) = 2 cycles */ +#define B2TT_3 0x0000000C /* B2 Transition Time (Read to Write) = 3 cycles */ +#define B2TT_4 0x00000000 /* B2 Transition Time (Read to Write) = 4 cycles */ +#define B2ST_1 0x00000010 /* B2 Setup Time (AOE to Read/Write) = 1 cycle */ +#define B2ST_2 0x00000020 /* B2 Setup Time (AOE to Read/Write) = 2 cycles */ +#define B2ST_3 0x00000030 /* B2 Setup Time (AOE to Read/Write) = 3 cycles */ +#define B2ST_4 0x00000000 /* B2 Setup Time (AOE to Read/Write) = 4 cycles */ +#define B2HT_1 0x00000040 /* B2 Hold Time (~Read/Write to ~AOE) = 1 cycle */ +#define B2HT_2 0x00000080 /* B2 Hold Time (~Read/Write to ~AOE) = 2 cycles */ +#define B2HT_3 0x000000C0 /* B2 Hold Time (~Read/Write to ~AOE) = 3 cycles */ +#define B2HT_0 0x00000000 /* B2 Hold Time (~Read/Write to ~AOE) = 0 cycles */ +#define B2RAT_1 0x00000100 /* B2 Read Access Time = 1 cycle */ +#define B2RAT_2 0x00000200 /* B2 Read Access Time = 2 cycles */ +#define B2RAT_3 0x00000300 /* B2 Read Access Time = 3 cycles */ +#define B2RAT_4 0x00000400 /* B2 Read Access Time = 4 cycles */ +#define B2RAT_5 0x00000500 /* B2 Read Access Time = 5 cycles */ +#define B2RAT_6 0x00000600 /* B2 Read Access Time = 6 cycles */ +#define B2RAT_7 0x00000700 /* B2 Read Access Time = 7 cycles */ +#define B2RAT_8 0x00000800 /* B2 Read Access Time = 8 cycles */ +#define B2RAT_9 0x00000900 /* B2 Read Access Time = 9 cycles */ +#define B2RAT_10 0x00000A00 /* B2 Read Access Time = 10 cycles */ +#define B2RAT_11 0x00000B00 /* B2 Read Access Time = 11 cycles */ +#define B2RAT_12 0x00000C00 /* B2 Read Access Time = 12 cycles */ +#define B2RAT_13 0x00000D00 /* B2 Read Access Time = 13 cycles */ +#define B2RAT_14 0x00000E00 /* B2 Read Access Time = 14 cycles */ +#define B2RAT_15 0x00000F00 /* B2 Read Access Time = 15 cycles */ +#define B2WAT_1 0x00001000 /* B2 Write Access Time = 1 cycle */ +#define B2WAT_2 0x00002000 /* B2 Write Access Time = 2 cycles */ +#define B2WAT_3 0x00003000 /* B2 Write Access Time = 3 cycles */ +#define B2WAT_4 0x00004000 /* B2 Write Access Time = 4 cycles */ +#define B2WAT_5 0x00005000 /* B2 Write Access Time = 5 cycles */ +#define B2WAT_6 0x00006000 /* B2 Write Access Time = 6 cycles */ +#define B2WAT_7 0x00007000 /* B2 Write Access Time = 7 cycles */ +#define B2WAT_8 0x00008000 /* B2 Write Access Time = 8 cycles */ +#define B2WAT_9 0x00009000 /* B2 Write Access Time = 9 cycles */ +#define B2WAT_10 0x0000A000 /* B2 Write Access Time = 10 cycles */ +#define B2WAT_11 0x0000B000 /* B2 Write Access Time = 11 cycles */ +#define B2WAT_12 0x0000C000 /* B2 Write Access Time = 12 cycles */ +#define B2WAT_13 0x0000D000 /* B2 Write Access Time = 13 cycles */ +#define B2WAT_14 0x0000E000 /* B2 Write Access Time = 14 cycles */ +#define B2WAT_15 0x0000F000 /* B2 Write Access Time = 15 cycles */ + +#define B3RDYEN 0x00010000 /* Bank 3 (B3) RDY Enable */ +#define B3RDYPOL 0x00020000 /* B3 RDY Active High */ +#define B3TT_1 0x00040000 /* B3 Transition Time (Read to Write) = 1 cycle */ +#define B3TT_2 0x00080000 /* B3 Transition Time (Read to Write) = 2 cycles */ +#define B3TT_3 0x000C0000 /* B3 Transition Time (Read to Write) = 3 cycles */ +#define B3TT_4 0x00000000 /* B3 Transition Time (Read to Write) = 4 cycles */ +#define B3ST_1 0x00100000 /* B3 Setup Time (AOE to Read/Write) = 1 cycle */ +#define B3ST_2 0x00200000 /* B3 Setup Time (AOE to Read/Write) = 2 cycles */ +#define B3ST_3 0x00300000 /* B3 Setup Time (AOE to Read/Write) = 3 cycles */ +#define B3ST_4 0x00000000 /* B3 Setup Time (AOE to Read/Write) = 4 cycles */ +#define B3HT_1 0x00400000 /* B3 Hold Time (~Read/Write to ~AOE) = 1 cycle */ +#define B3HT_2 0x00800000 /* B3 Hold Time (~Read/Write to ~AOE) = 2 cycles */ +#define B3HT_3 0x00C00000 /* B3 Hold Time (~Read/Write to ~AOE) = 3 cycles */ +#define B3HT_0 0x00000000 /* B3 Hold Time (~Read/Write to ~AOE) = 0 cycles */ +#define B3RAT_1 0x01000000 /* B3 Read Access Time = 1 cycle */ +#define B3RAT_2 0x02000000 /* B3 Read Access Time = 2 cycles */ +#define B3RAT_3 0x03000000 /* B3 Read Access Time = 3 cycles */ +#define B3RAT_4 0x04000000 /* B3 Read Access Time = 4 cycles */ +#define B3RAT_5 0x05000000 /* B3 Read Access Time = 5 cycles */ +#define B3RAT_6 0x06000000 /* B3 Read Access Time = 6 cycles */ +#define B3RAT_7 0x07000000 /* B3 Read Access Time = 7 cycles */ +#define B3RAT_8 0x08000000 /* B3 Read Access Time = 8 cycles */ +#define B3RAT_9 0x09000000 /* B3 Read Access Time = 9 cycles */ +#define B3RAT_10 0x0A000000 /* B3 Read Access Time = 10 cycles */ +#define B3RAT_11 0x0B000000 /* B3 Read Access Time = 11 cycles */ +#define B3RAT_12 0x0C000000 /* B3 Read Access Time = 12 cycles */ +#define B3RAT_13 0x0D000000 /* B3 Read Access Time = 13 cycles */ +#define B3RAT_14 0x0E000000 /* B3 Read Access Time = 14 cycles */ +#define B3RAT_15 0x0F000000 /* B3 Read Access Time = 15 cycles */ +#define B3WAT_1 0x10000000 /* B3 Write Access Time = 1 cycle */ +#define B3WAT_2 0x20000000 /* B3 Write Access Time = 2 cycles */ +#define B3WAT_3 0x30000000 /* B3 Write Access Time = 3 cycles */ +#define B3WAT_4 0x40000000 /* B3 Write Access Time = 4 cycles */ +#define B3WAT_5 0x50000000 /* B3 Write Access Time = 5 cycles */ +#define B3WAT_6 0x60000000 /* B3 Write Access Time = 6 cycles */ +#define B3WAT_7 0x70000000 /* B3 Write Access Time = 7 cycles */ +#define B3WAT_8 0x80000000 /* B3 Write Access Time = 8 cycles */ +#define B3WAT_9 0x90000000 /* B3 Write Access Time = 9 cycles */ +#define B3WAT_10 0xA0000000 /* B3 Write Access Time = 10 cycles */ +#define B3WAT_11 0xB0000000 /* B3 Write Access Time = 11 cycles */ +#define B3WAT_12 0xC0000000 /* B3 Write Access Time = 12 cycles */ +#define B3WAT_13 0xD0000000 /* B3 Write Access Time = 13 cycles */ +#define B3WAT_14 0xE0000000 /* B3 Write Access Time = 14 cycles */ +#define B3WAT_15 0xF0000000 /* B3 Write Access Time = 15 cycles */ + +/* ********************** SDRAM CONTROLLER MASKS **********************************************/ +/* EBIU_SDGCTL Masks */ +#define SCTLE 0x00000001 /* Enable SDRAM Signals */ +#define CL_2 0x00000008 /* SDRAM CAS Latency = 2 cycles */ +#define CL_3 0x0000000C /* SDRAM CAS Latency = 3 cycles */ +#define PASR_ALL 0x00000000 /* All 4 SDRAM Banks Refreshed In Self-Refresh */ +#define PASR_B0_B1 0x00000010 /* SDRAM Banks 0 and 1 Are Refreshed In Self-Refresh */ +#define PASR_B0 0x00000020 /* Only SDRAM Bank 0 Is Refreshed In Self-Refresh */ +#define TRAS_1 0x00000040 /* SDRAM tRAS = 1 cycle */ +#define TRAS_2 0x00000080 /* SDRAM tRAS = 2 cycles */ +#define TRAS_3 0x000000C0 /* SDRAM tRAS = 3 cycles */ +#define TRAS_4 0x00000100 /* SDRAM tRAS = 4 cycles */ +#define TRAS_5 0x00000140 /* SDRAM tRAS = 5 cycles */ +#define TRAS_6 0x00000180 /* SDRAM tRAS = 6 cycles */ +#define TRAS_7 0x000001C0 /* SDRAM tRAS = 7 cycles */ +#define TRAS_8 0x00000200 /* SDRAM tRAS = 8 cycles */ +#define TRAS_9 0x00000240 /* SDRAM tRAS = 9 cycles */ +#define TRAS_10 0x00000280 /* SDRAM tRAS = 10 cycles */ +#define TRAS_11 0x000002C0 /* SDRAM tRAS = 11 cycles */ +#define TRAS_12 0x00000300 /* SDRAM tRAS = 12 cycles */ +#define TRAS_13 0x00000340 /* SDRAM tRAS = 13 cycles */ +#define TRAS_14 0x00000380 /* SDRAM tRAS = 14 cycles */ +#define TRAS_15 0x000003C0 /* SDRAM tRAS = 15 cycles */ +#define TRP_1 0x00000800 /* SDRAM tRP = 1 cycle */ +#define TRP_2 0x00001000 /* SDRAM tRP = 2 cycles */ +#define TRP_3 0x00001800 /* SDRAM tRP = 3 cycles */ +#define TRP_4 0x00002000 /* SDRAM tRP = 4 cycles */ +#define TRP_5 0x00002800 /* SDRAM tRP = 5 cycles */ +#define TRP_6 0x00003000 /* SDRAM tRP = 6 cycles */ +#define TRP_7 0x00003800 /* SDRAM tRP = 7 cycles */ +#define TRCD_1 0x00008000 /* SDRAM tRCD = 1 cycle */ +#define TRCD_2 0x00010000 /* SDRAM tRCD = 2 cycles */ +#define TRCD_3 0x00018000 /* SDRAM tRCD = 3 cycles */ +#define TRCD_4 0x00020000 /* SDRAM tRCD = 4 cycles */ +#define TRCD_5 0x00028000 /* SDRAM tRCD = 5 cycles */ +#define TRCD_6 0x00030000 /* SDRAM tRCD = 6 cycles */ +#define TRCD_7 0x00038000 /* SDRAM tRCD = 7 cycles */ +#define TWR_1 0x00080000 /* SDRAM tWR = 1 cycle */ +#define TWR_2 0x00100000 /* SDRAM tWR = 2 cycles */ +#define TWR_3 0x00180000 /* SDRAM tWR = 3 cycles */ +#define PUPSD 0x00200000 /* Power-Up Start Delay (15 SCLK Cycles Delay) */ +#define PSM 0x00400000 /* Power-Up Sequence (Mode Register Before/After* Refresh) */ +#define PSS 0x00800000 /* Enable Power-Up Sequence on Next SDRAM Access */ +#define SRFS 0x01000000 /* Enable SDRAM Self-Refresh Mode */ +#define EBUFE 0x02000000 /* Enable External Buffering Timing */ +#define FBBRW 0x04000000 /* Enable Fast Back-To-Back Read To Write */ +#define EMREN 0x10000000 /* Extended Mode Register Enable */ +#define TCSR 0x20000000 /* Temp-Compensated Self-Refresh Value (85/45* Deg C) */ +#define CDDBG 0x40000000 /* Tristate SDRAM Controls During Bus Grant */ + +/* EBIU_SDBCTL Masks */ +#define EBE 0x0001 /* Enable SDRAM External Bank */ +#define EBSZ_16 0x0000 /* SDRAM External Bank Size = 16MB */ +#define EBSZ_32 0x0002 /* SDRAM External Bank Size = 32MB */ +#define EBSZ_64 0x0004 /* SDRAM External Bank Size = 64MB */ +#define EBSZ_128 0x0006 /* SDRAM External Bank Size = 128MB */ +#define EBCAW_8 0x0000 /* SDRAM External Bank Column Address Width = 8 Bits */ +#define EBCAW_9 0x0010 /* SDRAM External Bank Column Address Width = 9 Bits */ +#define EBCAW_10 0x0020 /* SDRAM External Bank Column Address Width = 10 Bits */ +#define EBCAW_11 0x0030 /* SDRAM External Bank Column Address Width = 11 Bits */ + +/* EBIU_SDSTAT Masks */ +#define SDCI 0x0001 /* SDRAM Controller Idle */ +#define SDSRA 0x0002 /* SDRAM Self-Refresh Active */ +#define SDPUA 0x0004 /* SDRAM Power-Up Active */ +#define SDRS 0x0008 /* SDRAM Will Power-Up On Next Access */ +#define SDEASE 0x0010 /* SDRAM EAB Sticky Error Status */ +#define BGSTAT 0x0020 /* Bus Grant Status */ + +/* ************************** DMA CONTROLLER MASKS ********************************/ +/* DMAx_CONFIG, MDMA_yy_CONFIG Masks */ +#define DMAEN 0x0001 /* DMA Channel Enable */ +#define WNR 0x0002 /* Channel Direction (W/R*) */ +#define WDSIZE_8 0x0000 /* Transfer Word Size = 8 */ +#define WDSIZE_16 0x0004 /* Transfer Word Size = 16 */ +#define WDSIZE_32 0x0008 /* Transfer Word Size = 32 */ +#define DMA2D 0x0010 /* DMA Mode (2D/1D*) */ +#define RESTART 0x0020 /* DMA Buffer Clear */ +#define DI_SEL 0x0040 /* Data Interrupt Timing Select */ +#define DI_EN 0x0080 /* Data Interrupt Enable */ +#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */ +#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */ +#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */ +#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */ +#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */ +#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */ +#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */ +#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */ +#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */ +#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */ +#define NDSIZE 0x0900 /* Next Descriptor Size */ + +#define DMAFLOW 0x7000 /* Flow Control */ +#define DMAFLOW_STOP 0x0000 /* Stop Mode */ +#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */ +#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */ +#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */ +#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */ + +/* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */ +#define CTYPE 0x0040 /* DMA Channel Type Indicator (Memory/Peripheral*) */ +#define PMAP 0xF000 /* Peripheral Mapped To This Channel */ +#define PMAP_PPI 0x0000 /* PPI Port DMA */ +#define PMAP_EMACRX 0x1000 /* Ethernet Receive DMA */ +#define PMAP_EMACTX 0x2000 /* Ethernet Transmit DMA */ +#define PMAP_SPORT0RX 0x3000 /* SPORT0 Receive DMA */ +#define PMAP_SPORT0TX 0x4000 /* SPORT0 Transmit DMA */ +#define PMAP_SPORT1RX 0x5000 /* SPORT1 Receive DMA */ +#define PMAP_SPORT1TX 0x6000 /* SPORT1 Transmit DMA */ +#define PMAP_SPI 0x7000 /* SPI Port DMA */ +#define PMAP_UART0RX 0x8000 /* UART0 Port Receive DMA */ +#define PMAP_UART0TX 0x9000 /* UART0 Port Transmit DMA */ +#define PMAP_UART1RX 0xA000 /* UART1 Port Receive DMA */ +#define PMAP_UART1TX 0xB000 /* UART1 Port Transmit DMA */ + +/* DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS Masks */ +#define DMA_DONE 0x0001 /* DMA Completion Interrupt Status */ +#define DMA_ERR 0x0002 /* DMA Error Interrupt Status */ +#define DFETCH 0x0004 /* DMA Descriptor Fetch Indicator */ +#define DMA_RUN 0x0008 /* DMA Channel Running Indicator */ + +/* ************ PARALLEL PERIPHERAL INTERFACE (PPI) MASKS *************/ +/* PPI_CONTROL Masks */ +#define PORT_EN 0x0001 /* PPI Port Enable */ +#define PORT_DIR 0x0002 /* PPI Port Direction */ +#define XFR_TYPE 0x000C /* PPI Transfer Type */ +#define PORT_CFG 0x0030 /* PPI Port Configuration */ +#define FLD_SEL 0x0040 /* PPI Active Field Select */ +#define PACK_EN 0x0080 /* PPI Packing Mode */ +#define DMA32 0x0100 /* PPI 32-bit DMA Enable */ +#define SKIP_EN 0x0200 /* PPI Skip Element Enable */ +#define SKIP_EO 0x0400 /* PPI Skip Even/Odd Elements */ +#define DLENGTH 0x3800 /* PPI Data Length */ +#define DLEN_8 0x0000 /* Data Length = 8 Bits */ +#define DLEN_10 0x0800 /* Data Length = 10 Bits */ +#define DLEN_11 0x1000 /* Data Length = 11 Bits */ +#define DLEN_12 0x1800 /* Data Length = 12 Bits */ +#define DLEN_13 0x2000 /* Data Length = 13 Bits */ +#define DLEN_14 0x2800 /* Data Length = 14 Bits */ +#define DLEN_15 0x3000 /* Data Length = 15 Bits */ +#define DLEN_16 0x3800 /* Data Length = 16 Bits */ +#define POLC 0x4000 /* PPI Clock Polarity */ +#define POLS 0x8000 /* PPI Frame Sync Polarity */ + +/* PPI_STATUS Masks */ +#define FLD 0x0400 /* Field Indicator */ +#define FT_ERR 0x0800 /* Frame Track Error */ +#define OVR 0x1000 /* FIFO Overflow Error */ +#define UNDR 0x2000 /* FIFO Underrun Error */ +#define ERR_DET 0x4000 /* Error Detected Indicator */ +#define ERR_NCOR 0x8000 /* Error Not Corrected Indicator */ + +/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ***********************/ +/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */ +#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */ +#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */ + +/* TWI_PRESCALE Masks */ +#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */ +#define TWI_ENA 0x0080 /* TWI Enable */ +#define SCCB 0x0200 /* SCCB Compatibility Enable */ + +/* TWI_SLAVE_CTRL Masks */ +#define SEN 0x0001 /* Slave Enable */ +#define SADD_LEN 0x0002 /* Slave Address Length */ +#define STDVAL 0x0004 /* Slave Transmit Data Valid */ +#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ +#define GEN 0x0010 /* General Call Adrress Matching Enabled */ + +/* TWI_SLAVE_STAT Masks */ +#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ +#define GCALL 0x0002 /* General Call Indicator */ + +/* TWI_MASTER_CTRL Masks */ +#define MEN 0x0001 /* Master Mode Enable */ +#define MADD_LEN 0x0002 /* Master Address Length */ +#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */ +#define FAST 0x0008 /* Use Fast Mode Timing Specs */ +#define STOP 0x0010 /* Issue Stop Condition */ +#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */ +#define DCNT 0x3FC0 /* Data Bytes To Transfer */ +#define SDAOVR 0x4000 /* Serial Data Override */ +#define SCLOVR 0x8000 /* Serial Clock Override */ + +/* TWI_MASTER_STAT Masks */ +#define MPROG 0x0001 /* Master Transfer In Progress */ +#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */ +#define ANAK 0x0004 /* Address Not Acknowledged */ +#define DNAK 0x0008 /* Data Not Acknowledged */ +#define BUFRDERR 0x0010 /* Buffer Read Error */ +#define BUFWRERR 0x0020 /* Buffer Write Error */ +#define SDASEN 0x0040 /* Serial Data Sense */ +#define SCLSEN 0x0080 /* Serial Clock Sense */ +#define BUSBUSY 0x0100 /* Bus Busy Indicator */ + +/* TWI_INT_SRC and TWI_INT_ENABLE Masks */ +#define SINIT 0x0001 /* Slave Transfer Initiated */ +#define SCOMP 0x0002 /* Slave Transfer Complete */ +#define SERR 0x0004 /* Slave Transfer Error */ +#define SOVF 0x0008 /* Slave Overflow */ +#define MCOMP 0x0010 /* Master Transfer Complete */ +#define MERR 0x0020 /* Master Transfer Error */ +#define XMTSERV 0x0040 /* Transmit FIFO Service */ +#define RCVSERV 0x0080 /* Receive FIFO Service */ + +/* TWI_FIFO_CTRL Masks */ +#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */ +#define RCVFLUSH 0x0002 /* Receive Buffer Flush */ +#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */ +#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */ + +/* TWI_FIFO_STAT Masks */ +#define XMTSTAT 0x0003 /* Transmit FIFO Status */ +#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */ +#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */ +#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */ + +#define RCVSTAT 0x000C /* Receive FIFO Status */ +#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */ +#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ +#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ + +/* ************ CONTROLLER AREA NETWORK (CAN) MASKS ***************/ +/* CAN_CONTROL Masks */ +#define SRS 0x0001 /* Software Reset */ +#define DNM 0x0002 /* Device Net Mode */ +#define ABO 0x0004 /* Auto-Bus On Enable */ +#define TXPRIO 0x0008 /* TX Priority (Priority/Mailbox*) */ +#define WBA 0x0010 /* Wake-Up On CAN Bus Activity Enable */ +#define SMR 0x0020 /* Sleep Mode Request */ +#define CSR 0x0040 /* CAN Suspend Mode Request */ +#define CCR 0x0080 /* CAN Configuration Mode Request */ + +/* CAN_STATUS Masks */ +#define WT 0x0001 /* TX Warning Flag */ +#define WR 0x0002 /* RX Warning Flag */ +#define EP 0x0004 /* Error Passive Mode */ +#define EBO 0x0008 /* Error Bus Off Mode */ +#define SMA 0x0020 /* Sleep Mode Acknowledge */ +#define CSA 0x0040 /* Suspend Mode Acknowledge */ +#define CCA 0x0080 /* Configuration Mode Acknowledge */ +#define MBPTR 0x1F00 /* Mailbox Pointer */ +#define TRM 0x4000 /* Transmit Mode */ +#define REC 0x8000 /* Receive Mode */ + +/* CAN_CLOCK Masks */ +#define BRP 0x03FF /* Bit-Rate Pre-Scaler */ + +/* CAN_TIMING Masks */ +#define TSEG1 0x000F /* Time Segment 1 */ +#define TSEG2 0x0070 /* Time Segment 2 */ +#define SAM 0x0080 /* Sampling */ +#define SJW 0x0300 /* Synchronization Jump Width */ + +/* CAN_DEBUG Masks */ +#define DEC 0x0001 /* Disable CAN Error Counters */ +#define DRI 0x0002 /* Disable CAN RX Input */ +#define DTO 0x0004 /* Disable CAN TX Output */ +#define DIL 0x0008 /* Disable CAN Internal Loop */ +#define MAA 0x0010 /* Mode Auto-Acknowledge Enable */ +#define MRB 0x0020 /* Mode Read Back Enable */ +#define CDE 0x8000 /* CAN Debug Enable */ + +/* CAN_CEC Masks */ +#define RXECNT 0x00FF /* Receive Error Counter */ +#define TXECNT 0xFF00 /* Transmit Error Counter */ + +/* CAN_INTR Masks */ +#define MBRIF 0x0001 /* Mailbox Receive Interrupt */ +#define MBTIF 0x0002 /* Mailbox Transmit Interrupt */ +#define GIRQ 0x0004 /* Global Interrupt */ +#define SMACK 0x0008 /* Sleep Mode Acknowledge */ +#define CANTX 0x0040 /* CAN TX Bus Value */ +#define CANRX 0x0080 /* CAN RX Bus Value */ + +/* CAN_MBxx_ID1 and CAN_MBxx_ID0 Masks */ +#define DFC 0xFFFF /* Data Filtering Code (If Enabled) (ID0) */ +#define EXTID_LO 0xFFFF /* Lower 16 Bits of Extended Identifier (ID0) */ +#define EXTID_HI 0x0003 /* Upper 2 Bits of Extended Identifier (ID1) */ +#define BASEID 0x1FFC /* Base Identifier */ +#define IDE 0x2000 /* Identifier Extension */ +#define RTR 0x4000 /* Remote Frame Transmission Request */ +#define AME 0x8000 /* Acceptance Mask Enable */ + +/* CAN_MBxx_TIMESTAMP Masks */ +#define TSV 0xFFFF /* Timestamp */ + +/* CAN_MBxx_LENGTH Masks */ +#define DLC 0x000F /* Data Length Code */ + +/* CAN_AMxxH and CAN_AMxxL Masks */ +#define DFM 0xFFFF /* Data Field Mask (If Enabled) (CAN_AMxxL) */ +#define EXTID_LO 0xFFFF /* Lower 16 Bits of Extended Identifier (CAN_AMxxL) */ +#define EXTID_HI 0x0003 /* Upper 2 Bits of Extended Identifier (CAN_AMxxH) */ +#define BASEID 0x1FFC /* Base Identifier */ +#define AMIDE 0x2000 /* Acceptance Mask ID Extension Enable */ +#define FMD 0x4000 /* Full Mask Data Field Enable */ +#define FDF 0x8000 /* Filter On Data Field Enable */ + +/* CAN_MC1 Masks */ +#define MC0 0x0001 /* Enable Mailbox 0 */ +#define MC1 0x0002 /* Enable Mailbox 1 */ +#define MC2 0x0004 /* Enable Mailbox 2 */ +#define MC3 0x0008 /* Enable Mailbox 3 */ +#define MC4 0x0010 /* Enable Mailbox 4 */ +#define MC5 0x0020 /* Enable Mailbox 5 */ +#define MC6 0x0040 /* Enable Mailbox 6 */ +#define MC7 0x0080 /* Enable Mailbox 7 */ +#define MC8 0x0100 /* Enable Mailbox 8 */ +#define MC9 0x0200 /* Enable Mailbox 9 */ +#define MC10 0x0400 /* Enable Mailbox 10 */ +#define MC11 0x0800 /* Enable Mailbox 11 */ +#define MC12 0x1000 /* Enable Mailbox 12 */ +#define MC13 0x2000 /* Enable Mailbox 13 */ +#define MC14 0x4000 /* Enable Mailbox 14 */ +#define MC15 0x8000 /* Enable Mailbox 15 */ + +/* CAN_MC2 Masks */ +#define MC16 0x0001 /* Enable Mailbox 16 */ +#define MC17 0x0002 /* Enable Mailbox 17 */ +#define MC18 0x0004 /* Enable Mailbox 18 */ +#define MC19 0x0008 /* Enable Mailbox 19 */ +#define MC20 0x0010 /* Enable Mailbox 20 */ +#define MC21 0x0020 /* Enable Mailbox 21 */ +#define MC22 0x0040 /* Enable Mailbox 22 */ +#define MC23 0x0080 /* Enable Mailbox 23 */ +#define MC24 0x0100 /* Enable Mailbox 24 */ +#define MC25 0x0200 /* Enable Mailbox 25 */ +#define MC26 0x0400 /* Enable Mailbox 26 */ +#define MC27 0x0800 /* Enable Mailbox 27 */ +#define MC28 0x1000 /* Enable Mailbox 28 */ +#define MC29 0x2000 /* Enable Mailbox 29 */ +#define MC30 0x4000 /* Enable Mailbox 30 */ +#define MC31 0x8000 /* Enable Mailbox 31 */ + +/* CAN_MD1 Masks */ +#define MD0 0x0001 /* Enable Mailbox 0 For Receive */ +#define MD1 0x0002 /* Enable Mailbox 1 For Receive */ +#define MD2 0x0004 /* Enable Mailbox 2 For Receive */ +#define MD3 0x0008 /* Enable Mailbox 3 For Receive */ +#define MD4 0x0010 /* Enable Mailbox 4 For Receive */ +#define MD5 0x0020 /* Enable Mailbox 5 For Receive */ +#define MD6 0x0040 /* Enable Mailbox 6 For Receive */ +#define MD7 0x0080 /* Enable Mailbox 7 For Receive */ +#define MD8 0x0100 /* Enable Mailbox 8 For Receive */ +#define MD9 0x0200 /* Enable Mailbox 9 For Receive */ +#define MD10 0x0400 /* Enable Mailbox 10 For Receive */ +#define MD11 0x0800 /* Enable Mailbox 11 For Receive */ +#define MD12 0x1000 /* Enable Mailbox 12 For Receive */ +#define MD13 0x2000 /* Enable Mailbox 13 For Receive */ +#define MD14 0x4000 /* Enable Mailbox 14 For Receive */ +#define MD15 0x8000 /* Enable Mailbox 15 For Receive */ + +/* CAN_MD2 Masks */ +#define MD16 0x0001 /* Enable Mailbox 16 For Receive */ +#define MD17 0x0002 /* Enable Mailbox 17 For Receive */ +#define MD18 0x0004 /* Enable Mailbox 18 For Receive */ +#define MD19 0x0008 /* Enable Mailbox 19 For Receive */ +#define MD20 0x0010 /* Enable Mailbox 20 For Receive */ +#define MD21 0x0020 /* Enable Mailbox 21 For Receive */ +#define MD22 0x0040 /* Enable Mailbox 22 For Receive */ +#define MD23 0x0080 /* Enable Mailbox 23 For Receive */ +#define MD24 0x0100 /* Enable Mailbox 24 For Receive */ +#define MD25 0x0200 /* Enable Mailbox 25 For Receive */ +#define MD26 0x0400 /* Enable Mailbox 26 For Receive */ +#define MD27 0x0800 /* Enable Mailbox 27 For Receive */ +#define MD28 0x1000 /* Enable Mailbox 28 For Receive */ +#define MD29 0x2000 /* Enable Mailbox 29 For Receive */ +#define MD30 0x4000 /* Enable Mailbox 30 For Receive */ +#define MD31 0x8000 /* Enable Mailbox 31 For Receive */ + +/* CAN_RMP1 Masks */ +#define RMP0 0x0001 /* RX Message Pending In Mailbox 0 */ +#define RMP1 0x0002 /* RX Message Pending In Mailbox 1 */ +#define RMP2 0x0004 /* RX Message Pending In Mailbox 2 */ +#define RMP3 0x0008 /* RX Message Pending In Mailbox 3 */ +#define RMP4 0x0010 /* RX Message Pending In Mailbox 4 */ +#define RMP5 0x0020 /* RX Message Pending In Mailbox 5 */ +#define RMP6 0x0040 /* RX Message Pending In Mailbox 6 */ +#define RMP7 0x0080 /* RX Message Pending In Mailbox 7 */ +#define RMP8 0x0100 /* RX Message Pending In Mailbox 8 */ +#define RMP9 0x0200 /* RX Message Pending In Mailbox 9 */ +#define RMP10 0x0400 /* RX Message Pending In Mailbox 10 */ +#define RMP11 0x0800 /* RX Message Pending In Mailbox 11 */ +#define RMP12 0x1000 /* RX Message Pending In Mailbox 12 */ +#define RMP13 0x2000 /* RX Message Pending In Mailbox 13 */ +#define RMP14 0x4000 /* RX Message Pending In Mailbox 14 */ +#define RMP15 0x8000 /* RX Message Pending In Mailbox 15 */ + +/* CAN_RMP2 Masks */ +#define RMP16 0x0001 /* RX Message Pending In Mailbox 16 */ +#define RMP17 0x0002 /* RX Message Pending In Mailbox 17 */ +#define RMP18 0x0004 /* RX Message Pending In Mailbox 18 */ +#define RMP19 0x0008 /* RX Message Pending In Mailbox 19 */ +#define RMP20 0x0010 /* RX Message Pending In Mailbox 20 */ +#define RMP21 0x0020 /* RX Message Pending In Mailbox 21 */ +#define RMP22 0x0040 /* RX Message Pending In Mailbox 22 */ +#define RMP23 0x0080 /* RX Message Pending In Mailbox 23 */ +#define RMP24 0x0100 /* RX Message Pending In Mailbox 24 */ +#define RMP25 0x0200 /* RX Message Pending In Mailbox 25 */ +#define RMP26 0x0400 /* RX Message Pending In Mailbox 26 */ +#define RMP27 0x0800 /* RX Message Pending In Mailbox 27 */ +#define RMP28 0x1000 /* RX Message Pending In Mailbox 28 */ +#define RMP29 0x2000 /* RX Message Pending In Mailbox 29 */ +#define RMP30 0x4000 /* RX Message Pending In Mailbox 30 */ +#define RMP31 0x8000 /* RX Message Pending In Mailbox 31 */ + +/* CAN_RML1 Masks */ +#define RML0 0x0001 /* RX Message Lost In Mailbox 0 */ +#define RML1 0x0002 /* RX Message Lost In Mailbox 1 */ +#define RML2 0x0004 /* RX Message Lost In Mailbox 2 */ +#define RML3 0x0008 /* RX Message Lost In Mailbox 3 */ +#define RML4 0x0010 /* RX Message Lost In Mailbox 4 */ +#define RML5 0x0020 /* RX Message Lost In Mailbox 5 */ +#define RML6 0x0040 /* RX Message Lost In Mailbox 6 */ +#define RML7 0x0080 /* RX Message Lost In Mailbox 7 */ +#define RML8 0x0100 /* RX Message Lost In Mailbox 8 */ +#define RML9 0x0200 /* RX Message Lost In Mailbox 9 */ +#define RML10 0x0400 /* RX Message Lost In Mailbox 10 */ +#define RML11 0x0800 /* RX Message Lost In Mailbox 11 */ +#define RML12 0x1000 /* RX Message Lost In Mailbox 12 */ +#define RML13 0x2000 /* RX Message Lost In Mailbox 13 */ +#define RML14 0x4000 /* RX Message Lost In Mailbox 14 */ +#define RML15 0x8000 /* RX Message Lost In Mailbox 15 */ + +/* CAN_RML2 Masks */ +#define RML16 0x0001 /* RX Message Lost In Mailbox 16 */ +#define RML17 0x0002 /* RX Message Lost In Mailbox 17 */ +#define RML18 0x0004 /* RX Message Lost In Mailbox 18 */ +#define RML19 0x0008 /* RX Message Lost In Mailbox 19 */ +#define RML20 0x0010 /* RX Message Lost In Mailbox 20 */ +#define RML21 0x0020 /* RX Message Lost In Mailbox 21 */ +#define RML22 0x0040 /* RX Message Lost In Mailbox 22 */ +#define RML23 0x0080 /* RX Message Lost In Mailbox 23 */ +#define RML24 0x0100 /* RX Message Lost In Mailbox 24 */ +#define RML25 0x0200 /* RX Message Lost In Mailbox 25 */ +#define RML26 0x0400 /* RX Message Lost In Mailbox 26 */ +#define RML27 0x0800 /* RX Message Lost In Mailbox 27 */ +#define RML28 0x1000 /* RX Message Lost In Mailbox 28 */ +#define RML29 0x2000 /* RX Message Lost In Mailbox 29 */ +#define RML30 0x4000 /* RX Message Lost In Mailbox 30 */ +#define RML31 0x8000 /* RX Message Lost In Mailbox 31 */ + +/* CAN_OPSS1 Masks */ +#define OPSS0 0x0001 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 0 */ +#define OPSS1 0x0002 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 1 */ +#define OPSS2 0x0004 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 2 */ +#define OPSS3 0x0008 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 3 */ +#define OPSS4 0x0010 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 4 */ +#define OPSS5 0x0020 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 5 */ +#define OPSS6 0x0040 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 6 */ +#define OPSS7 0x0080 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 7 */ +#define OPSS8 0x0100 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 8 */ +#define OPSS9 0x0200 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 9 */ +#define OPSS10 0x0400 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 10 */ +#define OPSS11 0x0800 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 11 */ +#define OPSS12 0x1000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 12 */ +#define OPSS13 0x2000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 13 */ +#define OPSS14 0x4000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 14 */ +#define OPSS15 0x8000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 15 */ + +/* CAN_OPSS2 Masks */ +#define OPSS16 0x0001 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 16 */ +#define OPSS17 0x0002 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 17 */ +#define OPSS18 0x0004 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 18 */ +#define OPSS19 0x0008 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 19 */ +#define OPSS20 0x0010 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 20 */ +#define OPSS21 0x0020 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 21 */ +#define OPSS22 0x0040 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 22 */ +#define OPSS23 0x0080 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 23 */ +#define OPSS24 0x0100 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 24 */ +#define OPSS25 0x0200 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 25 */ +#define OPSS26 0x0400 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 26 */ +#define OPSS27 0x0800 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 27 */ +#define OPSS28 0x1000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 28 */ +#define OPSS29 0x2000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 29 */ +#define OPSS30 0x4000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 30 */ +#define OPSS31 0x8000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 31 */ + +/* CAN_TRR1 Masks */ +#define TRR0 0x0001 /* Deny But Don't Lock Access To Mailbox 0 */ +#define TRR1 0x0002 /* Deny But Don't Lock Access To Mailbox 1 */ +#define TRR2 0x0004 /* Deny But Don't Lock Access To Mailbox 2 */ +#define TRR3 0x0008 /* Deny But Don't Lock Access To Mailbox 3 */ +#define TRR4 0x0010 /* Deny But Don't Lock Access To Mailbox 4 */ +#define TRR5 0x0020 /* Deny But Don't Lock Access To Mailbox 5 */ +#define TRR6 0x0040 /* Deny But Don't Lock Access To Mailbox 6 */ +#define TRR7 0x0080 /* Deny But Don't Lock Access To Mailbox 7 */ +#define TRR8 0x0100 /* Deny But Don't Lock Access To Mailbox 8 */ +#define TRR9 0x0200 /* Deny But Don't Lock Access To Mailbox 9 */ +#define TRR10 0x0400 /* Deny But Don't Lock Access To Mailbox 10 */ +#define TRR11 0x0800 /* Deny But Don't Lock Access To Mailbox 11 */ +#define TRR12 0x1000 /* Deny But Don't Lock Access To Mailbox 12 */ +#define TRR13 0x2000 /* Deny But Don't Lock Access To Mailbox 13 */ +#define TRR14 0x4000 /* Deny But Don't Lock Access To Mailbox 14 */ +#define TRR15 0x8000 /* Deny But Don't Lock Access To Mailbox 15 */ + +/* CAN_TRR2 Masks */ +#define TRR16 0x0001 /* Deny But Don't Lock Access To Mailbox 16 */ +#define TRR17 0x0002 /* Deny But Don't Lock Access To Mailbox 17 */ +#define TRR18 0x0004 /* Deny But Don't Lock Access To Mailbox 18 */ +#define TRR19 0x0008 /* Deny But Don't Lock Access To Mailbox 19 */ +#define TRR20 0x0010 /* Deny But Don't Lock Access To Mailbox 20 */ +#define TRR21 0x0020 /* Deny But Don't Lock Access To Mailbox 21 */ +#define TRR22 0x0040 /* Deny But Don't Lock Access To Mailbox 22 */ +#define TRR23 0x0080 /* Deny But Don't Lock Access To Mailbox 23 */ +#define TRR24 0x0100 /* Deny But Don't Lock Access To Mailbox 24 */ +#define TRR25 0x0200 /* Deny But Don't Lock Access To Mailbox 25 */ +#define TRR26 0x0400 /* Deny But Don't Lock Access To Mailbox 26 */ +#define TRR27 0x0800 /* Deny But Don't Lock Access To Mailbox 27 */ +#define TRR28 0x1000 /* Deny But Don't Lock Access To Mailbox 28 */ +#define TRR29 0x2000 /* Deny But Don't Lock Access To Mailbox 29 */ +#define TRR30 0x4000 /* Deny But Don't Lock Access To Mailbox 30 */ +#define TRR31 0x8000 /* Deny But Don't Lock Access To Mailbox 31 */ + +/* CAN_TRS1 Masks */ +#define TRS0 0x0001 /* Remote Frame Request For Mailbox 0 */ +#define TRS1 0x0002 /* Remote Frame Request For Mailbox 1 */ +#define TRS2 0x0004 /* Remote Frame Request For Mailbox 2 */ +#define TRS3 0x0008 /* Remote Frame Request For Mailbox 3 */ +#define TRS4 0x0010 /* Remote Frame Request For Mailbox 4 */ +#define TRS5 0x0020 /* Remote Frame Request For Mailbox 5 */ +#define TRS6 0x0040 /* Remote Frame Request For Mailbox 6 */ +#define TRS7 0x0080 /* Remote Frame Request For Mailbox 7 */ +#define TRS8 0x0100 /* Remote Frame Request For Mailbox 8 */ +#define TRS9 0x0200 /* Remote Frame Request For Mailbox 9 */ +#define TRS10 0x0400 /* Remote Frame Request For Mailbox 10 */ +#define TRS11 0x0800 /* Remote Frame Request For Mailbox 11 */ +#define TRS12 0x1000 /* Remote Frame Request For Mailbox 12 */ +#define TRS13 0x2000 /* Remote Frame Request For Mailbox 13 */ +#define TRS14 0x4000 /* Remote Frame Request For Mailbox 14 */ +#define TRS15 0x8000 /* Remote Frame Request For Mailbox 15 */ + +/* CAN_TRS2 Masks */ +#define TRS16 0x0001 /* Remote Frame Request For Mailbox 16 */ +#define TRS17 0x0002 /* Remote Frame Request For Mailbox 17 */ +#define TRS18 0x0004 /* Remote Frame Request For Mailbox 18 */ +#define TRS19 0x0008 /* Remote Frame Request For Mailbox 19 */ +#define TRS20 0x0010 /* Remote Frame Request For Mailbox 20 */ +#define TRS21 0x0020 /* Remote Frame Request For Mailbox 21 */ +#define TRS22 0x0040 /* Remote Frame Request For Mailbox 22 */ +#define TRS23 0x0080 /* Remote Frame Request For Mailbox 23 */ +#define TRS24 0x0100 /* Remote Frame Request For Mailbox 24 */ +#define TRS25 0x0200 /* Remote Frame Request For Mailbox 25 */ +#define TRS26 0x0400 /* Remote Frame Request For Mailbox 26 */ +#define TRS27 0x0800 /* Remote Frame Request For Mailbox 27 */ +#define TRS28 0x1000 /* Remote Frame Request For Mailbox 28 */ +#define TRS29 0x2000 /* Remote Frame Request For Mailbox 29 */ +#define TRS30 0x4000 /* Remote Frame Request For Mailbox 30 */ +#define TRS31 0x8000 /* Remote Frame Request For Mailbox 31 */ + +/* CAN_AA1 Masks */ +#define AA0 0x0001 /* Aborted Message In Mailbox 0 */ +#define AA1 0x0002 /* Aborted Message In Mailbox 1 */ +#define AA2 0x0004 /* Aborted Message In Mailbox 2 */ +#define AA3 0x0008 /* Aborted Message In Mailbox 3 */ +#define AA4 0x0010 /* Aborted Message In Mailbox 4 */ +#define AA5 0x0020 /* Aborted Message In Mailbox 5 */ +#define AA6 0x0040 /* Aborted Message In Mailbox 6 */ +#define AA7 0x0080 /* Aborted Message In Mailbox 7 */ +#define AA8 0x0100 /* Aborted Message In Mailbox 8 */ +#define AA9 0x0200 /* Aborted Message In Mailbox 9 */ +#define AA10 0x0400 /* Aborted Message In Mailbox 10 */ +#define AA11 0x0800 /* Aborted Message In Mailbox 11 */ +#define AA12 0x1000 /* Aborted Message In Mailbox 12 */ +#define AA13 0x2000 /* Aborted Message In Mailbox 13 */ +#define AA14 0x4000 /* Aborted Message In Mailbox 14 */ +#define AA15 0x8000 /* Aborted Message In Mailbox 15 */ + +/* CAN_AA2 Masks */ +#define AA16 0x0001 /* Aborted Message In Mailbox 16 */ +#define AA17 0x0002 /* Aborted Message In Mailbox 17 */ +#define AA18 0x0004 /* Aborted Message In Mailbox 18 */ +#define AA19 0x0008 /* Aborted Message In Mailbox 19 */ +#define AA20 0x0010 /* Aborted Message In Mailbox 20 */ +#define AA21 0x0020 /* Aborted Message In Mailbox 21 */ +#define AA22 0x0040 /* Aborted Message In Mailbox 22 */ +#define AA23 0x0080 /* Aborted Message In Mailbox 23 */ +#define AA24 0x0100 /* Aborted Message In Mailbox 24 */ +#define AA25 0x0200 /* Aborted Message In Mailbox 25 */ +#define AA26 0x0400 /* Aborted Message In Mailbox 26 */ +#define AA27 0x0800 /* Aborted Message In Mailbox 27 */ +#define AA28 0x1000 /* Aborted Message In Mailbox 28 */ +#define AA29 0x2000 /* Aborted Message In Mailbox 29 */ +#define AA30 0x4000 /* Aborted Message In Mailbox 30 */ +#define AA31 0x8000 /* Aborted Message In Mailbox 31 */ + +/* CAN_TA1 Masks */ +#define TA0 0x0001 /* Transmit Successful From Mailbox 0 */ +#define TA1 0x0002 /* Transmit Successful From Mailbox 1 */ +#define TA2 0x0004 /* Transmit Successful From Mailbox 2 */ +#define TA3 0x0008 /* Transmit Successful From Mailbox 3 */ +#define TA4 0x0010 /* Transmit Successful From Mailbox 4 */ +#define TA5 0x0020 /* Transmit Successful From Mailbox 5 */ +#define TA6 0x0040 /* Transmit Successful From Mailbox 6 */ +#define TA7 0x0080 /* Transmit Successful From Mailbox 7 */ +#define TA8 0x0100 /* Transmit Successful From Mailbox 8 */ +#define TA9 0x0200 /* Transmit Successful From Mailbox 9 */ +#define TA10 0x0400 /* Transmit Successful From Mailbox 10 */ +#define TA11 0x0800 /* Transmit Successful From Mailbox 11 */ +#define TA12 0x1000 /* Transmit Successful From Mailbox 12 */ +#define TA13 0x2000 /* Transmit Successful From Mailbox 13 */ +#define TA14 0x4000 /* Transmit Successful From Mailbox 14 */ +#define TA15 0x8000 /* Transmit Successful From Mailbox 15 */ + +/* CAN_TA2 Masks */ +#define TA16 0x0001 /* Transmit Successful From Mailbox 16 */ +#define TA17 0x0002 /* Transmit Successful From Mailbox 17 */ +#define TA18 0x0004 /* Transmit Successful From Mailbox 18 */ +#define TA19 0x0008 /* Transmit Successful From Mailbox 19 */ +#define TA20 0x0010 /* Transmit Successful From Mailbox 20 */ +#define TA21 0x0020 /* Transmit Successful From Mailbox 21 */ +#define TA22 0x0040 /* Transmit Successful From Mailbox 22 */ +#define TA23 0x0080 /* Transmit Successful From Mailbox 23 */ +#define TA24 0x0100 /* Transmit Successful From Mailbox 24 */ +#define TA25 0x0200 /* Transmit Successful From Mailbox 25 */ +#define TA26 0x0400 /* Transmit Successful From Mailbox 26 */ +#define TA27 0x0800 /* Transmit Successful From Mailbox 27 */ +#define TA28 0x1000 /* Transmit Successful From Mailbox 28 */ +#define TA29 0x2000 /* Transmit Successful From Mailbox 29 */ +#define TA30 0x4000 /* Transmit Successful From Mailbox 30 */ +#define TA31 0x8000 /* Transmit Successful From Mailbox 31 */ + +/* CAN_MBTD Masks */ +#define TDPTR 0x001F /* Mailbox To Temporarily Disable */ +#define TDA 0x0040 /* Temporary Disable Acknowledge */ +#define TDR 0x0080 /* Temporary Disable Request */ + +/* CAN_RFH1 Masks */ +#define RFH0 0x0001 /* Enable Automatic Remote Frame Handling For Mailbox 0 */ +#define RFH1 0x0002 /* Enable Automatic Remote Frame Handling For Mailbox 1 */ +#define RFH2 0x0004 /* Enable Automatic Remote Frame Handling For Mailbox 2 */ +#define RFH3 0x0008 /* Enable Automatic Remote Frame Handling For Mailbox 3 */ +#define RFH4 0x0010 /* Enable Automatic Remote Frame Handling For Mailbox 4 */ +#define RFH5 0x0020 /* Enable Automatic Remote Frame Handling For Mailbox 5 */ +#define RFH6 0x0040 /* Enable Automatic Remote Frame Handling For Mailbox 6 */ +#define RFH7 0x0080 /* Enable Automatic Remote Frame Handling For Mailbox 7 */ +#define RFH8 0x0100 /* Enable Automatic Remote Frame Handling For Mailbox 8 */ +#define RFH9 0x0200 /* Enable Automatic Remote Frame Handling For Mailbox 9 */ +#define RFH10 0x0400 /* Enable Automatic Remote Frame Handling For Mailbox 10 */ +#define RFH11 0x0800 /* Enable Automatic Remote Frame Handling For Mailbox 11 */ +#define RFH12 0x1000 /* Enable Automatic Remote Frame Handling For Mailbox 12 */ +#define RFH13 0x2000 /* Enable Automatic Remote Frame Handling For Mailbox 13 */ +#define RFH14 0x4000 /* Enable Automatic Remote Frame Handling For Mailbox 14 */ +#define RFH15 0x8000 /* Enable Automatic Remote Frame Handling For Mailbox 15 */ + +/* CAN_RFH2 Masks */ +#define RFH16 0x0001 /* Enable Automatic Remote Frame Handling For Mailbox 16 */ +#define RFH17 0x0002 /* Enable Automatic Remote Frame Handling For Mailbox 17 */ +#define RFH18 0x0004 /* Enable Automatic Remote Frame Handling For Mailbox 18 */ +#define RFH19 0x0008 /* Enable Automatic Remote Frame Handling For Mailbox 19 */ +#define RFH20 0x0010 /* Enable Automatic Remote Frame Handling For Mailbox 20 */ +#define RFH21 0x0020 /* Enable Automatic Remote Frame Handling For Mailbox 21 */ +#define RFH22 0x0040 /* Enable Automatic Remote Frame Handling For Mailbox 22 */ +#define RFH23 0x0080 /* Enable Automatic Remote Frame Handling For Mailbox 23 */ +#define RFH24 0x0100 /* Enable Automatic Remote Frame Handling For Mailbox 24 */ +#define RFH25 0x0200 /* Enable Automatic Remote Frame Handling For Mailbox 25 */ +#define RFH26 0x0400 /* Enable Automatic Remote Frame Handling For Mailbox 26 */ +#define RFH27 0x0800 /* Enable Automatic Remote Frame Handling For Mailbox 27 */ +#define RFH28 0x1000 /* Enable Automatic Remote Frame Handling For Mailbox 28 */ +#define RFH29 0x2000 /* Enable Automatic Remote Frame Handling For Mailbox 29 */ +#define RFH30 0x4000 /* Enable Automatic Remote Frame Handling For Mailbox 30 */ +#define RFH31 0x8000 /* Enable Automatic Remote Frame Handling For Mailbox 31 */ + +/* CAN_MBTIF1 Masks */ +#define MBTIF0 0x0001 /* TX Interrupt Active In Mailbox 0 */ +#define MBTIF1 0x0002 /* TX Interrupt Active In Mailbox 1 */ +#define MBTIF2 0x0004 /* TX Interrupt Active In Mailbox 2 */ +#define MBTIF3 0x0008 /* TX Interrupt Active In Mailbox 3 */ +#define MBTIF4 0x0010 /* TX Interrupt Active In Mailbox 4 */ +#define MBTIF5 0x0020 /* TX Interrupt Active In Mailbox 5 */ +#define MBTIF6 0x0040 /* TX Interrupt Active In Mailbox 6 */ +#define MBTIF7 0x0080 /* TX Interrupt Active In Mailbox 7 */ +#define MBTIF8 0x0100 /* TX Interrupt Active In Mailbox 8 */ +#define MBTIF9 0x0200 /* TX Interrupt Active In Mailbox 9 */ +#define MBTIF10 0x0400 /* TX Interrupt Active In Mailbox 10 */ +#define MBTIF11 0x0800 /* TX Interrupt Active In Mailbox 11 */ +#define MBTIF12 0x1000 /* TX Interrupt Active In Mailbox 12 */ +#define MBTIF13 0x2000 /* TX Interrupt Active In Mailbox 13 */ +#define MBTIF14 0x4000 /* TX Interrupt Active In Mailbox 14 */ +#define MBTIF15 0x8000 /* TX Interrupt Active In Mailbox 15 */ + +/* CAN_MBTIF2 Masks */ +#define MBTIF16 0x0001 /* TX Interrupt Active In Mailbox 16 */ +#define MBTIF17 0x0002 /* TX Interrupt Active In Mailbox 17 */ +#define MBTIF18 0x0004 /* TX Interrupt Active In Mailbox 18 */ +#define MBTIF19 0x0008 /* TX Interrupt Active In Mailbox 19 */ +#define MBTIF20 0x0010 /* TX Interrupt Active In Mailbox 20 */ +#define MBTIF21 0x0020 /* TX Interrupt Active In Mailbox 21 */ +#define MBTIF22 0x0040 /* TX Interrupt Active In Mailbox 22 */ +#define MBTIF23 0x0080 /* TX Interrupt Active In Mailbox 23 */ +#define MBTIF24 0x0100 /* TX Interrupt Active In Mailbox 24 */ +#define MBTIF25 0x0200 /* TX Interrupt Active In Mailbox 25 */ +#define MBTIF26 0x0400 /* TX Interrupt Active In Mailbox 26 */ +#define MBTIF27 0x0800 /* TX Interrupt Active In Mailbox 27 */ +#define MBTIF28 0x1000 /* TX Interrupt Active In Mailbox 28 */ +#define MBTIF29 0x2000 /* TX Interrupt Active In Mailbox 29 */ +#define MBTIF30 0x4000 /* TX Interrupt Active In Mailbox 30 */ +#define MBTIF31 0x8000 /* TX Interrupt Active In Mailbox 31 */ + +/* CAN_MBRIF1 Masks */ +#define MBRIF0 0x0001 /* RX Interrupt Active In Mailbox 0 */ +#define MBRIF1 0x0002 /* RX Interrupt Active In Mailbox 1 */ +#define MBRIF2 0x0004 /* RX Interrupt Active In Mailbox 2 */ +#define MBRIF3 0x0008 /* RX Interrupt Active In Mailbox 3 */ +#define MBRIF4 0x0010 /* RX Interrupt Active In Mailbox 4 */ +#define MBRIF5 0x0020 /* RX Interrupt Active In Mailbox 5 */ +#define MBRIF6 0x0040 /* RX Interrupt Active In Mailbox 6 */ +#define MBRIF7 0x0080 /* RX Interrupt Active In Mailbox 7 */ +#define MBRIF8 0x0100 /* RX Interrupt Active In Mailbox 8 */ +#define MBRIF9 0x0200 /* RX Interrupt Active In Mailbox 9 */ +#define MBRIF10 0x0400 /* RX Interrupt Active In Mailbox 10 */ +#define MBRIF11 0x0800 /* RX Interrupt Active In Mailbox 11 */ +#define MBRIF12 0x1000 /* RX Interrupt Active In Mailbox 12 */ +#define MBRIF13 0x2000 /* RX Interrupt Active In Mailbox 13 */ +#define MBRIF14 0x4000 /* RX Interrupt Active In Mailbox 14 */ +#define MBRIF15 0x8000 /* RX Interrupt Active In Mailbox 15 */ + +/* CAN_MBRIF2 Masks */ +#define MBRIF16 0x0001 /* RX Interrupt Active In Mailbox 16 */ +#define MBRIF17 0x0002 /* RX Interrupt Active In Mailbox 17 */ +#define MBRIF18 0x0004 /* RX Interrupt Active In Mailbox 18 */ +#define MBRIF19 0x0008 /* RX Interrupt Active In Mailbox 19 */ +#define MBRIF20 0x0010 /* RX Interrupt Active In Mailbox 20 */ +#define MBRIF21 0x0020 /* RX Interrupt Active In Mailbox 21 */ +#define MBRIF22 0x0040 /* RX Interrupt Active In Mailbox 22 */ +#define MBRIF23 0x0080 /* RX Interrupt Active In Mailbox 23 */ +#define MBRIF24 0x0100 /* RX Interrupt Active In Mailbox 24 */ +#define MBRIF25 0x0200 /* RX Interrupt Active In Mailbox 25 */ +#define MBRIF26 0x0400 /* RX Interrupt Active In Mailbox 26 */ +#define MBRIF27 0x0800 /* RX Interrupt Active In Mailbox 27 */ +#define MBRIF28 0x1000 /* RX Interrupt Active In Mailbox 28 */ +#define MBRIF29 0x2000 /* RX Interrupt Active In Mailbox 29 */ +#define MBRIF30 0x4000 /* RX Interrupt Active In Mailbox 30 */ +#define MBRIF31 0x8000 /* RX Interrupt Active In Mailbox 31 */ + +/* CAN_MBIM1 Masks */ +#define MBIM0 0x0001 /* Enable Interrupt For Mailbox 0 */ +#define MBIM1 0x0002 /* Enable Interrupt For Mailbox 1 */ +#define MBIM2 0x0004 /* Enable Interrupt For Mailbox 2 */ +#define MBIM3 0x0008 /* Enable Interrupt For Mailbox 3 */ +#define MBIM4 0x0010 /* Enable Interrupt For Mailbox 4 */ +#define MBIM5 0x0020 /* Enable Interrupt For Mailbox 5 */ +#define MBIM6 0x0040 /* Enable Interrupt For Mailbox 6 */ +#define MBIM7 0x0080 /* Enable Interrupt For Mailbox 7 */ +#define MBIM8 0x0100 /* Enable Interrupt For Mailbox 8 */ +#define MBIM9 0x0200 /* Enable Interrupt For Mailbox 9 */ +#define MBIM10 0x0400 /* Enable Interrupt For Mailbox 10 */ +#define MBIM11 0x0800 /* Enable Interrupt For Mailbox 11 */ +#define MBIM12 0x1000 /* Enable Interrupt For Mailbox 12 */ +#define MBIM13 0x2000 /* Enable Interrupt For Mailbox 13 */ +#define MBIM14 0x4000 /* Enable Interrupt For Mailbox 14 */ +#define MBIM15 0x8000 /* Enable Interrupt For Mailbox 15 */ + +/* CAN_MBIM2 Masks */ +#define MBIM16 0x0001 /* Enable Interrupt For Mailbox 16 */ +#define MBIM17 0x0002 /* Enable Interrupt For Mailbox 17 */ +#define MBIM18 0x0004 /* Enable Interrupt For Mailbox 18 */ +#define MBIM19 0x0008 /* Enable Interrupt For Mailbox 19 */ +#define MBIM20 0x0010 /* Enable Interrupt For Mailbox 20 */ +#define MBIM21 0x0020 /* Enable Interrupt For Mailbox 21 */ +#define MBIM22 0x0040 /* Enable Interrupt For Mailbox 22 */ +#define MBIM23 0x0080 /* Enable Interrupt For Mailbox 23 */ +#define MBIM24 0x0100 /* Enable Interrupt For Mailbox 24 */ +#define MBIM25 0x0200 /* Enable Interrupt For Mailbox 25 */ +#define MBIM26 0x0400 /* Enable Interrupt For Mailbox 26 */ +#define MBIM27 0x0800 /* Enable Interrupt For Mailbox 27 */ +#define MBIM28 0x1000 /* Enable Interrupt For Mailbox 28 */ +#define MBIM29 0x2000 /* Enable Interrupt For Mailbox 29 */ +#define MBIM30 0x4000 /* Enable Interrupt For Mailbox 30 */ +#define MBIM31 0x8000 /* Enable Interrupt For Mailbox 31 */ + +/* CAN_GIM Masks */ +#define EWTIM 0x0001 /* Enable TX Error Count Interrupt */ +#define EWRIM 0x0002 /* Enable RX Error Count Interrupt */ +#define EPIM 0x0004 /* Enable Error-Passive Mode Interrupt */ +#define BOIM 0x0008 /* Enable Bus Off Interrupt */ +#define WUIM 0x0010 /* Enable Wake-Up Interrupt */ +#define UIAIM 0x0020 /* Enable Access To Unimplemented Address Interrupt */ +#define AAIM 0x0040 /* Enable Abort Acknowledge Interrupt */ +#define RMLIM 0x0080 /* Enable RX Message Lost Interrupt */ +#define UCEIM 0x0100 /* Enable Universal Counter Overflow Interrupt */ +#define EXTIM 0x0200 /* Enable External Trigger Output Interrupt */ +#define ADIM 0x0400 /* Enable Access Denied Interrupt */ + +/* CAN_GIS Masks */ +#define EWTIS 0x0001 /* TX Error Count IRQ Status */ +#define EWRIS 0x0002 /* RX Error Count IRQ Status */ +#define EPIS 0x0004 /* Error-Passive Mode IRQ Status */ +#define BOIS 0x0008 /* Bus Off IRQ Status */ +#define WUIS 0x0010 /* Wake-Up IRQ Status */ +#define UIAIS 0x0020 /* Access To Unimplemented Address IRQ Status */ +#define AAIS 0x0040 /* Abort Acknowledge IRQ Status */ +#define RMLIS 0x0080 /* RX Message Lost IRQ Status */ +#define UCEIS 0x0100 /* Universal Counter Overflow IRQ Status */ +#define EXTIS 0x0200 /* External Trigger Output IRQ Status */ +#define ADIS 0x0400 /* Access Denied IRQ Status */ + +/* CAN_GIF Masks */ +#define EWTIF 0x0001 /* TX Error Count IRQ Flag */ +#define EWRIF 0x0002 /* RX Error Count IRQ Flag */ +#define EPIF 0x0004 /* Error-Passive Mode IRQ Flag */ +#define BOIF 0x0008 /* Bus Off IRQ Flag */ +#define WUIF 0x0010 /* Wake-Up IRQ Flag */ +#define UIAIF 0x0020 /* Access To Unimplemented Address IRQ Flag */ +#define AAIF 0x0040 /* Abort Acknowledge IRQ Flag */ +#define RMLIF 0x0080 /* RX Message Lost IRQ Flag */ +#define UCEIF 0x0100 /* Universal Counter Overflow IRQ Flag */ +#define EXTIF 0x0200 /* External Trigger Output IRQ Flag */ +#define ADIF 0x0400 /* Access Denied IRQ Flag */ + +/* CAN_UCCNF Masks */ +#define UCCNF 0x000F /* Universal Counter Mode */ +#define UC_STAMP 0x0001 /* Timestamp Mode */ +#define UC_WDOG 0x0002 /* Watchdog Mode */ +#define UC_AUTOTX 0x0003 /* Auto-Transmit Mode */ +#define UC_ERROR 0x0006 /* CAN Error Frame Count */ +#define UC_OVER 0x0007 /* CAN Overload Frame Count */ +#define UC_LOST 0x0008 /* Arbitration Lost During TX Count */ +#define UC_AA 0x0009 /* TX Abort Count */ +#define UC_TA 0x000A /* TX Successful Count */ +#define UC_REJECT 0x000B /* RX Message Rejected Count */ +#define UC_RML 0x000C /* RX Message Lost Count */ +#define UC_RX 0x000D /* Total Successful RX Messages Count */ +#define UC_RMP 0x000E /* Successful RX W/Matching ID Count */ +#define UC_ALL 0x000F /* Correct Message On CAN Bus Line Count */ +#define UCRC 0x0020 /* Universal Counter Reload/Clear */ +#define UCCT 0x0040 /* Universal Counter CAN Trigger */ +#define UCE 0x0080 /* Universal Counter Enable */ + +/* CAN_ESR Masks */ +#define ACKE 0x0004 /* Acknowledge Error */ +#define SER 0x0008 /* Stuff Error */ +#define CRCE 0x0010 /* CRC Error */ +#define SA0 0x0020 /* Stuck At Dominant Error */ +#define BEF 0x0040 /* Bit Error Flag */ +#define FER 0x0080 /* Form Error Flag */ + +/* CAN_EWR Masks */ +#define EWLREC 0x00FF /* RX Error Count Limit (For EWRIS) */ +#define EWLTEC 0xFF00 /* TX Error Count Limit (For EWTIS) */ + +/* ******************* PIN CONTROL REGISTER MASKS ************************/ +/* PORT_MUX Masks */ +#define PJSE 0x0001 /* Port J SPI/SPORT Enable */ +#define PJSE_SPORT 0x0000 /* Enable TFS0/DT0PRI */ +#define PJSE_SPI 0x0001 /* Enable SPI_SSEL3:2 */ + +#define PJCE(x) (((x)&0x3)<<1) /* Port J CAN/SPI/SPORT Enable */ +#define PJCE_SPORT 0x0000 /* Enable DR0SEC/DT0SEC */ +#define PJCE_CAN 0x0002 /* Enable CAN RX/TX */ +#define PJCE_SPI 0x0004 /* Enable SPI_SSEL7 */ + +#define PFDE 0x0008 /* Port F DMA Request Enable */ +#define PGDE_UART 0x0000 /* Enable UART0 RX/TX */ +#define PGDE_DMA 0x0008 /* Enable DMAR1:0 */ + +#define PFTE 0x0010 /* Port F Timer Enable */ +#define PFTE_UART 0x0000 /* Enable UART1 RX/TX */ +#define PFTE_TIMER 0x0010 /* Enable TMR7:6 */ + +#define PFS6E 0x0020 /* Port F SPI SSEL 6 Enable */ +#define PFS6E_TIMER 0x0000 /* Enable TMR5 */ +#define PFS6E_SPI 0x0020 /* Enable SPI_SSEL6 */ + +#define PFS5E 0x0040 /* Port F SPI SSEL 5 Enable */ +#define PFS5E_TIMER 0x0000 /* Enable TMR4 */ +#define PFS5E_SPI 0x0040 /* Enable SPI_SSEL5 */ + +#define PFS4E 0x0080 /* Port F SPI SSEL 4 Enable */ +#define PFS4E_TIMER 0x0000 /* Enable TMR3 */ +#define PFS4E_SPI 0x0080 /* Enable SPI_SSEL4 */ + +#define PFFE 0x0100 /* Port F PPI Frame Sync Enable */ +#define PFFE_TIMER 0x0000 /* Enable TMR2 */ +#define PFFE_PPI 0x0100 /* Enable PPI FS3 */ + +#define PGSE 0x0200 /* Port G SPORT1 Secondary Enable */ +#define PGSE_PPI 0x0000 /* Enable PPI D9:8 */ +#define PGSE_SPORT 0x0200 /* Enable DR1SEC/DT1SEC */ + +#define PGRE 0x0400 /* Port G SPORT1 Receive Enable */ +#define PGRE_PPI 0x0000 /* Enable PPI D12:10 */ +#define PGRE_SPORT 0x0400 /* Enable DR1PRI/RFS1/RSCLK1 */ + +#define PGTE 0x0800 /* Port G SPORT1 Transmit Enable */ +#define PGTE_PPI 0x0000 /* Enable PPI D15:13 */ +#define PGTE_SPORT 0x0800 /* Enable DT1PRI/TFS1/TSCLK1 */ + +/* ****************** HANDSHAKE DMA (HDMA) MASKS *********************/ +/* HDMAx_CTL Masks */ +#define HMDMAEN 0x0001 /* Enable Handshake DMA 0/1 */ +#define REP 0x0002 /* HDMA Request Polarity */ +#define UTE 0x0004 /* Urgency Threshold Enable */ +#define OIE 0x0010 /* Overflow Interrupt Enable */ +#define BDIE 0x0020 /* Block Done Interrupt Enable */ +#define MBDI 0x0040 /* Mask Block Done IRQ If Pending ECNT */ +#define DRQ 0x0300 /* HDMA Request Type */ +#define DRQ_NONE 0x0000 /* No Request */ +#define DRQ_SINGLE 0x0100 /* Channels Request Single */ +#define DRQ_MULTI 0x0200 /* Channels Request Multi (Default) */ +#define DRQ_URGENT 0x0300 /* Channels Request Multi Urgent */ +#define RBC 0x1000 /* Reload BCNT With IBCNT */ +#define PS 0x2000 /* HDMA Pin Status */ +#define OI 0x4000 /* Overflow Interrupt Generated */ +#define BDI 0x8000 /* Block Done Interrupt Generated */ + +#endif /* _DEF_BF534_H */ diff --git a/include/asm-blackfin/mach-bf537/defBF537.h b/include/asm-blackfin/mach-bf537/defBF537.h new file mode 100644 index 000000000000..26f9c02eb73c --- /dev/null +++ b/include/asm-blackfin/mach-bf537/defBF537.h @@ -0,0 +1,404 @@ +/* + * file: include/asm-blackfin/mach-bf537/defbf537.h + * based on: + * author: + * + * created: + * description: + * system mmr register map + * rev: + * + * modified: + * + * + * bugs: enter bugs at http://blackfin.uclinux.org/ + * + * this program is free software; you can redistribute it and/or modify + * it under the terms of the gnu general public license as published by + * the free software foundation; either version 2, or (at your option) + * any later version. + * + * this program is distributed in the hope that it will be useful, + * but without any warranty; without even the implied warranty of + * merchantability or fitness for a particular purpose. see the + * gnu general public license for more details. + * + * you should have received a copy of the gnu general public license + * along with this program; see the file copying. + * if not, write to the free software foundation, + * 59 temple place - suite 330, boston, ma 02111-1307, usa. + */ + +#ifndef _DEF_BF537_H +#define _DEF_BF537_H + +/*include all Core registers and bit definitions*/ +#include "defBF537.h" + +/*include core specific register pointer definitions*/ +#include + +/************************************************************************************ +** Define EMAC Section Unique to BF536/BF537 +*************************************************************************************/ + +/* 10/100 Ethernet Controller (0xFFC03000 - 0xFFC031FF) */ +#define EMAC_OPMODE 0xFFC03000 /* Operating Mode Register */ +#define EMAC_ADDRLO 0xFFC03004 /* Address Low (32 LSBs) Register */ +#define EMAC_ADDRHI 0xFFC03008 /* Address High (16 MSBs) Register */ +#define EMAC_HASHLO 0xFFC0300C /* Multicast Hash Table Low (Bins 31-0) Register */ +#define EMAC_HASHHI 0xFFC03010 /* Multicast Hash Table High (Bins 63-32) Register */ +#define EMAC_STAADD 0xFFC03014 /* Station Management Address Register */ +#define EMAC_STADAT 0xFFC03018 /* Station Management Data Register */ +#define EMAC_FLC 0xFFC0301C /* Flow Control Register */ +#define EMAC_VLAN1 0xFFC03020 /* VLAN1 Tag Register */ +#define EMAC_VLAN2 0xFFC03024 /* VLAN2 Tag Register */ +#define EMAC_WKUP_CTL 0xFFC0302C /* Wake-Up Control/Status Register */ +#define EMAC_WKUP_FFMSK0 0xFFC03030 /* Wake-Up Frame Filter 0 Byte Mask Register */ +#define EMAC_WKUP_FFMSK1 0xFFC03034 /* Wake-Up Frame Filter 1 Byte Mask Register */ +#define EMAC_WKUP_FFMSK2 0xFFC03038 /* Wake-Up Frame Filter 2 Byte Mask Register */ +#define EMAC_WKUP_FFMSK3 0xFFC0303C /* Wake-Up Frame Filter 3 Byte Mask Register */ +#define EMAC_WKUP_FFCMD 0xFFC03040 /* Wake-Up Frame Filter Commands Register */ +#define EMAC_WKUP_FFOFF 0xFFC03044 /* Wake-Up Frame Filter Offsets Register */ +#define EMAC_WKUP_FFCRC0 0xFFC03048 /* Wake-Up Frame Filter 0,1 CRC-16 Register */ +#define EMAC_WKUP_FFCRC1 0xFFC0304C /* Wake-Up Frame Filter 2,3 CRC-16 Register */ + +#define EMAC_SYSCTL 0xFFC03060 /* EMAC System Control Register */ +#define EMAC_SYSTAT 0xFFC03064 /* EMAC System Status Register */ +#define EMAC_RX_STAT 0xFFC03068 /* RX Current Frame Status Register */ +#define EMAC_RX_STKY 0xFFC0306C /* RX Sticky Frame Status Register */ +#define EMAC_RX_IRQE 0xFFC03070 /* RX Frame Status Interrupt Enables Register */ +#define EMAC_TX_STAT 0xFFC03074 /* TX Current Frame Status Register */ +#define EMAC_TX_STKY 0xFFC03078 /* TX Sticky Frame Status Register */ +#define EMAC_TX_IRQE 0xFFC0307C /* TX Frame Status Interrupt Enables Register */ + +#define EMAC_MMC_CTL 0xFFC03080 /* MMC Counter Control Register */ +#define EMAC_MMC_RIRQS 0xFFC03084 /* MMC RX Interrupt Status Register */ +#define EMAC_MMC_RIRQE 0xFFC03088 /* MMC RX Interrupt Enables Register */ +#define EMAC_MMC_TIRQS 0xFFC0308C /* MMC TX Interrupt Status Register */ +#define EMAC_MMC_TIRQE 0xFFC03090 /* MMC TX Interrupt Enables Register */ + +#define EMAC_RXC_OK 0xFFC03100 /* RX Frame Successful Count */ +#define EMAC_RXC_FCS 0xFFC03104 /* RX Frame FCS Failure Count */ +#define EMAC_RXC_ALIGN 0xFFC03108 /* RX Alignment Error Count */ +#define EMAC_RXC_OCTET 0xFFC0310C /* RX Octets Successfully Received Count */ +#define EMAC_RXC_DMAOVF 0xFFC03110 /* Internal MAC Sublayer Error RX Frame Count */ +#define EMAC_RXC_UNICST 0xFFC03114 /* Unicast RX Frame Count */ +#define EMAC_RXC_MULTI 0xFFC03118 /* Multicast RX Frame Count */ +#define EMAC_RXC_BROAD 0xFFC0311C /* Broadcast RX Frame Count */ +#define EMAC_RXC_LNERRI 0xFFC03120 /* RX Frame In Range Error Count */ +#define EMAC_RXC_LNERRO 0xFFC03124 /* RX Frame Out Of Range Error Count */ +#define EMAC_RXC_LONG 0xFFC03128 /* RX Frame Too Long Count */ +#define EMAC_RXC_MACCTL 0xFFC0312C /* MAC Control RX Frame Count */ +#define EMAC_RXC_OPCODE 0xFFC03130 /* Unsupported Op-Code RX Frame Count */ +#define EMAC_RXC_PAUSE 0xFFC03134 /* MAC Control Pause RX Frame Count */ +#define EMAC_RXC_ALLFRM 0xFFC03138 /* Overall RX Frame Count */ +#define EMAC_RXC_ALLOCT 0xFFC0313C /* Overall RX Octet Count */ +#define EMAC_RXC_TYPED 0xFFC03140 /* Type/Length Consistent RX Frame Count */ +#define EMAC_RXC_SHORT 0xFFC03144 /* RX Frame Fragment Count - Byte Count x < 64 */ +#define EMAC_RXC_EQ64 0xFFC03148 /* Good RX Frame Count - Byte Count x = 64 */ +#define EMAC_RXC_LT128 0xFFC0314C /* Good RX Frame Count - Byte Count 64 <= x < 128 */ +#define EMAC_RXC_LT256 0xFFC03150 /* Good RX Frame Count - Byte Count 128 <= x < 256 */ +#define EMAC_RXC_LT512 0xFFC03154 /* Good RX Frame Count - Byte Count 256 <= x < 512 */ +#define EMAC_RXC_LT1024 0xFFC03158 /* Good RX Frame Count - Byte Count 512 <= x < 1024 */ +#define EMAC_RXC_GE1024 0xFFC0315C /* Good RX Frame Count - Byte Count x >= 1024 */ + +#define EMAC_TXC_OK 0xFFC03180 /* TX Frame Successful Count */ +#define EMAC_TXC_1COL 0xFFC03184 /* TX Frames Successful After Single Collision Count */ +#define EMAC_TXC_GT1COL 0xFFC03188 /* TX Frames Successful After Multiple Collisions Count */ +#define EMAC_TXC_OCTET 0xFFC0318C /* TX Octets Successfully Received Count */ +#define EMAC_TXC_DEFER 0xFFC03190 /* TX Frame Delayed Due To Busy Count */ +#define EMAC_TXC_LATECL 0xFFC03194 /* Late TX Collisions Count */ +#define EMAC_TXC_XS_COL 0xFFC03198 /* TX Frame Failed Due To Excessive Collisions Count */ +#define EMAC_TXC_DMAUND 0xFFC0319C /* Internal MAC Sublayer Error TX Frame Count */ +#define EMAC_TXC_CRSERR 0xFFC031A0 /* Carrier Sense Deasserted During TX Frame Count */ +#define EMAC_TXC_UNICST 0xFFC031A4 /* Unicast TX Frame Count */ +#define EMAC_TXC_MULTI 0xFFC031A8 /* Multicast TX Frame Count */ +#define EMAC_TXC_BROAD 0xFFC031AC /* Broadcast TX Frame Count */ +#define EMAC_TXC_XS_DFR 0xFFC031B0 /* TX Frames With Excessive Deferral Count */ +#define EMAC_TXC_MACCTL 0xFFC031B4 /* MAC Control TX Frame Count */ +#define EMAC_TXC_ALLFRM 0xFFC031B8 /* Overall TX Frame Count */ +#define EMAC_TXC_ALLOCT 0xFFC031BC /* Overall TX Octet Count */ +#define EMAC_TXC_EQ64 0xFFC031C0 /* Good TX Frame Count - Byte Count x = 64 */ +#define EMAC_TXC_LT128 0xFFC031C4 /* Good TX Frame Count - Byte Count 64 <= x < 128 */ +#define EMAC_TXC_LT256 0xFFC031C8 /* Good TX Frame Count - Byte Count 128 <= x < 256 */ +#define EMAC_TXC_LT512 0xFFC031CC /* Good TX Frame Count - Byte Count 256 <= x < 512 */ +#define EMAC_TXC_LT1024 0xFFC031D0 /* Good TX Frame Count - Byte Count 512 <= x < 1024 */ +#define EMAC_TXC_GE1024 0xFFC031D4 /* Good TX Frame Count - Byte Count x >= 1024 */ +#define EMAC_TXC_ABORT 0xFFC031D8 /* Total TX Frames Aborted Count */ + +/* Listing for IEEE-Supported Count Registers */ +#define FramesReceivedOK EMAC_RXC_OK /* RX Frame Successful Count */ +#define FrameCheckSequenceErrors EMAC_RXC_FCS /* RX Frame FCS Failure Count */ +#define AlignmentErrors EMAC_RXC_ALIGN /* RX Alignment Error Count */ +#define OctetsReceivedOK EMAC_RXC_OCTET /* RX Octets Successfully Received Count */ +#define FramesLostDueToIntMACRcvError EMAC_RXC_DMAOVF /* Internal MAC Sublayer Error RX Frame Count */ +#define UnicastFramesReceivedOK EMAC_RXC_UNICST /* Unicast RX Frame Count */ +#define MulticastFramesReceivedOK EMAC_RXC_MULTI /* Multicast RX Frame Count */ +#define BroadcastFramesReceivedOK EMAC_RXC_BROAD /* Broadcast RX Frame Count */ +#define InRangeLengthErrors EMAC_RXC_LNERRI /* RX Frame In Range Error Count */ +#define OutOfRangeLengthField EMAC_RXC_LNERRO /* RX Frame Out Of Range Error Count */ +#define FrameTooLongErrors EMAC_RXC_LONG /* RX Frame Too Long Count */ +#define MACControlFramesReceived EMAC_RXC_MACCTL /* MAC Control RX Frame Count */ +#define UnsupportedOpcodesReceived EMAC_RXC_OPCODE /* Unsupported Op-Code RX Frame Count */ +#define PAUSEMACCtrlFramesReceived EMAC_RXC_PAUSE /* MAC Control Pause RX Frame Count */ +#define FramesReceivedAll EMAC_RXC_ALLFRM /* Overall RX Frame Count */ +#define OctetsReceivedAll EMAC_RXC_ALLOCT /* Overall RX Octet Count */ +#define TypedFramesReceived EMAC_RXC_TYPED /* Type/Length Consistent RX Frame Count */ +#define FramesLenLt64Received EMAC_RXC_SHORT /* RX Frame Fragment Count - Byte Count x < 64 */ +#define FramesLenEq64Received EMAC_RXC_EQ64 /* Good RX Frame Count - Byte Count x = 64 */ +#define FramesLen65_127Received EMAC_RXC_LT128 /* Good RX Frame Count - Byte Count 64 <= x < 128 */ +#define FramesLen128_255Received EMAC_RXC_LT256 /* Good RX Frame Count - Byte Count 128 <= x < 256 */ +#define FramesLen256_511Received EMAC_RXC_LT512 /* Good RX Frame Count - Byte Count 256 <= x < 512 */ +#define FramesLen512_1023Received EMAC_RXC_LT1024 /* Good RX Frame Count - Byte Count 512 <= x < 1024 */ +#define FramesLen1024_MaxReceived EMAC_RXC_GE1024 /* Good RX Frame Count - Byte Count x >= 1024 */ + +#define FramesTransmittedOK EMAC_TXC_OK /* TX Frame Successful Count */ +#define SingleCollisionFrames EMAC_TXC_1COL /* TX Frames Successful After Single Collision Count */ +#define MultipleCollisionFrames EMAC_TXC_GT1COL /* TX Frames Successful After Multiple Collisions Count */ +#define OctetsTransmittedOK EMAC_TXC_OCTET /* TX Octets Successfully Received Count */ +#define FramesWithDeferredXmissions EMAC_TXC_DEFER /* TX Frame Delayed Due To Busy Count */ +#define LateCollisions EMAC_TXC_LATECL /* Late TX Collisions Count */ +#define FramesAbortedDueToXSColls EMAC_TXC_XS_COL /* TX Frame Failed Due To Excessive Collisions Count */ +#define FramesLostDueToIntMacXmitError EMAC_TXC_DMAUND /* Internal MAC Sublayer Error TX Frame Count */ +#define CarrierSenseErrors EMAC_TXC_CRSERR /* Carrier Sense Deasserted During TX Frame Count */ +#define UnicastFramesXmittedOK EMAC_TXC_UNICST /* Unicast TX Frame Count */ +#define MulticastFramesXmittedOK EMAC_TXC_MULTI /* Multicast TX Frame Count */ +#define BroadcastFramesXmittedOK EMAC_TXC_BROAD /* Broadcast TX Frame Count */ +#define FramesWithExcessiveDeferral EMAC_TXC_XS_DFR /* TX Frames With Excessive Deferral Count */ +#define MACControlFramesTransmitted EMAC_TXC_MACCTL /* MAC Control TX Frame Count */ +#define FramesTransmittedAll EMAC_TXC_ALLFRM /* Overall TX Frame Count */ +#define OctetsTransmittedAll EMAC_TXC_ALLOCT /* Overall TX Octet Count */ +#define FramesLenEq64Transmitted EMAC_TXC_EQ64 /* Good TX Frame Count - Byte Count x = 64 */ +#define FramesLen65_127Transmitted EMAC_TXC_LT128 /* Good TX Frame Count - Byte Count 64 <= x < 128 */ +#define FramesLen128_255Transmitted EMAC_TXC_LT256 /* Good TX Frame Count - Byte Count 128 <= x < 256 */ +#define FramesLen256_511Transmitted EMAC_TXC_LT512 /* Good TX Frame Count - Byte Count 256 <= x < 512 */ +#define FramesLen512_1023Transmitted EMAC_TXC_LT1024 /* Good TX Frame Count - Byte Count 512 <= x < 1024 */ +#define FramesLen1024_MaxTransmitted EMAC_TXC_GE1024 /* Good TX Frame Count - Byte Count x >= 1024 */ +#define TxAbortedFrames EMAC_TXC_ABORT /* Total TX Frames Aborted Count */ + +/*********************************************************************************** +** System MMR Register Bits And Macros +** +** Disclaimer: All macros are intended to make C and Assembly code more readable. +** Use these macros carefully, as any that do left shifts for field +** depositing will result in the lower order bits being destroyed. Any +** macro that shifts left to properly position the bit-field should be +** used as part of an OR to initialize a register and NOT as a dynamic +** modifier UNLESS the lower order bits are saved and ORed back in when +** the macro is used. +*************************************************************************************/ +/************************ ETHERNET 10/100 CONTROLLER MASKS ************************/ +/* EMAC_OPMODE Masks */ +#define RE 0x00000001 /* Receiver Enable */ +#define ASTP 0x00000002 /* Enable Automatic Pad Stripping On RX Frames */ +#define HU 0x00000010 /* Hash Filter Unicast Address */ +#define HM 0x00000020 /* Hash Filter Multicast Address */ +#define PAM 0x00000040 /* Pass-All-Multicast Mode Enable */ +#define PR 0x00000080 /* Promiscuous Mode Enable */ +#define IFE 0x00000100 /* Inverse Filtering Enable */ +#define DBF 0x00000200 /* Disable Broadcast Frame Reception */ +#define PBF 0x00000400 /* Pass Bad Frames Enable */ +#define PSF 0x00000800 /* Pass Short Frames Enable */ +#define RAF 0x00001000 /* Receive-All Mode */ +#define TE 0x00010000 /* Transmitter Enable */ +#define DTXPAD 0x00020000 /* Disable Automatic TX Padding */ +#define DTXCRC 0x00040000 /* Disable Automatic TX CRC Generation */ +#define DC 0x00080000 /* Deferral Check */ +#define BOLMT 0x00300000 /* Back-Off Limit */ +#define BOLMT_10 0x00000000 /* 10-bit range */ +#define BOLMT_8 0x00100000 /* 8-bit range */ +#define BOLMT_4 0x00200000 /* 4-bit range */ +#define BOLMT_1 0x00300000 /* 1-bit range */ +#define DRTY 0x00400000 /* Disable TX Retry On Collision */ +#define LCTRE 0x00800000 /* Enable TX Retry On Late Collision */ +#define RMII 0x01000000 /* RMII/MII* Mode */ +#define RMII_10 0x02000000 /* Speed Select for RMII Port (10MBit/100MBit*) */ +#define FDMODE 0x04000000 /* Duplex Mode Enable (Full/Half*) */ +#define LB 0x08000000 /* Internal Loopback Enable */ +#define DRO 0x10000000 /* Disable Receive Own Frames (Half-Duplex Mode) */ + +/* EMAC_STAADD Masks */ +#define STABUSY 0x00000001 /* Initiate Station Mgt Reg Access / STA Busy Stat */ +#define STAOP 0x00000002 /* Station Management Operation Code (Write/Read*) */ +#define STADISPRE 0x00000004 /* Disable Preamble Generation */ +#define STAIE 0x00000008 /* Station Mgt. Transfer Done Interrupt Enable */ +#define REGAD 0x000007C0 /* STA Register Address */ +#define PHYAD 0x0000F800 /* PHY Device Address */ + +#define SET_REGAD(x) (((x)&0x1F)<< 6 ) /* Set STA Register Address */ +#define SET_PHYAD(x) (((x)&0x1F)<< 11 ) /* Set PHY Device Address */ + +/* EMAC_STADAT Mask */ +#define STADATA 0x0000FFFF /* Station Management Data */ + +/* EMAC_FLC Masks */ +#define FLCBUSY 0x00000001 /* Send Flow Ctrl Frame / Flow Ctrl Busy Status */ +#define FLCE 0x00000002 /* Flow Control Enable */ +#define PCF 0x00000004 /* Pass Control Frames */ +#define BKPRSEN 0x00000008 /* Enable Backpressure */ +#define FLCPAUSE 0xFFFF0000 /* Pause Time */ + +#define SET_FLCPAUSE(x) (((x)&0xFFFF)<< 16) /* Set Pause Time */ + +/* EMAC_WKUP_CTL Masks */ +#define CAPWKFRM 0x00000001 /* Capture Wake-Up Frames */ +#define MPKE 0x00000002 /* Magic Packet Enable */ +#define RWKE 0x00000004 /* Remote Wake-Up Frame Enable */ +#define GUWKE 0x00000008 /* Global Unicast Wake Enable */ +#define MPKS 0x00000020 /* Magic Packet Received Status */ +#define RWKS 0x00000F00 /* Wake-Up Frame Received Status, Filters 3:0 */ + +/* EMAC_WKUP_FFCMD Masks */ +#define WF0_E 0x00000001 /* Enable Wake-Up Filter 0 */ +#define WF0_T 0x00000008 /* Wake-Up Filter 0 Addr Type (Multicast/Unicast*) */ +#define WF1_E 0x00000100 /* Enable Wake-Up Filter 1 */ +#define WF1_T 0x00000800 /* Wake-Up Filter 1 Addr Type (Multicast/Unicast*) */ +#define WF2_E 0x00010000 /* Enable Wake-Up Filter 2 */ +#define WF2_T 0x00080000 /* Wake-Up Filter 2 Addr Type (Multicast/Unicast*) */ +#define WF3_E 0x01000000 /* Enable Wake-Up Filter 3 */ +#define WF3_T 0x08000000 /* Wake-Up Filter 3 Addr Type (Multicast/Unicast*) */ + +/* EMAC_WKUP_FFOFF Masks */ +#define WF0_OFF 0x000000FF /* Wake-Up Filter 0 Pattern Offset */ +#define WF1_OFF 0x0000FF00 /* Wake-Up Filter 1 Pattern Offset */ +#define WF2_OFF 0x00FF0000 /* Wake-Up Filter 2 Pattern Offset */ +#define WF3_OFF 0xFF000000 /* Wake-Up Filter 3 Pattern Offset */ + +#define SET_WF0_OFF(x) (((x)&0xFF)<< 0 ) /* Set Wake-Up Filter 0 Byte Offset */ +#define SET_WF1_OFF(x) (((x)&0xFF)<< 8 ) /* Set Wake-Up Filter 1 Byte Offset */ +#define SET_WF2_OFF(x) (((x)&0xFF)<< 16 ) /* Set Wake-Up Filter 2 Byte Offset */ +#define SET_WF3_OFF(x) (((x)&0xFF)<< 24 ) /* Set Wake-Up Filter 3 Byte Offset */ +/* Set ALL Offsets */ +#define SET_WF_OFFS(x0,x1,x2,x3) (SET_WF0_OFF((x0))|SET_WF1_OFF((x1))|SET_WF2_OFF((x2))|SET_WF3_OFF((x3))) + +/* EMAC_WKUP_FFCRC0 Masks */ +#define WF0_CRC 0x0000FFFF /* Wake-Up Filter 0 Pattern CRC */ +#define WF1_CRC 0xFFFF0000 /* Wake-Up Filter 1 Pattern CRC */ + +#define SET_WF0_CRC(x) (((x)&0xFFFF)<< 0 ) /* Set Wake-Up Filter 0 Target CRC */ +#define SET_WF1_CRC(x) (((x)&0xFFFF)<< 16 ) /* Set Wake-Up Filter 1 Target CRC */ + +/* EMAC_WKUP_FFCRC1 Masks */ +#define WF2_CRC 0x0000FFFF /* Wake-Up Filter 2 Pattern CRC */ +#define WF3_CRC 0xFFFF0000 /* Wake-Up Filter 3 Pattern CRC */ + +#define SET_WF2_CRC(x) (((x)&0xFFFF)<< 0 ) /* Set Wake-Up Filter 2 Target CRC */ +#define SET_WF3_CRC(x) (((x)&0xFFFF)<< 16 ) /* Set Wake-Up Filter 3 Target CRC */ + +/* EMAC_SYSCTL Masks */ +#define PHYIE 0x00000001 /* PHY_INT Interrupt Enable */ +#define RXDWA 0x00000002 /* Receive Frame DMA Word Alignment (Odd/Even*) */ +#define RXCKS 0x00000004 /* Enable RX Frame TCP/UDP Checksum Computation */ +#define MDCDIV 0x00003F00 /* SCLK:MDC Clock Divisor [MDC=SCLK/(2*(N+1))] */ + +#define SET_MDCDIV(x) (((x)&0x3F)<< 8) /* Set MDC Clock Divisor */ + +/* EMAC_SYSTAT Masks */ +#define PHYINT 0x00000001 /* PHY_INT Interrupt Status */ +#define MMCINT 0x00000002 /* MMC Counter Interrupt Status */ +#define RXFSINT 0x00000004 /* RX Frame-Status Interrupt Status */ +#define TXFSINT 0x00000008 /* TX Frame-Status Interrupt Status */ +#define WAKEDET 0x00000010 /* Wake-Up Detected Status */ +#define RXDMAERR 0x00000020 /* RX DMA Direction Error Status */ +#define TXDMAERR 0x00000040 /* TX DMA Direction Error Status */ +#define STMDONE 0x00000080 /* Station Mgt. Transfer Done Interrupt Status */ + +/* EMAC_RX_STAT, EMAC_RX_STKY, and EMAC_RX_IRQE Masks */ +#define RX_FRLEN 0x000007FF /* Frame Length In Bytes */ +#define RX_COMP 0x00001000 /* RX Frame Complete */ +#define RX_OK 0x00002000 /* RX Frame Received With No Errors */ +#define RX_LONG 0x00004000 /* RX Frame Too Long Error */ +#define RX_ALIGN 0x00008000 /* RX Frame Alignment Error */ +#define RX_CRC 0x00010000 /* RX Frame CRC Error */ +#define RX_LEN 0x00020000 /* RX Frame Length Error */ +#define RX_FRAG 0x00040000 /* RX Frame Fragment Error */ +#define RX_ADDR 0x00080000 /* RX Frame Address Filter Failed Error */ +#define RX_DMAO 0x00100000 /* RX Frame DMA Overrun Error */ +#define RX_PHY 0x00200000 /* RX Frame PHY Error */ +#define RX_LATE 0x00400000 /* RX Frame Late Collision Error */ +#define RX_RANGE 0x00800000 /* RX Frame Length Field Out of Range Error */ +#define RX_MULTI 0x01000000 /* RX Multicast Frame Indicator */ +#define RX_BROAD 0x02000000 /* RX Broadcast Frame Indicator */ +#define RX_CTL 0x04000000 /* RX Control Frame Indicator */ +#define RX_UCTL 0x08000000 /* Unsupported RX Control Frame Indicator */ +#define RX_TYPE 0x10000000 /* RX Typed Frame Indicator */ +#define RX_VLAN1 0x20000000 /* RX VLAN1 Frame Indicator */ +#define RX_VLAN2 0x40000000 /* RX VLAN2 Frame Indicator */ +#define RX_ACCEPT 0x80000000 /* RX Frame Accepted Indicator */ + +/* EMAC_TX_STAT, EMAC_TX_STKY, and EMAC_TX_IRQE Masks */ +#define TX_COMP 0x00000001 /* TX Frame Complete */ +#define TX_OK 0x00000002 /* TX Frame Sent With No Errors */ +#define TX_ECOLL 0x00000004 /* TX Frame Excessive Collision Error */ +#define TX_LATE 0x00000008 /* TX Frame Late Collision Error */ +#define TX_DMAU 0x00000010 /* TX Frame DMA Underrun Error (STAT) */ +#define TX_MACE 0x00000010 /* Internal MAC Error Detected (STKY and IRQE) */ +#define TX_EDEFER 0x00000020 /* TX Frame Excessive Deferral Error */ +#define TX_BROAD 0x00000040 /* TX Broadcast Frame Indicator */ +#define TX_MULTI 0x00000080 /* TX Multicast Frame Indicator */ +#define TX_CCNT 0x00000F00 /* TX Frame Collision Count */ +#define TX_DEFER 0x00001000 /* TX Frame Deferred Indicator */ +#define TX_CRS 0x00002000 /* TX Frame Carrier Sense Not Asserted Error */ +#define TX_LOSS 0x00004000 /* TX Frame Carrier Lost During TX Error */ +#define TX_RETRY 0x00008000 /* TX Frame Successful After Retry */ +#define TX_FRLEN 0x07FF0000 /* TX Frame Length (Bytes) */ + +/* EMAC_MMC_CTL Masks */ +#define RSTC 0x00000001 /* Reset All Counters */ +#define CROLL 0x00000002 /* Counter Roll-Over Enable */ +#define CCOR 0x00000004 /* Counter Clear-On-Read Mode Enable */ +#define MMCE 0x00000008 /* Enable MMC Counter Operation */ + +/* EMAC_MMC_RIRQS and EMAC_MMC_RIRQE Masks */ +#define RX_OK_CNT 0x00000001 /* RX Frames Received With No Errors */ +#define RX_FCS_CNT 0x00000002 /* RX Frames W/Frame Check Sequence Errors */ +#define RX_ALIGN_CNT 0x00000004 /* RX Frames With Alignment Errors */ +#define RX_OCTET_CNT 0x00000008 /* RX Octets Received OK */ +#define RX_LOST_CNT 0x00000010 /* RX Frames Lost Due To Internal MAC RX Error */ +#define RX_UNI_CNT 0x00000020 /* Unicast RX Frames Received OK */ +#define RX_MULTI_CNT 0x00000040 /* Multicast RX Frames Received OK */ +#define RX_BROAD_CNT 0x00000080 /* Broadcast RX Frames Received OK */ +#define RX_IRL_CNT 0x00000100 /* RX Frames With In-Range Length Errors */ +#define RX_ORL_CNT 0x00000200 /* RX Frames With Out-Of-Range Length Errors */ +#define RX_LONG_CNT 0x00000400 /* RX Frames With Frame Too Long Errors */ +#define RX_MACCTL_CNT 0x00000800 /* MAC Control RX Frames Received */ +#define RX_OPCODE_CTL 0x00001000 /* Unsupported Op-Code RX Frames Received */ +#define RX_PAUSE_CNT 0x00002000 /* PAUSEMAC Control RX Frames Received */ +#define RX_ALLF_CNT 0x00004000 /* All RX Frames Received */ +#define RX_ALLO_CNT 0x00008000 /* All RX Octets Received */ +#define RX_TYPED_CNT 0x00010000 /* Typed RX Frames Received */ +#define RX_SHORT_CNT 0x00020000 /* RX Frame Fragments (< 64 Bytes) Received */ +#define RX_EQ64_CNT 0x00040000 /* 64-Byte RX Frames Received */ +#define RX_LT128_CNT 0x00080000 /* 65-127-Byte RX Frames Received */ +#define RX_LT256_CNT 0x00100000 /* 128-255-Byte RX Frames Received */ +#define RX_LT512_CNT 0x00200000 /* 256-511-Byte RX Frames Received */ +#define RX_LT1024_CNT 0x00400000 /* 512-1023-Byte RX Frames Received */ +#define RX_GE1024_CNT 0x00800000 /* 1024-Max-Byte RX Frames Received */ + +/* EMAC_MMC_TIRQS and EMAC_MMC_TIRQE Masks */ +#define TX_OK_CNT 0x00000001 /* TX Frames Sent OK */ +#define TX_SCOLL_CNT 0x00000002 /* TX Frames With Single Collisions */ +#define TX_MCOLL_CNT 0x00000004 /* TX Frames With Multiple Collisions */ +#define TX_OCTET_CNT 0x00000008 /* TX Octets Sent OK */ +#define TX_DEFER_CNT 0x00000010 /* TX Frames With Deferred Transmission */ +#define TX_LATE_CNT 0x00000020 /* TX Frames With Late Collisions */ +#define TX_ABORTC_CNT 0x00000040 /* TX Frames Aborted Due To Excess Collisions */ +#define TX_LOST_CNT 0x00000080 /* TX Frames Lost Due To Internal MAC TX Error */ +#define TX_CRS_CNT 0x00000100 /* TX Frames With Carrier Sense Errors */ +#define TX_UNI_CNT 0x00000200 /* Unicast TX Frames Sent */ +#define TX_MULTI_CNT 0x00000400 /* Multicast TX Frames Sent */ +#define TX_BROAD_CNT 0x00000800 /* Broadcast TX Frames Sent */ +#define TX_EXDEF_CTL 0x00001000 /* TX Frames With Excessive Deferral */ +#define TX_MACCTL_CNT 0x00002000 /* MAC Control TX Frames Sent */ +#define TX_ALLF_CNT 0x00004000 /* All TX Frames Sent */ +#define TX_ALLO_CNT 0x00008000 /* All TX Octets Sent */ +#define TX_EQ64_CNT 0x00010000 /* 64-Byte TX Frames Sent */ +#define TX_LT128_CNT 0x00020000 /* 65-127-Byte TX Frames Sent */ +#define TX_LT256_CNT 0x00040000 /* 128-255-Byte TX Frames Sent */ +#define TX_LT512_CNT 0x00080000 /* 256-511-Byte TX Frames Sent */ +#define TX_LT1024_CNT 0x00100000 /* 512-1023-Byte TX Frames Sent */ +#define TX_GE1024_CNT 0x00200000 /* 1024-Max-Byte TX Frames Sent */ +#define TX_ABORT_CNT 0x00400000 /* TX Frames Aborted */ + +#endif /* _DEF_BF537_H */ diff --git a/include/asm-blackfin/mach-bf537/dma.h b/include/asm-blackfin/mach-bf537/dma.h new file mode 100644 index 000000000000..7a964040870a --- /dev/null +++ b/include/asm-blackfin/mach-bf537/dma.h @@ -0,0 +1,55 @@ +/* + * file: include/asm-blackfin/mach-bf537/dma.h + * based on: + * author: + * + * created: + * description: + * system mmr register map + * rev: + * + * modified: + * + * + * bugs: enter bugs at http://blackfin.uclinux.org/ + * + * this program is free software; you can redistribute it and/or modify + * it under the terms of the gnu general public license as published by + * the free software foundation; either version 2, or (at your option) + * any later version. + * + * this program is distributed in the hope that it will be useful, + * but without any warranty; without even the implied warranty of + * merchantability or fitness for a particular purpose. see the + * gnu general public license for more details. + * + * you should have received a copy of the gnu general public license + * along with this program; see the file copying. + * if not, write to the free software foundation, + * 59 temple place - suite 330, boston, ma 02111-1307, usa. + */ + +#ifndef _MACH_DMA_H_ +#define _MACH_DMA_H_ + +#define MAX_BLACKFIN_DMA_CHANNEL 16 + +#define CH_PPI 0 +#define CH_EMAC_RX 1 +#define CH_EMAC_TX 2 +#define CH_SPORT0_RX 3 +#define CH_SPORT0_TX 4 +#define CH_SPORT1_RX 5 +#define CH_SPORT1_TX 6 +#define CH_SPI 7 +#define CH_UART0_RX 8 +#define CH_UART0_TX 9 +#define CH_UART1_RX 10 +#define CH_UART1_TX 11 + +#define CH_MEM_STREAM0_DEST 12 /* TX */ +#define CH_MEM_STREAM0_SRC 13 /* RX */ +#define CH_MEM_STREAM1_DEST 14 /* TX */ +#define CH_MEM_STREAM1_SRC 15 /* RX */ + +#endif diff --git a/include/asm-blackfin/mach-bf537/irq.h b/include/asm-blackfin/mach-bf537/irq.h new file mode 100644 index 000000000000..8af2a832ef6b --- /dev/null +++ b/include/asm-blackfin/mach-bf537/irq.h @@ -0,0 +1,219 @@ +/* + * file: include/asm-blackfin/mach-bf537/irq.h + * based on: + * author: + * + * created: + * description: + * system mmr register map + * rev: + * + * modified: + * + * + * bugs: enter bugs at http://blackfin.uclinux.org/ + * + * this program is free software; you can redistribute it and/or modify + * it under the terms of the gnu general public license as published by + * the free software foundation; either version 2, or (at your option) + * any later version. + * + * this program is distributed in the hope that it will be useful, + * but without any warranty; without even the implied warranty of + * merchantability or fitness for a particular purpose. see the + * gnu general public license for more details. + * + * you should have received a copy of the gnu general public license + * along with this program; see the file copying. + * if not, write to the free software foundation, + * 59 temple place - suite 330, boston, ma 02111-1307, usa. + */ + +#ifndef _BF537_IRQ_H_ +#define _BF537_IRQ_H_ + +/* + * Interrupt source definitions + Event Source Core Event Name +Core Emulation ** + Events (highest priority) EMU 0 + Reset RST 1 + NMI NMI 2 + Exception EVX 3 + Reserved -- 4 + Hardware Error IVHW 5 + Core Timer IVTMR 6 * + +..... + + Software Interrupt 1 IVG14 31 + Software Interrupt 2 -- + (lowest priority) IVG15 32 * + */ + +#define SYS_IRQS 41 +#define NR_PERI_INTS 32 + +/* The ABSTRACT IRQ definitions */ +/** the first seven of the following are fixed, the rest you change if you need to **/ +#define IRQ_EMU 0 /*Emulation */ +#define IRQ_RST 1 /*reset */ +#define IRQ_NMI 2 /*Non Maskable */ +#define IRQ_EVX 3 /*Exception */ +#define IRQ_UNUSED 4 /*- unused interrupt*/ +#define IRQ_HWERR 5 /*Hardware Error */ +#define IRQ_CORETMR 6 /*Core timer */ + +#define IRQ_PLL_WAKEUP 7 /*PLL Wakeup Interrupt */ +#define IRQ_DMA_ERROR 8 /*DMA Error (general) */ +#define IRQ_GENERIC_ERROR 9 /*GENERIC Error Interrupt */ +#define IRQ_RTC 10 /*RTC Interrupt */ +#define IRQ_PPI 11 /*DMA0 Interrupt (PPI) */ +#define IRQ_SPORT0_RX 12 /*DMA3 Interrupt (SPORT0 RX) */ +#define IRQ_SPORT0_TX 13 /*DMA4 Interrupt (SPORT0 TX) */ +#define IRQ_SPORT1_RX 14 /*DMA5 Interrupt (SPORT1 RX) */ +#define IRQ_SPORT1_TX 15 /*DMA6 Interrupt (SPORT1 TX) */ +#define IRQ_TWI 16 /*TWI Interrupt */ +#define IRQ_SPI 17 /*DMA7 Interrupt (SPI) */ +#define IRQ_UART0_RX 18 /*DMA8 Interrupt (UART0 RX) */ +#define IRQ_UART0_TX 19 /*DMA9 Interrupt (UART0 TX) */ +#define IRQ_UART1_RX 20 /*DMA10 Interrupt (UART1 RX) */ +#define IRQ_UART1_TX 21 /*DMA11 Interrupt (UART1 TX) */ +#define IRQ_CAN_RX 22 /*CAN Receive Interrupt */ +#define IRQ_CAN_TX 23 /*CAN Transmit Interrupt */ +#define IRQ_MAC_RX 24 /*DMA1 (Ethernet RX) Interrupt */ +#define IRQ_MAC_TX 25 /*DMA2 (Ethernet TX) Interrupt */ +#define IRQ_TMR0 26 /*Timer 0 */ +#define IRQ_TMR1 27 /*Timer 1 */ +#define IRQ_TMR2 28 /*Timer 2 */ +#define IRQ_TMR3 29 /*Timer 3 */ +#define IRQ_TMR4 30 /*Timer 4 */ +#define IRQ_TMR5 31 /*Timer 5 */ +#define IRQ_TMR6 32 /*Timer 6 */ +#define IRQ_TMR7 33 /*Timer 7 */ +#define IRQ_PROG_INTA 34 /* PF Ports F&G (PF15:0) Interrupt A */ +#define IRQ_PORTG_INTB 35 /* PF Port G (PF15:0) Interrupt B */ +#define IRQ_MEM_DMA0 36 /*(Memory DMA Stream 0) */ +#define IRQ_MEM_DMA1 37 /*(Memory DMA Stream 1) */ +#define IRQ_PROG_INTB 38 /* PF Ports F (PF15:0) Interrupt B */ +#define IRQ_WATCH 38 /*Watch Dog Timer */ +#define IRQ_SW_INT1 40 /*Software Int 1 */ +#define IRQ_SW_INT2 41 /*Software Int 2 (reserved for SYSCALL) */ + +#define IRQ_PPI_ERROR 42 /*PPI Error Interrupt */ +#define IRQ_CAN_ERROR 43 /*CAN Error Interrupt */ +#define IRQ_MAC_ERROR 44 /*PPI Error Interrupt */ +#define IRQ_SPORT0_ERROR 45 /*SPORT0 Error Interrupt */ +#define IRQ_SPORT1_ERROR 46 /*SPORT1 Error Interrupt */ +#define IRQ_SPI_ERROR 47 /*SPI Error Interrupt */ +#define IRQ_UART0_ERROR 48 /*UART Error Interrupt */ +#define IRQ_UART1_ERROR 49 /*UART Error Interrupt */ + +#define IRQ_PF0 50 +#define IRQ_PF1 51 +#define IRQ_PF2 52 +#define IRQ_PF3 53 +#define IRQ_PF4 54 +#define IRQ_PF5 55 +#define IRQ_PF6 56 +#define IRQ_PF7 57 +#define IRQ_PF8 58 +#define IRQ_PF9 59 +#define IRQ_PF10 60 +#define IRQ_PF11 61 +#define IRQ_PF12 62 +#define IRQ_PF13 63 +#define IRQ_PF14 64 +#define IRQ_PF15 65 + +#define IRQ_PG0 66 +#define IRQ_PG1 67 +#define IRQ_PG2 68 +#define IRQ_PG3 69 +#define IRQ_PG4 70 +#define IRQ_PG5 71 +#define IRQ_PG6 72 +#define IRQ_PG7 73 +#define IRQ_PG8 74 +#define IRQ_PG9 75 +#define IRQ_PG10 76 +#define IRQ_PG11 77 +#define IRQ_PG12 78 +#define IRQ_PG13 79 +#define IRQ_PG14 80 +#define IRQ_PG15 81 + +#define IRQ_PH0 82 +#define IRQ_PH1 83 +#define IRQ_PH2 84 +#define IRQ_PH3 85 +#define IRQ_PH4 86 +#define IRQ_PH5 87 +#define IRQ_PH6 88 +#define IRQ_PH7 89 +#define IRQ_PH8 90 +#define IRQ_PH9 91 +#define IRQ_PH10 92 +#define IRQ_PH11 93 +#define IRQ_PH12 94 +#define IRQ_PH13 95 +#define IRQ_PH14 96 +#define IRQ_PH15 97 + +#ifdef CONFIG_IRQCHIP_DEMUX_GPIO +#define NR_IRQS (IRQ_PH15+1) +#else +#define NR_IRQS (IRQ_UART1_ERROR+1) +#endif + +#define IVG7 7 +#define IVG8 8 +#define IVG9 9 +#define IVG10 10 +#define IVG11 11 +#define IVG12 12 +#define IVG13 13 +#define IVG14 14 +#define IVG15 15 + +/* IAR0 BIT FIELDS*/ +#define IRQ_PLL_WAKEUP_POS 0 +#define IRQ_DMA_ERROR_POS 4 +#define IRQ_ERROR_POS 8 +#define IRQ_RTC_POS 12 +#define IRQ_PPI_POS 16 +#define IRQ_SPORT0_RX_POS 20 +#define IRQ_SPORT0_TX_POS 24 +#define IRQ_SPORT1_RX_POS 28 + +/* IAR1 BIT FIELDS*/ +#define IRQ_SPORT1_TX_POS 0 +#define IRQ_TWI_POS 4 +#define IRQ_SPI_POS 8 +#define IRQ_UART0_RX_POS 12 +#define IRQ_UART0_TX_POS 16 +#define IRQ_UART1_RX_POS 20 +#define IRQ_UART1_TX_POS 24 +#define IRQ_CAN_RX_POS 28 + +/* IAR2 BIT FIELDS*/ +#define IRQ_CAN_TX_POS 0 +#define IRQ_MAC_RX_POS 4 +#define IRQ_MAC_TX_POS 8 +#define IRQ_TMR0_POS 12 +#define IRQ_TMR1_POS 16 +#define IRQ_TMR2_POS 20 +#define IRQ_TMR3_POS 24 +#define IRQ_TMR4_POS 28 + +/* IAR3 BIT FIELDS*/ +#define IRQ_TMR5_POS 0 +#define IRQ_TMR6_POS 4 +#define IRQ_TMR7_POS 8 +#define IRQ_PROG_INTA_POS 12 +#define IRQ_PORTG_INTB_POS 16 +#define IRQ_MEM_DMA0_POS 20 +#define IRQ_MEM_DMA1_POS 24 +#define IRQ_WATCH_POS 28 + +#endif /* _BF537_IRQ_H_ */ diff --git a/include/asm-blackfin/mach-bf537/mem_init.h b/include/asm-blackfin/mach-bf537/mem_init.h new file mode 100644 index 000000000000..9ad979d416c6 --- /dev/null +++ b/include/asm-blackfin/mach-bf537/mem_init.h @@ -0,0 +1,330 @@ +/* + * File: include/asm-blackfin/mach-bf537/mem_init.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Rev: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#if (CONFIG_MEM_MT48LC16M16A2TG_75 || CONFIG_MEM_MT48LC64M4A2FB_7E || CONFIG_MEM_MT48LC16M8A2TG_75 || CONFIG_MEM_GENERIC_BOARD || CONFIG_MEM_MT48LC32M8A2_75) +#if (CONFIG_SCLK_HZ > 119402985) +#define SDRAM_tRP TRP_2 +#define SDRAM_tRP_num 2 +#define SDRAM_tRAS TRAS_7 +#define SDRAM_tRAS_num 7 +#define SDRAM_tRCD TRCD_2 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 104477612) && (CONFIG_SCLK_HZ <= 119402985) +#define SDRAM_tRP TRP_2 +#define SDRAM_tRP_num 2 +#define SDRAM_tRAS TRAS_6 +#define SDRAM_tRAS_num 6 +#define SDRAM_tRCD TRCD_2 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 89552239) && (CONFIG_SCLK_HZ <= 104477612) +#define SDRAM_tRP TRP_2 +#define SDRAM_tRP_num 2 +#define SDRAM_tRAS TRAS_5 +#define SDRAM_tRAS_num 5 +#define SDRAM_tRCD TRCD_2 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 74626866) && (CONFIG_SCLK_HZ <= 89552239) +#define SDRAM_tRP TRP_2 +#define SDRAM_tRP_num 2 +#define SDRAM_tRAS TRAS_4 +#define SDRAM_tRAS_num 4 +#define SDRAM_tRCD TRCD_2 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 66666667) && (CONFIG_SCLK_HZ <= 74626866) +#define SDRAM_tRP TRP_2 +#define SDRAM_tRP_num 2 +#define SDRAM_tRAS TRAS_3 +#define SDRAM_tRAS_num 3 +#define SDRAM_tRCD TRCD_2 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 59701493) && (CONFIG_SCLK_HZ <= 66666667) +#define SDRAM_tRP TRP_1 +#define SDRAM_tRP_num 1 +#define SDRAM_tRAS TRAS_4 +#define SDRAM_tRAS_num 3 +#define SDRAM_tRCD TRCD_1 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 44776119) && (CONFIG_SCLK_HZ <= 59701493) +#define SDRAM_tRP TRP_1 +#define SDRAM_tRP_num 1 +#define SDRAM_tRAS TRAS_3 +#define SDRAM_tRAS_num 3 +#define SDRAM_tRCD TRCD_1 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 29850746) && (CONFIG_SCLK_HZ <= 44776119) +#define SDRAM_tRP TRP_1 +#define SDRAM_tRP_num 1 +#define SDRAM_tRAS TRAS_2 +#define SDRAM_tRAS_num 2 +#define SDRAM_tRCD TRCD_1 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ <= 29850746) +#define SDRAM_tRP TRP_1 +#define SDRAM_tRP_num 1 +#define SDRAM_tRAS TRAS_1 +#define SDRAM_tRAS_num 1 +#define SDRAM_tRCD TRCD_1 +#define SDRAM_tWR TWR_2 +#endif +#endif + +#if (CONFIG_MEM_MT48LC16M16A2TG_75) + /*SDRAM INFORMATION: */ +#define SDRAM_Tref 64 /* Refresh period in milliseconds */ +#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */ +#define SDRAM_CL CL_3 +#endif + +#if (CONFIG_MEM_MT48LC16M8A2TG_75) + /*SDRAM INFORMATION: */ +#define SDRAM_Tref 64 /* Refresh period in milliseconds */ +#define SDRAM_NRA 4096 /* Number of row addresses in SDRAM */ +#define SDRAM_CL CL_3 +#endif + +#if (CONFIG_MEM_MT48LC32M8A2_75) + /*SDRAM INFORMATION: */ +#define SDRAM_Tref 64 /* Refresh period in milliseconds */ +#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */ +#define SDRAM_CL CL_3 +#endif + +#if (CONFIG_MEM_MT48LC64M4A2FB_7E) + /*SDRAM INFORMATION: */ +#define SDRAM_Tref 64 /* Refresh period in milliseconds */ +#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */ +#define SDRAM_CL CL_3 +#endif + +#if (CONFIG_MEM_GENERIC_BOARD) + /*SDRAM INFORMATION: Modify this for your board */ +#define SDRAM_Tref 64 /* Refresh period in milliseconds */ +#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */ +#define SDRAM_CL CL_3 +#endif + +#if (CONFIG_MEM_SIZE == 128) +#define SDRAM_SIZE EBSZ_128 +#endif +#if (CONFIG_MEM_SIZE == 64) +#define SDRAM_SIZE EBSZ_64 +#endif +#if (CONFIG_MEM_SIZE == 32) +#define SDRAM_SIZE EBSZ_32 +#endif +#if (CONFIG_MEM_SIZE == 16) +#define SDRAM_SIZE EBSZ_16 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 11) +#define SDRAM_WIDTH EBCAW_11 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 10) +#define SDRAM_WIDTH EBCAW_10 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 9) +#define SDRAM_WIDTH EBCAW_9 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 8) +#define SDRAM_WIDTH EBCAW_8 +#endif + +#define mem_SDBCTL (SDRAM_WIDTH | SDRAM_SIZE | EBE) + +/* Equation from section 17 (p17-46) of BF533 HRM */ +#define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num) + +/* Enable SCLK Out */ +#define mem_SDGCTL (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR | PSS) + +#if defined CONFIG_CLKIN_HALF +#define CLKIN_HALF 1 +#else +#define CLKIN_HALF 0 +#endif + +#if defined CONFIG_PLL_BYPASS +#define PLL_BYPASS 1 +#else +#define PLL_BYPASS 0 +#endif + +/***************************************Currently Not Being Used *********************************/ +#define flash_EBIU_AMBCTL_WAT ((CONFIG_FLASH_SPEED_BWAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1 +#define flash_EBIU_AMBCTL_RAT ((CONFIG_FLASH_SPEED_BRAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1 +#define flash_EBIU_AMBCTL_HT ((CONFIG_FLASH_SPEED_BHT * 4) / (4000000000 / CONFIG_SCLK_HZ)) +#define flash_EBIU_AMBCTL_ST ((CONFIG_FLASH_SPEED_BST * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1 +#define flash_EBIU_AMBCTL_TT ((CONFIG_FLASH_SPEED_BTT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1 + +#if (flash_EBIU_AMBCTL_TT > 3) +#define flash_EBIU_AMBCTL0_TT B0TT_4 +#endif +#if (flash_EBIU_AMBCTL_TT == 3) +#define flash_EBIU_AMBCTL0_TT B0TT_3 +#endif +#if (flash_EBIU_AMBCTL_TT == 2) +#define flash_EBIU_AMBCTL0_TT B0TT_2 +#endif +#if (flash_EBIU_AMBCTL_TT < 2) +#define flash_EBIU_AMBCTL0_TT B0TT_1 +#endif + +#if (flash_EBIU_AMBCTL_ST > 3) +#define flash_EBIU_AMBCTL0_ST B0ST_4 +#endif +#if (flash_EBIU_AMBCTL_ST == 3) +#define flash_EBIU_AMBCTL0_ST B0ST_3 +#endif +#if (flash_EBIU_AMBCTL_ST == 2) +#define flash_EBIU_AMBCTL0_ST B0ST_2 +#endif +#if (flash_EBIU_AMBCTL_ST < 2) +#define flash_EBIU_AMBCTL0_ST B0ST_1 +#endif + +#if (flash_EBIU_AMBCTL_HT > 2) +#define flash_EBIU_AMBCTL0_HT B0HT_3 +#endif +#if (flash_EBIU_AMBCTL_HT == 2) +#define flash_EBIU_AMBCTL0_HT B0HT_2 +#endif +#if (flash_EBIU_AMBCTL_HT == 1) +#define flash_EBIU_AMBCTL0_HT B0HT_1 +#endif +#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT == 0) +#define flash_EBIU_AMBCTL0_HT B0HT_0 +#endif +#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT != 0) +#define flash_EBIU_AMBCTL0_HT B0HT_1 +#endif + +#if (flash_EBIU_AMBCTL_WAT > 14) +#define flash_EBIU_AMBCTL0_WAT B0WAT_15 +#endif +#if (flash_EBIU_AMBCTL_WAT == 14) +#define flash_EBIU_AMBCTL0_WAT B0WAT_14 +#endif +#if (flash_EBIU_AMBCTL_WAT == 13) +#define flash_EBIU_AMBCTL0_WAT B0WAT_13 +#endif +#if (flash_EBIU_AMBCTL_WAT == 12) +#define flash_EBIU_AMBCTL0_WAT B0WAT_12 +#endif +#if (flash_EBIU_AMBCTL_WAT == 11) +#define flash_EBIU_AMBCTL0_WAT B0WAT_11 +#endif +#if (flash_EBIU_AMBCTL_WAT == 10) +#define flash_EBIU_AMBCTL0_WAT B0WAT_10 +#endif +#if (flash_EBIU_AMBCTL_WAT == 9) +#define flash_EBIU_AMBCTL0_WAT B0WAT_9 +#endif +#if (flash_EBIU_AMBCTL_WAT == 8) +#define flash_EBIU_AMBCTL0_WAT B0WAT_8 +#endif +#if (flash_EBIU_AMBCTL_WAT == 7) +#define flash_EBIU_AMBCTL0_WAT B0WAT_7 +#endif +#if (flash_EBIU_AMBCTL_WAT == 6) +#define flash_EBIU_AMBCTL0_WAT B0WAT_6 +#endif +#if (flash_EBIU_AMBCTL_WAT == 5) +#define flash_EBIU_AMBCTL0_WAT B0WAT_5 +#endif +#if (flash_EBIU_AMBCTL_WAT == 4) +#define flash_EBIU_AMBCTL0_WAT B0WAT_4 +#endif +#if (flash_EBIU_AMBCTL_WAT == 3) +#define flash_EBIU_AMBCTL0_WAT B0WAT_3 +#endif +#if (flash_EBIU_AMBCTL_WAT == 2) +#define flash_EBIU_AMBCTL0_WAT B0WAT_2 +#endif +#if (flash_EBIU_AMBCTL_WAT == 1) +#define flash_EBIU_AMBCTL0_WAT B0WAT_1 +#endif + +#if (flash_EBIU_AMBCTL_RAT > 14) +#define flash_EBIU_AMBCTL0_RAT B0RAT_15 +#endif +#if (flash_EBIU_AMBCTL_RAT == 14) +#define flash_EBIU_AMBCTL0_RAT B0RAT_14 +#endif +#if (flash_EBIU_AMBCTL_RAT == 13) +#define flash_EBIU_AMBCTL0_RAT B0RAT_13 +#endif +#if (flash_EBIU_AMBCTL_RAT == 12) +#define flash_EBIU_AMBCTL0_RAT B0RAT_12 +#endif +#if (flash_EBIU_AMBCTL_RAT == 11) +#define flash_EBIU_AMBCTL0_RAT B0RAT_11 +#endif +#if (flash_EBIU_AMBCTL_RAT == 10) +#define flash_EBIU_AMBCTL0_RAT B0RAT_10 +#endif +#if (flash_EBIU_AMBCTL_RAT == 9) +#define flash_EBIU_AMBCTL0_RAT B0RAT_9 +#endif +#if (flash_EBIU_AMBCTL_RAT == 8) +#define flash_EBIU_AMBCTL0_RAT B0RAT_8 +#endif +#if (flash_EBIU_AMBCTL_RAT == 7) +#define flash_EBIU_AMBCTL0_RAT B0RAT_7 +#endif +#if (flash_EBIU_AMBCTL_RAT == 6) +#define flash_EBIU_AMBCTL0_RAT B0RAT_6 +#endif +#if (flash_EBIU_AMBCTL_RAT == 5) +#define flash_EBIU_AMBCTL0_RAT B0RAT_5 +#endif +#if (flash_EBIU_AMBCTL_RAT == 4) +#define flash_EBIU_AMBCTL0_RAT B0RAT_4 +#endif +#if (flash_EBIU_AMBCTL_RAT == 3) +#define flash_EBIU_AMBCTL0_RAT B0RAT_3 +#endif +#if (flash_EBIU_AMBCTL_RAT == 2) +#define flash_EBIU_AMBCTL0_RAT B0RAT_2 +#endif +#if (flash_EBIU_AMBCTL_RAT == 1) +#define flash_EBIU_AMBCTL0_RAT B0RAT_1 +#endif + +#define flash_EBIU_AMBCTL0 \ + (flash_EBIU_AMBCTL0_WAT | flash_EBIU_AMBCTL0_RAT | flash_EBIU_AMBCTL0_HT | \ + flash_EBIU_AMBCTL0_ST | flash_EBIU_AMBCTL0_TT | CONFIG_FLASH_SPEED_RDYEN) diff --git a/include/asm-blackfin/mach-bf537/mem_map.h b/include/asm-blackfin/mach-bf537/mem_map.h new file mode 100644 index 000000000000..2a808c1202bf --- /dev/null +++ b/include/asm-blackfin/mach-bf537/mem_map.h @@ -0,0 +1,175 @@ +/* + * file: include/asm-blackfin/mach-bf537/mem_map.h + * based on: + * author: + * + * created: + * description: + * Memory MAP Common header file for blackfin BF537/6/4 of processors. + * rev: + * + * modified: + * + * bugs: enter bugs at http://blackfin.uclinux.org/ + * + * this program is free software; you can redistribute it and/or modify + * it under the terms of the gnu general public license as published by + * the free software foundation; either version 2, or (at your option) + * any later version. + * + * this program is distributed in the hope that it will be useful, + * but without any warranty; without even the implied warranty of + * merchantability or fitness for a particular purpose. see the + * gnu general public license for more details. + * + * you should have received a copy of the gnu general public license + * along with this program; see the file copying. + * if not, write to the free software foundation, + * 59 temple place - suite 330, boston, ma 02111-1307, usa. + */ + +#ifndef _MEM_MAP_537_H_ +#define _MEM_MAP_537_H_ + +#define COREMMR_BASE 0xFFE00000 /* Core MMRs */ +#define SYSMMR_BASE 0xFFC00000 /* System MMRs */ + +/* Async Memory Banks */ +#define ASYNC_BANK3_BASE 0x20300000 /* Async Bank 3 */ +#define ASYNC_BANK3_SIZE 0x00100000 /* 1M */ +#define ASYNC_BANK2_BASE 0x20200000 /* Async Bank 2 */ +#define ASYNC_BANK2_SIZE 0x00100000 /* 1M */ +#define ASYNC_BANK1_BASE 0x20100000 /* Async Bank 1 */ +#define ASYNC_BANK1_SIZE 0x00100000 /* 1M */ +#define ASYNC_BANK0_BASE 0x20000000 /* Async Bank 0 */ +#define ASYNC_BANK0_SIZE 0x00100000 /* 1M */ + +/* Boot ROM Memory */ + +#define BOOT_ROM_START 0xEF000000 + +/* Level 1 Memory */ + +/* Memory Map for ADSP-BF537 processors */ + +#ifdef CONFIG_BLKFIN_CACHE +#define BLKFIN_ICACHESIZE (16*1024) +#else +#define BLKFIN_ICACHESIZE (0*1024) +#endif + + +#ifdef CONFIG_BF537 +#define L1_CODE_START 0xFFA00000 +#define L1_DATA_A_START 0xFF800000 +#define L1_DATA_B_START 0xFF900000 + +#define L1_CODE_LENGTH 0xC000 + +#ifdef CONFIG_BLKFIN_DCACHE + +#ifdef CONFIG_BLKFIN_DCACHE_BANKA +#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH (0x8000 - 0x4000) +#define L1_DATA_B_LENGTH 0x8000 +#define BLKFIN_DCACHESIZE (16*1024) +#define BLKFIN_DSUPBANKS 1 +#else +#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH (0x8000 - 0x4000) +#define L1_DATA_B_LENGTH (0x8000 - 0x4000) +#define BLKFIN_DCACHESIZE (32*1024) +#define BLKFIN_DSUPBANKS 2 +#endif + +#else +#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH 0x8000 +#define L1_DATA_B_LENGTH 0x8000 +#define BLKFIN_DCACHESIZE (0*1024) +#define BLKFIN_DSUPBANKS 0 +#endif /*CONFIG_BLKFIN_DCACHE*/ + +#endif /*CONFIG_BF537*/ + +/* Memory Map for ADSP-BF536 processors */ + +#ifdef CONFIG_BF536 +#define L1_CODE_START 0xFFA00000 +#define L1_DATA_A_START 0xFF804000 +#define L1_DATA_B_START 0xFF904000 + +#define L1_CODE_LENGTH 0xC000 + + +#ifdef CONFIG_BLKFIN_DCACHE + +#ifdef CONFIG_BLKFIN_DCACHE_BANKA +#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH (0x4000 - 0x4000) +#define L1_DATA_B_LENGTH 0x4000 +#define BLKFIN_DCACHESIZE (16*1024) +#define BLKFIN_DSUPBANKS 1 + +#else +#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH (0x4000 - 0x4000) +#define L1_DATA_B_LENGTH (0x4000 - 0x4000) +#define BLKFIN_DCACHESIZE (32*1024) +#define BLKFIN_DSUPBANKS 2 +#endif + +#else +#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH 0x4000 +#define L1_DATA_B_LENGTH 0x4000 +#define BLKFIN_DCACHESIZE (0*1024) +#define BLKFIN_DSUPBANKS 0 +#endif /*CONFIG_BLKFIN_DCACHE*/ + +#endif + +/* Memory Map for ADSP-BF534 processors */ + +#ifdef CONFIG_BF534 +#define L1_CODE_START 0xFFA00000 +#define L1_DATA_A_START 0xFF800000 +#define L1_DATA_B_START 0xFF900000 + +#define L1_CODE_LENGTH 0xC000 + +#ifdef CONFIG_BLKFIN_DCACHE + +#ifdef CONFIG_BLKFIN_DCACHE_BANKA +#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH (0x8000 - 0x4000) +#define L1_DATA_B_LENGTH 0x8000 +#define BLKFIN_DCACHESIZE (16*1024) +#define BLKFIN_DSUPBANKS 1 + +#else +#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH (0x8000 - 0x4000) +#define L1_DATA_B_LENGTH (0x8000 - 0x4000) +#define BLKFIN_DCACHESIZE (32*1024) +#define BLKFIN_DSUPBANKS 2 +#endif + +#else +#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH 0x8000 +#define L1_DATA_B_LENGTH 0x8000 +#define BLKFIN_DCACHESIZE (0*1024) +#define BLKFIN_DSUPBANKS 0 +#endif /*CONFIG_BLKFIN_DCACHE*/ + +#endif + +/* Scratch Pad Memory */ + +#if defined(CONFIG_BF537) || defined(CONFIG_BF536) || defined(CONFIG_BF534) +#define L1_SCRATCH_START 0xFFB00000 +#define L1_SCRATCH_LENGTH 0x1000 +#endif + +#endif /* _MEM_MAP_537_H_ */ diff --git a/include/asm-blackfin/mach-bf561/anomaly.h b/include/asm-blackfin/mach-bf561/anomaly.h new file mode 100644 index 000000000000..f5b32d66517d --- /dev/null +++ b/include/asm-blackfin/mach-bf561/anomaly.h @@ -0,0 +1,184 @@ + +/* + * File: include/asm-blackfin/mach-bf561/anomaly.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Rev: + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* This file shoule be up to date with: + * - Revision L, 10Aug2006; ADSP-BF561 Silicon Anomaly List + */ + +#ifndef _MACH_ANOMALY_H_ +#define _MACH_ANOMALY_H_ + +/* We do not support 0.1 or 0.4 silicon - sorry */ +#if (defined(CONFIG_BF_REV_0_1) || defined(CONFIG_BF_REV_0_2) || defined(CONFIG_BF_REV_0_4)) +#error Kernel will not work on BF561 Version 0.1, 0.2, or 0.4 +#endif + +/* Issues that are common to 0.5 and 0.3 silicon */ +#if (defined(CONFIG_BF_REV_0_5) || defined(CONFIG_BF_REV_0_3)) +#define ANOMALY_05000074 /* A multi issue instruction with dsp32shiftimm in + slot1 and store of a P register in slot 2 is not + supported */ +#define ANOMALY_05000099 /* UART Line Status Register (UART_LSR) bits are not + updated at the same time. */ +#define ANOMALY_05000120 /* Testset instructions restricted to 32-bit aligned + memory locations */ +#define ANOMALY_05000122 /* Rx.H cannot be used to access 16-bit System MMR + registers */ +#define ANOMALY_05000127 /* Signbits instruction not functional under certain + conditions */ +#define ANOMALY_05000149 /* IMDMA S1/D1 channel may stall */ +#define ANOMALY_05000166 /* PPI Data Lengths Between 8 and 16 do not zero out + upper bits */ +#define ANOMALY_05000167 /* Turning Serial Ports on With External Frame Syncs */ +#define ANOMALY_05000180 /* PPI_DELAY not functional in PPI modes with 0 frame + syncs */ +#define ANOMALY_05000182 /* IMDMA does not operate to full speed for 600MHz + and higher devices */ +#define ANOMALY_05000187 /* IMDMA Corrupted Data after a Halt */ +#define ANOMALY_05000190 /* PPI not functional at core voltage < 1Volt */ +#define ANOMALY_05000208 /* VSTAT status bit in PLL_STAT register is not + functional */ +#define ANOMALY_05000245 /* Spurious Hardware Error from an access in the + shadow of a conditional branch */ +#define ANOMALY_05000257 /* Interrupt/Exception during short hardware loop + may cause bad instruction fetches */ +#define ANOMALY_05000265 /* Sensitivity to noise with slow input edge rates on + external SPORT TX and RX clocks */ +#define ANOMALY_05000267 /* IMDMA may corrupt data under certain conditions */ +#define ANOMALY_05000269 /* High I/O activity causes output voltage of internal + voltage regulator (VDDint) to increase */ +#define ANOMALY_05000270 /* High I/O activity causes output voltage of internal + voltage regulator (VDDint) to decrease */ +#define ANOMALY_05000272 /* Certain data cache write through modes fail for + VDDint <=0.9V */ +#define ANOMALY_05000274 /* Data cache write back to external synchronous memory + may be lost */ +#define ANOMALY_05000275 /* PPI Timing and sampling informaton updates */ +#define ANOMALY_05000312 /* Errors when SSYNC, CSYNC, or loads to LT, LB and LC + registers are interrupted */ + +#endif /* (defined(CONFIG_BF_REV_0_5) || defined(CONFIG_BF_REV_0_3)) */ + +#if (defined(CONFIG_BF_REV_0_5)) +#define ANOMALY_05000254 /* Incorrect Timer Pulse Width in Single-Shot PWM_OUT + mode with external clock */ +#define ANOMALY_05000266 /* IMDMA destination IRQ status must be read prior to + using IMDMA */ +#endif + +#if (defined(CONFIG_BF_REV_0_3)) +#define ANOMALY_05000156 /* Timers in PWM-Out Mode with PPI GP Receive (Input) + Mode with 0 Frame Syncs */ +#define ANOMALY_05000168 /* SDRAM auto-refresh and subsequent Power Ups */ +#define ANOMALY_05000169 /* DATA CPLB page miss can result in lost write-through + cache data writes */ +#define ANOMALY_05000171 /* Boot-ROM code modifies SICA_IWRx wakeup registers */ +#define ANOMALY_05000174 /* Cache Fill Buffer Data lost */ +#define ANOMALY_05000175 /* Overlapping Sequencer and Memory Stalls */ +#define ANOMALY_05000176 /* Multiplication of (-1) by (-1) followed by an + accumulator saturation */ +#define ANOMALY_05000179 /* PPI_COUNT cannot be programmed to 0 in General + Purpose TX or RX modes */ +#define ANOMALY_05000181 /* Disabling the PPI resets the PPI configuration + registers */ +#define ANOMALY_05000184 /* Timer Pin limitations for PPI TX Modes with + External Frame Syncs */ +#define ANOMALY_05000185 /* PPI TX Mode with 2 External Frame Syncs */ +#define ANOMALY_05000186 /* PPI packing with Data Length greater than 8 bits + (not a meaningful mode) */ +#define ANOMALY_05000188 /* IMDMA Restrictions on Descriptor and Buffer + Placement in Memory */ +#define ANOMALY_05000189 /* False Protection Exception */ +#define ANOMALY_05000193 /* False Flag Pin Interrupts on Edge Sensitive Inputs + when polarity setting is changed */ +#define ANOMALY_05000194 /* Restarting SPORT in specific modes may cause data + corruption */ +#define ANOMALY_05000198 /* Failing MMR accesses when stalled by preceding + memory read */ +#define ANOMALY_05000199 /* DMA current address shows wrong value during carry + fix */ +#define ANOMALY_05000200 /* SPORT TFS and DT are incorrectly driven during + inactive channels in certain conditions */ +#define ANOMALY_05000202 /* Possible infinite stall with specific dual-DAG + situation */ +#define ANOMALY_05000204 /* Incorrect data read with write-through cache and + allocate cache lines on reads only mode */ +#define ANOMALY_05000205 /* Specific sequence that can cause DMA error or DMA + stopping */ +#define ANOMALY_05000207 /* Recovery from "brown-out" condition */ +#define ANOMALY_05000209 /* Speed-Path in computational unit affects certain + instructions */ +#define ANOMALY_05000215 /* UART TX Interrupt masked erroneously */ +#define ANOMALY_05000219 /* NMI event at boot time results in unpredictable + state */ +#define ANOMALY_05000220 /* Data Corruption with Cached External Memory and + Non-Cached On-Chip L2 Memory */ +#define ANOMALY_05000225 /* Incorrect pulse-width of UART start-bit */ +#define ANOMALY_05000227 /* Scratchpad memory bank reads may return incorrect + data */ +#define ANOMALY_05000230 /* UART Receiver is less robust against Baudrate + Differences in certain Conditions */ +#define ANOMALY_05000231 /* UART STB bit incorrectly affects receiver setting */ +#define ANOMALY_05000232 /* SPORT data transmit lines are incorrectly driven in + multichannel mode */ +#define ANOMALY_05000242 /* DF bit in PLL_CTL register does not respond to + hardware reset */ +#define ANOMALY_05000244 /* If i-cache is on, CSYNC/SSYNC/IDLE around Change of + Control causes failures */ +#define ANOMALY_05000248 /* TESTSET operation forces stall on the other core */ +#define ANOMALY_05000250 /* Incorrect Bit-Shift of Data Word in Multichannel + (TDM) mode in certain conditions */ +#define ANOMALY_05000251 /* Exception not generated for MMR accesses in + reserved region */ +#define ANOMALY_05000253 /* Maximum external clock speed for Timers */ +#define ANOMALY_05000258 /* Instruction Cache is corrupted when bits 9 and 12 + of the ICPLB Data registers differ */ +#define ANOMALY_05000260 /* ICPLB_STATUS MMR register may be corrupted */ +#define ANOMALY_05000261 /* DCPLB_FAULT_ADDR MMR register may be corrupted */ +#define ANOMALY_05000262 /* Stores to data cache may be lost */ +#define ANOMALY_05000263 /* Hardware loop corrupted when taking an ICPLB + exception */ +#define ANOMALY_05000264 /* CSYNC/SSYNC/IDLE causes infinite stall in second + to last instruction in hardware loop */ +#define ANOMALY_05000276 /* Timing requirements change for External Frame + Sync PPI Modes with non-zero PPI_DELAY */ +#define ANOMALY_05000278 /* Disabling Peripherals with DMA running may cause + DMA system instability */ +#define ANOMALY_05000281 /* False Hardware Error Exception when ISR context is + not restored */ +#define ANOMALY_05000283 /* An MMR write is stalled indefinitely when killed + in a particular stage */ +#define ANOMALY_05000287 /* A read will receive incorrect data under certain + conditions */ +#define ANOMALY_05000288 /* SPORTs may receive bad data if FIFOs fill up */ +#endif + +#endif /* _MACH_ANOMALY_H_ */ diff --git a/include/asm-blackfin/mach-bf561/bf561.h b/include/asm-blackfin/mach-bf561/bf561.h new file mode 100644 index 000000000000..96a5d3a47e45 --- /dev/null +++ b/include/asm-blackfin/mach-bf561/bf561.h @@ -0,0 +1,408 @@ +/* + * File: include/asm-blackfin/mach-bf561/bf561.h + * Based on: + * Author: + * + * Created: + * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561 + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __MACH_BF561_H__ +#define __MACH_BF561_H__ + +#define SUPPORTED_REVID 0x3 + +#define OFFSET_(x) ((x) & 0x0000FFFF) +#define L1_ISRAM 0xFFA00000 +#define L1_ISRAM_END 0xFFA04000 +#define DATA_BANKA_SRAM 0xFF800000 +#define DATA_BANKA_SRAM_END 0xFF804000 +#define DATA_BANKB_SRAM 0xFF900000 +#define DATA_BANKB_SRAM_END 0xFF904000 +#define L1_DSRAMA 0xFF800000 +#define L1_DSRAMA_END 0xFF804000 +#define L1_DSRAMB 0xFF900000 +#define L1_DSRAMB_END 0xFF904000 +#define L2_SRAM 0xFEB00000 +#define L2_SRAM_END 0xFEB20000 +#define AMB_FLASH 0x20000000 +#define AMB_FLASH_END 0x21000000 +#define AMB_FLASH_LENGTH 0x01000000 +#define L1_ISRAM_LENGTH 0x4000 +#define L1_DSRAMA_LENGTH 0x4000 +#define L1_DSRAMB_LENGTH 0x4000 +#define L2_SRAM_LENGTH 0x20000 + +/*some misc defines*/ +#define IMASK_IVG15 0x8000 +#define IMASK_IVG14 0x4000 +#define IMASK_IVG13 0x2000 +#define IMASK_IVG12 0x1000 + +#define IMASK_IVG11 0x0800 +#define IMASK_IVG10 0x0400 +#define IMASK_IVG9 0x0200 +#define IMASK_IVG8 0x0100 + +#define IMASK_IVG7 0x0080 +#define IMASK_IVGTMR 0x0040 +#define IMASK_IVGHW 0x0020 + +/*************************** + * Blackfin Cache setup + */ + + +#define BLKFIN_ISUBBANKS 4 +#define BLKFIN_IWAYS 4 +#define BLKFIN_ILINES 32 + +#define BLKFIN_DSUBBANKS 4 +#define BLKFIN_DWAYS 2 +#define BLKFIN_DLINES 64 + +#define WAY0_L 0x1 +#define WAY1_L 0x2 +#define WAY01_L 0x3 +#define WAY2_L 0x4 +#define WAY02_L 0x5 +#define WAY12_L 0x6 +#define WAY012_L 0x7 + +#define WAY3_L 0x8 +#define WAY03_L 0x9 +#define WAY13_L 0xA +#define WAY013_L 0xB + +#define WAY32_L 0xC +#define WAY320_L 0xD +#define WAY321_L 0xE +#define WAYALL_L 0xF + +#define DMC_ENABLE (2<<2) /*yes, 2, not 1 */ + +/* IAR0 BIT FIELDS */ +#define PLL_WAKEUP_BIT 0xFFFFFFFF +#define DMA1_ERROR_BIT 0xFFFFFF0F +#define DMA2_ERROR_BIT 0xFFFFF0FF +#define IMDMA_ERROR_BIT 0xFFFF0FFF +#define PPI1_ERROR_BIT 0xFFF0FFFF +#define PPI2_ERROR_BIT 0xFF0FFFFF +#define SPORT0_ERROR_BIT 0xF0FFFFFF +#define SPORT1_ERROR_BIT 0x0FFFFFFF +/* IAR1 BIT FIELDS */ +#define SPI_ERROR_BIT 0xFFFFFFFF +#define UART_ERROR_BIT 0xFFFFFF0F +#define RESERVED_ERROR_BIT 0xFFFFF0FF +#define DMA1_0_BIT 0xFFFF0FFF +#define DMA1_1_BIT 0xFFF0FFFF +#define DMA1_2_BIT 0xFF0FFFFF +#define DMA1_3_BIT 0xF0FFFFFF +#define DMA1_4_BIT 0x0FFFFFFF +/* IAR2 BIT FIELDS */ +#define DMA1_5_BIT 0xFFFFFFFF +#define DMA1_6_BIT 0xFFFFFF0F +#define DMA1_7_BIT 0xFFFFF0FF +#define DMA1_8_BIT 0xFFFF0FFF +#define DMA1_9_BIT 0xFFF0FFFF +#define DMA1_10_BIT 0xFF0FFFFF +#define DMA1_11_BIT 0xF0FFFFFF +#define DMA2_0_BIT 0x0FFFFFFF +/* IAR3 BIT FIELDS */ +#define DMA2_1_BIT 0xFFFFFFFF +#define DMA2_2_BIT 0xFFFFFF0F +#define DMA2_3_BIT 0xFFFFF0FF +#define DMA2_4_BIT 0xFFFF0FFF +#define DMA2_5_BIT 0xFFF0FFFF +#define DMA2_6_BIT 0xFF0FFFFF +#define DMA2_7_BIT 0xF0FFFFFF +#define DMA2_8_BIT 0x0FFFFFFF +/* IAR4 BIT FIELDS */ +#define DMA2_9_BIT 0xFFFFFFFF +#define DMA2_10_BIT 0xFFFFFF0F +#define DMA2_11_BIT 0xFFFFF0FF +#define TIMER0_BIT 0xFFFF0FFF +#define TIMER1_BIT 0xFFF0FFFF +#define TIMER2_BIT 0xFF0FFFFF +#define TIMER3_BIT 0xF0FFFFFF +#define TIMER4_BIT 0x0FFFFFFF +/* IAR5 BIT FIELDS */ +#define TIMER5_BIT 0xFFFFFFFF +#define TIMER6_BIT 0xFFFFFF0F +#define TIMER7_BIT 0xFFFFF0FF +#define TIMER8_BIT 0xFFFF0FFF +#define TIMER9_BIT 0xFFF0FFFF +#define TIMER10_BIT 0xFF0FFFFF +#define TIMER11_BIT 0xF0FFFFFF +#define PROG0_INTA_BIT 0x0FFFFFFF +/* IAR6 BIT FIELDS */ +#define PROG0_INTB_BIT 0xFFFFFFFF +#define PROG1_INTA_BIT 0xFFFFFF0F +#define PROG1_INTB_BIT 0xFFFFF0FF +#define PROG2_INTA_BIT 0xFFFF0FFF +#define PROG2_INTB_BIT 0xFFF0FFFF +#define DMA1_WRRD0_BIT 0xFF0FFFFF +#define DMA1_WRRD1_BIT 0xF0FFFFFF +#define DMA2_WRRD0_BIT 0x0FFFFFFF +/* IAR7 BIT FIELDS */ +#define DMA2_WRRD1_BIT 0xFFFFFFFF +#define IMDMA_WRRD0_BIT 0xFFFFFF0F +#define IMDMA_WRRD1_BIT 0xFFFFF0FF +#define WATCH_BIT 0xFFFF0FFF +#define RESERVED_1_BIT 0xFFF0FFFF +#define RESERVED_2_BIT 0xFF0FFFFF +#define SUPPLE_0_BIT 0xF0FFFFFF +#define SUPPLE_1_BIT 0x0FFFFFFF + +/* Miscellaneous Values */ + +/****************************** EBIU Settings ********************************/ +#define AMBCTL0VAL ((CONFIG_BANK_1 << 16) | CONFIG_BANK_0) +#define AMBCTL1VAL ((CONFIG_BANK_3 << 16) | CONFIG_BANK_2) + +#if defined(CONFIG_C_AMBEN_ALL) +#define V_AMBEN AMBEN_ALL +#elif defined(CONFIG_C_AMBEN) +#define V_AMBEN 0x0 +#elif defined(CONFIG_C_AMBEN_B0) +#define V_AMBEN AMBEN_B0 +#elif defined(CONFIG_C_AMBEN_B0_B1) +#define V_AMBEN AMBEN_B0_B1 +#elif defined(CONFIG_C_AMBEN_B0_B1_B2) +#define V_AMBEN AMBEN_B0_B1_B2 +#endif + +#ifdef CONFIG_C_AMCKEN +#define V_AMCKEN AMCKEN +#else +#define V_AMCKEN 0x0 +#endif + +#ifdef CONFIG_C_B0PEN +#define V_B0PEN 0x10 +#else +#define V_B0PEN 0x00 +#endif + +#ifdef CONFIG_C_B1PEN +#define V_B1PEN 0x20 +#else +#define V_B1PEN 0x00 +#endif + +#ifdef CONFIG_C_B2PEN +#define V_B2PEN 0x40 +#else +#define V_B2PEN 0x00 +#endif + +#ifdef CONFIG_C_B3PEN +#define V_B3PEN 0x80 +#else +#define V_B3PEN 0x00 +#endif + +#ifdef CONFIG_C_CDPRIO +#define V_CDPRIO 0x100 +#else +#define V_CDPRIO 0x0 +#endif + +#define AMGCTLVAL (V_AMBEN | V_AMCKEN | V_CDPRIO | V_B0PEN | V_B1PEN | V_B2PEN | V_B3PEN | 0x0002) + +#define MAX_VC 600000000 +#define MIN_VC 50000000 + +/******************************* PLL Settings ********************************/ +#ifdef CONFIG_BFIN_KERNEL_CLOCK +#if (CONFIG_VCO_MULT < 0) +#error "VCO Multiplier is less than 0. Please select a different value" +#endif + +#if (CONFIG_VCO_MULT == 0) +#error "VCO Multiplier should be greater than 0. Please select a different value" +#endif + +#ifndef CONFIG_CLKIN_HALF +#define CONFIG_VCO_HZ (CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) +#else +#define CONFIG_VCO_HZ ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)/2) +#endif + +#ifndef CONFIG_PLL_BYPASS +#define CONFIG_CCLK_HZ (CONFIG_VCO_HZ/CONFIG_CCLK_DIV) +#define CONFIG_SCLK_HZ (CONFIG_VCO_HZ/CONFIG_SCLK_DIV) +#else +#define CONFIG_CCLK_HZ CONFIG_CLKIN_HZ +#define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ +#endif + +#if (CONFIG_SCLK_DIV < 1) +#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value" +#endif + +#if (CONFIG_SCLK_DIV > 15) +#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value" +#endif + +#if (CONFIG_CCLK_DIV != 1) +#if (CONFIG_CCLK_DIV != 2) +#if (CONFIG_CCLK_DIV != 4) +#if (CONFIG_CCLK_DIV != 8) +#error "CCLK DIV can be 1,2,4 or 8 only. Please select a proper value" +#endif +#endif +#endif +#endif + +#if (CONFIG_VCO_HZ > MAX_VC) +#error "VCO selected is more than maximum value. Please change the VCO multipler" +#endif + +#if (CONFIG_SCLK_HZ > 133000000) +#error "Sclk value selected is more than maximum. Please select a proper value for SCLK multiplier" +#endif + +#if (CONFIG_SCLK_HZ < 27000000) +#error "Sclk value selected is less than minimum. Please select a proper value for SCLK multiplier" +#endif + +#if (CONFIG_SCLK_HZ >= CONFIG_CCLK_HZ) +#if (CONFIG_SCLK_HZ != CONFIG_CLKIN_HZ) +#if (CONFIG_CCLK_HZ != CONFIG_CLKIN_HZ) +#error "Please select sclk less than cclk" +#endif +#endif +#endif + +#if (CONFIG_CCLK_DIV == 1) +#define CONFIG_CCLK_ACT_DIV CCLK_DIV1 +#endif +#if (CONFIG_CCLK_DIV == 2) +#define CONFIG_CCLK_ACT_DIV CCLK_DIV2 +#endif +#if (CONFIG_CCLK_DIV == 4) +#define CONFIG_CCLK_ACT_DIV CCLK_DIV4 +#endif +#if (CONFIG_CCLK_DIV == 8) +#define CONFIG_CCLK_ACT_DIV CCLK_DIV8 +#endif +#ifndef CONFIG_CCLK_ACT_DIV +#define CONFIG_CCLK_ACT_DIV CONFIG_CCLK_DIV_not_defined_properly +#endif + +#if defined(ANOMALY_05000273) && (CONFIG_CCLK_DIV == 1) +#error ANOMALY 05000273, please make sure CCLK is at least 2x SCLK +#endif + +#endif /* CONFIG_BFIN_KERNEL_CLOCK */ + +#ifdef CONFIG_BF561 +#define CPU "BF561" +#define CPUID 0x027bb000 +#endif +#ifndef CPU +#define CPU "UNKNOWN" +#define CPUID 0x0 +#endif + +#if (CONFIG_MEM_SIZE % 4) +#error "SDRAM memory size must be a multiple of 4MB!" +#endif +#define SDRAM_IGENERIC (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO) +#define SDRAM_IKERNEL (SDRAM_IGENERIC | CPLB_LOCK) +#define L1_IMEMORY ( CPLB_USER_RD | CPLB_VALID | CPLB_LOCK) +#define SDRAM_INON_CHBL ( CPLB_USER_RD | CPLB_VALID) + +/*Use the menuconfig cache policy here - CONFIG_BLKFIN_WT/CONFIG_BLKFIN_WB*/ + +#define ANOMALY_05000158_WORKAROUND 0x200 +#ifdef CONFIG_BLKFIN_WB /*Write Back Policy */ +#define SDRAM_DGENERIC (CPLB_L1_CHBL | CPLB_DIRTY \ + | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND) +#else /*Write Through */ +#define SDRAM_DGENERIC (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_DIRTY \ + | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND) +#endif + + +#define L1_DMEMORY (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY) +#define SDRAM_DNON_CHBL (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY) +#define SDRAM_EBIU (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY) +#define SDRAM_OOPS (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY) + +#define L2_MEMORY (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY) + +#define SIZE_1K 0x00000400 /* 1K */ +#define SIZE_4K 0x00001000 /* 4K */ +#define SIZE_1M 0x00100000 /* 1M */ +#define SIZE_4M 0x00400000 /* 4M */ + +#define MAX_CPLBS (16 * 2) + +/* +* Number of required data CPLB switchtable entries +* MEMSIZE / 4 (we mostly install 4M page size CPLBs +* approx 16 for smaller 1MB page size CPLBs for allignment purposes +* 1 for L1 Data Memory +* 1 for L2 Data Memory +* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO +* 64 for ASYNC Memory +*/ + + +#define MAX_SWITCH_D_CPLBS (((CONFIG_MEM_SIZE / 4) + 16 + 1 + 1 + 1 + 64) * 2) + +/* +* Number of required instruction CPLB switchtable entries +* MEMSIZE / 4 (we mostly install 4M page size CPLBs +* approx 12 for smaller 1MB page size CPLBs for allignment purposes +* 1 for L1 Instruction Memory +* 1 for L2 Instruction Memory +* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO +*/ + +#define MAX_SWITCH_I_CPLBS (((CONFIG_MEM_SIZE / 4) + 12 + 1 + 1 + 1) * 2) + +#if 0 /* comment by mhfan */ +/* Event Vector Table Address */ +#define EVT_EMULATION_ADDR 0xffe02000 +#define EVT_RESET_ADDR 0xffe02004 +#define EVT_NMI_ADDR 0xffe02008 +#define EVT_EXCEPTION_ADDR 0xffe0200c +#define EVT_GLOBAL_INT_ENB_ADDR 0xffe02010 +#define EVT_HARDWARE_ERROR_ADDR 0xffe02014 +#define EVT_TIMER_ADDR 0xffe02018 +#define EVT_IVG7_ADDR 0xffe0201c +#define EVT_IVG8_ADDR 0xffe02020 +#define EVT_IVG9_ADDR 0xffe02024 +#define EVT_IVG10_ADDR 0xffe02028 +#define EVT_IVG11_ADDR 0xffe0202c +#define EVT_IVG12_ADDR 0xffe02030 +#define EVT_IVG13_ADDR 0xffe02034 +#define EVT_IVG14_ADDR 0xffe02038 +#define EVT_IVG15_ADDR 0xffe0203c +#define EVT_OVERRIDE_ADDR 0xffe02100 +#endif /* comment by mhfan */ + +#endif /* __MACH_BF561_H__ */ diff --git a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h new file mode 100644 index 000000000000..23bf76aa3451 --- /dev/null +++ b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h @@ -0,0 +1,108 @@ +#include +#include + +#define NR_PORTS 1 + +#define OFFSET_THR 0x00 /* Transmit Holding register */ +#define OFFSET_RBR 0x00 /* Receive Buffer register */ +#define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */ +#define OFFSET_IER 0x04 /* Interrupt Enable Register */ +#define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */ +#define OFFSET_IIR 0x08 /* Interrupt Identification Register */ +#define OFFSET_LCR 0x0C /* Line Control Register */ +#define OFFSET_MCR 0x10 /* Modem Control Register */ +#define OFFSET_LSR 0x14 /* Line Status Register */ +#define OFFSET_MSR 0x18 /* Modem Status Register */ +#define OFFSET_SCR 0x1C /* SCR Scratch Register */ +#define OFFSET_GCTL 0x24 /* Global Control Register */ + +#define UART_GET_CHAR(uart) bfin_read16(((uart)->port.membase + OFFSET_RBR)) +#define UART_GET_DLL(uart) bfin_read16(((uart)->port.membase + OFFSET_DLL)) +#define UART_GET_IER(uart) bfin_read16(((uart)->port.membase + OFFSET_IER)) +#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH)) +#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR)) +#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) +#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) +#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) + +#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) +#define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v) +#define UART_PUT_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER),v) +#define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v) +#define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v) +#define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v) + +#ifdef CONFIG_BFIN_UART0_CTSRTS +# define CONFIG_SERIAL_BFIN_CTSRTS +# ifndef CONFIG_UART0_CTS_PIN +# define CONFIG_UART0_CTS_PIN -1 +# endif +# ifndef CONFIG_UART0_RTS_PIN +# define CONFIG_UART0_RTS_PIN -1 +# endif +#endif + +struct bfin_serial_port { + struct uart_port port; + unsigned int old_status; +#ifdef CONFIG_SERIAL_BFIN_DMA + int tx_done; + int tx_count; + struct circ_buf rx_dma_buf; + struct timer_list rx_dma_timer; + int rx_dma_nrows; + unsigned int tx_dma_channel; + unsigned int rx_dma_channel; + struct work_struct tx_dma_workqueue; +#else + struct work_struct cts_workqueue; +#endif +#ifdef CONFIG_SERIAL_BFIN_CTSRTS + int cts_pin; + int rts_pin; +#endif +}; + +struct bfin_serial_port bfin_serial_ports[NR_PORTS]; +struct bfin_serial_res { + unsigned long uart_base_addr; + int uart_irq; +#ifdef CONFIG_SERIAL_BFIN_DMA + unsigned int uart_tx_dma_channel; + unsigned int uart_rx_dma_channel; +#endif +#ifdef CONFIG_SERIAL_BFIN_CTSRTS + int uart_cts_pin; + int uart_rts_pin; +#endif +}; + +struct bfin_serial_res bfin_serial_resource[] = { + 0xFFC00400, + IRQ_UART_RX, +#ifdef CONFIG_SERIAL_BFIN_DMA + CH_UART_TX, + CH_UART_RX, +#endif +#ifdef CONFIG_BFIN_UART0_CTSRTS + CONFIG_UART0_CTS_PIN, + CONFIG_UART0_RTS_PIN, +#endif +}; + + +int nr_ports = NR_PORTS; +static void bfin_serial_hw_init(struct bfin_serial_port *uart) +{ + +#ifdef CONFIG_SERIAL_BFIN_CTSRTS + if (uart->cts_pin >= 0) { + gpio_request(uart->cts_pin, NULL); + gpio_direction_input(uart->cts_pin); + } + if (uart->rts_pin >= 0) { + gpio_request(uart->rts_pin, NULL); + gpio_direction_input(uart->rts_pin); + } +#endif +} diff --git a/include/asm-blackfin/mach-bf561/blackfin.h b/include/asm-blackfin/mach-bf561/blackfin.h new file mode 100644 index 000000000000..2537c845e8b0 --- /dev/null +++ b/include/asm-blackfin/mach-bf561/blackfin.h @@ -0,0 +1,52 @@ +/* + * File: include/asm-blackfin/mach-bf561/blackfin.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Rev: + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _MACH_BLACKFIN_H_ +#define _MACH_BLACKFIN_H_ + +#define BF561_FAMILY + +#include "bf561.h" +#include "mem_map.h" +#include "defBF561.h" +#include "anomaly.h" + +#if !(defined(__ASSEMBLY__) || defined(ASSEMBLY)) +#include "cdefBF561.h" +#endif + +#define bfin_read_FIO_FLAG_D() bfin_read_FIO0_FLAG_D() +#define bfin_write_FIO_FLAG_D(val) bfin_write_FIO0_FLAG_D(val) +#define bfin_read_FIO_DIR() bfin_read_FIO0_DIR() +#define bfin_write_FIO_DIR(val) bfin_write_FIO0_DIR(val) +#define bfin_read_FIO_INEN() bfin_read_FIO0_INEN() +#define bfin_write_FIO_INEN(val) bfin_write_FIO0_INEN(val) + +#endif /* _MACH_BLACKFIN_H_ */ diff --git a/include/asm-blackfin/mach-bf561/cdefBF561.h b/include/asm-blackfin/mach-bf561/cdefBF561.h new file mode 100644 index 000000000000..5dc0ed835447 --- /dev/null +++ b/include/asm-blackfin/mach-bf561/cdefBF561.h @@ -0,0 +1,1543 @@ +/* + * File: include/asm-blackfin/mach-bf561/cdefBF561.h + * Based on: + * Author: + * + * Created: + * Description: C POINTERS TO SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561 + * + * Rev: + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _CDEF_BF561_H +#define _CDEF_BF561_H + +/* +#if !defined(__ADSPBF561__) +#warning cdefBF561.h should only be included for BF561 chip. +#endif +*/ +/* include all Core registers and bit definitions */ +#include "defBF561.h" + +/*include core specific register pointer definitions*/ +#include + +#include + +/*********************************************************************************** */ +/* System MMR Register Map */ +/*********************************************************************************** */ + +/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */ +#define bfin_read_PLL_CTL() bfin_read16(PLL_CTL) +#define bfin_write_PLL_CTL(val) bfin_write16(PLL_CTL,val) +#define bfin_read_PLL_DIV() bfin_read16(PLL_DIV) +#define bfin_write_PLL_DIV(val) bfin_write16(PLL_DIV,val) +#define bfin_read_VR_CTL() bfin_read16(VR_CTL) +/* Writing to VR_CTL initiates a PLL relock sequence. */ +static __inline__ void bfin_write_VR_CTL(unsigned int val) +{ + unsigned long flags, iwr; + + bfin_write16(VR_CTL, val); + __builtin_bfin_ssync(); + /* Enable the PLL Wakeup bit in SIC IWR */ + iwr = bfin_read32(SICA_IWR0); + /* Only allow PPL Wakeup) */ + bfin_write32(SICA_IWR0, IWR_ENABLE(0)); + local_irq_save(flags); + asm("IDLE;"); + local_irq_restore(flags); + bfin_write32(SICA_IWR0, iwr); +} +#define bfin_read_PLL_STAT() bfin_read16(PLL_STAT) +#define bfin_write_PLL_STAT(val) bfin_write16(PLL_STAT,val) +#define bfin_read_PLL_LOCKCNT() bfin_read16(PLL_LOCKCNT) +#define bfin_write_PLL_LOCKCNT(val) bfin_write16(PLL_LOCKCNT,val) +#define bfin_read_CHIPID() bfin_read32(CHIPID) + +/* System Reset and Interrupt Controller registers for core A (0xFFC0 0100-0xFFC0 01FF) */ +#define bfin_read_SICA_SWRST() bfin_read16(SICA_SWRST) +#define bfin_write_SICA_SWRST(val) bfin_write16(SICA_SWRST,val) +#define bfin_read_SICA_SYSCR() bfin_read16(SICA_SYSCR) +#define bfin_write_SICA_SYSCR(val) bfin_write16(SICA_SYSCR,val) +#define bfin_read_SICA_RVECT() bfin_read16(SICA_RVECT) +#define bfin_write_SICA_RVECT(val) bfin_write16(SICA_RVECT,val) +#define bfin_read_SICA_IMASK() bfin_read32(SICA_IMASK) +#define bfin_write_SICA_IMASK(val) bfin_write32(SICA_IMASK,val) +#define bfin_read_SICA_IMASK0() bfin_read32(SICA_IMASK0) +#define bfin_write_SICA_IMASK0(val) bfin_write32(SICA_IMASK0,val) +#define bfin_read_SICA_IMASK1() bfin_read32(SICA_IMASK1) +#define bfin_write_SICA_IMASK1(val) bfin_write32(SICA_IMASK1,val) +#define bfin_read_SICA_IAR0() bfin_read32(SICA_IAR0) +#define bfin_write_SICA_IAR0(val) bfin_write32(SICA_IAR0,val) +#define bfin_read_SICA_IAR1() bfin_read32(SICA_IAR1) +#define bfin_write_SICA_IAR1(val) bfin_write32(SICA_IAR1,val) +#define bfin_read_SICA_IAR2() bfin_read32(SICA_IAR2) +#define bfin_write_SICA_IAR2(val) bfin_write32(SICA_IAR2,val) +#define bfin_read_SICA_IAR3() bfin_read32(SICA_IAR3) +#define bfin_write_SICA_IAR3(val) bfin_write32(SICA_IAR3,val) +#define bfin_read_SICA_IAR4() bfin_read32(SICA_IAR4) +#define bfin_write_SICA_IAR4(val) bfin_write32(SICA_IAR4,val) +#define bfin_read_SICA_IAR5() bfin_read32(SICA_IAR5) +#define bfin_write_SICA_IAR5(val) bfin_write32(SICA_IAR5,val) +#define bfin_read_SICA_IAR6() bfin_read32(SICA_IAR6) +#define bfin_write_SICA_IAR6(val) bfin_write32(SICA_IAR6,val) +#define bfin_read_SICA_IAR7() bfin_read32(SICA_IAR7) +#define bfin_write_SICA_IAR7(val) bfin_write32(SICA_IAR7,val) +#define bfin_read_SICA_ISR0() bfin_read32(SICA_ISR0) +#define bfin_write_SICA_ISR0(val) bfin_write32(SICA_ISR0,val) +#define bfin_read_SICA_ISR1() bfin_read32(SICA_ISR1) +#define bfin_write_SICA_ISR1(val) bfin_write32(SICA_ISR1,val) +#define bfin_read_SICA_IWR0() bfin_read32(SICA_IWR0) +#define bfin_write_SICA_IWR0(val) bfin_write32(SICA_IWR0,val) +#define bfin_read_SICA_IWR1() bfin_read32(SICA_IWR1) +#define bfin_write_SICA_IWR1(val) bfin_write32(SICA_IWR1,val) + +/* System Reset and Interrupt Controller registers for Core B (0xFFC0 1100-0xFFC0 11FF) */ +#define bfin_read_SICB_SWRST() bfin_read16(SICB_SWRST) +#define bfin_write_SICB_SWRST(val) bfin_write16(SICB_SWRST,val) +#define bfin_read_SICB_SYSCR() bfin_read16(SICB_SYSCR) +#define bfin_write_SICB_SYSCR(val) bfin_write16(SICB_SYSCR,val) +#define bfin_read_SICB_RVECT() bfin_read16(SICB_RVECT) +#define bfin_write_SICB_RVECT(val) bfin_write16(SICB_RVECT,val) +#define bfin_read_SICB_IMASK0() bfin_read32(SICB_IMASK0) +#define bfin_write_SICB_IMASK0(val) bfin_write32(SICB_IMASK0,val) +#define bfin_read_SICB_IMASK1() bfin_read32(SICB_IMASK1) +#define bfin_write_SICB_IMASK1(val) bfin_write32(SICB_IMASK1,val) +#define bfin_read_SICB_IAR0() bfin_read32(SICB_IAR0) +#define bfin_write_SICB_IAR0(val) bfin_write32(SICB_IAR0,val) +#define bfin_read_SICB_IAR1() bfin_read32(SICB_IAR1) +#define bfin_write_SICB_IAR1(val) bfin_write32(SICB_IAR1,val) +#define bfin_read_SICB_IAR2() bfin_read32(SICB_IAR2) +#define bfin_write_SICB_IAR2(val) bfin_write32(SICB_IAR2,val) +#define bfin_read_SICB_IAR3() bfin_read32(SICB_IAR3) +#define bfin_write_SICB_IAR3(val) bfin_write32(SICB_IAR3,val) +#define bfin_read_SICB_IAR4() bfin_read32(SICB_IAR4) +#define bfin_write_SICB_IAR4(val) bfin_write32(SICB_IAR4,val) +#define bfin_read_SICB_IAR5() bfin_read32(SICB_IAR5) +#define bfin_write_SICB_IAR5(val) bfin_write32(SICB_IAR5,val) +#define bfin_read_SICB_IAR6() bfin_read32(SICB_IAR6) +#define bfin_write_SICB_IAR6(val) bfin_write32(SICB_IAR6,val) +#define bfin_read_SICB_IAR7() bfin_read32(SICB_IAR7) +#define bfin_write_SICB_IAR7(val) bfin_write32(SICB_IAR7,val) +#define bfin_read_SICB_ISR0() bfin_read32(SICB_ISR0) +#define bfin_write_SICB_ISR0(val) bfin_write32(SICB_ISR0,val) +#define bfin_read_SICB_ISR1() bfin_read32(SICB_ISR1) +#define bfin_write_SICB_ISR1(val) bfin_write32(SICB_ISR1,val) +#define bfin_read_SICB_IWR0() bfin_read32(SICB_IWR0) +#define bfin_write_SICB_IWR0(val) bfin_write32(SICB_IWR0,val) +#define bfin_read_SICB_IWR1() bfin_read32(SICB_IWR1) +#define bfin_write_SICB_IWR1(val) bfin_write32(SICB_IWR1,val) +/* Watchdog Timer registers for Core A (0xFFC0 0200-0xFFC0 02FF) */ +#define bfin_read_WDOGA_CTL() bfin_read16(WDOGA_CTL) +#define bfin_write_WDOGA_CTL(val) bfin_write16(WDOGA_CTL,val) +#define bfin_read_WDOGA_CNT() bfin_read32(WDOGA_CNT) +#define bfin_write_WDOGA_CNT(val) bfin_write32(WDOGA_CNT,val) +#define bfin_read_WDOGA_STAT() bfin_read32(WDOGA_STAT) +#define bfin_write_WDOGA_STAT(val) bfin_write32(WDOGA_STAT,val) + +/* Watchdog Timer registers for Core B (0xFFC0 1200-0xFFC0 12FF) */ +#define bfin_read_WDOGB_CTL() bfin_read16(WDOGB_CTL) +#define bfin_write_WDOGB_CTL(val) bfin_write16(WDOGB_CTL,val) +#define bfin_read_WDOGB_CNT() bfin_read32(WDOGB_CNT) +#define bfin_write_WDOGB_CNT(val) bfin_write32(WDOGB_CNT,val) +#define bfin_read_WDOGB_STAT() bfin_read32(WDOGB_STAT) +#define bfin_write_WDOGB_STAT(val) bfin_write32(WDOGB_STAT,val) + +/* UART Controller (0xFFC00400 - 0xFFC004FF) */ +#define bfin_read_UART_THR() bfin_read16(UART_THR) +#define bfin_write_UART_THR(val) bfin_write16(UART_THR,val) +#define bfin_read_UART_RBR() bfin_read16(UART_RBR) +#define bfin_write_UART_RBR(val) bfin_write16(UART_RBR,val) +#define bfin_read_UART_DLL() bfin_read16(UART_DLL) +#define bfin_write_UART_DLL(val) bfin_write16(UART_DLL,val) +#define bfin_read_UART_IER() bfin_read16(UART_IER) +#define bfin_write_UART_IER(val) bfin_write16(UART_IER,val) +#define bfin_read_UART_DLH() bfin_read16(UART_DLH) +#define bfin_write_UART_DLH(val) bfin_write16(UART_DLH,val) +#define bfin_read_UART_IIR() bfin_read16(UART_IIR) +#define bfin_write_UART_IIR(val) bfin_write16(UART_IIR,val) +#define bfin_read_UART_LCR() bfin_read16(UART_LCR) +#define bfin_write_UART_LCR(val) bfin_write16(UART_LCR,val) +#define bfin_read_UART_MCR() bfin_read16(UART_MCR) +#define bfin_write_UART_MCR(val) bfin_write16(UART_MCR,val) +#define bfin_read_UART_LSR() bfin_read16(UART_LSR) +#define bfin_write_UART_LSR(val) bfin_write16(UART_LSR,val) +#define bfin_read_UART_MSR() bfin_read16(UART_MSR) +#define bfin_write_UART_MSR(val) bfin_write16(UART_MSR,val) +#define bfin_read_UART_SCR() bfin_read16(UART_SCR) +#define bfin_write_UART_SCR(val) bfin_write16(UART_SCR,val) +#define bfin_read_UART_GCTL() bfin_read16(UART_GCTL) +#define bfin_write_UART_GCTL(val) bfin_write16(UART_GCTL,val) + +/* SPI Controller (0xFFC00500 - 0xFFC005FF) */ +#define bfin_read_SPI_CTL() bfin_read16(SPI_CTL) +#define bfin_write_SPI_CTL(val) bfin_write16(SPI_CTL,val) +#define bfin_read_SPI_FLG() bfin_read16(SPI_FLG) +#define bfin_write_SPI_FLG(val) bfin_write16(SPI_FLG,val) +#define bfin_read_SPI_STAT() bfin_read16(SPI_STAT) +#define bfin_write_SPI_STAT(val) bfin_write16(SPI_STAT,val) +#define bfin_read_SPI_TDBR() bfin_read16(SPI_TDBR) +#define bfin_write_SPI_TDBR(val) bfin_write16(SPI_TDBR,val) +#define bfin_read_SPI_RDBR() bfin_read16(SPI_RDBR) +#define bfin_write_SPI_RDBR(val) bfin_write16(SPI_RDBR,val) +#define bfin_read_SPI_BAUD() bfin_read16(SPI_BAUD) +#define bfin_write_SPI_BAUD(val) bfin_write16(SPI_BAUD,val) +#define bfin_read_SPI_SHADOW() bfin_read16(SPI_SHADOW) +#define bfin_write_SPI_SHADOW(val) bfin_write16(SPI_SHADOW,val) + +/* Timer 0-7 registers (0xFFC0 0600-0xFFC0 06FF) */ +#define bfin_read_TIMER0_CONFIG() bfin_read16(TIMER0_CONFIG) +#define bfin_write_TIMER0_CONFIG(val) bfin_write16(TIMER0_CONFIG,val) +#define bfin_read_TIMER0_COUNTER() bfin_read32(TIMER0_COUNTER) +#define bfin_write_TIMER0_COUNTER(val) bfin_write32(TIMER0_COUNTER,val) +#define bfin_read_TIMER0_PERIOD() bfin_read32(TIMER0_PERIOD) +#define bfin_write_TIMER0_PERIOD(val) bfin_write32(TIMER0_PERIOD,val) +#define bfin_read_TIMER0_WIDTH() bfin_read32(TIMER0_WIDTH) +#define bfin_write_TIMER0_WIDTH(val) bfin_write32(TIMER0_WIDTH,val) +#define bfin_read_TIMER1_CONFIG() bfin_read16(TIMER1_CONFIG) +#define bfin_write_TIMER1_CONFIG(val) bfin_write16(TIMER1_CONFIG,val) +#define bfin_read_TIMER1_COUNTER() bfin_read32(TIMER1_COUNTER) +#define bfin_write_TIMER1_COUNTER(val) bfin_write32(TIMER1_COUNTER,val) +#define bfin_read_TIMER1_PERIOD() bfin_read32(TIMER1_PERIOD) +#define bfin_write_TIMER1_PERIOD(val) bfin_write32(TIMER1_PERIOD,val) +#define bfin_read_TIMER1_WIDTH() bfin_read32(TIMER1_WIDTH) +#define bfin_write_TIMER1_WIDTH(val) bfin_write32(TIMER1_WIDTH,val) +#define bfin_read_TIMER2_CONFIG() bfin_read16(TIMER2_CONFIG) +#define bfin_write_TIMER2_CONFIG(val) bfin_write16(TIMER2_CONFIG,val) +#define bfin_read_TIMER2_COUNTER() bfin_read32(TIMER2_COUNTER) +#define bfin_write_TIMER2_COUNTER(val) bfin_write32(TIMER2_COUNTER,val) +#define bfin_read_TIMER2_PERIOD() bfin_read32(TIMER2_PERIOD) +#define bfin_write_TIMER2_PERIOD(val) bfin_write32(TIMER2_PERIOD,val) +#define bfin_read_TIMER2_WIDTH() bfin_read32(TIMER2_WIDTH) +#define bfin_write_TIMER2_WIDTH(val) bfin_write32(TIMER2_WIDTH,val) +#define bfin_read_TIMER3_CONFIG() bfin_read16(TIMER3_CONFIG) +#define bfin_write_TIMER3_CONFIG(val) bfin_write16(TIMER3_CONFIG,val) +#define bfin_read_TIMER3_COUNTER() bfin_read32(TIMER3_COUNTER) +#define bfin_write_TIMER3_COUNTER(val) bfin_write32(TIMER3_COUNTER,val) +#define bfin_read_TIMER3_PERIOD() bfin_read32(TIMER3_PERIOD) +#define bfin_write_TIMER3_PERIOD(val) bfin_write32(TIMER3_PERIOD,val) +#define bfin_read_TIMER3_WIDTH() bfin_read32(TIMER3_WIDTH) +#define bfin_write_TIMER3_WIDTH(val) bfin_write32(TIMER3_WIDTH,val) +#define bfin_read_TIMER4_CONFIG() bfin_read16(TIMER4_CONFIG) +#define bfin_write_TIMER4_CONFIG(val) bfin_write16(TIMER4_CONFIG,val) +#define bfin_read_TIMER4_COUNTER() bfin_read32(TIMER4_COUNTER) +#define bfin_write_TIMER4_COUNTER(val) bfin_write32(TIMER4_COUNTER,val) +#define bfin_read_TIMER4_PERIOD() bfin_read32(TIMER4_PERIOD) +#define bfin_write_TIMER4_PERIOD(val) bfin_write32(TIMER4_PERIOD,val) +#define bfin_read_TIMER4_WIDTH() bfin_read32(TIMER4_WIDTH) +#define bfin_write_TIMER4_WIDTH(val) bfin_write32(TIMER4_WIDTH,val) +#define bfin_read_TIMER5_CONFIG() bfin_read16(TIMER5_CONFIG) +#define bfin_write_TIMER5_CONFIG(val) bfin_write16(TIMER5_CONFIG,val) +#define bfin_read_TIMER5_COUNTER() bfin_read32(TIMER5_COUNTER) +#define bfin_write_TIMER5_COUNTER(val) bfin_write32(TIMER5_COUNTER,val) +#define bfin_read_TIMER5_PERIOD() bfin_read32(TIMER5_PERIOD) +#define bfin_write_TIMER5_PERIOD(val) bfin_write32(TIMER5_PERIOD,val) +#define bfin_read_TIMER5_WIDTH() bfin_read32(TIMER5_WIDTH) +#define bfin_write_TIMER5_WIDTH(val) bfin_write32(TIMER5_WIDTH,val) +#define bfin_read_TIMER6_CONFIG() bfin_read16(TIMER6_CONFIG) +#define bfin_write_TIMER6_CONFIG(val) bfin_write16(TIMER6_CONFIG,val) +#define bfin_read_TIMER6_COUNTER() bfin_read32(TIMER6_COUNTER) +#define bfin_write_TIMER6_COUNTER(val) bfin_write32(TIMER6_COUNTER,val) +#define bfin_read_TIMER6_PERIOD() bfin_read32(TIMER6_PERIOD) +#define bfin_write_TIMER6_PERIOD(val) bfin_write32(TIMER6_PERIOD,val) +#define bfin_read_TIMER6_WIDTH() bfin_read32(TIMER6_WIDTH) +#define bfin_write_TIMER6_WIDTH(val) bfin_write32(TIMER6_WIDTH,val) +#define bfin_read_TIMER7_CONFIG() bfin_read16(TIMER7_CONFIG) +#define bfin_write_TIMER7_CONFIG(val) bfin_write16(TIMER7_CONFIG,val) +#define bfin_read_TIMER7_COUNTER() bfin_read32(TIMER7_COUNTER) +#define bfin_write_TIMER7_COUNTER(val) bfin_write32(TIMER7_COUNTER,val) +#define bfin_read_TIMER7_PERIOD() bfin_read32(TIMER7_PERIOD) +#define bfin_write_TIMER7_PERIOD(val) bfin_write32(TIMER7_PERIOD,val) +#define bfin_read_TIMER7_WIDTH() bfin_read32(TIMER7_WIDTH) +#define bfin_write_TIMER7_WIDTH(val) bfin_write32(TIMER7_WIDTH,val) + +/* Timer registers 8-11 (0xFFC0 1600-0xFFC0 16FF) */ +#define bfin_read_TMRS8_ENABLE() bfin_read16(TMRS8_ENABLE) +#define bfin_write_TMRS8_ENABLE(val) bfin_write16(TMRS8_ENABLE,val) +#define bfin_read_TMRS8_DISABLE() bfin_read16(TMRS8_DISABLE) +#define bfin_write_TMRS8_DISABLE(val) bfin_write16(TMRS8_DISABLE,val) +#define bfin_read_TMRS8_STATUS() bfin_read32(TMRS8_STATUS) +#define bfin_write_TMRS8_STATUS(val) bfin_write32(TMRS8_STATUS,val) +#define bfin_read_TIMER8_CONFIG() bfin_read16(TIMER8_CONFIG) +#define bfin_write_TIMER8_CONFIG(val) bfin_write16(TIMER8_CONFIG,val) +#define bfin_read_TIMER8_COUNTER() bfin_read32(TIMER8_COUNTER) +#define bfin_write_TIMER8_COUNTER(val) bfin_write32(TIMER8_COUNTER,val) +#define bfin_read_TIMER8_PERIOD() bfin_read32(TIMER8_PERIOD) +#define bfin_write_TIMER8_PERIOD(val) bfin_write32(TIMER8_PERIOD,val) +#define bfin_read_TIMER8_WIDTH() bfin_read32(TIMER8_WIDTH) +#define bfin_write_TIMER8_WIDTH(val) bfin_write32(TIMER8_WIDTH,val) +#define bfin_read_TIMER9_CONFIG() bfin_read16(TIMER9_CONFIG) +#define bfin_write_TIMER9_CONFIG(val) bfin_write16(TIMER9_CONFIG,val) +#define bfin_read_TIMER9_COUNTER() bfin_read32(TIMER9_COUNTER) +#define bfin_write_TIMER9_COUNTER(val) bfin_write32(TIMER9_COUNTER,val) +#define bfin_read_TIMER9_PERIOD() bfin_read32(TIMER9_PERIOD) +#define bfin_write_TIMER9_PERIOD(val) bfin_write32(TIMER9_PERIOD,val) +#define bfin_read_TIMER9_WIDTH() bfin_read32(TIMER9_WIDTH) +#define bfin_write_TIMER9_WIDTH(val) bfin_write32(TIMER9_WIDTH,val) +#define bfin_read_TIMER10_CONFIG() bfin_read16(TIMER10_CONFIG) +#define bfin_write_TIMER10_CONFIG(val) bfin_write16(TIMER10_CONFIG,val) +#define bfin_read_TIMER10_COUNTER() bfin_read32(TIMER10_COUNTER) +#define bfin_write_TIMER10_COUNTER(val) bfin_write32(TIMER10_COUNTER,val) +#define bfin_read_TIMER10_PERIOD() bfin_read32(TIMER10_PERIOD) +#define bfin_write_TIMER10_PERIOD(val) bfin_write32(TIMER10_PERIOD,val) +#define bfin_read_TIMER10_WIDTH() bfin_read32(TIMER10_WIDTH) +#define bfin_write_TIMER10_WIDTH(val) bfin_write32(TIMER10_WIDTH,val) +#define bfin_read_TIMER11_CONFIG() bfin_read16(TIMER11_CONFIG) +#define bfin_write_TIMER11_CONFIG(val) bfin_write16(TIMER11_CONFIG,val) +#define bfin_read_TIMER11_COUNTER() bfin_read32(TIMER11_COUNTER) +#define bfin_write_TIMER11_COUNTER(val) bfin_write32(TIMER11_COUNTER,val) +#define bfin_read_TIMER11_PERIOD() bfin_read32(TIMER11_PERIOD) +#define bfin_write_TIMER11_PERIOD(val) bfin_write32(TIMER11_PERIOD,val) +#define bfin_read_TIMER11_WIDTH() bfin_read32(TIMER11_WIDTH) +#define bfin_write_TIMER11_WIDTH(val) bfin_write32(TIMER11_WIDTH,val) +#define bfin_read_TMRS4_ENABLE() bfin_read16(TMRS4_ENABLE) +#define bfin_write_TMRS4_ENABLE(val) bfin_write16(TMRS4_ENABLE,val) +#define bfin_read_TMRS4_DISABLE() bfin_read16(TMRS4_DISABLE) +#define bfin_write_TMRS4_DISABLE(val) bfin_write16(TMRS4_DISABLE,val) +#define bfin_read_TMRS4_STATUS() bfin_read32(TMRS4_STATUS) +#define bfin_write_TMRS4_STATUS(val) bfin_write32(TMRS4_STATUS,val) + +/* Programmable Flag 0 registers (0xFFC0 0700-0xFFC0 07FF) */ +#define bfin_read_FIO0_FLAG_D() bfin_read16(FIO0_FLAG_D) +#define bfin_write_FIO0_FLAG_D(val) bfin_write16(FIO0_FLAG_D,val) +#define bfin_read_FIO0_FLAG_C() bfin_read16(FIO0_FLAG_C) +#define bfin_write_FIO0_FLAG_C(val) bfin_write16(FIO0_FLAG_C,val) +#define bfin_read_FIO0_FLAG_S() bfin_read16(FIO0_FLAG_S) +#define bfin_write_FIO0_FLAG_S(val) bfin_write16(FIO0_FLAG_S,val) +#define bfin_read_FIO0_FLAG_T() bfin_read16(FIO0_FLAG_T) +#define bfin_write_FIO0_FLAG_T(val) bfin_write16(FIO0_FLAG_T,val) +#define bfin_read_FIO0_MASKA_D() bfin_read16(FIO0_MASKA_D) +#define bfin_write_FIO0_MASKA_D(val) bfin_write16(FIO0_MASKA_D,val) +#define bfin_read_FIO0_MASKA_C() bfin_read16(FIO0_MASKA_C) +#define bfin_write_FIO0_MASKA_C(val) bfin_write16(FIO0_MASKA_C,val) +#define bfin_read_FIO0_MASKA_S() bfin_read16(FIO0_MASKA_S) +#define bfin_write_FIO0_MASKA_S(val) bfin_write16(FIO0_MASKA_S,val) +#define bfin_read_FIO0_MASKA_T() bfin_read16(FIO0_MASKA_T) +#define bfin_write_FIO0_MASKA_T(val) bfin_write16(FIO0_MASKA_T,val) +#define bfin_read_FIO0_MASKB_D() bfin_read16(FIO0_MASKB_D) +#define bfin_write_FIO0_MASKB_D(val) bfin_write16(FIO0_MASKB_D,val) +#define bfin_read_FIO0_MASKB_C() bfin_read16(FIO0_MASKB_C) +#define bfin_write_FIO0_MASKB_C(val) bfin_write16(FIO0_MASKB_C,val) +#define bfin_read_FIO0_MASKB_S() bfin_read16(FIO0_MASKB_S) +#define bfin_write_FIO0_MASKB_S(val) bfin_write16(FIO0_MASKB_S,val) +#define bfin_read_FIO0_MASKB_T() bfin_read16(FIO0_MASKB_T) +#define bfin_write_FIO0_MASKB_T(val) bfin_write16(FIO0_MASKB_T,val) +#define bfin_read_FIO0_DIR() bfin_read16(FIO0_DIR) +#define bfin_write_FIO0_DIR(val) bfin_write16(FIO0_DIR,val) +#define bfin_read_FIO0_POLAR() bfin_read16(FIO0_POLAR) +#define bfin_write_FIO0_POLAR(val) bfin_write16(FIO0_POLAR,val) +#define bfin_read_FIO0_EDGE() bfin_read16(FIO0_EDGE) +#define bfin_write_FIO0_EDGE(val) bfin_write16(FIO0_EDGE,val) +#define bfin_read_FIO0_BOTH() bfin_read16(FIO0_BOTH) +#define bfin_write_FIO0_BOTH(val) bfin_write16(FIO0_BOTH,val) +#define bfin_read_FIO0_INEN() bfin_read16(FIO0_INEN) +#define bfin_write_FIO0_INEN(val) bfin_write16(FIO0_INEN,val) +/* Programmable Flag 1 registers (0xFFC0 1500-0xFFC0 15FF) */ +#define bfin_read_FIO1_FLAG_D() bfin_read16(FIO1_FLAG_D) +#define bfin_write_FIO1_FLAG_D(val) bfin_write16(FIO1_FLAG_D,val) +#define bfin_read_FIO1_FLAG_C() bfin_read16(FIO1_FLAG_C) +#define bfin_write_FIO1_FLAG_C(val) bfin_write16(FIO1_FLAG_C,val) +#define bfin_read_FIO1_FLAG_S() bfin_read16(FIO1_FLAG_S) +#define bfin_write_FIO1_FLAG_S(val) bfin_write16(FIO1_FLAG_S,val) +#define bfin_read_FIO1_FLAG_T() bfin_read16(FIO1_FLAG_T) +#define bfin_write_FIO1_FLAG_T(val) bfin_write16(FIO1_FLAG_T,val) +#define bfin_read_FIO1_MASKA_D() bfin_read16(FIO1_MASKA_D) +#define bfin_write_FIO1_MASKA_D(val) bfin_write16(FIO1_MASKA_D,val) +#define bfin_read_FIO1_MASKA_C() bfin_read16(FIO1_MASKA_C) +#define bfin_write_FIO1_MASKA_C(val) bfin_write16(FIO1_MASKA_C,val) +#define bfin_read_FIO1_MASKA_S() bfin_read16(FIO1_MASKA_S) +#define bfin_write_FIO1_MASKA_S(val) bfin_write16(FIO1_MASKA_S,val) +#define bfin_read_FIO1_MASKA_T() bfin_read16(FIO1_MASKA_T) +#define bfin_write_FIO1_MASKA_T(val) bfin_write16(FIO1_MASKA_T,val) +#define bfin_read_FIO1_MASKB_D() bfin_read16(FIO1_MASKB_D) +#define bfin_write_FIO1_MASKB_D(val) bfin_write16(FIO1_MASKB_D,val) +#define bfin_read_FIO1_MASKB_C() bfin_read16(FIO1_MASKB_C) +#define bfin_write_FIO1_MASKB_C(val) bfin_write16(FIO1_MASKB_C,val) +#define bfin_read_FIO1_MASKB_S() bfin_read16(FIO1_MASKB_S) +#define bfin_write_FIO1_MASKB_S(val) bfin_write16(FIO1_MASKB_S,val) +#define bfin_read_FIO1_MASKB_T() bfin_read16(FIO1_MASKB_T) +#define bfin_write_FIO1_MASKB_T(val) bfin_write16(FIO1_MASKB_T,val) +#define bfin_read_FIO1_DIR() bfin_read16(FIO1_DIR) +#define bfin_write_FIO1_DIR(val) bfin_write16(FIO1_DIR,val) +#define bfin_read_FIO1_POLAR() bfin_read16(FIO1_POLAR) +#define bfin_write_FIO1_POLAR(val) bfin_write16(FIO1_POLAR,val) +#define bfin_read_FIO1_EDGE() bfin_read16(FIO1_EDGE) +#define bfin_write_FIO1_EDGE(val) bfin_write16(FIO1_EDGE,val) +#define bfin_read_FIO1_BOTH() bfin_read16(FIO1_BOTH) +#define bfin_write_FIO1_BOTH(val) bfin_write16(FIO1_BOTH,val) +#define bfin_read_FIO1_INEN() bfin_read16(FIO1_INEN) +#define bfin_write_FIO1_INEN(val) bfin_write16(FIO1_INEN,val) +/* Programmable Flag registers (0xFFC0 1700-0xFFC0 17FF) */ +#define bfin_read_FIO2_FLAG_D() bfin_read16(FIO2_FLAG_D) +#define bfin_write_FIO2_FLAG_D(val) bfin_write16(FIO2_FLAG_D,val) +#define bfin_read_FIO2_FLAG_C() bfin_read16(FIO2_FLAG_C) +#define bfin_write_FIO2_FLAG_C(val) bfin_write16(FIO2_FLAG_C,val) +#define bfin_read_FIO2_FLAG_S() bfin_read16(FIO2_FLAG_S) +#define bfin_write_FIO2_FLAG_S(val) bfin_write16(FIO2_FLAG_S,val) +#define bfin_read_FIO2_FLAG_T() bfin_read16(FIO2_FLAG_T) +#define bfin_write_FIO2_FLAG_T(val) bfin_write16(FIO2_FLAG_T,val) +#define bfin_read_FIO2_MASKA_D() bfin_read16(FIO2_MASKA_D) +#define bfin_write_FIO2_MASKA_D(val) bfin_write16(FIO2_MASKA_D,val) +#define bfin_read_FIO2_MASKA_C() bfin_read16(FIO2_MASKA_C) +#define bfin_write_FIO2_MASKA_C(val) bfin_write16(FIO2_MASKA_C,val) +#define bfin_read_FIO2_MASKA_S() bfin_read16(FIO2_MASKA_S) +#define bfin_write_FIO2_MASKA_S(val) bfin_write16(FIO2_MASKA_S,val) +#define bfin_read_FIO2_MASKA_T() bfin_read16(FIO2_MASKA_T) +#define bfin_write_FIO2_MASKA_T(val) bfin_write16(FIO2_MASKA_T,val) +#define bfin_read_FIO2_MASKB_D() bfin_read16(FIO2_MASKB_D) +#define bfin_write_FIO2_MASKB_D(val) bfin_write16(FIO2_MASKB_D,val) +#define bfin_read_FIO2_MASKB_C() bfin_read16(FIO2_MASKB_C) +#define bfin_write_FIO2_MASKB_C(val) bfin_write16(FIO2_MASKB_C,val) +#define bfin_read_FIO2_MASKB_S() bfin_read16(FIO2_MASKB_S) +#define bfin_write_FIO2_MASKB_S(val) bfin_write16(FIO2_MASKB_S,val) +#define bfin_read_FIO2_MASKB_T() bfin_read16(FIO2_MASKB_T) +#define bfin_write_FIO2_MASKB_T(val) bfin_write16(FIO2_MASKB_T,val) +#define bfin_read_FIO2_DIR() bfin_read16(FIO2_DIR) +#define bfin_write_FIO2_DIR(val) bfin_write16(FIO2_DIR,val) +#define bfin_read_FIO2_POLAR() bfin_read16(FIO2_POLAR) +#define bfin_write_FIO2_POLAR(val) bfin_write16(FIO2_POLAR,val) +#define bfin_read_FIO2_EDGE() bfin_read16(FIO2_EDGE) +#define bfin_write_FIO2_EDGE(val) bfin_write16(FIO2_EDGE,val) +#define bfin_read_FIO2_BOTH() bfin_read16(FIO2_BOTH) +#define bfin_write_FIO2_BOTH(val) bfin_write16(FIO2_BOTH,val) +#define bfin_read_FIO2_INEN() bfin_read16(FIO2_INEN) +#define bfin_write_FIO2_INEN(val) bfin_write16(FIO2_INEN,val) +/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */ +#define bfin_read_SPORT0_TCR1() bfin_read16(SPORT0_TCR1) +#define bfin_write_SPORT0_TCR1(val) bfin_write16(SPORT0_TCR1,val) +#define bfin_read_SPORT0_TCR2() bfin_read16(SPORT0_TCR2) +#define bfin_write_SPORT0_TCR2(val) bfin_write16(SPORT0_TCR2,val) +#define bfin_read_SPORT0_TCLKDIV() bfin_read16(SPORT0_TCLKDIV) +#define bfin_write_SPORT0_TCLKDIV(val) bfin_write16(SPORT0_TCLKDIV,val) +#define bfin_read_SPORT0_TFSDIV() bfin_read16(SPORT0_TFSDIV) +#define bfin_write_SPORT0_TFSDIV(val) bfin_write16(SPORT0_TFSDIV,val) +#define bfin_read_SPORT0_TX() bfin_read32(SPORT0_TX) +#define bfin_write_SPORT0_TX(val) bfin_write32(SPORT0_TX,val) +#define bfin_read_SPORT0_RX() bfin_read32(SPORT0_RX) +#define bfin_write_SPORT0_RX(val) bfin_write32(SPORT0_RX,val) +#define bfin_read_SPORT0_TX32() bfin_read32(SPORT0_TX) +#define bfin_write_SPORT0_TX32(val) bfin_write32(SPORT0_TX,val) +#define bfin_read_SPORT0_RX32() bfin_read32(SPORT0_RX) +#define bfin_write_SPORT0_RX32(val) bfin_write32(SPORT0_RX,val) +#define bfin_read_SPORT0_TX16() bfin_read16(SPORT0_TX) +#define bfin_write_SPORT0_TX16(val) bfin_write16(SPORT0_TX,val) +#define bfin_read_SPORT0_RX16() bfin_read16(SPORT0_RX) +#define bfin_write_SPORT0_RX16(val) bfin_write16(SPORT0_RX,val) +#define bfin_read_SPORT0_RCR1() bfin_read16(SPORT0_RCR1) +#define bfin_write_SPORT0_RCR1(val) bfin_write16(SPORT0_RCR1,val) +#define bfin_read_SPORT0_RCR2() bfin_read16(SPORT0_RCR2) +#define bfin_write_SPORT0_RCR2(val) bfin_write16(SPORT0_RCR2,val) +#define bfin_read_SPORT0_RCLKDIV() bfin_read16(SPORT0_RCLKDIV) +#define bfin_write_SPORT0_RCLKDIV(val) bfin_write16(SPORT0_RCLKDIV,val) +#define bfin_read_SPORT0_RFSDIV() bfin_read16(SPORT0_RFSDIV) +#define bfin_write_SPORT0_RFSDIV(val) bfin_write16(SPORT0_RFSDIV,val) +#define bfin_read_SPORT0_STAT() bfin_read16(SPORT0_STAT) +#define bfin_write_SPORT0_STAT(val) bfin_write16(SPORT0_STAT,val) +#define bfin_read_SPORT0_CHNL() bfin_read16(SPORT0_CHNL) +#define bfin_write_SPORT0_CHNL(val) bfin_write16(SPORT0_CHNL,val) +#define bfin_read_SPORT0_MCMC1() bfin_read16(SPORT0_MCMC1) +#define bfin_write_SPORT0_MCMC1(val) bfin_write16(SPORT0_MCMC1,val) +#define bfin_read_SPORT0_MCMC2() bfin_read16(SPORT0_MCMC2) +#define bfin_write_SPORT0_MCMC2(val) bfin_write16(SPORT0_MCMC2,val) +#define bfin_read_SPORT0_MTCS0() bfin_read32(SPORT0_MTCS0) +#define bfin_write_SPORT0_MTCS0(val) bfin_write32(SPORT0_MTCS0,val) +#define bfin_read_SPORT0_MTCS1() bfin_read32(SPORT0_MTCS1) +#define bfin_write_SPORT0_MTCS1(val) bfin_write32(SPORT0_MTCS1,val) +#define bfin_read_SPORT0_MTCS2() bfin_read32(SPORT0_MTCS2) +#define bfin_write_SPORT0_MTCS2(val) bfin_write32(SPORT0_MTCS2,val) +#define bfin_read_SPORT0_MTCS3() bfin_read32(SPORT0_MTCS3) +#define bfin_write_SPORT0_MTCS3(val) bfin_write32(SPORT0_MTCS3,val) +#define bfin_read_SPORT0_MRCS0() bfin_read32(SPORT0_MRCS0) +#define bfin_write_SPORT0_MRCS0(val) bfin_write32(SPORT0_MRCS0,val) +#define bfin_read_SPORT0_MRCS1() bfin_read32(SPORT0_MRCS1) +#define bfin_write_SPORT0_MRCS1(val) bfin_write32(SPORT0_MRCS1,val) +#define bfin_read_SPORT0_MRCS2() bfin_read32(SPORT0_MRCS2) +#define bfin_write_SPORT0_MRCS2(val) bfin_write32(SPORT0_MRCS2,val) +#define bfin_read_SPORT0_MRCS3() bfin_read32(SPORT0_MRCS3) +#define bfin_write_SPORT0_MRCS3(val) bfin_write32(SPORT0_MRCS3,val) +/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */ +#define bfin_read_SPORT1_TCR1() bfin_read16(SPORT1_TCR1) +#define bfin_write_SPORT1_TCR1(val) bfin_write16(SPORT1_TCR1,val) +#define bfin_read_SPORT1_TCR2() bfin_read16(SPORT1_TCR2) +#define bfin_write_SPORT1_TCR2(val) bfin_write16(SPORT1_TCR2,val) +#define bfin_read_SPORT1_TCLKDIV() bfin_read16(SPORT1_TCLKDIV) +#define bfin_write_SPORT1_TCLKDIV(val) bfin_write16(SPORT1_TCLKDIV,val) +#define bfin_read_SPORT1_TFSDIV() bfin_read16(SPORT1_TFSDIV) +#define bfin_write_SPORT1_TFSDIV(val) bfin_write16(SPORT1_TFSDIV,val) +#define bfin_read_SPORT1_TX() bfin_read32(SPORT1_TX) +#define bfin_write_SPORT1_TX(val) bfin_write32(SPORT1_TX,val) +#define bfin_read_SPORT1_RX() bfin_read32(SPORT1_RX) +#define bfin_write_SPORT1_RX(val) bfin_write32(SPORT1_RX,val) +#define bfin_read_SPORT1_TX32() bfin_read32(SPORT1_TX) +#define bfin_write_SPORT1_TX32(val) bfin_write32(SPORT1_TX,val) +#define bfin_read_SPORT1_RX32() bfin_read32(SPORT1_RX) +#define bfin_write_SPORT1_RX32(val) bfin_write32(SPORT1_RX,val) +#define bfin_read_SPORT1_TX16() bfin_read16(SPORT1_TX) +#define bfin_write_SPORT1_TX16(val) bfin_write16(SPORT1_TX,val) +#define bfin_read_SPORT1_RX16() bfin_read16(SPORT1_RX) +#define bfin_write_SPORT1_RX16(val) bfin_write16(SPORT1_RX,val) +#define bfin_read_SPORT1_RCR1() bfin_read16(SPORT1_RCR1) +#define bfin_write_SPORT1_RCR1(val) bfin_write16(SPORT1_RCR1,val) +#define bfin_read_SPORT1_RCR2() bfin_read16(SPORT1_RCR2) +#define bfin_write_SPORT1_RCR2(val) bfin_write16(SPORT1_RCR2,val) +#define bfin_read_SPORT1_RCLKDIV() bfin_read16(SPORT1_RCLKDIV) +#define bfin_write_SPORT1_RCLKDIV(val) bfin_write16(SPORT1_RCLKDIV,val) +#define bfin_read_SPORT1_RFSDIV() bfin_read16(SPORT1_RFSDIV) +#define bfin_write_SPORT1_RFSDIV(val) bfin_write16(SPORT1_RFSDIV,val) +#define bfin_read_SPORT1_STAT() bfin_read16(SPORT1_STAT) +#define bfin_write_SPORT1_STAT(val) bfin_write16(SPORT1_STAT,val) +#define bfin_read_SPORT1_CHNL() bfin_read16(SPORT1_CHNL) +#define bfin_write_SPORT1_CHNL(val) bfin_write16(SPORT1_CHNL,val) +#define bfin_read_SPORT1_MCMC1() bfin_read16(SPORT1_MCMC1) +#define bfin_write_SPORT1_MCMC1(val) bfin_write16(SPORT1_MCMC1,val) +#define bfin_read_SPORT1_MCMC2() bfin_read16(SPORT1_MCMC2) +#define bfin_write_SPORT1_MCMC2(val) bfin_write16(SPORT1_MCMC2,val) +#define bfin_read_SPORT1_MTCS0() bfin_read32(SPORT1_MTCS0) +#define bfin_write_SPORT1_MTCS0(val) bfin_write32(SPORT1_MTCS0,val) +#define bfin_read_SPORT1_MTCS1() bfin_read32(SPORT1_MTCS1) +#define bfin_write_SPORT1_MTCS1(val) bfin_write32(SPORT1_MTCS1,val) +#define bfin_read_SPORT1_MTCS2() bfin_read32(SPORT1_MTCS2) +#define bfin_write_SPORT1_MTCS2(val) bfin_write32(SPORT1_MTCS2,val) +#define bfin_read_SPORT1_MTCS3() bfin_read32(SPORT1_MTCS3) +#define bfin_write_SPORT1_MTCS3(val) bfin_write32(SPORT1_MTCS3,val) +#define bfin_read_SPORT1_MRCS0() bfin_read32(SPORT1_MRCS0) +#define bfin_write_SPORT1_MRCS0(val) bfin_write32(SPORT1_MRCS0,val) +#define bfin_read_SPORT1_MRCS1() bfin_read32(SPORT1_MRCS1) +#define bfin_write_SPORT1_MRCS1(val) bfin_write32(SPORT1_MRCS1,val) +#define bfin_read_SPORT1_MRCS2() bfin_read32(SPORT1_MRCS2) +#define bfin_write_SPORT1_MRCS2(val) bfin_write32(SPORT1_MRCS2,val) +#define bfin_read_SPORT1_MRCS3() bfin_read32(SPORT1_MRCS3) +#define bfin_write_SPORT1_MRCS3(val) bfin_write32(SPORT1_MRCS3,val) +/* Asynchronous Memory Controller - External Bus Interface Unit */ +#define bfin_read_EBIU_AMGCTL() bfin_read16(EBIU_AMGCTL) +#define bfin_write_EBIU_AMGCTL(val) bfin_write16(EBIU_AMGCTL,val) +#define bfin_read_EBIU_AMBCTL0() bfin_read32(EBIU_AMBCTL0) +#define bfin_write_EBIU_AMBCTL0(val) bfin_write32(EBIU_AMBCTL0,val) +#define bfin_read_EBIU_AMBCTL1() bfin_read32(EBIU_AMBCTL1) +#define bfin_write_EBIU_AMBCTL1(val) bfin_write32(EBIU_AMBCTL1,val) +/* SDRAM Controller External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */ +#define bfin_read_EBIU_SDGCTL() bfin_read32(EBIU_SDGCTL) +#define bfin_write_EBIU_SDGCTL(val) bfin_write32(EBIU_SDGCTL,val) +#define bfin_read_EBIU_SDBCTL() bfin_read32(EBIU_SDBCTL) +#define bfin_write_EBIU_SDBCTL(val) bfin_write32(EBIU_SDBCTL,val) +#define bfin_read_EBIU_SDRRC() bfin_read16(EBIU_SDRRC) +#define bfin_write_EBIU_SDRRC(val) bfin_write16(EBIU_SDRRC,val) +#define bfin_read_EBIU_SDSTAT() bfin_read16(EBIU_SDSTAT) +#define bfin_write_EBIU_SDSTAT(val) bfin_write16(EBIU_SDSTAT,val) +/* Parallel Peripheral Interface (PPI) 0 registers (0xFFC0 1000-0xFFC0 10FF) */ +#define bfin_read_PPI0_CONTROL() bfin_read16(PPI0_CONTROL) +#define bfin_write_PPI0_CONTROL(val) bfin_write16(PPI0_CONTROL,val) +#define bfin_read_PPI0_STATUS() bfin_read16(PPI0_STATUS) +#define bfin_write_PPI0_STATUS(val) bfin_write16(PPI0_STATUS,val) +#define bfin_read_PPI0_COUNT() bfin_read16(PPI0_COUNT) +#define bfin_write_PPI0_COUNT(val) bfin_write16(PPI0_COUNT,val) +#define bfin_read_PPI0_DELAY() bfin_read16(PPI0_DELAY) +#define bfin_write_PPI0_DELAY(val) bfin_write16(PPI0_DELAY,val) +#define bfin_read_PPI0_FRAME() bfin_read16(PPI0_FRAME) +#define bfin_write_PPI0_FRAME(val) bfin_write16(PPI0_FRAME,val) +/* Parallel Peripheral Interface (PPI) 1 registers (0xFFC0 1300-0xFFC0 13FF) */ +#define bfin_read_PPI1_CONTROL() bfin_read16(PPI1_CONTROL) +#define bfin_write_PPI1_CONTROL(val) bfin_write16(PPI1_CONTROL,val) +#define bfin_read_PPI1_STATUS() bfin_read16(PPI1_STATUS) +#define bfin_write_PPI1_STATUS(val) bfin_write16(PPI1_STATUS,val) +#define bfin_read_PPI1_COUNT() bfin_read16(PPI1_COUNT) +#define bfin_write_PPI1_COUNT(val) bfin_write16(PPI1_COUNT,val) +#define bfin_read_PPI1_DELAY() bfin_read16(PPI1_DELAY) +#define bfin_write_PPI1_DELAY(val) bfin_write16(PPI1_DELAY,val) +#define bfin_read_PPI1_FRAME() bfin_read16(PPI1_FRAME) +#define bfin_write_PPI1_FRAME(val) bfin_write16(PPI1_FRAME,val) +/*DMA traffic control registers */ +#define bfin_read_DMA1_TC_PER() bfin_read16(DMA1_TC_PER) +#define bfin_write_DMA1_TC_PER(val) bfin_write16(DMA1_TC_PER,val) +#define bfin_read_DMA1_TC_CNT() bfin_read16(DMA1_TC_CNT) +#define bfin_write_DMA1_TC_CNT(val) bfin_write16(DMA1_TC_CNT,val) +#define bfin_read_DMA2_TC_PER() bfin_read16(DMA2_TC_PER) +#define bfin_write_DMA2_TC_PER(val) bfin_write16(DMA2_TC_PER,val) +#define bfin_read_DMA2_TC_CNT() bfin_read16(DMA2_TC_CNT) +#define bfin_write_DMA2_TC_CNT(val) bfin_write16(DMA2_TC_CNT,val) +/* DMA1 Controller registers (0xFFC0 1C00-0xFFC0 1FFF) */ +#define bfin_read_DMA1_0_CONFIG() bfin_read16(DMA1_0_CONFIG) +#define bfin_write_DMA1_0_CONFIG(val) bfin_write16(DMA1_0_CONFIG,val) +#define bfin_read_DMA1_0_NEXT_DESC_PTR() bfin_read32(DMA1_0_NEXT_DESC_PTR) +#define bfin_write_DMA1_0_NEXT_DESC_PTR(val) bfin_write32(DMA1_0_NEXT_DESC_PTR,val) +#define bfin_read_DMA1_0_START_ADDR() bfin_read32(DMA1_0_START_ADDR) +#define bfin_write_DMA1_0_START_ADDR(val) bfin_write32(DMA1_0_START_ADDR,val) +#define bfin_read_DMA1_0_X_COUNT() bfin_read16(DMA1_0_X_COUNT) +#define bfin_write_DMA1_0_X_COUNT(val) bfin_write16(DMA1_0_X_COUNT,val) +#define bfin_read_DMA1_0_Y_COUNT() bfin_read16(DMA1_0_Y_COUNT) +#define bfin_write_DMA1_0_Y_COUNT(val) bfin_write16(DMA1_0_Y_COUNT,val) +#define bfin_read_DMA1_0_X_MODIFY() bfin_read16(DMA1_0_X_MODIFY) +#define bfin_write_DMA1_0_X_MODIFY(val) bfin_write16(DMA1_0_X_MODIFY,val) +#define bfin_read_DMA1_0_Y_MODIFY() bfin_read16(DMA1_0_Y_MODIFY) +#define bfin_write_DMA1_0_Y_MODIFY(val) bfin_write16(DMA1_0_Y_MODIFY,val) +#define bfin_read_DMA1_0_CURR_DESC_PTR() bfin_read32(DMA1_0_CURR_DESC_PTR) +#define bfin_write_DMA1_0_CURR_DESC_PTR(val) bfin_write32(DMA1_0_CURR_DESC_PTR,val) +#define bfin_read_DMA1_0_CURR_ADDR() bfin_read32(DMA1_0_CURR_ADDR) +#define bfin_write_DMA1_0_CURR_ADDR(val) bfin_write32(DMA1_0_CURR_ADDR,val) +#define bfin_read_DMA1_0_CURR_X_COUNT() bfin_read16(DMA1_0_CURR_X_COUNT) +#define bfin_write_DMA1_0_CURR_X_COUNT(val) bfin_write16(DMA1_0_CURR_X_COUNT,val) +#define bfin_read_DMA1_0_CURR_Y_COUNT() bfin_read16(DMA1_0_CURR_Y_COUNT) +#define bfin_write_DMA1_0_CURR_Y_COUNT(val) bfin_write16(DMA1_0_CURR_Y_COUNT,val) +#define bfin_read_DMA1_0_IRQ_STATUS() bfin_read16(DMA1_0_IRQ_STATUS) +#define bfin_write_DMA1_0_IRQ_STATUS(val) bfin_write16(DMA1_0_IRQ_STATUS,val) +#define bfin_read_DMA1_0_PERIPHERAL_MAP() bfin_read16(DMA1_0_PERIPHERAL_MAP) +#define bfin_write_DMA1_0_PERIPHERAL_MAP(val) bfin_write16(DMA1_0_PERIPHERAL_MAP,val) +#define bfin_read_DMA1_1_CONFIG() bfin_read16(DMA1_1_CONFIG) +#define bfin_write_DMA1_1_CONFIG(val) bfin_write16(DMA1_1_CONFIG,val) +#define bfin_read_DMA1_1_NEXT_DESC_PTR() bfin_read32(DMA1_1_NEXT_DESC_PTR) +#define bfin_write_DMA1_1_NEXT_DESC_PTR(val) bfin_write32(DMA1_1_NEXT_DESC_PTR,val) +#define bfin_read_DMA1_1_START_ADDR() bfin_read32(DMA1_1_START_ADDR) +#define bfin_write_DMA1_1_START_ADDR(val) bfin_write32(DMA1_1_START_ADDR,val) +#define bfin_read_DMA1_1_X_COUNT() bfin_read16(DMA1_1_X_COUNT) +#define bfin_write_DMA1_1_X_COUNT(val) bfin_write16(DMA1_1_X_COUNT,val) +#define bfin_read_DMA1_1_Y_COUNT() bfin_read16(DMA1_1_Y_COUNT) +#define bfin_write_DMA1_1_Y_COUNT(val) bfin_write16(DMA1_1_Y_COUNT,val) +#define bfin_read_DMA1_1_X_MODIFY() bfin_read16(DMA1_1_X_MODIFY) +#define bfin_write_DMA1_1_X_MODIFY(val) bfin_write16(DMA1_1_X_MODIFY,val) +#define bfin_read_DMA1_1_Y_MODIFY() bfin_read16(DMA1_1_Y_MODIFY) +#define bfin_write_DMA1_1_Y_MODIFY(val) bfin_write16(DMA1_1_Y_MODIFY,val) +#define bfin_read_DMA1_1_CURR_DESC_PTR() bfin_read32(DMA1_1_CURR_DESC_PTR) +#define bfin_write_DMA1_1_CURR_DESC_PTR(val) bfin_write32(DMA1_1_CURR_DESC_PTR,val) +#define bfin_read_DMA1_1_CURR_ADDR() bfin_read32(DMA1_1_CURR_ADDR) +#define bfin_write_DMA1_1_CURR_ADDR(val) bfin_write32(DMA1_1_CURR_ADDR,val) +#define bfin_read_DMA1_1_CURR_X_COUNT() bfin_read16(DMA1_1_CURR_X_COUNT) +#define bfin_write_DMA1_1_CURR_X_COUNT(val) bfin_write16(DMA1_1_CURR_X_COUNT,val) +#define bfin_read_DMA1_1_CURR_Y_COUNT() bfin_read16(DMA1_1_CURR_Y_COUNT) +#define bfin_write_DMA1_1_CURR_Y_COUNT(val) bfin_write16(DMA1_1_CURR_Y_COUNT,val) +#define bfin_read_DMA1_1_IRQ_STATUS() bfin_read16(DMA1_1_IRQ_STATUS) +#define bfin_write_DMA1_1_IRQ_STATUS(val) bfin_write16(DMA1_1_IRQ_STATUS,val) +#define bfin_read_DMA1_1_PERIPHERAL_MAP() bfin_read16(DMA1_1_PERIPHERAL_MAP) +#define bfin_write_DMA1_1_PERIPHERAL_MAP(val) bfin_write16(DMA1_1_PERIPHERAL_MAP,val) +#define bfin_read_DMA1_2_CONFIG() bfin_read16(DMA1_2_CONFIG) +#define bfin_write_DMA1_2_CONFIG(val) bfin_write16(DMA1_2_CONFIG,val) +#define bfin_read_DMA1_2_NEXT_DESC_PTR() bfin_read32(DMA1_2_NEXT_DESC_PTR) +#define bfin_write_DMA1_2_NEXT_DESC_PTR(val) bfin_write32(DMA1_2_NEXT_DESC_PTR,val) +#define bfin_read_DMA1_2_START_ADDR() bfin_read32(DMA1_2_START_ADDR) +#define bfin_write_DMA1_2_START_ADDR(val) bfin_write32(DMA1_2_START_ADDR,val) +#define bfin_read_DMA1_2_X_COUNT() bfin_read16(DMA1_2_X_COUNT) +#define bfin_write_DMA1_2_X_COUNT(val) bfin_write16(DMA1_2_X_COUNT,val) +#define bfin_read_DMA1_2_Y_COUNT() bfin_read16(DMA1_2_Y_COUNT) +#define bfin_write_DMA1_2_Y_COUNT(val) bfin_write16(DMA1_2_Y_COUNT,val) +#define bfin_read_DMA1_2_X_MODIFY() bfin_read16(DMA1_2_X_MODIFY) +#define bfin_write_DMA1_2_X_MODIFY(val) bfin_write16(DMA1_2_X_MODIFY,val) +#define bfin_read_DMA1_2_Y_MODIFY() bfin_read16(DMA1_2_Y_MODIFY) +#define bfin_write_DMA1_2_Y_MODIFY(val) bfin_write16(DMA1_2_Y_MODIFY,val) +#define bfin_read_DMA1_2_CURR_DESC_PTR() bfin_read32(DMA1_2_CURR_DESC_PTR) +#define bfin_write_DMA1_2_CURR_DESC_PTR(val) bfin_write32(DMA1_2_CURR_DESC_PTR,val) +#define bfin_read_DMA1_2_CURR_ADDR() bfin_read32(DMA1_2_CURR_ADDR) +#define bfin_write_DMA1_2_CURR_ADDR(val) bfin_write32(DMA1_2_CURR_ADDR,val) +#define bfin_read_DMA1_2_CURR_X_COUNT() bfin_read16(DMA1_2_CURR_X_COUNT) +#define bfin_write_DMA1_2_CURR_X_COUNT(val) bfin_write16(DMA1_2_CURR_X_COUNT,val) +#define bfin_read_DMA1_2_CURR_Y_COUNT() bfin_read16(DMA1_2_CURR_Y_COUNT) +#define bfin_write_DMA1_2_CURR_Y_COUNT(val) bfin_write16(DMA1_2_CURR_Y_COUNT,val) +#define bfin_read_DMA1_2_IRQ_STATUS() bfin_read16(DMA1_2_IRQ_STATUS) +#define bfin_write_DMA1_2_IRQ_STATUS(val) bfin_write16(DMA1_2_IRQ_STATUS,val) +#define bfin_read_DMA1_2_PERIPHERAL_MAP() bfin_read16(DMA1_2_PERIPHERAL_MAP) +#define bfin_write_DMA1_2_PERIPHERAL_MAP(val) bfin_write16(DMA1_2_PERIPHERAL_MAP,val) +#define bfin_read_DMA1_3_CONFIG() bfin_read16(DMA1_3_CONFIG) +#define bfin_write_DMA1_3_CONFIG(val) bfin_write16(DMA1_3_CONFIG,val) +#define bfin_read_DMA1_3_NEXT_DESC_PTR() bfin_read32(DMA1_3_NEXT_DESC_PTR) +#define bfin_write_DMA1_3_NEXT_DESC_PTR(val) bfin_write32(DMA1_3_NEXT_DESC_PTR,val) +#define bfin_read_DMA1_3_START_ADDR() bfin_read32(DMA1_3_START_ADDR) +#define bfin_write_DMA1_3_START_ADDR(val) bfin_write32(DMA1_3_START_ADDR,val) +#define bfin_read_DMA1_3_X_COUNT() bfin_read16(DMA1_3_X_COUNT) +#define bfin_write_DMA1_3_X_COUNT(val) bfin_write16(DMA1_3_X_COUNT,val) +#define bfin_read_DMA1_3_Y_COUNT() bfin_read16(DMA1_3_Y_COUNT) +#define bfin_write_DMA1_3_Y_COUNT(val) bfin_write16(DMA1_3_Y_COUNT,val) +#define bfin_read_DMA1_3_X_MODIFY() bfin_read16(DMA1_3_X_MODIFY) +#define bfin_write_DMA1_3_X_MODIFY(val) bfin_write16(DMA1_3_X_MODIFY,val) +#define bfin_read_DMA1_3_Y_MODIFY() bfin_read16(DMA1_3_Y_MODIFY) +#define bfin_write_DMA1_3_Y_MODIFY(val) bfin_write16(DMA1_3_Y_MODIFY,val) +#define bfin_read_DMA1_3_CURR_DESC_PTR() bfin_read32(DMA1_3_CURR_DESC_PTR) +#define bfin_write_DMA1_3_CURR_DESC_PTR(val) bfin_write32(DMA1_3_CURR_DESC_PTR,val) +#define bfin_read_DMA1_3_CURR_ADDR() bfin_read32(DMA1_3_CURR_ADDR) +#define bfin_write_DMA1_3_CURR_ADDR(val) bfin_write32(DMA1_3_CURR_ADDR,val) +#define bfin_read_DMA1_3_CURR_X_COUNT() bfin_read16(DMA1_3_CURR_X_COUNT) +#define bfin_write_DMA1_3_CURR_X_COUNT(val) bfin_write16(DMA1_3_CURR_X_COUNT,val) +#define bfin_read_DMA1_3_CURR_Y_COUNT() bfin_read16(DMA1_3_CURR_Y_COUNT) +#define bfin_write_DMA1_3_CURR_Y_COUNT(val) bfin_write16(DMA1_3_CURR_Y_COUNT,val) +#define bfin_read_DMA1_3_IRQ_STATUS() bfin_read16(DMA1_3_IRQ_STATUS) +#define bfin_write_DMA1_3_IRQ_STATUS(val) bfin_write16(DMA1_3_IRQ_STATUS,val) +#define bfin_read_DMA1_3_PERIPHERAL_MAP() bfin_read16(DMA1_3_PERIPHERAL_MAP) +#define bfin_write_DMA1_3_PERIPHERAL_MAP(val) bfin_write16(DMA1_3_PERIPHERAL_MAP,val) +#define bfin_read_DMA1_4_CONFIG() bfin_read16(DMA1_4_CONFIG) +#define bfin_write_DMA1_4_CONFIG(val) bfin_write16(DMA1_4_CONFIG,val) +#define bfin_read_DMA1_4_NEXT_DESC_PTR() bfin_read32(DMA1_4_NEXT_DESC_PTR) +#define bfin_write_DMA1_4_NEXT_DESC_PTR(val) bfin_write32(DMA1_4_NEXT_DESC_PTR,val) +#define bfin_read_DMA1_4_START_ADDR() bfin_read32(DMA1_4_START_ADDR) +#define bfin_write_DMA1_4_START_ADDR(val) bfin_write32(DMA1_4_START_ADDR,val) +#define bfin_read_DMA1_4_X_COUNT() bfin_read16(DMA1_4_X_COUNT) +#define bfin_write_DMA1_4_X_COUNT(val) bfin_write16(DMA1_4_X_COUNT,val) +#define bfin_read_DMA1_4_Y_COUNT() bfin_read16(DMA1_4_Y_COUNT) +#define bfin_write_DMA1_4_Y_COUNT(val) bfin_write16(DMA1_4_Y_COUNT,val) +#define bfin_read_DMA1_4_X_MODIFY() bfin_read16(DMA1_4_X_MODIFY) +#define bfin_write_DMA1_4_X_MODIFY(val) bfin_write16(DMA1_4_X_MODIFY,val) +#define bfin_read_DMA1_4_Y_MODIFY() bfin_read16(DMA1_4_Y_MODIFY) +#define bfin_write_DMA1_4_Y_MODIFY(val) bfin_write16(DMA1_4_Y_MODIFY,val) +#define bfin_read_DMA1_4_CURR_DESC_PTR() bfin_read32(DMA1_4_CURR_DESC_PTR) +#define bfin_write_DMA1_4_CURR_DESC_PTR(val) bfin_write32(DMA1_4_CURR_DESC_PTR,val) +#define bfin_read_DMA1_4_CURR_ADDR() bfin_read32(DMA1_4_CURR_ADDR) +#define bfin_write_DMA1_4_CURR_ADDR(val) bfin_write32(DMA1_4_CURR_ADDR,val) +#define bfin_read_DMA1_4_CURR_X_COUNT() bfin_read16(DMA1_4_CURR_X_COUNT) +#define bfin_write_DMA1_4_CURR_X_COUNT(val) bfin_write16(DMA1_4_CURR_X_COUNT,val) +#define bfin_read_DMA1_4_CURR_Y_COUNT() bfin_read16(DMA1_4_CURR_Y_COUNT) +#define bfin_write_DMA1_4_CURR_Y_COUNT(val) bfin_write16(DMA1_4_CURR_Y_COUNT,val) +#define bfin_read_DMA1_4_IRQ_STATUS() bfin_read16(DMA1_4_IRQ_STATUS) +#define bfin_write_DMA1_4_IRQ_STATUS(val) bfin_write16(DMA1_4_IRQ_STATUS,val) +#define bfin_read_DMA1_4_PERIPHERAL_MAP() bfin_read16(DMA1_4_PERIPHERAL_MAP) +#define bfin_write_DMA1_4_PERIPHERAL_MAP(val) bfin_write16(DMA1_4_PERIPHERAL_MAP,val) +#define bfin_read_DMA1_5_CONFIG() bfin_read16(DMA1_5_CONFIG) +#define bfin_write_DMA1_5_CONFIG(val) bfin_write16(DMA1_5_CONFIG,val) +#define bfin_read_DMA1_5_NEXT_DESC_PTR() bfin_read32(DMA1_5_NEXT_DESC_PTR) +#define bfin_write_DMA1_5_NEXT_DESC_PTR(val) bfin_write32(DMA1_5_NEXT_DESC_PTR,val) +#define bfin_read_DMA1_5_START_ADDR() bfin_read32(DMA1_5_START_ADDR) +#define bfin_write_DMA1_5_START_ADDR(val) bfin_write32(DMA1_5_START_ADDR,val) +#define bfin_read_DMA1_5_X_COUNT() bfin_read16(DMA1_5_X_COUNT) +#define bfin_write_DMA1_5_X_COUNT(val) bfin_write16(DMA1_5_X_COUNT,val) +#define bfin_read_DMA1_5_Y_COUNT() bfin_read16(DMA1_5_Y_COUNT) +#define bfin_write_DMA1_5_Y_COUNT(val) bfin_write16(DMA1_5_Y_COUNT,val) +#define bfin_read_DMA1_5_X_MODIFY() bfin_read16(DMA1_5_X_MODIFY) +#define bfin_write_DMA1_5_X_MODIFY(val) bfin_write16(DMA1_5_X_MODIFY,val) +#define bfin_read_DMA1_5_Y_MODIFY() bfin_read16(DMA1_5_Y_MODIFY) +#define bfin_write_DMA1_5_Y_MODIFY(val) bfin_write16(DMA1_5_Y_MODIFY,val) +#define bfin_read_DMA1_5_CURR_DESC_PTR() bfin_read32(DMA1_5_CURR_DESC_PTR) +#define bfin_write_DMA1_5_CURR_DESC_PTR(val) bfin_write32(DMA1_5_CURR_DESC_PTR,val) +#define bfin_read_DMA1_5_CURR_ADDR() bfin_read32(DMA1_5_CURR_ADDR) +#define bfin_write_DMA1_5_CURR_ADDR(val) bfin_write32(DMA1_5_CURR_ADDR,val) +#define bfin_read_DMA1_5_CURR_X_COUNT() bfin_read16(DMA1_5_CURR_X_COUNT) +#define bfin_write_DMA1_5_CURR_X_COUNT(val) bfin_write16(DMA1_5_CURR_X_COUNT,val) +#define bfin_read_DMA1_5_CURR_Y_COUNT() bfin_read16(DMA1_5_CURR_Y_COUNT) +#define bfin_write_DMA1_5_CURR_Y_COUNT(val) bfin_write16(DMA1_5_CURR_Y_COUNT,val) +#define bfin_read_DMA1_5_IRQ_STATUS() bfin_read16(DMA1_5_IRQ_STATUS) +#define bfin_write_DMA1_5_IRQ_STATUS(val) bfin_write16(DMA1_5_IRQ_STATUS,val) +#define bfin_read_DMA1_5_PERIPHERAL_MAP() bfin_read16(DMA1_5_PERIPHERAL_MAP) +#define bfin_write_DMA1_5_PERIPHERAL_MAP(val) bfin_write16(DMA1_5_PERIPHERAL_MAP,val) +#define bfin_read_DMA1_6_CONFIG() bfin_read16(DMA1_6_CONFIG) +#define bfin_write_DMA1_6_CONFIG(val) bfin_write16(DMA1_6_CONFIG,val) +#define bfin_read_DMA1_6_NEXT_DESC_PTR() bfin_read32(DMA1_6_NEXT_DESC_PTR) +#define bfin_write_DMA1_6_NEXT_DESC_PTR(val) bfin_write32(DMA1_6_NEXT_DESC_PTR,val) +#define bfin_read_DMA1_6_START_ADDR() bfin_read32(DMA1_6_START_ADDR) +#define bfin_write_DMA1_6_START_ADDR(val) bfin_write32(DMA1_6_START_ADDR,val) +#define bfin_read_DMA1_6_X_COUNT() bfin_read16(DMA1_6_X_COUNT) +#define bfin_write_DMA1_6_X_COUNT(val) bfin_write16(DMA1_6_X_COUNT,val) +#define bfin_read_DMA1_6_Y_COUNT() bfin_read16(DMA1_6_Y_COUNT) +#define bfin_write_DMA1_6_Y_COUNT(val) bfin_write16(DMA1_6_Y_COUNT,val) +#define bfin_read_DMA1_6_X_MODIFY() bfin_read16(DMA1_6_X_MODIFY) +#define bfin_write_DMA1_6_X_MODIFY(val) bfin_write16(DMA1_6_X_MODIFY,val) +#define bfin_read_DMA1_6_Y_MODIFY() bfin_read16(DMA1_6_Y_MODIFY) +#define bfin_write_DMA1_6_Y_MODIFY(val) bfin_write16(DMA1_6_Y_MODIFY,val) +#define bfin_read_DMA1_6_CURR_DESC_PTR() bfin_read32(DMA1_6_CURR_DESC_PTR) +#define bfin_write_DMA1_6_CURR_DESC_PTR(val) bfin_write32(DMA1_6_CURR_DESC_PTR,val) +#define bfin_read_DMA1_6_CURR_ADDR() bfin_read32(DMA1_6_CURR_ADDR) +#define bfin_write_DMA1_6_CURR_ADDR(val) bfin_write32(DMA1_6_CURR_ADDR,val) +#define bfin_read_DMA1_6_CURR_X_COUNT() bfin_read16(DMA1_6_CURR_X_COUNT) +#define bfin_write_DMA1_6_CURR_X_COUNT(val) bfin_write16(DMA1_6_CURR_X_COUNT,val) +#define bfin_read_DMA1_6_CURR_Y_COUNT() bfin_read16(DMA1_6_CURR_Y_COUNT) +#define bfin_write_DMA1_6_CURR_Y_COUNT(val) bfin_write16(DMA1_6_CURR_Y_COUNT,val) +#define bfin_read_DMA1_6_IRQ_STATUS() bfin_read16(DMA1_6_IRQ_STATUS) +#define bfin_write_DMA1_6_IRQ_STATUS(val) bfin_write16(DMA1_6_IRQ_STATUS,val) +#define bfin_read_DMA1_6_PERIPHERAL_MAP() bfin_read16(DMA1_6_PERIPHERAL_MAP) +#define bfin_write_DMA1_6_PERIPHERAL_MAP(val) bfin_write16(DMA1_6_PERIPHERAL_MAP,val) +#define bfin_read_DMA1_7_CONFIG() bfin_read16(DMA1_7_CONFIG) +#define bfin_write_DMA1_7_CONFIG(val) bfin_write16(DMA1_7_CONFIG,val) +#define bfin_read_DMA1_7_NEXT_DESC_PTR() bfin_read32(DMA1_7_NEXT_DESC_PTR) +#define bfin_write_DMA1_7_NEXT_DESC_PTR(val) bfin_write32(DMA1_7_NEXT_DESC_PTR,val) +#define bfin_read_DMA1_7_START_ADDR() bfin_read32(DMA1_7_START_ADDR) +#define bfin_write_DMA1_7_START_ADDR(val) bfin_write32(DMA1_7_START_ADDR,val) +#define bfin_read_DMA1_7_X_COUNT() bfin_read16(DMA1_7_X_COUNT) +#define bfin_write_DMA1_7_X_COUNT(val) bfin_write16(DMA1_7_X_COUNT,val) +#define bfin_read_DMA1_7_Y_COUNT() bfin_read16(DMA1_7_Y_COUNT) +#define bfin_write_DMA1_7_Y_COUNT(val) bfin_write16(DMA1_7_Y_COUNT,val) +#define bfin_read_DMA1_7_X_MODIFY() bfin_read16(DMA1_7_X_MODIFY) +#define bfin_write_DMA1_7_X_MODIFY(val) bfin_write16(DMA1_7_X_MODIFY,val) +#define bfin_read_DMA1_7_Y_MODIFY() bfin_read16(DMA1_7_Y_MODIFY) +#define bfin_write_DMA1_7_Y_MODIFY(val) bfin_write16(DMA1_7_Y_MODIFY,val) +#define bfin_read_DMA1_7_CURR_DESC_PTR() bfin_read32(DMA1_7_CURR_DESC_PTR) +#define bfin_write_DMA1_7_CURR_DESC_PTR(val) bfin_write32(DMA1_7_CURR_DESC_PTR,val) +#define bfin_read_DMA1_7_CURR_ADDR() bfin_read32(DMA1_7_CURR_ADDR) +#define bfin_write_DMA1_7_CURR_ADDR(val) bfin_write32(DMA1_7_CURR_ADDR,val) +#define bfin_read_DMA1_7_CURR_X_COUNT() bfin_read16(DMA1_7_CURR_X_COUNT) +#define bfin_write_DMA1_7_CURR_X_COUNT(val) bfin_write16(DMA1_7_CURR_X_COUNT,val) +#define bfin_read_DMA1_7_CURR_Y_COUNT() bfin_read16(DMA1_7_CURR_Y_COUNT) +#define bfin_write_DMA1_7_CURR_Y_COUNT(val) bfin_write16(DMA1_7_CURR_Y_COUNT,val) +#define bfin_read_DMA1_7_IRQ_STATUS() bfin_read16(DMA1_7_IRQ_STATUS) +#define bfin_write_DMA1_7_IRQ_STATUS(val) bfin_write16(DMA1_7_IRQ_STATUS,val) +#define bfin_read_DMA1_7_PERIPHERAL_MAP() bfin_read16(DMA1_7_PERIPHERAL_MAP) +#define bfin_write_DMA1_7_PERIPHERAL_MAP(val) bfin_write16(DMA1_7_PERIPHERAL_MAP,val) +#define bfin_read_DMA1_8_CONFIG() bfin_read16(DMA1_8_CONFIG) +#define bfin_write_DMA1_8_CONFIG(val) bfin_write16(DMA1_8_CONFIG,val) +#define bfin_read_DMA1_8_NEXT_DESC_PTR() bfin_read32(DMA1_8_NEXT_DESC_PTR) +#define bfin_write_DMA1_8_NEXT_DESC_PTR(val) bfin_write32(DMA1_8_NEXT_DESC_PTR,val) +#define bfin_read_DMA1_8_START_ADDR() bfin_read32(DMA1_8_START_ADDR) +#define bfin_write_DMA1_8_START_ADDR(val) bfin_write32(DMA1_8_START_ADDR,val) +#define bfin_read_DMA1_8_X_COUNT() bfin_read16(DMA1_8_X_COUNT) +#define bfin_write_DMA1_8_X_COUNT(val) bfin_write16(DMA1_8_X_COUNT,val) +#define bfin_read_DMA1_8_Y_COUNT() bfin_read16(DMA1_8_Y_COUNT) +#define bfin_write_DMA1_8_Y_COUNT(val) bfin_write16(DMA1_8_Y_COUNT,val) +#define bfin_read_DMA1_8_X_MODIFY() bfin_read16(DMA1_8_X_MODIFY) +#define bfin_write_DMA1_8_X_MODIFY(val) bfin_write16(DMA1_8_X_MODIFY,val) +#define bfin_read_DMA1_8_Y_MODIFY() bfin_read16(DMA1_8_Y_MODIFY) +#define bfin_write_DMA1_8_Y_MODIFY(val) bfin_write16(DMA1_8_Y_MODIFY,val) +#define bfin_read_DMA1_8_CURR_DESC_PTR() bfin_read32(DMA1_8_CURR_DESC_PTR) +#define bfin_write_DMA1_8_CURR_DESC_PTR(val) bfin_write32(DMA1_8_CURR_DESC_PTR,val) +#define bfin_read_DMA1_8_CURR_ADDR() bfin_read32(DMA1_8_CURR_ADDR) +#define bfin_write_DMA1_8_CURR_ADDR(val) bfin_write32(DMA1_8_CURR_ADDR,val) +#define bfin_read_DMA1_8_CURR_X_COUNT() bfin_read16(DMA1_8_CURR_X_COUNT) +#define bfin_write_DMA1_8_CURR_X_COUNT(val) bfin_write16(DMA1_8_CURR_X_COUNT,val) +#define bfin_read_DMA1_8_CURR_Y_COUNT() bfin_read16(DMA1_8_CURR_Y_COUNT) +#define bfin_write_DMA1_8_CURR_Y_COUNT(val) bfin_write16(DMA1_8_CURR_Y_COUNT,val) +#define bfin_read_DMA1_8_IRQ_STATUS() bfin_read16(DMA1_8_IRQ_STATUS) +#define bfin_write_DMA1_8_IRQ_STATUS(val) bfin_write16(DMA1_8_IRQ_STATUS,val) +#define bfin_read_DMA1_8_PERIPHERAL_MAP() bfin_read16(DMA1_8_PERIPHERAL_MAP) +#define bfin_write_DMA1_8_PERIPHERAL_MAP(val) bfin_write16(DMA1_8_PERIPHERAL_MAP,val) +#define bfin_read_DMA1_9_CONFIG() bfin_read16(DMA1_9_CONFIG) +#define bfin_write_DMA1_9_CONFIG(val) bfin_write16(DMA1_9_CONFIG,val) +#define bfin_read_DMA1_9_NEXT_DESC_PTR() bfin_read32(DMA1_9_NEXT_DESC_PTR) +#define bfin_write_DMA1_9_NEXT_DESC_PTR(val) bfin_write32(DMA1_9_NEXT_DESC_PTR,val) +#define bfin_read_DMA1_9_START_ADDR() bfin_read32(DMA1_9_START_ADDR) +#define bfin_write_DMA1_9_START_ADDR(val) bfin_write32(DMA1_9_START_ADDR,val) +#define bfin_read_DMA1_9_X_COUNT() bfin_read16(DMA1_9_X_COUNT) +#define bfin_write_DMA1_9_X_COUNT(val) bfin_write16(DMA1_9_X_COUNT,val) +#define bfin_read_DMA1_9_Y_COUNT() bfin_read16(DMA1_9_Y_COUNT) +#define bfin_write_DMA1_9_Y_COUNT(val) bfin_write16(DMA1_9_Y_COUNT,val) +#define bfin_read_DMA1_9_X_MODIFY() bfin_read16(DMA1_9_X_MODIFY) +#define bfin_write_DMA1_9_X_MODIFY(val) bfin_write16(DMA1_9_X_MODIFY,val) +#define bfin_read_DMA1_9_Y_MODIFY() bfin_read16(DMA1_9_Y_MODIFY) +#define bfin_write_DMA1_9_Y_MODIFY(val) bfin_write16(DMA1_9_Y_MODIFY,val) +#define bfin_read_DMA1_9_CURR_DESC_PTR() bfin_read32(DMA1_9_CURR_DESC_PTR) +#define bfin_write_DMA1_9_CURR_DESC_PTR(val) bfin_write32(DMA1_9_CURR_DESC_PTR,val) +#define bfin_read_DMA1_9_CURR_ADDR() bfin_read32(DMA1_9_CURR_ADDR) +#define bfin_write_DMA1_9_CURR_ADDR(val) bfin_write32(DMA1_9_CURR_ADDR,val) +#define bfin_read_DMA1_9_CURR_X_COUNT() bfin_read16(DMA1_9_CURR_X_COUNT) +#define bfin_write_DMA1_9_CURR_X_COUNT(val) bfin_write16(DMA1_9_CURR_X_COUNT,val) +#define bfin_read_DMA1_9_CURR_Y_COUNT() bfin_read16(DMA1_9_CURR_Y_COUNT) +#define bfin_write_DMA1_9_CURR_Y_COUNT(val) bfin_write16(DMA1_9_CURR_Y_COUNT,val) +#define bfin_read_DMA1_9_IRQ_STATUS() bfin_read16(DMA1_9_IRQ_STATUS) +#define bfin_write_DMA1_9_IRQ_STATUS(val) bfin_write16(DMA1_9_IRQ_STATUS,val) +#define bfin_read_DMA1_9_PERIPHERAL_MAP() bfin_read16(DMA1_9_PERIPHERAL_MAP) +#define bfin_write_DMA1_9_PERIPHERAL_MAP(val) bfin_write16(DMA1_9_PERIPHERAL_MAP,val) +#define bfin_read_DMA1_10_CONFIG() bfin_read16(DMA1_10_CONFIG) +#define bfin_write_DMA1_10_CONFIG(val) bfin_write16(DMA1_10_CONFIG,val) +#define bfin_read_DMA1_10_NEXT_DESC_PTR() bfin_read32(DMA1_10_NEXT_DESC_PTR) +#define bfin_write_DMA1_10_NEXT_DESC_PTR(val) bfin_write32(DMA1_10_NEXT_DESC_PTR,val) +#define bfin_read_DMA1_10_START_ADDR() bfin_read32(DMA1_10_START_ADDR) +#define bfin_write_DMA1_10_START_ADDR(val) bfin_write32(DMA1_10_START_ADDR,val) +#define bfin_read_DMA1_10_X_COUNT() bfin_read16(DMA1_10_X_COUNT) +#define bfin_write_DMA1_10_X_COUNT(val) bfin_write16(DMA1_10_X_COUNT,val) +#define bfin_read_DMA1_10_Y_COUNT() bfin_read16(DMA1_10_Y_COUNT) +#define bfin_write_DMA1_10_Y_COUNT(val) bfin_write16(DMA1_10_Y_COUNT,val) +#define bfin_read_DMA1_10_X_MODIFY() bfin_read16(DMA1_10_X_MODIFY) +#define bfin_write_DMA1_10_X_MODIFY(val) bfin_write16(DMA1_10_X_MODIFY,val) +#define bfin_read_DMA1_10_Y_MODIFY() bfin_read16(DMA1_10_Y_MODIFY) +#define bfin_write_DMA1_10_Y_MODIFY(val) bfin_write16(DMA1_10_Y_MODIFY,val) +#define bfin_read_DMA1_10_CURR_DESC_PTR() bfin_read32(DMA1_10_CURR_DESC_PTR) +#define bfin_write_DMA1_10_CURR_DESC_PTR(val) bfin_write32(DMA1_10_CURR_DESC_PTR,val) +#define bfin_read_DMA1_10_CURR_ADDR() bfin_read32(DMA1_10_CURR_ADDR) +#define bfin_write_DMA1_10_CURR_ADDR(val) bfin_write32(DMA1_10_CURR_ADDR,val) +#define bfin_read_DMA1_10_CURR_X_COUNT() bfin_read16(DMA1_10_CURR_X_COUNT) +#define bfin_write_DMA1_10_CURR_X_COUNT(val) bfin_write16(DMA1_10_CURR_X_COUNT,val) +#define bfin_read_DMA1_10_CURR_Y_COUNT() bfin_read16(DMA1_10_CURR_Y_COUNT) +#define bfin_write_DMA1_10_CURR_Y_COUNT(val) bfin_write16(DMA1_10_CURR_Y_COUNT,val) +#define bfin_read_DMA1_10_IRQ_STATUS() bfin_read16(DMA1_10_IRQ_STATUS) +#define bfin_write_DMA1_10_IRQ_STATUS(val) bfin_write16(DMA1_10_IRQ_STATUS,val) +#define bfin_read_DMA1_10_PERIPHERAL_MAP() bfin_read16(DMA1_10_PERIPHERAL_MAP) +#define bfin_write_DMA1_10_PERIPHERAL_MAP(val) bfin_write16(DMA1_10_PERIPHERAL_MAP,val) +#define bfin_read_DMA1_11_CONFIG() bfin_read16(DMA1_11_CONFIG) +#define bfin_write_DMA1_11_CONFIG(val) bfin_write16(DMA1_11_CONFIG,val) +#define bfin_read_DMA1_11_NEXT_DESC_PTR() bfin_read32(DMA1_11_NEXT_DESC_PTR) +#define bfin_write_DMA1_11_NEXT_DESC_PTR(val) bfin_write32(DMA1_11_NEXT_DESC_PTR,val) +#define bfin_read_DMA1_11_START_ADDR() bfin_read32(DMA1_11_START_ADDR) +#define bfin_write_DMA1_11_START_ADDR(val) bfin_write32(DMA1_11_START_ADDR,val) +#define bfin_read_DMA1_11_X_COUNT() bfin_read16(DMA1_11_X_COUNT) +#define bfin_write_DMA1_11_X_COUNT(val) bfin_write16(DMA1_11_X_COUNT,val) +#define bfin_read_DMA1_11_Y_COUNT() bfin_read16(DMA1_11_Y_COUNT) +#define bfin_write_DMA1_11_Y_COUNT(val) bfin_write16(DMA1_11_Y_COUNT,val) +#define bfin_read_DMA1_11_X_MODIFY() bfin_read16(DMA1_11_X_MODIFY) +#define bfin_write_DMA1_11_X_MODIFY(val) bfin_write16(DMA1_11_X_MODIFY,val) +#define bfin_read_DMA1_11_Y_MODIFY() bfin_read16(DMA1_11_Y_MODIFY) +#define bfin_write_DMA1_11_Y_MODIFY(val) bfin_write16(DMA1_11_Y_MODIFY,val) +#define bfin_read_DMA1_11_CURR_DESC_PTR() bfin_read32(DMA1_11_CURR_DESC_PTR) +#define bfin_write_DMA1_11_CURR_DESC_PTR(val) bfin_write32(DMA1_11_CURR_DESC_PTR,val) +#define bfin_read_DMA1_11_CURR_ADDR() bfin_read32(DMA1_11_CURR_ADDR) +#define bfin_write_DMA1_11_CURR_ADDR(val) bfin_write32(DMA1_11_CURR_ADDR,val) +#define bfin_read_DMA1_11_CURR_X_COUNT() bfin_read16(DMA1_11_CURR_X_COUNT) +#define bfin_write_DMA1_11_CURR_X_COUNT(val) bfin_write16(DMA1_11_CURR_X_COUNT,val) +#define bfin_read_DMA1_11_CURR_Y_COUNT() bfin_read16(DMA1_11_CURR_Y_COUNT) +#define bfin_write_DMA1_11_CURR_Y_COUNT(val) bfin_write16(DMA1_11_CURR_Y_COUNT,val) +#define bfin_read_DMA1_11_IRQ_STATUS() bfin_read16(DMA1_11_IRQ_STATUS) +#define bfin_write_DMA1_11_IRQ_STATUS(val) bfin_write16(DMA1_11_IRQ_STATUS,val) +#define bfin_read_DMA1_11_PERIPHERAL_MAP() bfin_read16(DMA1_11_PERIPHERAL_MAP) +#define bfin_write_DMA1_11_PERIPHERAL_MAP(val) bfin_write16(DMA1_11_PERIPHERAL_MAP,val) +/* Memory DMA1 Controller registers (0xFFC0 1E80-0xFFC0 1FFF) */ +#define bfin_read_MDMA1_D0_CONFIG() bfin_read16(MDMA1_D0_CONFIG) +#define bfin_write_MDMA1_D0_CONFIG(val) bfin_write16(MDMA1_D0_CONFIG,val) +#define bfin_read_MDMA1_D0_NEXT_DESC_PTR() bfin_read32(MDMA1_D0_NEXT_DESC_PTR) +#define bfin_write_MDMA1_D0_NEXT_DESC_PTR(val) bfin_write32(MDMA1_D0_NEXT_DESC_PTR,val) +#define bfin_read_MDMA1_D0_START_ADDR() bfin_read32(MDMA1_D0_START_ADDR) +#define bfin_write_MDMA1_D0_START_ADDR(val) bfin_write32(MDMA1_D0_START_ADDR,val) +#define bfin_read_MDMA1_D0_X_COUNT() bfin_read16(MDMA1_D0_X_COUNT) +#define bfin_write_MDMA1_D0_X_COUNT(val) bfin_write16(MDMA1_D0_X_COUNT,val) +#define bfin_read_MDMA1_D0_Y_COUNT() bfin_read16(MDMA1_D0_Y_COUNT) +#define bfin_write_MDMA1_D0_Y_COUNT(val) bfin_write16(MDMA1_D0_Y_COUNT,val) +#define bfin_read_MDMA1_D0_X_MODIFY() bfin_read16(MDMA1_D0_X_MODIFY) +#define bfin_write_MDMA1_D0_X_MODIFY(val) bfin_write16(MDMA1_D0_X_MODIFY,val) +#define bfin_read_MDMA1_D0_Y_MODIFY() bfin_read16(MDMA1_D0_Y_MODIFY) +#define bfin_write_MDMA1_D0_Y_MODIFY(val) bfin_write16(MDMA1_D0_Y_MODIFY,val) +#define bfin_read_MDMA1_D0_CURR_DESC_PTR() bfin_read32(MDMA1_D0_CURR_DESC_PTR) +#define bfin_write_MDMA1_D0_CURR_DESC_PTR(val) bfin_write32(MDMA1_D0_CURR_DESC_PTR,val) +#define bfin_read_MDMA1_D0_CURR_ADDR() bfin_read32(MDMA1_D0_CURR_ADDR) +#define bfin_write_MDMA1_D0_CURR_ADDR(val) bfin_write32(MDMA1_D0_CURR_ADDR,val) +#define bfin_read_MDMA1_D0_CURR_X_COUNT() bfin_read16(MDMA1_D0_CURR_X_COUNT) +#define bfin_write_MDMA1_D0_CURR_X_COUNT(val) bfin_write16(MDMA1_D0_CURR_X_COUNT,val) +#define bfin_read_MDMA1_D0_CURR_Y_COUNT() bfin_read16(MDMA1_D0_CURR_Y_COUNT) +#define bfin_write_MDMA1_D0_CURR_Y_COUNT(val) bfin_write16(MDMA1_D0_CURR_Y_COUNT,val) +#define bfin_read_MDMA1_D0_IRQ_STATUS() bfin_read16(MDMA1_D0_IRQ_STATUS) +#define bfin_write_MDMA1_D0_IRQ_STATUS(val) bfin_write16(MDMA1_D0_IRQ_STATUS,val) +#define bfin_read_MDMA1_D0_PERIPHERAL_MAP() bfin_read16(MDMA1_D0_PERIPHERAL_MAP) +#define bfin_write_MDMA1_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA1_D0_PERIPHERAL_MAP,val) +#define bfin_read_MDMA1_S0_CONFIG() bfin_read16(MDMA1_S0_CONFIG) +#define bfin_write_MDMA1_S0_CONFIG(val) bfin_write16(MDMA1_S0_CONFIG,val) +#define bfin_read_MDMA1_S0_NEXT_DESC_PTR() bfin_read32(MDMA1_S0_NEXT_DESC_PTR) +#define bfin_write_MDMA1_S0_NEXT_DESC_PTR(val) bfin_write32(MDMA1_S0_NEXT_DESC_PTR,val) +#define bfin_read_MDMA1_S0_START_ADDR() bfin_read32(MDMA1_S0_START_ADDR) +#define bfin_write_MDMA1_S0_START_ADDR(val) bfin_write32(MDMA1_S0_START_ADDR,val) +#define bfin_read_MDMA1_S0_X_COUNT() bfin_read16(MDMA1_S0_X_COUNT) +#define bfin_write_MDMA1_S0_X_COUNT(val) bfin_write16(MDMA1_S0_X_COUNT,val) +#define bfin_read_MDMA1_S0_Y_COUNT() bfin_read16(MDMA1_S0_Y_COUNT) +#define bfin_write_MDMA1_S0_Y_COUNT(val) bfin_write16(MDMA1_S0_Y_COUNT,val) +#define bfin_read_MDMA1_S0_X_MODIFY() bfin_read16(MDMA1_S0_X_MODIFY) +#define bfin_write_MDMA1_S0_X_MODIFY(val) bfin_write16(MDMA1_S0_X_MODIFY,val) +#define bfin_read_MDMA1_S0_Y_MODIFY() bfin_read16(MDMA1_S0_Y_MODIFY) +#define bfin_write_MDMA1_S0_Y_MODIFY(val) bfin_write16(MDMA1_S0_Y_MODIFY,val) +#define bfin_read_MDMA1_S0_CURR_DESC_PTR() bfin_read32(MDMA1_S0_CURR_DESC_PTR) +#define bfin_write_MDMA1_S0_CURR_DESC_PTR(val) bfin_write32(MDMA1_S0_CURR_DESC_PTR,val) +#define bfin_read_MDMA1_S0_CURR_ADDR() bfin_read32(MDMA1_S0_CURR_ADDR) +#define bfin_write_MDMA1_S0_CURR_ADDR(val) bfin_write32(MDMA1_S0_CURR_ADDR,val) +#define bfin_read_MDMA1_S0_CURR_X_COUNT() bfin_read16(MDMA1_S0_CURR_X_COUNT) +#define bfin_write_MDMA1_S0_CURR_X_COUNT(val) bfin_write16(MDMA1_S0_CURR_X_COUNT,val) +#define bfin_read_MDMA1_S0_CURR_Y_COUNT() bfin_read16(MDMA1_S0_CURR_Y_COUNT) +#define bfin_write_MDMA1_S0_CURR_Y_COUNT(val) bfin_write16(MDMA1_S0_CURR_Y_COUNT,val) +#define bfin_read_MDMA1_S0_IRQ_STATUS() bfin_read16(MDMA1_S0_IRQ_STATUS) +#define bfin_write_MDMA1_S0_IRQ_STATUS(val) bfin_write16(MDMA1_S0_IRQ_STATUS,val) +#define bfin_read_MDMA1_S0_PERIPHERAL_MAP() bfin_read16(MDMA1_S0_PERIPHERAL_MAP) +#define bfin_write_MDMA1_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA1_S0_PERIPHERAL_MAP,val) +#define bfin_read_MDMA1_D1_CONFIG() bfin_read16(MDMA1_D1_CONFIG) +#define bfin_write_MDMA1_D1_CONFIG(val) bfin_write16(MDMA1_D1_CONFIG,val) +#define bfin_read_MDMA1_D1_NEXT_DESC_PTR() bfin_read32(MDMA1_D1_NEXT_DESC_PTR) +#define bfin_write_MDMA1_D1_NEXT_DESC_PTR(val) bfin_write32(MDMA1_D1_NEXT_DESC_PTR,val) +#define bfin_read_MDMA1_D1_START_ADDR() bfin_read32(MDMA1_D1_START_ADDR) +#define bfin_write_MDMA1_D1_START_ADDR(val) bfin_write32(MDMA1_D1_START_ADDR,val) +#define bfin_read_MDMA1_D1_X_COUNT() bfin_read16(MDMA1_D1_X_COUNT) +#define bfin_write_MDMA1_D1_X_COUNT(val) bfin_write16(MDMA1_D1_X_COUNT,val) +#define bfin_read_MDMA1_D1_Y_COUNT() bfin_read16(MDMA1_D1_Y_COUNT) +#define bfin_write_MDMA1_D1_Y_COUNT(val) bfin_write16(MDMA1_D1_Y_COUNT,val) +#define bfin_read_MDMA1_D1_X_MODIFY() bfin_read16(MDMA1_D1_X_MODIFY) +#define bfin_write_MDMA1_D1_X_MODIFY(val) bfin_write16(MDMA1_D1_X_MODIFY,val) +#define bfin_read_MDMA1_D1_Y_MODIFY() bfin_read16(MDMA1_D1_Y_MODIFY) +#define bfin_write_MDMA1_D1_Y_MODIFY(val) bfin_write16(MDMA1_D1_Y_MODIFY,val) +#define bfin_read_MDMA1_D1_CURR_DESC_PTR() bfin_read32(MDMA1_D1_CURR_DESC_PTR) +#define bfin_write_MDMA1_D1_CURR_DESC_PTR(val) bfin_write32(MDMA1_D1_CURR_DESC_PTR,val) +#define bfin_read_MDMA1_D1_CURR_ADDR() bfin_read32(MDMA1_D1_CURR_ADDR) +#define bfin_write_MDMA1_D1_CURR_ADDR(val) bfin_write32(MDMA1_D1_CURR_ADDR,val) +#define bfin_read_MDMA1_D1_CURR_X_COUNT() bfin_read16(MDMA1_D1_CURR_X_COUNT) +#define bfin_write_MDMA1_D1_CURR_X_COUNT(val) bfin_write16(MDMA1_D1_CURR_X_COUNT,val) +#define bfin_read_MDMA1_D1_CURR_Y_COUNT() bfin_read16(MDMA1_D1_CURR_Y_COUNT) +#define bfin_write_MDMA1_D1_CURR_Y_COUNT(val) bfin_write16(MDMA1_D1_CURR_Y_COUNT,val) +#define bfin_read_MDMA1_D1_IRQ_STATUS() bfin_read16(MDMA1_D1_IRQ_STATUS) +#define bfin_write_MDMA1_D1_IRQ_STATUS(val) bfin_write16(MDMA1_D1_IRQ_STATUS,val) +#define bfin_read_MDMA1_D1_PERIPHERAL_MAP() bfin_read16(MDMA1_D1_PERIPHERAL_MAP) +#define bfin_write_MDMA1_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA1_D1_PERIPHERAL_MAP,val) +#define bfin_read_MDMA1_S1_CONFIG() bfin_read16(MDMA1_S1_CONFIG) +#define bfin_write_MDMA1_S1_CONFIG(val) bfin_write16(MDMA1_S1_CONFIG,val) +#define bfin_read_MDMA1_S1_NEXT_DESC_PTR() bfin_read32(MDMA1_S1_NEXT_DESC_PTR) +#define bfin_write_MDMA1_S1_NEXT_DESC_PTR(val) bfin_write32(MDMA1_S1_NEXT_DESC_PTR,val) +#define bfin_read_MDMA1_S1_START_ADDR() bfin_read32(MDMA1_S1_START_ADDR) +#define bfin_write_MDMA1_S1_START_ADDR(val) bfin_write32(MDMA1_S1_START_ADDR,val) +#define bfin_read_MDMA1_S1_X_COUNT() bfin_read16(MDMA1_S1_X_COUNT) +#define bfin_write_MDMA1_S1_X_COUNT(val) bfin_write16(MDMA1_S1_X_COUNT,val) +#define bfin_read_MDMA1_S1_Y_COUNT() bfin_read16(MDMA1_S1_Y_COUNT) +#define bfin_write_MDMA1_S1_Y_COUNT(val) bfin_write16(MDMA1_S1_Y_COUNT,val) +#define bfin_read_MDMA1_S1_X_MODIFY() bfin_read16(MDMA1_S1_X_MODIFY) +#define bfin_write_MDMA1_S1_X_MODIFY(val) bfin_write16(MDMA1_S1_X_MODIFY,val) +#define bfin_read_MDMA1_S1_Y_MODIFY() bfin_read16(MDMA1_S1_Y_MODIFY) +#define bfin_write_MDMA1_S1_Y_MODIFY(val) bfin_write16(MDMA1_S1_Y_MODIFY,val) +#define bfin_read_MDMA1_S1_CURR_DESC_PTR() bfin_read32(MDMA1_S1_CURR_DESC_PTR) +#define bfin_write_MDMA1_S1_CURR_DESC_PTR(val) bfin_write32(MDMA1_S1_CURR_DESC_PTR,val) +#define bfin_read_MDMA1_S1_CURR_ADDR() bfin_read32(MDMA1_S1_CURR_ADDR) +#define bfin_write_MDMA1_S1_CURR_ADDR(val) bfin_write32(MDMA1_S1_CURR_ADDR,val) +#define bfin_read_MDMA1_S1_CURR_X_COUNT() bfin_read16(MDMA1_S1_CURR_X_COUNT) +#define bfin_write_MDMA1_S1_CURR_X_COUNT(val) bfin_write16(MDMA1_S1_CURR_X_COUNT,val) +#define bfin_read_MDMA1_S1_CURR_Y_COUNT() bfin_read16(MDMA1_S1_CURR_Y_COUNT) +#define bfin_write_MDMA1_S1_CURR_Y_COUNT(val) bfin_write16(MDMA1_S1_CURR_Y_COUNT,val) +#define bfin_read_MDMA1_S1_IRQ_STATUS() bfin_read16(MDMA1_S1_IRQ_STATUS) +#define bfin_write_MDMA1_S1_IRQ_STATUS(val) bfin_write16(MDMA1_S1_IRQ_STATUS,val) +#define bfin_read_MDMA1_S1_PERIPHERAL_MAP() bfin_read16(MDMA1_S1_PERIPHERAL_MAP) +#define bfin_write_MDMA1_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA1_S1_PERIPHERAL_MAP,val) +/* DMA2 Controller registers (0xFFC0 0C00-0xFFC0 0DFF) */ +#define bfin_read_DMA2_0_CONFIG() bfin_read16(DMA2_0_CONFIG) +#define bfin_write_DMA2_0_CONFIG(val) bfin_write16(DMA2_0_CONFIG,val) +#define bfin_read_DMA2_0_NEXT_DESC_PTR() bfin_read32(DMA2_0_NEXT_DESC_PTR) +#define bfin_write_DMA2_0_NEXT_DESC_PTR(val) bfin_write32(DMA2_0_NEXT_DESC_PTR,val) +#define bfin_read_DMA2_0_START_ADDR() bfin_read32(DMA2_0_START_ADDR) +#define bfin_write_DMA2_0_START_ADDR(val) bfin_write32(DMA2_0_START_ADDR,val) +#define bfin_read_DMA2_0_X_COUNT() bfin_read16(DMA2_0_X_COUNT) +#define bfin_write_DMA2_0_X_COUNT(val) bfin_write16(DMA2_0_X_COUNT,val) +#define bfin_read_DMA2_0_Y_COUNT() bfin_read16(DMA2_0_Y_COUNT) +#define bfin_write_DMA2_0_Y_COUNT(val) bfin_write16(DMA2_0_Y_COUNT,val) +#define bfin_read_DMA2_0_X_MODIFY() bfin_read16(DMA2_0_X_MODIFY) +#define bfin_write_DMA2_0_X_MODIFY(val) bfin_write16(DMA2_0_X_MODIFY,val) +#define bfin_read_DMA2_0_Y_MODIFY() bfin_read16(DMA2_0_Y_MODIFY) +#define bfin_write_DMA2_0_Y_MODIFY(val) bfin_write16(DMA2_0_Y_MODIFY,val) +#define bfin_read_DMA2_0_CURR_DESC_PTR() bfin_read32(DMA2_0_CURR_DESC_PTR) +#define bfin_write_DMA2_0_CURR_DESC_PTR(val) bfin_write32(DMA2_0_CURR_DESC_PTR,val) +#define bfin_read_DMA2_0_CURR_ADDR() bfin_read32(DMA2_0_CURR_ADDR) +#define bfin_write_DMA2_0_CURR_ADDR(val) bfin_write32(DMA2_0_CURR_ADDR,val) +#define bfin_read_DMA2_0_CURR_X_COUNT() bfin_read16(DMA2_0_CURR_X_COUNT) +#define bfin_write_DMA2_0_CURR_X_COUNT(val) bfin_write16(DMA2_0_CURR_X_COUNT,val) +#define bfin_read_DMA2_0_CURR_Y_COUNT() bfin_read16(DMA2_0_CURR_Y_COUNT) +#define bfin_write_DMA2_0_CURR_Y_COUNT(val) bfin_write16(DMA2_0_CURR_Y_COUNT,val) +#define bfin_read_DMA2_0_IRQ_STATUS() bfin_read16(DMA2_0_IRQ_STATUS) +#define bfin_write_DMA2_0_IRQ_STATUS(val) bfin_write16(DMA2_0_IRQ_STATUS,val) +#define bfin_read_DMA2_0_PERIPHERAL_MAP() bfin_read16(DMA2_0_PERIPHERAL_MAP) +#define bfin_write_DMA2_0_PERIPHERAL_MAP(val) bfin_write16(DMA2_0_PERIPHERAL_MAP,val) +#define bfin_read_DMA2_1_CONFIG() bfin_read16(DMA2_1_CONFIG) +#define bfin_write_DMA2_1_CONFIG(val) bfin_write16(DMA2_1_CONFIG,val) +#define bfin_read_DMA2_1_NEXT_DESC_PTR() bfin_read32(DMA2_1_NEXT_DESC_PTR) +#define bfin_write_DMA2_1_NEXT_DESC_PTR(val) bfin_write32(DMA2_1_NEXT_DESC_PTR,val) +#define bfin_read_DMA2_1_START_ADDR() bfin_read32(DMA2_1_START_ADDR) +#define bfin_write_DMA2_1_START_ADDR(val) bfin_write32(DMA2_1_START_ADDR,val) +#define bfin_read_DMA2_1_X_COUNT() bfin_read16(DMA2_1_X_COUNT) +#define bfin_write_DMA2_1_X_COUNT(val) bfin_write16(DMA2_1_X_COUNT,val) +#define bfin_read_DMA2_1_Y_COUNT() bfin_read16(DMA2_1_Y_COUNT) +#define bfin_write_DMA2_1_Y_COUNT(val) bfin_write16(DMA2_1_Y_COUNT,val) +#define bfin_read_DMA2_1_X_MODIFY() bfin_read16(DMA2_1_X_MODIFY) +#define bfin_write_DMA2_1_X_MODIFY(val) bfin_write16(DMA2_1_X_MODIFY,val) +#define bfin_read_DMA2_1_Y_MODIFY() bfin_read16(DMA2_1_Y_MODIFY) +#define bfin_write_DMA2_1_Y_MODIFY(val) bfin_write16(DMA2_1_Y_MODIFY,val) +#define bfin_read_DMA2_1_CURR_DESC_PTR() bfin_read32(DMA2_1_CURR_DESC_PTR) +#define bfin_write_DMA2_1_CURR_DESC_PTR(val) bfin_write32(DMA2_1_CURR_DESC_PTR,val) +#define bfin_read_DMA2_1_CURR_ADDR() bfin_read32(DMA2_1_CURR_ADDR) +#define bfin_write_DMA2_1_CURR_ADDR(val) bfin_write32(DMA2_1_CURR_ADDR,val) +#define bfin_read_DMA2_1_CURR_X_COUNT() bfin_read16(DMA2_1_CURR_X_COUNT) +#define bfin_write_DMA2_1_CURR_X_COUNT(val) bfin_write16(DMA2_1_CURR_X_COUNT,val) +#define bfin_read_DMA2_1_CURR_Y_COUNT() bfin_read16(DMA2_1_CURR_Y_COUNT) +#define bfin_write_DMA2_1_CURR_Y_COUNT(val) bfin_write16(DMA2_1_CURR_Y_COUNT,val) +#define bfin_read_DMA2_1_IRQ_STATUS() bfin_read16(DMA2_1_IRQ_STATUS) +#define bfin_write_DMA2_1_IRQ_STATUS(val) bfin_write16(DMA2_1_IRQ_STATUS,val) +#define bfin_read_DMA2_1_PERIPHERAL_MAP() bfin_read16(DMA2_1_PERIPHERAL_MAP) +#define bfin_write_DMA2_1_PERIPHERAL_MAP(val) bfin_write16(DMA2_1_PERIPHERAL_MAP,val) +#define bfin_read_DMA2_2_CONFIG() bfin_read16(DMA2_2_CONFIG) +#define bfin_write_DMA2_2_CONFIG(val) bfin_write16(DMA2_2_CONFIG,val) +#define bfin_read_DMA2_2_NEXT_DESC_PTR() bfin_read32(DMA2_2_NEXT_DESC_PTR) +#define bfin_write_DMA2_2_NEXT_DESC_PTR(val) bfin_write32(DMA2_2_NEXT_DESC_PTR,val) +#define bfin_read_DMA2_2_START_ADDR() bfin_read32(DMA2_2_START_ADDR) +#define bfin_write_DMA2_2_START_ADDR(val) bfin_write32(DMA2_2_START_ADDR,val) +#define bfin_read_DMA2_2_X_COUNT() bfin_read16(DMA2_2_X_COUNT) +#define bfin_write_DMA2_2_X_COUNT(val) bfin_write16(DMA2_2_X_COUNT,val) +#define bfin_read_DMA2_2_Y_COUNT() bfin_read16(DMA2_2_Y_COUNT) +#define bfin_write_DMA2_2_Y_COUNT(val) bfin_write16(DMA2_2_Y_COUNT,val) +#define bfin_read_DMA2_2_X_MODIFY() bfin_read16(DMA2_2_X_MODIFY) +#define bfin_write_DMA2_2_X_MODIFY(val) bfin_write16(DMA2_2_X_MODIFY,val) +#define bfin_read_DMA2_2_Y_MODIFY() bfin_read16(DMA2_2_Y_MODIFY) +#define bfin_write_DMA2_2_Y_MODIFY(val) bfin_write16(DMA2_2_Y_MODIFY,val) +#define bfin_read_DMA2_2_CURR_DESC_PTR() bfin_read32(DMA2_2_CURR_DESC_PTR) +#define bfin_write_DMA2_2_CURR_DESC_PTR(val) bfin_write32(DMA2_2_CURR_DESC_PTR,val) +#define bfin_read_DMA2_2_CURR_ADDR() bfin_read32(DMA2_2_CURR_ADDR) +#define bfin_write_DMA2_2_CURR_ADDR(val) bfin_write32(DMA2_2_CURR_ADDR,val) +#define bfin_read_DMA2_2_CURR_X_COUNT() bfin_read16(DMA2_2_CURR_X_COUNT) +#define bfin_write_DMA2_2_CURR_X_COUNT(val) bfin_write16(DMA2_2_CURR_X_COUNT,val) +#define bfin_read_DMA2_2_CURR_Y_COUNT() bfin_read16(DMA2_2_CURR_Y_COUNT) +#define bfin_write_DMA2_2_CURR_Y_COUNT(val) bfin_write16(DMA2_2_CURR_Y_COUNT,val) +#define bfin_read_DMA2_2_IRQ_STATUS() bfin_read16(DMA2_2_IRQ_STATUS) +#define bfin_write_DMA2_2_IRQ_STATUS(val) bfin_write16(DMA2_2_IRQ_STATUS,val) +#define bfin_read_DMA2_2_PERIPHERAL_MAP() bfin_read16(DMA2_2_PERIPHERAL_MAP) +#define bfin_write_DMA2_2_PERIPHERAL_MAP(val) bfin_write16(DMA2_2_PERIPHERAL_MAP,val) +#define bfin_read_DMA2_3_CONFIG() bfin_read16(DMA2_3_CONFIG) +#define bfin_write_DMA2_3_CONFIG(val) bfin_write16(DMA2_3_CONFIG,val) +#define bfin_read_DMA2_3_NEXT_DESC_PTR() bfin_read32(DMA2_3_NEXT_DESC_PTR) +#define bfin_write_DMA2_3_NEXT_DESC_PTR(val) bfin_write32(DMA2_3_NEXT_DESC_PTR,val) +#define bfin_read_DMA2_3_START_ADDR() bfin_read32(DMA2_3_START_ADDR) +#define bfin_write_DMA2_3_START_ADDR(val) bfin_write32(DMA2_3_START_ADDR,val) +#define bfin_read_DMA2_3_X_COUNT() bfin_read16(DMA2_3_X_COUNT) +#define bfin_write_DMA2_3_X_COUNT(val) bfin_write16(DMA2_3_X_COUNT,val) +#define bfin_read_DMA2_3_Y_COUNT() bfin_read16(DMA2_3_Y_COUNT) +#define bfin_write_DMA2_3_Y_COUNT(val) bfin_write16(DMA2_3_Y_COUNT,val) +#define bfin_read_DMA2_3_X_MODIFY() bfin_read16(DMA2_3_X_MODIFY) +#define bfin_write_DMA2_3_X_MODIFY(val) bfin_write16(DMA2_3_X_MODIFY,val) +#define bfin_read_DMA2_3_Y_MODIFY() bfin_read16(DMA2_3_Y_MODIFY) +#define bfin_write_DMA2_3_Y_MODIFY(val) bfin_write16(DMA2_3_Y_MODIFY,val) +#define bfin_read_DMA2_3_CURR_DESC_PTR() bfin_read32(DMA2_3_CURR_DESC_PTR) +#define bfin_write_DMA2_3_CURR_DESC_PTR(val) bfin_write32(DMA2_3_CURR_DESC_PTR,val) +#define bfin_read_DMA2_3_CURR_ADDR() bfin_read32(DMA2_3_CURR_ADDR) +#define bfin_write_DMA2_3_CURR_ADDR(val) bfin_write32(DMA2_3_CURR_ADDR,val) +#define bfin_read_DMA2_3_CURR_X_COUNT() bfin_read16(DMA2_3_CURR_X_COUNT) +#define bfin_write_DMA2_3_CURR_X_COUNT(val) bfin_write16(DMA2_3_CURR_X_COUNT,val) +#define bfin_read_DMA2_3_CURR_Y_COUNT() bfin_read16(DMA2_3_CURR_Y_COUNT) +#define bfin_write_DMA2_3_CURR_Y_COUNT(val) bfin_write16(DMA2_3_CURR_Y_COUNT,val) +#define bfin_read_DMA2_3_IRQ_STATUS() bfin_read16(DMA2_3_IRQ_STATUS) +#define bfin_write_DMA2_3_IRQ_STATUS(val) bfin_write16(DMA2_3_IRQ_STATUS,val) +#define bfin_read_DMA2_3_PERIPHERAL_MAP() bfin_read16(DMA2_3_PERIPHERAL_MAP) +#define bfin_write_DMA2_3_PERIPHERAL_MAP(val) bfin_write16(DMA2_3_PERIPHERAL_MAP,val) +#define bfin_read_DMA2_4_CONFIG() bfin_read16(DMA2_4_CONFIG) +#define bfin_write_DMA2_4_CONFIG(val) bfin_write16(DMA2_4_CONFIG,val) +#define bfin_read_DMA2_4_NEXT_DESC_PTR() bfin_read32(DMA2_4_NEXT_DESC_PTR) +#define bfin_write_DMA2_4_NEXT_DESC_PTR(val) bfin_write32(DMA2_4_NEXT_DESC_PTR,val) +#define bfin_read_DMA2_4_START_ADDR() bfin_read32(DMA2_4_START_ADDR) +#define bfin_write_DMA2_4_START_ADDR(val) bfin_write32(DMA2_4_START_ADDR,val) +#define bfin_read_DMA2_4_X_COUNT() bfin_read16(DMA2_4_X_COUNT) +#define bfin_write_DMA2_4_X_COUNT(val) bfin_write16(DMA2_4_X_COUNT,val) +#define bfin_read_DMA2_4_Y_COUNT() bfin_read16(DMA2_4_Y_COUNT) +#define bfin_write_DMA2_4_Y_COUNT(val) bfin_write16(DMA2_4_Y_COUNT,val) +#define bfin_read_DMA2_4_X_MODIFY() bfin_read16(DMA2_4_X_MODIFY) +#define bfin_write_DMA2_4_X_MODIFY(val) bfin_write16(DMA2_4_X_MODIFY,val) +#define bfin_read_DMA2_4_Y_MODIFY() bfin_read16(DMA2_4_Y_MODIFY) +#define bfin_write_DMA2_4_Y_MODIFY(val) bfin_write16(DMA2_4_Y_MODIFY,val) +#define bfin_read_DMA2_4_CURR_DESC_PTR() bfin_read32(DMA2_4_CURR_DESC_PTR) +#define bfin_write_DMA2_4_CURR_DESC_PTR(val) bfin_write32(DMA2_4_CURR_DESC_PTR,val) +#define bfin_read_DMA2_4_CURR_ADDR() bfin_read32(DMA2_4_CURR_ADDR) +#define bfin_write_DMA2_4_CURR_ADDR(val) bfin_write32(DMA2_4_CURR_ADDR,val) +#define bfin_read_DMA2_4_CURR_X_COUNT() bfin_read16(DMA2_4_CURR_X_COUNT) +#define bfin_write_DMA2_4_CURR_X_COUNT(val) bfin_write16(DMA2_4_CURR_X_COUNT,val) +#define bfin_read_DMA2_4_CURR_Y_COUNT() bfin_read16(DMA2_4_CURR_Y_COUNT) +#define bfin_write_DMA2_4_CURR_Y_COUNT(val) bfin_write16(DMA2_4_CURR_Y_COUNT,val) +#define bfin_read_DMA2_4_IRQ_STATUS() bfin_read16(DMA2_4_IRQ_STATUS) +#define bfin_write_DMA2_4_IRQ_STATUS(val) bfin_write16(DMA2_4_IRQ_STATUS,val) +#define bfin_read_DMA2_4_PERIPHERAL_MAP() bfin_read16(DMA2_4_PERIPHERAL_MAP) +#define bfin_write_DMA2_4_PERIPHERAL_MAP(val) bfin_write16(DMA2_4_PERIPHERAL_MAP,val) +#define bfin_read_DMA2_5_CONFIG() bfin_read16(DMA2_5_CONFIG) +#define bfin_write_DMA2_5_CONFIG(val) bfin_write16(DMA2_5_CONFIG,val) +#define bfin_read_DMA2_5_NEXT_DESC_PTR() bfin_read32(DMA2_5_NEXT_DESC_PTR) +#define bfin_write_DMA2_5_NEXT_DESC_PTR(val) bfin_write32(DMA2_5_NEXT_DESC_PTR,val) +#define bfin_read_DMA2_5_START_ADDR() bfin_read32(DMA2_5_START_ADDR) +#define bfin_write_DMA2_5_START_ADDR(val) bfin_write32(DMA2_5_START_ADDR,val) +#define bfin_read_DMA2_5_X_COUNT() bfin_read16(DMA2_5_X_COUNT) +#define bfin_write_DMA2_5_X_COUNT(val) bfin_write16(DMA2_5_X_COUNT,val) +#define bfin_read_DMA2_5_Y_COUNT() bfin_read16(DMA2_5_Y_COUNT) +#define bfin_write_DMA2_5_Y_COUNT(val) bfin_write16(DMA2_5_Y_COUNT,val) +#define bfin_read_DMA2_5_X_MODIFY() bfin_read16(DMA2_5_X_MODIFY) +#define bfin_write_DMA2_5_X_MODIFY(val) bfin_write16(DMA2_5_X_MODIFY,val) +#define bfin_read_DMA2_5_Y_MODIFY() bfin_read16(DMA2_5_Y_MODIFY) +#define bfin_write_DMA2_5_Y_MODIFY(val) bfin_write16(DMA2_5_Y_MODIFY,val) +#define bfin_read_DMA2_5_CURR_DESC_PTR() bfin_read32(DMA2_5_CURR_DESC_PTR) +#define bfin_write_DMA2_5_CURR_DESC_PTR(val) bfin_write32(DMA2_5_CURR_DESC_PTR,val) +#define bfin_read_DMA2_5_CURR_ADDR() bfin_read32(DMA2_5_CURR_ADDR) +#define bfin_write_DMA2_5_CURR_ADDR(val) bfin_write32(DMA2_5_CURR_ADDR,val) +#define bfin_read_DMA2_5_CURR_X_COUNT() bfin_read16(DMA2_5_CURR_X_COUNT) +#define bfin_write_DMA2_5_CURR_X_COUNT(val) bfin_write16(DMA2_5_CURR_X_COUNT,val) +#define bfin_read_DMA2_5_CURR_Y_COUNT() bfin_read16(DMA2_5_CURR_Y_COUNT) +#define bfin_write_DMA2_5_CURR_Y_COUNT(val) bfin_write16(DMA2_5_CURR_Y_COUNT,val) +#define bfin_read_DMA2_5_IRQ_STATUS() bfin_read16(DMA2_5_IRQ_STATUS) +#define bfin_write_DMA2_5_IRQ_STATUS(val) bfin_write16(DMA2_5_IRQ_STATUS,val) +#define bfin_read_DMA2_5_PERIPHERAL_MAP() bfin_read16(DMA2_5_PERIPHERAL_MAP) +#define bfin_write_DMA2_5_PERIPHERAL_MAP(val) bfin_write16(DMA2_5_PERIPHERAL_MAP,val) +#define bfin_read_DMA2_6_CONFIG() bfin_read16(DMA2_6_CONFIG) +#define bfin_write_DMA2_6_CONFIG(val) bfin_write16(DMA2_6_CONFIG,val) +#define bfin_read_DMA2_6_NEXT_DESC_PTR() bfin_read32(DMA2_6_NEXT_DESC_PTR) +#define bfin_write_DMA2_6_NEXT_DESC_PTR(val) bfin_write32(DMA2_6_NEXT_DESC_PTR,val) +#define bfin_read_DMA2_6_START_ADDR() bfin_read32(DMA2_6_START_ADDR) +#define bfin_write_DMA2_6_START_ADDR(val) bfin_write32(DMA2_6_START_ADDR,val) +#define bfin_read_DMA2_6_X_COUNT() bfin_read16(DMA2_6_X_COUNT) +#define bfin_write_DMA2_6_X_COUNT(val) bfin_write16(DMA2_6_X_COUNT,val) +#define bfin_read_DMA2_6_Y_COUNT() bfin_read16(DMA2_6_Y_COUNT) +#define bfin_write_DMA2_6_Y_COUNT(val) bfin_write16(DMA2_6_Y_COUNT,val) +#define bfin_read_DMA2_6_X_MODIFY() bfin_read16(DMA2_6_X_MODIFY) +#define bfin_write_DMA2_6_X_MODIFY(val) bfin_write16(DMA2_6_X_MODIFY,val) +#define bfin_read_DMA2_6_Y_MODIFY() bfin_read16(DMA2_6_Y_MODIFY) +#define bfin_write_DMA2_6_Y_MODIFY(val) bfin_write16(DMA2_6_Y_MODIFY,val) +#define bfin_read_DMA2_6_CURR_DESC_PTR() bfin_read32(DMA2_6_CURR_DESC_PTR) +#define bfin_write_DMA2_6_CURR_DESC_PTR(val) bfin_write32(DMA2_6_CURR_DESC_PTR,val) +#define bfin_read_DMA2_6_CURR_ADDR() bfin_read32(DMA2_6_CURR_ADDR) +#define bfin_write_DMA2_6_CURR_ADDR(val) bfin_write32(DMA2_6_CURR_ADDR,val) +#define bfin_read_DMA2_6_CURR_X_COUNT() bfin_read16(DMA2_6_CURR_X_COUNT) +#define bfin_write_DMA2_6_CURR_X_COUNT(val) bfin_write16(DMA2_6_CURR_X_COUNT,val) +#define bfin_read_DMA2_6_CURR_Y_COUNT() bfin_read16(DMA2_6_CURR_Y_COUNT) +#define bfin_write_DMA2_6_CURR_Y_COUNT(val) bfin_write16(DMA2_6_CURR_Y_COUNT,val) +#define bfin_read_DMA2_6_IRQ_STATUS() bfin_read16(DMA2_6_IRQ_STATUS) +#define bfin_write_DMA2_6_IRQ_STATUS(val) bfin_write16(DMA2_6_IRQ_STATUS,val) +#define bfin_read_DMA2_6_PERIPHERAL_MAP() bfin_read16(DMA2_6_PERIPHERAL_MAP) +#define bfin_write_DMA2_6_PERIPHERAL_MAP(val) bfin_write16(DMA2_6_PERIPHERAL_MAP,val) +#define bfin_read_DMA2_7_CONFIG() bfin_read16(DMA2_7_CONFIG) +#define bfin_write_DMA2_7_CONFIG(val) bfin_write16(DMA2_7_CONFIG,val) +#define bfin_read_DMA2_7_NEXT_DESC_PTR() bfin_read32(DMA2_7_NEXT_DESC_PTR) +#define bfin_write_DMA2_7_NEXT_DESC_PTR(val) bfin_write32(DMA2_7_NEXT_DESC_PTR,val) +#define bfin_read_DMA2_7_START_ADDR() bfin_read32(DMA2_7_START_ADDR) +#define bfin_write_DMA2_7_START_ADDR(val) bfin_write32(DMA2_7_START_ADDR,val) +#define bfin_read_DMA2_7_X_COUNT() bfin_read16(DMA2_7_X_COUNT) +#define bfin_write_DMA2_7_X_COUNT(val) bfin_write16(DMA2_7_X_COUNT,val) +#define bfin_read_DMA2_7_Y_COUNT() bfin_read16(DMA2_7_Y_COUNT) +#define bfin_write_DMA2_7_Y_COUNT(val) bfin_write16(DMA2_7_Y_COUNT,val) +#define bfin_read_DMA2_7_X_MODIFY() bfin_read16(DMA2_7_X_MODIFY) +#define bfin_write_DMA2_7_X_MODIFY(val) bfin_write16(DMA2_7_X_MODIFY,val) +#define bfin_read_DMA2_7_Y_MODIFY() bfin_read16(DMA2_7_Y_MODIFY) +#define bfin_write_DMA2_7_Y_MODIFY(val) bfin_write16(DMA2_7_Y_MODIFY,val) +#define bfin_read_DMA2_7_CURR_DESC_PTR() bfin_read32(DMA2_7_CURR_DESC_PTR) +#define bfin_write_DMA2_7_CURR_DESC_PTR(val) bfin_write32(DMA2_7_CURR_DESC_PTR,val) +#define bfin_read_DMA2_7_CURR_ADDR() bfin_read32(DMA2_7_CURR_ADDR) +#define bfin_write_DMA2_7_CURR_ADDR(val) bfin_write32(DMA2_7_CURR_ADDR,val) +#define bfin_read_DMA2_7_CURR_X_COUNT() bfin_read16(DMA2_7_CURR_X_COUNT) +#define bfin_write_DMA2_7_CURR_X_COUNT(val) bfin_write16(DMA2_7_CURR_X_COUNT,val) +#define bfin_read_DMA2_7_CURR_Y_COUNT() bfin_read16(DMA2_7_CURR_Y_COUNT) +#define bfin_write_DMA2_7_CURR_Y_COUNT(val) bfin_write16(DMA2_7_CURR_Y_COUNT,val) +#define bfin_read_DMA2_7_IRQ_STATUS() bfin_read16(DMA2_7_IRQ_STATUS) +#define bfin_write_DMA2_7_IRQ_STATUS(val) bfin_write16(DMA2_7_IRQ_STATUS,val) +#define bfin_read_DMA2_7_PERIPHERAL_MAP() bfin_read16(DMA2_7_PERIPHERAL_MAP) +#define bfin_write_DMA2_7_PERIPHERAL_MAP(val) bfin_write16(DMA2_7_PERIPHERAL_MAP,val) +#define bfin_read_DMA2_8_CONFIG() bfin_read16(DMA2_8_CONFIG) +#define bfin_write_DMA2_8_CONFIG(val) bfin_write16(DMA2_8_CONFIG,val) +#define bfin_read_DMA2_8_NEXT_DESC_PTR() bfin_read32(DMA2_8_NEXT_DESC_PTR) +#define bfin_write_DMA2_8_NEXT_DESC_PTR(val) bfin_write32(DMA2_8_NEXT_DESC_PTR,val) +#define bfin_read_DMA2_8_START_ADDR() bfin_read32(DMA2_8_START_ADDR) +#define bfin_write_DMA2_8_START_ADDR(val) bfin_write32(DMA2_8_START_ADDR,val) +#define bfin_read_DMA2_8_X_COUNT() bfin_read16(DMA2_8_X_COUNT) +#define bfin_write_DMA2_8_X_COUNT(val) bfin_write16(DMA2_8_X_COUNT,val) +#define bfin_read_DMA2_8_Y_COUNT() bfin_read16(DMA2_8_Y_COUNT) +#define bfin_write_DMA2_8_Y_COUNT(val) bfin_write16(DMA2_8_Y_COUNT,val) +#define bfin_read_DMA2_8_X_MODIFY() bfin_read16(DMA2_8_X_MODIFY) +#define bfin_write_DMA2_8_X_MODIFY(val) bfin_write16(DMA2_8_X_MODIFY,val) +#define bfin_read_DMA2_8_Y_MODIFY() bfin_read16(DMA2_8_Y_MODIFY) +#define bfin_write_DMA2_8_Y_MODIFY(val) bfin_write16(DMA2_8_Y_MODIFY,val) +#define bfin_read_DMA2_8_CURR_DESC_PTR() bfin_read32(DMA2_8_CURR_DESC_PTR) +#define bfin_write_DMA2_8_CURR_DESC_PTR(val) bfin_write32(DMA2_8_CURR_DESC_PTR,val) +#define bfin_read_DMA2_8_CURR_ADDR() bfin_read32(DMA2_8_CURR_ADDR) +#define bfin_write_DMA2_8_CURR_ADDR(val) bfin_write32(DMA2_8_CURR_ADDR,val) +#define bfin_read_DMA2_8_CURR_X_COUNT() bfin_read16(DMA2_8_CURR_X_COUNT) +#define bfin_write_DMA2_8_CURR_X_COUNT(val) bfin_write16(DMA2_8_CURR_X_COUNT,val) +#define bfin_read_DMA2_8_CURR_Y_COUNT() bfin_read16(DMA2_8_CURR_Y_COUNT) +#define bfin_write_DMA2_8_CURR_Y_COUNT(val) bfin_write16(DMA2_8_CURR_Y_COUNT,val) +#define bfin_read_DMA2_8_IRQ_STATUS() bfin_read16(DMA2_8_IRQ_STATUS) +#define bfin_write_DMA2_8_IRQ_STATUS(val) bfin_write16(DMA2_8_IRQ_STATUS,val) +#define bfin_read_DMA2_8_PERIPHERAL_MAP() bfin_read16(DMA2_8_PERIPHERAL_MAP) +#define bfin_write_DMA2_8_PERIPHERAL_MAP(val) bfin_write16(DMA2_8_PERIPHERAL_MAP,val) +#define bfin_read_DMA2_9_CONFIG() bfin_read16(DMA2_9_CONFIG) +#define bfin_write_DMA2_9_CONFIG(val) bfin_write16(DMA2_9_CONFIG,val) +#define bfin_read_DMA2_9_NEXT_DESC_PTR() bfin_read32(DMA2_9_NEXT_DESC_PTR) +#define bfin_write_DMA2_9_NEXT_DESC_PTR(val) bfin_write32(DMA2_9_NEXT_DESC_PTR,val) +#define bfin_read_DMA2_9_START_ADDR() bfin_read32(DMA2_9_START_ADDR) +#define bfin_write_DMA2_9_START_ADDR(val) bfin_write32(DMA2_9_START_ADDR,val) +#define bfin_read_DMA2_9_X_COUNT() bfin_read16(DMA2_9_X_COUNT) +#define bfin_write_DMA2_9_X_COUNT(val) bfin_write16(DMA2_9_X_COUNT,val) +#define bfin_read_DMA2_9_Y_COUNT() bfin_read16(DMA2_9_Y_COUNT) +#define bfin_write_DMA2_9_Y_COUNT(val) bfin_write16(DMA2_9_Y_COUNT,val) +#define bfin_read_DMA2_9_X_MODIFY() bfin_read16(DMA2_9_X_MODIFY) +#define bfin_write_DMA2_9_X_MODIFY(val) bfin_write16(DMA2_9_X_MODIFY,val) +#define bfin_read_DMA2_9_Y_MODIFY() bfin_read16(DMA2_9_Y_MODIFY) +#define bfin_write_DMA2_9_Y_MODIFY(val) bfin_write16(DMA2_9_Y_MODIFY,val) +#define bfin_read_DMA2_9_CURR_DESC_PTR() bfin_read32(DMA2_9_CURR_DESC_PTR) +#define bfin_write_DMA2_9_CURR_DESC_PTR(val) bfin_write32(DMA2_9_CURR_DESC_PTR,val) +#define bfin_read_DMA2_9_CURR_ADDR() bfin_read32(DMA2_9_CURR_ADDR) +#define bfin_write_DMA2_9_CURR_ADDR(val) bfin_write32(DMA2_9_CURR_ADDR,val) +#define bfin_read_DMA2_9_CURR_X_COUNT() bfin_read16(DMA2_9_CURR_X_COUNT) +#define bfin_write_DMA2_9_CURR_X_COUNT(val) bfin_write16(DMA2_9_CURR_X_COUNT,val) +#define bfin_read_DMA2_9_CURR_Y_COUNT() bfin_read16(DMA2_9_CURR_Y_COUNT) +#define bfin_write_DMA2_9_CURR_Y_COUNT(val) bfin_write16(DMA2_9_CURR_Y_COUNT,val) +#define bfin_read_DMA2_9_IRQ_STATUS() bfin_read16(DMA2_9_IRQ_STATUS) +#define bfin_write_DMA2_9_IRQ_STATUS(val) bfin_write16(DMA2_9_IRQ_STATUS,val) +#define bfin_read_DMA2_9_PERIPHERAL_MAP() bfin_read16(DMA2_9_PERIPHERAL_MAP) +#define bfin_write_DMA2_9_PERIPHERAL_MAP(val) bfin_write16(DMA2_9_PERIPHERAL_MAP,val) +#define bfin_read_DMA2_10_CONFIG() bfin_read16(DMA2_10_CONFIG) +#define bfin_write_DMA2_10_CONFIG(val) bfin_write16(DMA2_10_CONFIG,val) +#define bfin_read_DMA2_10_NEXT_DESC_PTR() bfin_read32(DMA2_10_NEXT_DESC_PTR) +#define bfin_write_DMA2_10_NEXT_DESC_PTR(val) bfin_write32(DMA2_10_NEXT_DESC_PTR,val) +#define bfin_read_DMA2_10_START_ADDR() bfin_read32(DMA2_10_START_ADDR) +#define bfin_write_DMA2_10_START_ADDR(val) bfin_write32(DMA2_10_START_ADDR,val) +#define bfin_read_DMA2_10_X_COUNT() bfin_read16(DMA2_10_X_COUNT) +#define bfin_write_DMA2_10_X_COUNT(val) bfin_write16(DMA2_10_X_COUNT,val) +#define bfin_read_DMA2_10_Y_COUNT() bfin_read16(DMA2_10_Y_COUNT) +#define bfin_write_DMA2_10_Y_COUNT(val) bfin_write16(DMA2_10_Y_COUNT,val) +#define bfin_read_DMA2_10_X_MODIFY() bfin_read16(DMA2_10_X_MODIFY) +#define bfin_write_DMA2_10_X_MODIFY(val) bfin_write16(DMA2_10_X_MODIFY,val) +#define bfin_read_DMA2_10_Y_MODIFY() bfin_read16(DMA2_10_Y_MODIFY) +#define bfin_write_DMA2_10_Y_MODIFY(val) bfin_write16(DMA2_10_Y_MODIFY,val) +#define bfin_read_DMA2_10_CURR_DESC_PTR() bfin_read32(DMA2_10_CURR_DESC_PTR) +#define bfin_write_DMA2_10_CURR_DESC_PTR(val) bfin_write32(DMA2_10_CURR_DESC_PTR,val) +#define bfin_read_DMA2_10_CURR_ADDR() bfin_read32(DMA2_10_CURR_ADDR) +#define bfin_write_DMA2_10_CURR_ADDR(val) bfin_write32(DMA2_10_CURR_ADDR,val) +#define bfin_read_DMA2_10_CURR_X_COUNT() bfin_read16(DMA2_10_CURR_X_COUNT) +#define bfin_write_DMA2_10_CURR_X_COUNT(val) bfin_write16(DMA2_10_CURR_X_COUNT,val) +#define bfin_read_DMA2_10_CURR_Y_COUNT() bfin_read16(DMA2_10_CURR_Y_COUNT) +#define bfin_write_DMA2_10_CURR_Y_COUNT(val) bfin_write16(DMA2_10_CURR_Y_COUNT,val) +#define bfin_read_DMA2_10_IRQ_STATUS() bfin_read16(DMA2_10_IRQ_STATUS) +#define bfin_write_DMA2_10_IRQ_STATUS(val) bfin_write16(DMA2_10_IRQ_STATUS,val) +#define bfin_read_DMA2_10_PERIPHERAL_MAP() bfin_read16(DMA2_10_PERIPHERAL_MAP) +#define bfin_write_DMA2_10_PERIPHERAL_MAP(val) bfin_write16(DMA2_10_PERIPHERAL_MAP,val) +#define bfin_read_DMA2_11_CONFIG() bfin_read16(DMA2_11_CONFIG) +#define bfin_write_DMA2_11_CONFIG(val) bfin_write16(DMA2_11_CONFIG,val) +#define bfin_read_DMA2_11_NEXT_DESC_PTR() bfin_read32(DMA2_11_NEXT_DESC_PTR) +#define bfin_write_DMA2_11_NEXT_DESC_PTR(val) bfin_write32(DMA2_11_NEXT_DESC_PTR,val) +#define bfin_read_DMA2_11_START_ADDR() bfin_read32(DMA2_11_START_ADDR) +#define bfin_write_DMA2_11_START_ADDR(val) bfin_write32(DMA2_11_START_ADDR,val) +#define bfin_read_DMA2_11_X_COUNT() bfin_read16(DMA2_11_X_COUNT) +#define bfin_write_DMA2_11_X_COUNT(val) bfin_write16(DMA2_11_X_COUNT,val) +#define bfin_read_DMA2_11_Y_COUNT() bfin_read16(DMA2_11_Y_COUNT) +#define bfin_write_DMA2_11_Y_COUNT(val) bfin_write16(DMA2_11_Y_COUNT,val) +#define bfin_read_DMA2_11_X_MODIFY() bfin_read16(DMA2_11_X_MODIFY) +#define bfin_write_DMA2_11_X_MODIFY(val) bfin_write16(DMA2_11_X_MODIFY,val) +#define bfin_read_DMA2_11_Y_MODIFY() bfin_read16(DMA2_11_Y_MODIFY) +#define bfin_write_DMA2_11_Y_MODIFY(val) bfin_write16(DMA2_11_Y_MODIFY,val) +#define bfin_read_DMA2_11_CURR_DESC_PTR() bfin_read32(DMA2_11_CURR_DESC_PTR) +#define bfin_write_DMA2_11_CURR_DESC_PTR(val) bfin_write32(DMA2_11_CURR_DESC_PTR,val) +#define bfin_read_DMA2_11_CURR_ADDR() bfin_read32(DMA2_11_CURR_ADDR) +#define bfin_write_DMA2_11_CURR_ADDR(val) bfin_write32(DMA2_11_CURR_ADDR,val) +#define bfin_read_DMA2_11_CURR_X_COUNT() bfin_read16(DMA2_11_CURR_X_COUNT) +#define bfin_write_DMA2_11_CURR_X_COUNT(val) bfin_write16(DMA2_11_CURR_X_COUNT,val) +#define bfin_read_DMA2_11_CURR_Y_COUNT() bfin_read16(DMA2_11_CURR_Y_COUNT) +#define bfin_write_DMA2_11_CURR_Y_COUNT(val) bfin_write16(DMA2_11_CURR_Y_COUNT,val) +#define bfin_read_DMA2_11_IRQ_STATUS() bfin_read16(DMA2_11_IRQ_STATUS) +#define bfin_write_DMA2_11_IRQ_STATUS(val) bfin_write16(DMA2_11_IRQ_STATUS,val) +#define bfin_read_DMA2_11_PERIPHERAL_MAP() bfin_read16(DMA2_11_PERIPHERAL_MAP) +#define bfin_write_DMA2_11_PERIPHERAL_MAP(val) bfin_write16(DMA2_11_PERIPHERAL_MAP,val) +/* Memory DMA2 Controller registers (0xFFC0 0E80-0xFFC0 0FFF) */ +#define bfin_read_MDMA2_D0_CONFIG() bfin_read16(MDMA2_D0_CONFIG) +#define bfin_write_MDMA2_D0_CONFIG(val) bfin_write16(MDMA2_D0_CONFIG,val) +#define bfin_read_MDMA2_D0_NEXT_DESC_PTR() bfin_read32(MDMA2_D0_NEXT_DESC_PTR) +#define bfin_write_MDMA2_D0_NEXT_DESC_PTR(val) bfin_write32(MDMA2_D0_NEXT_DESC_PTR,val) +#define bfin_read_MDMA2_D0_START_ADDR() bfin_read32(MDMA2_D0_START_ADDR) +#define bfin_write_MDMA2_D0_START_ADDR(val) bfin_write32(MDMA2_D0_START_ADDR,val) +#define bfin_read_MDMA2_D0_X_COUNT() bfin_read16(MDMA2_D0_X_COUNT) +#define bfin_write_MDMA2_D0_X_COUNT(val) bfin_write16(MDMA2_D0_X_COUNT,val) +#define bfin_read_MDMA2_D0_Y_COUNT() bfin_read16(MDMA2_D0_Y_COUNT) +#define bfin_write_MDMA2_D0_Y_COUNT(val) bfin_write16(MDMA2_D0_Y_COUNT,val) +#define bfin_read_MDMA2_D0_X_MODIFY() bfin_read16(MDMA2_D0_X_MODIFY) +#define bfin_write_MDMA2_D0_X_MODIFY(val) bfin_write16(MDMA2_D0_X_MODIFY,val) +#define bfin_read_MDMA2_D0_Y_MODIFY() bfin_read16(MDMA2_D0_Y_MODIFY) +#define bfin_write_MDMA2_D0_Y_MODIFY(val) bfin_write16(MDMA2_D0_Y_MODIFY,val) +#define bfin_read_MDMA2_D0_CURR_DESC_PTR() bfin_read32(MDMA2_D0_CURR_DESC_PTR) +#define bfin_write_MDMA2_D0_CURR_DESC_PTR(val) bfin_write32(MDMA2_D0_CURR_DESC_PTR,val) +#define bfin_read_MDMA2_D0_CURR_ADDR() bfin_read32(MDMA2_D0_CURR_ADDR) +#define bfin_write_MDMA2_D0_CURR_ADDR(val) bfin_write32(MDMA2_D0_CURR_ADDR,val) +#define bfin_read_MDMA2_D0_CURR_X_COUNT() bfin_read16(MDMA2_D0_CURR_X_COUNT) +#define bfin_write_MDMA2_D0_CURR_X_COUNT(val) bfin_write16(MDMA2_D0_CURR_X_COUNT,val) +#define bfin_read_MDMA2_D0_CURR_Y_COUNT() bfin_read16(MDMA2_D0_CURR_Y_COUNT) +#define bfin_write_MDMA2_D0_CURR_Y_COUNT(val) bfin_write16(MDMA2_D0_CURR_Y_COUNT,val) +#define bfin_read_MDMA2_D0_IRQ_STATUS() bfin_read16(MDMA2_D0_IRQ_STATUS) +#define bfin_write_MDMA2_D0_IRQ_STATUS(val) bfin_write16(MDMA2_D0_IRQ_STATUS,val) +#define bfin_read_MDMA2_D0_PERIPHERAL_MAP() bfin_read16(MDMA2_D0_PERIPHERAL_MAP) +#define bfin_write_MDMA2_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA2_D0_PERIPHERAL_MAP,val) +#define bfin_read_MDMA2_S0_CONFIG() bfin_read16(MDMA2_S0_CONFIG) +#define bfin_write_MDMA2_S0_CONFIG(val) bfin_write16(MDMA2_S0_CONFIG,val) +#define bfin_read_MDMA2_S0_NEXT_DESC_PTR() bfin_read32(MDMA2_S0_NEXT_DESC_PTR) +#define bfin_write_MDMA2_S0_NEXT_DESC_PTR(val) bfin_write32(MDMA2_S0_NEXT_DESC_PTR,val) +#define bfin_read_MDMA2_S0_START_ADDR() bfin_read32(MDMA2_S0_START_ADDR) +#define bfin_write_MDMA2_S0_START_ADDR(val) bfin_write32(MDMA2_S0_START_ADDR,val) +#define bfin_read_MDMA2_S0_X_COUNT() bfin_read16(MDMA2_S0_X_COUNT) +#define bfin_write_MDMA2_S0_X_COUNT(val) bfin_write16(MDMA2_S0_X_COUNT,val) +#define bfin_read_MDMA2_S0_Y_COUNT() bfin_read16(MDMA2_S0_Y_COUNT) +#define bfin_write_MDMA2_S0_Y_COUNT(val) bfin_write16(MDMA2_S0_Y_COUNT,val) +#define bfin_read_MDMA2_S0_X_MODIFY() bfin_read16(MDMA2_S0_X_MODIFY) +#define bfin_write_MDMA2_S0_X_MODIFY(val) bfin_write16(MDMA2_S0_X_MODIFY,val) +#define bfin_read_MDMA2_S0_Y_MODIFY() bfin_read16(MDMA2_S0_Y_MODIFY) +#define bfin_write_MDMA2_S0_Y_MODIFY(val) bfin_write16(MDMA2_S0_Y_MODIFY,val) +#define bfin_read_MDMA2_S0_CURR_DESC_PTR() bfin_read32(MDMA2_S0_CURR_DESC_PTR) +#define bfin_write_MDMA2_S0_CURR_DESC_PTR(val) bfin_write32(MDMA2_S0_CURR_DESC_PTR,val) +#define bfin_read_MDMA2_S0_CURR_ADDR() bfin_read32(MDMA2_S0_CURR_ADDR) +#define bfin_write_MDMA2_S0_CURR_ADDR(val) bfin_write32(MDMA2_S0_CURR_ADDR,val) +#define bfin_read_MDMA2_S0_CURR_X_COUNT() bfin_read16(MDMA2_S0_CURR_X_COUNT) +#define bfin_write_MDMA2_S0_CURR_X_COUNT(val) bfin_write16(MDMA2_S0_CURR_X_COUNT,val) +#define bfin_read_MDMA2_S0_CURR_Y_COUNT() bfin_read16(MDMA2_S0_CURR_Y_COUNT) +#define bfin_write_MDMA2_S0_CURR_Y_COUNT(val) bfin_write16(MDMA2_S0_CURR_Y_COUNT,val) +#define bfin_read_MDMA2_S0_IRQ_STATUS() bfin_read16(MDMA2_S0_IRQ_STATUS) +#define bfin_write_MDMA2_S0_IRQ_STATUS(val) bfin_write16(MDMA2_S0_IRQ_STATUS,val) +#define bfin_read_MDMA2_S0_PERIPHERAL_MAP() bfin_read16(MDMA2_S0_PERIPHERAL_MAP) +#define bfin_write_MDMA2_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA2_S0_PERIPHERAL_MAP,val) +#define bfin_read_MDMA2_D1_CONFIG() bfin_read16(MDMA2_D1_CONFIG) +#define bfin_write_MDMA2_D1_CONFIG(val) bfin_write16(MDMA2_D1_CONFIG,val) +#define bfin_read_MDMA2_D1_NEXT_DESC_PTR() bfin_read32(MDMA2_D1_NEXT_DESC_PTR) +#define bfin_write_MDMA2_D1_NEXT_DESC_PTR(val) bfin_write32(MDMA2_D1_NEXT_DESC_PTR,val) +#define bfin_read_MDMA2_D1_START_ADDR() bfin_read32(MDMA2_D1_START_ADDR) +#define bfin_write_MDMA2_D1_START_ADDR(val) bfin_write32(MDMA2_D1_START_ADDR,val) +#define bfin_read_MDMA2_D1_X_COUNT() bfin_read16(MDMA2_D1_X_COUNT) +#define bfin_write_MDMA2_D1_X_COUNT(val) bfin_write16(MDMA2_D1_X_COUNT,val) +#define bfin_read_MDMA2_D1_Y_COUNT() bfin_read16(MDMA2_D1_Y_COUNT) +#define bfin_write_MDMA2_D1_Y_COUNT(val) bfin_write16(MDMA2_D1_Y_COUNT,val) +#define bfin_read_MDMA2_D1_X_MODIFY() bfin_read16(MDMA2_D1_X_MODIFY) +#define bfin_write_MDMA2_D1_X_MODIFY(val) bfin_write16(MDMA2_D1_X_MODIFY,val) +#define bfin_read_MDMA2_D1_Y_MODIFY() bfin_read16(MDMA2_D1_Y_MODIFY) +#define bfin_write_MDMA2_D1_Y_MODIFY(val) bfin_write16(MDMA2_D1_Y_MODIFY,val) +#define bfin_read_MDMA2_D1_CURR_DESC_PTR() bfin_read32(MDMA2_D1_CURR_DESC_PTR) +#define bfin_write_MDMA2_D1_CURR_DESC_PTR(val) bfin_write32(MDMA2_D1_CURR_DESC_PTR,val) +#define bfin_read_MDMA2_D1_CURR_ADDR() bfin_read32(MDMA2_D1_CURR_ADDR) +#define bfin_write_MDMA2_D1_CURR_ADDR(val) bfin_write32(MDMA2_D1_CURR_ADDR,val) +#define bfin_read_MDMA2_D1_CURR_X_COUNT() bfin_read16(MDMA2_D1_CURR_X_COUNT) +#define bfin_write_MDMA2_D1_CURR_X_COUNT(val) bfin_write16(MDMA2_D1_CURR_X_COUNT,val) +#define bfin_read_MDMA2_D1_CURR_Y_COUNT() bfin_read16(MDMA2_D1_CURR_Y_COUNT) +#define bfin_write_MDMA2_D1_CURR_Y_COUNT(val) bfin_write16(MDMA2_D1_CURR_Y_COUNT,val) +#define bfin_read_MDMA2_D1_IRQ_STATUS() bfin_read16(MDMA2_D1_IRQ_STATUS) +#define bfin_write_MDMA2_D1_IRQ_STATUS(val) bfin_write16(MDMA2_D1_IRQ_STATUS,val) +#define bfin_read_MDMA2_D1_PERIPHERAL_MAP() bfin_read16(MDMA2_D1_PERIPHERAL_MAP) +#define bfin_write_MDMA2_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA2_D1_PERIPHERAL_MAP,val) +#define bfin_read_MDMA2_S1_CONFIG() bfin_read16(MDMA2_S1_CONFIG) +#define bfin_write_MDMA2_S1_CONFIG(val) bfin_write16(MDMA2_S1_CONFIG,val) +#define bfin_read_MDMA2_S1_NEXT_DESC_PTR() bfin_read32(MDMA2_S1_NEXT_DESC_PTR) +#define bfin_write_MDMA2_S1_NEXT_DESC_PTR(val) bfin_write32(MDMA2_S1_NEXT_DESC_PTR,val) +#define bfin_read_MDMA2_S1_START_ADDR() bfin_read32(MDMA2_S1_START_ADDR) +#define bfin_write_MDMA2_S1_START_ADDR(val) bfin_write32(MDMA2_S1_START_ADDR,val) +#define bfin_read_MDMA2_S1_X_COUNT() bfin_read16(MDMA2_S1_X_COUNT) +#define bfin_write_MDMA2_S1_X_COUNT(val) bfin_write16(MDMA2_S1_X_COUNT,val) +#define bfin_read_MDMA2_S1_Y_COUNT() bfin_read16(MDMA2_S1_Y_COUNT) +#define bfin_write_MDMA2_S1_Y_COUNT(val) bfin_write16(MDMA2_S1_Y_COUNT,val) +#define bfin_read_MDMA2_S1_X_MODIFY() bfin_read16(MDMA2_S1_X_MODIFY) +#define bfin_write_MDMA2_S1_X_MODIFY(val) bfin_write16(MDMA2_S1_X_MODIFY,val) +#define bfin_read_MDMA2_S1_Y_MODIFY() bfin_read16(MDMA2_S1_Y_MODIFY) +#define bfin_write_MDMA2_S1_Y_MODIFY(val) bfin_write16(MDMA2_S1_Y_MODIFY,val) +#define bfin_read_MDMA2_S1_CURR_DESC_PTR() bfin_read32(MDMA2_S1_CURR_DESC_PTR) +#define bfin_write_MDMA2_S1_CURR_DESC_PTR(val) bfin_write32(MDMA2_S1_CURR_DESC_PTR,val) +#define bfin_read_MDMA2_S1_CURR_ADDR() bfin_read32(MDMA2_S1_CURR_ADDR) +#define bfin_write_MDMA2_S1_CURR_ADDR(val) bfin_write32(MDMA2_S1_CURR_ADDR,val) +#define bfin_read_MDMA2_S1_CURR_X_COUNT() bfin_read16(MDMA2_S1_CURR_X_COUNT) +#define bfin_write_MDMA2_S1_CURR_X_COUNT(val) bfin_write16(MDMA2_S1_CURR_X_COUNT,val) +#define bfin_read_MDMA2_S1_CURR_Y_COUNT() bfin_read16(MDMA2_S1_CURR_Y_COUNT) +#define bfin_write_MDMA2_S1_CURR_Y_COUNT(val) bfin_write16(MDMA2_S1_CURR_Y_COUNT,val) +#define bfin_read_MDMA2_S1_IRQ_STATUS() bfin_read16(MDMA2_S1_IRQ_STATUS) +#define bfin_write_MDMA2_S1_IRQ_STATUS(val) bfin_write16(MDMA2_S1_IRQ_STATUS,val) +#define bfin_read_MDMA2_S1_PERIPHERAL_MAP() bfin_read16(MDMA2_S1_PERIPHERAL_MAP) +#define bfin_write_MDMA2_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA2_S1_PERIPHERAL_MAP,val) +/* Internal Memory DMA Registers (0xFFC0_1800 - 0xFFC0_19FF) */ +#define bfin_read_IMDMA_D0_CONFIG() bfin_read16(IMDMA_D0_CONFIG) +#define bfin_write_IMDMA_D0_CONFIG(val) bfin_write16(IMDMA_D0_CONFIG,val) +#define bfin_read_IMDMA_D0_NEXT_DESC_PTR() bfin_read32(IMDMA_D0_NEXT_DESC_PTR) +#define bfin_write_IMDMA_D0_NEXT_DESC_PTR(val) bfin_write32(IMDMA_D0_NEXT_DESC_PTR,val) +#define bfin_read_IMDMA_D0_START_ADDR() bfin_read32(IMDMA_D0_START_ADDR) +#define bfin_write_IMDMA_D0_START_ADDR(val) bfin_write32(IMDMA_D0_START_ADDR,val) +#define bfin_read_IMDMA_D0_X_COUNT() bfin_read16(IMDMA_D0_X_COUNT) +#define bfin_write_IMDMA_D0_X_COUNT(val) bfin_write16(IMDMA_D0_X_COUNT,val) +#define bfin_read_IMDMA_D0_Y_COUNT() bfin_read16(IMDMA_D0_Y_COUNT) +#define bfin_write_IMDMA_D0_Y_COUNT(val) bfin_write16(IMDMA_D0_Y_COUNT,val) +#define bfin_read_IMDMA_D0_X_MODIFY() bfin_read16(IMDMA_D0_X_MODIFY) +#define bfin_write_IMDMA_D0_X_MODIFY(val) bfin_write16(IMDMA_D0_X_MODIFY,val) +#define bfin_read_IMDMA_D0_Y_MODIFY() bfin_read16(IMDMA_D0_Y_MODIFY) +#define bfin_write_IMDMA_D0_Y_MODIFY(val) bfin_write16(IMDMA_D0_Y_MODIFY,val) +#define bfin_read_IMDMA_D0_CURR_DESC_PTR() bfin_read32(IMDMA_D0_CURR_DESC_PTR) +#define bfin_write_IMDMA_D0_CURR_DESC_PTR(val) bfin_write32(IMDMA_D0_CURR_DESC_PTR,val) +#define bfin_read_IMDMA_D0_CURR_ADDR() bfin_read32(IMDMA_D0_CURR_ADDR) +#define bfin_write_IMDMA_D0_CURR_ADDR(val) bfin_write32(IMDMA_D0_CURR_ADDR,val) +#define bfin_read_IMDMA_D0_CURR_X_COUNT() bfin_read16(IMDMA_D0_CURR_X_COUNT) +#define bfin_write_IMDMA_D0_CURR_X_COUNT(val) bfin_write16(IMDMA_D0_CURR_X_COUNT,val) +#define bfin_read_IMDMA_D0_CURR_Y_COUNT() bfin_read16(IMDMA_D0_CURR_Y_COUNT) +#define bfin_write_IMDMA_D0_CURR_Y_COUNT(val) bfin_write16(IMDMA_D0_CURR_Y_COUNT,val) +#define bfin_read_IMDMA_D0_IRQ_STATUS() bfin_read16(IMDMA_D0_IRQ_STATUS) +#define bfin_write_IMDMA_D0_IRQ_STATUS(val) bfin_write16(IMDMA_D0_IRQ_STATUS,val) +#define bfin_read_IMDMA_S0_CONFIG() bfin_read16(IMDMA_S0_CONFIG) +#define bfin_write_IMDMA_S0_CONFIG(val) bfin_write16(IMDMA_S0_CONFIG,val) +#define bfin_read_IMDMA_S0_NEXT_DESC_PTR() bfin_read32(IMDMA_S0_NEXT_DESC_PTR) +#define bfin_write_IMDMA_S0_NEXT_DESC_PTR(val) bfin_write32(IMDMA_S0_NEXT_DESC_PTR,val) +#define bfin_read_IMDMA_S0_START_ADDR() bfin_read32(IMDMA_S0_START_ADDR) +#define bfin_write_IMDMA_S0_START_ADDR(val) bfin_write32(IMDMA_S0_START_ADDR,val) +#define bfin_read_IMDMA_S0_X_COUNT() bfin_read16(IMDMA_S0_X_COUNT) +#define bfin_write_IMDMA_S0_X_COUNT(val) bfin_write16(IMDMA_S0_X_COUNT,val) +#define bfin_read_IMDMA_S0_Y_COUNT() bfin_read16(IMDMA_S0_Y_COUNT) +#define bfin_write_IMDMA_S0_Y_COUNT(val) bfin_write16(IMDMA_S0_Y_COUNT,val) +#define bfin_read_IMDMA_S0_X_MODIFY() bfin_read16(IMDMA_S0_X_MODIFY) +#define bfin_write_IMDMA_S0_X_MODIFY(val) bfin_write16(IMDMA_S0_X_MODIFY,val) +#define bfin_read_IMDMA_S0_Y_MODIFY() bfin_read16(IMDMA_S0_Y_MODIFY) +#define bfin_write_IMDMA_S0_Y_MODIFY(val) bfin_write16(IMDMA_S0_Y_MODIFY,val) +#define bfin_read_IMDMA_S0_CURR_DESC_PTR() bfin_read32(IMDMA_S0_CURR_DESC_PTR) +#define bfin_write_IMDMA_S0_CURR_DESC_PTR(val) bfin_write32(IMDMA_S0_CURR_DESC_PTR,val) +#define bfin_read_IMDMA_S0_CURR_ADDR() bfin_read32(IMDMA_S0_CURR_ADDR) +#define bfin_write_IMDMA_S0_CURR_ADDR(val) bfin_write32(IMDMA_S0_CURR_ADDR,val) +#define bfin_read_IMDMA_S0_CURR_X_COUNT() bfin_read16(IMDMA_S0_CURR_X_COUNT) +#define bfin_write_IMDMA_S0_CURR_X_COUNT(val) bfin_write16(IMDMA_S0_CURR_X_COUNT,val) +#define bfin_read_IMDMA_S0_CURR_Y_COUNT() bfin_read16(IMDMA_S0_CURR_Y_COUNT) +#define bfin_write_IMDMA_S0_CURR_Y_COUNT(val) bfin_write16(IMDMA_S0_CURR_Y_COUNT,val) +#define bfin_read_IMDMA_S0_IRQ_STATUS() bfin_read16(IMDMA_S0_IRQ_STATUS) +#define bfin_write_IMDMA_S0_IRQ_STATUS(val) bfin_write16(IMDMA_S0_IRQ_STATUS,val) +#define bfin_read_IMDMA_D1_CONFIG() bfin_read16(IMDMA_D1_CONFIG) +#define bfin_write_IMDMA_D1_CONFIG(val) bfin_write16(IMDMA_D1_CONFIG,val) +#define bfin_read_IMDMA_D1_NEXT_DESC_PTR() bfin_read32(IMDMA_D1_NEXT_DESC_PTR) +#define bfin_write_IMDMA_D1_NEXT_DESC_PTR(val) bfin_write32(IMDMA_D1_NEXT_DESC_PTR,val) +#define bfin_read_IMDMA_D1_START_ADDR() bfin_read32(IMDMA_D1_START_ADDR) +#define bfin_write_IMDMA_D1_START_ADDR(val) bfin_write32(IMDMA_D1_START_ADDR,val) +#define bfin_read_IMDMA_D1_X_COUNT() bfin_read16(IMDMA_D1_X_COUNT) +#define bfin_write_IMDMA_D1_X_COUNT(val) bfin_write16(IMDMA_D1_X_COUNT,val) +#define bfin_read_IMDMA_D1_Y_COUNT() bfin_read16(IMDMA_D1_Y_COUNT) +#define bfin_write_IMDMA_D1_Y_COUNT(val) bfin_write16(IMDMA_D1_Y_COUNT,val) +#define bfin_read_IMDMA_D1_X_MODIFY() bfin_read16(IMDMA_D1_X_MODIFY) +#define bfin_write_IMDMA_D1_X_MODIFY(val) bfin_write16(IMDMA_D1_X_MODIFY,val) +#define bfin_read_IMDMA_D1_Y_MODIFY() bfin_read16(IMDMA_D1_Y_MODIFY) +#define bfin_write_IMDMA_D1_Y_MODIFY(val) bfin_write16(IMDMA_D1_Y_MODIFY,val) +#define bfin_read_IMDMA_D1_CURR_DESC_PTR() bfin_read32(IMDMA_D1_CURR_DESC_PTR) +#define bfin_write_IMDMA_D1_CURR_DESC_PTR(val) bfin_write32(IMDMA_D1_CURR_DESC_PTR,val) +#define bfin_read_IMDMA_D1_CURR_ADDR() bfin_read32(IMDMA_D1_CURR_ADDR) +#define bfin_write_IMDMA_D1_CURR_ADDR(val) bfin_write32(IMDMA_D1_CURR_ADDR,val) +#define bfin_read_IMDMA_D1_CURR_X_COUNT() bfin_read16(IMDMA_D1_CURR_X_COUNT) +#define bfin_write_IMDMA_D1_CURR_X_COUNT(val) bfin_write16(IMDMA_D1_CURR_X_COUNT,val) +#define bfin_read_IMDMA_D1_CURR_Y_COUNT() bfin_read16(IMDMA_D1_CURR_Y_COUNT) +#define bfin_write_IMDMA_D1_CURR_Y_COUNT(val) bfin_write16(IMDMA_D1_CURR_Y_COUNT,val) +#define bfin_read_IMDMA_D1_IRQ_STATUS() bfin_read16(IMDMA_D1_IRQ_STATUS) +#define bfin_write_IMDMA_D1_IRQ_STATUS(val) bfin_write16(IMDMA_D1_IRQ_STATUS,val) +#define bfin_read_IMDMA_S1_CONFIG() bfin_read16(IMDMA_S1_CONFIG) +#define bfin_write_IMDMA_S1_CONFIG(val) bfin_write16(IMDMA_S1_CONFIG,val) +#define bfin_read_IMDMA_S1_NEXT_DESC_PTR() bfin_read32(IMDMA_S1_NEXT_DESC_PTR) +#define bfin_write_IMDMA_S1_NEXT_DESC_PTR(val) bfin_write32(IMDMA_S1_NEXT_DESC_PTR,val) +#define bfin_read_IMDMA_S1_START_ADDR() bfin_read32(IMDMA_S1_START_ADDR) +#define bfin_write_IMDMA_S1_START_ADDR(val) bfin_write32(IMDMA_S1_START_ADDR,val) +#define bfin_read_IMDMA_S1_X_COUNT() bfin_read16(IMDMA_S1_X_COUNT) +#define bfin_write_IMDMA_S1_X_COUNT(val) bfin_write16(IMDMA_S1_X_COUNT,val) +#define bfin_read_IMDMA_S1_Y_COUNT() bfin_read16(IMDMA_S1_Y_COUNT) +#define bfin_write_IMDMA_S1_Y_COUNT(val) bfin_write16(IMDMA_S1_Y_COUNT,val) +#define bfin_read_IMDMA_S1_X_MODIFY() bfin_read16(IMDMA_S1_X_MODIFY) +#define bfin_write_IMDMA_S1_X_MODIFY(val) bfin_write16(IMDMA_S1_X_MODIFY,val) +#define bfin_read_IMDMA_S1_Y_MODIFY() bfin_read16(IMDMA_S1_Y_MODIFY) +#define bfin_write_IMDMA_S1_Y_MODIFY(val) bfin_write16(IMDMA_S1_Y_MODIFY,val) +#define bfin_read_IMDMA_S1_CURR_DESC_PTR() bfin_read32(IMDMA_S1_CURR_DESC_PTR) +#define bfin_write_IMDMA_S1_CURR_DESC_PTR(val) bfin_write32(IMDMA_S1_CURR_DESC_PTR,val) +#define bfin_read_IMDMA_S1_CURR_ADDR() bfin_read32(IMDMA_S1_CURR_ADDR) +#define bfin_write_IMDMA_S1_CURR_ADDR(val) bfin_write32(IMDMA_S1_CURR_ADDR,val) +#define bfin_read_IMDMA_S1_CURR_X_COUNT() bfin_read16(IMDMA_S1_CURR_X_COUNT) +#define bfin_write_IMDMA_S1_CURR_X_COUNT(val) bfin_write16(IMDMA_S1_CURR_X_COUNT,val) +#define bfin_read_IMDMA_S1_CURR_Y_COUNT() bfin_read16(IMDMA_S1_CURR_Y_COUNT) +#define bfin_write_IMDMA_S1_CURR_Y_COUNT(val) bfin_write16(IMDMA_S1_CURR_Y_COUNT,val) +#define bfin_read_IMDMA_S1_IRQ_STATUS() bfin_read16(IMDMA_S1_IRQ_STATUS) +#define bfin_write_IMDMA_S1_IRQ_STATUS(val) bfin_write16(IMDMA_S1_IRQ_STATUS,val) + +#define bfin_read_MDMA_S0_CONFIG() bfin_read_MDMA1_S0_CONFIG() +#define bfin_write_MDMA_S0_CONFIG(val) bfin_write_MDMA1_S0_CONFIG(val) +#define bfin_read_MDMA_S0_IRQ_STATUS() bfin_read_MDMA1_S0_IRQ_STATUS() +#define bfin_write_MDMA_S0_IRQ_STATUS(val) bfin_write_MDMA1_S0_IRQ_STATUS(val) +#define bfin_read_MDMA_S0_X_MODIFY() bfin_read_MDMA1_S0_X_MODIFY() +#define bfin_write_MDMA_S0_X_MODIFY(val) bfin_write_MDMA1_S0_X_MODIFY(val) +#define bfin_read_MDMA_S0_Y_MODIFY() bfin_read_MDMA1_S0_Y_MODIFY() +#define bfin_write_MDMA_S0_Y_MODIFY(val) bfin_write_MDMA1_S0_Y_MODIFY(val) +#define bfin_read_MDMA_S0_X_COUNT() bfin_read_MDMA1_S0_X_COUNT() +#define bfin_write_MDMA_S0_X_COUNT(val) bfin_write_MDMA1_S0_X_COUNT(val) +#define bfin_read_MDMA_S0_Y_COUNT() bfin_read_MDMA1_S0_Y_COUNT() +#define bfin_write_MDMA_S0_Y_COUNT(val) bfin_write_MDMA1_S0_Y_COUNT(val) +#define bfin_read_MDMA_S0_START_ADDR() bfin_read_MDMA1_S0_START_ADDR() +#define bfin_write_MDMA_S0_START_ADDR(val) bfin_write_MDMA1_S0_START_ADDR(val) +#define bfin_read_MDMA_D0_CONFIG() bfin_read_MDMA1_D0_CONFIG() +#define bfin_write_MDMA_D0_CONFIG(val) bfin_write_MDMA1_D0_CONFIG(val) +#define bfin_read_MDMA_D0_IRQ_STATUS() bfin_read_MDMA1_D0_IRQ_STATUS() +#define bfin_write_MDMA_D0_IRQ_STATUS(val) bfin_write_MDMA1_D0_IRQ_STATUS(val) +#define bfin_read_MDMA_D0_X_MODIFY() bfin_read_MDMA1_D0_X_MODIFY() +#define bfin_write_MDMA_D0_X_MODIFY(val) bfin_write_MDMA1_D0_X_MODIFY(val) +#define bfin_read_MDMA_D0_Y_MODIFY() bfin_read_MDMA1_D0_Y_MODIFY() +#define bfin_write_MDMA_D0_Y_MODIFY(val) bfin_write_MDMA1_D0_Y_MODIFY(val) +#define bfin_read_MDMA_D0_X_COUNT() bfin_read_MDMA1_D0_X_COUNT() +#define bfin_write_MDMA_D0_X_COUNT(val) bfin_write_MDMA1_D0_X_COUNT(val) +#define bfin_read_MDMA_D0_Y_COUNT() bfin_read_MDMA1_D0_Y_COUNT() +#define bfin_write_MDMA_D0_Y_COUNT(val) bfin_write_MDMA1_D0_Y_COUNT(val) +#define bfin_read_MDMA_D0_START_ADDR() bfin_read_MDMA1_D0_START_ADDR() +#define bfin_write_MDMA_D0_START_ADDR(val) bfin_write_MDMA1_D0_START_ADDR(val) + +#endif /* _CDEF_BF561_H */ diff --git a/include/asm-blackfin/mach-bf561/defBF561.h b/include/asm-blackfin/mach-bf561/defBF561.h new file mode 100644 index 000000000000..a6de4c69ba55 --- /dev/null +++ b/include/asm-blackfin/mach-bf561/defBF561.h @@ -0,0 +1,1717 @@ + +/* + * File: include/asm-blackfin/mach-bf561/defBF561.h + * Based on: + * Author: + * + * Created: + * Description: + * SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561 + * Rev: + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _DEF_BF561_H +#define _DEF_BF561_H +/* +#if !defined(__ADSPBF561__) +#warning defBF561.h should only be included for BF561 chip. +#endif +*/ +/* include all Core registers and bit definitions */ +#include + +/*********************************************************************************** */ +/* System MMR Register Map */ +/*********************************************************************************** */ + +/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */ + +#define PLL_CTL 0xFFC00000 /* PLL Control register (16-bit) */ +#define PLL_DIV 0xFFC00004 /* PLL Divide Register (16-bit) */ +#define VR_CTL 0xFFC00008 /* Voltage Regulator Control Register (16-bit) */ +#define PLL_STAT 0xFFC0000C /* PLL Status register (16-bit) */ +#define PLL_LOCKCNT 0xFFC00010 /* PLL Lock Count register (16-bit) */ +#define CHIPID 0xFFC00014 /* Chip ID Register */ + +/* System Reset and Interrupt Controller registers for core A (0xFFC0 0100-0xFFC0 01FF) */ +#define SICA_SWRST 0xFFC00100 /* Software Reset register */ +#define SICA_SYSCR 0xFFC00104 /* System Reset Configuration register */ +#define SICA_RVECT 0xFFC00108 /* SIC Reset Vector Address Register */ +#define SICA_IMASK 0xFFC0010C /* SIC Interrupt Mask register 0 - hack to fix old tests */ +#define SICA_IMASK0 0xFFC0010C /* SIC Interrupt Mask register 0 */ +#define SICA_IMASK1 0xFFC00110 /* SIC Interrupt Mask register 1 */ +#define SICA_IAR0 0xFFC00124 /* SIC Interrupt Assignment Register 0 */ +#define SICA_IAR1 0xFFC00128 /* SIC Interrupt Assignment Register 1 */ +#define SICA_IAR2 0xFFC0012C /* SIC Interrupt Assignment Register 2 */ +#define SICA_IAR3 0xFFC00130 /* SIC Interrupt Assignment Register 3 */ +#define SICA_IAR4 0xFFC00134 /* SIC Interrupt Assignment Register 4 */ +#define SICA_IAR5 0xFFC00138 /* SIC Interrupt Assignment Register 5 */ +#define SICA_IAR6 0xFFC0013C /* SIC Interrupt Assignment Register 6 */ +#define SICA_IAR7 0xFFC00140 /* SIC Interrupt Assignment Register 7 */ +#define SICA_ISR0 0xFFC00114 /* SIC Interrupt Status register 0 */ +#define SICA_ISR1 0xFFC00118 /* SIC Interrupt Status register 1 */ +#define SICA_IWR0 0xFFC0011C /* SIC Interrupt Wakeup-Enable register 0 */ +#define SICA_IWR1 0xFFC00120 /* SIC Interrupt Wakeup-Enable register 1 */ + +/* System Reset and Interrupt Controller registers for Core B (0xFFC0 1100-0xFFC0 11FF) */ +#define SICB_SWRST 0xFFC01100 /* reserved */ +#define SICB_SYSCR 0xFFC01104 /* reserved */ +#define SICB_RVECT 0xFFC01108 /* SIC Reset Vector Address Register */ +#define SICB_IMASK0 0xFFC0110C /* SIC Interrupt Mask register 0 */ +#define SICB_IMASK1 0xFFC01110 /* SIC Interrupt Mask register 1 */ +#define SICB_IAR0 0xFFC01124 /* SIC Interrupt Assignment Register 0 */ +#define SICB_IAR1 0xFFC01128 /* SIC Interrupt Assignment Register 1 */ +#define SICB_IAR2 0xFFC0112C /* SIC Interrupt Assignment Register 2 */ +#define SICB_IAR3 0xFFC01130 /* SIC Interrupt Assignment Register 3 */ +#define SICB_IAR4 0xFFC01134 /* SIC Interrupt Assignment Register 4 */ +#define SICB_IAR5 0xFFC01138 /* SIC Interrupt Assignment Register 5 */ +#define SICB_IAR6 0xFFC0113C /* SIC Interrupt Assignment Register 6 */ +#define SICB_IAR7 0xFFC01140 /* SIC Interrupt Assignment Register 7 */ +#define SICB_ISR0 0xFFC01114 /* SIC Interrupt Status register 0 */ +#define SICB_ISR1 0xFFC01118 /* SIC Interrupt Status register 1 */ +#define SICB_IWR0 0xFFC0111C /* SIC Interrupt Wakeup-Enable register 0 */ +#define SICB_IWR1 0xFFC01120 /* SIC Interrupt Wakeup-Enable register 1 */ + +/* Watchdog Timer registers for Core A (0xFFC0 0200-0xFFC0 02FF) */ +#define WDOGA_CTL 0xFFC00200 /* Watchdog Control register */ +#define WDOGA_CNT 0xFFC00204 /* Watchdog Count register */ +#define WDOGA_STAT 0xFFC00208 /* Watchdog Status register */ + +/* Watchdog Timer registers for Core B (0xFFC0 1200-0xFFC0 12FF) */ +#define WDOGB_CTL 0xFFC01200 /* Watchdog Control register */ +#define WDOGB_CNT 0xFFC01204 /* Watchdog Count register */ +#define WDOGB_STAT 0xFFC01208 /* Watchdog Status register */ + +/* UART Controller (0xFFC00400 - 0xFFC004FF) */ +#define UART_THR 0xFFC00400 /* Transmit Holding register */ +#define UART_RBR 0xFFC00400 /* Receive Buffer register */ +#define UART_DLL 0xFFC00400 /* Divisor Latch (Low-Byte) */ +#define UART_IER 0xFFC00404 /* Interrupt Enable Register */ +#define UART_DLH 0xFFC00404 /* Divisor Latch (High-Byte) */ +#define UART_IIR 0xFFC00408 /* Interrupt Identification Register */ +#define UART_LCR 0xFFC0040C /* Line Control Register */ +#define UART_MCR 0xFFC00410 /* Modem Control Register */ +#define UART_LSR 0xFFC00414 /* Line Status Register */ +#define UART_MSR 0xFFC00418 /* Modem Status Register */ +#define UART_SCR 0xFFC0041C /* SCR Scratch Register */ +#define UART_GCTL 0xFFC00424 /* Global Control Register */ + +/* SPI Controller (0xFFC00500 - 0xFFC005FF) */ +#define SPI_CTL 0xFFC00500 /* SPI Control Register */ +#define SPI_FLG 0xFFC00504 /* SPI Flag register */ +#define SPI_STAT 0xFFC00508 /* SPI Status register */ +#define SPI_TDBR 0xFFC0050C /* SPI Transmit Data Buffer Register */ +#define SPI_RDBR 0xFFC00510 /* SPI Receive Data Buffer Register */ +#define SPI_BAUD 0xFFC00514 /* SPI Baud rate Register */ +#define SPI_SHADOW 0xFFC00518 /* SPI_RDBR Shadow Register */ + +/* Timer 0-7 registers (0xFFC0 0600-0xFFC0 06FF) */ +#define TIMER0_CONFIG 0xFFC00600 /* Timer0 Configuration register */ +#define TIMER0_COUNTER 0xFFC00604 /* Timer0 Counter register */ +#define TIMER0_PERIOD 0xFFC00608 /* Timer0 Period register */ +#define TIMER0_WIDTH 0xFFC0060C /* Timer0 Width register */ + +#define TIMER1_CONFIG 0xFFC00610 /* Timer1 Configuration register */ +#define TIMER1_COUNTER 0xFFC00614 /* Timer1 Counter register */ +#define TIMER1_PERIOD 0xFFC00618 /* Timer1 Period register */ +#define TIMER1_WIDTH 0xFFC0061C /* Timer1 Width register */ + +#define TIMER2_CONFIG 0xFFC00620 /* Timer2 Configuration register */ +#define TIMER2_COUNTER 0xFFC00624 /* Timer2 Counter register */ +#define TIMER2_PERIOD 0xFFC00628 /* Timer2 Period register */ +#define TIMER2_WIDTH 0xFFC0062C /* Timer2 Width register */ + +#define TIMER3_CONFIG 0xFFC00630 /* Timer3 Configuration register */ +#define TIMER3_COUNTER 0xFFC00634 /* Timer3 Counter register */ +#define TIMER3_PERIOD 0xFFC00638 /* Timer3 Period register */ +#define TIMER3_WIDTH 0xFFC0063C /* Timer3 Width register */ + +#define TIMER4_CONFIG 0xFFC00640 /* Timer4 Configuration register */ +#define TIMER4_COUNTER 0xFFC00644 /* Timer4 Counter register */ +#define TIMER4_PERIOD 0xFFC00648 /* Timer4 Period register */ +#define TIMER4_WIDTH 0xFFC0064C /* Timer4 Width register */ + +#define TIMER5_CONFIG 0xFFC00650 /* Timer5 Configuration register */ +#define TIMER5_COUNTER 0xFFC00654 /* Timer5 Counter register */ +#define TIMER5_PERIOD 0xFFC00658 /* Timer5 Period register */ +#define TIMER5_WIDTH 0xFFC0065C /* Timer5 Width register */ + +#define TIMER6_CONFIG 0xFFC00660 /* Timer6 Configuration register */ +#define TIMER6_COUNTER 0xFFC00664 /* Timer6 Counter register */ +#define TIMER6_PERIOD 0xFFC00668 /* Timer6 Period register */ +#define TIMER6_WIDTH 0xFFC0066C /* Timer6 Width register */ + +#define TIMER7_CONFIG 0xFFC00670 /* Timer7 Configuration register */ +#define TIMER7_COUNTER 0xFFC00674 /* Timer7 Counter register */ +#define TIMER7_PERIOD 0xFFC00678 /* Timer7 Period register */ +#define TIMER7_WIDTH 0xFFC0067C /* Timer7 Width register */ + +#define TMRS8_ENABLE 0xFFC00680 /* Timer Enable Register */ +#define TMRS8_DISABLE 0xFFC00684 /* Timer Disable register */ +#define TMRS8_STATUS 0xFFC00688 /* Timer Status register */ + +/* Timer registers 8-11 (0xFFC0 1600-0xFFC0 16FF) */ +#define TIMER8_CONFIG 0xFFC01600 /* Timer8 Configuration register */ +#define TIMER8_COUNTER 0xFFC01604 /* Timer8 Counter register */ +#define TIMER8_PERIOD 0xFFC01608 /* Timer8 Period register */ +#define TIMER8_WIDTH 0xFFC0160C /* Timer8 Width register */ + +#define TIMER9_CONFIG 0xFFC01610 /* Timer9 Configuration register */ +#define TIMER9_COUNTER 0xFFC01614 /* Timer9 Counter register */ +#define TIMER9_PERIOD 0xFFC01618 /* Timer9 Period register */ +#define TIMER9_WIDTH 0xFFC0161C /* Timer9 Width register */ + +#define TIMER10_CONFIG 0xFFC01620 /* Timer10 Configuration register */ +#define TIMER10_COUNTER 0xFFC01624 /* Timer10 Counter register */ +#define TIMER10_PERIOD 0xFFC01628 /* Timer10 Period register */ +#define TIMER10_WIDTH 0xFFC0162C /* Timer10 Width register */ + +#define TIMER11_CONFIG 0xFFC01630 /* Timer11 Configuration register */ +#define TIMER11_COUNTER 0xFFC01634 /* Timer11 Counter register */ +#define TIMER11_PERIOD 0xFFC01638 /* Timer11 Period register */ +#define TIMER11_WIDTH 0xFFC0163C /* Timer11 Width register */ + +#define TMRS4_ENABLE 0xFFC01640 /* Timer Enable Register */ +#define TMRS4_DISABLE 0xFFC01644 /* Timer Disable register */ +#define TMRS4_STATUS 0xFFC01648 /* Timer Status register */ + +/* Programmable Flag 0 registers (0xFFC0 0700-0xFFC0 07FF) */ +#define FIO0_FLAG_D 0xFFC00700 /* Flag Data register */ +#define FIO0_FLAG_C 0xFFC00704 /* Flag Clear register */ +#define FIO0_FLAG_S 0xFFC00708 /* Flag Set register */ +#define FIO0_FLAG_T 0xFFC0070C /* Flag Toggle register */ +#define FIO0_MASKA_D 0xFFC00710 /* Flag Mask Interrupt A Data register */ +#define FIO0_MASKA_C 0xFFC00714 /* Flag Mask Interrupt A Clear register */ +#define FIO0_MASKA_S 0xFFC00718 /* Flag Mask Interrupt A Set register */ +#define FIO0_MASKA_T 0xFFC0071C /* Flag Mask Interrupt A Toggle register */ +#define FIO0_MASKB_D 0xFFC00720 /* Flag Mask Interrupt B Data register */ +#define FIO0_MASKB_C 0xFFC00724 /* Flag Mask Interrupt B Clear register */ +#define FIO0_MASKB_S 0xFFC00728 /* Flag Mask Interrupt B Set register */ +#define FIO0_MASKB_T 0xFFC0072C /* Flag Mask Interrupt B Toggle register */ +#define FIO0_DIR 0xFFC00730 /* Flag Direction register */ +#define FIO0_POLAR 0xFFC00734 /* Flag Polarity register */ +#define FIO0_EDGE 0xFFC00738 /* Flag Interrupt Sensitivity register */ +#define FIO0_BOTH 0xFFC0073C /* Flag Set on Both Edges register */ +#define FIO0_INEN 0xFFC00740 /* Flag Input Enable register */ + +/* Programmable Flag 1 registers (0xFFC0 1500-0xFFC0 15FF) */ +#define FIO1_FLAG_D 0xFFC01500 /* Flag Data register (mask used to directly */ +#define FIO1_FLAG_C 0xFFC01504 /* Flag Clear register */ +#define FIO1_FLAG_S 0xFFC01508 /* Flag Set register */ +#define FIO1_FLAG_T 0xFFC0150C /* Flag Toggle register (mask used to */ +#define FIO1_MASKA_D 0xFFC01510 /* Flag Mask Interrupt A Data register */ +#define FIO1_MASKA_C 0xFFC01514 /* Flag Mask Interrupt A Clear register */ +#define FIO1_MASKA_S 0xFFC01518 /* Flag Mask Interrupt A Set register */ +#define FIO1_MASKA_T 0xFFC0151C /* Flag Mask Interrupt A Toggle register */ +#define FIO1_MASKB_D 0xFFC01520 /* Flag Mask Interrupt B Data register */ +#define FIO1_MASKB_C 0xFFC01524 /* Flag Mask Interrupt B Clear register */ +#define FIO1_MASKB_S 0xFFC01528 /* Flag Mask Interrupt B Set register */ +#define FIO1_MASKB_T 0xFFC0152C /* Flag Mask Interrupt B Toggle register */ +#define FIO1_DIR 0xFFC01530 /* Flag Direction register */ +#define FIO1_POLAR 0xFFC01534 /* Flag Polarity register */ +#define FIO1_EDGE 0xFFC01538 /* Flag Interrupt Sensitivity register */ +#define FIO1_BOTH 0xFFC0153C /* Flag Set on Both Edges register */ +#define FIO1_INEN 0xFFC01540 /* Flag Input Enable register */ + +/* Programmable Flag registers (0xFFC0 1700-0xFFC0 17FF) */ +#define FIO2_FLAG_D 0xFFC01700 /* Flag Data register (mask used to directly */ +#define FIO2_FLAG_C 0xFFC01704 /* Flag Clear register */ +#define FIO2_FLAG_S 0xFFC01708 /* Flag Set register */ +#define FIO2_FLAG_T 0xFFC0170C /* Flag Toggle register (mask used to */ +#define FIO2_MASKA_D 0xFFC01710 /* Flag Mask Interrupt A Data register */ +#define FIO2_MASKA_C 0xFFC01714 /* Flag Mask Interrupt A Clear register */ +#define FIO2_MASKA_S 0xFFC01718 /* Flag Mask Interrupt A Set register */ +#define FIO2_MASKA_T 0xFFC0171C /* Flag Mask Interrupt A Toggle register */ +#define FIO2_MASKB_D 0xFFC01720 /* Flag Mask Interrupt B Data register */ +#define FIO2_MASKB_C 0xFFC01724 /* Flag Mask Interrupt B Clear register */ +#define FIO2_MASKB_S 0xFFC01728 /* Flag Mask Interrupt B Set register */ +#define FIO2_MASKB_T 0xFFC0172C /* Flag Mask Interrupt B Toggle register */ +#define FIO2_DIR 0xFFC01730 /* Flag Direction register */ +#define FIO2_POLAR 0xFFC01734 /* Flag Polarity register */ +#define FIO2_EDGE 0xFFC01738 /* Flag Interrupt Sensitivity register */ +#define FIO2_BOTH 0xFFC0173C /* Flag Set on Both Edges register */ +#define FIO2_INEN 0xFFC01740 /* Flag Input Enable register */ + +/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */ +#define SPORT0_TCR1 0xFFC00800 /* SPORT0 Transmit Configuration 1 Register */ +#define SPORT0_TCR2 0xFFC00804 /* SPORT0 Transmit Configuration 2 Register */ +#define SPORT0_TCLKDIV 0xFFC00808 /* SPORT0 Transmit Clock Divider */ +#define SPORT0_TFSDIV 0xFFC0080C /* SPORT0 Transmit Frame Sync Divider */ +#define SPORT0_TX 0xFFC00810 /* SPORT0 TX Data Register */ +#define SPORT0_RX 0xFFC00818 /* SPORT0 RX Data Register */ +#define SPORT0_RCR1 0xFFC00820 /* SPORT0 Transmit Configuration 1 Register */ +#define SPORT0_RCR2 0xFFC00824 /* SPORT0 Transmit Configuration 2 Register */ +#define SPORT0_RCLKDIV 0xFFC00828 /* SPORT0 Receive Clock Divider */ +#define SPORT0_RFSDIV 0xFFC0082C /* SPORT0 Receive Frame Sync Divider */ +#define SPORT0_STAT 0xFFC00830 /* SPORT0 Status Register */ +#define SPORT0_CHNL 0xFFC00834 /* SPORT0 Current Channel Register */ +#define SPORT0_MCMC1 0xFFC00838 /* SPORT0 Multi-Channel Configuration Register 1 */ +#define SPORT0_MCMC2 0xFFC0083C /* SPORT0 Multi-Channel Configuration Register 2 */ +#define SPORT0_MTCS0 0xFFC00840 /* SPORT0 Multi-Channel Transmit Select Register 0 */ +#define SPORT0_MTCS1 0xFFC00844 /* SPORT0 Multi-Channel Transmit Select Register 1 */ +#define SPORT0_MTCS2 0xFFC00848 /* SPORT0 Multi-Channel Transmit Select Register 2 */ +#define SPORT0_MTCS3 0xFFC0084C /* SPORT0 Multi-Channel Transmit Select Register 3 */ +#define SPORT0_MRCS0 0xFFC00850 /* SPORT0 Multi-Channel Receive Select Register 0 */ +#define SPORT0_MRCS1 0xFFC00854 /* SPORT0 Multi-Channel Receive Select Register 1 */ +#define SPORT0_MRCS2 0xFFC00858 /* SPORT0 Multi-Channel Receive Select Register 2 */ +#define SPORT0_MRCS3 0xFFC0085C /* SPORT0 Multi-Channel Receive Select Register 3 */ + +/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */ +#define SPORT1_TCR1 0xFFC00900 /* SPORT1 Transmit Configuration 1 Register */ +#define SPORT1_TCR2 0xFFC00904 /* SPORT1 Transmit Configuration 2 Register */ +#define SPORT1_TCLKDIV 0xFFC00908 /* SPORT1 Transmit Clock Divider */ +#define SPORT1_TFSDIV 0xFFC0090C /* SPORT1 Transmit Frame Sync Divider */ +#define SPORT1_TX 0xFFC00910 /* SPORT1 TX Data Register */ +#define SPORT1_RX 0xFFC00918 /* SPORT1 RX Data Register */ +#define SPORT1_RCR1 0xFFC00920 /* SPORT1 Transmit Configuration 1 Register */ +#define SPORT1_RCR2 0xFFC00924 /* SPORT1 Transmit Configuration 2 Register */ +#define SPORT1_RCLKDIV 0xFFC00928 /* SPORT1 Receive Clock Divider */ +#define SPORT1_RFSDIV 0xFFC0092C /* SPORT1 Receive Frame Sync Divider */ +#define SPORT1_STAT 0xFFC00930 /* SPORT1 Status Register */ +#define SPORT1_CHNL 0xFFC00934 /* SPORT1 Current Channel Register */ +#define SPORT1_MCMC1 0xFFC00938 /* SPORT1 Multi-Channel Configuration Register 1 */ +#define SPORT1_MCMC2 0xFFC0093C /* SPORT1 Multi-Channel Configuration Register 2 */ +#define SPORT1_MTCS0 0xFFC00940 /* SPORT1 Multi-Channel Transmit Select Register 0 */ +#define SPORT1_MTCS1 0xFFC00944 /* SPORT1 Multi-Channel Transmit Select Register 1 */ +#define SPORT1_MTCS2 0xFFC00948 /* SPORT1 Multi-Channel Transmit Select Register 2 */ +#define SPORT1_MTCS3 0xFFC0094C /* SPORT1 Multi-Channel Transmit Select Register 3 */ +#define SPORT1_MRCS0 0xFFC00950 /* SPORT1 Multi-Channel Receive Select Register 0 */ +#define SPORT1_MRCS1 0xFFC00954 /* SPORT1 Multi-Channel Receive Select Register 1 */ +#define SPORT1_MRCS2 0xFFC00958 /* SPORT1 Multi-Channel Receive Select Register 2 */ +#define SPORT1_MRCS3 0xFFC0095C /* SPORT1 Multi-Channel Receive Select Register 3 */ + +/* Asynchronous Memory Controller - External Bus Interface Unit */ +#define EBIU_AMGCTL 0xFFC00A00 /* Asynchronous Memory Global Control Register */ +#define EBIU_AMBCTL0 0xFFC00A04 /* Asynchronous Memory Bank Control Register 0 */ +#define EBIU_AMBCTL1 0xFFC00A08 /* Asynchronous Memory Bank Control Register 1 */ + +/* SDRAM Controller External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */ +#define EBIU_SDGCTL 0xFFC00A10 /* SDRAM Global Control Register */ +#define EBIU_SDBCTL 0xFFC00A14 /* SDRAM Bank Control Register */ +#define EBIU_SDRRC 0xFFC00A18 /* SDRAM Refresh Rate Control Register */ +#define EBIU_SDSTAT 0xFFC00A1C /* SDRAM Status Register */ + +/* Parallel Peripheral Interface (PPI) 0 registers (0xFFC0 1000-0xFFC0 10FF) */ +#define PPI0_CONTROL 0xFFC01000 /* PPI0 Control register */ +#define PPI0_STATUS 0xFFC01004 /* PPI0 Status register */ +#define PPI0_COUNT 0xFFC01008 /* PPI0 Transfer Count register */ +#define PPI0_DELAY 0xFFC0100C /* PPI0 Delay Count register */ +#define PPI0_FRAME 0xFFC01010 /* PPI0 Frame Length register */ + +/*Parallel Peripheral Interface (PPI) 1 registers (0xFFC0 1300-0xFFC0 13FF) */ +#define PPI1_CONTROL 0xFFC01300 /* PPI1 Control register */ +#define PPI1_STATUS 0xFFC01304 /* PPI1 Status register */ +#define PPI1_COUNT 0xFFC01308 /* PPI1 Transfer Count register */ +#define PPI1_DELAY 0xFFC0130C /* PPI1 Delay Count register */ +#define PPI1_FRAME 0xFFC01310 /* PPI1 Frame Length register */ + +/*DMA traffic control registers */ +#define DMA1_TC_PER 0xFFC01B0C /* Traffic control periods */ +#define DMA1_TC_CNT 0xFFC01B10 /* Traffic control current counts */ +#define DMA2_TC_PER 0xFFC00B0C /* Traffic control periods */ +#define DMA2_TC_CNT 0xFFC00B10 /* Traffic control current counts */ + +/* DMA1 Controller registers (0xFFC0 1C00-0xFFC0 1FFF) */ +#define DMA1_0_CONFIG 0xFFC01C08 /* DMA1 Channel 0 Configuration register */ +#define DMA1_0_NEXT_DESC_PTR 0xFFC01C00 /* DMA1 Channel 0 Next Descripter Ptr Reg */ +#define DMA1_0_START_ADDR 0xFFC01C04 /* DMA1 Channel 0 Start Address */ +#define DMA1_0_X_COUNT 0xFFC01C10 /* DMA1 Channel 0 Inner Loop Count */ +#define DMA1_0_Y_COUNT 0xFFC01C18 /* DMA1 Channel 0 Outer Loop Count */ +#define DMA1_0_X_MODIFY 0xFFC01C14 /* DMA1 Channel 0 Inner Loop Addr Increment */ +#define DMA1_0_Y_MODIFY 0xFFC01C1C /* DMA1 Channel 0 Outer Loop Addr Increment */ +#define DMA1_0_CURR_DESC_PTR 0xFFC01C20 /* DMA1 Channel 0 Current Descriptor Pointer */ +#define DMA1_0_CURR_ADDR 0xFFC01C24 /* DMA1 Channel 0 Current Address Pointer */ +#define DMA1_0_CURR_X_COUNT 0xFFC01C30 /* DMA1 Channel 0 Current Inner Loop Count */ +#define DMA1_0_CURR_Y_COUNT 0xFFC01C38 /* DMA1 Channel 0 Current Outer Loop Count */ +#define DMA1_0_IRQ_STATUS 0xFFC01C28 /* DMA1 Channel 0 Interrupt/Status Register */ +#define DMA1_0_PERIPHERAL_MAP 0xFFC01C2C /* DMA1 Channel 0 Peripheral Map Register */ + +#define DMA1_1_CONFIG 0xFFC01C48 /* DMA1 Channel 1 Configuration register */ +#define DMA1_1_NEXT_DESC_PTR 0xFFC01C40 /* DMA1 Channel 1 Next Descripter Ptr Reg */ +#define DMA1_1_START_ADDR 0xFFC01C44 /* DMA1 Channel 1 Start Address */ +#define DMA1_1_X_COUNT 0xFFC01C50 /* DMA1 Channel 1 Inner Loop Count */ +#define DMA1_1_Y_COUNT 0xFFC01C58 /* DMA1 Channel 1 Outer Loop Count */ +#define DMA1_1_X_MODIFY 0xFFC01C54 /* DMA1 Channel 1 Inner Loop Addr Increment */ +#define DMA1_1_Y_MODIFY 0xFFC01C5C /* DMA1 Channel 1 Outer Loop Addr Increment */ +#define DMA1_1_CURR_DESC_PTR 0xFFC01C60 /* DMA1 Channel 1 Current Descriptor Pointer */ +#define DMA1_1_CURR_ADDR 0xFFC01C64 /* DMA1 Channel 1 Current Address Pointer */ +#define DMA1_1_CURR_X_COUNT 0xFFC01C70 /* DMA1 Channel 1 Current Inner Loop Count */ +#define DMA1_1_CURR_Y_COUNT 0xFFC01C78 /* DMA1 Channel 1 Current Outer Loop Count */ +#define DMA1_1_IRQ_STATUS 0xFFC01C68 /* DMA1 Channel 1 Interrupt/Status Register */ +#define DMA1_1_PERIPHERAL_MAP 0xFFC01C6C /* DMA1 Channel 1 Peripheral Map Register */ + +#define DMA1_2_CONFIG 0xFFC01C88 /* DMA1 Channel 2 Configuration register */ +#define DMA1_2_NEXT_DESC_PTR 0xFFC01C80 /* DMA1 Channel 2 Next Descripter Ptr Reg */ +#define DMA1_2_START_ADDR 0xFFC01C84 /* DMA1 Channel 2 Start Address */ +#define DMA1_2_X_COUNT 0xFFC01C90 /* DMA1 Channel 2 Inner Loop Count */ +#define DMA1_2_Y_COUNT 0xFFC01C98 /* DMA1 Channel 2 Outer Loop Count */ +#define DMA1_2_X_MODIFY 0xFFC01C94 /* DMA1 Channel 2 Inner Loop Addr Increment */ +#define DMA1_2_Y_MODIFY 0xFFC01C9C /* DMA1 Channel 2 Outer Loop Addr Increment */ +#define DMA1_2_CURR_DESC_PTR 0xFFC01CA0 /* DMA1 Channel 2 Current Descriptor Pointer */ +#define DMA1_2_CURR_ADDR 0xFFC01CA4 /* DMA1 Channel 2 Current Address Pointer */ +#define DMA1_2_CURR_X_COUNT 0xFFC01CB0 /* DMA1 Channel 2 Current Inner Loop Count */ +#define DMA1_2_CURR_Y_COUNT 0xFFC01CB8 /* DMA1 Channel 2 Current Outer Loop Count */ +#define DMA1_2_IRQ_STATUS 0xFFC01CA8 /* DMA1 Channel 2 Interrupt/Status Register */ +#define DMA1_2_PERIPHERAL_MAP 0xFFC01CAC /* DMA1 Channel 2 Peripheral Map Register */ + +#define DMA1_3_CONFIG 0xFFC01CC8 /* DMA1 Channel 3 Configuration register */ +#define DMA1_3_NEXT_DESC_PTR 0xFFC01CC0 /* DMA1 Channel 3 Next Descripter Ptr Reg */ +#define DMA1_3_START_ADDR 0xFFC01CC4 /* DMA1 Channel 3 Start Address */ +#define DMA1_3_X_COUNT 0xFFC01CD0 /* DMA1 Channel 3 Inner Loop Count */ +#define DMA1_3_Y_COUNT 0xFFC01CD8 /* DMA1 Channel 3 Outer Loop Count */ +#define DMA1_3_X_MODIFY 0xFFC01CD4 /* DMA1 Channel 3 Inner Loop Addr Increment */ +#define DMA1_3_Y_MODIFY 0xFFC01CDC /* DMA1 Channel 3 Outer Loop Addr Increment */ +#define DMA1_3_CURR_DESC_PTR 0xFFC01CE0 /* DMA1 Channel 3 Current Descriptor Pointer */ +#define DMA1_3_CURR_ADDR 0xFFC01CE4 /* DMA1 Channel 3 Current Address Pointer */ +#define DMA1_3_CURR_X_COUNT 0xFFC01CF0 /* DMA1 Channel 3 Current Inner Loop Count */ +#define DMA1_3_CURR_Y_COUNT 0xFFC01CF8 /* DMA1 Channel 3 Current Outer Loop Count */ +#define DMA1_3_IRQ_STATUS 0xFFC01CE8 /* DMA1 Channel 3 Interrupt/Status Register */ +#define DMA1_3_PERIPHERAL_MAP 0xFFC01CEC /* DMA1 Channel 3 Peripheral Map Register */ + +#define DMA1_4_CONFIG 0xFFC01D08 /* DMA1 Channel 4 Configuration register */ +#define DMA1_4_NEXT_DESC_PTR 0xFFC01D00 /* DMA1 Channel 4 Next Descripter Ptr Reg */ +#define DMA1_4_START_ADDR 0xFFC01D04 /* DMA1 Channel 4 Start Address */ +#define DMA1_4_X_COUNT 0xFFC01D10 /* DMA1 Channel 4 Inner Loop Count */ +#define DMA1_4_Y_COUNT 0xFFC01D18 /* DMA1 Channel 4 Outer Loop Count */ +#define DMA1_4_X_MODIFY 0xFFC01D14 /* DMA1 Channel 4 Inner Loop Addr Increment */ +#define DMA1_4_Y_MODIFY 0xFFC01D1C /* DMA1 Channel 4 Outer Loop Addr Increment */ +#define DMA1_4_CURR_DESC_PTR 0xFFC01D20 /* DMA1 Channel 4 Current Descriptor Pointer */ +#define DMA1_4_CURR_ADDR 0xFFC01D24 /* DMA1 Channel 4 Current Address Pointer */ +#define DMA1_4_CURR_X_COUNT 0xFFC01D30 /* DMA1 Channel 4 Current Inner Loop Count */ +#define DMA1_4_CURR_Y_COUNT 0xFFC01D38 /* DMA1 Channel 4 Current Outer Loop Count */ +#define DMA1_4_IRQ_STATUS 0xFFC01D28 /* DMA1 Channel 4 Interrupt/Status Register */ +#define DMA1_4_PERIPHERAL_MAP 0xFFC01D2C /* DMA1 Channel 4 Peripheral Map Register */ + +#define DMA1_5_CONFIG 0xFFC01D48 /* DMA1 Channel 5 Configuration register */ +#define DMA1_5_NEXT_DESC_PTR 0xFFC01D40 /* DMA1 Channel 5 Next Descripter Ptr Reg */ +#define DMA1_5_START_ADDR 0xFFC01D44 /* DMA1 Channel 5 Start Address */ +#define DMA1_5_X_COUNT 0xFFC01D50 /* DMA1 Channel 5 Inner Loop Count */ +#define DMA1_5_Y_COUNT 0xFFC01D58 /* DMA1 Channel 5 Outer Loop Count */ +#define DMA1_5_X_MODIFY 0xFFC01D54 /* DMA1 Channel 5 Inner Loop Addr Increment */ +#define DMA1_5_Y_MODIFY 0xFFC01D5C /* DMA1 Channel 5 Outer Loop Addr Increment */ +#define DMA1_5_CURR_DESC_PTR 0xFFC01D60 /* DMA1 Channel 5 Current Descriptor Pointer */ +#define DMA1_5_CURR_ADDR 0xFFC01D64 /* DMA1 Channel 5 Current Address Pointer */ +#define DMA1_5_CURR_X_COUNT 0xFFC01D70 /* DMA1 Channel 5 Current Inner Loop Count */ +#define DMA1_5_CURR_Y_COUNT 0xFFC01D78 /* DMA1 Channel 5 Current Outer Loop Count */ +#define DMA1_5_IRQ_STATUS 0xFFC01D68 /* DMA1 Channel 5 Interrupt/Status Register */ +#define DMA1_5_PERIPHERAL_MAP 0xFFC01D6C /* DMA1 Channel 5 Peripheral Map Register */ + +#define DMA1_6_CONFIG 0xFFC01D88 /* DMA1 Channel 6 Configuration register */ +#define DMA1_6_NEXT_DESC_PTR 0xFFC01D80 /* DMA1 Channel 6 Next Descripter Ptr Reg */ +#define DMA1_6_START_ADDR 0xFFC01D84 /* DMA1 Channel 6 Start Address */ +#define DMA1_6_X_COUNT 0xFFC01D90 /* DMA1 Channel 6 Inner Loop Count */ +#define DMA1_6_Y_COUNT 0xFFC01D98 /* DMA1 Channel 6 Outer Loop Count */ +#define DMA1_6_X_MODIFY 0xFFC01D94 /* DMA1 Channel 6 Inner Loop Addr Increment */ +#define DMA1_6_Y_MODIFY 0xFFC01D9C /* DMA1 Channel 6 Outer Loop Addr Increment */ +#define DMA1_6_CURR_DESC_PTR 0xFFC01DA0 /* DMA1 Channel 6 Current Descriptor Pointer */ +#define DMA1_6_CURR_ADDR 0xFFC01DA4 /* DMA1 Channel 6 Current Address Pointer */ +#define DMA1_6_CURR_X_COUNT 0xFFC01DB0 /* DMA1 Channel 6 Current Inner Loop Count */ +#define DMA1_6_CURR_Y_COUNT 0xFFC01DB8 /* DMA1 Channel 6 Current Outer Loop Count */ +#define DMA1_6_IRQ_STATUS 0xFFC01DA8 /* DMA1 Channel 6 Interrupt/Status Register */ +#define DMA1_6_PERIPHERAL_MAP 0xFFC01DAC /* DMA1 Channel 6 Peripheral Map Register */ + +#define DMA1_7_CONFIG 0xFFC01DC8 /* DMA1 Channel 7 Configuration register */ +#define DMA1_7_NEXT_DESC_PTR 0xFFC01DC0 /* DMA1 Channel 7 Next Descripter Ptr Reg */ +#define DMA1_7_START_ADDR 0xFFC01DC4 /* DMA1 Channel 7 Start Address */ +#define DMA1_7_X_COUNT 0xFFC01DD0 /* DMA1 Channel 7 Inner Loop Count */ +#define DMA1_7_Y_COUNT 0xFFC01DD8 /* DMA1 Channel 7 Outer Loop Count */ +#define DMA1_7_X_MODIFY 0xFFC01DD4 /* DMA1 Channel 7 Inner Loop Addr Increment */ +#define DMA1_7_Y_MODIFY 0xFFC01DDC /* DMA1 Channel 7 Outer Loop Addr Increment */ +#define DMA1_7_CURR_DESC_PTR 0xFFC01DE0 /* DMA1 Channel 7 Current Descriptor Pointer */ +#define DMA1_7_CURR_ADDR 0xFFC01DE4 /* DMA1 Channel 7 Current Address Pointer */ +#define DMA1_7_CURR_X_COUNT 0xFFC01DF0 /* DMA1 Channel 7 Current Inner Loop Count */ +#define DMA1_7_CURR_Y_COUNT 0xFFC01DF8 /* DMA1 Channel 7 Current Outer Loop Count */ +#define DMA1_7_IRQ_STATUS 0xFFC01DE8 /* DMA1 Channel 7 Interrupt/Status Register */ +#define DMA1_7_PERIPHERAL_MAP 0xFFC01DEC /* DMA1 Channel 7 Peripheral Map Register */ + +#define DMA1_8_CONFIG 0xFFC01E08 /* DMA1 Channel 8 Configuration register */ +#define DMA1_8_NEXT_DESC_PTR 0xFFC01E00 /* DMA1 Channel 8 Next Descripter Ptr Reg */ +#define DMA1_8_START_ADDR 0xFFC01E04 /* DMA1 Channel 8 Start Address */ +#define DMA1_8_X_COUNT 0xFFC01E10 /* DMA1 Channel 8 Inner Loop Count */ +#define DMA1_8_Y_COUNT 0xFFC01E18 /* DMA1 Channel 8 Outer Loop Count */ +#define DMA1_8_X_MODIFY 0xFFC01E14 /* DMA1 Channel 8 Inner Loop Addr Increment */ +#define DMA1_8_Y_MODIFY 0xFFC01E1C /* DMA1 Channel 8 Outer Loop Addr Increment */ +#define DMA1_8_CURR_DESC_PTR 0xFFC01E20 /* DMA1 Channel 8 Current Descriptor Pointer */ +#define DMA1_8_CURR_ADDR 0xFFC01E24 /* DMA1 Channel 8 Current Address Pointer */ +#define DMA1_8_CURR_X_COUNT 0xFFC01E30 /* DMA1 Channel 8 Current Inner Loop Count */ +#define DMA1_8_CURR_Y_COUNT 0xFFC01E38 /* DMA1 Channel 8 Current Outer Loop Count */ +#define DMA1_8_IRQ_STATUS 0xFFC01E28 /* DMA1 Channel 8 Interrupt/Status Register */ +#define DMA1_8_PERIPHERAL_MAP 0xFFC01E2C /* DMA1 Channel 8 Peripheral Map Register */ + +#define DMA1_9_CONFIG 0xFFC01E48 /* DMA1 Channel 9 Configuration register */ +#define DMA1_9_NEXT_DESC_PTR 0xFFC01E40 /* DMA1 Channel 9 Next Descripter Ptr Reg */ +#define DMA1_9_START_ADDR 0xFFC01E44 /* DMA1 Channel 9 Start Address */ +#define DMA1_9_X_COUNT 0xFFC01E50 /* DMA1 Channel 9 Inner Loop Count */ +#define DMA1_9_Y_COUNT 0xFFC01E58 /* DMA1 Channel 9 Outer Loop Count */ +#define DMA1_9_X_MODIFY 0xFFC01E54 /* DMA1 Channel 9 Inner Loop Addr Increment */ +#define DMA1_9_Y_MODIFY 0xFFC01E5C /* DMA1 Channel 9 Outer Loop Addr Increment */ +#define DMA1_9_CURR_DESC_PTR 0xFFC01E60 /* DMA1 Channel 9 Current Descriptor Pointer */ +#define DMA1_9_CURR_ADDR 0xFFC01E64 /* DMA1 Channel 9 Current Address Pointer */ +#define DMA1_9_CURR_X_COUNT 0xFFC01E70 /* DMA1 Channel 9 Current Inner Loop Count */ +#define DMA1_9_CURR_Y_COUNT 0xFFC01E78 /* DMA1 Channel 9 Current Outer Loop Count */ +#define DMA1_9_IRQ_STATUS 0xFFC01E68 /* DMA1 Channel 9 Interrupt/Status Register */ +#define DMA1_9_PERIPHERAL_MAP 0xFFC01E6C /* DMA1 Channel 9 Peripheral Map Register */ + +#define DMA1_10_CONFIG 0xFFC01E88 /* DMA1 Channel 10 Configuration register */ +#define DMA1_10_NEXT_DESC_PTR 0xFFC01E80 /* DMA1 Channel 10 Next Descripter Ptr Reg */ +#define DMA1_10_START_ADDR 0xFFC01E84 /* DMA1 Channel 10 Start Address */ +#define DMA1_10_X_COUNT 0xFFC01E90 /* DMA1 Channel 10 Inner Loop Count */ +#define DMA1_10_Y_COUNT 0xFFC01E98 /* DMA1 Channel 10 Outer Loop Count */ +#define DMA1_10_X_MODIFY 0xFFC01E94 /* DMA1 Channel 10 Inner Loop Addr Increment */ +#define DMA1_10_Y_MODIFY 0xFFC01E9C /* DMA1 Channel 10 Outer Loop Addr Increment */ +#define DMA1_10_CURR_DESC_PTR 0xFFC01EA0 /* DMA1 Channel 10 Current Descriptor Pointer */ +#define DMA1_10_CURR_ADDR 0xFFC01EA4 /* DMA1 Channel 10 Current Address Pointer */ +#define DMA1_10_CURR_X_COUNT 0xFFC01EB0 /* DMA1 Channel 10 Current Inner Loop Count */ +#define DMA1_10_CURR_Y_COUNT 0xFFC01EB8 /* DMA1 Channel 10 Current Outer Loop Count */ +#define DMA1_10_IRQ_STATUS 0xFFC01EA8 /* DMA1 Channel 10 Interrupt/Status Register */ +#define DMA1_10_PERIPHERAL_MAP 0xFFC01EAC /* DMA1 Channel 10 Peripheral Map Register */ + +#define DMA1_11_CONFIG 0xFFC01EC8 /* DMA1 Channel 11 Configuration register */ +#define DMA1_11_NEXT_DESC_PTR 0xFFC01EC0 /* DMA1 Channel 11 Next Descripter Ptr Reg */ +#define DMA1_11_START_ADDR 0xFFC01EC4 /* DMA1 Channel 11 Start Address */ +#define DMA1_11_X_COUNT 0xFFC01ED0 /* DMA1 Channel 11 Inner Loop Count */ +#define DMA1_11_Y_COUNT 0xFFC01ED8 /* DMA1 Channel 11 Outer Loop Count */ +#define DMA1_11_X_MODIFY 0xFFC01ED4 /* DMA1 Channel 11 Inner Loop Addr Increment */ +#define DMA1_11_Y_MODIFY 0xFFC01EDC /* DMA1 Channel 11 Outer Loop Addr Increment */ +#define DMA1_11_CURR_DESC_PTR 0xFFC01EE0 /* DMA1 Channel 11 Current Descriptor Pointer */ +#define DMA1_11_CURR_ADDR 0xFFC01EE4 /* DMA1 Channel 11 Current Address Pointer */ +#define DMA1_11_CURR_X_COUNT 0xFFC01EF0 /* DMA1 Channel 11 Current Inner Loop Count */ +#define DMA1_11_CURR_Y_COUNT 0xFFC01EF8 /* DMA1 Channel 11 Current Outer Loop Count */ +#define DMA1_11_IRQ_STATUS 0xFFC01EE8 /* DMA1 Channel 11 Interrupt/Status Register */ +#define DMA1_11_PERIPHERAL_MAP 0xFFC01EEC /* DMA1 Channel 11 Peripheral Map Register */ + +/* Memory DMA1 Controller registers (0xFFC0 1E80-0xFFC0 1FFF) */ +#define MDMA1_D0_CONFIG 0xFFC01F08 /*MemDMA1 Stream 0 Destination Configuration */ +#define MDMA1_D0_NEXT_DESC_PTR 0xFFC01F00 /*MemDMA1 Stream 0 Destination Next Descriptor Ptr Reg */ +#define MDMA1_D0_START_ADDR 0xFFC01F04 /*MemDMA1 Stream 0 Destination Start Address */ +#define MDMA1_D0_X_COUNT 0xFFC01F10 /*MemDMA1 Stream 0 Destination Inner-Loop Count */ +#define MDMA1_D0_Y_COUNT 0xFFC01F18 /*MemDMA1 Stream 0 Destination Outer-Loop Count */ +#define MDMA1_D0_X_MODIFY 0xFFC01F14 /*MemDMA1 Stream 0 Dest Inner-Loop Address-Increment */ +#define MDMA1_D0_Y_MODIFY 0xFFC01F1C /*MemDMA1 Stream 0 Dest Outer-Loop Address-Increment */ +#define MDMA1_D0_CURR_DESC_PTR 0xFFC01F20 /*MemDMA1 Stream 0 Dest Current Descriptor Ptr reg */ +#define MDMA1_D0_CURR_ADDR 0xFFC01F24 /*MemDMA1 Stream 0 Destination Current Address */ +#define MDMA1_D0_CURR_X_COUNT 0xFFC01F30 /*MemDMA1 Stream 0 Dest Current Inner-Loop Count */ +#define MDMA1_D0_CURR_Y_COUNT 0xFFC01F38 /*MemDMA1 Stream 0 Dest Current Outer-Loop Count */ +#define MDMA1_D0_IRQ_STATUS 0xFFC01F28 /*MemDMA1 Stream 0 Destination Interrupt/Status */ +#define MDMA1_D0_PERIPHERAL_MAP 0xFFC01F2C /*MemDMA1 Stream 0 Destination Peripheral Map */ + +#define MDMA1_S0_CONFIG 0xFFC01F48 /*MemDMA1 Stream 0 Source Configuration */ +#define MDMA1_S0_NEXT_DESC_PTR 0xFFC01F40 /*MemDMA1 Stream 0 Source Next Descriptor Ptr Reg */ +#define MDMA1_S0_START_ADDR 0xFFC01F44 /*MemDMA1 Stream 0 Source Start Address */ +#define MDMA1_S0_X_COUNT 0xFFC01F50 /*MemDMA1 Stream 0 Source Inner-Loop Count */ +#define MDMA1_S0_Y_COUNT 0xFFC01F58 /*MemDMA1 Stream 0 Source Outer-Loop Count */ +#define MDMA1_S0_X_MODIFY 0xFFC01F54 /*MemDMA1 Stream 0 Source Inner-Loop Address-Increment */ +#define MDMA1_S0_Y_MODIFY 0xFFC01F5C /*MemDMA1 Stream 0 Source Outer-Loop Address-Increment */ +#define MDMA1_S0_CURR_DESC_PTR 0xFFC01F60 /*MemDMA1 Stream 0 Source Current Descriptor Ptr reg */ +#define MDMA1_S0_CURR_ADDR 0xFFC01F64 /*MemDMA1 Stream 0 Source Current Address */ +#define MDMA1_S0_CURR_X_COUNT 0xFFC01F70 /*MemDMA1 Stream 0 Source Current Inner-Loop Count */ +#define MDMA1_S0_CURR_Y_COUNT 0xFFC01F78 /*MemDMA1 Stream 0 Source Current Outer-Loop Count */ +#define MDMA1_S0_IRQ_STATUS 0xFFC01F68 /*MemDMA1 Stream 0 Source Interrupt/Status */ +#define MDMA1_S0_PERIPHERAL_MAP 0xFFC01F6C /*MemDMA1 Stream 0 Source Peripheral Map */ + +#define MDMA1_D1_CONFIG 0xFFC01F88 /*MemDMA1 Stream 1 Destination Configuration */ +#define MDMA1_D1_NEXT_DESC_PTR 0xFFC01F80 /*MemDMA1 Stream 1 Destination Next Descriptor Ptr Reg */ +#define MDMA1_D1_START_ADDR 0xFFC01F84 /*MemDMA1 Stream 1 Destination Start Address */ +#define MDMA1_D1_X_COUNT 0xFFC01F90 /*MemDMA1 Stream 1 Destination Inner-Loop Count */ +#define MDMA1_D1_Y_COUNT 0xFFC01F98 /*MemDMA1 Stream 1 Destination Outer-Loop Count */ +#define MDMA1_D1_X_MODIFY 0xFFC01F94 /*MemDMA1 Stream 1 Dest Inner-Loop Address-Increment */ +#define MDMA1_D1_Y_MODIFY 0xFFC01F9C /*MemDMA1 Stream 1 Dest Outer-Loop Address-Increment */ +#define MDMA1_D1_CURR_DESC_PTR 0xFFC01FA0 /*MemDMA1 Stream 1 Dest Current Descriptor Ptr reg */ +#define MDMA1_D1_CURR_ADDR 0xFFC01FA4 /*MemDMA1 Stream 1 Dest Current Address */ +#define MDMA1_D1_CURR_X_COUNT 0xFFC01FB0 /*MemDMA1 Stream 1 Dest Current Inner-Loop Count */ +#define MDMA1_D1_CURR_Y_COUNT 0xFFC01FB8 /*MemDMA1 Stream 1 Dest Current Outer-Loop Count */ +#define MDMA1_D1_IRQ_STATUS 0xFFC01FA8 /*MemDMA1 Stream 1 Dest Interrupt/Status */ +#define MDMA1_D1_PERIPHERAL_MAP 0xFFC01FAC /*MemDMA1 Stream 1 Dest Peripheral Map */ + +#define MDMA1_S1_CONFIG 0xFFC01FC8 /*MemDMA1 Stream 1 Source Configuration */ +#define MDMA1_S1_NEXT_DESC_PTR 0xFFC01FC0 /*MemDMA1 Stream 1 Source Next Descriptor Ptr Reg */ +#define MDMA1_S1_START_ADDR 0xFFC01FC4 /*MemDMA1 Stream 1 Source Start Address */ +#define MDMA1_S1_X_COUNT 0xFFC01FD0 /*MemDMA1 Stream 1 Source Inner-Loop Count */ +#define MDMA1_S1_Y_COUNT 0xFFC01FD8 /*MemDMA1 Stream 1 Source Outer-Loop Count */ +#define MDMA1_S1_X_MODIFY 0xFFC01FD4 /*MemDMA1 Stream 1 Source Inner-Loop Address-Increment */ +#define MDMA1_S1_Y_MODIFY 0xFFC01FDC /*MemDMA1 Stream 1 Source Outer-Loop Address-Increment */ +#define MDMA1_S1_CURR_DESC_PTR 0xFFC01FE0 /*MemDMA1 Stream 1 Source Current Descriptor Ptr reg */ +#define MDMA1_S1_CURR_ADDR 0xFFC01FE4 /*MemDMA1 Stream 1 Source Current Address */ +#define MDMA1_S1_CURR_X_COUNT 0xFFC01FF0 /*MemDMA1 Stream 1 Source Current Inner-Loop Count */ +#define MDMA1_S1_CURR_Y_COUNT 0xFFC01FF8 /*MemDMA1 Stream 1 Source Current Outer-Loop Count */ +#define MDMA1_S1_IRQ_STATUS 0xFFC01FE8 /*MemDMA1 Stream 1 Source Interrupt/Status */ +#define MDMA1_S1_PERIPHERAL_MAP 0xFFC01FEC /*MemDMA1 Stream 1 Source Peripheral Map */ + +/* DMA2 Controller registers (0xFFC0 0C00-0xFFC0 0DFF) */ +#define DMA2_0_CONFIG 0xFFC00C08 /* DMA2 Channel 0 Configuration register */ +#define DMA2_0_NEXT_DESC_PTR 0xFFC00C00 /* DMA2 Channel 0 Next Descripter Ptr Reg */ +#define DMA2_0_START_ADDR 0xFFC00C04 /* DMA2 Channel 0 Start Address */ +#define DMA2_0_X_COUNT 0xFFC00C10 /* DMA2 Channel 0 Inner Loop Count */ +#define DMA2_0_Y_COUNT 0xFFC00C18 /* DMA2 Channel 0 Outer Loop Count */ +#define DMA2_0_X_MODIFY 0xFFC00C14 /* DMA2 Channel 0 Inner Loop Addr Increment */ +#define DMA2_0_Y_MODIFY 0xFFC00C1C /* DMA2 Channel 0 Outer Loop Addr Increment */ +#define DMA2_0_CURR_DESC_PTR 0xFFC00C20 /* DMA2 Channel 0 Current Descriptor Pointer */ +#define DMA2_0_CURR_ADDR 0xFFC00C24 /* DMA2 Channel 0 Current Address Pointer */ +#define DMA2_0_CURR_X_COUNT 0xFFC00C30 /* DMA2 Channel 0 Current Inner Loop Count */ +#define DMA2_0_CURR_Y_COUNT 0xFFC00C38 /* DMA2 Channel 0 Current Outer Loop Count */ +#define DMA2_0_IRQ_STATUS 0xFFC00C28 /* DMA2 Channel 0 Interrupt/Status Register */ +#define DMA2_0_PERIPHERAL_MAP 0xFFC00C2C /* DMA2 Channel 0 Peripheral Map Register */ + +#define DMA2_1_CONFIG 0xFFC00C48 /* DMA2 Channel 1 Configuration register */ +#define DMA2_1_NEXT_DESC_PTR 0xFFC00C40 /* DMA2 Channel 1 Next Descripter Ptr Reg */ +#define DMA2_1_START_ADDR 0xFFC00C44 /* DMA2 Channel 1 Start Address */ +#define DMA2_1_X_COUNT 0xFFC00C50 /* DMA2 Channel 1 Inner Loop Count */ +#define DMA2_1_Y_COUNT 0xFFC00C58 /* DMA2 Channel 1 Outer Loop Count */ +#define DMA2_1_X_MODIFY 0xFFC00C54 /* DMA2 Channel 1 Inner Loop Addr Increment */ +#define DMA2_1_Y_MODIFY 0xFFC00C5C /* DMA2 Channel 1 Outer Loop Addr Increment */ +#define DMA2_1_CURR_DESC_PTR 0xFFC00C60 /* DMA2 Channel 1 Current Descriptor Pointer */ +#define DMA2_1_CURR_ADDR 0xFFC00C64 /* DMA2 Channel 1 Current Address Pointer */ +#define DMA2_1_CURR_X_COUNT 0xFFC00C70 /* DMA2 Channel 1 Current Inner Loop Count */ +#define DMA2_1_CURR_Y_COUNT 0xFFC00C78 /* DMA2 Channel 1 Current Outer Loop Count */ +#define DMA2_1_IRQ_STATUS 0xFFC00C68 /* DMA2 Channel 1 Interrupt/Status Register */ +#define DMA2_1_PERIPHERAL_MAP 0xFFC00C6C /* DMA2 Channel 1 Peripheral Map Register */ + +#define DMA2_2_CONFIG 0xFFC00C88 /* DMA2 Channel 2 Configuration register */ +#define DMA2_2_NEXT_DESC_PTR 0xFFC00C80 /* DMA2 Channel 2 Next Descripter Ptr Reg */ +#define DMA2_2_START_ADDR 0xFFC00C84 /* DMA2 Channel 2 Start Address */ +#define DMA2_2_X_COUNT 0xFFC00C90 /* DMA2 Channel 2 Inner Loop Count */ +#define DMA2_2_Y_COUNT 0xFFC00C98 /* DMA2 Channel 2 Outer Loop Count */ +#define DMA2_2_X_MODIFY 0xFFC00C94 /* DMA2 Channel 2 Inner Loop Addr Increment */ +#define DMA2_2_Y_MODIFY 0xFFC00C9C /* DMA2 Channel 2 Outer Loop Addr Increment */ +#define DMA2_2_CURR_DESC_PTR 0xFFC00CA0 /* DMA2 Channel 2 Current Descriptor Pointer */ +#define DMA2_2_CURR_ADDR 0xFFC00CA4 /* DMA2 Channel 2 Current Address Pointer */ +#define DMA2_2_CURR_X_COUNT 0xFFC00CB0 /* DMA2 Channel 2 Current Inner Loop Count */ +#define DMA2_2_CURR_Y_COUNT 0xFFC00CB8 /* DMA2 Channel 2 Current Outer Loop Count */ +#define DMA2_2_IRQ_STATUS 0xFFC00CA8 /* DMA2 Channel 2 Interrupt/Status Register */ +#define DMA2_2_PERIPHERAL_MAP 0xFFC00CAC /* DMA2 Channel 2 Peripheral Map Register */ + +#define DMA2_3_CONFIG 0xFFC00CC8 /* DMA2 Channel 3 Configuration register */ +#define DMA2_3_NEXT_DESC_PTR 0xFFC00CC0 /* DMA2 Channel 3 Next Descripter Ptr Reg */ +#define DMA2_3_START_ADDR 0xFFC00CC4 /* DMA2 Channel 3 Start Address */ +#define DMA2_3_X_COUNT 0xFFC00CD0 /* DMA2 Channel 3 Inner Loop Count */ +#define DMA2_3_Y_COUNT 0xFFC00CD8 /* DMA2 Channel 3 Outer Loop Count */ +#define DMA2_3_X_MODIFY 0xFFC00CD4 /* DMA2 Channel 3 Inner Loop Addr Increment */ +#define DMA2_3_Y_MODIFY 0xFFC00CDC /* DMA2 Channel 3 Outer Loop Addr Increment */ +#define DMA2_3_CURR_DESC_PTR 0xFFC00CE0 /* DMA2 Channel 3 Current Descriptor Pointer */ +#define DMA2_3_CURR_ADDR 0xFFC00CE4 /* DMA2 Channel 3 Current Address Pointer */ +#define DMA2_3_CURR_X_COUNT 0xFFC00CF0 /* DMA2 Channel 3 Current Inner Loop Count */ +#define DMA2_3_CURR_Y_COUNT 0xFFC00CF8 /* DMA2 Channel 3 Current Outer Loop Count */ +#define DMA2_3_IRQ_STATUS 0xFFC00CE8 /* DMA2 Channel 3 Interrupt/Status Register */ +#define DMA2_3_PERIPHERAL_MAP 0xFFC00CEC /* DMA2 Channel 3 Peripheral Map Register */ + +#define DMA2_4_CONFIG 0xFFC00D08 /* DMA2 Channel 4 Configuration register */ +#define DMA2_4_NEXT_DESC_PTR 0xFFC00D00 /* DMA2 Channel 4 Next Descripter Ptr Reg */ +#define DMA2_4_START_ADDR 0xFFC00D04 /* DMA2 Channel 4 Start Address */ +#define DMA2_4_X_COUNT 0xFFC00D10 /* DMA2 Channel 4 Inner Loop Count */ +#define DMA2_4_Y_COUNT 0xFFC00D18 /* DMA2 Channel 4 Outer Loop Count */ +#define DMA2_4_X_MODIFY 0xFFC00D14 /* DMA2 Channel 4 Inner Loop Addr Increment */ +#define DMA2_4_Y_MODIFY 0xFFC00D1C /* DMA2 Channel 4 Outer Loop Addr Increment */ +#define DMA2_4_CURR_DESC_PTR 0xFFC00D20 /* DMA2 Channel 4 Current Descriptor Pointer */ +#define DMA2_4_CURR_ADDR 0xFFC00D24 /* DMA2 Channel 4 Current Address Pointer */ +#define DMA2_4_CURR_X_COUNT 0xFFC00D30 /* DMA2 Channel 4 Current Inner Loop Count */ +#define DMA2_4_CURR_Y_COUNT 0xFFC00D38 /* DMA2 Channel 4 Current Outer Loop Count */ +#define DMA2_4_IRQ_STATUS 0xFFC00D28 /* DMA2 Channel 4 Interrupt/Status Register */ +#define DMA2_4_PERIPHERAL_MAP 0xFFC00D2C /* DMA2 Channel 4 Peripheral Map Register */ + +#define DMA2_5_CONFIG 0xFFC00D48 /* DMA2 Channel 5 Configuration register */ +#define DMA2_5_NEXT_DESC_PTR 0xFFC00D40 /* DMA2 Channel 5 Next Descripter Ptr Reg */ +#define DMA2_5_START_ADDR 0xFFC00D44 /* DMA2 Channel 5 Start Address */ +#define DMA2_5_X_COUNT 0xFFC00D50 /* DMA2 Channel 5 Inner Loop Count */ +#define DMA2_5_Y_COUNT 0xFFC00D58 /* DMA2 Channel 5 Outer Loop Count */ +#define DMA2_5_X_MODIFY 0xFFC00D54 /* DMA2 Channel 5 Inner Loop Addr Increment */ +#define DMA2_5_Y_MODIFY 0xFFC00D5C /* DMA2 Channel 5 Outer Loop Addr Increment */ +#define DMA2_5_CURR_DESC_PTR 0xFFC00D60 /* DMA2 Channel 5 Current Descriptor Pointer */ +#define DMA2_5_CURR_ADDR 0xFFC00D64 /* DMA2 Channel 5 Current Address Pointer */ +#define DMA2_5_CURR_X_COUNT 0xFFC00D70 /* DMA2 Channel 5 Current Inner Loop Count */ +#define DMA2_5_CURR_Y_COUNT 0xFFC00D78 /* DMA2 Channel 5 Current Outer Loop Count */ +#define DMA2_5_IRQ_STATUS 0xFFC00D68 /* DMA2 Channel 5 Interrupt/Status Register */ +#define DMA2_5_PERIPHERAL_MAP 0xFFC00D6C /* DMA2 Channel 5 Peripheral Map Register */ + +#define DMA2_6_CONFIG 0xFFC00D88 /* DMA2 Channel 6 Configuration register */ +#define DMA2_6_NEXT_DESC_PTR 0xFFC00D80 /* DMA2 Channel 6 Next Descripter Ptr Reg */ +#define DMA2_6_START_ADDR 0xFFC00D84 /* DMA2 Channel 6 Start Address */ +#define DMA2_6_X_COUNT 0xFFC00D90 /* DMA2 Channel 6 Inner Loop Count */ +#define DMA2_6_Y_COUNT 0xFFC00D98 /* DMA2 Channel 6 Outer Loop Count */ +#define DMA2_6_X_MODIFY 0xFFC00D94 /* DMA2 Channel 6 Inner Loop Addr Increment */ +#define DMA2_6_Y_MODIFY 0xFFC00D9C /* DMA2 Channel 6 Outer Loop Addr Increment */ +#define DMA2_6_CURR_DESC_PTR 0xFFC00DA0 /* DMA2 Channel 6 Current Descriptor Pointer */ +#define DMA2_6_CURR_ADDR 0xFFC00DA4 /* DMA2 Channel 6 Current Address Pointer */ +#define DMA2_6_CURR_X_COUNT 0xFFC00DB0 /* DMA2 Channel 6 Current Inner Loop Count */ +#define DMA2_6_CURR_Y_COUNT 0xFFC00DB8 /* DMA2 Channel 6 Current Outer Loop Count */ +#define DMA2_6_IRQ_STATUS 0xFFC00DA8 /* DMA2 Channel 6 Interrupt/Status Register */ +#define DMA2_6_PERIPHERAL_MAP 0xFFC00DAC /* DMA2 Channel 6 Peripheral Map Register */ + +#define DMA2_7_CONFIG 0xFFC00DC8 /* DMA2 Channel 7 Configuration register */ +#define DMA2_7_NEXT_DESC_PTR 0xFFC00DC0 /* DMA2 Channel 7 Next Descripter Ptr Reg */ +#define DMA2_7_START_ADDR 0xFFC00DC4 /* DMA2 Channel 7 Start Address */ +#define DMA2_7_X_COUNT 0xFFC00DD0 /* DMA2 Channel 7 Inner Loop Count */ +#define DMA2_7_Y_COUNT 0xFFC00DD8 /* DMA2 Channel 7 Outer Loop Count */ +#define DMA2_7_X_MODIFY 0xFFC00DD4 /* DMA2 Channel 7 Inner Loop Addr Increment */ +#define DMA2_7_Y_MODIFY 0xFFC00DDC /* DMA2 Channel 7 Outer Loop Addr Increment */ +#define DMA2_7_CURR_DESC_PTR 0xFFC00DE0 /* DMA2 Channel 7 Current Descriptor Pointer */ +#define DMA2_7_CURR_ADDR 0xFFC00DE4 /* DMA2 Channel 7 Current Address Pointer */ +#define DMA2_7_CURR_X_COUNT 0xFFC00DF0 /* DMA2 Channel 7 Current Inner Loop Count */ +#define DMA2_7_CURR_Y_COUNT 0xFFC00DF8 /* DMA2 Channel 7 Current Outer Loop Count */ +#define DMA2_7_IRQ_STATUS 0xFFC00DE8 /* DMA2 Channel 7 Interrupt/Status Register */ +#define DMA2_7_PERIPHERAL_MAP 0xFFC00DEC /* DMA2 Channel 7 Peripheral Map Register */ + +#define DMA2_8_CONFIG 0xFFC00E08 /* DMA2 Channel 8 Configuration register */ +#define DMA2_8_NEXT_DESC_PTR 0xFFC00E00 /* DMA2 Channel 8 Next Descripter Ptr Reg */ +#define DMA2_8_START_ADDR 0xFFC00E04 /* DMA2 Channel 8 Start Address */ +#define DMA2_8_X_COUNT 0xFFC00E10 /* DMA2 Channel 8 Inner Loop Count */ +#define DMA2_8_Y_COUNT 0xFFC00E18 /* DMA2 Channel 8 Outer Loop Count */ +#define DMA2_8_X_MODIFY 0xFFC00E14 /* DMA2 Channel 8 Inner Loop Addr Increment */ +#define DMA2_8_Y_MODIFY 0xFFC00E1C /* DMA2 Channel 8 Outer Loop Addr Increment */ +#define DMA2_8_CURR_DESC_PTR 0xFFC00E20 /* DMA2 Channel 8 Current Descriptor Pointer */ +#define DMA2_8_CURR_ADDR 0xFFC00E24 /* DMA2 Channel 8 Current Address Pointer */ +#define DMA2_8_CURR_X_COUNT 0xFFC00E30 /* DMA2 Channel 8 Current Inner Loop Count */ +#define DMA2_8_CURR_Y_COUNT 0xFFC00E38 /* DMA2 Channel 8 Current Outer Loop Count */ +#define DMA2_8_IRQ_STATUS 0xFFC00E28 /* DMA2 Channel 8 Interrupt/Status Register */ +#define DMA2_8_PERIPHERAL_MAP 0xFFC00E2C /* DMA2 Channel 8 Peripheral Map Register */ + +#define DMA2_9_CONFIG 0xFFC00E48 /* DMA2 Channel 9 Configuration register */ +#define DMA2_9_NEXT_DESC_PTR 0xFFC00E40 /* DMA2 Channel 9 Next Descripter Ptr Reg */ +#define DMA2_9_START_ADDR 0xFFC00E44 /* DMA2 Channel 9 Start Address */ +#define DMA2_9_X_COUNT 0xFFC00E50 /* DMA2 Channel 9 Inner Loop Count */ +#define DMA2_9_Y_COUNT 0xFFC00E58 /* DMA2 Channel 9 Outer Loop Count */ +#define DMA2_9_X_MODIFY 0xFFC00E54 /* DMA2 Channel 9 Inner Loop Addr Increment */ +#define DMA2_9_Y_MODIFY 0xFFC00E5C /* DMA2 Channel 9 Outer Loop Addr Increment */ +#define DMA2_9_CURR_DESC_PTR 0xFFC00E60 /* DMA2 Channel 9 Current Descriptor Pointer */ +#define DMA2_9_CURR_ADDR 0xFFC00E64 /* DMA2 Channel 9 Current Address Pointer */ +#define DMA2_9_CURR_X_COUNT 0xFFC00E70 /* DMA2 Channel 9 Current Inner Loop Count */ +#define DMA2_9_CURR_Y_COUNT 0xFFC00E78 /* DMA2 Channel 9 Current Outer Loop Count */ +#define DMA2_9_IRQ_STATUS 0xFFC00E68 /* DMA2 Channel 9 Interrupt/Status Register */ +#define DMA2_9_PERIPHERAL_MAP 0xFFC00E6C /* DMA2 Channel 9 Peripheral Map Register */ + +#define DMA2_10_CONFIG 0xFFC00E88 /* DMA2 Channel 10 Configuration register */ +#define DMA2_10_NEXT_DESC_PTR 0xFFC00E80 /* DMA2 Channel 10 Next Descripter Ptr Reg */ +#define DMA2_10_START_ADDR 0xFFC00E84 /* DMA2 Channel 10 Start Address */ +#define DMA2_10_X_COUNT 0xFFC00E90 /* DMA2 Channel 10 Inner Loop Count */ +#define DMA2_10_Y_COUNT 0xFFC00E98 /* DMA2 Channel 10 Outer Loop Count */ +#define DMA2_10_X_MODIFY 0xFFC00E94 /* DMA2 Channel 10 Inner Loop Addr Increment */ +#define DMA2_10_Y_MODIFY 0xFFC00E9C /* DMA2 Channel 10 Outer Loop Addr Increment */ +#define DMA2_10_CURR_DESC_PTR 0xFFC00EA0 /* DMA2 Channel 10 Current Descriptor Pointer */ +#define DMA2_10_CURR_ADDR 0xFFC00EA4 /* DMA2 Channel 10 Current Address Pointer */ +#define DMA2_10_CURR_X_COUNT 0xFFC00EB0 /* DMA2 Channel 10 Current Inner Loop Count */ +#define DMA2_10_CURR_Y_COUNT 0xFFC00EB8 /* DMA2 Channel 10 Current Outer Loop Count */ +#define DMA2_10_IRQ_STATUS 0xFFC00EA8 /* DMA2 Channel 10 Interrupt/Status Register */ +#define DMA2_10_PERIPHERAL_MAP 0xFFC00EAC /* DMA2 Channel 10 Peripheral Map Register */ + +#define DMA2_11_CONFIG 0xFFC00EC8 /* DMA2 Channel 11 Configuration register */ +#define DMA2_11_NEXT_DESC_PTR 0xFFC00EC0 /* DMA2 Channel 11 Next Descripter Ptr Reg */ +#define DMA2_11_START_ADDR 0xFFC00EC4 /* DMA2 Channel 11 Start Address */ +#define DMA2_11_X_COUNT 0xFFC00ED0 /* DMA2 Channel 11 Inner Loop Count */ +#define DMA2_11_Y_COUNT 0xFFC00ED8 /* DMA2 Channel 11 Outer Loop Count */ +#define DMA2_11_X_MODIFY 0xFFC00ED4 /* DMA2 Channel 11 Inner Loop Addr Increment */ +#define DMA2_11_Y_MODIFY 0xFFC00EDC /* DMA2 Channel 11 Outer Loop Addr Increment */ +#define DMA2_11_CURR_DESC_PTR 0xFFC00EE0 /* DMA2 Channel 11 Current Descriptor Pointer */ +#define DMA2_11_CURR_ADDR 0xFFC00EE4 /* DMA2 Channel 11 Current Address Pointer */ +#define DMA2_11_CURR_X_COUNT 0xFFC00EF0 /* DMA2 Channel 11 Current Inner Loop Count */ +#define DMA2_11_CURR_Y_COUNT 0xFFC00EF8 /* DMA2 Channel 11 Current Outer Loop Count */ +#define DMA2_11_IRQ_STATUS 0xFFC00EE8 /* DMA2 Channel 11 Interrupt/Status Register */ +#define DMA2_11_PERIPHERAL_MAP 0xFFC00EEC /* DMA2 Channel 11 Peripheral Map Register */ + +/* Memory DMA2 Controller registers (0xFFC0 0E80-0xFFC0 0FFF) */ +#define MDMA2_D0_CONFIG 0xFFC00F08 /*MemDMA2 Stream 0 Destination Configuration register */ +#define MDMA2_D0_NEXT_DESC_PTR 0xFFC00F00 /*MemDMA2 Stream 0 Destination Next Descriptor Ptr Reg */ +#define MDMA2_D0_START_ADDR 0xFFC00F04 /*MemDMA2 Stream 0 Destination Start Address */ +#define MDMA2_D0_X_COUNT 0xFFC00F10 /*MemDMA2 Stream 0 Dest Inner-Loop Count register */ +#define MDMA2_D0_Y_COUNT 0xFFC00F18 /*MemDMA2 Stream 0 Dest Outer-Loop Count register */ +#define MDMA2_D0_X_MODIFY 0xFFC00F14 /*MemDMA2 Stream 0 Dest Inner-Loop Address-Increment */ +#define MDMA2_D0_Y_MODIFY 0xFFC00F1C /*MemDMA2 Stream 0 Dest Outer-Loop Address-Increment */ +#define MDMA2_D0_CURR_DESC_PTR 0xFFC00F20 /*MemDMA2 Stream 0 Dest Current Descriptor Ptr reg */ +#define MDMA2_D0_CURR_ADDR 0xFFC00F24 /*MemDMA2 Stream 0 Destination Current Address */ +#define MDMA2_D0_CURR_X_COUNT 0xFFC00F30 /*MemDMA2 Stream 0 Dest Current Inner-Loop Count reg */ +#define MDMA2_D0_CURR_Y_COUNT 0xFFC00F38 /*MemDMA2 Stream 0 Dest Current Outer-Loop Count reg */ +#define MDMA2_D0_IRQ_STATUS 0xFFC00F28 /*MemDMA2 Stream 0 Dest Interrupt/Status Register */ +#define MDMA2_D0_PERIPHERAL_MAP 0xFFC00F2C /*MemDMA2 Stream 0 Destination Peripheral Map register */ + +#define MDMA2_S0_CONFIG 0xFFC00F48 /*MemDMA2 Stream 0 Source Configuration register */ +#define MDMA2_S0_NEXT_DESC_PTR 0xFFC00F40 /*MemDMA2 Stream 0 Source Next Descriptor Ptr Reg */ +#define MDMA2_S0_START_ADDR 0xFFC00F44 /*MemDMA2 Stream 0 Source Start Address */ +#define MDMA2_S0_X_COUNT 0xFFC00F50 /*MemDMA2 Stream 0 Source Inner-Loop Count register */ +#define MDMA2_S0_Y_COUNT 0xFFC00F58 /*MemDMA2 Stream 0 Source Outer-Loop Count register */ +#define MDMA2_S0_X_MODIFY 0xFFC00F54 /*MemDMA2 Stream 0 Src Inner-Loop Addr-Increment reg */ +#define MDMA2_S0_Y_MODIFY 0xFFC00F5C /*MemDMA2 Stream 0 Src Outer-Loop Addr-Increment reg */ +#define MDMA2_S0_CURR_DESC_PTR 0xFFC00F60 /*MemDMA2 Stream 0 Source Current Descriptor Ptr reg */ +#define MDMA2_S0_CURR_ADDR 0xFFC00F64 /*MemDMA2 Stream 0 Source Current Address */ +#define MDMA2_S0_CURR_X_COUNT 0xFFC00F70 /*MemDMA2 Stream 0 Src Current Inner-Loop Count reg */ +#define MDMA2_S0_CURR_Y_COUNT 0xFFC00F78 /*MemDMA2 Stream 0 Src Current Outer-Loop Count reg */ +#define MDMA2_S0_IRQ_STATUS 0xFFC00F68 /*MemDMA2 Stream 0 Source Interrupt/Status Register */ +#define MDMA2_S0_PERIPHERAL_MAP 0xFFC00F6C /*MemDMA2 Stream 0 Source Peripheral Map register */ + +#define MDMA2_D1_CONFIG 0xFFC00F88 /*MemDMA2 Stream 1 Destination Configuration register */ +#define MDMA2_D1_NEXT_DESC_PTR 0xFFC00F80 /*MemDMA2 Stream 1 Destination Next Descriptor Ptr Reg */ +#define MDMA2_D1_START_ADDR 0xFFC00F84 /*MemDMA2 Stream 1 Destination Start Address */ +#define MDMA2_D1_X_COUNT 0xFFC00F90 /*MemDMA2 Stream 1 Dest Inner-Loop Count register */ +#define MDMA2_D1_Y_COUNT 0xFFC00F98 /*MemDMA2 Stream 1 Dest Outer-Loop Count register */ +#define MDMA2_D1_X_MODIFY 0xFFC00F94 /*MemDMA2 Stream 1 Dest Inner-Loop Address-Increment */ +#define MDMA2_D1_Y_MODIFY 0xFFC00F9C /*MemDMA2 Stream 1 Dest Outer-Loop Address-Increment */ +#define MDMA2_D1_CURR_DESC_PTR 0xFFC00FA0 /*MemDMA2 Stream 1 Destination Current Descriptor Ptr */ +#define MDMA2_D1_CURR_ADDR 0xFFC00FA4 /*MemDMA2 Stream 1 Destination Current Address reg */ +#define MDMA2_D1_CURR_X_COUNT 0xFFC00FB0 /*MemDMA2 Stream 1 Dest Current Inner-Loop Count reg */ +#define MDMA2_D1_CURR_Y_COUNT 0xFFC00FB8 /*MemDMA2 Stream 1 Dest Current Outer-Loop Count reg */ +#define MDMA2_D1_IRQ_STATUS 0xFFC00FA8 /*MemDMA2 Stream 1 Destination Interrupt/Status Reg */ +#define MDMA2_D1_PERIPHERAL_MAP 0xFFC00FAC /*MemDMA2 Stream 1 Destination Peripheral Map register */ + +#define MDMA2_S1_CONFIG 0xFFC00FC8 /*MemDMA2 Stream 1 Source Configuration register */ +#define MDMA2_S1_NEXT_DESC_PTR 0xFFC00FC0 /*MemDMA2 Stream 1 Source Next Descriptor Ptr Reg */ +#define MDMA2_S1_START_ADDR 0xFFC00FC4 /*MemDMA2 Stream 1 Source Start Address */ +#define MDMA2_S1_X_COUNT 0xFFC00FD0 /*MemDMA2 Stream 1 Source Inner-Loop Count register */ +#define MDMA2_S1_Y_COUNT 0xFFC00FD8 /*MemDMA2 Stream 1 Source Outer-Loop Count register */ +#define MDMA2_S1_X_MODIFY 0xFFC00FD4 /*MemDMA2 Stream 1 Src Inner-Loop Address-Increment */ +#define MDMA2_S1_Y_MODIFY 0xFFC00FDC /*MemDMA2 Stream 1 Source Outer-Loop Address-Increment */ +#define MDMA2_S1_CURR_DESC_PTR 0xFFC00FE0 /*MemDMA2 Stream 1 Source Current Descriptor Ptr reg */ +#define MDMA2_S1_CURR_ADDR 0xFFC00FE4 /*MemDMA2 Stream 1 Source Current Address */ +#define MDMA2_S1_CURR_X_COUNT 0xFFC00FF0 /*MemDMA2 Stream 1 Source Current Inner-Loop Count */ +#define MDMA2_S1_CURR_Y_COUNT 0xFFC00FF8 /*MemDMA2 Stream 1 Source Current Outer-Loop Count */ +#define MDMA2_S1_IRQ_STATUS 0xFFC00FE8 /*MemDMA2 Stream 1 Source Interrupt/Status Register */ +#define MDMA2_S1_PERIPHERAL_MAP 0xFFC00FEC /*MemDMA2 Stream 1 Source Peripheral Map register */ + +/* Internal Memory DMA Registers (0xFFC0_1800 - 0xFFC0_19FF) */ +#define IMDMA_D0_CONFIG 0xFFC01808 /*IMDMA Stream 0 Destination Configuration */ +#define IMDMA_D0_NEXT_DESC_PTR 0xFFC01800 /*IMDMA Stream 0 Destination Next Descriptor Ptr Reg */ +#define IMDMA_D0_START_ADDR 0xFFC01804 /*IMDMA Stream 0 Destination Start Address */ +#define IMDMA_D0_X_COUNT 0xFFC01810 /*IMDMA Stream 0 Destination Inner-Loop Count */ +#define IMDMA_D0_Y_COUNT 0xFFC01818 /*IMDMA Stream 0 Destination Outer-Loop Count */ +#define IMDMA_D0_X_MODIFY 0xFFC01814 /*IMDMA Stream 0 Dest Inner-Loop Address-Increment */ +#define IMDMA_D0_Y_MODIFY 0xFFC0181C /*IMDMA Stream 0 Dest Outer-Loop Address-Increment */ +#define IMDMA_D0_CURR_DESC_PTR 0xFFC01820 /*IMDMA Stream 0 Destination Current Descriptor Ptr */ +#define IMDMA_D0_CURR_ADDR 0xFFC01824 /*IMDMA Stream 0 Destination Current Address */ +#define IMDMA_D0_CURR_X_COUNT 0xFFC01830 /*IMDMA Stream 0 Destination Current Inner-Loop Count */ +#define IMDMA_D0_CURR_Y_COUNT 0xFFC01838 /*IMDMA Stream 0 Destination Current Outer-Loop Count */ +#define IMDMA_D0_IRQ_STATUS 0xFFC01828 /*IMDMA Stream 0 Destination Interrupt/Status */ + +#define IMDMA_S0_CONFIG 0xFFC01848 /*IMDMA Stream 0 Source Configuration */ +#define IMDMA_S0_NEXT_DESC_PTR 0xFFC01840 /*IMDMA Stream 0 Source Next Descriptor Ptr Reg */ +#define IMDMA_S0_START_ADDR 0xFFC01844 /*IMDMA Stream 0 Source Start Address */ +#define IMDMA_S0_X_COUNT 0xFFC01850 /*IMDMA Stream 0 Source Inner-Loop Count */ +#define IMDMA_S0_Y_COUNT 0xFFC01858 /*IMDMA Stream 0 Source Outer-Loop Count */ +#define IMDMA_S0_X_MODIFY 0xFFC01854 /*IMDMA Stream 0 Source Inner-Loop Address-Increment */ +#define IMDMA_S0_Y_MODIFY 0xFFC0185C /*IMDMA Stream 0 Source Outer-Loop Address-Increment */ +#define IMDMA_S0_CURR_DESC_PTR 0xFFC01860 /*IMDMA Stream 0 Source Current Descriptor Ptr reg */ +#define IMDMA_S0_CURR_ADDR 0xFFC01864 /*IMDMA Stream 0 Source Current Address */ +#define IMDMA_S0_CURR_X_COUNT 0xFFC01870 /*IMDMA Stream 0 Source Current Inner-Loop Count */ +#define IMDMA_S0_CURR_Y_COUNT 0xFFC01878 /*IMDMA Stream 0 Source Current Outer-Loop Count */ +#define IMDMA_S0_IRQ_STATUS 0xFFC01868 /*IMDMA Stream 0 Source Interrupt/Status */ + +#define IMDMA_D1_CONFIG 0xFFC01888 /*IMDMA Stream 1 Destination Configuration */ +#define IMDMA_D1_NEXT_DESC_PTR 0xFFC01880 /*IMDMA Stream 1 Destination Next Descriptor Ptr Reg */ +#define IMDMA_D1_START_ADDR 0xFFC01884 /*IMDMA Stream 1 Destination Start Address */ +#define IMDMA_D1_X_COUNT 0xFFC01890 /*IMDMA Stream 1 Destination Inner-Loop Count */ +#define IMDMA_D1_Y_COUNT 0xFFC01898 /*IMDMA Stream 1 Destination Outer-Loop Count */ +#define IMDMA_D1_X_MODIFY 0xFFC01894 /*IMDMA Stream 1 Dest Inner-Loop Address-Increment */ +#define IMDMA_D1_Y_MODIFY 0xFFC0189C /*IMDMA Stream 1 Dest Outer-Loop Address-Increment */ +#define IMDMA_D1_CURR_DESC_PTR 0xFFC018A0 /*IMDMA Stream 1 Destination Current Descriptor Ptr */ +#define IMDMA_D1_CURR_ADDR 0xFFC018A4 /*IMDMA Stream 1 Destination Current Address */ +#define IMDMA_D1_CURR_X_COUNT 0xFFC018B0 /*IMDMA Stream 1 Destination Current Inner-Loop Count */ +#define IMDMA_D1_CURR_Y_COUNT 0xFFC018B8 /*IMDMA Stream 1 Destination Current Outer-Loop Count */ +#define IMDMA_D1_IRQ_STATUS 0xFFC018A8 /*IMDMA Stream 1 Destination Interrupt/Status */ + +#define IMDMA_S1_CONFIG 0xFFC018C8 /*IMDMA Stream 1 Source Configuration */ +#define IMDMA_S1_NEXT_DESC_PTR 0xFFC018C0 /*IMDMA Stream 1 Source Next Descriptor Ptr Reg */ +#define IMDMA_S1_START_ADDR 0xFFC018C4 /*IMDMA Stream 1 Source Start Address */ +#define IMDMA_S1_X_COUNT 0xFFC018D0 /*IMDMA Stream 1 Source Inner-Loop Count */ +#define IMDMA_S1_Y_COUNT 0xFFC018D8 /*IMDMA Stream 1 Source Outer-Loop Count */ +#define IMDMA_S1_X_MODIFY 0xFFC018D4 /*IMDMA Stream 1 Source Inner-Loop Address-Increment */ +#define IMDMA_S1_Y_MODIFY 0xFFC018DC /*IMDMA Stream 1 Source Outer-Loop Address-Increment */ +#define IMDMA_S1_CURR_DESC_PTR 0xFFC018E0 /*IMDMA Stream 1 Source Current Descriptor Ptr reg */ +#define IMDMA_S1_CURR_ADDR 0xFFC018E4 /*IMDMA Stream 1 Source Current Address */ +#define IMDMA_S1_CURR_X_COUNT 0xFFC018F0 /*IMDMA Stream 1 Source Current Inner-Loop Count */ +#define IMDMA_S1_CURR_Y_COUNT 0xFFC018F8 /*IMDMA Stream 1 Source Current Outer-Loop Count */ +#define IMDMA_S1_IRQ_STATUS 0xFFC018E8 /*IMDMA Stream 1 Source Interrupt/Status */ + +/*********************************************************************************** */ +/* System MMR Register Bits */ +/******************************************************************************* */ + +/* ********************* PLL AND RESET MASKS ************************ */ + +/* PLL_CTL Masks */ +#define PLL_CLKIN 0x00000000 /* Pass CLKIN to PLL */ +#define PLL_CLKIN_DIV2 0x00000001 /* Pass CLKIN/2 to PLL */ +#define PLL_OFF 0x00000002 /* Shut off PLL clocks */ +#define STOPCK_OFF 0x00000008 /* Core clock off */ +#define PDWN 0x00000020 /* Put the PLL in a Deep Sleep state */ +#define BYPASS 0x00000100 /* Bypass the PLL */ + +/* CHIPID Masks */ +#define CHIPID_VERSION 0xF0000000 +#define CHIPID_FAMILY 0x0FFFF000 +#define CHIPID_MANUFACTURE 0x00000FFE + +/* PLL_DIV Masks */ +#define SCLK_DIV(x) (x) /* SCLK = VCO / x */ + +#define CCLK_DIV1 0x00000000 /* CCLK = VCO / 1 */ +#define CCLK_DIV2 0x00000010 /* CCLK = VCO / 2 */ +#define CCLK_DIV4 0x00000020 /* CCLK = VCO / 4 */ +#define CCLK_DIV8 0x00000030 /* CCLK = VCO / 8 */ + +/* PLL_STAT Masks */ +#define ACTIVE_PLLENABLED 0x0001 /* Processor In Active Mode With PLL Enabled */ +#define FULL_ON 0x0002 /* Processor In Full On Mode */ +#define ACTIVE_PLLDISABLED 0x0004 /* Processor In Active Mode With PLL Disabled */ +#define PLL_LOCKED 0x0020 /* PLL_LOCKCNT Has Been Reached */ + +/* SWRST Mask */ +#define SYSTEM_RESET 0x00000007 /* Initiates a system software reset */ +#define SWRST_DBL_FAULT_B 0x00000800 /* SWRST Core B Double Fault */ +#define SWRST_DBL_FAULT_A 0x00001000 /* SWRST Core A Double Fault */ +#define SWRST_WDT_B 0x00002000 /* SWRST Watchdog B */ +#define SWRST_WDT_A 0x00004000 /* SWRST Watchdog A */ +#define SWRST_OCCURRED 0x00008000 /* SWRST Status */ + +/* ************* SYSTEM INTERRUPT CONTROLLER MASKS ***************** */ + +/* SICu_IARv Masks */ +/* u = A or B */ +/* v = 0 to 7 */ +/* w = 0 or 1 */ + +/* Per_number = 0 to 63 */ +/* IVG_number = 7 to 15 */ +#define Peripheral_IVG(Per_number, IVG_number) \ + ((IVG_number) - 7) << (((Per_number) % 8) * 4) /* Peripheral #Per_number assigned IVG #IVG_number */ + /* Usage: r0.l = lo(Peripheral_IVG(62, 10)); */ + /* r0.h = hi(Peripheral_IVG(62, 10)); */ + +/* SICx_IMASKw Masks */ +/* masks are 32 bit wide, so two writes reguired for "64 bit" wide registers */ +#define SIC_UNMASK_ALL 0x00000000 /* Unmask all peripheral interrupts */ +#define SIC_MASK_ALL 0xFFFFFFFF /* Mask all peripheral interrupts */ +#define SIC_MASK(x) (1 << (x)) /* Mask Peripheral #x interrupt */ +#define SIC_UNMASK(x) (0xFFFFFFFF ^ (1 << (x))) /* Unmask Peripheral #x interrupt */ + +/* SIC_IWR Masks */ +#define IWR_DISABLE_ALL 0x00000000 /* Wakeup Disable all peripherals */ +#define IWR_ENABLE_ALL 0xFFFFFFFF /* Wakeup Enable all peripherals */ +/* x = pos 0 to 31, for 32-63 use value-32 */ +#define IWR_ENABLE(x) (1 << (x)) /* Wakeup Enable Peripheral #x */ +#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << (x))) /* Wakeup Disable Peripheral #x */ + +/* ********* WATCHDOG TIMER MASKS ********************8 */ + +/* Watchdog Timer WDOG_CTL Register */ +#define ICTL(x) ((x<<1) & 0x0006) +#define ENABLE_RESET 0x00000000 /* Set Watchdog Timer to generate reset */ +#define ENABLE_NMI 0x00000002 /* Set Watchdog Timer to generate non-maskable interrupt */ +#define ENABLE_GPI 0x00000004 /* Set Watchdog Timer to generate general-purpose interrupt */ +#define DISABLE_EVT 0x00000006 /* Disable Watchdog Timer interrupts */ + +#define TMR_EN 0x0000 +#define TMR_DIS 0x0AD0 +#define TRO 0x8000 + +#define ICTL_P0 0x01 +#define ICTL_P1 0x02 +#define TRO_P 0x0F + +/* ***************************** UART CONTROLLER MASKS ********************** */ + +/* UART_LCR Register */ + +#define DLAB 0x80 +#define SB 0x40 +#define STP 0x20 +#define EPS 0x10 +#define PEN 0x08 +#define STB 0x04 +#define WLS(x) ((x-5) & 0x03) + +#define DLAB_P 0x07 +#define SB_P 0x06 +#define STP_P 0x05 +#define EPS_P 0x04 +#define PEN_P 0x03 +#define STB_P 0x02 +#define WLS_P1 0x01 +#define WLS_P0 0x00 + +/* UART_MCR Register */ +#define LOOP_ENA 0x10 +#define LOOP_ENA_P 0x04 + +/* UART_LSR Register */ +#define TEMT 0x40 +#define THRE 0x20 +#define BI 0x10 +#define FE 0x08 +#define PE 0x04 +#define OE 0x02 +#define DR 0x01 + +#define TEMP_P 0x06 +#define THRE_P 0x05 +#define BI_P 0x04 +#define FE_P 0x03 +#define PE_P 0x02 +#define OE_P 0x01 +#define DR_P 0x00 + +/* UART_IER Register */ +#define ELSI 0x04 +#define ETBEI 0x02 +#define ERBFI 0x01 + +#define ELSI_P 0x02 +#define ETBEI_P 0x01 +#define ERBFI_P 0x00 + +/* UART_IIR Register */ +#define STATUS(x) ((x << 1) & 0x06) +#define NINT 0x01 +#define STATUS_P1 0x02 +#define STATUS_P0 0x01 +#define NINT_P 0x00 +#define IIR_TX_READY 0x02 /* UART_THR empty */ +#define IIR_RX_READY 0x04 /* Receive data ready */ +#define IIR_LINE_CHANGE 0x06 /* Receive line status */ +#define IIR_STATUS 0x06 + +/* UART_GCTL Register */ +#define FFE 0x20 +#define FPE 0x10 +#define RPOLC 0x08 +#define TPOLC 0x04 +#define IREN 0x02 +#define UCEN 0x01 + +#define FFE_P 0x05 +#define FPE_P 0x04 +#define RPOLC_P 0x03 +#define TPOLC_P 0x02 +#define IREN_P 0x01 +#define UCEN_P 0x00 + +/* ********** SERIAL PORT MASKS ********************** */ + +/* SPORTx_TCR1 Masks */ +#define TSPEN 0x0001 /* TX enable */ +#define ITCLK 0x0002 /* Internal TX Clock Select */ +#define TDTYPE 0x000C /* TX Data Formatting Select */ +#define TLSBIT 0x0010 /* TX Bit Order */ +#define ITFS 0x0200 /* Internal TX Frame Sync Select */ +#define TFSR 0x0400 /* TX Frame Sync Required Select */ +#define DITFS 0x0800 /* Data Independent TX Frame Sync Select */ +#define LTFS 0x1000 /* Low TX Frame Sync Select */ +#define LATFS 0x2000 /* Late TX Frame Sync Select */ +#define TCKFE 0x4000 /* TX Clock Falling Edge Select */ + +/* SPORTx_TCR2 Masks */ +#define SLEN 0x001F /*TX Word Length */ +#define TXSE 0x0100 /*TX Secondary Enable */ +#define TSFSE 0x0200 /*TX Stereo Frame Sync Enable */ +#define TRFST 0x0400 /*TX Right-First Data Order */ + +/* SPORTx_RCR1 Masks */ +#define RSPEN 0x0001 /* RX enable */ +#define IRCLK 0x0002 /* Internal RX Clock Select */ +#define RDTYPE 0x000C /* RX Data Formatting Select */ +#define RULAW 0x0008 /* u-Law enable */ +#define RALAW 0x000C /* A-Law enable */ +#define RLSBIT 0x0010 /* RX Bit Order */ +#define IRFS 0x0200 /* Internal RX Frame Sync Select */ +#define RFSR 0x0400 /* RX Frame Sync Required Select */ +#define LRFS 0x1000 /* Low RX Frame Sync Select */ +#define LARFS 0x2000 /* Late RX Frame Sync Select */ +#define RCKFE 0x4000 /* RX Clock Falling Edge Select */ + +/* SPORTx_RCR2 Masks */ +#define SLEN 0x001F /*RX Word Length */ +#define RXSE 0x0100 /*RX Secondary Enable */ +#define RSFSE 0x0200 /*RX Stereo Frame Sync Enable */ +#define RRFST 0x0400 /*Right-First Data Order */ + +/*SPORTx_STAT Masks */ +#define RXNE 0x0001 /*RX FIFO Not Empty Status */ +#define RUVF 0x0002 /*RX Underflow Status */ +#define ROVF 0x0004 /*RX Overflow Status */ +#define TXF 0x0008 /*TX FIFO Full Status */ +#define TUVF 0x0010 /*TX Underflow Status */ +#define TOVF 0x0020 /*TX Overflow Status */ +#define TXHRE 0x0040 /*TX Hold Register Empty */ + +/*SPORTx_MCMC1 Masks */ +#define SP_WSIZE 0x0000F000 /*Multichannel Window Size Field */ +#define SP_WOFF 0x000003FF /*Multichannel Window Offset Field */ + +/*SPORTx_MCMC2 Masks */ +#define MCCRM 0x00000003 /*Multichannel Clock Recovery Mode */ +#define MCDTXPE 0x00000004 /*Multichannel DMA Transmit Packing */ +#define MCDRXPE 0x00000008 /*Multichannel DMA Receive Packing */ +#define MCMEN 0x00000010 /*Multichannel Frame Mode Enable */ +#define FSDR 0x00000080 /*Multichannel Frame Sync to Data Relationship */ +#define MFD 0x0000F000 /*Multichannel Frame Delay */ + +/* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */ + +/* PPI_CONTROL Masks */ +#define PORT_EN 0x00000001 /* PPI Port Enable */ +#define PORT_DIR 0x00000002 /* PPI Port Direction */ +#define XFR_TYPE 0x0000000C /* PPI Transfer Type */ +#define PORT_CFG 0x00000030 /* PPI Port Configuration */ +#define FLD_SEL 0x00000040 /* PPI Active Field Select */ +#define PACK_EN 0x00000080 /* PPI Packing Mode */ +#define DMA32 0x00000100 /* PPI 32-bit DMA Enable */ +#define SKIP_EN 0x00000200 /* PPI Skip Element Enable */ +#define SKIP_EO 0x00000400 /* PPI Skip Even/Odd Elements */ +#define DLENGTH 0x00003800 /* PPI Data Length */ +#define DLEN_8 0x0 /* PPI Data Length mask for DLEN=8 */ +#define DLEN(x) (((x-9) & 0x07) << 11) /* PPI Data Length (only works for x=10-->x=16) */ +#define POL 0x0000C000 /* PPI Signal Polarities */ + +/* PPI_STATUS Masks */ +#define FLD 0x00000400 /* Field Indicator */ +#define FT_ERR 0x00000800 /* Frame Track Error */ +#define OVR 0x00001000 /* FIFO Overflow Error */ +#define UNDR 0x00002000 /* FIFO Underrun Error */ +#define ERR_DET 0x00004000 /* Error Detected Indicator */ +#define ERR_NCOR 0x00008000 /* Error Not Corrected Indicator */ + +/* ********** DMA CONTROLLER MASKS *********************8 */ + +/* DMAx_CONFIG, MDMA_yy_CONFIG, IMDMA_yy_CONFIG Masks */ +#define DMAEN 0x00000001 /* Channel Enable */ +#define WNR 0x00000002 /* Channel Direction (W/R*) */ +#define WDSIZE_8 0x00000000 /* Word Size 8 bits */ +#define WDSIZE_16 0x00000004 /* Word Size 16 bits */ +#define WDSIZE_32 0x00000008 /* Word Size 32 bits */ +#define DMA2D 0x00000010 /* 2D/1D* Mode */ +#define RESTART 0x00000020 /* Restart */ +#define DI_SEL 0x00000040 /* Data Interrupt Select */ +#define DI_EN 0x00000080 /* Data Interrupt Enable */ +#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */ +#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */ +#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */ +#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */ +#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */ +#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */ +#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */ +#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */ +#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */ +#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */ +#define NDSIZE 0x00000900 /* Next Descriptor Size */ +#define DMAFLOW 0x00007000 /* Flow Control */ +#define DMAFLOW_STOP 0x0000 /* Stop Mode */ +#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */ +#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */ +#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */ +#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */ + +#define DMAEN_P 0 /* Channel Enable */ +#define WNR_P 1 /* Channel Direction (W/R*) */ +#define DMA2D_P 4 /* 2D/1D* Mode */ +#define RESTART_P 5 /* Restart */ +#define DI_SEL_P 6 /* Data Interrupt Select */ +#define DI_EN_P 7 /* Data Interrupt Enable */ + +/* DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS, IMDMA_yy_IRQ_STATUS Masks */ + +#define DMA_DONE 0x00000001 /* DMA Done Indicator */ +#define DMA_ERR 0x00000002 /* DMA Error Indicator */ +#define DFETCH 0x00000004 /* Descriptor Fetch Indicator */ +#define DMA_RUN 0x00000008 /* DMA Running Indicator */ + +#define DMA_DONE_P 0 /* DMA Done Indicator */ +#define DMA_ERR_P 1 /* DMA Error Indicator */ +#define DFETCH_P 2 /* Descriptor Fetch Indicator */ +#define DMA_RUN_P 3 /* DMA Running Indicator */ + +/* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP, IMDMA_yy_PERIPHERAL_MAP Masks */ + +#define CTYPE 0x00000040 /* DMA Channel Type Indicator */ +#define CTYPE_P 6 /* DMA Channel Type Indicator BIT POSITION */ +#define PCAP8 0x00000080 /* DMA 8-bit Operation Indicator */ +#define PCAP16 0x00000100 /* DMA 16-bit Operation Indicator */ +#define PCAP32 0x00000200 /* DMA 32-bit Operation Indicator */ +#define PCAPWR 0x00000400 /* DMA Write Operation Indicator */ +#define PCAPRD 0x00000800 /* DMA Read Operation Indicator */ +#define PMAP 0x00007000 /* DMA Peripheral Map Field */ + +/* ************* GENERAL PURPOSE TIMER MASKS ******************** */ + +/* PWM Timer bit definitions */ + +/* TIMER_ENABLE Register */ +#define TIMEN0 0x0001 +#define TIMEN1 0x0002 +#define TIMEN2 0x0004 +#define TIMEN3 0x0008 +#define TIMEN4 0x0010 +#define TIMEN5 0x0020 +#define TIMEN6 0x0040 +#define TIMEN7 0x0080 +#define TIMEN8 0x0001 +#define TIMEN9 0x0002 +#define TIMEN10 0x0004 +#define TIMEN11 0x0008 + +#define TIMEN0_P 0x00 +#define TIMEN1_P 0x01 +#define TIMEN2_P 0x02 +#define TIMEN3_P 0x03 +#define TIMEN4_P 0x04 +#define TIMEN5_P 0x05 +#define TIMEN6_P 0x06 +#define TIMEN7_P 0x07 +#define TIMEN8_P 0x00 +#define TIMEN9_P 0x01 +#define TIMEN10_P 0x02 +#define TIMEN11_P 0x03 + +/* TIMER_DISABLE Register */ +#define TIMDIS0 0x0001 +#define TIMDIS1 0x0002 +#define TIMDIS2 0x0004 +#define TIMDIS3 0x0008 +#define TIMDIS4 0x0010 +#define TIMDIS5 0x0020 +#define TIMDIS6 0x0040 +#define TIMDIS7 0x0080 +#define TIMDIS8 0x0001 +#define TIMDIS9 0x0002 +#define TIMDIS10 0x0004 +#define TIMDIS11 0x0008 + +#define TIMDIS0_P 0x00 +#define TIMDIS1_P 0x01 +#define TIMDIS2_P 0x02 +#define TIMDIS3_P 0x03 +#define TIMDIS4_P 0x04 +#define TIMDIS5_P 0x05 +#define TIMDIS6_P 0x06 +#define TIMDIS7_P 0x07 +#define TIMDIS8_P 0x00 +#define TIMDIS9_P 0x01 +#define TIMDIS10_P 0x02 +#define TIMDIS11_P 0x03 + +/* TIMER_STATUS Register */ +#define TIMIL0 0x00000001 +#define TIMIL1 0x00000002 +#define TIMIL2 0x00000004 +#define TIMIL3 0x00000008 +#define TIMIL4 0x00010000 +#define TIMIL5 0x00020000 +#define TIMIL6 0x00040000 +#define TIMIL7 0x00080000 +#define TIMIL8 0x0001 +#define TIMIL9 0x0002 +#define TIMIL10 0x0004 +#define TIMIL11 0x0008 +#define TOVL_ERR0 0x00000010 +#define TOVL_ERR1 0x00000020 +#define TOVL_ERR2 0x00000040 +#define TOVL_ERR3 0x00000080 +#define TOVL_ERR4 0x00100000 +#define TOVL_ERR5 0x00200000 +#define TOVL_ERR6 0x00400000 +#define TOVL_ERR7 0x00800000 +#define TOVL_ERR8 0x0010 +#define TOVL_ERR9 0x0020 +#define TOVL_ERR10 0x0040 +#define TOVL_ERR11 0x0080 +#define TRUN0 0x00001000 +#define TRUN1 0x00002000 +#define TRUN2 0x00004000 +#define TRUN3 0x00008000 +#define TRUN4 0x10000000 +#define TRUN5 0x20000000 +#define TRUN6 0x40000000 +#define TRUN7 0x80000000 +#define TRUN8 0x1000 +#define TRUN9 0x2000 +#define TRUN10 0x4000 +#define TRUN11 0x8000 + +#define TIMIL0_P 0x00 +#define TIMIL1_P 0x01 +#define TIMIL2_P 0x02 +#define TIMIL3_P 0x03 +#define TIMIL4_P 0x10 +#define TIMIL5_P 0x11 +#define TIMIL6_P 0x12 +#define TIMIL7_P 0x13 +#define TIMIL8_P 0x00 +#define TIMIL9_P 0x01 +#define TIMIL10_P 0x02 +#define TIMIL11_P 0x03 +#define TOVL_ERR0_P 0x04 +#define TOVL_ERR1_P 0x05 +#define TOVL_ERR2_P 0x06 +#define TOVL_ERR3_P 0x07 +#define TOVL_ERR4_P 0x14 +#define TOVL_ERR5_P 0x15 +#define TOVL_ERR6_P 0x16 +#define TOVL_ERR7_P 0x17 +#define TOVL_ERR8_P 0x04 +#define TOVL_ERR9_P 0x05 +#define TOVL_ERR10_P 0x06 +#define TOVL_ERR11_P 0x07 +#define TRUN0_P 0x0C +#define TRUN1_P 0x0D +#define TRUN2_P 0x0E +#define TRUN3_P 0x0F +#define TRUN4_P 0x1C +#define TRUN5_P 0x1D +#define TRUN6_P 0x1E +#define TRUN7_P 0x1F +#define TRUN8_P 0x0C +#define TRUN9_P 0x0D +#define TRUN10_P 0x0E +#define TRUN11_P 0x0F + +/* TIMERx_CONFIG Registers */ +#define PWM_OUT 0x0001 +#define WDTH_CAP 0x0002 +#define EXT_CLK 0x0003 +#define PULSE_HI 0x0004 +#define PERIOD_CNT 0x0008 +#define IRQ_ENA 0x0010 +#define TIN_SEL 0x0020 +#define OUT_DIS 0x0040 +#define CLK_SEL 0x0080 +#define TOGGLE_HI 0x0100 +#define EMU_RUN 0x0200 +#define ERR_TYP(x) ((x & 0x03) << 14) + +#define TMODE_P0 0x00 +#define TMODE_P1 0x01 +#define PULSE_HI_P 0x02 +#define PERIOD_CNT_P 0x03 +#define IRQ_ENA_P 0x04 +#define TIN_SEL_P 0x05 +#define OUT_DIS_P 0x06 +#define CLK_SEL_P 0x07 +#define TOGGLE_HI_P 0x08 +#define EMU_RUN_P 0x09 +#define ERR_TYP_P0 0x0E +#define ERR_TYP_P1 0x0F + +/*/ ****************** PROGRAMMABLE FLAG MASKS ********************* */ + +/* General Purpose IO (0xFFC00700 - 0xFFC007FF) Masks */ +#define PF0 0x0001 +#define PF1 0x0002 +#define PF2 0x0004 +#define PF3 0x0008 +#define PF4 0x0010 +#define PF5 0x0020 +#define PF6 0x0040 +#define PF7 0x0080 +#define PF8 0x0100 +#define PF9 0x0200 +#define PF10 0x0400 +#define PF11 0x0800 +#define PF12 0x1000 +#define PF13 0x2000 +#define PF14 0x4000 +#define PF15 0x8000 + +/* General Purpose IO (0xFFC00700 - 0xFFC007FF) BIT POSITIONS */ +#define PF0_P 0 +#define PF1_P 1 +#define PF2_P 2 +#define PF3_P 3 +#define PF4_P 4 +#define PF5_P 5 +#define PF6_P 6 +#define PF7_P 7 +#define PF8_P 8 +#define PF9_P 9 +#define PF10_P 10 +#define PF11_P 11 +#define PF12_P 12 +#define PF13_P 13 +#define PF14_P 14 +#define PF15_P 15 + +/* *********** SERIAL PERIPHERAL INTERFACE (SPI) MASKS **************** */ + +/* SPI_CTL Masks */ +#define TIMOD 0x00000003 /* Transfer initiation mode and interrupt generation */ +#define SZ 0x00000004 /* Send Zero (=0) or last (=1) word when TDBR empty. */ +#define GM 0x00000008 /* When RDBR full, get more (=1) data or discard (=0) incoming Data */ +#define PSSE 0x00000010 /* Enable (=1) Slave-Select input for Master. */ +#define EMISO 0x00000020 /* Enable (=1) MISO pin as an output. */ +#define SIZE 0x00000100 /* Word length (0 => 8 bits, 1 => 16 bits) */ +#define LSBF 0x00000200 /* Data format (0 => MSB sent/received first 1 => LSB sent/received first) */ +#define CPHA 0x00000400 /* Clock phase (0 => SPICLK starts toggling in middle of xfer, 1 => SPICLK toggles at the beginning of xfer. */ +#define CPOL 0x00000800 /* Clock polarity (0 => active-high, 1 => active-low) */ +#define MSTR 0x00001000 /* Configures SPI as master (=1) or slave (=0) */ +#define WOM 0x00002000 /* Open drain (=1) data output enable (for MOSI and MISO) */ +#define SPE 0x00004000 /* SPI module enable (=1), disable (=0) */ + +/* SPI_FLG Masks */ +#define FLS1 0x00000002 /* Enables (=1) SPI_FLOUT1 as flag output for SPI Slave-select */ +#define FLS2 0x00000004 /* Enables (=1) SPI_FLOUT2 as flag output for SPI Slave-select */ +#define FLS3 0x00000008 /* Enables (=1) SPI_FLOUT3 as flag output for SPI Slave-select */ +#define FLS4 0x00000010 /* Enables (=1) SPI_FLOUT4 as flag output for SPI Slave-select */ +#define FLS5 0x00000020 /* Enables (=1) SPI_FLOUT5 as flag output for SPI Slave-select */ +#define FLS6 0x00000040 /* Enables (=1) SPI_FLOUT6 as flag output for SPI Slave-select */ +#define FLS7 0x00000080 /* Enables (=1) SPI_FLOUT7 as flag output for SPI Slave-select */ +#define FLG1 0x00000200 /* Activates (=0) SPI_FLOUT1 as flag output for SPI Slave-select */ +#define FLG2 0x00000400 /* Activates (=0) SPI_FLOUT2 as flag output for SPI Slave-select */ +#define FLG3 0x00000800 /* Activates (=0) SPI_FLOUT3 as flag output for SPI Slave-select */ +#define FLG4 0x00001000 /* Activates (=0) SPI_FLOUT4 as flag output for SPI Slave-select */ +#define FLG5 0x00002000 /* Activates (=0) SPI_FLOUT5 as flag output for SPI Slave-select */ +#define FLG6 0x00004000 /* Activates (=0) SPI_FLOUT6 as flag output for SPI Slave-select */ +#define FLG7 0x00008000 /* Activates (=0) SPI_FLOUT7 as flag output for SPI Slave-select */ + +/* SPI_FLG Bit Positions */ +#define FLS1_P 0x00000001 /* Enables (=1) SPI_FLOUT1 as flag output for SPI Slave-select */ +#define FLS2_P 0x00000002 /* Enables (=1) SPI_FLOUT2 as flag output for SPI Slave-select */ +#define FLS3_P 0x00000003 /* Enables (=1) SPI_FLOUT3 as flag output for SPI Slave-select */ +#define FLS4_P 0x00000004 /* Enables (=1) SPI_FLOUT4 as flag output for SPI Slave-select */ +#define FLS5_P 0x00000005 /* Enables (=1) SPI_FLOUT5 as flag output for SPI Slave-select */ +#define FLS6_P 0x00000006 /* Enables (=1) SPI_FLOUT6 as flag output for SPI Slave-select */ +#define FLS7_P 0x00000007 /* Enables (=1) SPI_FLOUT7 as flag output for SPI Slave-select */ +#define FLG1_P 0x00000009 /* Activates (=0) SPI_FLOUT1 as flag output for SPI Slave-select */ +#define FLG2_P 0x0000000A /* Activates (=0) SPI_FLOUT2 as flag output for SPI Slave-select */ +#define FLG3_P 0x0000000B /* Activates (=0) SPI_FLOUT3 as flag output for SPI Slave-select */ +#define FLG4_P 0x0000000C /* Activates (=0) SPI_FLOUT4 as flag output for SPI Slave-select */ +#define FLG5_P 0x0000000D /* Activates (=0) SPI_FLOUT5 as flag output for SPI Slave-select */ +#define FLG6_P 0x0000000E /* Activates (=0) SPI_FLOUT6 as flag output for SPI Slave-select */ +#define FLG7_P 0x0000000F /* Activates (=0) SPI_FLOUT7 as flag output for SPI Slave-select */ + +/* SPI_STAT Masks */ +#define SPIF 0x00000001 /* Set (=1) when SPI single-word transfer complete */ +#define MODF 0x00000002 /* Set (=1) in a master device when some other device tries to become master */ +#define TXE 0x00000004 /* Set (=1) when transmission occurs with no new data in SPI_TDBR */ +#define TXS 0x00000008 /* SPI_TDBR Data Buffer Status (0=Empty, 1=Full) */ +#define RBSY 0x00000010 /* Set (=1) when data is received with RDBR full */ +#define RXS 0x00000020 /* SPI_RDBR Data Buffer Status (0=Empty, 1=Full) */ +#define TXCOL 0x00000040 /* When set (=1), corrupt data may have been transmitted */ + +/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS ************* */ + +/* AMGCTL Masks */ +#define AMCKEN 0x0001 /* Enable CLKOUT */ +#define AMBEN_B0 0x0002 /* Enable Asynchronous Memory Bank 0 only */ +#define AMBEN_B0_B1 0x0004 /* Enable Asynchronous Memory Banks 0 & 1 only */ +#define AMBEN_B0_B1_B2 0x0006 /* Enable Asynchronous Memory Banks 0, 1, and 2 */ +#define AMBEN_ALL 0x0008 /* Enable Asynchronous Memory Banks (all) 0, 1, 2, and 3 */ +#define B0_PEN 0x0010 /* Enable 16-bit packing Bank 0 */ +#define B1_PEN 0x0020 /* Enable 16-bit packing Bank 1 */ +#define B2_PEN 0x0040 /* Enable 16-bit packing Bank 2 */ +#define B3_PEN 0x0080 /* Enable 16-bit packing Bank 3 */ + +/* AMGCTL Bit Positions */ +#define AMCKEN_P 0x00000000 /* Enable CLKOUT */ +#define AMBEN_P0 0x00000001 /* Asynchronous Memory Enable, 000 - banks 0-3 disabled, 001 - Bank 0 enabled */ +#define AMBEN_P1 0x00000002 /* Asynchronous Memory Enable, 010 - banks 0&1 enabled, 011 - banks 0-3 enabled */ +#define AMBEN_P2 0x00000003 /* Asynchronous Memory Enable, 1xx - All banks (bank 0, 1, 2, and 3) enabled */ +#define B0_PEN_P 0x004 /* Enable 16-bit packing Bank 0 */ +#define B1_PEN_P 0x005 /* Enable 16-bit packing Bank 1 */ +#define B2_PEN_P 0x006 /* Enable 16-bit packing Bank 2 */ +#define B3_PEN_P 0x007 /* Enable 16-bit packing Bank 3 */ + +/* AMBCTL0 Masks */ +#define B0RDYEN 0x00000001 /* Bank 0 RDY Enable, 0=disable, 1=enable */ +#define B0RDYPOL 0x00000002 /* Bank 0 RDY Active high, 0=active low, 1=active high */ +#define B0TT_1 0x00000004 /* Bank 0 Transition Time from Read to Write = 1 cycle */ +#define B0TT_2 0x00000008 /* Bank 0 Transition Time from Read to Write = 2 cycles */ +#define B0TT_3 0x0000000C /* Bank 0 Transition Time from Read to Write = 3 cycles */ +#define B0TT_4 0x00000000 /* Bank 0 Transition Time from Read to Write = 4 cycles */ +#define B0ST_1 0x00000010 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=1 cycle */ +#define B0ST_2 0x00000020 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=2 cycles */ +#define B0ST_3 0x00000030 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=3 cycles */ +#define B0ST_4 0x00000000 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=4 cycles */ +#define B0HT_1 0x00000040 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 1 cycle */ +#define B0HT_2 0x00000080 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 2 cycles */ +#define B0HT_3 0x000000C0 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 3 cycles */ +#define B0HT_0 0x00000000 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 0 cycles */ +#define B0RAT_1 0x00000100 /* Bank 0 Read Access Time = 1 cycle */ +#define B0RAT_2 0x00000200 /* Bank 0 Read Access Time = 2 cycles */ +#define B0RAT_3 0x00000300 /* Bank 0 Read Access Time = 3 cycles */ +#define B0RAT_4 0x00000400 /* Bank 0 Read Access Time = 4 cycles */ +#define B0RAT_5 0x00000500 /* Bank 0 Read Access Time = 5 cycles */ +#define B0RAT_6 0x00000600 /* Bank 0 Read Access Time = 6 cycles */ +#define B0RAT_7 0x00000700 /* Bank 0 Read Access Time = 7 cycles */ +#define B0RAT_8 0x00000800 /* Bank 0 Read Access Time = 8 cycles */ +#define B0RAT_9 0x00000900 /* Bank 0 Read Access Time = 9 cycles */ +#define B0RAT_10 0x00000A00 /* Bank 0 Read Access Time = 10 cycles */ +#define B0RAT_11 0x00000B00 /* Bank 0 Read Access Time = 11 cycles */ +#define B0RAT_12 0x00000C00 /* Bank 0 Read Access Time = 12 cycles */ +#define B0RAT_13 0x00000D00 /* Bank 0 Read Access Time = 13 cycles */ +#define B0RAT_14 0x00000E00 /* Bank 0 Read Access Time = 14 cycles */ +#define B0RAT_15 0x00000F00 /* Bank 0 Read Access Time = 15 cycles */ +#define B0WAT_1 0x00001000 /* Bank 0 Write Access Time = 1 cycle */ +#define B0WAT_2 0x00002000 /* Bank 0 Write Access Time = 2 cycles */ +#define B0WAT_3 0x00003000 /* Bank 0 Write Access Time = 3 cycles */ +#define B0WAT_4 0x00004000 /* Bank 0 Write Access Time = 4 cycles */ +#define B0WAT_5 0x00005000 /* Bank 0 Write Access Time = 5 cycles */ +#define B0WAT_6 0x00006000 /* Bank 0 Write Access Time = 6 cycles */ +#define B0WAT_7 0x00007000 /* Bank 0 Write Access Time = 7 cycles */ +#define B0WAT_8 0x00008000 /* Bank 0 Write Access Time = 8 cycles */ +#define B0WAT_9 0x00009000 /* Bank 0 Write Access Time = 9 cycles */ +#define B0WAT_10 0x0000A000 /* Bank 0 Write Access Time = 10 cycles */ +#define B0WAT_11 0x0000B000 /* Bank 0 Write Access Time = 11 cycles */ +#define B0WAT_12 0x0000C000 /* Bank 0 Write Access Time = 12 cycles */ +#define B0WAT_13 0x0000D000 /* Bank 0 Write Access Time = 13 cycles */ +#define B0WAT_14 0x0000E000 /* Bank 0 Write Access Time = 14 cycles */ +#define B0WAT_15 0x0000F000 /* Bank 0 Write Access Time = 15 cycles */ +#define B1RDYEN 0x00010000 /* Bank 1 RDY enable, 0=disable, 1=enable */ +#define B1RDYPOL 0x00020000 /* Bank 1 RDY Active high, 0=active low, 1=active high */ +#define B1TT_1 0x00040000 /* Bank 1 Transition Time from Read to Write = 1 cycle */ +#define B1TT_2 0x00080000 /* Bank 1 Transition Time from Read to Write = 2 cycles */ +#define B1TT_3 0x000C0000 /* Bank 1 Transition Time from Read to Write = 3 cycles */ +#define B1TT_4 0x00000000 /* Bank 1 Transition Time from Read to Write = 4 cycles */ +#define B1ST_1 0x00100000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */ +#define B1ST_2 0x00200000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */ +#define B1ST_3 0x00300000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */ +#define B1ST_4 0x00000000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */ +#define B1HT_1 0x00400000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */ +#define B1HT_2 0x00800000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */ +#define B1HT_3 0x00C00000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */ +#define B1HT_0 0x00000000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */ +#define B1RAT_1 0x01000000 /* Bank 1 Read Access Time = 1 cycle */ +#define B1RAT_2 0x02000000 /* Bank 1 Read Access Time = 2 cycles */ +#define B1RAT_3 0x03000000 /* Bank 1 Read Access Time = 3 cycles */ +#define B1RAT_4 0x04000000 /* Bank 1 Read Access Time = 4 cycles */ +#define B1RAT_5 0x05000000 /* Bank 1 Read Access Time = 5 cycles */ +#define B1RAT_6 0x06000000 /* Bank 1 Read Access Time = 6 cycles */ +#define B1RAT_7 0x07000000 /* Bank 1 Read Access Time = 7 cycles */ +#define B1RAT_8 0x08000000 /* Bank 1 Read Access Time = 8 cycles */ +#define B1RAT_9 0x09000000 /* Bank 1 Read Access Time = 9 cycles */ +#define B1RAT_10 0x0A000000 /* Bank 1 Read Access Time = 10 cycles */ +#define B1RAT_11 0x0B000000 /* Bank 1 Read Access Time = 11 cycles */ +#define B1RAT_12 0x0C000000 /* Bank 1 Read Access Time = 12 cycles */ +#define B1RAT_13 0x0D000000 /* Bank 1 Read Access Time = 13 cycles */ +#define B1RAT_14 0x0E000000 /* Bank 1 Read Access Time = 14 cycles */ +#define B1RAT_15 0x0F000000 /* Bank 1 Read Access Time = 15 cycles */ +#define B1WAT_1 0x10000000 /* Bank 1 Write Access Time = 1 cycle */ +#define B1WAT_2 0x20000000 /* Bank 1 Write Access Time = 2 cycles */ +#define B1WAT_3 0x30000000 /* Bank 1 Write Access Time = 3 cycles */ +#define B1WAT_4 0x40000000 /* Bank 1 Write Access Time = 4 cycles */ +#define B1WAT_5 0x50000000 /* Bank 1 Write Access Time = 5 cycles */ +#define B1WAT_6 0x60000000 /* Bank 1 Write Access Time = 6 cycles */ +#define B1WAT_7 0x70000000 /* Bank 1 Write Access Time = 7 cycles */ +#define B1WAT_8 0x80000000 /* Bank 1 Write Access Time = 8 cycles */ +#define B1WAT_9 0x90000000 /* Bank 1 Write Access Time = 9 cycles */ +#define B1WAT_10 0xA0000000 /* Bank 1 Write Access Time = 10 cycles */ +#define B1WAT_11 0xB0000000 /* Bank 1 Write Access Time = 11 cycles */ +#define B1WAT_12 0xC0000000 /* Bank 1 Write Access Time = 12 cycles */ +#define B1WAT_13 0xD0000000 /* Bank 1 Write Access Time = 13 cycles */ +#define B1WAT_14 0xE0000000 /* Bank 1 Write Access Time = 14 cycles */ +#define B1WAT_15 0xF0000000 /* Bank 1 Write Access Time = 15 cycles */ + +/* AMBCTL1 Masks */ +#define B2RDYEN 0x00000001 /* Bank 2 RDY Enable, 0=disable, 1=enable */ +#define B2RDYPOL 0x00000002 /* Bank 2 RDY Active high, 0=active low, 1=active high */ +#define B2TT_1 0x00000004 /* Bank 2 Transition Time from Read to Write = 1 cycle */ +#define B2TT_2 0x00000008 /* Bank 2 Transition Time from Read to Write = 2 cycles */ +#define B2TT_3 0x0000000C /* Bank 2 Transition Time from Read to Write = 3 cycles */ +#define B2TT_4 0x00000000 /* Bank 2 Transition Time from Read to Write = 4 cycles */ +#define B2ST_1 0x00000010 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */ +#define B2ST_2 0x00000020 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */ +#define B2ST_3 0x00000030 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */ +#define B2ST_4 0x00000000 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */ +#define B2HT_1 0x00000040 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */ +#define B2HT_2 0x00000080 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */ +#define B2HT_3 0x000000C0 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */ +#define B2HT_0 0x00000000 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */ +#define B2RAT_1 0x00000100 /* Bank 2 Read Access Time = 1 cycle */ +#define B2RAT_2 0x00000200 /* Bank 2 Read Access Time = 2 cycles */ +#define B2RAT_3 0x00000300 /* Bank 2 Read Access Time = 3 cycles */ +#define B2RAT_4 0x00000400 /* Bank 2 Read Access Time = 4 cycles */ +#define B2RAT_5 0x00000500 /* Bank 2 Read Access Time = 5 cycles */ +#define B2RAT_6 0x00000600 /* Bank 2 Read Access Time = 6 cycles */ +#define B2RAT_7 0x00000700 /* Bank 2 Read Access Time = 7 cycles */ +#define B2RAT_8 0x00000800 /* Bank 2 Read Access Time = 8 cycles */ +#define B2RAT_9 0x00000900 /* Bank 2 Read Access Time = 9 cycles */ +#define B2RAT_10 0x00000A00 /* Bank 2 Read Access Time = 10 cycles */ +#define B2RAT_11 0x00000B00 /* Bank 2 Read Access Time = 11 cycles */ +#define B2RAT_12 0x00000C00 /* Bank 2 Read Access Time = 12 cycles */ +#define B2RAT_13 0x00000D00 /* Bank 2 Read Access Time = 13 cycles */ +#define B2RAT_14 0x00000E00 /* Bank 2 Read Access Time = 14 cycles */ +#define B2RAT_15 0x00000F00 /* Bank 2 Read Access Time = 15 cycles */ +#define B2WAT_1 0x00001000 /* Bank 2 Write Access Time = 1 cycle */ +#define B2WAT_2 0x00002000 /* Bank 2 Write Access Time = 2 cycles */ +#define B2WAT_3 0x00003000 /* Bank 2 Write Access Time = 3 cycles */ +#define B2WAT_4 0x00004000 /* Bank 2 Write Access Time = 4 cycles */ +#define B2WAT_5 0x00005000 /* Bank 2 Write Access Time = 5 cycles */ +#define B2WAT_6 0x00006000 /* Bank 2 Write Access Time = 6 cycles */ +#define B2WAT_7 0x00007000 /* Bank 2 Write Access Time = 7 cycles */ +#define B2WAT_8 0x00008000 /* Bank 2 Write Access Time = 8 cycles */ +#define B2WAT_9 0x00009000 /* Bank 2 Write Access Time = 9 cycles */ +#define B2WAT_10 0x0000A000 /* Bank 2 Write Access Time = 10 cycles */ +#define B2WAT_11 0x0000B000 /* Bank 2 Write Access Time = 11 cycles */ +#define B2WAT_12 0x0000C000 /* Bank 2 Write Access Time = 12 cycles */ +#define B2WAT_13 0x0000D000 /* Bank 2 Write Access Time = 13 cycles */ +#define B2WAT_14 0x0000E000 /* Bank 2 Write Access Time = 14 cycles */ +#define B2WAT_15 0x0000F000 /* Bank 2 Write Access Time = 15 cycles */ +#define B3RDYEN 0x00010000 /* Bank 3 RDY enable, 0=disable, 1=enable */ +#define B3RDYPOL 0x00020000 /* Bank 3 RDY Active high, 0=active low, 1=active high */ +#define B3TT_1 0x00040000 /* Bank 3 Transition Time from Read to Write = 1 cycle */ +#define B3TT_2 0x00080000 /* Bank 3 Transition Time from Read to Write = 2 cycles */ +#define B3TT_3 0x000C0000 /* Bank 3 Transition Time from Read to Write = 3 cycles */ +#define B3TT_4 0x00000000 /* Bank 3 Transition Time from Read to Write = 4 cycles */ +#define B3ST_1 0x00100000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */ +#define B3ST_2 0x00200000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */ +#define B3ST_3 0x00300000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */ +#define B3ST_4 0x00000000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */ +#define B3HT_1 0x00400000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */ +#define B3HT_2 0x00800000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */ +#define B3HT_3 0x00C00000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */ +#define B3HT_0 0x00000000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */ +#define B3RAT_1 0x01000000 /* Bank 3 Read Access Time = 1 cycle */ +#define B3RAT_2 0x02000000 /* Bank 3 Read Access Time = 2 cycles */ +#define B3RAT_3 0x03000000 /* Bank 3 Read Access Time = 3 cycles */ +#define B3RAT_4 0x04000000 /* Bank 3 Read Access Time = 4 cycles */ +#define B3RAT_5 0x05000000 /* Bank 3 Read Access Time = 5 cycles */ +#define B3RAT_6 0x06000000 /* Bank 3 Read Access Time = 6 cycles */ +#define B3RAT_7 0x07000000 /* Bank 3 Read Access Time = 7 cycles */ +#define B3RAT_8 0x08000000 /* Bank 3 Read Access Time = 8 cycles */ +#define B3RAT_9 0x09000000 /* Bank 3 Read Access Time = 9 cycles */ +#define B3RAT_10 0x0A000000 /* Bank 3 Read Access Time = 10 cycles */ +#define B3RAT_11 0x0B000000 /* Bank 3 Read Access Time = 11 cycles */ +#define B3RAT_12 0x0C000000 /* Bank 3 Read Access Time = 12 cycles */ +#define B3RAT_13 0x0D000000 /* Bank 3 Read Access Time = 13 cycles */ +#define B3RAT_14 0x0E000000 /* Bank 3 Read Access Time = 14 cycles */ +#define B3RAT_15 0x0F000000 /* Bank 3 Read Access Time = 15 cycles */ +#define B3WAT_1 0x10000000 /* Bank 3 Write Access Time = 1 cycle */ +#define B3WAT_2 0x20000000 /* Bank 3 Write Access Time = 2 cycles */ +#define B3WAT_3 0x30000000 /* Bank 3 Write Access Time = 3 cycles */ +#define B3WAT_4 0x40000000 /* Bank 3 Write Access Time = 4 cycles */ +#define B3WAT_5 0x50000000 /* Bank 3 Write Access Time = 5 cycles */ +#define B3WAT_6 0x60000000 /* Bank 3 Write Access Time = 6 cycles */ +#define B3WAT_7 0x70000000 /* Bank 3 Write Access Time = 7 cycles */ +#define B3WAT_8 0x80000000 /* Bank 3 Write Access Time = 8 cycles */ +#define B3WAT_9 0x90000000 /* Bank 3 Write Access Time = 9 cycles */ +#define B3WAT_10 0xA0000000 /* Bank 3 Write Access Time = 10 cycles */ +#define B3WAT_11 0xB0000000 /* Bank 3 Write Access Time = 11 cycles */ +#define B3WAT_12 0xC0000000 /* Bank 3 Write Access Time = 12 cycles */ +#define B3WAT_13 0xD0000000 /* Bank 3 Write Access Time = 13 cycles */ +#define B3WAT_14 0xE0000000 /* Bank 3 Write Access Time = 14 cycles */ +#define B3WAT_15 0xF0000000 /* Bank 3 Write Access Time = 15 cycles */ + +/* ********************** SDRAM CONTROLLER MASKS *************************** */ + +/* EBIU_SDGCTL Masks */ +#define SCTLE 0x00000001 /* Enable SCLK[0], /SRAS, /SCAS, /SWE, SDQM[3:0] */ +#define CL_2 0x00000008 /* SDRAM CAS latency = 2 cycles */ +#define CL_3 0x0000000C /* SDRAM CAS latency = 3 cycles */ +#define PFE 0x00000010 /* Enable SDRAM prefetch */ +#define PFP 0x00000020 /* Prefetch has priority over AMC requests */ +#define TRAS_1 0x00000040 /* SDRAM tRAS = 1 cycle */ +#define TRAS_2 0x00000080 /* SDRAM tRAS = 2 cycles */ +#define TRAS_3 0x000000C0 /* SDRAM tRAS = 3 cycles */ +#define TRAS_4 0x00000100 /* SDRAM tRAS = 4 cycles */ +#define TRAS_5 0x00000140 /* SDRAM tRAS = 5 cycles */ +#define TRAS_6 0x00000180 /* SDRAM tRAS = 6 cycles */ +#define TRAS_7 0x000001C0 /* SDRAM tRAS = 7 cycles */ +#define TRAS_8 0x00000200 /* SDRAM tRAS = 8 cycles */ +#define TRAS_9 0x00000240 /* SDRAM tRAS = 9 cycles */ +#define TRAS_10 0x00000280 /* SDRAM tRAS = 10 cycles */ +#define TRAS_11 0x000002C0 /* SDRAM tRAS = 11 cycles */ +#define TRAS_12 0x00000300 /* SDRAM tRAS = 12 cycles */ +#define TRAS_13 0x00000340 /* SDRAM tRAS = 13 cycles */ +#define TRAS_14 0x00000380 /* SDRAM tRAS = 14 cycles */ +#define TRAS_15 0x000003C0 /* SDRAM tRAS = 15 cycles */ +#define TRP_1 0x00000800 /* SDRAM tRP = 1 cycle */ +#define TRP_2 0x00001000 /* SDRAM tRP = 2 cycles */ +#define TRP_3 0x00001800 /* SDRAM tRP = 3 cycles */ +#define TRP_4 0x00002000 /* SDRAM tRP = 4 cycles */ +#define TRP_5 0x00002800 /* SDRAM tRP = 5 cycles */ +#define TRP_6 0x00003000 /* SDRAM tRP = 6 cycles */ +#define TRP_7 0x00003800 /* SDRAM tRP = 7 cycles */ +#define TRCD_1 0x00008000 /* SDRAM tRCD = 1 cycle */ +#define TRCD_2 0x00010000 /* SDRAM tRCD = 2 cycles */ +#define TRCD_3 0x00018000 /* SDRAM tRCD = 3 cycles */ +#define TRCD_4 0x00020000 /* SDRAM tRCD = 4 cycles */ +#define TRCD_5 0x00028000 /* SDRAM tRCD = 5 cycles */ +#define TRCD_6 0x00030000 /* SDRAM tRCD = 6 cycles */ +#define TRCD_7 0x00038000 /* SDRAM tRCD = 7 cycles */ +#define TWR_1 0x00080000 /* SDRAM tWR = 1 cycle */ +#define TWR_2 0x00100000 /* SDRAM tWR = 2 cycles */ +#define TWR_3 0x00180000 /* SDRAM tWR = 3 cycles */ +#define PUPSD 0x00200000 /*Power-up start delay */ +#define PSM 0x00400000 /* SDRAM power-up sequence = Precharge, mode register set, 8 CBR refresh cycles */ +#define PSS 0x00800000 /* enable SDRAM power-up sequence on next SDRAM access */ +#define SRFS 0x01000000 /* Start SDRAM self-refresh mode */ +#define EBUFE 0x02000000 /* Enable external buffering timing */ +#define FBBRW 0x04000000 /* Fast back-to-back read write enable */ +#define EMREN 0x10000000 /* Extended mode register enable */ +#define TCSR 0x20000000 /* Temp compensated self refresh value 85 deg C */ +#define CDDBG 0x40000000 /* Tristate SDRAM controls during bus grant */ + +/* EBIU_SDBCTL Masks */ +#define EB0_E 0x00000001 /* Enable SDRAM external bank 0 */ +#define EB0_SZ_16 0x00000000 /* SDRAM external bank size = 16MB */ +#define EB0_SZ_32 0x00000002 /* SDRAM external bank size = 32MB */ +#define EB0_SZ_64 0x00000004 /* SDRAM external bank size = 64MB */ +#define EB0_SZ_128 0x00000006 /* SDRAM external bank size = 128MB */ +#define EB0_CAW_8 0x00000000 /* SDRAM external bank column address width = 8 bits */ +#define EB0_CAW_9 0x00000010 /* SDRAM external bank column address width = 9 bits */ +#define EB0_CAW_10 0x00000020 /* SDRAM external bank column address width = 9 bits */ +#define EB0_CAW_11 0x00000030 /* SDRAM external bank column address width = 9 bits */ + +#define EB1_E 0x00000100 /* Enable SDRAM external bank 1 */ +#define EB1__SZ_16 0x00000000 /* SDRAM external bank size = 16MB */ +#define EB1__SZ_32 0x00000200 /* SDRAM external bank size = 32MB */ +#define EB1__SZ_64 0x00000400 /* SDRAM external bank size = 64MB */ +#define EB1__SZ_128 0x00000600 /* SDRAM external bank size = 128MB */ +#define EB1__CAW_8 0x00000000 /* SDRAM external bank column address width = 8 bits */ +#define EB1__CAW_9 0x00001000 /* SDRAM external bank column address width = 9 bits */ +#define EB1__CAW_10 0x00002000 /* SDRAM external bank column address width = 9 bits */ +#define EB1__CAW_11 0x00003000 /* SDRAM external bank column address width = 9 bits */ + +#define EB2__E 0x00010000 /* Enable SDRAM external bank 2 */ +#define EB2__SZ_16 0x00000000 /* SDRAM external bank size = 16MB */ +#define EB2__SZ_32 0x00020000 /* SDRAM external bank size = 32MB */ +#define EB2__SZ_64 0x00040000 /* SDRAM external bank size = 64MB */ +#define EB2__SZ_128 0x00060000 /* SDRAM external bank size = 128MB */ +#define EB2__CAW_8 0x00000000 /* SDRAM external bank column address width = 8 bits */ +#define EB2__CAW_9 0x00100000 /* SDRAM external bank column address width = 9 bits */ +#define EB2__CAW_10 0x00200000 /* SDRAM external bank column address width = 9 bits */ +#define EB2__CAW_11 0x00300000 /* SDRAM external bank column address width = 9 bits */ + +#define EB3__E 0x01000000 /* Enable SDRAM external bank 3 */ +#define EB3__SZ_16 0x00000000 /* SDRAM external bank size = 16MB */ +#define EB3__SZ_32 0x02000000 /* SDRAM external bank size = 32MB */ +#define EB3__SZ_64 0x04000000 /* SDRAM external bank size = 64MB */ +#define EB3__SZ_128 0x06000000 /* SDRAM external bank size = 128MB */ +#define EB3__CAW_8 0x00000000 /* SDRAM external bank column address width = 8 bits */ +#define EB3__CAW_9 0x10000000 /* SDRAM external bank column address width = 9 bits */ +#define EB3__CAW_10 0x20000000 /* SDRAM external bank column address width = 9 bits */ +#define EB3__CAW_11 0x30000000 /* SDRAM external bank column address width = 9 bits */ + +/* EBIU_SDSTAT Masks */ +#define SDCI 0x00000001 /* SDRAM controller is idle */ +#define SDSRA 0x00000002 /* SDRAM SDRAM self refresh is active */ +#define SDPUA 0x00000004 /* SDRAM power up active */ +#define SDRS 0x00000008 /* SDRAM is in reset state */ +#define SDEASE 0x00000010 /* SDRAM EAB sticky error status - W1C */ +#define BGSTAT 0x00000020 /* Bus granted */ + +/*VR_CTL Masks*/ +#define WAKE 0x100 +#define VLEV_6 0x60 +#define VLEV_7 0x70 +#define VLEV_8 0x80 +#define VLEV_9 0x90 +#define VLEV_10 0xA0 +#define VLEV_11 0xB0 +#define VLEV_12 0xC0 +#define VLEV_13 0xD0 +#define VLEV_14 0xE0 +#define VLEV_15 0xF0 +#define FREQ_3 0x03 + +#endif /* _DEF_BF561_H */ diff --git a/include/asm-blackfin/mach-bf561/dma.h b/include/asm-blackfin/mach-bf561/dma.h new file mode 100644 index 000000000000..21d982003e75 --- /dev/null +++ b/include/asm-blackfin/mach-bf561/dma.h @@ -0,0 +1,35 @@ +/***************************************************************************** +* +* BF-533/2/1 Specific Declarations +* +****************************************************************************/ + +#ifndef _MACH_DMA_H_ +#define _MACH_DMA_H_ + +#define MAX_BLACKFIN_DMA_CHANNEL 36 + +#define CH_PPI0 0 +#define CH_PPI (CH_PPI0) +#define CH_PPI1 1 +#define CH_SPORT0_RX 12 +#define CH_SPORT0_TX 13 +#define CH_SPORT1_RX 14 +#define CH_SPORT1_TX 15 +#define CH_SPI 16 +#define CH_UART_RX 17 +#define CH_UART_TX 18 +#define CH_MEM_STREAM0_DEST 24 /* TX */ +#define CH_MEM_STREAM0_SRC 25 /* RX */ +#define CH_MEM_STREAM1_DEST 26 /* TX */ +#define CH_MEM_STREAM1_SRC 27 /* RX */ +#define CH_MEM_STREAM2_DEST 28 +#define CH_MEM_STREAM2_SRC 29 +#define CH_MEM_STREAM3_SRC 30 +#define CH_MEM_STREAM3_DEST 31 +#define CH_IMEM_STREAM0_DEST 32 +#define CH_IMEM_STREAM0_SRC 33 +#define CH_IMEM_STREAM1_SRC 34 +#define CH_IMEM_STREAM1_DEST 35 + +#endif diff --git a/include/asm-blackfin/mach-bf561/irq.h b/include/asm-blackfin/mach-bf561/irq.h new file mode 100644 index 000000000000..a753ce720d74 --- /dev/null +++ b/include/asm-blackfin/mach-bf561/irq.h @@ -0,0 +1,450 @@ + +/* + * File: include/asm-blackfin/mach-bf561/irq.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Rev: + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _BF561_IRQ_H_ +#define _BF561_IRQ_H_ + +/*********************************************************************** + * Interrupt source definitions: + Event Source Core Event Name IRQ No + (highest priority) + Emulation Events EMU 0 + Reset RST 1 + NMI NMI 2 + Exception EVX 3 + Reserved -- 4 + Hardware Error IVHW 5 + Core Timer IVTMR 6 * + + PLL Wakeup Interrupt IVG7 7 + DMA1 Error (generic) IVG7 8 + DMA2 Error (generic) IVG7 9 + IMDMA Error (generic) IVG7 10 + PPI1 Error Interrupt IVG7 11 + PPI2 Error Interrupt IVG7 12 + SPORT0 Error Interrupt IVG7 13 + SPORT1 Error Interrupt IVG7 14 + SPI Error Interrupt IVG7 15 + UART Error Interrupt IVG7 16 + Reserved Interrupt IVG7 17 + + DMA1 0 Interrupt(PPI1) IVG8 18 + DMA1 1 Interrupt(PPI2) IVG8 19 + DMA1 2 Interrupt IVG8 20 + DMA1 3 Interrupt IVG8 21 + DMA1 4 Interrupt IVG8 22 + DMA1 5 Interrupt IVG8 23 + DMA1 6 Interrupt IVG8 24 + DMA1 7 Interrupt IVG8 25 + DMA1 8 Interrupt IVG8 26 + DMA1 9 Interrupt IVG8 27 + DMA1 10 Interrupt IVG8 28 + DMA1 11 Interrupt IVG8 29 + + DMA2 0 (SPORT0 RX) IVG9 30 + DMA2 1 (SPORT0 TX) IVG9 31 + DMA2 2 (SPORT1 RX) IVG9 32 + DMA2 3 (SPORT2 TX) IVG9 33 + DMA2 4 (SPI) IVG9 34 + DMA2 5 (UART RX) IVG9 35 + DMA2 6 (UART TX) IVG9 36 + DMA2 7 Interrupt IVG9 37 + DMA2 8 Interrupt IVG9 38 + DMA2 9 Interrupt IVG9 39 + DMA2 10 Interrupt IVG9 40 + DMA2 11 Interrupt IVG9 41 + + TIMER 0 Interrupt IVG10 42 + TIMER 1 Interrupt IVG10 43 + TIMER 2 Interrupt IVG10 44 + TIMER 3 Interrupt IVG10 45 + TIMER 4 Interrupt IVG10 46 + TIMER 5 Interrupt IVG10 47 + TIMER 6 Interrupt IVG10 48 + TIMER 7 Interrupt IVG10 49 + TIMER 8 Interrupt IVG10 50 + TIMER 9 Interrupt IVG10 51 + TIMER 10 Interrupt IVG10 52 + TIMER 11 Interrupt IVG10 53 + + Programmable Flags0 A (8) IVG11 54 + Programmable Flags0 B (8) IVG11 55 + Programmable Flags1 A (8) IVG11 56 + Programmable Flags1 B (8) IVG11 57 + Programmable Flags2 A (8) IVG11 58 + Programmable Flags2 B (8) IVG11 59 + + MDMA1 0 write/read INT IVG8 60 + MDMA1 1 write/read INT IVG8 61 + + MDMA2 0 write/read INT IVG9 62 + MDMA2 1 write/read INT IVG9 63 + + IMDMA 0 write/read INT IVG12 64 + IMDMA 1 write/read INT IVG12 65 + + Watch Dog Timer IVG13 66 + + Reserved interrupt IVG7 67 + Reserved interrupt IVG7 68 + Supplemental interrupt 0 IVG7 69 + supplemental interrupt 1 IVG7 70 + + Software Interrupt 1 IVG14 71 + Software Interrupt 2 IVG15 72 * + (lowest priority) + **********************************************************************/ + +#define SYS_IRQS 72 +#define NR_PERI_INTS 64 + +/* + * The ABSTRACT IRQ definitions + * the first seven of the following are fixed, + * the rest you change if you need to. + */ +/* IVG 0-6*/ +#define IRQ_EMU 0 /* Emulation */ +#define IRQ_RST 1 /* Reset */ +#define IRQ_NMI 2 /* Non Maskable Interrupt */ +#define IRQ_EVX 3 /* Exception */ +#define IRQ_UNUSED 4 /* Reserved interrupt */ +#define IRQ_HWERR 5 /* Hardware Error */ +#define IRQ_CORETMR 6 /* Core timer */ + +#define IVG_BASE 7 +/* IVG 7 */ +#define IRQ_PLL_WAKEUP (IVG_BASE + 0) /* PLL Wakeup Interrupt */ +#define IRQ_DMA1_ERROR (IVG_BASE + 1) /* DMA1 Error (general) */ +#define IRQ_DMA_ERROR IRQ_DMA1_ERROR /* DMA1 Error (general) */ +#define IRQ_DMA2_ERROR (IVG_BASE + 2) /* DMA2 Error (general) */ +#define IRQ_IMDMA_ERROR (IVG_BASE + 3) /* IMDMA Error Interrupt */ +#define IRQ_PPI1_ERROR (IVG_BASE + 4) /* PPI1 Error Interrupt */ +#define IRQ_PPI_ERROR IRQ_PPI1_ERROR /* PPI1 Error Interrupt */ +#define IRQ_PPI2_ERROR (IVG_BASE + 5) /* PPI2 Error Interrupt */ +#define IRQ_SPORT0_ERROR (IVG_BASE + 6) /* SPORT0 Error Interrupt */ +#define IRQ_SPORT1_ERROR (IVG_BASE + 7) /* SPORT1 Error Interrupt */ +#define IRQ_SPI_ERROR (IVG_BASE + 8) /* SPI Error Interrupt */ +#define IRQ_UART_ERROR (IVG_BASE + 9) /* UART Error Interrupt */ +#define IRQ_RESERVED_ERROR (IVG_BASE + 10) /* Reversed Interrupt */ +/* IVG 8 */ +#define IRQ_DMA1_0 (IVG_BASE + 11) /* DMA1 0 Interrupt(PPI1) */ +#define IRQ_PPI IRQ_DMA1_0 /* DMA1 0 Interrupt(PPI1) */ +#define IRQ_PPI0 IRQ_DMA1_0 /* DMA1 0 Interrupt(PPI1) */ +#define IRQ_DMA1_1 (IVG_BASE + 12) /* DMA1 1 Interrupt(PPI2) */ +#define IRQ_PPI1 IRQ_DMA1_1 /* DMA1 1 Interrupt(PPI2) */ +#define IRQ_DMA1_2 (IVG_BASE + 13) /* DMA1 2 Interrupt */ +#define IRQ_DMA1_3 (IVG_BASE + 14) /* DMA1 3 Interrupt */ +#define IRQ_DMA1_4 (IVG_BASE + 15) /* DMA1 4 Interrupt */ +#define IRQ_DMA1_5 (IVG_BASE + 16) /* DMA1 5 Interrupt */ +#define IRQ_DMA1_6 (IVG_BASE + 17) /* DMA1 6 Interrupt */ +#define IRQ_DMA1_7 (IVG_BASE + 18) /* DMA1 7 Interrupt */ +#define IRQ_DMA1_8 (IVG_BASE + 19) /* DMA1 8 Interrupt */ +#define IRQ_DMA1_9 (IVG_BASE + 20) /* DMA1 9 Interrupt */ +#define IRQ_DMA1_10 (IVG_BASE + 21) /* DMA1 10 Interrupt */ +#define IRQ_DMA1_11 (IVG_BASE + 22) /* DMA1 11 Interrupt */ +/* IVG 9 */ +#define IRQ_DMA2_0 (IVG_BASE + 23) /* DMA2 0 (SPORT0 RX) */ +#define IRQ_SPORT0_RX IRQ_DMA2_0 /* DMA2 0 (SPORT0 RX) */ +#define IRQ_DMA2_1 (IVG_BASE + 24) /* DMA2 1 (SPORT0 TX) */ +#define IRQ_SPORT0_TX IRQ_DMA2_1 /* DMA2 1 (SPORT0 TX) */ +#define IRQ_DMA2_2 (IVG_BASE + 25) /* DMA2 2 (SPORT1 RX) */ +#define IRQ_SPORT1_RX IRQ_DMA2_2 /* DMA2 2 (SPORT1 RX) */ +#define IRQ_DMA2_3 (IVG_BASE + 26) /* DMA2 3 (SPORT2 TX) */ +#define IRQ_SPORT1_TX IRQ_DMA2_3 /* DMA2 3 (SPORT2 TX) */ +#define IRQ_DMA2_4 (IVG_BASE + 27) /* DMA2 4 (SPI) */ +#define IRQ_SPI IRQ_DMA2_4 /* DMA2 4 (SPI) */ +#define IRQ_DMA2_5 (IVG_BASE + 28) /* DMA2 5 (UART RX) */ +#define IRQ_UART_RX IRQ_DMA2_5 /* DMA2 5 (UART RX) */ +#define IRQ_DMA2_6 (IVG_BASE + 29) /* DMA2 6 (UART TX) */ +#define IRQ_UART_TX IRQ_DMA2_6 /* DMA2 6 (UART TX) */ +#define IRQ_DMA2_7 (IVG_BASE + 30) /* DMA2 7 Interrupt */ +#define IRQ_DMA2_8 (IVG_BASE + 31) /* DMA2 8 Interrupt */ +#define IRQ_DMA2_9 (IVG_BASE + 32) /* DMA2 9 Interrupt */ +#define IRQ_DMA2_10 (IVG_BASE + 33) /* DMA2 10 Interrupt */ +#define IRQ_DMA2_11 (IVG_BASE + 34) /* DMA2 11 Interrupt */ +/* IVG 10 */ +#define IRQ_TIMER0 (IVG_BASE + 35) /* TIMER 0 Interrupt */ +#define IRQ_TIMER1 (IVG_BASE + 36) /* TIMER 1 Interrupt */ +#define IRQ_TIMER2 (IVG_BASE + 37) /* TIMER 2 Interrupt */ +#define IRQ_TIMER3 (IVG_BASE + 38) /* TIMER 3 Interrupt */ +#define IRQ_TIMER4 (IVG_BASE + 39) /* TIMER 4 Interrupt */ +#define IRQ_TIMER5 (IVG_BASE + 40) /* TIMER 5 Interrupt */ +#define IRQ_TIMER6 (IVG_BASE + 41) /* TIMER 6 Interrupt */ +#define IRQ_TIMER7 (IVG_BASE + 42) /* TIMER 7 Interrupt */ +#define IRQ_TIMER8 (IVG_BASE + 43) /* TIMER 8 Interrupt */ +#define IRQ_TIMER9 (IVG_BASE + 44) /* TIMER 9 Interrupt */ +#define IRQ_TIMER10 (IVG_BASE + 45) /* TIMER 10 Interrupt */ +#define IRQ_TIMER11 (IVG_BASE + 46) /* TIMER 11 Interrupt */ +/* IVG 11 */ +#define IRQ_PROG0_INTA (IVG_BASE + 47) /* Programmable Flags0 A (8) */ +#define IRQ_PROG_INTA IRQ_PROG0_INTA /* Programmable Flags0 A (8) */ +#define IRQ_PROG0_INTB (IVG_BASE + 48) /* Programmable Flags0 B (8) */ +#define IRQ_PROG_INTB IRQ_PROG0_INTB /* Programmable Flags0 B (8) */ +#define IRQ_PROG1_INTA (IVG_BASE + 49) /* Programmable Flags1 A (8) */ +#define IRQ_PROG1_INTB (IVG_BASE + 50) /* Programmable Flags1 B (8) */ +#define IRQ_PROG2_INTA (IVG_BASE + 51) /* Programmable Flags2 A (8) */ +#define IRQ_PROG2_INTB (IVG_BASE + 52) /* Programmable Flags2 B (8) */ +/* IVG 8 */ +#define IRQ_DMA1_WRRD0 (IVG_BASE + 53) /* MDMA1 0 write/read INT */ +#define IRQ_DMA_WRRD0 IRQ_DMA1_WRRD0 /* MDMA1 0 write/read INT */ +#define IRQ_MEM_DMA0 IRQ_DMA1_WRRD0 +#define IRQ_DMA1_WRRD1 (IVG_BASE + 54) /* MDMA1 1 write/read INT */ +#define IRQ_DMA_WRRD1 IRQ_DMA1_WRRD1 /* MDMA1 1 write/read INT */ +#define IRQ_MEM_DMA1 IRQ_DMA1_WRRD1 +/* IVG 9 */ +#define IRQ_DMA2_WRRD0 (IVG_BASE + 55) /* MDMA2 0 write/read INT */ +#define IRQ_MEM_DMA2 IRQ_DMA2_WRRD0 +#define IRQ_DMA2_WRRD1 (IVG_BASE + 56) /* MDMA2 1 write/read INT */ +#define IRQ_MEM_DMA3 IRQ_DMA2_WRRD1 +/* IVG 12 */ +#define IRQ_IMDMA_WRRD0 (IVG_BASE + 57) /* IMDMA 0 write/read INT */ +#define IRQ_IMEM_DMA0 IRQ_IMDMA_WRRD0 +#define IRQ_IMDMA_WRRD1 (IVG_BASE + 58) /* IMDMA 1 write/read INT */ +#define IRQ_IMEM_DMA1 IRQ_IMDMA_WRRD1 +/* IVG 13 */ +#define IRQ_WATCH (IVG_BASE + 59) /* Watch Dog Timer */ +/* IVG 7 */ +#define IRQ_RESERVED_1 (IVG_BASE + 60) /* Reserved interrupt */ +#define IRQ_RESERVED_2 (IVG_BASE + 61) /* Reserved interrupt */ +#define IRQ_SUPPLE_0 (IVG_BASE + 62) /* Supplemental interrupt 0 */ +#define IRQ_SUPPLE_1 (IVG_BASE + 63) /* supplemental interrupt 1 */ +#define IRQ_SW_INT1 71 /* Software Interrupt 1 */ +#define IRQ_SW_INT2 72 /* Software Interrupt 2 */ + /* reserved for SYSCALL */ +#define IRQ_PF0 73 +#define IRQ_PF1 74 +#define IRQ_PF2 75 +#define IRQ_PF3 76 +#define IRQ_PF4 77 +#define IRQ_PF5 78 +#define IRQ_PF6 79 +#define IRQ_PF7 80 +#define IRQ_PF8 81 +#define IRQ_PF9 82 +#define IRQ_PF10 83 +#define IRQ_PF11 84 +#define IRQ_PF12 85 +#define IRQ_PF13 86 +#define IRQ_PF14 87 +#define IRQ_PF15 88 +#define IRQ_PF16 89 +#define IRQ_PF17 90 +#define IRQ_PF18 91 +#define IRQ_PF19 92 +#define IRQ_PF20 93 +#define IRQ_PF21 94 +#define IRQ_PF22 95 +#define IRQ_PF23 96 +#define IRQ_PF24 97 +#define IRQ_PF25 98 +#define IRQ_PF26 99 +#define IRQ_PF27 100 +#define IRQ_PF28 101 +#define IRQ_PF29 102 +#define IRQ_PF30 103 +#define IRQ_PF31 104 +#define IRQ_PF32 105 +#define IRQ_PF33 106 +#define IRQ_PF34 107 +#define IRQ_PF35 108 +#define IRQ_PF36 109 +#define IRQ_PF37 110 +#define IRQ_PF38 111 +#define IRQ_PF39 112 +#define IRQ_PF40 113 +#define IRQ_PF41 114 +#define IRQ_PF42 115 +#define IRQ_PF43 116 +#define IRQ_PF44 117 +#define IRQ_PF45 118 +#define IRQ_PF46 119 +#define IRQ_PF47 120 + +#ifdef CONFIG_IRQCHIP_DEMUX_GPIO +#define NR_IRQS (IRQ_PF47 + 1) +#else +#define NR_IRQS SYS_IRQS +#endif + +#define IVG7 7 +#define IVG8 8 +#define IVG9 9 +#define IVG10 10 +#define IVG11 11 +#define IVG12 12 +#define IVG13 13 +#define IVG14 14 +#define IVG15 15 + +/* + * DEFAULT PRIORITIES: + */ + +#define CONFIG_DEF_PLL_WAKEUP 7 +#define CONFIG_DEF_DMA1_ERROR 7 +#define CONFIG_DEF_DMA2_ERROR 7 +#define CONFIG_DEF_IMDMA_ERROR 7 +#define CONFIG_DEF_PPI1_ERROR 7 +#define CONFIG_DEF_PPI2_ERROR 7 +#define CONFIG_DEF_SPORT0_ERROR 7 +#define CONFIG_DEF_SPORT1_ERROR 7 +#define CONFIG_DEF_SPI_ERROR 7 +#define CONFIG_DEF_UART_ERROR 7 +#define CONFIG_DEF_RESERVED_ERROR 7 +#define CONFIG_DEF_DMA1_0 8 +#define CONFIG_DEF_DMA1_1 8 +#define CONFIG_DEF_DMA1_2 8 +#define CONFIG_DEF_DMA1_3 8 +#define CONFIG_DEF_DMA1_4 8 +#define CONFIG_DEF_DMA1_5 8 +#define CONFIG_DEF_DMA1_6 8 +#define CONFIG_DEF_DMA1_7 8 +#define CONFIG_DEF_DMA1_8 8 +#define CONFIG_DEF_DMA1_9 8 +#define CONFIG_DEF_DMA1_10 8 +#define CONFIG_DEF_DMA1_11 8 +#define CONFIG_DEF_DMA2_0 9 +#define CONFIG_DEF_DMA2_1 9 +#define CONFIG_DEF_DMA2_2 9 +#define CONFIG_DEF_DMA2_3 9 +#define CONFIG_DEF_DMA2_4 9 +#define CONFIG_DEF_DMA2_5 9 +#define CONFIG_DEF_DMA2_6 9 +#define CONFIG_DEF_DMA2_7 9 +#define CONFIG_DEF_DMA2_8 9 +#define CONFIG_DEF_DMA2_9 9 +#define CONFIG_DEF_DMA2_10 9 +#define CONFIG_DEF_DMA2_11 9 +#define CONFIG_DEF_TIMER0 10 +#define CONFIG_DEF_TIMER1 10 +#define CONFIG_DEF_TIMER2 10 +#define CONFIG_DEF_TIMER3 10 +#define CONFIG_DEF_TIMER4 10 +#define CONFIG_DEF_TIMER5 10 +#define CONFIG_DEF_TIMER6 10 +#define CONFIG_DEF_TIMER7 10 +#define CONFIG_DEF_TIMER8 10 +#define CONFIG_DEF_TIMER9 10 +#define CONFIG_DEF_TIMER10 10 +#define CONFIG_DEF_TIMER11 10 +#define CONFIG_DEF_PROG0_INTA 11 +#define CONFIG_DEF_PROG0_INTB 11 +#define CONFIG_DEF_PROG1_INTA 11 +#define CONFIG_DEF_PROG1_INTB 11 +#define CONFIG_DEF_PROG2_INTA 11 +#define CONFIG_DEF_PROG2_INTB 11 +#define CONFIG_DEF_DMA1_WRRD0 8 +#define CONFIG_DEF_DMA1_WRRD1 8 +#define CONFIG_DEF_DMA2_WRRD0 9 +#define CONFIG_DEF_DMA2_WRRD1 9 +#define CONFIG_DEF_IMDMA_WRRD0 12 +#define CONFIG_DEF_IMDMA_WRRD1 12 +#define CONFIG_DEF_WATCH 13 +#define CONFIG_DEF_RESERVED_1 7 +#define CONFIG_DEF_RESERVED_2 7 +#define CONFIG_DEF_SUPPLE_0 7 +#define CONFIG_DEF_SUPPLE_1 7 + +/* IAR0 BIT FIELDS */ +#define IRQ_PLL_WAKEUP_POS 0 +#define IRQ_DMA1_ERROR_POS 4 +#define IRQ_DMA2_ERROR_POS 8 +#define IRQ_IMDMA_ERROR_POS 12 +#define IRQ_PPI0_ERROR_POS 16 +#define IRQ_PPI1_ERROR_POS 20 +#define IRQ_SPORT0_ERROR_POS 24 +#define IRQ_SPORT1_ERROR_POS 28 +/* IAR1 BIT FIELDS */ +#define IRQ_SPI_ERROR_POS 0 +#define IRQ_UART_ERROR_POS 4 +#define IRQ_RESERVED_ERROR_POS 8 +#define IRQ_DMA1_0_POS 12 +#define IRQ_DMA1_1_POS 16 +#define IRQ_DMA1_2_POS 20 +#define IRQ_DMA1_3_POS 24 +#define IRQ_DMA1_4_POS 28 +/* IAR2 BIT FIELDS */ +#define IRQ_DMA1_5_POS 0 +#define IRQ_DMA1_6_POS 4 +#define IRQ_DMA1_7_POS 8 +#define IRQ_DMA1_8_POS 12 +#define IRQ_DMA1_9_POS 16 +#define IRQ_DMA1_10_POS 20 +#define IRQ_DMA1_11_POS 24 +#define IRQ_DMA2_0_POS 28 +/* IAR3 BIT FIELDS */ +#define IRQ_DMA2_1_POS 0 +#define IRQ_DMA2_2_POS 4 +#define IRQ_DMA2_3_POS 8 +#define IRQ_DMA2_4_POS 12 +#define IRQ_DMA2_5_POS 16 +#define IRQ_DMA2_6_POS 20 +#define IRQ_DMA2_7_POS 24 +#define IRQ_DMA2_8_POS 28 +/* IAR4 BIT FIELDS */ +#define IRQ_DMA2_9_POS 0 +#define IRQ_DMA2_10_POS 4 +#define IRQ_DMA2_11_POS 8 +#define IRQ_TIMER0_POS 12 +#define IRQ_TIMER1_POS 16 +#define IRQ_TIMER2_POS 20 +#define IRQ_TIMER3_POS 24 +#define IRQ_TIMER4_POS 28 +/* IAR5 BIT FIELDS */ +#define IRQ_TIMER5_POS 0 +#define IRQ_TIMER6_POS 4 +#define IRQ_TIMER7_POS 8 +#define IRQ_TIMER8_POS 12 +#define IRQ_TIMER9_POS 16 +#define IRQ_TIMER10_POS 20 +#define IRQ_TIMER11_POS 24 +#define IRQ_PROG0_INTA_POS 28 +/* IAR6 BIT FIELDS */ +#define IRQ_PROG0_INTB_POS 0 +#define IRQ_PROG1_INTA_POS 4 +#define IRQ_PROG1_INTB_POS 8 +#define IRQ_PROG2_INTA_POS 12 +#define IRQ_PROG2_INTB_POS 16 +#define IRQ_DMA1_WRRD0_POS 20 +#define IRQ_DMA1_WRRD1_POS 24 +#define IRQ_DMA2_WRRD0_POS 28 +/* IAR7 BIT FIELDS */ +#define IRQ_DMA2_WRRD1_POS 0 +#define IRQ_IMDMA_WRRD0_POS 4 +#define IRQ_IMDMA_WRRD1_POS 8 +#define IRQ_WDTIMER_POS 12 +#define IRQ_RESERVED_1_POS 16 +#define IRQ_RESERVED_2_POS 20 +#define IRQ_SUPPLE_0_POS 24 +#define IRQ_SUPPLE_1_POS 28 + +#endif /* _BF561_IRQ_H_ */ diff --git a/include/asm-blackfin/mach-bf561/mem_init.h b/include/asm-blackfin/mach-bf561/mem_init.h new file mode 100644 index 000000000000..439a5895b346 --- /dev/null +++ b/include/asm-blackfin/mach-bf561/mem_init.h @@ -0,0 +1,322 @@ +/* + * File: include/asm-blackfin/mach-bf561/mem_init.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Rev: + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#if (CONFIG_MEM_MT48LC16M16A2TG_75 || CONFIG_MEM_MT48LC64M4A2FB_7E || CONFIG_MEM_GENERIC_BOARD || CONFIG_MEM_MT48LC8M32B2B5_7) +#if (CONFIG_SCLK_HZ > 119402985) +#define SDRAM_tRP TRP_2 +#define SDRAM_tRP_num 2 +#define SDRAM_tRAS TRAS_7 +#define SDRAM_tRAS_num 7 +#define SDRAM_tRCD TRCD_2 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 104477612) && (CONFIG_SCLK_HZ <= 119402985) +#define SDRAM_tRP TRP_2 +#define SDRAM_tRP_num 2 +#define SDRAM_tRAS TRAS_6 +#define SDRAM_tRAS_num 6 +#define SDRAM_tRCD TRCD_2 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 89552239) && (CONFIG_SCLK_HZ <= 104477612) +#define SDRAM_tRP TRP_2 +#define SDRAM_tRP_num 2 +#define SDRAM_tRAS TRAS_5 +#define SDRAM_tRAS_num 5 +#define SDRAM_tRCD TRCD_2 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 74626866) && (CONFIG_SCLK_HZ <= 89552239) +#define SDRAM_tRP TRP_2 +#define SDRAM_tRP_num 2 +#define SDRAM_tRAS TRAS_4 +#define SDRAM_tRAS_num 4 +#define SDRAM_tRCD TRCD_2 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 66666667) && (CONFIG_SCLK_HZ <= 74626866) +#define SDRAM_tRP TRP_2 +#define SDRAM_tRP_num 2 +#define SDRAM_tRAS TRAS_3 +#define SDRAM_tRAS_num 3 +#define SDRAM_tRCD TRCD_2 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 59701493) && (CONFIG_SCLK_HZ <= 66666667) +#define SDRAM_tRP TRP_1 +#define SDRAM_tRP_num 1 +#define SDRAM_tRAS TRAS_4 +#define SDRAM_tRAS_num 3 +#define SDRAM_tRCD TRCD_1 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 44776119) && (CONFIG_SCLK_HZ <= 59701493) +#define SDRAM_tRP TRP_1 +#define SDRAM_tRP_num 1 +#define SDRAM_tRAS TRAS_3 +#define SDRAM_tRAS_num 3 +#define SDRAM_tRCD TRCD_1 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ > 29850746) && (CONFIG_SCLK_HZ <= 44776119) +#define SDRAM_tRP TRP_1 +#define SDRAM_tRP_num 1 +#define SDRAM_tRAS TRAS_2 +#define SDRAM_tRAS_num 2 +#define SDRAM_tRCD TRCD_1 +#define SDRAM_tWR TWR_2 +#endif +#if (CONFIG_SCLK_HZ <= 29850746) +#define SDRAM_tRP TRP_1 +#define SDRAM_tRP_num 1 +#define SDRAM_tRAS TRAS_1 +#define SDRAM_tRAS_num 1 +#define SDRAM_tRCD TRCD_1 +#define SDRAM_tWR TWR_2 +#endif +#endif + +#if (CONFIG_MEM_MT48LC16M16A2TG_75) + /*SDRAM INFORMATION: */ +#define SDRAM_Tref 64 /* Refresh period in milliseconds */ +#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */ +#define SDRAM_CL CL_3 +#endif + +#if (CONFIG_MEM_MT48LC64M4A2FB_7E) + /*SDRAM INFORMATION: */ +#define SDRAM_Tref 64 /* Refresh period in milliseconds */ +#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */ +#define SDRAM_CL CL_3 +#endif + +#if (CONFIG_MEM_MT48LC8M32B2B5_7) + /*SDRAM INFORMATION: */ +#define SDRAM_Tref 64 /* Refresh period in milliseconds */ +#define SDRAM_NRA 4096 /* Number of row addresses in SDRAM */ +#define SDRAM_CL CL_3 +#endif + +#if (CONFIG_MEM_GENERIC_BOARD) + /*SDRAM INFORMATION: Modify this for your board */ +#define SDRAM_Tref 64 /* Refresh period in milliseconds */ +#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */ +#define SDRAM_CL CL_3 +#endif + +#if (CONFIG_MEM_SIZE == 128) +#define SDRAM_SIZE EB0_SZ_128 +#endif +#if (CONFIG_MEM_SIZE == 64) +#define SDRAM_SIZE EB0_SZ_64 +#endif +#if ( CONFIG_MEM_SIZE == 32) +#define SDRAM_SIZE EB0_SZ_32 +#endif +#if (CONFIG_MEM_SIZE == 16) +#define SDRAM_SIZE EB0_SZ_16 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 11) +#define SDRAM_WIDTH EB0_CAW_11 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 10) +#define SDRAM_WIDTH EB0_CAW_10 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 9) +#define SDRAM_WIDTH EB0_CAW_9 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 8) +#define SDRAM_WIDTH EB0_CAW_8 +#endif + +#define mem_SDBCTL (SDRAM_WIDTH | SDRAM_SIZE | EB0_E) + +/* Equation from section 17 (p17-46) of BF533 HRM */ +#define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num) + +/* Enable SCLK Out */ +#define mem_SDGCTL (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR | PSS) + +#if defined CONFIG_CLKIN_HALF +#define CLKIN_HALF 1 +#else +#define CLKIN_HALF 0 +#endif + +#if defined CONFIG_PLL_BYPASS +#define PLL_BYPASS 1 +#else +#define PLL_BYPASS 0 +#endif + +/***************************************Currently Not Being Used *********************************/ +#define flash_EBIU_AMBCTL_WAT ((CONFIG_FLASH_SPEED_BWAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1 +#define flash_EBIU_AMBCTL_RAT ((CONFIG_FLASH_SPEED_BRAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1 +#define flash_EBIU_AMBCTL_HT ((CONFIG_FLASH_SPEED_BHT * 4) / (4000000000 / CONFIG_SCLK_HZ)) +#define flash_EBIU_AMBCTL_ST ((CONFIG_FLASH_SPEED_BST * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1 +#define flash_EBIU_AMBCTL_TT ((CONFIG_FLASH_SPEED_BTT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1 + +#if (flash_EBIU_AMBCTL_TT > 3) +#define flash_EBIU_AMBCTL0_TT B0TT_4 +#endif +#if (flash_EBIU_AMBCTL_TT == 3) +#define flash_EBIU_AMBCTL0_TT B0TT_3 +#endif +#if (flash_EBIU_AMBCTL_TT == 2) +#define flash_EBIU_AMBCTL0_TT B0TT_2 +#endif +#if (flash_EBIU_AMBCTL_TT < 2) +#define flash_EBIU_AMBCTL0_TT B0TT_1 +#endif + +#if (flash_EBIU_AMBCTL_ST > 3) +#define flash_EBIU_AMBCTL0_ST B0ST_4 +#endif +#if (flash_EBIU_AMBCTL_ST == 3) +#define flash_EBIU_AMBCTL0_ST B0ST_3 +#endif +#if (flash_EBIU_AMBCTL_ST == 2) +#define flash_EBIU_AMBCTL0_ST B0ST_2 +#endif +#if (flash_EBIU_AMBCTL_ST < 2) +#define flash_EBIU_AMBCTL0_ST B0ST_1 +#endif + +#if (flash_EBIU_AMBCTL_HT > 2) +#define flash_EBIU_AMBCTL0_HT B0HT_3 +#endif +#if (flash_EBIU_AMBCTL_HT == 2) +#define flash_EBIU_AMBCTL0_HT B0HT_2 +#endif +#if (flash_EBIU_AMBCTL_HT == 1) +#define flash_EBIU_AMBCTL0_HT B0HT_1 +#endif +#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT == 0) +#define flash_EBIU_AMBCTL0_HT B0HT_0 +#endif +#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT != 0) +#define flash_EBIU_AMBCTL0_HT B0HT_1 +#endif + +#if (flash_EBIU_AMBCTL_WAT > 14) +#define flash_EBIU_AMBCTL0_WAT B0WAT_15 +#endif +#if (flash_EBIU_AMBCTL_WAT == 14) +#define flash_EBIU_AMBCTL0_WAT B0WAT_14 +#endif +#if (flash_EBIU_AMBCTL_WAT == 13) +#define flash_EBIU_AMBCTL0_WAT B0WAT_13 +#endif +#if (flash_EBIU_AMBCTL_WAT == 12) +#define flash_EBIU_AMBCTL0_WAT B0WAT_12 +#endif +#if (flash_EBIU_AMBCTL_WAT == 11) +#define flash_EBIU_AMBCTL0_WAT B0WAT_11 +#endif +#if (flash_EBIU_AMBCTL_WAT == 10) +#define flash_EBIU_AMBCTL0_WAT B0WAT_10 +#endif +#if (flash_EBIU_AMBCTL_WAT == 9) +#define flash_EBIU_AMBCTL0_WAT B0WAT_9 +#endif +#if (flash_EBIU_AMBCTL_WAT == 8) +#define flash_EBIU_AMBCTL0_WAT B0WAT_8 +#endif +#if (flash_EBIU_AMBCTL_WAT == 7) +#define flash_EBIU_AMBCTL0_WAT B0WAT_7 +#endif +#if (flash_EBIU_AMBCTL_WAT == 6) +#define flash_EBIU_AMBCTL0_WAT B0WAT_6 +#endif +#if (flash_EBIU_AMBCTL_WAT == 5) +#define flash_EBIU_AMBCTL0_WAT B0WAT_5 +#endif +#if (flash_EBIU_AMBCTL_WAT == 4) +#define flash_EBIU_AMBCTL0_WAT B0WAT_4 +#endif +#if (flash_EBIU_AMBCTL_WAT == 3) +#define flash_EBIU_AMBCTL0_WAT B0WAT_3 +#endif +#if (flash_EBIU_AMBCTL_WAT == 2) +#define flash_EBIU_AMBCTL0_WAT B0WAT_2 +#endif +#if (flash_EBIU_AMBCTL_WAT == 1) +#define flash_EBIU_AMBCTL0_WAT B0WAT_1 +#endif + +#if (flash_EBIU_AMBCTL_RAT > 14) +#define flash_EBIU_AMBCTL0_RAT B0RAT_15 +#endif +#if (flash_EBIU_AMBCTL_RAT == 14) +#define flash_EBIU_AMBCTL0_RAT B0RAT_14 +#endif +#if (flash_EBIU_AMBCTL_RAT == 13) +#define flash_EBIU_AMBCTL0_RAT B0RAT_13 +#endif +#if (flash_EBIU_AMBCTL_RAT == 12) +#define flash_EBIU_AMBCTL0_RAT B0RAT_12 +#endif +#if (flash_EBIU_AMBCTL_RAT == 11) +#define flash_EBIU_AMBCTL0_RAT B0RAT_11 +#endif +#if (flash_EBIU_AMBCTL_RAT == 10) +#define flash_EBIU_AMBCTL0_RAT B0RAT_10 +#endif +#if (flash_EBIU_AMBCTL_RAT == 9) +#define flash_EBIU_AMBCTL0_RAT B0RAT_9 +#endif +#if (flash_EBIU_AMBCTL_RAT == 8) +#define flash_EBIU_AMBCTL0_RAT B0RAT_8 +#endif +#if (flash_EBIU_AMBCTL_RAT == 7) +#define flash_EBIU_AMBCTL0_RAT B0RAT_7 +#endif +#if (flash_EBIU_AMBCTL_RAT == 6) +#define flash_EBIU_AMBCTL0_RAT B0RAT_6 +#endif +#if (flash_EBIU_AMBCTL_RAT == 5) +#define flash_EBIU_AMBCTL0_RAT B0RAT_5 +#endif +#if (flash_EBIU_AMBCTL_RAT == 4) +#define flash_EBIU_AMBCTL0_RAT B0RAT_4 +#endif +#if (flash_EBIU_AMBCTL_RAT == 3) +#define flash_EBIU_AMBCTL0_RAT B0RAT_3 +#endif +#if (flash_EBIU_AMBCTL_RAT == 2) +#define flash_EBIU_AMBCTL0_RAT B0RAT_2 +#endif +#if (flash_EBIU_AMBCTL_RAT == 1) +#define flash_EBIU_AMBCTL0_RAT B0RAT_1 +#endif + +#define flash_EBIU_AMBCTL0 \ + (flash_EBIU_AMBCTL0_WAT | flash_EBIU_AMBCTL0_RAT | flash_EBIU_AMBCTL0_HT | \ + flash_EBIU_AMBCTL0_ST | flash_EBIU_AMBCTL0_TT | CONFIG_FLASH_SPEED_RDYEN) diff --git a/include/asm-blackfin/mach-bf561/mem_map.h b/include/asm-blackfin/mach-bf561/mem_map.h new file mode 100644 index 000000000000..ebac9a8d838d --- /dev/null +++ b/include/asm-blackfin/mach-bf561/mem_map.h @@ -0,0 +1,75 @@ +/* + * Memory MAP + * Common header file for blackfin BF561 of processors. + */ + +#ifndef _MEM_MAP_561_H_ +#define _MEM_MAP_561_H_ + +#define COREMMR_BASE 0xFFE00000 /* Core MMRs */ +#define SYSMMR_BASE 0xFFC00000 /* System MMRs */ + +/* Async Memory Banks */ +#define ASYNC_BANK3_BASE 0x2C000000 /* Async Bank 3 */ +#define ASYNC_BANK3_SIZE 0x04000000 /* 64M */ +#define ASYNC_BANK2_BASE 0x28000000 /* Async Bank 2 */ +#define ASYNC_BANK2_SIZE 0x04000000 /* 64M */ +#define ASYNC_BANK1_BASE 0x24000000 /* Async Bank 1 */ +#define ASYNC_BANK1_SIZE 0x04000000 /* 64M */ +#define ASYNC_BANK0_BASE 0x20000000 /* Async Bank 0 */ +#define ASYNC_BANK0_SIZE 0x04000000 /* 64M */ + +/* Level 1 Memory */ + +#ifdef CONFIG_BLKFIN_CACHE +#define BLKFIN_ICACHESIZE (16*1024) +#else +#define BLKFIN_ICACHESIZE (0*1024) +#endif + +/* Memory Map for ADSP-BF561 processors */ + +#ifdef CONFIG_BF561 +#define L1_CODE_START 0xFFA00000 +#define L1_DATA_A_START 0xFF800000 +#define L1_DATA_B_START 0xFF900000 + +#define L1_CODE_LENGTH 0x4000 + +#ifdef CONFIG_BLKFIN_DCACHE + +#ifdef CONFIG_BLKFIN_DCACHE_BANKA +#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH (0x8000 - 0x4000) +#define L1_DATA_B_LENGTH 0x8000 +#define BLKFIN_DCACHESIZE (16*1024) +#define BLKFIN_DSUPBANKS 1 +#else +#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH (0x8000 - 0x4000) +#define L1_DATA_B_LENGTH (0x8000 - 0x4000) +#define BLKFIN_DCACHESIZE (32*1024) +#define BLKFIN_DSUPBANKS 2 +#endif + +#else +#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH 0x8000 +#define L1_DATA_B_LENGTH 0x8000 +#define BLKFIN_DCACHESIZE (0*1024) +#define BLKFIN_DSUPBANKS 0 +#endif /*CONFIG_BLKFIN_DCACHE*/ +#endif + +/* Level 2 Memory */ +#define L2_START 0xFEB00000 +#define L2_LENGTH 0x20000 + +/* Scratch Pad Memory */ + +#if defined(CONFIG_BF561) +#define L1_SCRATCH_START 0xFFB00000 +#define L1_SCRATCH_LENGTH 0x1000 +#endif + +#endif /* _MEM_MAP_533_H_ */ diff --git a/include/asm-blackfin/mach-common/cdef_LPBlackfin.h b/include/asm-blackfin/mach-common/cdef_LPBlackfin.h new file mode 100644 index 000000000000..22aa5e637993 --- /dev/null +++ b/include/asm-blackfin/mach-common/cdef_LPBlackfin.h @@ -0,0 +1,471 @@ + /* + * File: include/asm-blackfin/mach-common/cdef_LPBlackfin.h + * Based on: + * Author: unknown + * COPYRIGHT 2005 Analog Devices + * Created: ? + * Description: + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _CDEF_LPBLACKFIN_H +#define _CDEF_LPBLACKFIN_H + +/*#if !defined(__ADSPLPBLACKFIN__) +#warning cdef_LPBlackfin.h should only be included for 532 compatible chips. +#endif +*/ +#include + +/*Cache & SRAM Memory*/ +#define pSRAM_BASE_ADDRESS ((volatile void **)SRAM_BASE_ADDRESS) +#define bfin_read_SRAM_BASE_ADDRESS() bfin_read32(SRAM_BASE_ADDRESS) +#define bfin_write_SRAM_BASE_ADDRESS(val) bfin_write32(SRAM_BASE_ADDRESS,val) +#define pDMEM_CONTROL ((volatile unsigned long *)DMEM_CONTROL) +#define bfin_read_DMEM_CONTROL() bfin_read32(DMEM_CONTROL) +#define bfin_write_DMEM_CONTROL(val) bfin_write32(DMEM_CONTROL,val) +#define pDCPLB_STATUS ((volatile unsigned long *)DCPLB_STATUS) +#define bfin_read_DCPLB_STATUS() bfin_read32(DCPLB_STATUS) +#define bfin_write_DCPLB_STATUS(val) bfin_write32(DCPLB_STATUS,val) +#define pDCPLB_FAULT_ADDR ((volatile void **)DCPLB_FAULT_ADDR) +#define bfin_read_DCPLB_FAULT_ADDR() bfin_read32(DCPLB_FAULT_ADDR) +#define bfin_write_DCPLB_FAULT_ADDR(val) bfin_write32(DCPLB_FAULT_ADDR,val) +/* +#define MMR_TIMEOUT 0xFFE00010 +*/ +#define pDCPLB_ADDR0 ((volatile void **)DCPLB_ADDR0) +#define bfin_read_DCPLB_ADDR0() bfin_read32(DCPLB_ADDR0) +#define bfin_write_DCPLB_ADDR0(val) bfin_write32(DCPLB_ADDR0,val) +#define pDCPLB_ADDR1 ((volatile void **)DCPLB_ADDR1) +#define bfin_read_DCPLB_ADDR1() bfin_read32(DCPLB_ADDR1) +#define bfin_write_DCPLB_ADDR1(val) bfin_write32(DCPLB_ADDR1,val) +#define pDCPLB_ADDR2 ((volatile void **)DCPLB_ADDR2) +#define bfin_read_DCPLB_ADDR2() bfin_read32(DCPLB_ADDR2) +#define bfin_write_DCPLB_ADDR2(val) bfin_write32(DCPLB_ADDR2,val) +#define pDCPLB_ADDR3 ((volatile void **)DCPLB_ADDR3) +#define bfin_read_DCPLB_ADDR3() bfin_read32(DCPLB_ADDR3) +#define bfin_write_DCPLB_ADDR3(val) bfin_write32(DCPLB_ADDR3,val) +#define pDCPLB_ADDR4 ((volatile void **)DCPLB_ADDR4) +#define bfin_read_DCPLB_ADDR4() bfin_read32(DCPLB_ADDR4) +#define bfin_write_DCPLB_ADDR4(val) bfin_write32(DCPLB_ADDR4,val) +#define pDCPLB_ADDR5 ((volatile void **)DCPLB_ADDR5) +#define bfin_read_DCPLB_ADDR5() bfin_read32(DCPLB_ADDR5) +#define bfin_write_DCPLB_ADDR5(val) bfin_write32(DCPLB_ADDR5,val) +#define pDCPLB_ADDR6 ((volatile void **)DCPLB_ADDR6) +#define bfin_read_DCPLB_ADDR6() bfin_read32(DCPLB_ADDR6) +#define bfin_write_DCPLB_ADDR6(val) bfin_write32(DCPLB_ADDR6,val) +#define pDCPLB_ADDR7 ((volatile void **)DCPLB_ADDR7) +#define bfin_read_DCPLB_ADDR7() bfin_read32(DCPLB_ADDR7) +#define bfin_write_DCPLB_ADDR7(val) bfin_write32(DCPLB_ADDR7,val) +#define pDCPLB_ADDR8 ((volatile void **)DCPLB_ADDR8) +#define bfin_read_DCPLB_ADDR8() bfin_read32(DCPLB_ADDR8) +#define bfin_write_DCPLB_ADDR8(val) bfin_write32(DCPLB_ADDR8,val) +#define pDCPLB_ADDR9 ((volatile void **)DCPLB_ADDR9) +#define bfin_read_DCPLB_ADDR9() bfin_read32(DCPLB_ADDR9) +#define bfin_write_DCPLB_ADDR9(val) bfin_write32(DCPLB_ADDR9,val) +#define pDCPLB_ADDR10 ((volatile void **)DCPLB_ADDR10) +#define bfin_read_DCPLB_ADDR10() bfin_read32(DCPLB_ADDR10) +#define bfin_write_DCPLB_ADDR10(val) bfin_write32(DCPLB_ADDR10,val) +#define pDCPLB_ADDR11 ((volatile void **)DCPLB_ADDR11) +#define bfin_read_DCPLB_ADDR11() bfin_read32(DCPLB_ADDR11) +#define bfin_write_DCPLB_ADDR11(val) bfin_write32(DCPLB_ADDR11,val) +#define pDCPLB_ADDR12 ((volatile void **)DCPLB_ADDR12) +#define bfin_read_DCPLB_ADDR12() bfin_read32(DCPLB_ADDR12) +#define bfin_write_DCPLB_ADDR12(val) bfin_write32(DCPLB_ADDR12,val) +#define pDCPLB_ADDR13 ((volatile void **)DCPLB_ADDR13) +#define bfin_read_DCPLB_ADDR13() bfin_read32(DCPLB_ADDR13) +#define bfin_write_DCPLB_ADDR13(val) bfin_write32(DCPLB_ADDR13,val) +#define pDCPLB_ADDR14 ((volatile void **)DCPLB_ADDR14) +#define bfin_read_DCPLB_ADDR14() bfin_read32(DCPLB_ADDR14) +#define bfin_write_DCPLB_ADDR14(val) bfin_write32(DCPLB_ADDR14,val) +#define pDCPLB_ADDR15 ((volatile void **)DCPLB_ADDR15) +#define bfin_read_DCPLB_ADDR15() bfin_read32(DCPLB_ADDR15) +#define bfin_write_DCPLB_ADDR15(val) bfin_write32(DCPLB_ADDR15,val) +#define pDCPLB_DATA0 ((volatile unsigned long *)DCPLB_DATA0) +#define bfin_read_DCPLB_DATA0() bfin_read32(DCPLB_DATA0) +#define bfin_write_DCPLB_DATA0(val) bfin_write32(DCPLB_DATA0,val) +#define pDCPLB_DATA1 ((volatile unsigned long *)DCPLB_DATA1) +#define bfin_read_DCPLB_DATA1() bfin_read32(DCPLB_DATA1) +#define bfin_write_DCPLB_DATA1(val) bfin_write32(DCPLB_DATA1,val) +#define pDCPLB_DATA2 ((volatile unsigned long *)DCPLB_DATA2) +#define bfin_read_DCPLB_DATA2() bfin_read32(DCPLB_DATA2) +#define bfin_write_DCPLB_DATA2(val) bfin_write32(DCPLB_DATA2,val) +#define pDCPLB_DATA3 ((volatile unsigned long *)DCPLB_DATA3) +#define bfin_read_DCPLB_DATA3() bfin_read32(DCPLB_DATA3) +#define bfin_write_DCPLB_DATA3(val) bfin_write32(DCPLB_DATA3,val) +#define pDCPLB_DATA4 ((volatile unsigned long *)DCPLB_DATA4) +#define bfin_read_DCPLB_DATA4() bfin_read32(DCPLB_DATA4) +#define bfin_write_DCPLB_DATA4(val) bfin_write32(DCPLB_DATA4,val) +#define pDCPLB_DATA5 ((volatile unsigned long *)DCPLB_DATA5) +#define bfin_read_DCPLB_DATA5() bfin_read32(DCPLB_DATA5) +#define bfin_write_DCPLB_DATA5(val) bfin_write32(DCPLB_DATA5,val) +#define pDCPLB_DATA6 ((volatile unsigned long *)DCPLB_DATA6) +#define bfin_read_DCPLB_DATA6() bfin_read32(DCPLB_DATA6) +#define bfin_write_DCPLB_DATA6(val) bfin_write32(DCPLB_DATA6,val) +#define pDCPLB_DATA7 ((volatile unsigned long *)DCPLB_DATA7) +#define bfin_read_DCPLB_DATA7() bfin_read32(DCPLB_DATA7) +#define bfin_write_DCPLB_DATA7(val) bfin_write32(DCPLB_DATA7,val) +#define pDCPLB_DATA8 ((volatile unsigned long *)DCPLB_DATA8) +#define bfin_read_DCPLB_DATA8() bfin_read32(DCPLB_DATA8) +#define bfin_write_DCPLB_DATA8(val) bfin_write32(DCPLB_DATA8,val) +#define pDCPLB_DATA9 ((volatile unsigned long *)DCPLB_DATA9) +#define bfin_read_DCPLB_DATA9() bfin_read32(DCPLB_DATA9) +#define bfin_write_DCPLB_DATA9(val) bfin_write32(DCPLB_DATA9,val) +#define pDCPLB_DATA10 ((volatile unsigned long *)DCPLB_DATA10) +#define bfin_read_DCPLB_DATA10() bfin_read32(DCPLB_DATA10) +#define bfin_write_DCPLB_DATA10(val) bfin_write32(DCPLB_DATA10,val) +#define pDCPLB_DATA11 ((volatile unsigned long *)DCPLB_DATA11) +#define bfin_read_DCPLB_DATA11() bfin_read32(DCPLB_DATA11) +#define bfin_write_DCPLB_DATA11(val) bfin_write32(DCPLB_DATA11,val) +#define pDCPLB_DATA12 ((volatile unsigned long *)DCPLB_DATA12) +#define bfin_read_DCPLB_DATA12() bfin_read32(DCPLB_DATA12) +#define bfin_write_DCPLB_DATA12(val) bfin_write32(DCPLB_DATA12,val) +#define pDCPLB_DATA13 ((volatile unsigned long *)DCPLB_DATA13) +#define bfin_read_DCPLB_DATA13() bfin_read32(DCPLB_DATA13) +#define bfin_write_DCPLB_DATA13(val) bfin_write32(DCPLB_DATA13,val) +#define pDCPLB_DATA14 ((volatile unsigned long *)DCPLB_DATA14) +#define bfin_read_DCPLB_DATA14() bfin_read32(DCPLB_DATA14) +#define bfin_write_DCPLB_DATA14(val) bfin_write32(DCPLB_DATA14,val) +#define pDCPLB_DATA15 ((volatile unsigned long *)DCPLB_DATA15) +#define bfin_read_DCPLB_DATA15() bfin_read32(DCPLB_DATA15) +#define bfin_write_DCPLB_DATA15(val) bfin_write32(DCPLB_DATA15,val) +#define pDTEST_COMMAND ((volatile unsigned long *)DTEST_COMMAND) +#define bfin_read_DTEST_COMMAND() bfin_read32(DTEST_COMMAND) +#define bfin_write_DTEST_COMMAND(val) bfin_write32(DTEST_COMMAND,val) +/* +#define DTEST_INDEX 0xFFE00304 +*/ +#define pDTEST_DATA0 ((volatile unsigned long *)DTEST_DATA0) +#define bfin_read_DTEST_DATA0() bfin_read32(DTEST_DATA0) +#define bfin_write_DTEST_DATA0(val) bfin_write32(DTEST_DATA0,val) +#define pDTEST_DATA1 ((volatile unsigned long *)DTEST_DATA1) +#define bfin_read_DTEST_DATA1() bfin_read32(DTEST_DATA1) +#define bfin_write_DTEST_DATA1(val) bfin_write32(DTEST_DATA1,val) +/* +#define DTEST_DATA2 0xFFE00408 +#define DTEST_DATA3 0xFFE0040C +*/ +#define pIMEM_CONTROL ((volatile unsigned long *)IMEM_CONTROL) +#define bfin_read_IMEM_CONTROL() bfin_read32(IMEM_CONTROL) +#define bfin_write_IMEM_CONTROL(val) bfin_write32(IMEM_CONTROL,val) +#define pICPLB_STATUS ((volatile unsigned long *)ICPLB_STATUS) +#define bfin_read_ICPLB_STATUS() bfin_read32(ICPLB_STATUS) +#define bfin_write_ICPLB_STATUS(val) bfin_write32(ICPLB_STATUS,val) +#define pICPLB_FAULT_ADDR ((volatile void **)ICPLB_FAULT_ADDR) +#define bfin_read_ICPLB_FAULT_ADDR() bfin_read32(ICPLB_FAULT_ADDR) +#define bfin_write_ICPLB_FAULT_ADDR(val) bfin_write32(ICPLB_FAULT_ADDR,val) +#define pICPLB_ADDR0 ((volatile void **)ICPLB_ADDR0) +#define bfin_read_ICPLB_ADDR0() bfin_read32(ICPLB_ADDR0) +#define bfin_write_ICPLB_ADDR0(val) bfin_write32(ICPLB_ADDR0,val) +#define pICPLB_ADDR1 ((volatile void **)ICPLB_ADDR1) +#define bfin_read_ICPLB_ADDR1() bfin_read32(ICPLB_ADDR1) +#define bfin_write_ICPLB_ADDR1(val) bfin_write32(ICPLB_ADDR1,val) +#define pICPLB_ADDR2 ((volatile void **)ICPLB_ADDR2) +#define bfin_read_ICPLB_ADDR2() bfin_read32(ICPLB_ADDR2) +#define bfin_write_ICPLB_ADDR2(val) bfin_write32(ICPLB_ADDR2,val) +#define pICPLB_ADDR3 ((volatile void **)ICPLB_ADDR3) +#define bfin_read_ICPLB_ADDR3() bfin_read32(ICPLB_ADDR3) +#define bfin_write_ICPLB_ADDR3(val) bfin_write32(ICPLB_ADDR3,val) +#define pICPLB_ADDR4 ((volatile void **)ICPLB_ADDR4) +#define bfin_read_ICPLB_ADDR4() bfin_read32(ICPLB_ADDR4) +#define bfin_write_ICPLB_ADDR4(val) bfin_write32(ICPLB_ADDR4,val) +#define pICPLB_ADDR5 ((volatile void **)ICPLB_ADDR5) +#define bfin_read_ICPLB_ADDR5() bfin_read32(ICPLB_ADDR5) +#define bfin_write_ICPLB_ADDR5(val) bfin_write32(ICPLB_ADDR5,val) +#define pICPLB_ADDR6 ((volatile void **)ICPLB_ADDR6) +#define bfin_read_ICPLB_ADDR6() bfin_read32(ICPLB_ADDR6) +#define bfin_write_ICPLB_ADDR6(val) bfin_write32(ICPLB_ADDR6,val) +#define pICPLB_ADDR7 ((volatile void **)ICPLB_ADDR7) +#define bfin_read_ICPLB_ADDR7() bfin_read32(ICPLB_ADDR7) +#define bfin_write_ICPLB_ADDR7(val) bfin_write32(ICPLB_ADDR7,val) +#define pICPLB_ADDR8 ((volatile void **)ICPLB_ADDR8) +#define bfin_read_ICPLB_ADDR8() bfin_read32(ICPLB_ADDR8) +#define bfin_write_ICPLB_ADDR8(val) bfin_write32(ICPLB_ADDR8,val) +#define pICPLB_ADDR9 ((volatile void **)ICPLB_ADDR9) +#define bfin_read_ICPLB_ADDR9() bfin_read32(ICPLB_ADDR9) +#define bfin_write_ICPLB_ADDR9(val) bfin_write32(ICPLB_ADDR9,val) +#define pICPLB_ADDR10 ((volatile void **)ICPLB_ADDR10) +#define bfin_read_ICPLB_ADDR10() bfin_read32(ICPLB_ADDR10) +#define bfin_write_ICPLB_ADDR10(val) bfin_write32(ICPLB_ADDR10,val) +#define pICPLB_ADDR11 ((volatile void **)ICPLB_ADDR11) +#define bfin_read_ICPLB_ADDR11() bfin_read32(ICPLB_ADDR11) +#define bfin_write_ICPLB_ADDR11(val) bfin_write32(ICPLB_ADDR11,val) +#define pICPLB_ADDR12 ((volatile void **)ICPLB_ADDR12) +#define bfin_read_ICPLB_ADDR12() bfin_read32(ICPLB_ADDR12) +#define bfin_write_ICPLB_ADDR12(val) bfin_write32(ICPLB_ADDR12,val) +#define pICPLB_ADDR13 ((volatile void **)ICPLB_ADDR13) +#define bfin_read_ICPLB_ADDR13() bfin_read32(ICPLB_ADDR13) +#define bfin_write_ICPLB_ADDR13(val) bfin_write32(ICPLB_ADDR13,val) +#define pICPLB_ADDR14 ((volatile void **)ICPLB_ADDR14) +#define bfin_read_ICPLB_ADDR14() bfin_read32(ICPLB_ADDR14) +#define bfin_write_ICPLB_ADDR14(val) bfin_write32(ICPLB_ADDR14,val) +#define pICPLB_ADDR15 ((volatile void **)ICPLB_ADDR15) +#define bfin_read_ICPLB_ADDR15() bfin_read32(ICPLB_ADDR15) +#define bfin_write_ICPLB_ADDR15(val) bfin_write32(ICPLB_ADDR15,val) +#define pICPLB_DATA0 ((volatile unsigned long *)ICPLB_DATA0) +#define bfin_read_ICPLB_DATA0() bfin_read32(ICPLB_DATA0) +#define bfin_write_ICPLB_DATA0(val) bfin_write32(ICPLB_DATA0,val) +#define pICPLB_DATA1 ((volatile unsigned long *)ICPLB_DATA1) +#define bfin_read_ICPLB_DATA1() bfin_read32(ICPLB_DATA1) +#define bfin_write_ICPLB_DATA1(val) bfin_write32(ICPLB_DATA1,val) +#define pICPLB_DATA2 ((volatile unsigned long *)ICPLB_DATA2) +#define bfin_read_ICPLB_DATA2() bfin_read32(ICPLB_DATA2) +#define bfin_write_ICPLB_DATA2(val) bfin_write32(ICPLB_DATA2,val) +#define pICPLB_DATA3 ((volatile unsigned long *)ICPLB_DATA3) +#define bfin_read_ICPLB_DATA3() bfin_read32(ICPLB_DATA3) +#define bfin_write_ICPLB_DATA3(val) bfin_write32(ICPLB_DATA3,val) +#define pICPLB_DATA4 ((volatile unsigned long *)ICPLB_DATA4) +#define bfin_read_ICPLB_DATA4() bfin_read32(ICPLB_DATA4) +#define bfin_write_ICPLB_DATA4(val) bfin_write32(ICPLB_DATA4,val) +#define pICPLB_DATA5 ((volatile unsigned long *)ICPLB_DATA5) +#define bfin_read_ICPLB_DATA5() bfin_read32(ICPLB_DATA5) +#define bfin_write_ICPLB_DATA5(val) bfin_write32(ICPLB_DATA5,val) +#define pICPLB_DATA6 ((volatile unsigned long *)ICPLB_DATA6) +#define bfin_read_ICPLB_DATA6() bfin_read32(ICPLB_DATA6) +#define bfin_write_ICPLB_DATA6(val) bfin_write32(ICPLB_DATA6,val) +#define pICPLB_DATA7 ((volatile unsigned long *)ICPLB_DATA7) +#define bfin_read_ICPLB_DATA7() bfin_read32(ICPLB_DATA7) +#define bfin_write_ICPLB_DATA7(val) bfin_write32(ICPLB_DATA7,val) +#define pICPLB_DATA8 ((volatile unsigned long *)ICPLB_DATA8) +#define bfin_read_ICPLB_DATA8() bfin_read32(ICPLB_DATA8) +#define bfin_write_ICPLB_DATA8(val) bfin_write32(ICPLB_DATA8,val) +#define pICPLB_DATA9 ((volatile unsigned long *)ICPLB_DATA9) +#define bfin_read_ICPLB_DATA9() bfin_read32(ICPLB_DATA9) +#define bfin_write_ICPLB_DATA9(val) bfin_write32(ICPLB_DATA9,val) +#define pICPLB_DATA10 ((volatile unsigned long *)ICPLB_DATA10) +#define bfin_read_ICPLB_DATA10() bfin_read32(ICPLB_DATA10) +#define bfin_write_ICPLB_DATA10(val) bfin_write32(ICPLB_DATA10,val) +#define pICPLB_DATA11 ((volatile unsigned long *)ICPLB_DATA11) +#define bfin_read_ICPLB_DATA11() bfin_read32(ICPLB_DATA11) +#define bfin_write_ICPLB_DATA11(val) bfin_write32(ICPLB_DATA11,val) +#define pICPLB_DATA12 ((volatile unsigned long *)ICPLB_DATA12) +#define bfin_read_ICPLB_DATA12() bfin_read32(ICPLB_DATA12) +#define bfin_write_ICPLB_DATA12(val) bfin_write32(ICPLB_DATA12,val) +#define pICPLB_DATA13 ((volatile unsigned long *)ICPLB_DATA13) +#define bfin_read_ICPLB_DATA13() bfin_read32(ICPLB_DATA13) +#define bfin_write_ICPLB_DATA13(val) bfin_write32(ICPLB_DATA13,val) +#define pICPLB_DATA14 ((volatile unsigned long *)ICPLB_DATA14) +#define bfin_read_ICPLB_DATA14() bfin_read32(ICPLB_DATA14) +#define bfin_write_ICPLB_DATA14(val) bfin_write32(ICPLB_DATA14,val) +#define pICPLB_DATA15 ((volatile unsigned long *)ICPLB_DATA15) +#define bfin_read_ICPLB_DATA15() bfin_read32(ICPLB_DATA15) +#define bfin_write_ICPLB_DATA15(val) bfin_write32(ICPLB_DATA15,val) +#define pITEST_COMMAND ((volatile unsigned long *)ITEST_COMMAND) +#define bfin_read_ITEST_COMMAND() bfin_read32(ITEST_COMMAND) +#define bfin_write_ITEST_COMMAND(val) bfin_write32(ITEST_COMMAND,val) +#if 0 +#define ITEST_INDEX 0xFFE01304 /* Instruction Test Index Register */ +#endif +#define pITEST_DATA0 ((volatile unsigned long *)ITEST_DATA0) +#define bfin_read_ITEST_DATA0() bfin_read32(ITEST_DATA0) +#define bfin_write_ITEST_DATA0(val) bfin_write32(ITEST_DATA0,val) +#define pITEST_DATA1 ((volatile unsigned long *)ITEST_DATA1) +#define bfin_read_ITEST_DATA1() bfin_read32(ITEST_DATA1) +#define bfin_write_ITEST_DATA1(val) bfin_write32(ITEST_DATA1,val) + +/* Event/Interrupt Registers*/ + +#define pEVT0 ((volatile void **)EVT0) +#define bfin_read_EVT0() bfin_read32(EVT0) +#define bfin_write_EVT0(val) bfin_write32(EVT0,val) +#define pEVT1 ((volatile void **)EVT1) +#define bfin_read_EVT1() bfin_read32(EVT1) +#define bfin_write_EVT1(val) bfin_write32(EVT1,val) +#define pEVT2 ((volatile void **)EVT2) +#define bfin_read_EVT2() bfin_read32(EVT2) +#define bfin_write_EVT2(val) bfin_write32(EVT2,val) +#define pEVT3 ((volatile void **)EVT3) +#define bfin_read_EVT3() bfin_read32(EVT3) +#define bfin_write_EVT3(val) bfin_write32(EVT3,val) +#define pEVT4 ((volatile void **)EVT4) +#define bfin_read_EVT4() bfin_read32(EVT4) +#define bfin_write_EVT4(val) bfin_write32(EVT4,val) +#define pEVT5 ((volatile void **)EVT5) +#define bfin_read_EVT5() bfin_read32(EVT5) +#define bfin_write_EVT5(val) bfin_write32(EVT5,val) +#define pEVT6 ((volatile void **)EVT6) +#define bfin_read_EVT6() bfin_read32(EVT6) +#define bfin_write_EVT6(val) bfin_write32(EVT6,val) +#define pEVT7 ((volatile void **)EVT7) +#define bfin_read_EVT7() bfin_read32(EVT7) +#define bfin_write_EVT7(val) bfin_write32(EVT7,val) +#define pEVT8 ((volatile void **)EVT8) +#define bfin_read_EVT8() bfin_read32(EVT8) +#define bfin_write_EVT8(val) bfin_write32(EVT8,val) +#define pEVT9 ((volatile void **)EVT9) +#define bfin_read_EVT9() bfin_read32(EVT9) +#define bfin_write_EVT9(val) bfin_write32(EVT9,val) +#define pEVT10 ((volatile void **)EVT10) +#define bfin_read_EVT10() bfin_read32(EVT10) +#define bfin_write_EVT10(val) bfin_write32(EVT10,val) +#define pEVT11 ((volatile void **)EVT11) +#define bfin_read_EVT11() bfin_read32(EVT11) +#define bfin_write_EVT11(val) bfin_write32(EVT11,val) +#define pEVT12 ((volatile void **)EVT12) +#define bfin_read_EVT12() bfin_read32(EVT12) +#define bfin_write_EVT12(val) bfin_write32(EVT12,val) +#define pEVT13 ((volatile void **)EVT13) +#define bfin_read_EVT13() bfin_read32(EVT13) +#define bfin_write_EVT13(val) bfin_write32(EVT13,val) +#define pEVT14 ((volatile void **)EVT14) +#define bfin_read_EVT14() bfin_read32(EVT14) +#define bfin_write_EVT14(val) bfin_write32(EVT14,val) +#define pEVT15 ((volatile void **)EVT15) +#define bfin_read_EVT15() bfin_read32(EVT15) +#define bfin_write_EVT15(val) bfin_write32(EVT15,val) +#define pIMASK ((volatile unsigned long *)IMASK) +#define bfin_read_IMASK() bfin_read32(IMASK) +#define bfin_write_IMASK(val) bfin_write32(IMASK,val) +#define pIPEND ((volatile unsigned long *)IPEND) +#define bfin_read_IPEND() bfin_read32(IPEND) +#define bfin_write_IPEND(val) bfin_write32(IPEND,val) +#define pILAT ((volatile unsigned long *)ILAT) +#define bfin_read_ILAT() bfin_read32(ILAT) +#define bfin_write_ILAT(val) bfin_write32(ILAT,val) + +/*Core Timer Registers*/ +#define pTCNTL ((volatile unsigned long *)TCNTL) +#define bfin_read_TCNTL() bfin_read32(TCNTL) +#define bfin_write_TCNTL(val) bfin_write32(TCNTL,val) +#define pTPERIOD ((volatile unsigned long *)TPERIOD) +#define bfin_read_TPERIOD() bfin_read32(TPERIOD) +#define bfin_write_TPERIOD(val) bfin_write32(TPERIOD,val) +#define pTSCALE ((volatile unsigned long *)TSCALE) +#define bfin_read_TSCALE() bfin_read32(TSCALE) +#define bfin_write_TSCALE(val) bfin_write32(TSCALE,val) +#define pTCOUNT ((volatile unsigned long *)TCOUNT) +#define bfin_read_TCOUNT() bfin_read32(TCOUNT) +#define bfin_write_TCOUNT(val) bfin_write32(TCOUNT,val) + +/*Debug/MP/Emulation Registers*/ +#define pDSPID ((volatile unsigned long *)DSPID) +#define bfin_read_DSPID() bfin_read32(DSPID) +#define bfin_write_DSPID(val) bfin_write32(DSPID,val) +#define pDBGCTL ((volatile unsigned long *)DBGCTL) +#define bfin_read_DBGCTL() bfin_read32(DBGCTL) +#define bfin_write_DBGCTL(val) bfin_write32(DBGCTL,val) +#define pDBGSTAT ((volatile unsigned long *)DBGSTAT) +#define bfin_read_DBGSTAT() bfin_read32(DBGSTAT) +#define bfin_write_DBGSTAT(val) bfin_write32(DBGSTAT,val) +#define pEMUDAT ((volatile unsigned long *)EMUDAT) +#define bfin_read_EMUDAT() bfin_read32(EMUDAT) +#define bfin_write_EMUDAT(val) bfin_write32(EMUDAT,val) + +/*Trace Buffer Registers*/ +#define pTBUFCTL ((volatile unsigned long *)TBUFCTL) +#define bfin_read_TBUFCTL() bfin_read32(TBUFCTL) +#define bfin_write_TBUFCTL(val) bfin_write32(TBUFCTL,val) +#define pTBUFSTAT ((volatile unsigned long *)TBUFSTAT) +#define bfin_read_TBUFSTAT() bfin_read32(TBUFSTAT) +#define bfin_write_TBUFSTAT(val) bfin_write32(TBUFSTAT,val) +#define pTBUF ((volatile void **)TBUF) +#define bfin_read_TBUF() bfin_read32(TBUF) +#define bfin_write_TBUF(val) bfin_write32(TBUF,val) + +/*Watch Point Control Registers*/ +#define pWPIACTL ((volatile unsigned long *)WPIACTL) +#define bfin_read_WPIACTL() bfin_read32(WPIACTL) +#define bfin_write_WPIACTL(val) bfin_write32(WPIACTL,val) +#define pWPIA0 ((volatile void **)WPIA0) +#define bfin_read_WPIA0() bfin_read32(WPIA0) +#define bfin_write_WPIA0(val) bfin_write32(WPIA0,val) +#define pWPIA1 ((volatile void **)WPIA1) +#define bfin_read_WPIA1() bfin_read32(WPIA1) +#define bfin_write_WPIA1(val) bfin_write32(WPIA1,val) +#define pWPIA2 ((volatile void **)WPIA2) +#define bfin_read_WPIA2() bfin_read32(WPIA2) +#define bfin_write_WPIA2(val) bfin_write32(WPIA2,val) +#define pWPIA3 ((volatile void **)WPIA3) +#define bfin_read_WPIA3() bfin_read32(WPIA3) +#define bfin_write_WPIA3(val) bfin_write32(WPIA3,val) +#define pWPIA4 ((volatile void **)WPIA4) +#define bfin_read_WPIA4() bfin_read32(WPIA4) +#define bfin_write_WPIA4(val) bfin_write32(WPIA4,val) +#define pWPIA5 ((volatile void **)WPIA5) +#define bfin_read_WPIA5() bfin_read32(WPIA5) +#define bfin_write_WPIA5(val) bfin_write32(WPIA5,val) +#define pWPIACNT0 ((volatile unsigned long *)WPIACNT0) +#define bfin_read_WPIACNT0() bfin_read32(WPIACNT0) +#define bfin_write_WPIACNT0(val) bfin_write32(WPIACNT0,val) +#define pWPIACNT1 ((volatile unsigned long *)WPIACNT1) +#define bfin_read_WPIACNT1() bfin_read32(WPIACNT1) +#define bfin_write_WPIACNT1(val) bfin_write32(WPIACNT1,val) +#define pWPIACNT2 ((volatile unsigned long *)WPIACNT2) +#define bfin_read_WPIACNT2() bfin_read32(WPIACNT2) +#define bfin_write_WPIACNT2(val) bfin_write32(WPIACNT2,val) +#define pWPIACNT3 ((volatile unsigned long *)WPIACNT3) +#define bfin_read_WPIACNT3() bfin_read32(WPIACNT3) +#define bfin_write_WPIACNT3(val) bfin_write32(WPIACNT3,val) +#define pWPIACNT4 ((volatile unsigned long *)WPIACNT4) +#define bfin_read_WPIACNT4() bfin_read32(WPIACNT4) +#define bfin_write_WPIACNT4(val) bfin_write32(WPIACNT4,val) +#define pWPIACNT5 ((volatile unsigned long *)WPIACNT5) +#define bfin_read_WPIACNT5() bfin_read32(WPIACNT5) +#define bfin_write_WPIACNT5(val) bfin_write32(WPIACNT5,val) +#define pWPDACTL ((volatile unsigned long *)WPDACTL) +#define bfin_read_WPDACTL() bfin_read32(WPDACTL) +#define bfin_write_WPDACTL(val) bfin_write32(WPDACTL,val) +#define pWPDA0 ((volatile void **)WPDA0) +#define bfin_read_WPDA0() bfin_read32(WPDA0) +#define bfin_write_WPDA0(val) bfin_write32(WPDA0,val) +#define pWPDA1 ((volatile void **)WPDA1) +#define bfin_read_WPDA1() bfin_read32(WPDA1) +#define bfin_write_WPDA1(val) bfin_write32(WPDA1,val) +#define pWPDACNT0 ((volatile unsigned long *)WPDACNT0) +#define bfin_read_WPDACNT0() bfin_read32(WPDACNT0) +#define bfin_write_WPDACNT0(val) bfin_write32(WPDACNT0,val) +#define pWPDACNT1 ((volatile unsigned long *)WPDACNT1) +#define bfin_read_WPDACNT1() bfin_read32(WPDACNT1) +#define bfin_write_WPDACNT1(val) bfin_write32(WPDACNT1,val) +#define pWPSTAT ((volatile unsigned long *)WPSTAT) +#define bfin_read_WPSTAT() bfin_read32(WPSTAT) +#define bfin_write_WPSTAT(val) bfin_write32(WPSTAT,val) + +/*Performance Monitor Registers*/ +#define pPFCTL ((volatile unsigned long *)PFCTL) +#define bfin_read_PFCTL() bfin_read32(PFCTL) +#define bfin_write_PFCTL(val) bfin_write32(PFCTL,val) +#define pPFCNTR0 ((volatile unsigned long *)PFCNTR0) +#define bfin_read_PFCNTR0() bfin_read32(PFCNTR0) +#define bfin_write_PFCNTR0(val) bfin_write32(PFCNTR0,val) +#define pPFCNTR1 ((volatile unsigned long *)PFCNTR1) +#define bfin_read_PFCNTR1() bfin_read32(PFCNTR1) +#define bfin_write_PFCNTR1(val) bfin_write32(PFCNTR1,val) + +/* +#define IPRIO 0xFFE02110 +*/ + +#if defined(CONFIG_BFIN_ALIVE_LED) +#define pCONFIG_BFIN_ALIVE_LED_DPORT \ + (volatile unsigned short *)CONFIG_BFIN_ALIVE_LED_DPORT +#define pCONFIG_BFIN_ALIVE_LED_PORT \ + (volatile unsigned short *)CONFIG_BFIN_ALIVE_LED_PORT +#endif + +#if defined(CONFIG_BFIN_IDLE_LED) +#define pCONFIG_BFIN_IDLE_LED_DPORT \ + (volatile unsigned short *)CONFIG_BFIN_IDLE_LED_DPORT +#define pCONFIG_BFIN_IDLE_LED_PORT \ + (volatile unsigned short *)CONFIG_BFIN_IDLE_LED_PORT +#endif + +#endif /* _CDEF_LPBLACKFIN_H */ diff --git a/include/asm-blackfin/mach-common/context.S b/include/asm-blackfin/mach-common/context.S new file mode 100644 index 000000000000..fd0ebe1862b8 --- /dev/null +++ b/include/asm-blackfin/mach-common/context.S @@ -0,0 +1,350 @@ +/* + * File: arch/blackfin/kernel/context.S + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2007 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * Code to save processor context. + * We even save the register which are preserved by a function call + * - r4, r5, r6, r7, p3, p4, p5 + */ +.macro save_context_with_interrupts + [--sp] = SYSCFG; + + [--sp] = P0; /*orig_p0*/ + [--sp] = R0; /*orig_r0*/ + + [--sp] = ( R7:0, P5:0 ); + [--sp] = fp; + [--sp] = usp; + + [--sp] = i0; + [--sp] = i1; + [--sp] = i2; + [--sp] = i3; + + [--sp] = m0; + [--sp] = m1; + [--sp] = m2; + [--sp] = m3; + + [--sp] = l0; + [--sp] = l1; + [--sp] = l2; + [--sp] = l3; + + [--sp] = b0; + [--sp] = b1; + [--sp] = b2; + [--sp] = b3; + [--sp] = a0.x; + [--sp] = a0.w; + [--sp] = a1.x; + [--sp] = a1.w; + + [--sp] = LC0; + [--sp] = LC1; + [--sp] = LT0; + [--sp] = LT1; + [--sp] = LB0; + [--sp] = LB1; + + [--sp] = ASTAT; + + [--sp] = r0; /* Skip reserved */ + [--sp] = RETS; + r0 = RETI; + [--sp] = r0; + [--sp] = RETX; + [--sp] = RETN; + [--sp] = RETE; + [--sp] = SEQSTAT; + [--sp] = r0; /* Skip IPEND as well. */ + /* Switch to other method of keeping interrupts disabled. */ +#ifdef CONFIG_DEBUG_HWERR + r0 = 0x3f; + sti r0; +#else + cli r0; +#endif + [--sp] = RETI; /*orig_pc*/ + /* Clear all L registers. */ + r0 = 0 (x); + l0 = r0; + l1 = r0; + l2 = r0; + l3 = r0; +.endm + +.macro save_context_syscall + [--sp] = SYSCFG; + + [--sp] = P0; /*orig_p0*/ + [--sp] = R0; /*orig_r0*/ + [--sp] = ( R7:0, P5:0 ); + [--sp] = fp; + [--sp] = usp; + + [--sp] = i0; + [--sp] = i1; + [--sp] = i2; + [--sp] = i3; + + [--sp] = m0; + [--sp] = m1; + [--sp] = m2; + [--sp] = m3; + + [--sp] = l0; + [--sp] = l1; + [--sp] = l2; + [--sp] = l3; + + [--sp] = b0; + [--sp] = b1; + [--sp] = b2; + [--sp] = b3; + [--sp] = a0.x; + [--sp] = a0.w; + [--sp] = a1.x; + [--sp] = a1.w; + + [--sp] = LC0; + [--sp] = LC1; + [--sp] = LT0; + [--sp] = LT1; + [--sp] = LB0; + [--sp] = LB1; + + [--sp] = ASTAT; + + [--sp] = r0; /* Skip reserved */ + [--sp] = RETS; + r0 = RETI; + [--sp] = r0; + [--sp] = RETX; + [--sp] = RETN; + [--sp] = RETE; + [--sp] = SEQSTAT; + [--sp] = r0; /* Skip IPEND as well. */ + [--sp] = RETI; /*orig_pc*/ + /* Clear all L registers. */ + r0 = 0 (x); + l0 = r0; + l1 = r0; + l2 = r0; + l3 = r0; +.endm + +.macro save_context_no_interrupts + [--sp] = SYSCFG; + [--sp] = P0; /* orig_p0 */ + [--sp] = R0; /* orig_r0 */ + [--sp] = ( R7:0, P5:0 ); + [--sp] = fp; + [--sp] = usp; + + [--sp] = i0; + [--sp] = i1; + [--sp] = i2; + [--sp] = i3; + + [--sp] = m0; + [--sp] = m1; + [--sp] = m2; + [--sp] = m3; + + [--sp] = l0; + [--sp] = l1; + [--sp] = l2; + [--sp] = l3; + + [--sp] = b0; + [--sp] = b1; + [--sp] = b2; + [--sp] = b3; + [--sp] = a0.x; + [--sp] = a0.w; + [--sp] = a1.x; + [--sp] = a1.w; + + [--sp] = LC0; + [--sp] = LC1; + [--sp] = LT0; + [--sp] = LT1; + [--sp] = LB0; + [--sp] = LB1; + + [--sp] = ASTAT; + +#ifdef CONFIG_KGDB + fp = 0(Z); + r1 = sp; + r1 += 60; + r1 += 60; + r1 += 60; + [--sp] = r1; +#else + [--sp] = r0; /* Skip reserved */ +#endif + [--sp] = RETS; + r0 = RETI; + [--sp] = r0; + [--sp] = RETX; + [--sp] = RETN; + [--sp] = RETE; + [--sp] = SEQSTAT; +#ifdef CONFIG_KGDB + r1.l = lo(IPEND); + r1.h = hi(IPEND); + [--sp] = r1; +#else + [--sp] = r0; /* Skip IPEND as well. */ +#endif + [--sp] = r0; /*orig_pc*/ + /* Clear all L registers. */ + r0 = 0 (x); + l0 = r0; + l1 = r0; + l2 = r0; + l3 = r0; +.endm + +.macro restore_context_no_interrupts + sp += 4; /* Skip orig_pc */ + sp += 4; /* Skip IPEND */ + SEQSTAT = [sp++]; + RETE = [sp++]; + RETN = [sp++]; + RETX = [sp++]; + r0 = [sp++]; + RETI = r0; /* Restore RETI indirectly when in exception */ + RETS = [sp++]; + + sp += 4; /* Skip Reserved */ + + ASTAT = [sp++]; + + LB1 = [sp++]; + LB0 = [sp++]; + LT1 = [sp++]; + LT0 = [sp++]; + LC1 = [sp++]; + LC0 = [sp++]; + + a1.w = [sp++]; + a1.x = [sp++]; + a0.w = [sp++]; + a0.x = [sp++]; + b3 = [sp++]; + b2 = [sp++]; + b1 = [sp++]; + b0 = [sp++]; + + l3 = [sp++]; + l2 = [sp++]; + l1 = [sp++]; + l0 = [sp++]; + + m3 = [sp++]; + m2 = [sp++]; + m1 = [sp++]; + m0 = [sp++]; + + i3 = [sp++]; + i2 = [sp++]; + i1 = [sp++]; + i0 = [sp++]; + + sp += 4; + fp = [sp++]; + + ( R7 : 0, P5 : 0) = [ SP ++ ]; + sp += 8; /* Skip orig_r0/orig_p0 */ + SYSCFG = [sp++]; +.endm + +.macro restore_context_with_interrupts + sp += 4; /* Skip orig_pc */ + sp += 4; /* Skip IPEND */ + SEQSTAT = [sp++]; + RETE = [sp++]; + RETN = [sp++]; + RETX = [sp++]; + RETI = [sp++]; + RETS = [sp++]; + + p0.h = _irq_flags; + p0.l = _irq_flags; + r0 = [p0]; + sti r0; + + sp += 4; /* Skip Reserved */ + + ASTAT = [sp++]; + + LB1 = [sp++]; + LB0 = [sp++]; + LT1 = [sp++]; + LT0 = [sp++]; + LC1 = [sp++]; + LC0 = [sp++]; + + a1.w = [sp++]; + a1.x = [sp++]; + a0.w = [sp++]; + a0.x = [sp++]; + b3 = [sp++]; + b2 = [sp++]; + b1 = [sp++]; + b0 = [sp++]; + + l3 = [sp++]; + l2 = [sp++]; + l1 = [sp++]; + l0 = [sp++]; + + m3 = [sp++]; + m2 = [sp++]; + m1 = [sp++]; + m0 = [sp++]; + + i3 = [sp++]; + i2 = [sp++]; + i1 = [sp++]; + i0 = [sp++]; + + sp += 4; + fp = [sp++]; + + ( R7 : 0, P5 : 0) = [ SP ++ ]; + sp += 8; /* Skip orig_r0/orig_p0 */ + csync; + SYSCFG = [sp++]; + csync; +.endm + diff --git a/include/asm-blackfin/mach-common/def_LPBlackfin.h b/include/asm-blackfin/mach-common/def_LPBlackfin.h new file mode 100644 index 000000000000..76103526aec1 --- /dev/null +++ b/include/asm-blackfin/mach-common/def_LPBlackfin.h @@ -0,0 +1,691 @@ + /* + * File: include/asm-blackfin/mach-common/def_LPBlackfin.h + * Based on: + * Author: unknown + * COPYRIGHT 2005 Analog Devices + * Created: ? + * Description: + * + * Modified: + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* LP Blackfin CORE REGISTER BIT & ADDRESS DEFINITIONS FOR ADSP-BF532/33 */ + +#ifndef _DEF_LPBLACKFIN_H +#define _DEF_LPBLACKFIN_H + +#include + +/*#if !defined(__ADSPLPBLACKFIN__) +#warning def_LPBlackfin.h should only be included for 532 compatible chips. +#endif +*/ + +#define MK_BMSK_(x) (1<31 */ +#define TEST_WAY0 0x00000000 /* Access Way0 */ +#define TEST_WAY1 0x04000000 /* Access Way1 */ +/* ITEST_COMMAND only */ +#define TEST_WAY2 0x08000000 /* Access Way2 */ +#define TEST_WAY3 0x0C000000 /* Access Way3 */ +/* DTEST_COMMAND only */ +#define TEST_BNKSELA 0x00000000 /* Access SuperBank A */ +#define TEST_BNKSELB 0x00800000 /* Access SuperBank B */ + +#endif /* _DEF_LPBLACKFIN_H */ diff --git a/include/asm-blackfin/macros.h b/include/asm-blackfin/macros.h new file mode 100644 index 000000000000..c0c04a2f2dd5 --- /dev/null +++ b/include/asm-blackfin/macros.h @@ -0,0 +1,95 @@ +/************************************************************************ + * + * macros.h + * + * (c) Copyright 2001-2003 Analog Devices, Inc. All rights reserved. + * + ************************************************************************/ + +/* Defines various assembly macros. */ + +#ifndef _MACROS_H +#define _MACROS_H + +#define LO(con32) ((con32) & 0xFFFF) +#define lo(con32) ((con32) & 0xFFFF) +#define HI(con32) (((con32) >> 16) & 0xFFFF) +#define hi(con32) (((con32) >> 16) & 0xFFFF) + +/* + * Set the corresponding bits in a System Register (SR); + * All bits set in "mask" will be set in the system register + * specified by "sys_reg" bitset_SR(sys_reg, mask), where + * sys_reg is the system register and mask are the bits to be set. + */ +#define bitset_SR(sys_reg, mask)\ + [--SP] = (R7:6);\ + r7 = sys_reg;\ + r6.l = (mask) & 0xffff;\ + r6.h = (mask) >> 16;\ + r7 = r7 | r6;\ + sys_reg = r7;\ + csync;\ + (R7:6) = [SP++] + +/* + * Clear the corresponding bits in a System Register (SR); + * All bits set in "mask" will be cleared in the SR + * specified by "sys_reg" bitclr_SR(sys_reg, mask), where + * sys_reg is the SR and mask are the bits to be cleared. + */ +#define bitclr_SR(sys_reg, mask)\ + [--SP] = (R7:6);\ + r7 = sys_reg;\ + r7 =~ r7;\ + r6.l = (mask) & 0xffff;\ + r6.h = (mask) >> 16;\ + r7 = r7 | r6;\ + r7 =~ r7;\ + sys_reg = r7;\ + csync;\ + (R7:6) = [SP++] + +/* + * Set the corresponding bits in a Memory Mapped Register (MMR); + * All bits set in "mask" will be set in the MMR specified by "mmr_reg" + * bitset_MMR(mmr_reg, mask), where mmr_reg is the MMR and mask are + * the bits to be set. + */ +#define bitset_MMR(mmr_reg, mask)\ + [--SP] = (R7:6);\ + [--SP] = P5;\ + p5.l = mmr_reg & 0xffff;\ + p5.h = mmr_reg >> 16;\ + r7 = [p5];\ + r6.l = (mask) & 0xffff;\ + r6.h = (mask) >> 16;\ + r7 = r7 | r6;\ + [p5] = r7;\ + csync;\ + p5 = [SP++];\ + (R7:6) = [SP++] + +/* + * Clear the corresponding bits in a Memory Mapped Register (MMR); + * All bits set in "mask" will be cleared in the MMR specified by "mmr_reg" + * bitclr_MMRreg(mmr_reg, mask), where sys_reg is the MMR and mask are + * the bits to be cleared. + */ +#define bitclr_MMR(mmr_reg, mask)\ + [--SP] = (R7:6);\ + [--SP] = P5;\ + p5.l = mmr_reg & 0xffff;\ + p5.h = mmr_reg >> 16;\ + r7 = [p5];\ + r7 =~ r7;\ + r6.l = (mask) & 0xffff;\ + r6.h = (mask) >> 16;\ + r7 = r7 | r6;\ + r7 =~ r7;\ + [p5] = r7;\ + csync;\ + p5 = [SP++];\ + (R7:6) = [SP++] + +#endif /* _MACROS_H */ diff --git a/include/asm-blackfin/mem_map.h b/include/asm-blackfin/mem_map.h new file mode 100644 index 000000000000..42d1f37f6d9c --- /dev/null +++ b/include/asm-blackfin/mem_map.h @@ -0,0 +1,12 @@ +/* + * mem_map.h + * Common header file for blackfin family of processors. + * + */ + +#ifndef _MEM_MAP_H_ +#define _MEM_MAP_H_ + +#include + +#endif /* _MEM_MAP_H_ */ diff --git a/include/asm-blackfin/mman.h b/include/asm-blackfin/mman.h new file mode 100644 index 000000000000..4d504f908c0c --- /dev/null +++ b/include/asm-blackfin/mman.h @@ -0,0 +1,45 @@ +#ifndef __BFIN_MMAN_H__ +#define __BFIN_MMAN_H__ + +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_SEM 0x8 /* page may be used for atomic ops */ +#define PROT_NONE 0x0 /* page can not be accessed */ +#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ +#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ + +#define MAP_SHARED 0x01 /* Share changes */ +#define MAP_PRIVATE 0x02 /* Changes are private */ +#define MAP_TYPE 0x0f /* Mask for type of mapping */ +#define MAP_FIXED 0x10 /* Interpret addr exactly */ +#define MAP_ANONYMOUS 0x20 /* don't use a file */ + +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ +#define MAP_LOCKED 0x2000 /* pages are locked */ +#define MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ +#define MAP_NONBLOCK 0x10000 /* do not block on IO */ +#define MAP_UNINITIALIZE 0x4000000 /* For anonymous mmap, memory could + be uninitialized. */ + +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_INVALIDATE 2 /* invalidate the caches */ +#define MS_SYNC 4 /* synchronous memory sync */ + +#define MCL_CURRENT 1 /* lock all current mappings */ +#define MCL_FUTURE 2 /* lock all future mappings */ + +#define MADV_NORMAL 0x0 /* default page-in behavior */ +#define MADV_RANDOM 0x1 /* page-in minimum required */ +#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ +#define MADV_WILLNEED 0x3 /* pre-fault pages */ +#define MADV_DONTNEED 0x4 /* discard these pages */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif /* __BFIN_MMAN_H__ */ diff --git a/include/asm-blackfin/mmu.h b/include/asm-blackfin/mmu.h new file mode 100644 index 000000000000..11d52f1167d0 --- /dev/null +++ b/include/asm-blackfin/mmu.h @@ -0,0 +1,30 @@ +#ifndef __MMU_H +#define __MMU_H + +/* Copyright (C) 2002, David McCullough */ + +struct sram_list_struct { + struct sram_list_struct *next; + void *addr; + size_t length; +}; + +typedef struct { + struct vm_list_struct *vmlist; + unsigned long end_brk; + unsigned long stack_start; + + /* Points to the location in SDRAM where the L1 stack is normally + saved, or NULL if the stack is always in SDRAM. */ + void *l1_stack_save; + + struct sram_list_struct *sram_list; + +#ifdef CONFIG_BINFMT_ELF_FDPIC + unsigned long exec_fdpic_loadmap; + unsigned long interp_fdpic_loadmap; +#endif + +} mm_context_t; + +#endif diff --git a/include/asm-blackfin/mmu_context.h b/include/asm-blackfin/mmu_context.h new file mode 100644 index 000000000000..c5c71a6aaf19 --- /dev/null +++ b/include/asm-blackfin/mmu_context.h @@ -0,0 +1,129 @@ +/* + * File: include/asm-blackfin/mmu_context.h + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __BLACKFIN_MMU_CONTEXT_H__ +#define __BLACKFIN_MMU_CONTEXT_H__ + +#include +#include +#include + +extern void *current_l1_stack_save; +extern int nr_l1stack_tasks; +extern void *l1_stack_base; +extern unsigned long l1_stack_len; + +extern int l1sram_free(const void*); +extern void *l1sram_alloc_max(void*); + +static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) +{ +} + +/* Called when creating a new context during fork() or execve(). */ +static inline int +init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ + return 0; +} + +static inline void free_l1stack(void) +{ + nr_l1stack_tasks--; + if (nr_l1stack_tasks == 0) + l1sram_free(l1_stack_base); +} +static inline void destroy_context(struct mm_struct *mm) +{ + struct sram_list_struct *tmp; + + if (current_l1_stack_save == mm->context.l1_stack_save) + current_l1_stack_save = 0; + if (mm->context.l1_stack_save) + free_l1stack(); + + while ((tmp = mm->context.sram_list)) { + mm->context.sram_list = tmp->next; + sram_free(tmp->addr); + kfree(tmp); + } +} + +static inline unsigned long +alloc_l1stack(unsigned long length, unsigned long *stack_base) +{ + if (nr_l1stack_tasks == 0) { + l1_stack_base = l1sram_alloc_max(&l1_stack_len); + if (!l1_stack_base) + return 0; + } + + if (l1_stack_len < length) { + if (nr_l1stack_tasks == 0) + l1sram_free(l1_stack_base); + return 0; + } + *stack_base = (unsigned long)l1_stack_base; + nr_l1stack_tasks++; + return l1_stack_len; +} + +static inline int +activate_l1stack(struct mm_struct *mm, unsigned long sp_base) +{ + if (current_l1_stack_save) + memcpy(current_l1_stack_save, l1_stack_base, l1_stack_len); + mm->context.l1_stack_save = current_l1_stack_save = (void*)sp_base; + memcpy(l1_stack_base, current_l1_stack_save, l1_stack_len); + return 1; +} + +#define deactivate_mm(tsk,mm) do { } while (0) + +static inline void activate_mm(struct mm_struct *prev_mm, + struct mm_struct *next_mm) +{ + if (!next_mm->context.l1_stack_save) + return; + if (next_mm->context.l1_stack_save == current_l1_stack_save) + return; + if (current_l1_stack_save) { + memcpy(current_l1_stack_save, l1_stack_base, l1_stack_len); + } + current_l1_stack_save = next_mm->context.l1_stack_save; + memcpy(l1_stack_base, current_l1_stack_save, l1_stack_len); +} + +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, + struct task_struct *tsk) +{ + activate_mm(prev, next); +} + +#endif diff --git a/include/asm-blackfin/module.h b/include/asm-blackfin/module.h new file mode 100644 index 000000000000..3c7ce1644280 --- /dev/null +++ b/include/asm-blackfin/module.h @@ -0,0 +1,19 @@ +#ifndef _ASM_BFIN_MODULE_H +#define _ASM_BFIN_MODULE_H + +#define MODULE_SYMBOL_PREFIX "_" + +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr +#define FLG_CODE_IN_L1 0x10 +#define FLG_DATA_IN_L1 0x20 + +struct mod_arch_specific { + Elf_Shdr *text_l1; + Elf_Shdr *data_a_l1; + Elf_Shdr *bss_a_l1; + Elf_Shdr *data_b_l1; + Elf_Shdr *bss_b_l1; +}; +#endif /* _ASM_BFIN_MODULE_H */ diff --git a/include/asm-blackfin/msgbuf.h b/include/asm-blackfin/msgbuf.h new file mode 100644 index 000000000000..6fcbe8cd801d --- /dev/null +++ b/include/asm-blackfin/msgbuf.h @@ -0,0 +1,31 @@ +#ifndef _BFIN_MSGBUF_H +#define _BFIN_MSGBUF_H + +/* + * The msqid64_ds structure for bfin architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct msqid64_ds { + struct ipc64_perm msg_perm; + __kernel_time_t msg_stime; /* last msgsnd time */ + unsigned long __unused1; + __kernel_time_t msg_rtime; /* last msgrcv time */ + unsigned long __unused2; + __kernel_time_t msg_ctime; /* last change time */ + unsigned long __unused3; + unsigned long msg_cbytes; /* current number of bytes on queue */ + unsigned long msg_qnum; /* number of messages in queue */ + unsigned long msg_qbytes; /* max number of bytes on queue */ + __kernel_pid_t msg_lspid; /* pid of last msgsnd */ + __kernel_pid_t msg_lrpid; /* last receive pid */ + unsigned long __unused4; + unsigned long __unused5; +}; + +#endif /* _BFIN_MSGBUF_H */ diff --git a/include/asm-blackfin/mutex.h b/include/asm-blackfin/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-blackfin/mutex.h @@ -0,0 +1,9 @@ +/* + * Pull in the generic implementation for the mutex fastpath. + * + * TODO: implement optimized primitives instead, or leave the generic + * implementation in place, or pick the atomic_xchg() based generic + * implementation. (see asm-generic/mutex-xchg.h for details) + */ + +#include diff --git a/include/asm-blackfin/namei.h b/include/asm-blackfin/namei.h new file mode 100644 index 000000000000..8b89a2d65cb4 --- /dev/null +++ b/include/asm-blackfin/namei.h @@ -0,0 +1,19 @@ +/* + * linux/include/asm/namei.h + * + * Included from linux/fs/namei.c + * + * Changes made by Lineo Inc. May 2001 + */ + +#ifndef __BFIN_NAMEI_H +#define __BFIN_NAMEI_H + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif diff --git a/include/asm-blackfin/page.h b/include/asm-blackfin/page.h new file mode 100644 index 000000000000..ffad947f1b2a --- /dev/null +++ b/include/asm-blackfin/page.h @@ -0,0 +1,89 @@ +#ifndef _BLACKFIN_PAGE_H +#define _BLACKFIN_PAGE_H + +/* PAGE_SHIFT determines the page size */ + +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#ifdef __KERNEL__ + +#include + +#ifndef __ASSEMBLY__ + +#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) +#define free_user_page(page, addr) free_page(addr) + +#define clear_page(page) memset((page), 0, PAGE_SIZE) +#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE) + +#define clear_user_page(page, vaddr,pg) clear_page(page) +#define copy_user_page(to, from, vaddr,pg) copy_page(to, from) + +/* + * These are used to make use of C type-checking.. + */ +typedef struct { + unsigned long pte; +} pte_t; +typedef struct { + unsigned long pmd[16]; +} pmd_t; +typedef struct { + unsigned long pgd; +} pgd_t; +typedef struct { + unsigned long pgprot; +} pgprot_t; + +#define pte_val(x) ((x).pte) +#define pmd_val(x) ((&x)->pmd[0]) +#define pgd_val(x) ((x).pgd) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgd(x) ((pgd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +extern unsigned long memory_start; +extern unsigned long memory_end; + +#endif /* !__ASSEMBLY__ */ + +#include +#include + +#define PAGE_OFFSET (PAGE_OFFSET_RAW) + +#ifndef __ASSEMBLY__ + +#define __pa(vaddr) virt_to_phys((void *)(vaddr)) +#define __va(paddr) phys_to_virt((unsigned long)(paddr)) + +#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT) + +#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) +#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) +#define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)) +#define page_to_virt(page) ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET) +#define VALID_PAGE(page) ((page - mem_map) < max_mapnr) + +#define pfn_to_page(pfn) virt_to_page(pfn_to_virt(pfn)) +#define page_to_pfn(page) virt_to_pfn(page_to_virt(page)) +#define pfn_valid(pfn) ((pfn) < max_mapnr) + +#define virt_addr_valid(kaddr) (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \ + ((void *)(kaddr) < (void *)memory_end)) + +#include + +#endif /* __ASSEMBLY__ */ +#endif /* __KERNEL__ */ + +#endif /* _BLACKFIN_PAGE_H */ diff --git a/include/asm-blackfin/page_offset.h b/include/asm-blackfin/page_offset.h new file mode 100644 index 000000000000..3b671d5fd70d --- /dev/null +++ b/include/asm-blackfin/page_offset.h @@ -0,0 +1,6 @@ + +/* This handles the memory map.. */ + +#ifdef CONFIG_BFIN +#define PAGE_OFFSET_RAW 0x00000000 +#endif diff --git a/include/asm-blackfin/param.h b/include/asm-blackfin/param.h new file mode 100644 index 000000000000..41564a6347f8 --- /dev/null +++ b/include/asm-blackfin/param.h @@ -0,0 +1,22 @@ +#ifndef _BLACKFIN_PARAM_H +#define _BLACKFIN_PARAM_H + +#ifdef __KERNEL__ +#define HZ CONFIG_HZ +#define USER_HZ 100 +#define CLOCKS_PER_SEC (USER_HZ) +#endif + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 4096 + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif /* _BLACKFIN_PARAM_H */ diff --git a/include/asm-blackfin/pci.h b/include/asm-blackfin/pci.h new file mode 100644 index 000000000000..61277358c865 --- /dev/null +++ b/include/asm-blackfin/pci.h @@ -0,0 +1,148 @@ +/* Changed from asm-m68k version, Lineo Inc. May 2001 */ + +#ifndef _ASM_BFIN_PCI_H +#define _ASM_BFIN_PCI_H + +#include + +/* + * + * Written by Wout Klaren. + */ + +/* Added by Chang Junxiao */ +#define PCIBIOS_MIN_IO 0x00001000 +#define PCIBIOS_MIN_MEM 0x10000000 + +#define PCI_DMA_BUS_IS_PHYS (1) +struct pci_ops; + +/* + * Structure with hardware dependent information and functions of the + * PCI bus. + */ +struct pci_bus_info { + + /* + * Resources of the PCI bus. + */ + struct resource mem_space; + struct resource io_space; + + /* + * System dependent functions. + */ + struct pci_ops *bfin_pci_ops; + void (*fixup) (int pci_modify); + void (*conf_device) (unsigned char bus, unsigned char device_fn); +}; + +#define pcibios_assign_all_busses() 0 +static inline void pcibios_set_master(struct pci_dev *dev) +{ + + /* No special bus mastering setup handling */ +} +static inline void pcibios_penalize_isa_irq(int irq) +{ + + /* We don't do dynamic PCI IRQ allocation */ +} +static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, + size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + + /* return virt_to_bus(ptr); */ + return (dma_addr_t) ptr; +} + +/* Unmap a single streaming mode DMA translation. The dma_addr and size + * must match what was provided for in a previous pci_map_single call. All + * other usages are undefined. + * + * After this call, reads by the cpu to the buffer are guarenteed to see + * whatever the device wrote there. + */ +static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, + size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + + /* Nothing to do */ +} + +/* Map a set of buffers described by scatterlist in streaming + * mode for DMA. This is the scather-gather version of the + * above pci_map_single interface. Here the scatter gather list + * elements are each tagged with the appropriate dma address + * and length. They are obtained via sg_dma_{address,length}(SG). + * + * NOTE: An implementation may be able to use a smaller number of + * DMA address/length pairs than there are SG table elements. + * (for example via virtual mapping capabilities) + * The routine returns the number of addr/length pairs actually + * used, at most nents. + * + * Device ownership issues as mentioned above for pci_map_single are + * the same here. + */ +static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nents, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + return nents; +} + +/* Unmap a set of streaming mode DMA translations. + * Again, cpu read rules concerning calls here are the same as for + * pci_unmap_single() above. + */ +static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nents, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + + /* Nothing to do */ +} + +/* Make physical memory consistent for a single + * streaming mode DMA translation after a transfer. + * + * If you perform a pci_map_single() but wish to interrogate the + * buffer using the cpu, yet do not wish to teardown the PCI dma + * mapping, you must call this function before doing so. At the + * next point you give the PCI dma address back to the card, the + * device again owns the buffer. + */ +static inline void pci_dma_sync_single(struct pci_dev *hwdev, + dma_addr_t dma_handle, size_t size, + int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + + /* Nothing to do */ +} + +/* Make physical memory consistent for a set of streaming + * mode DMA translations after a transfer. + * + * The same as pci_dma_sync_single but for a scatter-gather list, + * same rules and usage. + */ +static inline void pci_dma_sync_sg(struct pci_dev *hwdev, + struct scatterlist *sg, int nelems, + int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + + /* Nothing to do */ +} + +#endif /* _ASM_BFIN_PCI_H */ diff --git a/include/asm-blackfin/percpu.h b/include/asm-blackfin/percpu.h new file mode 100644 index 000000000000..78dd61f6b39f --- /dev/null +++ b/include/asm-blackfin/percpu.h @@ -0,0 +1,6 @@ +#ifndef __ARCH_BLACKFIN_PERCPU__ +#define __ARCH_BLACKFIN_PERCPU__ + +#include + +#endif /* __ARCH_BLACKFIN_PERCPU__ */ diff --git a/include/asm-blackfin/pgalloc.h b/include/asm-blackfin/pgalloc.h new file mode 100644 index 000000000000..c686e0542fd0 --- /dev/null +++ b/include/asm-blackfin/pgalloc.h @@ -0,0 +1,8 @@ +#ifndef _BLACKFIN_PGALLOC_H +#define _BLACKFIN_PGALLOC_H + +#include + +#define check_pgt_cache() do { } while (0) + +#endif /* _BLACKFIN_PGALLOC_H */ diff --git a/include/asm-blackfin/pgtable.h b/include/asm-blackfin/pgtable.h new file mode 100644 index 000000000000..5a8f9e431c40 --- /dev/null +++ b/include/asm-blackfin/pgtable.h @@ -0,0 +1,96 @@ +#ifndef _BLACKFIN_PGTABLE_H +#define _BLACKFIN_PGTABLE_H + +#include + +#include +#include + +typedef pte_t *pte_addr_t; +/* +* Trivial page table functions. +*/ +#define pgd_present(pgd) (1) +#define pgd_none(pgd) (0) +#define pgd_bad(pgd) (0) +#define pgd_clear(pgdp) +#define kern_addr_valid(addr) (1) + +#define pmd_offset(a, b) ((void *)0) +#define pmd_none(x) (!pmd_val(x)) +#define pmd_present(x) (pmd_val(x)) +#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) +#define pmd_bad(x) (pmd_val(x) & ~PAGE_MASK) + +#define kern_addr_valid(addr) (1) + +#define PAGE_NONE __pgprot(0) /* these mean nothing to NO_MM */ +#define PAGE_SHARED __pgprot(0) /* these mean nothing to NO_MM */ +#define PAGE_COPY __pgprot(0) /* these mean nothing to NO_MM */ +#define PAGE_READONLY __pgprot(0) /* these mean nothing to NO_MM */ +#define PAGE_KERNEL __pgprot(0) /* these mean nothing to NO_MM */ + +extern void paging_init(void); + +#define __swp_type(x) (0) +#define __swp_offset(x) (0) +#define __swp_entry(typ,off) ((swp_entry_t) { ((typ) | ((off) << 7)) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) + +static inline int pte_file(pte_t pte) +{ + return 0; +} + +#define set_pte(pteptr, pteval) (*(pteptr) = pteval) +#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval) + +/* + * Page assess control based on Blackfin CPLB management + */ +#define _PAGE_RD (CPLB_USER_RD) +#define _PAGE_WR (CPLB_USER_WR) +#define _PAGE_USER (CPLB_USER_RD | CPLB_USER_WR) +#define _PAGE_ACCESSED CPLB_ALL_ACCESS +#define _PAGE_DIRTY (CPLB_DIRTY) + +#define PTE_BIT_FUNC(fn, op) \ + static inline pte_t pte_##fn(pte_t _pte) { _pte.pte op; return _pte; } + +PTE_BIT_FUNC(rdprotect, &= ~_PAGE_RD); +PTE_BIT_FUNC(mkread, |= _PAGE_RD); +PTE_BIT_FUNC(wrprotect, &= ~_PAGE_WR); +PTE_BIT_FUNC(mkwrite, |= _PAGE_WR); +PTE_BIT_FUNC(exprotect, &= ~_PAGE_USER); +PTE_BIT_FUNC(mkexec, |= _PAGE_USER); +PTE_BIT_FUNC(mkclean, &= ~_PAGE_DIRTY); +PTE_BIT_FUNC(mkdirty, |= _PAGE_DIRTY); +PTE_BIT_FUNC(mkold, &= ~_PAGE_ACCESSED); +PTE_BIT_FUNC(mkyoung, |= _PAGE_ACCESSED); + +/* + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +#define ZERO_PAGE(vaddr) (virt_to_page(0)) + +extern unsigned int kobjsize(const void *objp); + +#define swapper_pg_dir ((pgd_t *) 0) +/* + * No page table caches to initialise. + */ +#define pgtable_cache_init() do { } while (0) +#define io_remap_pfn_range remap_pfn_range + +/* + * All 32bit addresses are effectively valid for vmalloc... + * Sort of meaningless for non-VM targets. + */ +#define VMALLOC_START 0 +#define VMALLOC_END 0xffffffff + +#include + +#endif /* _BLACKFIN_PGTABLE_H */ diff --git a/include/asm-blackfin/poll.h b/include/asm-blackfin/poll.h new file mode 100644 index 000000000000..94cc2636e0e2 --- /dev/null +++ b/include/asm-blackfin/poll.h @@ -0,0 +1,24 @@ +#ifndef __BFIN_POLL_H +#define __BFIN_POLL_H + +#define POLLIN 1 +#define POLLPRI 2 +#define POLLOUT 4 +#define POLLERR 8 +#define POLLHUP 16 +#define POLLNVAL 32 +#define POLLRDNORM 64 +#define POLLWRNORM POLLOUT +#define POLLRDBAND 128 +#define POLLWRBAND 256 +#define POLLMSG 0x0400 +#define POLLREMOVE 0x1000 +#define POLLRDHUP 0x2000 + +struct pollfd { + int fd; + short events; + short revents; +}; + +#endif /* __BFIN_POLL_H */ diff --git a/include/asm-blackfin/posix_types.h b/include/asm-blackfin/posix_types.h new file mode 100644 index 000000000000..c3fa50fa50b8 --- /dev/null +++ b/include/asm-blackfin/posix_types.h @@ -0,0 +1,65 @@ +#ifndef __ARCH_BFIN_POSIX_TYPES_H +#define __ARCH_BFIN_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned int __kernel_ipc_pid_t; +typedef unsigned int __kernel_uid_t; +typedef unsigned int __kernel_gid_t; +typedef unsigned long __kernel_size_t; +typedef long __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_timer_t; +typedef int __kernel_clockid_t; +typedef int __kernel_daddr_t; +typedef char *__kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; +typedef unsigned short __kernel_old_dev_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) + +#undef __FD_CLR +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) + +#undef __FD_ISSET +#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp))) + +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ + +#endif diff --git a/include/asm-blackfin/processor.h b/include/asm-blackfin/processor.h new file mode 100644 index 000000000000..997465c93e82 --- /dev/null +++ b/include/asm-blackfin/processor.h @@ -0,0 +1,130 @@ +#ifndef __ASM_BFIN_PROCESSOR_H +#define __ASM_BFIN_PROCESSOR_H + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ __label__ _l; _l: &&_l;}) + +#include +#include +#include + +static inline unsigned long rdusp(void) +{ + unsigned long usp; + + __asm__ __volatile__("%0 = usp;\n\t":"=da"(usp)); + return usp; +} + +static inline void wrusp(unsigned long usp) +{ + __asm__ __volatile__("usp = %0;\n\t"::"da"(usp)); +} + +/* + * User space process size: 1st byte beyond user address space. + */ +extern unsigned long memory_end; +#define TASK_SIZE (memory_end) + +#define TASK_UNMAPPED_BASE 0 + +struct thread_struct { + unsigned long ksp; /* kernel stack pointer */ + unsigned long usp; /* user stack pointer */ + unsigned short seqstat; /* saved status register */ + unsigned long esp0; /* points to SR of stack frame pt_regs */ + unsigned long pc; /* instruction pointer */ + void * debuggerinfo; +}; + +#define INIT_THREAD { \ + sizeof(init_stack) + (unsigned long) init_stack, 0, \ + PS_S, 0, 0 \ +} + +/* + * Do necessary setup to start up a newly executed thread. + * + * pass the data segment into user programs if it exists, + * it can't hurt anything as far as I can tell + */ +#define start_thread(_regs, _pc, _usp) \ +do { \ + set_fs(USER_DS); \ + (_regs)->pc = (_pc); \ + if (current->mm) \ + (_regs)->p5 = current->mm->start_data; \ + current->thread_info->l1_task_info.stack_start \ + = (void *)current->mm->context.stack_start; \ + current->thread_info->l1_task_info.lowest_sp = (void *)(_usp); \ + memcpy(L1_SCRATCH_TASK_INFO, ¤t->thread_info->l1_task_info, \ + sizeof(*L1_SCRATCH_TASK_INFO)); \ + wrusp(_usp); \ +} while(0) + +/* Forward declaration, a strange C thing */ +struct task_struct; + +/* Free all resources held by a thread. */ +static inline void release_thread(struct task_struct *dead_task) +{ +} + +#define prepare_to_copy(tsk) do { } while (0) + +extern int kernel_thread(int (*fn) (void *), void *arg, unsigned long flags); + +/* + * Free current thread data structures etc.. + */ +static inline void exit_thread(void) +{ +} + +/* + * Return saved PC of a blocked thread. + */ +#define thread_saved_pc(tsk) (tsk->thread.pc) + +unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(tsk) \ + ({ \ + unsigned long eip = 0; \ + if ((tsk)->thread.esp0 > PAGE_SIZE && \ + MAP_NR((tsk)->thread.esp0) < max_mapnr) \ + eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ + eip; }) +#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) + +#define cpu_relax() barrier() + +/* Get the Silicon Revision of the chip */ +static inline uint32_t bfin_revid(void) +{ + /* stored in the upper 4 bits */ + return bfin_read_CHIPID() >> 28; +} + +static inline uint32_t bfin_compiled_revid(void) +{ +#if defined(CONFIG_BF_REV_0_0) + return 0; +#elif defined(CONFIG_BF_REV_0_1) + return 1; +#elif defined(CONFIG_BF_REV_0_2) + return 2; +#elif defined(CONFIG_BF_REV_0_3) + return 3; +#elif defined(CONFIG_BF_REV_0_4) + return 4; +#elif defined(CONFIG_BF_REV_0_5) + return 5; +#endif +} + +#endif diff --git a/include/asm-blackfin/ptrace.h b/include/asm-blackfin/ptrace.h new file mode 100644 index 000000000000..b8346cd3a6f6 --- /dev/null +++ b/include/asm-blackfin/ptrace.h @@ -0,0 +1,166 @@ +#ifndef _BFIN_PTRACE_H +#define _BFIN_PTRACE_H + +/* + * GCC defines register number like this: + * ----------------------------- + * 0 - 7 are data registers R0-R7 + * 8 - 15 are address registers P0-P7 + * 16 - 31 dsp registers I/B/L0 -- I/B/L3 & M0--M3 + * 32 - 33 A registers A0 & A1 + * 34 - status register + * ----------------------------- + * + * We follows above, except: + * 32-33 --- Low 32-bit of A0&1 + * 34-35 --- High 8-bit of A0&1 + */ + +#ifndef __ASSEMBLY__ + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long orig_pc; + long ipend; + long seqstat; + long rete; + long retn; + long retx; + long pc; /* PC == RETI */ + long rets; + long reserved; /* Used as scratch during system calls */ + long astat; + long lb1; + long lb0; + long lt1; + long lt0; + long lc1; + long lc0; + long a1w; + long a1x; + long a0w; + long a0x; + long b3; + long b2; + long b1; + long b0; + long l3; + long l2; + long l1; + long l0; + long m3; + long m2; + long m1; + long m0; + long i3; + long i2; + long i1; + long i0; + long usp; + long fp; + long p5; + long p4; + long p3; + long p2; + long p1; + long p0; + long r7; + long r6; + long r5; + long r4; + long r3; + long r2; + long r1; + long r0; + long orig_r0; + long orig_p0; + long syscfg; +}; + +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 /* ptrace signal */ + +#ifdef CONFIG_BINFMT_ELF_FDPIC +#define PTRACE_GETFDPIC 31 +#define PTRACE_GETFDPIC_EXEC 0 +#define PTRACE_GETFDPIC_INTERP 1 +#endif + +#define PS_S (0x0002) + +/* user_mode returns true if only one bit is set in IPEND, other than the + master interrupt enable. */ +#define user_mode(regs) (!(((regs)->ipend & ~0x10) & (((regs)->ipend & ~0x10) - 1))) +#define instruction_pointer(regs) ((regs)->pc) +#define profile_pc(regs) instruction_pointer(regs) +extern void show_regs(struct pt_regs *); + +#endif /* __ASSEMBLY__ */ + +/* + * Offsets used by 'ptrace' system call interface. + */ + +#define PT_R0 204 +#define PT_R1 200 +#define PT_R2 196 +#define PT_R3 192 +#define PT_R4 188 +#define PT_R5 184 +#define PT_R6 180 +#define PT_R7 176 +#define PT_P0 172 +#define PT_P1 168 +#define PT_P2 164 +#define PT_P3 160 +#define PT_P4 156 +#define PT_P5 152 +#define PT_FP 148 +#define PT_USP 144 +#define PT_I0 140 +#define PT_I1 136 +#define PT_I2 132 +#define PT_I3 128 +#define PT_M0 124 +#define PT_M1 120 +#define PT_M2 116 +#define PT_M3 112 +#define PT_L0 108 +#define PT_L1 104 +#define PT_L2 100 +#define PT_L3 96 +#define PT_B0 92 +#define PT_B1 88 +#define PT_B2 84 +#define PT_B3 80 +#define PT_A0X 76 +#define PT_A0W 72 +#define PT_A1X 68 +#define PT_A1W 64 +#define PT_LC0 60 +#define PT_LC1 56 +#define PT_LT0 52 +#define PT_LT1 48 +#define PT_LB0 44 +#define PT_LB1 40 +#define PT_ASTAT 36 +#define PT_RESERVED 32 +#define PT_RETS 28 +#define PT_PC 24 +#define PT_RETX 20 +#define PT_RETN 16 +#define PT_RETE 12 +#define PT_SEQSTAT 8 +#define PT_IPEND 4 + +#define PT_SYSCFG 216 +#define PT_TEXT_ADDR 220 +#define PT_TEXT_END_ADDR 224 +#define PT_DATA_ADDR 228 +#define PT_FDPIC_EXEC 232 +#define PT_FDPIC_INTERP 236 + +#endif /* _BFIN_PTRACE_H */ diff --git a/include/asm-blackfin/resource.h b/include/asm-blackfin/resource.h new file mode 100644 index 000000000000..091355ab3495 --- /dev/null +++ b/include/asm-blackfin/resource.h @@ -0,0 +1,6 @@ +#ifndef _BFIN_RESOURCE_H +#define _BFIN_RESOURCE_H + +#include + +#endif /* _BFIN_RESOURCE_H */ diff --git a/include/asm-blackfin/scatterlist.h b/include/asm-blackfin/scatterlist.h new file mode 100644 index 000000000000..60e07b92044c --- /dev/null +++ b/include/asm-blackfin/scatterlist.h @@ -0,0 +1,26 @@ +#ifndef _BLACKFIN_SCATTERLIST_H +#define _BLACKFIN_SCATTERLIST_H + +#include + +struct scatterlist { + struct page *page; + unsigned int offset; + dma_addr_t dma_address; + unsigned int length; +}; + +/* + * These macros should be used after a pci_map_sg call has been done + * to get bus addresses of each of the SG entries and their lengths. + * You should only work with the number of sg entries pci_map_sg + * returns, or alternatively stop on the first sg_dma_len(sg) which + * is 0. + */ +#define sg_address(sg) (page_address((sg)->page) + (sg)->offset) +#define sg_dma_address(sg) ((sg)->dma_address) +#define sg_dma_len(sg) ((sg)->length) + +#define ISA_DMA_THRESHOLD (0xffffffff) + +#endif /* !(_BLACKFIN_SCATTERLIST_H) */ diff --git a/include/asm-blackfin/sections.h b/include/asm-blackfin/sections.h new file mode 100644 index 000000000000..1443c3353a8c --- /dev/null +++ b/include/asm-blackfin/sections.h @@ -0,0 +1,7 @@ +#ifndef _BLACKFIN_SECTIONS_H +#define _BLACKFIN_SECTIONS_H + +/* nothing to see, move along */ +#include + +#endif diff --git a/include/asm-blackfin/segment.h b/include/asm-blackfin/segment.h new file mode 100644 index 000000000000..02cfd09b5a99 --- /dev/null +++ b/include/asm-blackfin/segment.h @@ -0,0 +1,7 @@ +#ifndef _BFIN_SEGMENT_H +#define _BFIN_SEGMENT_H + +#define KERNEL_DS (0x5) +#define USER_DS (0x1) + +#endif /* _BFIN_SEGMENT_H */ diff --git a/include/asm-blackfin/semaphore-helper.h b/include/asm-blackfin/semaphore-helper.h new file mode 100644 index 000000000000..9082b0dc3eb5 --- /dev/null +++ b/include/asm-blackfin/semaphore-helper.h @@ -0,0 +1,82 @@ +/* Based on M68K version, Lineo Inc. May 2001 */ + +#ifndef _BFIN_SEMAPHORE_HELPER_H +#define _BFIN_SEMAPHORE_HELPER_H + +/* + * SMP- and interrupt-safe semaphores helper functions. + * + * (C) Copyright 1996 Linus Torvalds + * + */ + +#include + +/* + * These two _must_ execute atomically wrt each other. + */ +static inline void wake_one_more(struct semaphore *sem) +{ + atomic_inc(&sem->waking); +} + +static inline int waking_non_zero(struct semaphore *sem) +{ + int ret; + unsigned long flags = 0; + + spin_lock_irqsave(&semaphore_wake_lock, flags); + ret = 0; + if (atomic_read(&sem->waking) > 0) { + atomic_dec(&sem->waking); + ret = 1; + } + spin_unlock_irqrestore(&semaphore_wake_lock, flags); + return ret; +} + +/* + * waking_non_zero_interruptible: + * 1 got the lock + * 0 go to sleep + * -EINTR interrupted + */ +static inline int waking_non_zero_interruptible(struct semaphore *sem, + struct task_struct *tsk) +{ + int ret = 0; + unsigned long flags = 0; + + spin_lock_irqsave(&semaphore_wake_lock, flags); + if (atomic_read(&sem->waking) > 0) { + atomic_dec(&sem->waking); + ret = 1; + } else if (signal_pending(tsk)) { + atomic_inc(&sem->count); + ret = -EINTR; + } + spin_unlock_irqrestore(&semaphore_wake_lock, flags); + return ret; +} + +/* + * waking_non_zero_trylock: + * 1 failed to lock + * 0 got the lock + */ +static inline int waking_non_zero_trylock(struct semaphore *sem) +{ + int ret = 1; + unsigned long flags = 0; + + spin_lock_irqsave(&semaphore_wake_lock, flags); + if (atomic_read(&sem->waking) > 0) { + atomic_dec(&sem->waking); + ret = 0; + } else + atomic_inc(&sem->count); + spin_unlock_irqrestore(&semaphore_wake_lock, flags); + return ret; +} + +#endif /* _BFIN_SEMAPHORE_HELPER_H */ diff --git a/include/asm-blackfin/semaphore.h b/include/asm-blackfin/semaphore.h new file mode 100644 index 000000000000..94c04d7ab23e --- /dev/null +++ b/include/asm-blackfin/semaphore.h @@ -0,0 +1,106 @@ +#ifndef _BFIN_SEMAPHORE_H +#define _BFIN_SEMAPHORE_H + +#ifndef __ASSEMBLY__ + +#include +#include +#include +#include +#include + +/* + * Interrupt-safe semaphores.. + * + * (C) Copyright 1996 Linus Torvalds + * + * BFIN version by akbar hussain Lineo Inc April 2001 + * + */ + +struct semaphore { + atomic_t count; + int sleepers; + wait_queue_head_t wait; +}; + +#define __SEMAPHORE_INITIALIZER(name, n) \ +{ \ + .count = ATOMIC_INIT(n), \ + .sleepers = 0, \ + .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ +} + +#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ + struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) + +#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) +#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) + +static inline void sema_init(struct semaphore *sem, int val) +{ + *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val); +} + +static inline void init_MUTEX(struct semaphore *sem) +{ + sema_init(sem, 1); +} + +static inline void init_MUTEX_LOCKED(struct semaphore *sem) +{ + sema_init(sem, 0); +} + +asmlinkage void __down(struct semaphore *sem); +asmlinkage int __down_interruptible(struct semaphore *sem); +asmlinkage int __down_trylock(struct semaphore *sem); +asmlinkage void __up(struct semaphore *sem); + +extern spinlock_t semaphore_wake_lock; + +/* + * This is ugly, but we want the default case to fall through. + * "down_failed" is a special asm handler that calls the C + * routine that actually waits. + */ +static inline void down(struct semaphore *sem) +{ + might_sleep(); + if (atomic_dec_return(&sem->count) < 0) + __down(sem); +} + +static inline int down_interruptible(struct semaphore *sem) +{ + int ret = 0; + + might_sleep(); + if (atomic_dec_return(&sem->count) < 0) + ret = __down_interruptible(sem); + return (ret); +} + +static inline int down_trylock(struct semaphore *sem) +{ + int ret = 0; + + if (atomic_dec_return(&sem->count) < 0) + ret = __down_trylock(sem); + return ret; +} + +/* + * Note! This is subtle. We jump to wake people up only if + * the semaphore was negative (== somebody was waiting on it). + * The default case (no contention) will result in NO + * jumps for both down() and up(). + */ +static inline void up(struct semaphore *sem) +{ + if (atomic_inc_return(&sem->count) <= 0) + __up(sem); +} + +#endif /* __ASSEMBLY__ */ +#endif /* _BFIN_SEMAPHORE_H */ diff --git a/include/asm-blackfin/sembuf.h b/include/asm-blackfin/sembuf.h new file mode 100644 index 000000000000..18deb5c7fa5d --- /dev/null +++ b/include/asm-blackfin/sembuf.h @@ -0,0 +1,25 @@ +#ifndef _BFIN_SEMBUF_H +#define _BFIN_SEMBUF_H + +/* + * The semid64_ds structure for bfin architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct semid64_ds { + struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ + __kernel_time_t sem_otime; /* last semop time */ + unsigned long __unused1; + __kernel_time_t sem_ctime; /* last change time */ + unsigned long __unused2; + unsigned long sem_nsems; /* no. of semaphores in array */ + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _BFIN_SEMBUF_H */ diff --git a/include/asm-blackfin/setup.h b/include/asm-blackfin/setup.h new file mode 100644 index 000000000000..01c8c6cbe6fc --- /dev/null +++ b/include/asm-blackfin/setup.h @@ -0,0 +1,17 @@ +/* +** asm/setup.h -- Definition of the Linux/bfin setup information +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Copyright Lineo, Inc 2001 Tony Kou +** +*/ + +#ifndef _BFIN_SETUP_H +#define _BFIN_SETUP_H + +#define COMMAND_LINE_SIZE 512 + +#endif /* _BFIN_SETUP_H */ diff --git a/include/asm-blackfin/shmbuf.h b/include/asm-blackfin/shmbuf.h new file mode 100644 index 000000000000..612436303e89 --- /dev/null +++ b/include/asm-blackfin/shmbuf.h @@ -0,0 +1,42 @@ +#ifndef _BFIN_SHMBUF_H +#define _BFIN_SHMBUF_H + +/* + * The shmid64_ds structure for bfin architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct shmid64_ds { + struct ipc64_perm shm_perm; /* operation perms */ + size_t shm_segsz; /* size of segment (bytes) */ + __kernel_time_t shm_atime; /* last attach time */ + unsigned long __unused1; + __kernel_time_t shm_dtime; /* last detach time */ + unsigned long __unused2; + __kernel_time_t shm_ctime; /* last change time */ + unsigned long __unused3; + __kernel_pid_t shm_cpid; /* pid of creator */ + __kernel_pid_t shm_lpid; /* pid of last operator */ + unsigned long shm_nattch; /* no. of current attaches */ + unsigned long __unused4; + unsigned long __unused5; +}; + +struct shminfo64 { + unsigned long shmmax; + unsigned long shmmin; + unsigned long shmmni; + unsigned long shmseg; + unsigned long shmall; + unsigned long __unused1; + unsigned long __unused2; + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _BFIN_SHMBUF_H */ diff --git a/include/asm-blackfin/shmparam.h b/include/asm-blackfin/shmparam.h new file mode 100644 index 000000000000..3c03906b7664 --- /dev/null +++ b/include/asm-blackfin/shmparam.h @@ -0,0 +1,6 @@ +#ifndef _BFIN_SHMPARAM_H +#define _BFIN_SHMPARAM_H + +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ + +#endif /* _BFIN_SHMPARAM_H */ diff --git a/include/asm-blackfin/sigcontext.h b/include/asm-blackfin/sigcontext.h new file mode 100644 index 000000000000..ce00b03c2775 --- /dev/null +++ b/include/asm-blackfin/sigcontext.h @@ -0,0 +1,55 @@ +#ifndef _ASM_BLACKFIN_SIGCONTEXT_H +#define _ASM_BLACKFIN_SIGCONTEXT_H + +/* Add new entries at the end of the structure only. */ +struct sigcontext { + unsigned long sc_r0; + unsigned long sc_r1; + unsigned long sc_r2; + unsigned long sc_r3; + unsigned long sc_r4; + unsigned long sc_r5; + unsigned long sc_r6; + unsigned long sc_r7; + unsigned long sc_p0; + unsigned long sc_p1; + unsigned long sc_p2; + unsigned long sc_p3; + unsigned long sc_p4; + unsigned long sc_p5; + unsigned long sc_usp; + unsigned long sc_a0w; + unsigned long sc_a1w; + unsigned long sc_a0x; + unsigned long sc_a1x; + unsigned long sc_astat; + unsigned long sc_rets; + unsigned long sc_pc; + unsigned long sc_retx; + unsigned long sc_fp; + unsigned long sc_i0; + unsigned long sc_i1; + unsigned long sc_i2; + unsigned long sc_i3; + unsigned long sc_m0; + unsigned long sc_m1; + unsigned long sc_m2; + unsigned long sc_m3; + unsigned long sc_l0; + unsigned long sc_l1; + unsigned long sc_l2; + unsigned long sc_l3; + unsigned long sc_b0; + unsigned long sc_b1; + unsigned long sc_b2; + unsigned long sc_b3; + unsigned long sc_lc0; + unsigned long sc_lc1; + unsigned long sc_lt0; + unsigned long sc_lt1; + unsigned long sc_lb0; + unsigned long sc_lb1; + unsigned long sc_seqstat; +}; + +#endif diff --git a/include/asm-blackfin/siginfo.h b/include/asm-blackfin/siginfo.h new file mode 100644 index 000000000000..eca4565cea37 --- /dev/null +++ b/include/asm-blackfin/siginfo.h @@ -0,0 +1,35 @@ +#ifndef _BFIN_SIGINFO_H +#define _BFIN_SIGINFO_H + +#include +#include + +#define UID16_SIGINFO_COMPAT_NEEDED + +#define si_uid16 _sifields._kill._uid + +#define ILL_ILLPARAOP (__SI_FAULT|2) /* illegal opcode combine ********** */ +#define ILL_ILLEXCPT (__SI_FAULT|4) /* unrecoverable exception ********** */ +#define ILL_CPLB_VI (__SI_FAULT|9) /* D/I CPLB protect violation ******** */ +#define ILL_CPLB_MISS (__SI_FAULT|10) /* D/I CPLB miss ******** */ +#define ILL_CPLB_MULHIT (__SI_FAULT|11) /* D/I CPLB multiple hit ******** */ + +/* + * SIGBUS si_codes + */ +#define BUS_OPFETCH (__SI_FAULT|4) /* error from instruction fetch ******** */ + +/* + * SIGTRAP si_codes + */ +#define TRAP_STEP (__SI_FAULT|1) /* single-step breakpoint************* */ +#define TRAP_TRACEFLOW (__SI_FAULT|2) /* trace buffer overflow ************* */ +#define TRAP_WATCHPT (__SI_FAULT|3) /* watchpoint match ************* */ +#define TRAP_ILLTRAP (__SI_FAULT|4) /* illegal trap ************* */ + +/* + * SIGSEGV si_codes + */ +#define SEGV_STACKFLOW (__SI_FAULT|3) /* stack overflow */ + +#endif diff --git a/include/asm-blackfin/signal.h b/include/asm-blackfin/signal.h new file mode 100644 index 000000000000..0250429b736a --- /dev/null +++ b/include/asm-blackfin/signal.h @@ -0,0 +1,160 @@ +#ifndef _BLACKFIN_SIGNAL_H +#define _BLACKFIN_SIGNAL_H + +#include + +/* Avoid too many header ordering problems. */ +struct siginfo; + +#ifdef __KERNEL__ +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +#define _NSIG 64 +#define _NSIG_BPW 32 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +#define NSIG 32 +typedef unsigned long sigset_t; + +#endif /* __KERNEL__ */ + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGSYS 31 +#define SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define SIGRTMIN 32 +#define SIGRTMAX _NSIG + +/* + * SA_FLAGS values: + * + * SA_ONSTACK indicates that a registered stack_t will be used. + * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. + * SA_RESETHAND clears the handler when the signal is delivered. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. + * SA_NODEFER prevents the current signal from being masked in the handler. + * + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single + * Unix names RESETHAND and NODEFER respectively. + */ +#define SA_NOCLDSTOP 0x00000001 +#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_SIGINFO 0x00000004 +#define SA_ONSTACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_NODEFER 0x40000000 +#define SA_RESETHAND 0x80000000 + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND + +/* + * sigaltstack controls + */ +#define SS_ONSTACK 1 +#define SS_DISABLE 2 + +#define MINSIGSTKSZ 2048 +#define SIGSTKSZ 8192 + +#include + +#ifdef __KERNEL__ +struct old_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer) (void); +}; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + void (*sa_restorer) (void); + sigset_t sa_mask; /* mask last for extensibility */ +}; + +struct k_sigaction { + struct sigaction sa; +}; +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +struct sigaction { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction) (int, struct siginfo *, void *); + } _u; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer) (void); +}; + +#define sa_handler _u._sa_handler +#define sa_sigaction _u._sa_sigaction + +#endif /* __KERNEL__ */ + +typedef struct sigaltstack { + void *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +#ifdef __KERNEL__ + +#include +#undef __HAVE_ARCH_SIG_BITOPS + +#define ptrace_signal_deliver(regs, cookie) do { } while (0) + +#endif /* __KERNEL__ */ + +#endif /* _BLACKFIN_SIGNAL_H */ diff --git a/include/asm-blackfin/socket.h b/include/asm-blackfin/socket.h new file mode 100644 index 000000000000..5213c9652186 --- /dev/null +++ b/include/asm-blackfin/socket.h @@ -0,0 +1,53 @@ +#ifndef _ASM_SOCKET_H +#define _ASM_SOCKET_H + +#include + +/* For setsockoptions(2) */ +#define SOL_SOCKET 1 + +#define SO_DEBUG 1 +#define SO_REUSEADDR 2 +#define SO_TYPE 3 +#define SO_ERROR 4 +#define SO_DONTROUTE 5 +#define SO_BROADCAST 6 +#define SO_SNDBUF 7 +#define SO_RCVBUF 8 +#define SO_SNDBUFFORCE 32 +#define SO_RCVBUFFORCE 33 +#define SO_KEEPALIVE 9 +#define SO_OOBINLINE 10 +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_LINGER 13 +#define SO_BSDCOMPAT 14 +/* To add :#define SO_REUSEPORT 15 */ +#define SO_PASSCRED 16 +#define SO_PEERCRED 17 +#define SO_RCVLOWAT 18 +#define SO_SNDLOWAT 19 +#define SO_RCVTIMEO 20 +#define SO_SNDTIMEO 21 + +/* Security levels - as per NRL IPv6 - don't actually do anything */ +#define SO_SECURITY_AUTHENTICATION 22 +#define SO_SECURITY_ENCRYPTION_TRANSPORT 23 +#define SO_SECURITY_ENCRYPTION_NETWORK 24 + +#define SO_BINDTODEVICE 25 + +/* Socket filtering */ +#define SO_ATTACH_FILTER 26 +#define SO_DETACH_FILTER 27 + +#define SO_PEERNAME 28 +#define SO_TIMESTAMP 29 +#define SCM_TIMESTAMP SO_TIMESTAMP + +#define SO_ACCEPTCONN 30 +#define SO_PEERSEC 31 +#define SO_PASSSEC 34 +#define SO_TIMESTAMPNS 35 +#define SCM_TIMESTAMPNS SO_TIMESTAMPNS +#endif /* _ASM_SOCKET_H */ diff --git a/include/asm-blackfin/sockios.h b/include/asm-blackfin/sockios.h new file mode 100644 index 000000000000..426b89bfaa8b --- /dev/null +++ b/include/asm-blackfin/sockios.h @@ -0,0 +1,13 @@ +#ifndef __ARCH_BFIN_SOCKIOS__ +#define __ARCH_BFIN_SOCKIOS__ + +/* Socket-level I/O control calls. */ +#define FIOSETOWN 0x8901 +#define SIOCSPGRP 0x8902 +#define FIOGETOWN 0x8903 +#define SIOCGPGRP 0x8904 +#define SIOCATMARK 0x8905 +#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ +#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ + +#endif /* __ARCH_BFIN_SOCKIOS__ */ diff --git a/include/asm-blackfin/spinlock.h b/include/asm-blackfin/spinlock.h new file mode 100644 index 000000000000..64e908a50646 --- /dev/null +++ b/include/asm-blackfin/spinlock.h @@ -0,0 +1,6 @@ +#ifndef __BFIN_SPINLOCK_H +#define __BFIN_SPINLOCK_H + +#error blackfin architecture does not support SMP spin lock yet + +#endif diff --git a/include/asm-blackfin/stat.h b/include/asm-blackfin/stat.h new file mode 100644 index 000000000000..d2b6f11ec231 --- /dev/null +++ b/include/asm-blackfin/stat.h @@ -0,0 +1,63 @@ +#ifndef _BFIN_STAT_H +#define _BFIN_STAT_H + +struct stat { + unsigned short st_dev; + unsigned short __pad1; + unsigned long st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned short __pad2; + unsigned long st_size; + unsigned long st_blksize; + unsigned long st_blocks; + unsigned long st_atime; + unsigned long __unused1; + unsigned long st_mtime; + unsigned long __unused2; + unsigned long st_ctime; + unsigned long __unused3; + unsigned long __unused4; + unsigned long __unused5; +}; + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + */ +struct stat64 { + unsigned long long st_dev; + unsigned char __pad1[4]; + +#define STAT64_HAS_BROKEN_ST_INO 1 + unsigned long __st_ino; + + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned long long st_rdev; + unsigned char __pad2[4]; + + long long st_size; + unsigned long st_blksize; + + long long st_blocks; /* Number 512-byte blocks allocated. */ + + unsigned long st_atime; + unsigned long st_atime_nsec; + + unsigned long st_mtime; + unsigned long st_mtime_nsec; + + unsigned long st_ctime; + unsigned long st_ctime_nsec; + + unsigned long long st_ino; +}; + +#endif /* _BFIN_STAT_H */ diff --git a/include/asm-blackfin/statfs.h b/include/asm-blackfin/statfs.h new file mode 100644 index 000000000000..350672091ba3 --- /dev/null +++ b/include/asm-blackfin/statfs.h @@ -0,0 +1,6 @@ +#ifndef _BFIN_STATFS_H +#define _BFIN_STATFS_H + +#include + +#endif /* _BFIN_STATFS_H */ diff --git a/include/asm-blackfin/string.h b/include/asm-blackfin/string.h new file mode 100644 index 000000000000..6f1eb7d6d3cb --- /dev/null +++ b/include/asm-blackfin/string.h @@ -0,0 +1,104 @@ +#ifndef _BLACKFIN_STRING_H_ +#define _BLACKFIN_STRING_H_ + +#ifdef __KERNEL__ /* only set these up for kernel code */ + +#define __HAVE_ARCH_STRCPY +extern inline char *strcpy(char *dest, const char *src) +{ + char *xdest = dest; + char temp = 0; + + __asm__ __volatile__ + ("1:\t%2 = B [%1++] (Z);\n\t" + "B [%0++] = %2;\n\t" + "CC = %2;\n\t" + "if cc jump 1b (bp);\n" + : "+&a" (dest), "+&a" (src), "=&d" (temp) + ::"memory", "CC"); + return xdest; +} + +#define __HAVE_ARCH_STRNCPY +extern inline char *strncpy(char *dest, const char *src, size_t n) +{ + char *xdest = dest; + char temp = 0; + + if (n == 0) + return xdest; + + __asm__ __volatile__ + ("1:\t%3 = B [%1++] (Z);\n\t" + "B [%0++] = %3;\n\t" + "CC = %3;\n\t" + "if ! cc jump 2f;\n\t" + "%2 += -1;\n\t" + "CC = %2 == 0;\n\t" + "if ! cc jump 1b (bp);\n" + "2:\n" + : "+&a" (dest), "+&a" (src), "+&da" (n), "=&d" (temp) + ::"memory", "CC"); + return xdest; +} + +#define __HAVE_ARCH_STRCMP +extern inline int strcmp(const char *cs, const char *ct) +{ + char __res1, __res2; + + __asm__ + ("1:\t%2 = B[%0++] (Z);\n\t" /* get *cs */ + "%3 = B[%1++] (Z);\n\t" /* get *ct */ + "CC = %2 == %3;\n\t" /* compare a byte */ + "if ! cc jump 2f;\n\t" /* not equal, break out */ + "CC = %2;\n\t" /* at end of cs? */ + "if cc jump 1b (bp);\n\t" /* no, keep going */ + "jump.s 3f;\n" /* strings are equal */ + "2:\t%2 = %2 - %3;\n" /* *cs - *ct */ + "3:\n" + : "+&a" (cs), "+&a" (ct), "=&d" (__res1), "=&d" (__res2) + : : "CC"); + + return __res1; +} + +#define __HAVE_ARCH_STRNCMP +extern inline int strncmp(const char *cs, const char *ct, size_t count) +{ + char __res1, __res2; + + if (!count) + return 0; + __asm__ + ("1:\t%3 = B[%0++] (Z);\n\t" /* get *cs */ + "%4 = B[%1++] (Z);\n\t" /* get *ct */ + "CC = %3 == %4;\n\t" /* compare a byte */ + "if ! cc jump 3f;\n\t" /* not equal, break out */ + "CC = %3;\n\t" /* at end of cs? */ + "if ! cc jump 4f;\n\t" /* yes, all done */ + "%2 += -1;\n\t" /* no, adjust count */ + "CC = %2 == 0;\n\t" + "if ! cc jump 1b;\n" /* more to do, keep going */ + "2:\t%3 = 0;\n\t" /* strings are equal */ + "jump.s 4f;\n" + "3:\t%3 = %3 - %4;\n" /* *cs - *ct */ + "4:" + : "+&a" (cs), "+&a" (ct), "+&da" (count), "=&d" (__res1), "=&d" (__res2) + : : "CC"); + return __res1; +} + +#define __HAVE_ARCH_MEMSET +extern void *memset(void *s, int c, size_t count); +#define __HAVE_ARCH_MEMCPY +extern void *memcpy(void *d, const void *s, size_t count); +#define __HAVE_ARCH_MEMCMP +extern int memcmp(const void *, const void *, __kernel_size_t); +#define __HAVE_ARCH_MEMCHR +extern void *memchr(const void *s, int c, size_t n); +#define __HAVE_ARCH_MEMMOVE +extern void *memmove(void *dest, const void *src, size_t count); + +#endif /*__KERNEL__*/ +#endif /* _BLACKFIN_STRING_H_ */ diff --git a/include/asm-blackfin/system.h b/include/asm-blackfin/system.h new file mode 100644 index 000000000000..758bac7c1e74 --- /dev/null +++ b/include/asm-blackfin/system.h @@ -0,0 +1,250 @@ +/* + * File: include/asm/system.h + * Based on: + * Author: Tony Kou (tonyko@lineo.ca) + * Copyright (c) 2002 Arcturus Networks Inc. + * (www.arcturusnetworks.com) + * Copyright (c) 2003 Metrowerks (www.metrowerks.com) + * Copyright (c) 2004 Analog Device Inc. + * Created: 25Jan2001 - Tony Kou + * Description: system.h include file + * + * Modified: 22Sep2006 - Robin Getz + * - move include blackfin.h down, so I can get access to + * irq functions in other include files. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _BLACKFIN_SYSTEM_H +#define _BLACKFIN_SYSTEM_H + +#include +#include + +/* + * Interrupt configuring macros. + */ + +extern unsigned long irq_flags; + +#define local_irq_enable() do { \ + __asm__ __volatile__ ( \ + "sti %0;" \ + ::"d"(irq_flags)); \ +} while (0) + +#define local_irq_disable() do { \ + int _tmp_dummy; \ + __asm__ __volatile__ ( \ + "cli %0;" \ + :"=d" (_tmp_dummy):); \ +} while (0) + +#if defined(ANOMALY_05000244) && defined (CONFIG_BLKFIN_CACHE) +#define idle_with_irq_disabled() do { \ + __asm__ __volatile__ ( \ + "nop; nop;\n" \ + ".align 8;\n" \ + "sti %0; idle;\n" \ + ::"d" (irq_flags)); \ +} while (0) +#else +#define idle_with_irq_disabled() do { \ + __asm__ __volatile__ ( \ + ".align 8;\n" \ + "sti %0; idle;\n" \ + ::"d" (irq_flags)); \ +} while (0) +#endif + +#ifdef CONFIG_DEBUG_HWERR +#define __save_and_cli(x) do { \ + __asm__ __volatile__ ( \ + "cli %0;\n\tsti %1;" \ + :"=&d"(x): "d" (0x3F)); \ +} while (0) +#else +#define __save_and_cli(x) do { \ + __asm__ __volatile__ ( \ + "cli %0;" \ + :"=&d"(x):); \ +} while (0) +#endif + +#define local_save_flags(x) asm volatile ("cli %0;" \ + "sti %0;" \ + :"=d"(x):); + +#ifdef CONFIG_DEBUG_HWERR +#define irqs_enabled_from_flags(x) (((x) & ~0x3f) != 0) +#else +#define irqs_enabled_from_flags(x) ((x) != 0x1f) +#endif + +#define local_irq_restore(x) do { \ + if (irqs_enabled_from_flags(x)) \ + local_irq_enable (); \ +} while (0) + +/* For spinlocks etc */ +#define local_irq_save(x) __save_and_cli(x) + +#define irqs_disabled() \ +({ \ + unsigned long flags; \ + local_save_flags(flags); \ + !irqs_enabled_from_flags(flags); \ +}) + +/* + * Force strict CPU ordering. + */ +#define nop() asm volatile ("nop;\n\t"::) +#define mb() asm volatile ("" : : :"memory") +#define rmb() asm volatile ("" : : :"memory") +#define wmb() asm volatile ("" : : :"memory") +#define set_rmb(var, value) do { (void) xchg(&var, value); } while (0) +#define set_mb(var, value) set_rmb(var, value) +#define set_wmb(var, value) do { var = value; wmb(); } while (0) + +#define read_barrier_depends() do { } while(0) + +#ifdef CONFIG_SMP +#define smp_mb() mb() +#define smp_rmb() rmb() +#define smp_wmb() wmb() +#define smp_read_barrier_depends() read_barrier_depends() +#else +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define smp_read_barrier_depends() do { } while(0) +#endif + +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define tas(ptr) ((void)xchg((ptr),1)) + +struct __xchg_dummy { + unsigned long a[100]; +}; +#define __xg(x) ((volatile struct __xchg_dummy *)(x)) + +static inline unsigned long __xchg(unsigned long x, volatile void *ptr, + int size) +{ + unsigned long tmp = 0; + unsigned long flags = 0; + + local_irq_save(flags); + + switch (size) { + case 1: + __asm__ __volatile__ + ("%0 = b%2 (z);\n\t" + "b%2 = %1;\n\t" + : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 2: + __asm__ __volatile__ + ("%0 = w%2 (z);\n\t" + "w%2 = %1;\n\t" + : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 4: + __asm__ __volatile__ + ("%0 = %2;\n\t" + "%2 = %1;\n\t" + : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + } + local_irq_restore(flags); + return tmp; +} + +/* + * Atomic compare and exchange. Compare OLD with MEM, if identical, + * store NEW in MEM. Return the initial value in MEM. Success is + * indicated by comparing RETURN with OLD. + */ +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, + unsigned long new, int size) +{ + unsigned long tmp = 0; + unsigned long flags = 0; + + local_irq_save(flags); + + switch (size) { + case 1: + __asm__ __volatile__ + ("%0 = b%3 (z);\n\t" + "CC = %1 == %0;\n\t" + "IF !CC JUMP 1f;\n\t" + "b%3 = %2;\n\t" + "1:\n\t" + : "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory"); + break; + case 2: + __asm__ __volatile__ + ("%0 = w%3 (z);\n\t" + "CC = %1 == %0;\n\t" + "IF !CC JUMP 1f;\n\t" + "w%3 = %2;\n\t" + "1:\n\t" + : "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory"); + break; + case 4: + __asm__ __volatile__ + ("%0 = %3;\n\t" + "CC = %1 == %0;\n\t" + "IF !CC JUMP 1f;\n\t" + "%3 = %2;\n\t" + "1:\n\t" + : "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory"); + break; + } + local_irq_restore(flags); + return tmp; +} + +#define cmpxchg(ptr,o,n)\ + ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ + (unsigned long)(n),sizeof(*(ptr)))) + +#define prepare_to_switch() do { } while(0) + +/* + * switch_to(n) should switch tasks to task ptr, first checking that + * ptr isn't the current task, in which case it does nothing. + */ + +#include + +asmlinkage struct task_struct *resume(struct task_struct *prev, struct task_struct *next); + +#define switch_to(prev,next,last) \ +do { \ + memcpy (&prev->thread_info->l1_task_info, L1_SCRATCH_TASK_INFO, \ + sizeof *L1_SCRATCH_TASK_INFO); \ + memcpy (L1_SCRATCH_TASK_INFO, &next->thread_info->l1_task_info, \ + sizeof *L1_SCRATCH_TASK_INFO); \ + (last) = resume (prev, next); \ +} while (0) + +#endif /* _BLACKFIN_SYSTEM_H */ diff --git a/include/asm-blackfin/termbits.h b/include/asm-blackfin/termbits.h new file mode 100644 index 000000000000..2fd9dabdba77 --- /dev/null +++ b/include/asm-blackfin/termbits.h @@ -0,0 +1,184 @@ +#ifndef __ARCH_BFIN_TERMBITS_H__ +#define __ARCH_BFIN_TERMBITS_H__ + +#include + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 +#define IUTF8 0040000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0100000 +#define FF0 0000000 +#define FF1 0100000 + +/* c_cflag bit meaning */ +#define CBAUD 0010017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define CBAUDEX 0010000 +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define B460800 0010004 +#define B500000 0010005 +#define B576000 0010006 +#define B921600 0010007 +#define B1000000 0010010 +#define B1152000 0010011 +#define B1500000 0010012 +#define B2000000 0010013 +#define B2500000 0010014 +#define B3000000 0010015 +#define B3500000 0010016 +#define B4000000 0010017 +#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CMSPAR 010000000000 /* mark or space (stick) parity */ +#define CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif /* __ARCH_BFIN_TERMBITS_H__ */ diff --git a/include/asm-blackfin/termios.h b/include/asm-blackfin/termios.h new file mode 100644 index 000000000000..5c41478a51c6 --- /dev/null +++ b/include/asm-blackfin/termios.h @@ -0,0 +1,106 @@ +#ifndef __BFIN_TERMIOS_H__ +#define __BFIN_TERMIOS_H__ + +#include +#include + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ + +/* line disciplines */ +#define N_TTY 0 +#define N_SLIP 1 +#define N_MOUSE 2 +#define N_PPP 3 +#define N_STRIP 4 +#define N_AX25 5 +#define N_X25 6 /* X.25 async */ +#define N_6PACK 7 +#define N_MASC 8 /* Reserved for Mobitex module */ +#define N_R3964 9 /* Reserved for Simatic R3964 module */ +#define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ +#define N_IRDA 11 /* Linux IR - http://irda.sourceforge.net/ */ +#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ +#define N_HDLC 13 /* synchronous HDLC */ +#define N_SYNC_PPP 14 /* synchronous PPP */ +#define N_HCI 15 /* Bluetooth HCI UART */ + +#ifdef __KERNEL__ + +/* intr=^C quit=^\ erase=del kill=^U + eof=^D vtime=\0 vmin=\1 sxtc=\0 + start=^Q stop=^S susp=^Z eol=\0 + reprint=^R discard=^U werase=^W lnext=^V + eol2=\0 +*/ +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ + unsigned short __tmp; \ + get_user(__tmp,&(termio)->x); \ + *(unsigned short *) &(termios)->x = __tmp; \ +} + +#define user_termio_to_kernel_termios(termios, termio) \ +({ \ + SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ + copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ +}) + +/* + * Translate a "termios" structure into a "termio". Ugh. + */ +#define kernel_termios_to_user_termio(termio, termios) \ +({ \ + put_user((termios)->c_iflag, &(termio)->c_iflag); \ + put_user((termios)->c_oflag, &(termio)->c_oflag); \ + put_user((termios)->c_cflag, &(termio)->c_cflag); \ + put_user((termios)->c_lflag, &(termio)->c_lflag); \ + put_user((termios)->c_line, &(termio)->c_line); \ + copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ +}) + +#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) +#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) + +#endif /* __KERNEL__ */ + +#endif /* __BFIN_TERMIOS_H__ */ diff --git a/include/asm-blackfin/thread_info.h b/include/asm-blackfin/thread_info.h new file mode 100644 index 000000000000..fa8f08cf283e --- /dev/null +++ b/include/asm-blackfin/thread_info.h @@ -0,0 +1,143 @@ +/* + * File: include/asm-blackfin/thread_info.h + * Based on: include/asm-m68knommu/thread_info.h + * Author: LG Soft India + * Copyright (C) 2004-2005 Analog Devices Inc. + * Created: Tue Sep 21 2004 + * Description: Blackfin low-level thread information + * Modified: + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _ASM_THREAD_INFO_H +#define _ASM_THREAD_INFO_H + +#include +#include +#include +#include + +#ifdef __KERNEL__ + +/* Thread Align Mask to reach to the top of the stack + * for any process + */ +#define ALIGN_PAGE_MASK 0xffffe000 + +#ifndef __ASSEMBLY__ + +typedef unsigned long mm_segment_t; + +/* + * low level task data. + * If you change this, change the TI_* offsets below to match. + */ + +struct thread_info { + struct task_struct *task; /* main task structure */ + struct exec_domain *exec_domain; /* execution domain */ + unsigned long flags; /* low level flags */ + int cpu; /* cpu we're on */ + int preempt_count; /* 0 => preemptable, <0 => BUG */ + mm_segment_t addr_limit; /* address limit */ + struct restart_block restart_block; + struct l1_scratch_task_info l1_task_info; +}; + +/* + * macros/functions for gaining access to the thread information structure + */ +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .flags = 0, \ + .cpu = 0, \ + .preempt_count = 1, \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ +} +#define init_thread_info (init_thread_union.thread_info) +#define init_stack (init_thread_union.stack) + +/* + * Size of kernel stack for each process. This must be a power of 2... + */ +#define THREAD_SIZE 8192 /* 2 pages */ + +/* How to get the thread information struct from C */ + +static inline struct thread_info *current_thread_info(void) + __attribute__ ((__const__)); + +/* Given a task stack pointer, you can find it's task structure + * just by masking it to the 8K boundary. + */ +static inline struct thread_info *current_thread_info(void) +{ + struct thread_info *ti; + __asm__("%0 = sp;": "=&d"(ti): + ); + return (struct thread_info *)((long)ti & ~8191UL); +} + +/* thread information allocation */ +#define alloc_thread_info(tsk) ((struct thread_info *) \ + __get_free_pages(GFP_KERNEL, 1)) +#define free_thread_info(ti) free_pages((unsigned long) (ti), 1) +#endif /* __ASSEMBLY__ */ + +/* + * Offsets in thread_info structure, used in assembly code + */ +#define TI_TASK 0 +#define TI_EXECDOMAIN 4 +#define TI_FLAGS 8 +#define TI_CPU 12 +#define TI_PREEMPT 16 + +#define PREEMPT_ACTIVE 0x4000000 + +/* + * thread information flag bit numbers + */ +#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ +#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ +#define TIF_SIGPENDING 2 /* signal pending */ +#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ +#define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling + TIF_NEED_RESCHED */ +#define TIF_MEMDIE 5 +#define TIF_RESTORE_SIGMASK 6 /* restore signal mask in do_signal() */ +#define TIF_FREEZE 7 /* is freezing for suspend */ + +/* as above, but as bit values */ +#define _TIF_SYSCALL_TRACE (1<mm) + +#include + +#endif /* _BLACKFIN_TLB_H */ diff --git a/include/asm-blackfin/tlbflush.h b/include/asm-blackfin/tlbflush.h new file mode 100644 index 000000000000..10a07ba1e011 --- /dev/null +++ b/include/asm-blackfin/tlbflush.h @@ -0,0 +1,62 @@ +#ifndef _BLACKFIN_TLBFLUSH_H +#define _BLACKFIN_TLBFLUSH_H + +/* + * Copyright (C) 2000 Lineo, David McCullough + * Copyright (C) 2000-2002, Greg Ungerer + */ + +#include + +/* + * flush all user-space atc entries. + */ +static inline void __flush_tlb(void) +{ + BUG(); +} + +static inline void __flush_tlb_one(unsigned long addr) +{ + BUG(); +} + +#define flush_tlb() __flush_tlb() + +/* + * flush all atc entries (both kernel and user-space entries). + */ +static inline void flush_tlb_all(void) +{ + BUG(); +} + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + BUG(); +} + +static inline void flush_tlb_page(struct vm_area_struct *vma, + unsigned long addr) +{ + BUG(); +} + +static inline void flush_tlb_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + BUG(); +} + +static inline void flush_tlb_kernel_page(unsigned long addr) +{ + BUG(); +} + +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + BUG(); +} + +#endif diff --git a/include/asm-blackfin/topology.h b/include/asm-blackfin/topology.h new file mode 100644 index 000000000000..acee23987897 --- /dev/null +++ b/include/asm-blackfin/topology.h @@ -0,0 +1,6 @@ +#ifndef _ASM_BLACKFIN_TOPOLOGY_H +#define _ASM_BLACKFIN_TOPOLOGY_H + +#include + +#endif /* _ASM_BLACKFIN_TOPOLOGY_H */ diff --git a/include/asm-blackfin/traps.h b/include/asm-blackfin/traps.h new file mode 100644 index 000000000000..fe365b1b7ca8 --- /dev/null +++ b/include/asm-blackfin/traps.h @@ -0,0 +1,75 @@ +/* + * linux/include/asm/traps.h + * + * Copyright (C) 1993 Hamish Macdonald + * + * Lineo, Inc Jul 2001 Tony Kou + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef _BFIN_TRAPS_H +#define _BFIN_TRAPS_H + +#define VEC_SYS (0) +#define VEC_EXCPT01 (1) +#define VEC_EXCPT02 (2) +#define VEC_EXCPT03 (3) +#define VEC_EXCPT04 (4) +#define VEC_EXCPT05 (5) +#define VEC_EXCPT06 (6) +#define VEC_EXCPT07 (7) +#define VEC_EXCPT08 (8) +#define VEC_EXCPT09 (9) +#define VEC_EXCPT10 (10) +#define VEC_EXCPT11 (11) +#define VEC_EXCPT12 (12) +#define VEC_EXCPT13 (13) +#define VEC_EXCPT14 (14) +#define VEC_EXCPT15 (15) +#define VEC_STEP (16) +#define VEC_OVFLOW (17) +#define VEC_UNDEF_I (33) +#define VEC_ILGAL_I (34) +#define VEC_CPLB_VL (35) +#define VEC_MISALI_D (36) +#define VEC_UNCOV (37) +#define VEC_CPLB_M (38) +#define VEC_CPLB_MHIT (39) +#define VEC_WATCH (40) +#define VEC_ISTRU_VL (41) /*ADSP-BF535 only (MH) */ +#define VEC_MISALI_I (42) +#define VEC_CPLB_I_VL (43) +#define VEC_CPLB_I_M (44) +#define VEC_CPLB_I_MHIT (45) +#define VEC_ILL_RES (46) /* including unvalid supervisor mode insn */ + +#ifndef __ASSEMBLY__ + +#define HWC_x2 "System MMR Error\nAn error occurred due to an invalid access to an System MMR location\nPossible reason: a 32-bit register is accessed with a 16-bit instruction,\nor a 16-bit register is accessed with a 32-bit instruction.\n" +#define HWC_x3 "External Memory Addressing Error\n" +#define HWC_x12 "Performance Monitor Overflow\n" +#define HWC_x18 "RAISE 5 instruction\n Software issued a RAISE 5 instruction to invoke the Hardware\n" +#define HWC_default "Reserved\n" + +#define EXC_0x03 "Application stack overflow\n - Please increase the stack size of the application using elf2flt -s option,\n and/or reduce the stack use of the application.\n" +#define EXC_0x10 "Single step\n - When the processor is in single step mode, every instruction\n generates an exception. Primarily used for debugging.\n" +#define EXC_0x11 "Exception caused by a trace buffer full condition\n - The processor takes this exception when the trace\n buffer overflows (only when enabled by the Trace Unit Control register).\n" +#define EXC_0x21 "Undefined instruction\n - May be used to emulate instructions that are not defined for\n a particular processor implementation.\n" +#define EXC_0x22 "Illegal instruction combination\n - See section for multi-issue rules in the ADSP-BF53x Blackfin\n Processor Instruction Set Reference.\n" +#define EXC_0x23 "Data access CPLB protection violation\n - Attempted read or write to Supervisor resource,\n or illegal data memory access. \n" +#define EXC_0x24 "Data access misaligned address violation\n - Attempted misaligned data memory or data cache access.\n" +#define EXC_0x25 "Unrecoverable event\n - For example, an exception generated while processing a previous exception.\n" +#define EXC_0x26 "Data access CPLB miss\n - Used by the MMU to signal a CPLB miss on a data access.\n" +#define EXC_0x27 "Data access multiple CPLB hits\n - More than one CPLB entry matches data fetch address.\n" +#define EXC_0x28 "Program Sequencer Exception caused by an emulation watchpoint match\n - There is a watchpoint match, and one of the EMUSW\n bits in the Watchpoint Instruction Address Control register (WPIACTL) is set.\n" +#define EXC_0x2A "Instruction fetch misaligned address violation\n - Attempted misaligned instruction cache fetch. On a misaligned instruction fetch exception,\n the return address provided in RETX is the destination address which is misaligned, rather than the address of the offending instruction.\n" +#define EXC_0x2B "CPLB protection violation\n - Illegal instruction fetch access (memory protection violation).\n" +#define EXC_0x2C "Instruction fetch CPLB miss\n - CPLB miss on an instruction fetch.\n" +#define EXC_0x2D "Instruction fetch multiple CPLB hits\n - More than one CPLB entry matches instruction fetch address.\n" +#define EXC_0x2E "Illegal use of supervisor resource\n - Attempted to use a Supervisor register or instruction from User mode.\n Supervisor resources are registers and instructions that are reserved\n for Supervisor use: Supervisor only registers, all MMRs, and Supervisor\n only instructions.\n" + +#endif /* __ASSEMBLY__ */ +#endif /* _BFIN_TRAPS_H */ diff --git a/include/asm-blackfin/types.h b/include/asm-blackfin/types.h new file mode 100644 index 000000000000..36f8dc8c52ba --- /dev/null +++ b/include/asm-blackfin/types.h @@ -0,0 +1,66 @@ +#ifndef _BFIN_TYPES_H +#define _BFIN_TYPES_H + +/* + * This file is never included by application software unless + * explicitly requested (e.g., via linux/types.h) in which case the + * application is Linux specific so (user-) name space pollution is + * not a major issue. However, for interoperability, libraries still + * need to be careful to avoid a name clashes. + */ +#ifndef __ASSEMBLY__ + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +/* HK0617 -- Changes to unsigned long temporarily */ +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +#endif /* __ASSEMBLY__ */ +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +#define BITS_PER_LONG 32 + +#ifndef __ASSEMBLY__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +/* Dma addresses are 32-bits wide. */ + +typedef u32 dma_addr_t; +typedef u64 dma64_addr_t; + +#endif /* __ASSEMBLY__ */ + +#endif /* __KERNEL__ */ + +#endif /* _BFIN_TYPES_H */ diff --git a/include/asm-blackfin/uaccess.h b/include/asm-blackfin/uaccess.h new file mode 100644 index 000000000000..bfcb6794c672 --- /dev/null +++ b/include/asm-blackfin/uaccess.h @@ -0,0 +1,271 @@ +/* Changes made by Lineo Inc. May 2001 + * + * Based on: include/asm-m68knommu/uaccess.h + */ + +#ifndef __BLACKFIN_UACCESS_H +#define __BLACKFIN_UACCESS_H + +/* + * User space memory access functions + */ +#include +#include +#include + +#include +#ifndef CONFIG_NO_ACCESS_CHECK +# include +#endif + +#define get_ds() (KERNEL_DS) +#define get_fs() (current_thread_info()->addr_limit) + +static inline void set_fs(mm_segment_t fs) +{ + current_thread_info()->addr_limit = fs; +} + +#define segment_eq(a,b) ((a) == (b)) + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +#define access_ok(type,addr,size) _access_ok((unsigned long)(addr),(size)) + +static inline int is_in_rom(unsigned long addr) +{ + /* + * What we are really trying to do is determine if addr is + * in an allocated kernel memory region. If not then assume + * we cannot free it or otherwise de-allocate it. Ideally + * we could restrict this to really being in a ROM or flash, + * but that would need to be done on a board by board basis, + * not globally. + */ + if ((addr < _ramstart) || (addr >= _ramend)) + return (1); + + /* Default case, not in ROM */ + return (0); +} + +/* + * The fs value determines whether argument validity checking should be + * performed or not. If get_fs() == USER_DS, checking is performed, with + * get_fs() == KERNEL_DS, checking is bypassed. + */ + +#ifdef CONFIG_NO_ACCESS_CHECK +static inline int _access_ok(unsigned long addr, unsigned long size) { return 1; } +#else +#ifdef CONFIG_ACCESS_OK_L1 +extern int _access_ok(unsigned long addr, unsigned long size)__attribute__((l1_text)); +#else +extern int _access_ok(unsigned long addr, unsigned long size); +#endif +#endif + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry { + unsigned long insn, fixup; +}; + +/* Returns 0 if exception not found and fixup otherwise. */ +extern unsigned long search_exception_table(unsigned long); + +/* + * These are the main single-value transfer routines. They automatically + * use the right size if we just have the right pointer type. + */ + +#define put_user(x,p) \ + ({ \ + int _err = 0; \ + typeof(*(p)) _x = (x); \ + typeof(*(p)) *_p = (p); \ + if (!access_ok(VERIFY_WRITE, _p, sizeof(*(_p)))) {\ + _err = -EFAULT; \ + } \ + else { \ + switch (sizeof (*(_p))) { \ + case 1: \ + __put_user_asm(_x, _p, B); \ + break; \ + case 2: \ + __put_user_asm(_x, _p, W); \ + break; \ + case 4: \ + __put_user_asm(_x, _p, ); \ + break; \ + case 8: { \ + long _xl, _xh; \ + _xl = ((long *)&_x)[0]; \ + _xh = ((long *)&_x)[1]; \ + __put_user_asm(_xl, ((long *)_p)+0, ); \ + __put_user_asm(_xh, ((long *)_p)+1, ); \ + } break; \ + default: \ + _err = __put_user_bad(); \ + break; \ + } \ + } \ + _err; \ + }) + +#define __put_user(x,p) put_user(x,p) +static inline int bad_user_access_length(void) +{ + panic("bad_user_access_length"); + return -1; +} + +#define __put_user_bad() (printk(KERN_INFO "put_user_bad %s:%d %s\n",\ + __FILE__, __LINE__, __FUNCTION__),\ + bad_user_access_length(), (-EFAULT)) + +/* + * Tell gcc we read from memory instead of writing: this is because + * we do not write to any memory gcc knows about, so there are no + * aliasing issues. + */ + +#define __ptr(x) ((unsigned long *)(x)) + +#define __put_user_asm(x,p,bhw) \ + __asm__ (#bhw"[%1] = %0;\n\t" \ + : /* no outputs */ \ + :"d" (x),"a" (__ptr(p)) : "memory") + +#define get_user(x,p) \ + ({ \ + int _err = 0; \ + typeof(*(p)) *_p = (p); \ + if (!access_ok(VERIFY_READ, _p, sizeof(*(_p)))) { \ + _err = -EFAULT; \ + } \ + else { \ + switch (sizeof(*(_p))) { \ + case 1: \ + __get_user_asm(x, _p, B,(Z)); \ + break; \ + case 2: \ + __get_user_asm(x, _p, W,(Z)); \ + break; \ + case 4: \ + __get_user_asm(x, _p, , ); \ + break; \ + case 8: { \ + unsigned long _xl, _xh; \ + __get_user_asm(_xl, ((unsigned long *)_p)+0, , ); \ + __get_user_asm(_xh, ((unsigned long *)_p)+1, , ); \ + ((unsigned long *)&x)[0] = _xl; \ + ((unsigned long *)&x)[1] = _xh; \ + } break; \ + default: \ + x = 0; \ + printk(KERN_INFO "get_user_bad: %s:%d %s\n", \ + __FILE__, __LINE__, __FUNCTION__); \ + _err = __get_user_bad(); \ + break; \ + } \ + } \ + _err; \ + }) + +#define __get_user(x,p) get_user(x,p) + +#define __get_user_bad() (bad_user_access_length(), (-EFAULT)) + +#define __get_user_asm(x,p,bhw,option) \ + { \ + unsigned long _tmp; \ + __asm__ ("%0 =" #bhw "[%1]"#option";\n\t" \ + : "=d" (_tmp) \ + : "a" (__ptr(p))); \ + (x) = (__typeof__(*(p))) _tmp; \ + } + +#define __copy_from_user(to, from, n) copy_from_user(to, from, n) +#define __copy_to_user(to, from, n) copy_to_user(to, from, n) +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + +#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n))\ + return retval; }) + +#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n))\ + return retval; }) + +static inline long copy_from_user(void *to, + const void __user * from, unsigned long n) +{ + if (access_ok(VERIFY_READ, from, n)) + memcpy(to, from, n); + else + return n; + return 0; +} + +static inline long copy_to_user(void *to, + const void __user * from, unsigned long n) +{ + if (access_ok(VERIFY_WRITE, to, n)) + memcpy(to, from, n); + else + return n; + return 0; +} + +/* + * Copy a null terminated string from userspace. + */ + +static inline long strncpy_from_user(char *dst, + const char *src, long count) +{ + char *tmp; + if (!access_ok(VERIFY_READ, src, 1)) + return -EFAULT; + strncpy(dst, src, count); + for (tmp = dst; *tmp && count > 0; tmp++, count--) ; + return (tmp - dst); +} + +/* + * Return the size of a string (including the ending 0) + * + * Return 0 on exception, a value greater than N if too long + */ +static inline long strnlen_user(const char *src, long n) +{ + return (strlen(src) + 1); +} + +#define strlen_user(str) strnlen_user(str, 32767) + +/* + * Zero Userspace + */ + +static inline unsigned long __clear_user(void *to, unsigned long n) +{ + memset(to, 0, n); + return 0; +} + +#define clear_user(to, n) __clear_user(to, n) + +#endif /* _BLACKFIN_UACCESS_H */ diff --git a/include/asm-blackfin/ucontext.h b/include/asm-blackfin/ucontext.h new file mode 100644 index 000000000000..4a4e3856beba --- /dev/null +++ b/include/asm-blackfin/ucontext.h @@ -0,0 +1,17 @@ +/** Changes made by Tony Kou Lineo Inc. May 2001 + * + * Based on: include/m68knommu/ucontext.h + */ + +#ifndef _BLACKFIN_UCONTEXT_H +#define _BLACKFIN_UCONTEXT_H + +struct ucontext { + unsigned long uc_flags; /* the others are necessary */ + struct ucontext *uc_link; + stack_t uc_stack; + struct sigcontext uc_mcontext; + sigset_t uc_sigmask; /* mask last for extensibility */ +}; + +#endif /* _BLACKFIN_UCONTEXT_H */ diff --git a/include/asm-blackfin/unaligned.h b/include/asm-blackfin/unaligned.h new file mode 100644 index 000000000000..10081dc241ef --- /dev/null +++ b/include/asm-blackfin/unaligned.h @@ -0,0 +1,6 @@ +#ifndef __BFIN_UNALIGNED_H +#define __BFIN_UNALIGNED_H + +#include + +#endif /* __BFIN_UNALIGNED_H */ diff --git a/include/asm-blackfin/unistd.h b/include/asm-blackfin/unistd.h new file mode 100644 index 000000000000..4df8790a67d5 --- /dev/null +++ b/include/asm-blackfin/unistd.h @@ -0,0 +1,382 @@ +#ifndef __ASM_BFIN_UNISTD_H +#define __ASM_BFIN_UNISTD_H +/* + * This file contains the system call numbers. + */ +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 + /* 7 __NR_waitpid obsolete */ +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 + /* 17 __NR_break obsolete */ + /* 18 __NR_oldstat obsolete */ +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 + /* 22 __NR_umount obsolete */ +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 + /* 28 __NR_oldfstat obsolete */ +#define __NR_pause 29 + /* 30 __NR_utime obsolete */ + /* 31 __NR_stty obsolete */ + /* 32 __NR_gtty obsolete */ +#define __NR_access 33 +#define __NR_nice 34 + /* 35 __NR_ftime obsolete */ +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 + /* 44 __NR_prof obsolete */ +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 + /* 48 __NR_signal obsolete */ +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_umount2 52 + /* 53 __NR_lock obsolete */ +#define __NR_ioctl 54 +#define __NR_fcntl 55 + /* 56 __NR_mpx obsolete */ +#define __NR_setpgid 57 + /* 58 __NR_ulimit obsolete */ + /* 59 __NR_oldolduname obsolete */ +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 + /* 67 __NR_sigaction obsolete */ +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 + /* 72 __NR_sigsuspend obsolete */ + /* 73 __NR_sigpending obsolete */ +#define __NR_sethostname 74 +#define __NR_setrlimit 75 + /* 76 __NR_old_getrlimit obsolete */ +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 + /* 82 __NR_select obsolete */ +#define __NR_symlink 83 + /* 84 __NR_oldlstat obsolete */ +#define __NR_readlink 85 + /* 86 __NR_uselib obsolete */ + /* 87 __NR_swapon obsolete */ +#define __NR_reboot 88 + /* 89 __NR_readdir obsolete */ + /* 90 __NR_mmap obsolete */ +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 + /* 98 __NR_profil obsolete */ +#define __NR_statfs 99 +#define __NR_fstatfs 100 + /* 101 __NR_ioperm */ + /* 102 __NR_socketcall obsolete */ +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 + /* 109 __NR_olduname obsolete */ + /* 110 __NR_iopl obsolete */ +#define __NR_vhangup 111 + /* 112 __NR_idle obsolete */ + /* 113 __NR_vm86old */ +#define __NR_wait4 114 + /* 115 __NR_swapoff obsolete */ +#define __NR_sysinfo 116 + /* 117 __NR_ipc oboslete */ +#define __NR_fsync 118 + /* 119 __NR_sigreturn obsolete */ +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 + /* 123 __NR_modify_ldt obsolete */ +#define __NR_adjtimex 124 +#define __NR_mprotect 125 + /* 126 __NR_sigprocmask obsolete */ + /* 127 __NR_create_module obsolete */ +#define __NR_init_module 128 +#define __NR_delete_module 129 + /* 130 __NR_get_kernel_syms obsolete */ +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 + /* 135 was sysfs */ +#define __NR_personality 136 + /* 137 __NR_afs_syscall */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 + /* 142 __NR__newselect obsolete */ +#define __NR_flock 143 + /* 144 __NR_msync obsolete */ +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 +#define __NR_fdatasync 148 +#define __NR__sysctl 149 + /* 150 __NR_mlock */ + /* 151 __NR_munlock */ + /* 152 __NR_mlockall */ + /* 153 __NR_munlockall */ +#define __NR_sched_setparam 154 +#define __NR_sched_getparam 155 +#define __NR_sched_setscheduler 156 +#define __NR_sched_getscheduler 157 +#define __NR_sched_yield 158 +#define __NR_sched_get_priority_max 159 +#define __NR_sched_get_priority_min 160 +#define __NR_sched_rr_get_interval 161 +#define __NR_nanosleep 162 + /* 163 __NR_mremap */ +#define __NR_setresuid 164 +#define __NR_getresuid 165 + /* 166 __NR_vm86 */ + /* 167 __NR_query_module */ + /* 168 __NR_poll */ + /* 169 __NR_nfsservctl */ +#define __NR_setresgid 170 +#define __NR_getresgid 171 +#define __NR_prctl 172 +#define __NR_rt_sigreturn 173 +#define __NR_rt_sigaction 174 +#define __NR_rt_sigprocmask 175 +#define __NR_rt_sigpending 176 +#define __NR_rt_sigtimedwait 177 +#define __NR_rt_sigqueueinfo 178 +#define __NR_rt_sigsuspend 179 +#define __NR_pread 180 +#define __NR_pwrite 181 +#define __NR_lchown 182 +#define __NR_getcwd 183 +#define __NR_capget 184 +#define __NR_capset 185 +#define __NR_sigaltstack 186 +#define __NR_sendfile 187 + /* 188 __NR_getpmsg */ + /* 189 __NR_putpmsg */ +#define __NR_vfork 190 +#define __NR_getrlimit 191 +#define __NR_mmap2 192 +#define __NR_truncate64 193 +#define __NR_ftruncate64 194 +#define __NR_stat64 195 +#define __NR_lstat64 196 +#define __NR_fstat64 197 +#define __NR_chown32 198 +#define __NR_getuid32 199 +#define __NR_getgid32 200 +#define __NR_geteuid32 201 +#define __NR_getegid32 202 +#define __NR_setreuid32 203 +#define __NR_setregid32 204 +#define __NR_getgroups32 205 +#define __NR_setgroups32 206 +#define __NR_fchown32 207 +#define __NR_setresuid32 208 +#define __NR_getresuid32 209 +#define __NR_setresgid32 210 +#define __NR_getresgid32 211 +#define __NR_lchown32 212 +#define __NR_setuid32 213 +#define __NR_setgid32 214 +#define __NR_setfsuid32 215 +#define __NR_setfsgid32 216 +#define __NR_pivot_root 217 + /* 218 __NR_mincore */ + /* 219 __NR_madvise */ +#define __NR_getdents64 220 +#define __NR_fcntl64 221 + /* 222 reserved for TUX */ + /* 223 reserved for TUX */ +#define __NR_gettid 224 + /* 225 __NR_readahead */ +#define __NR_setxattr 226 +#define __NR_lsetxattr 227 +#define __NR_fsetxattr 228 +#define __NR_getxattr 229 +#define __NR_lgetxattr 230 +#define __NR_fgetxattr 231 +#define __NR_listxattr 232 +#define __NR_llistxattr 233 +#define __NR_flistxattr 234 +#define __NR_removexattr 235 +#define __NR_lremovexattr 236 +#define __NR_fremovexattr 237 +#define __NR_tkill 238 +#define __NR_sendfile64 239 +#define __NR_futex 240 +#define __NR_sched_setaffinity 241 +#define __NR_sched_getaffinity 242 + /* 243 __NR_set_thread_area */ + /* 244 __NR_get_thread_area */ +#define __NR_io_setup 245 +#define __NR_io_destroy 246 +#define __NR_io_getevents 247 +#define __NR_io_submit 248 +#define __NR_io_cancel 249 + /* 250 __NR_alloc_hugepages */ + /* 251 __NR_free_hugepages */ +#define __NR_exit_group 252 +#define __NR_lookup_dcookie 253 +#define __NR_bfin_spinlock 254 + +#define __NR_epoll_create 255 +#define __NR_epoll_ctl 256 +#define __NR_epoll_wait 257 + /* 258 __NR_remap_file_pages */ +#define __NR_set_tid_address 259 +#define __NR_timer_create 260 +#define __NR_timer_settime (__NR_timer_create+1) +#define __NR_timer_gettime (__NR_timer_create+2) +#define __NR_timer_getoverrun (__NR_timer_create+3) +#define __NR_timer_delete (__NR_timer_create+4) +#define __NR_clock_settime (__NR_timer_create+5) +#define __NR_clock_gettime (__NR_timer_create+6) +#define __NR_clock_getres (__NR_timer_create+7) +#define __NR_clock_nanosleep (__NR_timer_create+8) +#define __NR_statfs64 269 +#define __NR_fstatfs64 270 +#define __NR_tgkill 271 +#define __NR_utimes 272 +#define __NR_fadvise64_64 273 + /* 274 __NR_vserver */ + /* 275 __NR_mbind */ + /* 276 __NR_get_mempolicy */ + /* 277 __NR_set_mempolicy */ +#define __NR_mq_open 278 +#define __NR_mq_unlink (__NR_mq_open+1) +#define __NR_mq_timedsend (__NR_mq_open+2) +#define __NR_mq_timedreceive (__NR_mq_open+3) +#define __NR_mq_notify (__NR_mq_open+4) +#define __NR_mq_getsetattr (__NR_mq_open+5) + /* 284 __NR_sys_kexec_load */ +#define __NR_waitid 285 +#define __NR_add_key 286 +#define __NR_request_key 287 +#define __NR_keyctl 288 +#define __NR_ioprio_set 289 +#define __NR_ioprio_get 290 +#define __NR_inotify_init 291 +#define __NR_inotify_add_watch 292 +#define __NR_inotify_rm_watch 293 + /* 294 __NR_migrate_pages */ +#define __NR_openat 295 +#define __NR_mkdirat 296 +#define __NR_mknodat 297 +#define __NR_fchownat 298 +#define __NR_futimesat 299 +#define __NR_fstatat64 300 +#define __NR_unlinkat 301 +#define __NR_renameat 302 +#define __NR_linkat 303 +#define __NR_symlinkat 304 +#define __NR_readlinkat 305 +#define __NR_fchmodat 306 +#define __NR_faccessat 307 +#define __NR_pselect6 308 +#define __NR_ppoll 309 +#define __NR_unshare 310 + +/* Blackfin private syscalls */ +#define __NR_sram_alloc 311 +#define __NR_sram_free 312 +#define __NR_dma_memcpy 313 + +/* socket syscalls */ +#define __NR_accept 314 +#define __NR_bind 315 +#define __NR_connect 316 +#define __NR_getpeername 317 +#define __NR_getsockname 318 +#define __NR_getsockopt 319 +#define __NR_listen 320 +#define __NR_recv 321 +#define __NR_recvfrom 322 +#define __NR_recvmsg 323 +#define __NR_send 324 +#define __NR_sendmsg 325 +#define __NR_sendto 326 +#define __NR_setsockopt 327 +#define __NR_shutdown 328 +#define __NR_socket 329 +#define __NR_socketpair 330 + +/* sysv ipc syscalls */ +#define __NR_semctl 331 +#define __NR_semget 332 +#define __NR_semop 333 +#define __NR_msgctl 334 +#define __NR_msgget 335 +#define __NR_msgrcv 336 +#define __NR_msgsnd 337 +#define __NR_shmat 338 +#define __NR_shmctl 339 +#define __NR_shmdt 340 +#define __NR_shmget 341 + +#define __NR_syscall 342 +#define NR_syscalls __NR_syscall + +#ifdef __KERNEL__ +#define __ARCH_WANT_IPC_PARSE_VERSION +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_ALARM +#define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_PAUSE +#define __ARCH_WANT_SYS_SGETMASK +#define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_SYS_FADVISE64 +#define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK +#define __ARCH_WANT_SYS_NICE +#define __ARCH_WANT_SYS_RT_SIGACTION +#define __ARCH_WANT_SYS_RT_SIGSUSPEND +#endif + +/* + * "Conditional" syscalls + * + * What we want is __attribute__((weak,alias("sys_ni_syscall"))), + * but it doesn't work on all toolchains, so we just do it by hand + */ +#define cond_syscall(x) asm(".weak\t_" #x "\n\t.set\t_" #x ",_sys_ni_syscall"); + +#endif /* __ASM_BFIN_UNISTD_H */ diff --git a/include/asm-blackfin/user.h b/include/asm-blackfin/user.h new file mode 100644 index 000000000000..abc34629bd59 --- /dev/null +++ b/include/asm-blackfin/user.h @@ -0,0 +1,89 @@ +#ifndef _BFIN_USER_H +#define _BFIN_USER_H + +/* Changes by Tony Kou Lineo, Inc. July, 2001 + * + * Based include/asm-m68knommu/user.h + * + */ + +/* Core file format: The core file is written in such a way that gdb + can understand it and provide useful information to the user (under + linux we use the 'trad-core' bfd). There are quite a number of + obstacles to being able to view the contents of the floating point + registers, and until these are solved you will not be able to view the + contents of them. Actually, you can read in the core file and look at + the contents of the user struct to find out what the floating point + registers contain. + The actual file contents are as follows: + UPAGE: 1 page consisting of a user struct that tells gdb what is present + in the file. Directly after this is a copy of the task_struct, which + is currently not used by gdb, but it may come in useful at some point. + All of the registers are stored as part of the upage. The upage should + always be only one page. + DATA: The data area is stored. We use current->end_text to + current->brk to pick up all of the user variables, plus any memory + that may have been malloced. No attempt is made to determine if a page + is demand-zero or if a page is totally unused, we just cover the entire + range. All of the addresses are rounded in such a way that an integral + number of pages is written. + STACK: We need the stack information in order to get a meaningful + backtrace. We need to write the data from (esp) to + current->start_stack, so we round each of these off in order to be able + to write an integer number of pages. + The minimum core file size is 3 pages, or 12288 bytes. +*/ +struct user_bfinfp_struct { +}; + +/* This is the old layout of "struct pt_regs" as of Linux 1.x, and + is still the layout used by user (the new pt_regs doesn't have + all registers). */ +struct user_regs_struct { + long r0, r1, r2, r3, r4, r5, r6, r7; + long p0, p1, p2, p3, p4, p5, usp, fp; + long i0, i1, i2, i3; + long l0, l1, l2, l3; + long b0, b1, b2, b3; + long m0, m1, m2, m3; + long a0w, a1w; + long a0x, a1x; + unsigned long rets; + unsigned long astat; + unsigned long pc; + unsigned long orig_p0; +}; + +/* When the kernel dumps core, it starts by dumping the user struct - + this will be used by gdb to figure out where the data and stack segments + are within the file, and what virtual addresses to use. */ + +struct user { +/* We start with the registers, to mimic the way that "memory" is returned + from the ptrace(3,...) function. */ + + struct user_regs_struct regs; /* Where the registers are actually stored */ + +/* The rest of this junk is to help gdb figure out what goes where */ + unsigned long int u_tsize; /* Text segment size (pages). */ + unsigned long int u_dsize; /* Data segment size (pages). */ + unsigned long int u_ssize; /* Stack segment size (pages). */ + unsigned long start_code; /* Starting virtual address of text. */ + unsigned long start_stack; /* Starting virtual address of stack area. + This is actually the bottom of the stack, + the top of the stack is always found in the + esp register. */ + long int signal; /* Signal that caused the core dump. */ + int reserved; /* No longer used */ + struct user_regs_struct *u_ar0; + /* Used by gdb to help find the values for */ + /* the registers. */ + unsigned long magic; /* To uniquely identify a core file */ + char u_comm[32]; /* User command that was responsible */ +}; +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#endif diff --git a/include/linux/elf-em.h b/include/linux/elf-em.h index 666e0a5f00fc..0311bad838b1 100644 --- a/include/linux/elf-em.h +++ b/include/linux/elf-em.h @@ -30,6 +30,7 @@ #define EM_V850 87 /* NEC v850 */ #define EM_M32R 88 /* Renesas M32R */ #define EM_H8_300 46 /* Renesas H8/300,300H,H8S */ +#define EM_BLACKFIN 106 /* ADI Blackfin Processor */ #define EM_FRV 0x5441 /* Fujitsu FR-V */ #define EM_AVR32 0x18ad /* Atmel AVR32 */ diff --git a/include/linux/spi/ad7877.h b/include/linux/spi/ad7877.h new file mode 100644 index 000000000000..cdbed816f25e --- /dev/null +++ b/include/linux/spi/ad7877.h @@ -0,0 +1,24 @@ +/* linux/spi/ad7877.h */ + +/* Touchscreen characteristics vary between boards and models. The + * platform_data for the device's "struct device" holds this information. + * + * It's OK if the min/max values are zero. + */ +struct ad7877_platform_data { + u16 model; /* 7877 */ + u16 vref_delay_usecs; /* 0 for external vref; etc */ + u16 x_plate_ohms; + u16 y_plate_ohms; + + u16 x_min, x_max; + u16 y_min, y_max; + u16 pressure_min, pressure_max; + + u8 stopacq_polarity; /* 1 = Active HIGH, 0 = Active LOW */ + u8 first_conversion_delay; /* 0 = 0.5us, 1 = 128us, 2 = 1ms, 3 = 8ms */ + u8 acquisition_time; /* 0 = 2us, 1 = 4us, 2 = 8us, 3 = 16us */ + u8 averaging; /* 0 = 1, 1 = 4, 2 = 8, 3 = 16 */ + u8 pen_down_acc_interval; /* 0 = covert once, 1 = every 0.5 ms, + 2 = ever 1 ms, 3 = every 8 ms,*/ +}; diff --git a/include/linux/usb_sl811.h b/include/linux/usb_sl811.h new file mode 100644 index 000000000000..4f2d012d7309 --- /dev/null +++ b/include/linux/usb_sl811.h @@ -0,0 +1,26 @@ + +/* + * board initialization should put one of these into dev->platform_data + * and place the sl811hs onto platform_bus named "sl811-hcd". + */ + +struct sl811_platform_data { + unsigned can_wakeup:1; + + /* given port_power, msec/2 after power on till power good */ + u8 potpg; + + /* mA/2 power supplied on this port (max = default = 250) */ + u8 power; + + /* sl811 relies on an external source of VBUS current */ + void (*port_power)(struct device *dev, int is_on); + + /* pulse sl811 nRST (probably with a GPIO) */ + void (*reset)(struct device *dev); + + // some boards need something like these: + // int (*check_overcurrent)(struct device *dev); + // void (*clock_enable)(struct device *dev, int is_on); +}; + diff --git a/init/Kconfig b/init/Kconfig index 7ce952052947..ebe04f56d834 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -356,7 +356,7 @@ menuconfig EMBEDDED config UID16 bool "Enable 16-bit UID system calls" if EMBEDDED - depends on ARM || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && SPARC32_COMPAT) || UML || (X86_64 && IA32_EMULATION) + depends on ARM || BFIN || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && SPARC32_COMPAT) || UML || (X86_64 && IA32_EMULATION) default y help This enables the legacy 16-bit UID syscall wrappers. diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index bdbf3fe14de6..9a287796da8e 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -320,7 +320,7 @@ config DEBUG_HIGHMEM config DEBUG_BUGVERBOSE bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED depends on BUG - depends on ARM || ARM26 || AVR32 || M32R || M68K || SPARC32 || SPARC64 || FRV || SUPERH || GENERIC_BUG + depends on ARM || ARM26 || AVR32 || M32R || M68K || SPARC32 || SPARC64 || FRV || SUPERH || GENERIC_BUG || BFIN default !EMBEDDED help Say Y here to make BUG() panics output the file name and line number @@ -360,7 +360,7 @@ config DEBUG_LIST config FRAME_POINTER bool "Compile the kernel with frame pointers" - depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH) + depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH || BFIN) default y if DEBUG_INFO && UML help If you say Y here the resulting kernel image will be slightly larger diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index b0381823e404..511023b430a8 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c @@ -516,7 +516,8 @@ int main(int argc, char **argv) genksyms_usage(); return 1; } - if ((strcmp(arch, "v850") == 0) || (strcmp(arch, "h8300") == 0)) + if ((strcmp(arch, "v850") == 0) || (strcmp(arch, "h8300") == 0) + || (strcmp(arch, "blackfin") == 0)) mod_prefix = "_"; { extern int yydebug; diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c index 725d61c0fb43..db3881f14c2d 100644 --- a/scripts/mod/mk_elfconfig.c +++ b/scripts/mod/mk_elfconfig.c @@ -55,7 +55,8 @@ main(int argc, char **argv) else exit(1); - if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0)) + if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0) + || (strcmp(argv[1], "blackfin") == 0)) printf("#define MODULE_SYMBOL_PREFIX \"_\"\n"); else printf("#define MODULE_SYMBOL_PREFIX \"\"\n"); -- cgit v1.2.3-59-g8ed1b From aeecf3142d82414d511135cc85f86caddfb58338 Mon Sep 17 00:00:00 2001 From: john stultz Date: Sun, 6 May 2007 14:50:34 -0700 Subject: Convert h8/300 to generic timekeeping Currently h8/300 does not implement sub-jiffy timekeeping, so there is no benefit to having arch specific timekeeping code. This patch simply removes those functions and enables the generic timekeeping code. Signed-off-by: John Stultz Acked-by: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/h8300/Kconfig | 4 ++++ arch/h8300/kernel/time.c | 52 ------------------------------------------------ 2 files changed, 4 insertions(+), 52 deletions(-) (limited to 'arch') diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 1734d96422c6..86f6ca36363f 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -53,6 +53,10 @@ config GENERIC_CALIBRATE_DELAY bool default y +config GENERIC_TIME + bool + default y + config TIME_LOW_RES bool default y diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c index d1ef615ba895..91d3b56ddc68 100644 --- a/arch/h8300/kernel/time.c +++ b/arch/h8300/kernel/time.c @@ -66,55 +66,3 @@ void time_init(void) platform_timer_setup(timer_interrupt); } - -/* - * This version of gettimeofday has near microsecond resolution. - */ -void do_gettimeofday(struct timeval *tv) -{ - unsigned long flags; - unsigned long usec, sec; - - read_lock_irqsave(&xtime_lock, flags); - usec = 0; - sec = xtime.tv_sec; - usec += (xtime.tv_nsec / 1000); - read_unlock_irqrestore(&xtime_lock, flags); - - while (usec >= 1000000) { - usec -= 1000000; - sec++; - } - - tv->tv_sec = sec; - tv->tv_usec = usec; -} - -EXPORT_SYMBOL(do_gettimeofday); - -int do_settimeofday(struct timespec *tv) -{ - if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) - return -EINVAL; - - write_lock_irq(&xtime_lock); - /* This is revolting. We need to set the xtime.tv_usec - * correctly. However, the value in this location is - * is value at the last tick. - * Discover what correction gettimeofday - * would have done, and then undo it! - */ - while (tv->tv_nsec < 0) { - tv->tv_nsec += NSEC_PER_SEC; - tv->tv_sec--; - } - - xtime.tv_sec = tv->tv_sec; - xtime.tv_nsec = tv->tv_nsec; - ntp_clear(); - write_sequnlock_irq(&xtime_lock); - clock_was_set(); - return 0; -} - -EXPORT_SYMBOL(do_settimeofday); -- cgit v1.2.3-59-g8ed1b From c728d60455e8e8722ee08312a75f38dd7a866b5e Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Sun, 6 May 2007 14:50:35 -0700 Subject: h8300 generic irq h8300 using generic irq handler patch. Signed-off-by: Yoshinori Sato Cc: Thomas Gleixner Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/h8300/Kconfig | 4 + arch/h8300/Makefile | 2 +- arch/h8300/kernel/Makefile | 6 +- arch/h8300/kernel/irq.c | 211 ++++++++++++++++++++++++++++ arch/h8300/kernel/setup.c | 3 - arch/h8300/kernel/time.c | 2 +- arch/h8300/mm/kmap.c | 4 +- arch/h8300/platform/h8300h/Makefile | 2 +- arch/h8300/platform/h8300h/entry.S | 4 +- arch/h8300/platform/h8300h/generic/Makefile | 2 +- arch/h8300/platform/h8300h/ints_h8300h.c | 85 ----------- arch/h8300/platform/h8s/entry.S | 17 +-- include/asm-h8300/irq.h | 1 - include/asm-h8300/irq_regs.h | 1 + include/asm-h8300/pgtable.h | 1 + 15 files changed, 237 insertions(+), 108 deletions(-) create mode 100644 arch/h8300/kernel/irq.c delete mode 100644 arch/h8300/platform/h8300h/ints_h8300h.c create mode 100644 include/asm-h8300/irq_regs.h (limited to 'arch') diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 86f6ca36363f..618dbad696f6 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -49,6 +49,10 @@ config GENERIC_HWEIGHT bool default y +config GENERIC_HARDIRQS + bool + default y + config GENERIC_CALIBRATE_DELAY bool default y diff --git a/arch/h8300/Makefile b/arch/h8300/Makefile index 40b3f56f3666..b2d896a7e598 100644 --- a/arch/h8300/Makefile +++ b/arch/h8300/Makefile @@ -41,7 +41,7 @@ LDFLAGS += $(ldflags-y) CROSS_COMPILE = h8300-elf- LIBGCC := $(shell $(CROSS-COMPILE)$(CC) $(CFLAGS) -print-libgcc-file-name) -head-y := arch/$(ARCH)/platform/$(platform-y)/$(board-y)/crt0_$(model-y).o +head-y := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o core-y += arch/$(ARCH)/kernel/ \ arch/$(ARCH)/mm/ diff --git a/arch/h8300/kernel/Makefile b/arch/h8300/kernel/Makefile index 4edbc2ef6ca2..ccc1a7fbf94b 100644 --- a/arch/h8300/kernel/Makefile +++ b/arch/h8300/kernel/Makefile @@ -4,10 +4,8 @@ extra-y := vmlinux.lds -obj-y := process.o traps.o ptrace.o ints.o \ +obj-y := process.o traps.o ptrace.o irq.o \ sys_h8300.o time.o semaphore.o signal.o \ - setup.o gpio.o init_task.o syscalls.o devres.o - -devres-y = ../../../kernel/irq/devres.o + setup.o gpio.o init_task.o syscalls.o obj-$(CONFIG_MODULES) += module.o h8300_ksyms.o diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c new file mode 100644 index 000000000000..43d21e93f41f --- /dev/null +++ b/arch/h8300/kernel/irq.c @@ -0,0 +1,211 @@ +/* + * linux/arch/h8300/kernel/irq.c + * + * Copyright 2007 Yoshinori Sato + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/*#define DEBUG*/ + +extern unsigned long *interrupt_redirect_table; +extern const int h8300_saved_vectors[]; +extern const unsigned long h8300_trap_table[]; +int h8300_enable_irq_pin(unsigned int irq); +void h8300_disable_irq_pin(unsigned int irq); + +#define CPU_VECTOR ((unsigned long *)0x000000) +#define ADDR_MASK (0xffffff) + +static inline int is_ext_irq(unsigned int irq) +{ + return (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS)); +} + +static void h8300_enable_irq(unsigned int irq) +{ + if (is_ext_irq(irq)) + IER_REGS |= 1 << (irq - EXT_IRQ0); +} + +static void h8300_disable_irq(unsigned int irq) +{ + if (is_ext_irq(irq)) + IER_REGS &= ~(1 << (irq - EXT_IRQ0)); +} + +static void h8300_end_irq(unsigned int irq) +{ +} + +static unsigned int h8300_startup_irq(unsigned int irq) +{ + if (is_ext_irq(irq)) + return h8300_enable_irq_pin(irq); + else + return 0; +} + +static void h8300_shutdown_irq(unsigned int irq) +{ + if (is_ext_irq(irq)) + h8300_disable_irq_pin(irq); +} + +/* + * h8300 interrupt controler implementation + */ +struct irq_chip h8300irq_chip = { + .name = "H8300-INTC", + .startup = h8300_startup_irq, + .shutdown = h8300_shutdown_irq, + .enable = h8300_enable_irq, + .disable = h8300_disable_irq, + .ack = NULL, + .end = h8300_end_irq, +}; + +void ack_bad_irq(unsigned int irq) +{ + printk("unexpected IRQ trap at vector %02x\n", irq); +} + +#if defined(CONFIG_RAMKERNEL) +static unsigned long __init *get_vector_address(void) +{ + unsigned long *rom_vector = CPU_VECTOR; + unsigned long base,tmp; + int vec_no; + + base = rom_vector[EXT_IRQ0] & ADDR_MASK; + + /* check romvector format */ + for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ0+EXT_IRQS; vec_no++) { + if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK)) + return NULL; + } + + /* ramvector base address */ + base -= EXT_IRQ0*4; + + /* writerble check */ + tmp = ~(*(volatile unsigned long *)base); + (*(volatile unsigned long *)base) = tmp; + if ((*(volatile unsigned long *)base) != tmp) + return NULL; + return (unsigned long *)base; +} + +static void __init setup_vector(void) +{ + int i; + unsigned long *ramvec,*ramvec_p; + const unsigned long *trap_entry; + const int *saved_vector; + + ramvec = get_vector_address(); + if (ramvec == NULL) + panic("interrupt vector serup failed."); + else + printk(KERN_INFO "virtual vector at 0x%08lx\n",(unsigned long)ramvec); + + /* create redirect table */ + ramvec_p = ramvec; + trap_entry = h8300_trap_table; + saved_vector = h8300_saved_vectors; + for ( i = 0; i < NR_IRQS; i++) { + if (i == *saved_vector) { + ramvec_p++; + saved_vector++; + } else { + if ( i < NR_TRAPS ) { + if (*trap_entry) + *ramvec_p = VECTOR(*trap_entry); + ramvec_p++; + trap_entry++; + } else + *ramvec_p++ = REDIRECT(interrupt_entry); + } + } + interrupt_redirect_table = ramvec; +#ifdef DEBUG + ramvec_p = ramvec; + for (i = 0; i < NR_IRQS; i++) { + if ((i % 8) == 0) + printk(KERN_DEBUG "\n%p: ",ramvec_p); + printk(KERN_DEBUG "%p ",*ramvec_p); + ramvec_p++; + } + printk(KERN_DEBUG "\n"); +#endif +} +#else +#define setup_vector() do { } while(0) +#endif + +void __init init_IRQ(void) +{ + int c; + + setup_vector(); + + for (c = 0; c < NR_IRQS; c++) { + irq_desc[c].status = IRQ_DISABLED; + irq_desc[c].action = NULL; + irq_desc[c].depth = 1; + irq_desc[c].chip = &h8300irq_chip; + } +} + +asmlinkage void do_IRQ(int irq) +{ + irq_enter(); + __do_IRQ(irq); + irq_exit(); +} + +#if defined(CONFIG_PROC_FS) +int show_interrupts(struct seq_file *p, void *v) +{ + int i = *(loff_t *) v, j; + struct irqaction * action; + unsigned long flags; + + if (i == 0) + seq_puts(p, " CPU0"); + + if (i < NR_IRQS) { + spin_lock_irqsave(&irq_desc[i].lock, flags); + action = irq_desc[i].action; + if (!action) + goto unlock; + seq_printf(p, "%3d: ",i); + seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); + seq_printf(p, " %14s", irq_desc[i].chip->name); + seq_printf(p, "-%-8s", irq_desc[i].name); + seq_printf(p, " %s", action->name); + + for (action=action->next; action; action = action->next) + seq_printf(p, ", %s", action->name); + seq_putc(p, '\n'); +unlock: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); + } + return 0; +} +#endif diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c index 313cd8081044..b2e86d0255e6 100644 --- a/arch/h8300/kernel/setup.c +++ b/arch/h8300/kernel/setup.c @@ -33,10 +33,7 @@ #include #include - -#ifdef CONFIG_BLK_DEV_INITRD #include -#endif #if defined(__H8300H__) #define CPU "H8/300H" diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c index 91d3b56ddc68..330638220a2e 100644 --- a/arch/h8300/kernel/time.c +++ b/arch/h8300/kernel/time.c @@ -44,7 +44,7 @@ static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs) #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif - profile_tick(CPU_PROFILING, regs); + profile_tick(CPU_PROFILING); } void time_init(void) diff --git a/arch/h8300/mm/kmap.c b/arch/h8300/mm/kmap.c index 26ab17286a53..5c7af09ae8d1 100644 --- a/arch/h8300/mm/kmap.c +++ b/arch/h8300/mm/kmap.c @@ -24,12 +24,14 @@ #undef DEBUG +#define VIRT_OFFSET (0x01000000) + /* * Map some physical address range into the kernel address space. */ void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) { - return (void *)physaddr; + return (void *)(physaddr + VIRT_OFFSET); } /* diff --git a/arch/h8300/platform/h8300h/Makefile b/arch/h8300/platform/h8300h/Makefile index 5d42c772f75a..b24ea08aa0a7 100644 --- a/arch/h8300/platform/h8300h/Makefile +++ b/arch/h8300/platform/h8300h/Makefile @@ -4,4 +4,4 @@ # Reuse any files we can from the H8/300H # -obj-y := entry.o ints_h8300h.o ptrace_h8300h.o +obj-y := entry.o irq_pin.o ptrace_h8300h.o diff --git a/arch/h8300/platform/h8300h/entry.S b/arch/h8300/platform/h8300h/entry.S index d2dea2432fb2..f86ac3b5d4de 100644 --- a/arch/h8300/platform/h8300h/entry.S +++ b/arch/h8300/platform/h8300h/entry.S @@ -30,12 +30,12 @@ mov.l er0,@-sp stc ccr,r0l /* check kernel mode */ - orc #0x10,ccr btst #4,r0l bne 5f mov.l sp,@SYMBOL_NAME(sw_usp) /* user mode */ mov.l @sp,er0 + orc #0x10,ccr mov.l @SYMBOL_NAME(sw_ksp),sp sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */ mov.l er0,@-sp @@ -165,7 +165,7 @@ SYMBOL_NAME_LABEL(interrupt_entry) dec.l #1,er0 mov.l sp,er1 subs #4,er1 /* adjust ret_pc */ - jsr @SYMBOL_NAME(process_int) + jsr @SYMBOL_NAME(do_IRQ) mov.l @SYMBOL_NAME(irq_stat)+CPUSTAT_SOFTIRQ_PENDING,er0 beq 1f jsr @SYMBOL_NAME(do_softirq) diff --git a/arch/h8300/platform/h8300h/generic/Makefile b/arch/h8300/platform/h8300h/generic/Makefile index b6ea7688a616..32b964a9010e 100644 --- a/arch/h8300/platform/h8300h/generic/Makefile +++ b/arch/h8300/platform/h8300h/generic/Makefile @@ -2,5 +2,5 @@ # Makefile for the linux kernel. # +extra-y := crt0_$(MODEL).o obj-y := timer.o -extra-y = crt0_$(MODEL).o diff --git a/arch/h8300/platform/h8300h/ints_h8300h.c b/arch/h8300/platform/h8300h/ints_h8300h.c deleted file mode 100644 index f1777119b871..000000000000 --- a/arch/h8300/platform/h8300h/ints_h8300h.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * linux/arch/h8300/platform/h8300h/ints_h8300h.c - * Interrupt handling CPU variants - * - * Yoshinori Sato - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -/* saved vector list */ -const int __initdata h8300_saved_vectors[]={ -#if defined(CONFIG_GDB_DEBUG) - TRAP3_VEC, -#endif - -1 -}; - -/* trap entry table */ -const unsigned long __initdata h8300_trap_table[NR_TRAPS]={ - 0,0,0,0,0,0,0,0, - (unsigned long)system_call, /* TRAPA #0 */ - 0,0, - (unsigned long)trace_break, /* TRAPA #3 */ -}; - -int h8300_enable_irq_pin(unsigned int irq) -{ - int bitmask; - if (irq < EXT_IRQ0 || irq > EXT_IRQ5) - return 0; - - /* initialize IRQ pin */ - bitmask = 1 << (irq - EXT_IRQ0); - switch(irq) { - case EXT_IRQ0: - case EXT_IRQ1: - case EXT_IRQ2: - case EXT_IRQ3: - if (H8300_GPIO_RESERVE(H8300_GPIO_P8, bitmask) == 0) - return -EBUSY; - H8300_GPIO_DDR(H8300_GPIO_P8, bitmask, H8300_GPIO_INPUT); - break; - case EXT_IRQ4: - case EXT_IRQ5: - if (H8300_GPIO_RESERVE(H8300_GPIO_P9, bitmask) == 0) - return -EBUSY; - H8300_GPIO_DDR(H8300_GPIO_P9, bitmask, H8300_GPIO_INPUT); - break; - } - - return 0; -} - -void h8300_disable_irq_pin(unsigned int irq) -{ - int bitmask; - if (irq < EXT_IRQ0 || irq > EXT_IRQ5) - return; - - /* disable interrupt & release IRQ pin */ - bitmask = 1 << (irq - EXT_IRQ0); - switch(irq) { - case EXT_IRQ0: - case EXT_IRQ1: - case EXT_IRQ2: - case EXT_IRQ3: - *(volatile unsigned char *)IER &= ~bitmask; - H8300_GPIO_FREE(H8300_GPIO_P8, bitmask); - break ; - case EXT_IRQ4: - case EXT_IRQ5: - *(volatile unsigned char *)IER &= ~bitmask; - H8300_GPIO_FREE(H8300_GPIO_P9, bitmask); - break; - } -} diff --git a/arch/h8300/platform/h8s/entry.S b/arch/h8300/platform/h8s/entry.S index aeb2e9faa9b2..f3d6b8e8f959 100644 --- a/arch/h8300/platform/h8s/entry.S +++ b/arch/h8300/platform/h8s/entry.S @@ -31,12 +31,13 @@ mov.l er0,@-sp stc ccr,r0l /* check kernel mode */ - orc #0x10,ccr btst #4,r0l bne 5f - mov.l sp,@SYMBOL_NAME(sw_usp) /* user mode */ - mov.l @sp,er0 + /* user mode */ + mov.l sp,@SYMBOL_NAME(sw_usp) + mov.l @sp,er0 /* restore saved er0 */ + orc #0x10,ccr /* switch kernel stack */ mov.l @SYMBOL_NAME(sw_ksp),sp sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */ stm.l er0-er3,@-sp @@ -55,8 +56,9 @@ mov.l er0,@(LER0-LER3:16,sp) /* copy ER0 */ bra 6f 5: - mov.l @sp,er0 /* kernel mode */ - subs #2,sp /* dummy ccr */ + /* kernel mode */ + mov.l @sp,er0 /* restore saved er0 */ + subs #2,sp /* set dummy ccr */ stm.l er0-er3,@-sp mov.w @(LRET-LER3:16,sp),r1 /* copy old ccr */ mov.b r1h,r1l @@ -94,6 +96,7 @@ mov.l @sp+,er1 add.l #(LRET-LER1),sp /* remove LORIG - LRET */ mov.l sp,@SYMBOL_NAME(sw_ksp) + andc #0xef,ccr /* switch to user mode */ mov.l er0,sp bra 8f 7: @@ -173,9 +176,6 @@ SYMBOL_NAME_LABEL(interrupt_entry) SYMBOL_NAME_LABEL(system_call) subs #4,sp /* dummy LVEC */ SAVE_ALL - mov.w @(LCCR:16,sp),r1 - bset #4,r1l - ldc r1l,ccr /* restore ccr */ mov.l er0,er4 mov.l #-ENOSYS,er0 mov.l er0,@(LER0:16,sp) @@ -198,6 +198,7 @@ SYMBOL_NAME_LABEL(system_call) mov.l @(LER1:16,sp),er0 mov.l @(LER2:16,sp),er1 mov.l @(LER3:16,sp),er2 + andc #0x7f,ccr jsr @er4 mov.l er0,@(LER0:16,sp) /* save the return value */ #if defined(CONFIG_SYSCALL_PRINT) diff --git a/include/asm-h8300/irq.h b/include/asm-h8300/irq.h index 42a3ac424a9e..41be646c3514 100644 --- a/include/asm-h8300/irq.h +++ b/include/asm-h8300/irq.h @@ -61,6 +61,5 @@ static __inline__ int irq_canonicalize(int irq) extern void enable_irq(unsigned int); extern void disable_irq(unsigned int); -#define disable_irq_nosync(x) disable_irq(x) #endif /* _H8300_IRQ_H_ */ diff --git a/include/asm-h8300/irq_regs.h b/include/asm-h8300/irq_regs.h new file mode 100644 index 000000000000..3dd9c0b70270 --- /dev/null +++ b/include/asm-h8300/irq_regs.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-h8300/pgtable.h b/include/asm-h8300/pgtable.h index 8b7c6857998b..ddd07f485dd8 100644 --- a/include/asm-h8300/pgtable.h +++ b/include/asm-h8300/pgtable.h @@ -73,4 +73,5 @@ extern int is_in_rom(unsigned long); #define VMALLOC_START 0 #define VMALLOC_END 0xffffffff +#define arch_enter_lazy_cpu_mode() do {} while (0) #endif /* _H8300_PGTABLE_H */ -- cgit v1.2.3-59-g8ed1b From 97a572b3b877173e284c687be34d8ae81b826160 Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Sun, 6 May 2007 14:50:36 -0700 Subject: h8300: add zImage support h8300 zImage target support. Signed-off-by: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/h8300/boot/Makefile | 12 +- arch/h8300/boot/compressed/Makefile | 37 ++++++ arch/h8300/boot/compressed/head.S | 47 ++++++++ arch/h8300/boot/compressed/misc.c | 219 ++++++++++++++++++++++++++++++++++++ 4 files changed, 314 insertions(+), 1 deletion(-) create mode 100644 arch/h8300/boot/compressed/Makefile create mode 100644 arch/h8300/boot/compressed/head.S create mode 100644 arch/h8300/boot/compressed/misc.c (limited to 'arch') diff --git a/arch/h8300/boot/Makefile b/arch/h8300/boot/Makefile index 65086d925ca7..0bb62e064eea 100644 --- a/arch/h8300/boot/Makefile +++ b/arch/h8300/boot/Makefile @@ -1,12 +1,22 @@ # arch/h8300/boot/Makefile -targets := vmlinux.srec vmlinux.bin +targets := vmlinux.srec vmlinux.bin zImage +subdir- := compressed OBJCOPYFLAGS_vmlinux.srec := -Osrec OBJCOPYFLAGS_vmlinux.bin := -Obinary +OBJCOPYFLAGS_zImage := -O binary -R .note -R .comment -R .stab -R .stabstr -S $(obj)/vmlinux.srec $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) @echo ' Kernel: $@ is ready' +$(obj)/zImage: $(obj)/compressed/vmlinux FORCE + $(call if_changed,objcopy) + @echo 'Kernel: $@ is ready' + +$(obj)/compressed/vmlinux: FORCE + $(Q)$(MAKE) $(build)=$(obj)/compressed $@ + CLEAN_FILES += arch/$(ARCH)/vmlinux.bin arch/$(ARCH)/vmlinux.srec + diff --git a/arch/h8300/boot/compressed/Makefile b/arch/h8300/boot/compressed/Makefile new file mode 100644 index 000000000000..71aac82a8ae0 --- /dev/null +++ b/arch/h8300/boot/compressed/Makefile @@ -0,0 +1,37 @@ +# +# linux/arch/sh/boot/compressed/Makefile +# +# create a compressed vmlinux image from the original vmlinux +# + +targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o +EXTRA_AFLAGS := -traditional + +OBJECTS = $(obj)/head.o $(obj)/misc.o + +# +# IMAGE_OFFSET is the load offset of the compression loader +# Assign dummy values if these 2 variables are not defined, +# in order to suppress error message. +# +CONFIG_MEMORY_START ?= 0x00400000 +CONFIG_BOOT_LINK_OFFSET ?= 0x00400000 +IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET)]) + +LDFLAGS_vmlinux := -T $(obj)/vmlinux.lds + +$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE + $(call if_changed,ld) + @: + +$(obj)/vmlinux.bin: vmlinux FORCE + $(call if_changed,objcopy) + +$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE + $(call if_changed,gzip) + +LDFLAGS_piggy.o := -r --format binary --oformat elf32-h8300 -T +OBJCOPYFLAGS := -O binary + +$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE + $(call if_changed,ld) diff --git a/arch/h8300/boot/compressed/head.S b/arch/h8300/boot/compressed/head.S new file mode 100644 index 000000000000..b8e90d12d19e --- /dev/null +++ b/arch/h8300/boot/compressed/head.S @@ -0,0 +1,47 @@ +/* + * linux/arch/h8300/boot/compressed/head.S + * + * Copyright (C) 2006 Yoshinori Sato + */ + +.h8300h +#include + +#define SRAM_START 0xff4000 + + .section .text.startup + .global startup +startup: + mov.l #SRAM_START+0x8000, sp + mov.l #__sbss, er0 + mov.l #__ebss, er1 + sub.l er0, er1 + shlr er1 + shlr er1 + sub.l er2, er2 +1: + mov.l er2, @er0 + adds #4, er0 + dec.l #1, er1 + bne 1b + jsr @_decompress_kernel + jmp @0x400000 + + .align 9 +fake_headers_as_bzImage: + .word 0 + .ascii "HdrS" ; header signature + .word 0x0202 ; header version number (>= 0x0105) + ; or else old loadlin-1.5 will fail) + .word 0 ; default_switch + .word 0 ; SETUPSEG + .word 0x1000 + .word 0 ; pointing to kernel version string + .byte 0 ; = 0, old one (LILO, Loadlin, + ; 0xTV: T=0 for LILO + ; V = version + .byte 1 ; Load flags bzImage=1 + .word 0x8000 ; size to move, when setup is not + .long 0x100000 ; 0x100000 = default for big kernel + .long 0 ; address of loaded ramdisk image + .long 0 ; its size in bytes diff --git a/arch/h8300/boot/compressed/misc.c b/arch/h8300/boot/compressed/misc.c new file mode 100644 index 000000000000..845074588af0 --- /dev/null +++ b/arch/h8300/boot/compressed/misc.c @@ -0,0 +1,219 @@ +/* + * arch/h8300/boot/compressed/misc.c + * + * This is a collection of several routines from gzip-1.0.3 + * adapted for Linux. + * + * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 + * + * Adapted for h8300 by Yoshinori Sato 2006 + */ + +#include + +/* + * gzip declarations + */ + +#define OF(args) args +#define STATIC static + +#undef memset +#undef memcpy +#define memzero(s, n) memset ((s), 0, (n)) + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +#define WSIZE 0x8000 /* Window size must be at least 32k, */ + /* and a power of two */ + +static uch *inbuf; /* input buffer */ +static uch window[WSIZE]; /* Sliding window buffer */ + +static unsigned insize = 0; /* valid bytes in inbuf */ +static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ +static unsigned outcnt = 0; /* bytes in output buffer */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ +#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ +#define RESERVED 0xC0 /* bit 6,7: reserved */ + +#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) + +/* Diagnostic functions */ +#ifdef DEBUG +# define Assert(cond,msg) {if(!(cond)) error(msg);} +# define Trace(x) fprintf x +# define Tracev(x) {if (verbose) fprintf x ;} +# define Tracevv(x) {if (verbose>1) fprintf x ;} +# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} +# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +static int fill_inbuf(void); +static void flush_window(void); +static void error(char *m); +static void gzip_mark(void **); +static void gzip_release(void **); + +extern char input_data[]; +extern int input_len; + +static long bytes_out = 0; +static uch *output_data; +static unsigned long output_ptr = 0; + +static void *malloc(int size); +static void free(void *where); +static void error(char *m); +static void gzip_mark(void **); +static void gzip_release(void **); + +int puts(const char *); + +extern int _text; /* Defined in vmlinux.lds.S */ +extern int _end; +static unsigned long free_mem_ptr; +static unsigned long free_mem_end_ptr; + +#define HEAP_SIZE 0x10000 + +#include "../../../../lib/inflate.c" + +#define SCR *((volatile unsigned char *)0xffff8a) +#define TDR *((volatile unsigned char *)0xffff8b) +#define SSR *((volatile unsigned char *)0xffff8c) + +static void *malloc(int size) +{ + void *p; + + if (size <0) error("Malloc error"); + if (free_mem_ptr == 0) error("Memory error"); + + free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ + + p = (void *)free_mem_ptr; + free_mem_ptr += size; + + if (free_mem_ptr >= free_mem_end_ptr) + error("Out of memory"); + + return p; +} + +static void free(void *where) +{ /* Don't care */ +} + +static void gzip_mark(void **ptr) +{ + *ptr = (void *) free_mem_ptr; +} + +static void gzip_release(void **ptr) +{ + free_mem_ptr = (long) *ptr; +} + +int puts(const char *s) +{ + return 0; +} + +void* memset(void* s, int c, size_t n) +{ + int i; + char *ss = (char*)s; + + for (i=0;i> 8); + } + crc = c; + bytes_out += (ulg)outcnt; + output_ptr += (ulg)outcnt; + outcnt = 0; +} + +static void error(char *x) +{ + puts("\n\n"); + puts(x); + puts("\n\n -- System halted"); + + while(1); /* Halt */ +} + +#define STACK_SIZE (4096) +long user_stack [STACK_SIZE]; +long* stack_start = &user_stack[STACK_SIZE]; + +void decompress_kernel(void) +{ + output_data = 0; + output_ptr = (unsigned long)0x400000; + free_mem_ptr = (unsigned long)&_end; + free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; + + makecrc(); + puts("Uncompressing Linux... "); + gunzip(); + puts("Ok, booting the kernel.\n"); +} -- cgit v1.2.3-59-g8ed1b From 180e53a71f78e72a244deb65140928d4f3d72385 Mon Sep 17 00:00:00 2001 From: Milind Arun Choudhary Date: Sun, 6 May 2007 14:50:36 -0700 Subject: ROUND_UP macro cleanup in arch/alpha/kernel/osf_sys.c ROUND_UP macro cleanup use ALIGN Signed-off-by: Milind Arun Choudhary Cc: Ivan Kokshaysky Cc: Richard Henderson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/osf_sys.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 67ae41dcb6fa..ea405f5713ce 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -93,7 +93,6 @@ osf_set_program_attributes(unsigned long text_start, unsigned long text_len, * offset differences aren't the same as "d_reclen"). */ #define NAME_OFFSET offsetof (struct osf_dirent, d_name) -#define ROUND_UP(x) (((x)+3) & ~3) struct osf_dirent { unsigned int d_ino; @@ -115,7 +114,7 @@ osf_filldir(void *__buf, const char *name, int namlen, loff_t offset, { struct osf_dirent __user *dirent; struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf; - unsigned int reclen = ROUND_UP(NAME_OFFSET + namlen + 1); + unsigned int reclen = ALIGN(NAME_OFFSET + namlen + 1, sizeof(u32)); unsigned int d_ino; buf->error = -EINVAL; /* only used if we fail */ @@ -174,7 +173,6 @@ osf_getdirentries(unsigned int fd, struct osf_dirent __user *dirent, return error; } -#undef ROUND_UP #undef NAME_OFFSET asmlinkage unsigned long -- cgit v1.2.3-59-g8ed1b From eb2bce7f5e7ac1ca6da434461217fadf3c688d2c Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Sun, 6 May 2007 14:50:37 -0700 Subject: ALPHA: fix BOOTP image creation Files: arch/alpha/boot/bootpz.c Create a dummy "__kmalloc()" to satisfy the loader; never called. arch/alpha/boot/tools/objstrip.c Remove an include that is now (2.6.x) unnecessary. Signed-off-by: Jay Estabrook Signed-off-by: Ivan Kokshaysky Cc: Richard Henderson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/boot/bootpz.c | 6 ++++++ arch/alpha/boot/tools/objstrip.c | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/alpha/boot/bootpz.c b/arch/alpha/boot/bootpz.c index 4307bde80a35..1036b515e20c 100644 --- a/arch/alpha/boot/bootpz.c +++ b/arch/alpha/boot/bootpz.c @@ -467,3 +467,9 @@ start_kernel(void) #endif runkernel(); } + + /* dummy function, should never be called. */ +void *__kmalloc(size_t size, gfp_t flags) +{ + return (void *)NULL; +} diff --git a/arch/alpha/boot/tools/objstrip.c b/arch/alpha/boot/tools/objstrip.c index 67beb1b45e4f..96154e768a20 100644 --- a/arch/alpha/boot/tools/objstrip.c +++ b/arch/alpha/boot/tools/objstrip.c @@ -25,7 +25,6 @@ #include #include #include -#include #ifdef __ELF__ # include #endif -- cgit v1.2.3-59-g8ed1b From 2af0bc94a665f22975de11bddcf6c57907ce8255 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 6 May 2007 14:50:39 -0700 Subject: srmcons: fix kmalloc(GFP_KERNEL) inside spinlock Fixes http://bugzilla.kernel.org/show_bug.cgi?id=8341 Cc: Cc: Richard Henderson Cc: Ivan Kokshaysky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/srmcons.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index 756923203860..85a821aaceb4 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c @@ -164,9 +164,9 @@ srmcons_get_private_struct(struct srmcons_private **ps) int retval = 0; if (srmconsp == NULL) { + srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL); spin_lock_irqsave(&srmconsp_lock, flags); - srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL); if (srmconsp == NULL) retval = -ENOMEM; else { -- cgit v1.2.3-59-g8ed1b From e87be1143472d841c1907e6e7ae4862a30e3595c Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sun, 6 May 2007 14:50:39 -0700 Subject: ARM26: remove useless config option GENERIC_BUST_SPINLOCK. Remove the apparently useless config option GENERIC_BUST_SPINLOCK, since nothing in the source tree refers to it. Signed-off-by: Robert P. J. Day Acked-by: Ian Molton Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm26/Kconfig | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig index 989113dce415..20688bc13e9b 100644 --- a/arch/arm26/Kconfig +++ b/arch/arm26/Kconfig @@ -57,9 +57,6 @@ config GENERIC_CALIBRATE_DELAY bool default y -config GENERIC_BUST_SPINLOCK - bool - config ZONE_DMA bool default y -- cgit v1.2.3-59-g8ed1b From 74dfd666de861c97d47bdbd892f6d21b801d0247 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 6 May 2007 14:50:43 -0700 Subject: swsusp: do not use page flags Make swsusp use memory bitmaps instead of page flags for marking 'nosave' and free pages. This allows us to 'recycle' two page flags that can be used for other purposes. Also, the memory needed to store the bitmaps is allocated when necessary (ie. before the suspend) and freed after the resume which is more reasonable. The patch is designed to minimize the amount of changes and there are some nice simplifications and optimizations possible on top of it. I am going to implement them separately in the future. Signed-off-by: Rafael J. Wysocki Acked-by: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/e820.c | 26 ++--- include/linux/suspend.h | 58 ++++------- kernel/power/disk.c | 23 +++-- kernel/power/main.c | 2 + kernel/power/power.h | 2 + kernel/power/snapshot.c | 250 +++++++++++++++++++++++++++++++++++++++++++--- kernel/power/user.c | 4 + 7 files changed, 283 insertions(+), 82 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index be8965427a93..13c6c37610e0 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include @@ -256,22 +258,6 @@ void __init e820_reserve_resources(void) } } -/* Mark pages corresponding to given address range as nosave */ -static void __init -e820_mark_nosave_range(unsigned long start, unsigned long end) -{ - unsigned long pfn, max_pfn; - - if (start >= end) - return; - - printk("Nosave address range: %016lx - %016lx\n", start, end); - max_pfn = end >> PAGE_SHIFT; - for (pfn = start >> PAGE_SHIFT; pfn < max_pfn; pfn++) - if (pfn_valid(pfn)) - SetPageNosave(pfn_to_page(pfn)); -} - /* * Find the ranges of physical addresses that do not correspond to * e820 RAM areas and mark the corresponding pages as nosave for software @@ -290,13 +276,13 @@ void __init e820_mark_nosave_regions(void) struct e820entry *ei = &e820.map[i]; if (paddr < ei->addr) - e820_mark_nosave_range(paddr, - round_up(ei->addr, PAGE_SIZE)); + register_nosave_region(PFN_DOWN(paddr), + PFN_UP(ei->addr)); paddr = round_down(ei->addr + ei->size, PAGE_SIZE); if (ei->type != E820_RAM) - e820_mark_nosave_range(round_up(ei->addr, PAGE_SIZE), - paddr); + register_nosave_region(PFN_UP(ei->addr), + PFN_DOWN(paddr)); if (paddr >= (end_pfn << PAGE_SHIFT)) break; diff --git a/include/linux/suspend.h b/include/linux/suspend.h index a45b9f514492..3cc4d6394c07 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -24,63 +24,41 @@ struct pbe { extern void drain_local_pages(void); extern void mark_free_pages(struct zone *zone); -#ifdef CONFIG_PM -/* kernel/power/swsusp.c */ -extern int software_suspend(void); - -#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) +#if defined(CONFIG_PM) && defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) extern int pm_prepare_console(void); extern void pm_restore_console(void); #else static inline int pm_prepare_console(void) { return 0; } static inline void pm_restore_console(void) {} -#endif /* defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) */ +#endif + +#if defined(CONFIG_PM) && defined(CONFIG_SOFTWARE_SUSPEND) +/* kernel/power/swsusp.c */ +extern int software_suspend(void); +/* kernel/power/snapshot.c */ +extern void __init register_nosave_region(unsigned long, unsigned long); +extern int swsusp_page_is_forbidden(struct page *); +extern void swsusp_set_page_free(struct page *); +extern void swsusp_unset_page_free(struct page *); +extern unsigned long get_safe_page(gfp_t gfp_mask); #else static inline int software_suspend(void) { printk("Warning: fake suspend called\n"); return -ENOSYS; } -#endif /* CONFIG_PM */ + +static inline void register_nosave_region(unsigned long b, unsigned long e) {} +static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } +static inline void swsusp_set_page_free(struct page *p) {} +static inline void swsusp_unset_page_free(struct page *p) {} +#endif /* defined(CONFIG_PM) && defined(CONFIG_SOFTWARE_SUSPEND) */ void save_processor_state(void); void restore_processor_state(void); struct saved_context; void __save_processor_state(struct saved_context *ctxt); void __restore_processor_state(struct saved_context *ctxt); -unsigned long get_safe_page(gfp_t gfp_mask); - -/* Page management functions for the software suspend (swsusp) */ - -static inline void swsusp_set_page_forbidden(struct page *page) -{ - SetPageNosave(page); -} - -static inline int swsusp_page_is_forbidden(struct page *page) -{ - return PageNosave(page); -} - -static inline void swsusp_unset_page_forbidden(struct page *page) -{ - ClearPageNosave(page); -} - -static inline void swsusp_set_page_free(struct page *page) -{ - SetPageNosaveFree(page); -} - -static inline int swsusp_page_is_free(struct page *page) -{ - return PageNosaveFree(page); -} - -static inline void swsusp_unset_page_free(struct page *page) -{ - ClearPageNosaveFree(page); -} /* * XXX: We try to keep some more pages free so that I/O operations succeed diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 8df51c23bba4..403bc3722fee 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c @@ -139,14 +139,19 @@ int pm_suspend_disk(void) mdelay(5000); goto Thaw; } + /* Allocate memory management structures */ + error = create_basic_memory_bitmaps(); + if (error) + goto Thaw; + /* Free memory before shutting down devices. */ error = swsusp_shrink_memory(); if (error) - goto Thaw; + goto Finish; error = platform_prepare(); if (error) - goto Thaw; + goto Finish; suspend_console(); error = device_suspend(PMSG_FREEZE); @@ -181,7 +186,7 @@ int pm_suspend_disk(void) power_down(); else { swsusp_free(); - goto Thaw; + goto Finish; } } else { pr_debug("PM: Image restored successfully.\n"); @@ -194,6 +199,8 @@ int pm_suspend_disk(void) platform_finish(); device_resume(); resume_console(); + Finish: + free_basic_memory_bitmaps(); Thaw: unprepare_processes(); return error; @@ -239,13 +246,15 @@ static int software_resume(void) } pr_debug("PM: Checking swsusp image.\n"); - error = swsusp_check(); if (error) - goto Done; + goto Unlock; - pr_debug("PM: Preparing processes for restore.\n"); + error = create_basic_memory_bitmaps(); + if (error) + goto Unlock; + pr_debug("PM: Preparing processes for restore.\n"); error = prepare_processes(); if (error) { swsusp_close(); @@ -280,7 +289,9 @@ static int software_resume(void) printk(KERN_ERR "PM: Restore failed, recovering.\n"); unprepare_processes(); Done: + free_basic_memory_bitmaps(); /* For success case, the suspend path will release the lock */ + Unlock: mutex_unlock(&pm_mutex); pr_debug("PM: Resume from disk failed.\n"); return 0; diff --git a/kernel/power/main.c b/kernel/power/main.c index b21c2a56f960..5a779270cdbc 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -244,6 +244,7 @@ static int enter_state(suspend_state_t state) return error; } +#ifdef CONFIG_SOFTWARE_SUSPEND /* * This is main interface to the outside world. It needs to be * called from process context. @@ -252,6 +253,7 @@ int software_suspend(void) { return enter_state(PM_SUSPEND_DISK); } +#endif /** diff --git a/kernel/power/power.h b/kernel/power/power.h index 33bd94ceba32..1f8052bda0f7 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -48,6 +48,8 @@ extern sector_t swsusp_resume_block; extern asmlinkage int swsusp_arch_suspend(void); extern asmlinkage int swsusp_arch_resume(void); +extern int create_basic_memory_bitmaps(void); +extern void free_basic_memory_bitmaps(void); extern unsigned int count_data_pages(void); /** diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 48fc7a35571b..f66e4411795b 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,10 @@ #include "power.h" +static int swsusp_page_is_free(struct page *); +static void swsusp_set_page_forbidden(struct page *); +static void swsusp_unset_page_forbidden(struct page *); + /* List of PBEs needed for restoring the pages that were allocated before * the suspend and included in the suspend image, but have also been * allocated by the "resume" kernel, so their contents cannot be written @@ -224,11 +229,6 @@ static void chain_free(struct chain_allocator *ca, int clear_page_nosave) * of type unsigned long each). It also contains the pfns that * correspond to the start and end of the represented memory area and * the number of bit chunks in the block. - * - * NOTE: Memory bitmaps are used for two types of operations only: - * "set a bit" and "find the next bit set". Moreover, the searching - * is always carried out after all of the "set a bit" operations - * on given bitmap. */ #define BM_END_OF_MAP (~0UL) @@ -443,15 +443,13 @@ static void memory_bm_free(struct memory_bitmap *bm, int clear_nosave_free) } /** - * memory_bm_set_bit - set the bit in the bitmap @bm that corresponds + * memory_bm_find_bit - find the bit in the bitmap @bm that corresponds * to given pfn. The cur_zone_bm member of @bm and the cur_block member * of @bm->cur_zone_bm are updated. - * - * If the bit cannot be set, the function returns -EINVAL . */ -static int -memory_bm_set_bit(struct memory_bitmap *bm, unsigned long pfn) +static void memory_bm_find_bit(struct memory_bitmap *bm, unsigned long pfn, + void **addr, unsigned int *bit_nr) { struct zone_bitmap *zone_bm; struct bm_block *bb; @@ -463,8 +461,8 @@ memory_bm_set_bit(struct memory_bitmap *bm, unsigned long pfn) /* We don't assume that the zones are sorted by pfns */ while (pfn < zone_bm->start_pfn || pfn >= zone_bm->end_pfn) { zone_bm = zone_bm->next; - if (unlikely(!zone_bm)) - return -EINVAL; + + BUG_ON(!zone_bm); } bm->cur.zone_bm = zone_bm; } @@ -475,13 +473,40 @@ memory_bm_set_bit(struct memory_bitmap *bm, unsigned long pfn) while (pfn >= bb->end_pfn) { bb = bb->next; - if (unlikely(!bb)) - return -EINVAL; + + BUG_ON(!bb); } zone_bm->cur_block = bb; pfn -= bb->start_pfn; - set_bit(pfn % BM_BITS_PER_CHUNK, bb->data + pfn / BM_BITS_PER_CHUNK); - return 0; + *bit_nr = pfn % BM_BITS_PER_CHUNK; + *addr = bb->data + pfn / BM_BITS_PER_CHUNK; +} + +static void memory_bm_set_bit(struct memory_bitmap *bm, unsigned long pfn) +{ + void *addr; + unsigned int bit; + + memory_bm_find_bit(bm, pfn, &addr, &bit); + set_bit(bit, addr); +} + +static void memory_bm_clear_bit(struct memory_bitmap *bm, unsigned long pfn) +{ + void *addr; + unsigned int bit; + + memory_bm_find_bit(bm, pfn, &addr, &bit); + clear_bit(bit, addr); +} + +static int memory_bm_test_bit(struct memory_bitmap *bm, unsigned long pfn) +{ + void *addr; + unsigned int bit; + + memory_bm_find_bit(bm, pfn, &addr, &bit); + return test_bit(bit, addr); } /* Two auxiliary functions for memory_bm_next_pfn */ @@ -563,6 +588,199 @@ static unsigned long memory_bm_next_pfn(struct memory_bitmap *bm) return bb->start_pfn + chunk * BM_BITS_PER_CHUNK + bit; } +/** + * This structure represents a range of page frames the contents of which + * should not be saved during the suspend. + */ + +struct nosave_region { + struct list_head list; + unsigned long start_pfn; + unsigned long end_pfn; +}; + +static LIST_HEAD(nosave_regions); + +/** + * register_nosave_region - register a range of page frames the contents + * of which should not be saved during the suspend (to be used in the early + * initialization code) + */ + +void __init +register_nosave_region(unsigned long start_pfn, unsigned long end_pfn) +{ + struct nosave_region *region; + + if (start_pfn >= end_pfn) + return; + + if (!list_empty(&nosave_regions)) { + /* Try to extend the previous region (they should be sorted) */ + region = list_entry(nosave_regions.prev, + struct nosave_region, list); + if (region->end_pfn == start_pfn) { + region->end_pfn = end_pfn; + goto Report; + } + } + /* This allocation cannot fail */ + region = alloc_bootmem_low(sizeof(struct nosave_region)); + region->start_pfn = start_pfn; + region->end_pfn = end_pfn; + list_add_tail(®ion->list, &nosave_regions); + Report: + printk("swsusp: Registered nosave memory region: %016lx - %016lx\n", + start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT); +} + +/* + * Set bits in this map correspond to the page frames the contents of which + * should not be saved during the suspend. + */ +static struct memory_bitmap *forbidden_pages_map; + +/* Set bits in this map correspond to free page frames. */ +static struct memory_bitmap *free_pages_map; + +/* + * Each page frame allocated for creating the image is marked by setting the + * corresponding bits in forbidden_pages_map and free_pages_map simultaneously + */ + +void swsusp_set_page_free(struct page *page) +{ + if (free_pages_map) + memory_bm_set_bit(free_pages_map, page_to_pfn(page)); +} + +static int swsusp_page_is_free(struct page *page) +{ + return free_pages_map ? + memory_bm_test_bit(free_pages_map, page_to_pfn(page)) : 0; +} + +void swsusp_unset_page_free(struct page *page) +{ + if (free_pages_map) + memory_bm_clear_bit(free_pages_map, page_to_pfn(page)); +} + +static void swsusp_set_page_forbidden(struct page *page) +{ + if (forbidden_pages_map) + memory_bm_set_bit(forbidden_pages_map, page_to_pfn(page)); +} + +int swsusp_page_is_forbidden(struct page *page) +{ + return forbidden_pages_map ? + memory_bm_test_bit(forbidden_pages_map, page_to_pfn(page)) : 0; +} + +static void swsusp_unset_page_forbidden(struct page *page) +{ + if (forbidden_pages_map) + memory_bm_clear_bit(forbidden_pages_map, page_to_pfn(page)); +} + +/** + * mark_nosave_pages - set bits corresponding to the page frames the + * contents of which should not be saved in a given bitmap. + */ + +static void mark_nosave_pages(struct memory_bitmap *bm) +{ + struct nosave_region *region; + + if (list_empty(&nosave_regions)) + return; + + list_for_each_entry(region, &nosave_regions, list) { + unsigned long pfn; + + printk("swsusp: Marking nosave pages: %016lx - %016lx\n", + region->start_pfn << PAGE_SHIFT, + region->end_pfn << PAGE_SHIFT); + + for (pfn = region->start_pfn; pfn < region->end_pfn; pfn++) + memory_bm_set_bit(bm, pfn); + } +} + +/** + * create_basic_memory_bitmaps - create bitmaps needed for marking page + * frames that should not be saved and free page frames. The pointers + * forbidden_pages_map and free_pages_map are only modified if everything + * goes well, because we don't want the bits to be used before both bitmaps + * are set up. + */ + +int create_basic_memory_bitmaps(void) +{ + struct memory_bitmap *bm1, *bm2; + int error = 0; + + BUG_ON(forbidden_pages_map || free_pages_map); + + bm1 = kzalloc(sizeof(struct memory_bitmap), GFP_ATOMIC); + if (!bm1) + return -ENOMEM; + + error = memory_bm_create(bm1, GFP_ATOMIC | __GFP_COLD, PG_ANY); + if (error) + goto Free_first_object; + + bm2 = kzalloc(sizeof(struct memory_bitmap), GFP_ATOMIC); + if (!bm2) + goto Free_first_bitmap; + + error = memory_bm_create(bm2, GFP_ATOMIC | __GFP_COLD, PG_ANY); + if (error) + goto Free_second_object; + + forbidden_pages_map = bm1; + free_pages_map = bm2; + mark_nosave_pages(forbidden_pages_map); + + printk("swsusp: Basic memory bitmaps created\n"); + + return 0; + + Free_second_object: + kfree(bm2); + Free_first_bitmap: + memory_bm_free(bm1, PG_UNSAFE_CLEAR); + Free_first_object: + kfree(bm1); + return -ENOMEM; +} + +/** + * free_basic_memory_bitmaps - free memory bitmaps allocated by + * create_basic_memory_bitmaps(). The auxiliary pointers are necessary + * so that the bitmaps themselves are not referred to while they are being + * freed. + */ + +void free_basic_memory_bitmaps(void) +{ + struct memory_bitmap *bm1, *bm2; + + BUG_ON(!(forbidden_pages_map && free_pages_map)); + + bm1 = forbidden_pages_map; + bm2 = free_pages_map; + forbidden_pages_map = NULL; + free_pages_map = NULL; + memory_bm_free(bm1, PG_UNSAFE_CLEAR); + kfree(bm1); + memory_bm_free(bm2, PG_UNSAFE_CLEAR); + kfree(bm2); + + printk("swsusp: Basic memory bitmaps freed\n"); +} + /** * snapshot_additional_pages - estimate the number of additional pages * be needed for setting up the suspend image data structures for given diff --git a/kernel/power/user.c b/kernel/power/user.c index 7cf6713b2325..845acd84cb23 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -52,6 +52,9 @@ static int snapshot_open(struct inode *inode, struct file *filp) if ((filp->f_flags & O_ACCMODE) == O_RDWR) return -ENOSYS; + if(create_basic_memory_bitmaps()) + return -ENOMEM; + nonseekable_open(inode, filp); data = &snapshot_state; filp->private_data = data; @@ -77,6 +80,7 @@ static int snapshot_release(struct inode *inode, struct file *filp) struct snapshot_data *data; swsusp_free(); + free_basic_memory_bitmaps(); data = filp->private_data; free_all_swap_pages(data->swap, data->bitmap); free_bitmap(data->bitmap); -- cgit v1.2.3-59-g8ed1b From edfe7a569687c2cd85e82eaecae5b260577accbb Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sun, 6 May 2007 14:50:53 -0700 Subject: remove unused header file: arch/m68k/atari/atasound.h Signed-off-by: Robert P. J. Day Acked-by: Geert Uytterhoeven Cc: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/m68k/atari/atasound.h | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 arch/m68k/atari/atasound.h (limited to 'arch') diff --git a/arch/m68k/atari/atasound.h b/arch/m68k/atari/atasound.h deleted file mode 100644 index 1362762b8c0f..000000000000 --- a/arch/m68k/atari/atasound.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Minor numbers for the sound driver. - * - * Unfortunately Creative called the codec chip of SB as a DSP. For this - * reason the /dev/dsp is reserved for digitized audio use. There is a - * device for true DSP processors but it will be called something else. - * In v3.0 it's /dev/sndproc but this could be a temporary solution. - */ - -#define SND_NDEVS 256 /* Number of supported devices */ -#define SND_DEV_CTL 0 /* Control port /dev/mixer */ -#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM - synthesizer and MIDI output) */ -#define SND_DEV_MIDIN 2 /* Raw midi access */ -#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */ -#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */ -#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */ -#define SND_DEV_STATUS 6 /* /dev/sndstat */ -/* #7 not in use now. Was in 2.4. Free for use after v3.0. */ -#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */ -#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */ -#define SND_DEV_PSS SND_DEV_SNDPROC - -#define DSP_DEFAULT_SPEED 8000 - -#define ON 1 -#define OFF 0 - -#define MAX_AUDIO_DEV 5 -#define MAX_MIXER_DEV 2 -#define MAX_SYNTH_DEV 3 -#define MAX_MIDI_DEV 6 -#define MAX_TIMER_DEV 3 -- cgit v1.2.3-59-g8ed1b From 241258d1cc4d3551608364cd678d5a85239ad481 Mon Sep 17 00:00:00 2001 From: Milind Arun Choudhary Date: Sun, 6 May 2007 14:50:54 -0700 Subject: SPIN_LOCK_UNLOCKED cleanup in arch/m68k SPIN_LOCK_UNLOCKED cleanup,use __SPIN_LOCK_UNLOCKED instead Signed-off-by: Milind Arun Choudhary Cc: Geert Uytterhoeven Cc: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/m68k/amiga/amiints.c | 2 +- arch/m68k/amiga/cia.c | 4 ++-- arch/m68k/apollo/dn_ints.c | 2 +- arch/m68k/atari/ataints.c | 2 +- arch/m68k/kernel/ints.c | 4 ++-- arch/m68k/mac/macints.c | 2 +- arch/m68k/q40/q40ints.c | 2 +- arch/m68k/sun3/sun3ints.c | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c index 28d95cfe8ac0..907a5533c845 100644 --- a/arch/m68k/amiga/amiints.c +++ b/arch/m68k/amiga/amiints.c @@ -54,7 +54,7 @@ static irqreturn_t ami_int5(int irq, void *dev_id); static struct irq_controller amiga_irq_controller = { .name = "amiga", - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(amiga_irq_controller.lock), .enable = amiga_enable_irq, .disable = amiga_disable_irq, }; diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c index 7a20058eb380..c4a4ffd45bc0 100644 --- a/arch/m68k/amiga/cia.c +++ b/arch/m68k/amiga/cia.c @@ -123,7 +123,7 @@ static void cia_disable_irq(unsigned int irq) static struct irq_controller cia_irq_controller = { .name = "cia", - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(cia_irq_controller.lock), .enable = cia_enable_irq, .disable = cia_disable_irq, }; @@ -160,7 +160,7 @@ static void auto_disable_irq(unsigned int irq) static struct irq_controller auto_irq_controller = { .name = "auto", - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock), .enable = auto_enable_irq, .disable = auto_disable_irq, }; diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c index 4274af125998..13bd41bed28e 100644 --- a/arch/m68k/apollo/dn_ints.c +++ b/arch/m68k/apollo/dn_ints.c @@ -31,7 +31,7 @@ void apollo_irq_shutdown(unsigned int irq) static struct irq_controller apollo_irq_controller = { .name = "apollo", - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(apollo_irq_controller.lock), .startup = apollo_irq_startup, .shutdown = apollo_irq_shutdown, }; diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c index 7f812641790c..b85ca22024c1 100644 --- a/arch/m68k/atari/ataints.c +++ b/arch/m68k/atari/ataints.c @@ -339,7 +339,7 @@ static void atari_shutdown_irq(unsigned int irq) static struct irq_controller atari_irq_controller = { .name = "atari", - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(atari_irq_controller.lock), .startup = atari_startup_irq, .shutdown = atari_shutdown_irq, .enable = atari_enable_irq, diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index b66c97c904b3..60d4d75f5798 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -59,14 +59,14 @@ static int m68k_first_user_vec; static struct irq_controller auto_irq_controller = { .name = "auto", - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock), .startup = m68k_irq_startup, .shutdown = m68k_irq_shutdown, }; static struct irq_controller user_irq_controller = { .name = "user", - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(user_irq_controller.lock), .startup = m68k_irq_startup, .shutdown = m68k_irq_shutdown, }; diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c index f6fcd754d8f6..0fc72d8f786e 100644 --- a/arch/m68k/mac/macints.c +++ b/arch/m68k/mac/macints.c @@ -219,7 +219,7 @@ static void mac_disable_irq(unsigned int irq); static struct irq_controller mac_irq_controller = { .name = "mac", - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(mac_irq_controller.lock), .enable = mac_enable_irq, .disable = mac_disable_irq, }; diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c index 31cc07d8cec4..2fb25ae46a8a 100644 --- a/arch/m68k/q40/q40ints.c +++ b/arch/m68k/q40/q40ints.c @@ -59,7 +59,7 @@ static void q40_irq_shutdown(unsigned int irq) static struct irq_controller q40_irq_controller = { .name = "q40", - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(q40_irq_controller.lock), .startup = q40_irq_startup, .shutdown = q40_irq_shutdown, .enable = q40_enable_irq, diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c index 4232a2c2fae9..50df34bf80e3 100644 --- a/arch/m68k/sun3/sun3ints.c +++ b/arch/m68k/sun3/sun3ints.c @@ -90,7 +90,7 @@ static void sun3_inthandle(unsigned int irq, struct pt_regs *fp) static struct irq_controller sun3_irq_controller = { .name = "sun3", - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(sun3_irq_controller.lock), .startup = m68k_irq_startup, .shutdown = m68k_irq_shutdown, .enable = sun3_enable_irq, -- cgit v1.2.3-59-g8ed1b From 542401d97a3251ee20d7acb2f3736d0f34b49e64 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sun, 6 May 2007 14:50:56 -0700 Subject: CRIS: check for memory allocation Add checking for allocated memory. Indents and spaces are added to be familiar with the kernel coding style. Signed-off-by: Cyrill Gorcunov Acked-by: Mikael Starvik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/cris/kernel/profile.c | 81 +++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 33 deletions(-) (limited to 'arch') diff --git a/arch/cris/kernel/profile.c b/arch/cris/kernel/profile.c index 4cfcae620507..aad0a9e5991a 100644 --- a/arch/cris/kernel/profile.c +++ b/arch/cris/kernel/profile.c @@ -15,39 +15,47 @@ static int prof_running = 0; void cris_profile_sample(struct pt_regs* regs) { - if (!prof_running) - return; - if (user_mode(regs)) - *(unsigned int*)sample_buffer_pos = current->pid; - else - *(unsigned int*)sample_buffer_pos = 0; - *(unsigned int*)(sample_buffer_pos + 4) = instruction_pointer(regs); - sample_buffer_pos += 8; - if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE) - sample_buffer_pos = sample_buffer; + if (!prof_running) + return; + + if (user_mode(regs)) + *(unsigned int*)sample_buffer_pos = current->pid; + else + *(unsigned int*)sample_buffer_pos = 0; + + *(unsigned int*)(sample_buffer_pos + 4) = instruction_pointer(regs); + sample_buffer_pos += 8; + + if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE) + sample_buffer_pos = sample_buffer; } static ssize_t -read_cris_profile(struct file *file, char __user *buf, size_t count, loff_t *ppos) +read_cris_profile(struct file *file, char __user *buf, + size_t count, loff_t *ppos) { - unsigned long p = *ppos; - if (p > SAMPLE_BUFFER_SIZE) - return 0; - if (p + count > SAMPLE_BUFFER_SIZE) - count = SAMPLE_BUFFER_SIZE - p; - if (copy_to_user(buf, sample_buffer + p,count)) + unsigned long p = *ppos; + + if (p > SAMPLE_BUFFER_SIZE) + return 0; + + if (p + count > SAMPLE_BUFFER_SIZE) + count = SAMPLE_BUFFER_SIZE - p; + if (copy_to_user(buf, sample_buffer + p,count)) return -EFAULT; - memset(sample_buffer + p, 0, count); - *ppos += count; - return count; + + memset(sample_buffer + p, 0, count); + *ppos += count; + + return count; } static ssize_t write_cris_profile(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { - sample_buffer_pos = sample_buffer; - memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE); + sample_buffer_pos = sample_buffer; + memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE); } static const struct file_operations cris_proc_profile_operations = { @@ -58,16 +66,23 @@ static const struct file_operations cris_proc_profile_operations = { static int __init init_cris_profile(void) { - struct proc_dir_entry *entry; - sample_buffer = kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL); - sample_buffer_pos = sample_buffer; - entry = create_proc_entry("system_profile", S_IWUSR | S_IRUGO, NULL); - if (entry) { - entry->proc_fops = &cris_proc_profile_operations; - entry->size = SAMPLE_BUFFER_SIZE; - } - prof_running = 1; - return 0; + struct proc_dir_entry *entry; + + sample_buffer = kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL); + if (!sample_buffer) { + return -ENOMEM; + } + + sample_buffer_pos = sample_buffer; + + entry = create_proc_entry("system_profile", S_IWUSR | S_IRUGO, NULL); + if (entry) { + entry->proc_fops = &cris_proc_profile_operations; + entry->size = SAMPLE_BUFFER_SIZE; + } + prof_running = 1; + + return 0; } __initcall(init_cris_profile); -- cgit v1.2.3-59-g8ed1b From 7a3e965abfbdd5abacd29b9a67af91aa31b5f9d3 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sun, 6 May 2007 14:50:56 -0700 Subject: CRIS: remove code related to pre-2.2 kernel Remove conditionals and code related to checking for a pre-2.2 kernel. Signed-off-by: Robert P. J. Day Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/cris/arch-v32/kernel/fasttimer.c | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/cris/arch-v32/kernel/fasttimer.c b/arch/cris/arch-v32/kernel/fasttimer.c index 5daeb6f7f3b7..79e1e4c2ca1d 100644 --- a/arch/cris/arch-v32/kernel/fasttimer.c +++ b/arch/cris/arch-v32/kernel/fasttimer.c @@ -603,23 +603,8 @@ void schedule_usleep(unsigned long us) #ifdef CONFIG_PROC_FS static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) - ,int *eof, void *data_unused -#else - ,int unused -#endif - ); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) + ,int *eof, void *data_unused); static struct proc_dir_entry *fasttimer_proc_entry; -#else -static struct proc_dir_entry fasttimer_proc_entry = -{ - 0, 9, "fasttimer", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, NULL /* ops -- default to array */, - &proc_fasttimer_read /* get_info */, -}; -#endif #endif /* CONFIG_PROC_FS */ #ifdef CONFIG_PROC_FS @@ -628,12 +613,7 @@ static struct proc_dir_entry fasttimer_proc_entry = #define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300) static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) - ,int *eof, void *data_unused -#else - ,int unused -#endif - ) + ,int *eof, void *data_unused) { unsigned long flags; int i = 0; @@ -808,9 +788,7 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len memcpy(buf, bigbuf + offset, len); *start = buf; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) *eof = 1; -#endif return len; } @@ -974,12 +952,8 @@ void fast_timer_init(void) printk("fast_timer_init()\n"); #ifdef CONFIG_PROC_FS -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 ))) fasttimer_proc_entry->read_proc = proc_fasttimer_read; -#else - proc_register_dynamic(&proc_root, &fasttimer_proc_entry); -#endif #endif /* PROC_FS */ if(request_irq(TIMER_INTR_VECT, timer_trig_interrupt, IRQF_DISABLED, "fast timer int", NULL)) -- cgit v1.2.3-59-g8ed1b From 11100b1dfb6e9444d54d38e822753f59ee42a7e6 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:50:57 -0700 Subject: uml: delete unused code Get rid of a bunch of unused stuff - cpu_feature had no users linux_prog is little-used, so its declaration is moved to the user for easy deletion when the whole file goes away a long-unused debugging aid in helper.c is gone Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/kern_util.h | 1 - arch/um/include/user_util.h | 1 - arch/um/kernel/tt/gdb.c | 2 ++ arch/um/os-Linux/helper.c | 11 ----------- arch/um/os-Linux/main.c | 8 +------- arch/um/sys-i386/bugs.c | 23 ----------------------- arch/um/sys-x86_64/bugs.c | 23 ----------------------- 7 files changed, 3 insertions(+), 66 deletions(-) (limited to 'arch') diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index 173af029d12b..be850b9ec947 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h @@ -23,7 +23,6 @@ struct kern_handlers { extern const struct kern_handlers handlinfo_kern; extern int ncpus; -extern char *linux_prog; extern char *gdb_init; extern int kmalloc_ok; extern int jail; diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index 023575f67343..99492d5c82db 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -60,7 +60,6 @@ extern void kill_child_dead(int pid); extern int cont(int pid); extern void check_sigio(void); extern void arch_check_bugs(void); -extern int cpu_feature(char *what, char *buf, int len); extern int arch_handle_signal(int sig, union uml_pt_regs *regs); extern int arch_fixup(unsigned long address, void *sc_ptr); extern void arch_init_thread(void); diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c index 8eba8f7dca68..d284f69f04ee 100644 --- a/arch/um/kernel/tt/gdb.c +++ b/arch/um/kernel/tt/gdb.c @@ -115,6 +115,8 @@ struct gdb_data { int err; }; +extern char *linux_prog; + static void config_gdb_cb(void *arg) { struct gdb_data *data = arg; diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index c7ad6306e22f..a375cc138c2c 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -25,23 +25,12 @@ struct helper_data { char *buf; }; -/* Debugging aid, changed only from gdb */ -int helper_pause = 0; - -static void helper_hup(int sig) -{ -} - static int helper_child(void *arg) { struct helper_data *data = arg; char **argv = data->argv; int errval; - if (helper_pause){ - signal(SIGHUP, helper_hup); - pause(); - } if (data->pre_exec != NULL) (*data->pre_exec)(data->pre_data); errval = execvp_noalloc(data->buf, argv[0], argv); diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 685feaab65d2..7aa4c2a7a593 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -25,12 +25,7 @@ #include "os.h" #include "um_malloc.h" -/* Set in set_stklim, which is called from main and __wrap_malloc. - * __wrap_malloc only calls it if main hasn't started. - */ -unsigned long stacksizelim; - -/* Set in main */ +/* Set in main, unchanged thereafter */ char *linux_prog; #define PGD_BOUND (4 * 1024 * 1024) @@ -52,7 +47,6 @@ static void set_stklim(void) exit(1); } } - stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1); } static __init void do_uml_initcalls(void) diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c index f1bcd399ac90..e524a087679f 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/um/sys-i386/bugs.c @@ -79,29 +79,6 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) return(0); } -int cpu_feature(char *what, char *buf, int len) -{ - int fd, ret = 0; - - fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); - if(fd < 0){ - printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); - return(0); - } - - if(!find_cpuinfo_line(fd, what, buf, len)){ - printk("Couldn't find '%s' line in /proc/cpuinfo\n", what); - goto out_close; - } - - token(fd, buf, len, '\n'); - ret = 1; - - out_close: - os_close_file(fd); - return(ret); -} - static int check_cpu_flag(char *feature, int *have_it) { char buf[MAXTOKEN], c; diff --git a/arch/um/sys-x86_64/bugs.c b/arch/um/sys-x86_64/bugs.c index fdce7ea98ca7..73ca62312fda 100644 --- a/arch/um/sys-x86_64/bugs.c +++ b/arch/um/sys-x86_64/bugs.c @@ -88,29 +88,6 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) return(0); } -int cpu_feature(char *what, char *buf, int len) -{ - int fd, ret = 0; - - fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); - if(fd < 0){ - printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); - return(0); - } - - if(!find_cpuinfo_line(fd, what, buf, len)){ - printk("Couldn't find '%s' line in /proc/cpuinfo\n", what); - goto out_close; - } - - token(fd, buf, len, '\n'); - ret = 1; - - out_close: - os_close_file(fd); - return(ret); -} - /* Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only. This must remain at the end -- cgit v1.2.3-59-g8ed1b From a5ed1ffa6c2480cdcf3f0aa945f0b8622fe4e90b Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:50:58 -0700 Subject: uml: formatting fixes Formatting fixes - style violations whitespace breakage emacs formatting comment removal Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/um_arch.c | 51 ++++++++++++++++++++++---------------------- arch/um/os-Linux/main.c | 11 +++++----- arch/um/sys-i386/bugs.c | 54 +++++++++++++++++++++-------------------------- arch/um/sys-x86_64/bugs.c | 34 +++++++++++------------------ 4 files changed, 67 insertions(+), 83 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 89c6dba731f8..299d75a41a7f 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -63,8 +63,8 @@ struct cpuinfo_um boot_cpu_data = { unsigned long thread_saved_pc(struct task_struct *task) { - return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas, - task))); + return os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas, + task)); } static int show_cpuinfo(struct seq_file *m, void *v) @@ -86,7 +86,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) loops_per_jiffy/(500000/HZ), (loops_per_jiffy/(5000/HZ)) % 100); - return(0); + return 0; } static void *c_start(struct seq_file *m, loff_t *pos) @@ -212,12 +212,12 @@ __uml_setup("debug", no_skas_debug_setup, #ifdef CONFIG_SMP static int __init uml_ncpus_setup(char *line, int *add) { - if (!sscanf(line, "%d", &ncpus)) { - printf("Couldn't parse [%s]\n", line); - return -1; - } + if (!sscanf(line, "%d", &ncpus)) { + printf("Couldn't parse [%s]\n", line); + return -1; + } - return 0; + return 0; } __uml_setup("ncpus=", uml_ncpus_setup, @@ -234,7 +234,7 @@ static int force_tt = 0; static int __init mode_tt_setup(char *line, int *add) { force_tt = 1; - return(0); + return 0; } #else @@ -245,7 +245,7 @@ static int __init mode_tt_setup(char *line, int *add) static int __init mode_tt_setup(char *line, int *add) { printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n"); - return(0); + return 0; } #else @@ -256,7 +256,7 @@ static int __init mode_tt_setup(char *line, int *add) static int __init mode_tt_setup(char *line, int *add) { printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n"); - return(0); + return 0; } #endif @@ -274,16 +274,15 @@ int mode_tt = DEFAULT_TT; static int __init Usage(char *line, int *add) { - const char **p; + const char **p; printf(usage_string, init_utsname()->release); - p = &__uml_help_start; - while (p < &__uml_help_end) { - printf("%s", *p); - p++; - } + p = &__uml_help_start; + while (p < &__uml_help_end) { + printf("%s", *p); + p++; + } exit(0); - return 0; } @@ -379,8 +378,8 @@ int __init linux_main(int argc, char **argv) set_task_sizes_skas, &task_size); /* - * Setting up handlers to 'sig_info' struct - */ + * Setting up handlers to 'sig_info' struct + */ os_fill_handlinfo(handlinfo_kern); brk_start = (unsigned long) sbrk(0); @@ -407,7 +406,7 @@ int __init linux_main(int argc, char **argv) argv1_begin = argv[1]; argv1_end = &argv[1][strlen(argv[1])]; #endif - + highmem = 0; iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC; @@ -449,12 +448,12 @@ int __init linux_main(int argc, char **argv) printf("Kernel virtual memory size shrunk to %lu bytes\n", virtmem_size); - uml_postsetup(); + uml_postsetup(); task_protections((unsigned long) &init_thread_info); os_flush_stdout(); - return(CHOOSE_MODE(start_uml_tt(), start_uml_skas())); + return CHOOSE_MODE(start_uml_tt(), start_uml_skas()); } extern int uml_exitcode; @@ -467,7 +466,7 @@ static int panic_exit(struct notifier_block *self, unsigned long unused1, bust_spinlocks(0); uml_exitcode = 1; machine_halt(); - return(0); + return 0; } static struct notifier_block panic_exit_notifier = { @@ -482,14 +481,14 @@ void __init setup_arch(char **cmdline_p) &panic_exit_notifier); paging_init(); strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; + *cmdline_p = command_line; setup_hostinfo(); } void __init check_bugs(void) { arch_check_bugs(); - os_check_bugs(); + os_check_bugs(); } void apply_alternatives(struct alt_instr *start, struct alt_instr *end) diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 7aa4c2a7a593..2c089c2c63bf 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -218,7 +218,7 @@ int main(int argc, char **argv, char **envp) ret = 1; } printf("\n"); - return(uml_exitcode); + return uml_exitcode; } #define CAN_KMALLOC() \ @@ -231,7 +231,7 @@ void *__wrap_malloc(int size) void *ret; if(!CAN_KMALLOC()) - return(__real_malloc(size)); + return __real_malloc(size); else if(size <= PAGE_SIZE) /* finding contiguos pages can be hard*/ ret = um_kmalloc(size); else ret = um_vmalloc(size); @@ -242,16 +242,17 @@ void *__wrap_malloc(int size) if(ret == NULL) errno = ENOMEM; - return(ret); + return ret; } void *__wrap_calloc(int n, int size) { void *ptr = __wrap_malloc(n * size); - if(ptr == NULL) return(NULL); + if(ptr == NULL) + return NULL; memset(ptr, 0, n * size); - return(ptr); + return ptr; } extern void __real_free(void *); diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c index e524a087679f..cae0af14903a 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/um/sys-i386/bugs.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -32,21 +32,21 @@ static char token(int fd, char *buf, int len, char stop) n = os_read_file(fd, ptr, sizeof(*ptr)); c = *ptr++; if(n != sizeof(*ptr)){ - if(n == 0) return(0); + if(n == 0) + return 0; printk("Reading /proc/cpuinfo failed, err = %d\n", -n); if(n < 0) - return(n); - else - return(-EIO); + return n; + else return -EIO; } } while((c != '\n') && (c != stop) && (ptr < end)); if(ptr == end){ printk("Failed to find '%c' in /proc/cpuinfo\n", stop); - return(-1); + return -1; } *(ptr - 1) = '\0'; - return(c); + return c; } static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) @@ -58,25 +58,25 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) while(1){ c = token(fd, scratch, len - 1, ':'); if(c <= 0) - return(0); + return 0; else if(c != ':'){ printk("Failed to find ':' in /proc/cpuinfo\n"); - return(0); + return 0; } if(!strncmp(scratch, key, strlen(key))) - return(1); + return 1; do { n = os_read_file(fd, &c, sizeof(c)); if(n != sizeof(c)){ printk("Failed to find newline in " "/proc/cpuinfo, err = %d\n", -n); - return(0); + return 0; } } while(c != '\n'); } - return(0); + return 0; } static int check_cpu_flag(char *feature, int *have_it) @@ -96,7 +96,8 @@ static int check_cpu_flag(char *feature, int *have_it) goto out; c = token(fd, buf, len - 1, ' '); - if(c < 0) goto out; + if(c < 0) + goto out; else if(c != ' '){ printk("Failed to find ' ' in /proc/cpuinfo\n"); goto out; @@ -104,7 +105,8 @@ static int check_cpu_flag(char *feature, int *have_it) while(1){ c = token(fd, buf, len - 1, ' '); - if(c < 0) goto out; + if(c < 0) + goto out; else if(c == '\n') break; if(!strcmp(buf, feature)){ @@ -113,8 +115,10 @@ static int check_cpu_flag(char *feature, int *have_it) } } out: - if(*have_it == 0) printk("No\n"); - else if(*have_it == 1) printk("Yes\n"); + if(*have_it == 0) + printk("No\n"); + else if(*have_it == 1) + printk("Yes\n"); os_close_file(fd); return 1; } @@ -166,12 +170,13 @@ int arch_handle_signal(int sig, union uml_pt_regs *regs) /* This is testing for a cmov (0x0f 0x4x) instruction causing a * SIGILL in init. */ - if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return(0); + if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) + return 0; if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) panic("SIGILL in init, could not read instructions!\n"); if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) - return(0); + return 0; if(host_has_cmov == 0) panic("SIGILL caused by cmov, which this processor doesn't " @@ -185,16 +190,5 @@ int arch_handle_signal(int sig, union uml_pt_regs *regs) "implements it, boot a filesystem compiled for older " "processors"); else panic("Bad value for host_has_cmov (%d)", host_has_cmov); - return(0); + return 0; } - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/sys-x86_64/bugs.c b/arch/um/sys-x86_64/bugs.c index 73ca62312fda..9fa5392e3122 100644 --- a/arch/um/sys-x86_64/bugs.c +++ b/arch/um/sys-x86_64/bugs.c @@ -21,7 +21,7 @@ void arch_check_bugs(void) int arch_handle_signal(int sig, union uml_pt_regs *regs) { - return(0); + return 0; } #define MAXTOKEN 64 @@ -41,21 +41,21 @@ static char token(int fd, char *buf, int len, char stop) n = os_read_file(fd, ptr, sizeof(*ptr)); c = *ptr++; if(n != sizeof(*ptr)){ - if(n == 0) return(0); + if(n == 0) + return 0; printk("Reading /proc/cpuinfo failed, err = %d\n", -n); if(n < 0) - return(n); - else - return(-EIO); + return n; + else return -EIO; } } while((c != '\n') && (c != stop) && (ptr < end)); if(ptr == end){ printk("Failed to find '%c' in /proc/cpuinfo\n", stop); - return(-1); + return -1; } *(ptr - 1) = '\0'; - return(c); + return c; } static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) @@ -67,33 +67,23 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) while(1){ c = token(fd, scratch, len - 1, ':'); if(c <= 0) - return(0); + return 0; else if(c != ':'){ printk("Failed to find ':' in /proc/cpuinfo\n"); - return(0); + return 0; } if(!strncmp(scratch, key, strlen(key))) - return(1); + return 1; do { n = os_read_file(fd, &c, sizeof(c)); if(n != sizeof(c)){ printk("Failed to find newline in " "/proc/cpuinfo, err = %d\n", -n); - return(0); + return 0; } } while(c != '\n'); } - return(0); + return 0; } - -/* Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ -- cgit v1.2.3-59-g8ed1b From b4ffb6ad8d8477b561377ca150bbbfc0db02da54 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:50:59 -0700 Subject: uml: host_info tidying Move the host_info string from util.c to um_arch.c, where it is actually initialized and used. Also document its lack of locking. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/os.h | 2 +- arch/um/include/user_util.h | 2 -- arch/um/kernel/um_arch.c | 6 +++++- arch/um/os-Linux/util.c | 8 +++----- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 5c74da410451..22666b4a8be7 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -273,7 +273,7 @@ extern void stack_protections(unsigned long address); extern void task_protections(unsigned long address); extern int raw(int fd); extern void setup_machinename(char *machine_out); -extern void setup_hostinfo(void); +extern void setup_hostinfo(char *buf, int len); extern int setjmp_wrapper(void (*proc)(void *, void *), ...); /* time.c */ diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index 99492d5c82db..73ffea1829fc 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -36,8 +36,6 @@ extern unsigned long end_vm; extern unsigned long start_vm; extern unsigned long long highmem; -extern char host_info[]; - extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; extern unsigned long _unprotected_end; extern unsigned long brk_start; diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 299d75a41a7f..613fb082bbd5 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -17,6 +17,7 @@ #include "linux/seq_file.h" #include "linux/delay.h" #include "linux/module.h" +#include "linux/utsname.h" #include "asm/page.h" #include "asm/pgtable.h" #include "asm/ptrace.h" @@ -67,6 +68,9 @@ unsigned long thread_saved_pc(struct task_struct *task) task)); } +/* Changed in setup_arch, which is called in early boot */ +static char host_info[(__NEW_UTS_LEN + 1) * 5]; + static int show_cpuinfo(struct seq_file *m, void *v) { int index = 0; @@ -482,7 +486,7 @@ void __init setup_arch(char **cmdline_p) paging_init(); strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; - setup_hostinfo(); + setup_hostinfo(host_info, sizeof host_info); } void __init check_bugs(void) diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 56b8a50e8bc2..125854a2aa22 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -96,15 +96,13 @@ void setup_machinename(char *machine_out) strcpy(machine_out, host.machine); } -char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1]; - -void setup_hostinfo(void) +void setup_hostinfo(char *buf, int len) { struct utsname host; uname(&host); - sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename, - host.release, host.version, host.machine); + snprintf(buf, len, "%s %s %s %s %s", host.sysname, host.nodename, + host.release, host.version, host.machine); } int setjmp_wrapper(void (*proc)(void *, void *), ...) -- cgit v1.2.3-59-g8ed1b From 48b201846901c1780fbc7ea779dcc8aa8ab8e16b Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:00 -0700 Subject: uml: mark tt-mode code for future removal Mark some tt-mode-only code as such. Also cleaned up some formatting. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-i386/ptrace_user.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c index 01212c88fcc4..95dd309ff69a 100644 --- a/arch/um/sys-i386/ptrace_user.c +++ b/arch/um/sys-i386/ptrace_user.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -45,7 +45,8 @@ int ptrace_setfpregs(long pid, unsigned long *regs) return 0; } -/* All the below stuff is of interest for TT mode only */ +#ifdef UML_CONFIG_MODE_TT + static void write_debugregs(int pid, unsigned long *regs) { struct user *dummy; @@ -128,13 +129,4 @@ void update_debugregs(int seq) } #endif -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ +#endif -- cgit v1.2.3-59-g8ed1b From 1d94cda04eb82feb87c932ac3d4aef1e9dc78a43 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:00 -0700 Subject: uml: print coredump limits Print out core dump limits at boot time. This is to allow core dumps to be collected if something goes very wrong and to tell if a core dump isn't going to happen because of a resource limit. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/start_up.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'arch') diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 5178eba9afa5..1244179e6c83 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -329,8 +330,32 @@ static void __init check_ptrace(void) extern void check_tmpexec(void); +static void check_coredump_limit(void) +{ + struct rlimit lim; + int err = getrlimit(RLIMIT_CORE, &lim); + + if(err){ + perror("Getting core dump limit"); + return; + } + + printf("Core dump limits :\n\tsoft - "); + if(lim.rlim_cur == RLIM_INFINITY) + printf("NONE\n"); + else printf("%lu\n", lim.rlim_cur); + + printf("\thard - "); + if(lim.rlim_max == RLIM_INFINITY) + printf("NONE\n"); + else printf("%lu\n", lim.rlim_max); +} + void os_early_checks(void) { + /* Print out the core dump limits early */ + check_coredump_limit(); + check_ptrace(); /* Need to check this early because mmapping happens before the -- cgit v1.2.3-59-g8ed1b From b47d2debf229469c78af4145ee7ad35a0f21b67f Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:01 -0700 Subject: uml: handle block device hotplug errors If a disk fails to open, i.e. its host file doesn't exist, it won't be removable because the hot-unplug code checks the existence of its gendisk. This won't exist because it is only allocated for successfully opened disks. Thus, a typo on the command line can result in a unusable and unfixable disk. This is fixed by freeing the gendisk if it's there, but not letting that affect the removal. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 8bd9204ac1ab..53c36d1770c5 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -788,14 +788,12 @@ static int ubd_id(char **str, int *start_out, int *end_out) static int ubd_remove(int n, char **error_out) { + struct gendisk *disk; struct ubd *ubd_dev; int err = -ENODEV; mutex_lock(&ubd_lock); - if(ubd_gendisk[n] == NULL) - goto out; - ubd_dev = &ubd_devs[n]; if(ubd_dev->file == NULL) @@ -806,9 +804,12 @@ static int ubd_remove(int n, char **error_out) if(ubd_dev->count > 0) goto out; - del_gendisk(ubd_gendisk[n]); - put_disk(ubd_gendisk[n]); - ubd_gendisk[n] = NULL; + disk = ubd_gendisk[n]; + ubd_gendisk[n] = NULL; + if(disk != NULL){ + del_gendisk(disk); + put_disk(disk); + } if(fake_gendisk[n] != NULL){ del_gendisk(fake_gendisk[n]); -- cgit v1.2.3-59-g8ed1b From 56bd194bb200ef0c49517de67a7d7f4b043b11b1 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:02 -0700 Subject: uml: driver formatting fixes Fix a bunch of formatting violations in the drivers: return(n) -> return n whitespace fixes emacs formatting comment removal breaking if(foo) return(n) into two lines There are also a couple of errno use bugs: using errno in a printk when the failure put errno into a local variable saving errno after a printk, which can change it Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_user.c | 2 +- arch/um/drivers/daemon_user.c | 25 ++++++-------------- arch/um/drivers/mcast_user.c | 12 +++++----- arch/um/drivers/pcap_user.c | 33 +++++++++----------------- arch/um/drivers/ubd_user.c | 15 ++---------- arch/um/os-Linux/drivers/ethertap_user.c | 36 +++++++++++----------------- arch/um/os-Linux/drivers/tuntap_user.c | 40 +++++++++++++------------------- 7 files changed, 57 insertions(+), 106 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 0cad3546cb89..77d3fdb0c21a 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -158,7 +158,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) */ err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0); if(err < 0){ - printk("fork of winch_thread failed - errno = %d\n", errno); + printk("fork of winch_thread failed - errno = %d\n", err); goto out_close; } diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index 021b82c7a759..09d1de90297c 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -39,11 +39,11 @@ static struct sockaddr_un *new_addr(void *name, int len) sun = um_kmalloc(sizeof(struct sockaddr_un)); if(sun == NULL){ printk("new_addr: allocation of sockaddr_un failed\n"); - return(NULL); + return NULL; } sun->sun_family = AF_UNIX; memcpy(sun->sun_path, name, len); - return(sun); + return sun; } static int connect_to_switch(struct daemon_data *pri) @@ -112,7 +112,7 @@ static int connect_to_switch(struct daemon_data *pri) } pri->data_addr = sun; - return(fd); + return fd; out_free: kfree(sun); @@ -120,7 +120,7 @@ static int connect_to_switch(struct daemon_data *pri) os_close_file(fd); out: os_close_file(pri->control); - return(err); + return err; } static void daemon_user_init(void *data, void *dev) @@ -152,7 +152,7 @@ static void daemon_user_init(void *data, void *dev) static int daemon_open(void *data) { struct daemon_data *pri = data; - return(pri->fd); + return pri->fd; } static void daemon_remove(void *data) @@ -176,12 +176,12 @@ int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri) { struct sockaddr_un *data_addr = pri->data_addr; - return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr))); + return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)); } static int daemon_set_mtu(int mtu, void *data) { - return(mtu); + return mtu; } const struct net_user_info daemon_user_info = { @@ -194,14 +194,3 @@ const struct net_user_info daemon_user_info = { .delete_address = NULL, .max_packet = MAX_PACKET - ETH_HEADER_OTHER }; - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c index b827e82884c9..cfaa2cc43139 100644 --- a/arch/um/drivers/mcast_user.c +++ b/arch/um/drivers/mcast_user.c @@ -34,12 +34,12 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port) sin = um_kmalloc(sizeof(struct sockaddr_in)); if(sin == NULL){ printk("new_addr: allocation of sockaddr_in failed\n"); - return(NULL); + return NULL; } sin->sin_family = AF_INET; sin->sin_addr.s_addr = in_aton(addr); sin->sin_port = htons(port); - return(sin); + return sin; } static void mcast_user_init(void *data, void *dev) @@ -107,8 +107,8 @@ static int mcast_open(void *data) err = -errno; printk("mcast_open : data bind failed, errno = %d\n", errno); goto out_close; - } - + } + /* subscribe to the multicast group */ mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr; mreq.imr_interface.s_addr = 0; @@ -153,12 +153,12 @@ int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri) { struct sockaddr_in *data_addr = pri->mcast_addr; - return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr))); + return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)); } static int mcast_set_mtu(int mtu, void *data) { - return(mtu); + return mtu; } const struct net_user_info mcast_user_info = { diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c index 11921a7baa7b..a1747dc0ff6f 100644 --- a/arch/um/drivers/pcap_user.c +++ b/arch/um/drivers/pcap_user.c @@ -42,39 +42,39 @@ static int pcap_open(void *data) int err; if(pri->pcap == NULL) - return(-ENODEV); + return -ENODEV; if(pri->filter != NULL){ err = dev_netmask(pri->dev, &netmask); if(err < 0){ printk("pcap_open : dev_netmask failed\n"); - return(-EIO); + return -EIO; } pri->compiled = um_kmalloc(sizeof(struct bpf_program)); if(pri->compiled == NULL){ printk("pcap_open : kmalloc failed\n"); - return(-ENOMEM); + return -ENOMEM; } - + err = pcap_compile(pri->pcap, (struct bpf_program *) pri->compiled, pri->filter, pri->optimize, netmask); if(err < 0){ printk("pcap_open : pcap_compile failed - '%s'\n", pcap_geterr(pri->pcap)); - return(-EIO); + return -EIO; } err = pcap_setfilter(pri->pcap, pri->compiled); if(err < 0){ printk("pcap_open : pcap_setfilter failed - '%s'\n", pcap_geterr(pri->pcap)); - return(-EIO); + return -EIO; } } - - return(PCAP_FD(pri->pcap)); + + return PCAP_FD(pri->pcap); } static void pcap_remove(void *data) @@ -114,11 +114,11 @@ int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri) n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata); if(n < 0){ printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap)); - return(-EIO); + return -EIO; } else if(n == 0) - return(0); - return(hdata.len); + return 0; + return hdata.len; } const struct net_user_info pcap_user_info = { @@ -131,14 +131,3 @@ const struct net_user_info pcap_user_info = { .delete_address = NULL, .max_packet = MAX_PACKET - ETH_HEADER_OTHER }; - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index b94d2bc4fe06..039572cbedfe 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -47,8 +47,8 @@ int start_io_thread(unsigned long sp, int *fd_out) pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD, NULL); if(pid < 0){ - printk("start_io_thread - clone failed : errno = %d\n", errno); err = -errno; + printk("start_io_thread - clone failed : errno = %d\n", errno); goto out_close; } @@ -60,16 +60,5 @@ int start_io_thread(unsigned long sp, int *fd_out) kernel_fd = -1; *fd_out = -1; out: - return(err); + return err; } - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index 863981ba1468..f3ad0dac7cdc 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -121,7 +121,7 @@ static int etap_tramp(char *dev, char *gate, int control_me, n = os_read_file(control_me, &c, sizeof(c)); if(n != sizeof(c)){ printk("etap_tramp : read of status failed, err = %d\n", -n); - return(-EINVAL); + return -EINVAL; } if(c != 1){ printk("etap_tramp : uml_net failed\n"); @@ -132,7 +132,7 @@ static int etap_tramp(char *dev, char *gate, int control_me, else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)) printk("uml_net didn't exit with status 1\n"); } - return(err); + return err; } static int etap_open(void *data) @@ -142,20 +142,21 @@ static int etap_open(void *data) int data_fds[2], control_fds[2], err, output_len; err = tap_open_common(pri->dev, pri->gate_addr); - if(err) return(err); + if(err) + return err; err = os_pipe(data_fds, 0, 0); if(err < 0){ printk("data os_pipe failed - err = %d\n", -err); - return(err); + return err; } err = os_pipe(control_fds, 1, 0); if(err < 0){ printk("control os_pipe failed - err = %d\n", -err); - return(err); + return err; } - + err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], control_fds[1], data_fds[0], data_fds[1]); output_len = page_size(); @@ -171,13 +172,13 @@ static int etap_open(void *data) if(err < 0){ printk("etap_tramp failed - err = %d\n", -err); - return(err); + return err; } pri->data_fd = data_fds[0]; pri->control_fd = control_fds[0]; iter_addresses(pri->dev, etap_open_addr, &pri->control_fd); - return(data_fds[0]); + return data_fds[0]; } static void etap_close(int fd, void *data) @@ -195,7 +196,7 @@ static void etap_close(int fd, void *data) static int etap_set_mtu(int mtu, void *data) { - return(mtu); + return mtu; } static void etap_add_addr(unsigned char *addr, unsigned char *netmask, @@ -204,7 +205,8 @@ static void etap_add_addr(unsigned char *addr, unsigned char *netmask, struct ethertap_data *pri = data; tap_check_ips(pri->gate_addr, addr); - if(pri->control_fd == -1) return; + if(pri->control_fd == -1) + return; etap_open_addr(addr, netmask, &pri->control_fd); } @@ -213,7 +215,8 @@ static void etap_del_addr(unsigned char *addr, unsigned char *netmask, { struct ethertap_data *pri = data; - if(pri->control_fd == -1) return; + if(pri->control_fd == -1) + return; etap_close_addr(addr, netmask, &pri->control_fd); } @@ -227,14 +230,3 @@ const struct net_user_info ethertap_user_info = { .delete_address = etap_del_addr, .max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP }; - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index e846b23f7558..ab63fb6f9992 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -37,7 +37,8 @@ static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask, struct tuntap_data *pri = data; tap_check_ips(pri->gate_addr, addr); - if((pri->fd == -1) || pri->fixed_config) return; + if((pri->fd == -1) || pri->fixed_config) + return; open_addr(addr, netmask, pri->dev_name); } @@ -46,7 +47,8 @@ static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask, { struct tuntap_data *pri = data; - if((pri->fd == -1) || pri->fixed_config) return; + if((pri->fd == -1) || pri->fixed_config) + return; close_addr(addr, netmask, pri->dev_name); } @@ -58,7 +60,7 @@ struct tuntap_pre_exec_data { static void tuntap_pre_exec(void *arg) { struct tuntap_pre_exec_data *data = arg; - + dup2(data->stdout, 1); os_close_file(data->close_me); } @@ -83,7 +85,8 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, pid = run_helper(tuntap_pre_exec, &data, argv, NULL); - if(pid < 0) return(-pid); + if(pid < 0) + return -pid; os_close_file(remote); @@ -114,16 +117,16 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, cmsg = CMSG_FIRSTHDR(&msg); if(cmsg == NULL){ printk("tuntap_open_tramp : didn't receive a message\n"); - return(-EINVAL); + return -EINVAL; } if((cmsg->cmsg_level != SOL_SOCKET) || (cmsg->cmsg_type != SCM_RIGHTS)){ printk("tuntap_open_tramp : didn't receive a descriptor\n"); - return(-EINVAL); + return -EINVAL; } *fd_out = ((int *) CMSG_DATA(cmsg))[0]; os_set_exec_close(*fd_out, 1); - return(0); + return 0; } static int tuntap_open(void *data) @@ -135,7 +138,7 @@ static int tuntap_open(void *data) err = tap_open_common(pri->dev, pri->gate_addr); if(err < 0) - return(err); + return err; if(pri->fixed_config){ pri->fd = os_open_file("/dev/net/tun", @@ -143,7 +146,7 @@ static int tuntap_open(void *data) if(pri->fd < 0){ printk("Failed to open /dev/net/tun, err = %d\n", -pri->fd); - return(pri->fd); + return pri->fd; } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; @@ -160,7 +163,7 @@ static int tuntap_open(void *data) if(err < 0){ printk("tuntap_open : os_pipe failed - err = %d\n", -err); - return(err); + return err; } buffer = get_output_buffer(&len); @@ -175,7 +178,7 @@ static int tuntap_open(void *data) printk("%s", output); free_output_buffer(buffer); printk("tuntap_open_tramp failed - err = %d\n", -err); - return(err); + return err; } pri->dev_name = uml_strdup(buffer); @@ -187,7 +190,7 @@ static int tuntap_open(void *data) iter_addresses(pri->dev, open_addr, pri->dev_name); } - return(pri->fd); + return pri->fd; } static void tuntap_close(int fd, void *data) @@ -202,7 +205,7 @@ static void tuntap_close(int fd, void *data) static int tuntap_set_mtu(int mtu, void *data) { - return(mtu); + return mtu; } const struct net_user_info tuntap_user_info = { @@ -215,14 +218,3 @@ const struct net_user_info tuntap_user_info = { .delete_address = tuntap_del_addr, .max_packet = MAX_PACKET }; - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ -- cgit v1.2.3-59-g8ed1b From b16895b63c504698b0c3ab26ca3c41a4fa162a42 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 6 May 2007 14:51:03 -0700 Subject: uml-driver-formatting-fixes-fix Cc: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 77d3fdb0c21a..ed24eab647dd 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -158,7 +158,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) */ err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0); if(err < 0){ - printk("fork of winch_thread failed - errno = %d\n", err); + printk("fork of winch_thread failed - errno = %d\n", -err); goto out_close; } -- cgit v1.2.3-59-g8ed1b From f34d9d2dcb7f17b64124841345b23adc0843e7a5 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:04 -0700 Subject: uml: network interface hotplug error handling This fixes a number of problems associated with network interface hotplug. The userspace initialization function can fail in some cases, but the failure was never passed back to eth_configure, which proceeded with the configuration. This results in a zombie device that is present, but can't work. This is fixed by allowing the initialization routines to return an error, which is checked, and the configuration aborted on failure. eth_configure failed to check for many failures. Even when it did check, it didn't undo whatever initializations has already happened, so a present, but partially initialized and non-working device could result. It now checks everything that can fail, and bails out, undoing whatever had been done. The return value of eth_configure was always ignored, so it is now just void. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/daemon_user.c | 5 +- arch/um/drivers/mcast_user.c | 3 +- arch/um/drivers/net_kern.c | 81 ++++++++++++++++++-------------- arch/um/drivers/pcap_user.c | 5 +- arch/um/drivers/slip_user.c | 3 +- arch/um/drivers/slirp_user.c | 3 +- arch/um/include/net_user.h | 2 +- arch/um/os-Linux/drivers/ethertap_user.c | 3 +- arch/um/os-Linux/drivers/tuntap_user.c | 3 +- 9 files changed, 64 insertions(+), 44 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index 09d1de90297c..d0b656a517d3 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -123,7 +123,7 @@ static int connect_to_switch(struct daemon_data *pri) return err; } -static void daemon_user_init(void *data, void *dev) +static int daemon_user_init(void *data, void *dev) { struct daemon_data *pri = data; struct timeval tv; @@ -146,7 +146,10 @@ static void daemon_user_init(void *data, void *dev) if(pri->fd < 0){ kfree(pri->local_addr); pri->local_addr = NULL; + return pri->fd; } + + return 0; } static int daemon_open(void *data) diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c index cfaa2cc43139..0f64d9467286 100644 --- a/arch/um/drivers/mcast_user.c +++ b/arch/um/drivers/mcast_user.c @@ -42,12 +42,13 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port) return sin; } -static void mcast_user_init(void *data, void *dev) +static int mcast_user_init(void *data, void *dev) { struct mcast_data *pri = data; pri->mcast_addr = new_addr(pri->addr, pri->port); pri->dev = dev; + return 0; } static void mcast_remove(void *data) diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 859303730b2f..ac746fb5d10f 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -325,8 +325,8 @@ static struct platform_driver uml_net_driver = { }; static int driver_registered; -static int eth_configure(int n, void *init, char *mac, - struct transport *transport) +static void eth_configure(int n, void *init, char *mac, + struct transport *transport) { struct uml_net *device; struct net_device *dev; @@ -339,16 +339,12 @@ static int eth_configure(int n, void *init, char *mac, device = kzalloc(sizeof(*device), GFP_KERNEL); if (device == NULL) { printk(KERN_ERR "eth_configure failed to allocate uml_net\n"); - return(1); + return; } INIT_LIST_HEAD(&device->list); device->index = n; - spin_lock(&devices_lock); - list_add(&device->list, &devices); - spin_unlock(&devices_lock); - setup_etheraddr(mac, device->mac); printk(KERN_INFO "Netdevice %d ", n); @@ -360,7 +356,7 @@ static int eth_configure(int n, void *init, char *mac, dev = alloc_etherdev(size); if (dev == NULL) { printk(KERN_ERR "eth_configure: failed to allocate device\n"); - return 1; + goto out_free_device; } lp = dev->priv; @@ -376,7 +372,8 @@ static int eth_configure(int n, void *init, char *mac, } device->pdev.id = n; device->pdev.name = DRIVER_NAME; - platform_device_register(&device->pdev); + if(platform_device_register(&device->pdev)) + goto out_free_netdev; SET_NETDEV_DEV(dev,&device->pdev.dev); /* If this name ends up conflicting with an existing registered @@ -386,31 +383,12 @@ static int eth_configure(int n, void *init, char *mac, snprintf(dev->name, sizeof(dev->name), "eth%d", n); device->dev = dev; + /* + * These just fill in a data structure, so there's no failure + * to be worried about. + */ (*transport->kern->init)(dev, init); - dev->mtu = transport->user->max_packet; - dev->open = uml_net_open; - dev->hard_start_xmit = uml_net_start_xmit; - dev->stop = uml_net_close; - dev->get_stats = uml_net_get_stats; - dev->set_multicast_list = uml_net_set_multicast_list; - dev->tx_timeout = uml_net_tx_timeout; - dev->set_mac_address = uml_net_set_mac; - dev->change_mtu = uml_net_change_mtu; - dev->ethtool_ops = ¨_net_ethtool_ops; - dev->watchdog_timeo = (HZ >> 1); - dev->irq = UM_ETH_IRQ; - - rtnl_lock(); - err = register_netdevice(dev); - rtnl_unlock(); - if (err) { - device->dev = NULL; - /* XXX: should we call ->remove() here? */ - free_netdev(dev); - return 1; - } - /* lp.user is the first four bytes of the transport data, which * has already been initialized. This structure assignment will * overwrite that, so we make sure that .user gets overwritten with @@ -438,12 +416,45 @@ static int eth_configure(int n, void *init, char *mac, lp->tl.function = uml_net_user_timer_expire; memcpy(lp->mac, device->mac, sizeof(lp->mac)); - if (transport->user->init) - (*transport->user->init)(&lp->user, dev); + if ((transport->user->init != NULL) && + ((*transport->user->init)(&lp->user, dev) != 0)) + goto out_unregister; set_ether_mac(dev, device->mac); + dev->mtu = transport->user->max_packet; + dev->open = uml_net_open; + dev->hard_start_xmit = uml_net_start_xmit; + dev->stop = uml_net_close; + dev->get_stats = uml_net_get_stats; + dev->set_multicast_list = uml_net_set_multicast_list; + dev->tx_timeout = uml_net_tx_timeout; + dev->set_mac_address = uml_net_set_mac; + dev->change_mtu = uml_net_change_mtu; + dev->ethtool_ops = ¨_net_ethtool_ops; + dev->watchdog_timeo = (HZ >> 1); + dev->irq = UM_ETH_IRQ; - return 0; + rtnl_lock(); + err = register_netdevice(dev); + rtnl_unlock(); + if (err) + goto out_undo_user_init; + + spin_lock(&devices_lock); + list_add(&device->list, &devices); + spin_unlock(&devices_lock); + + return; + +out_undo_user_init: + if (transport->user->init != NULL) + (*transport->user->remove)(&lp->user); +out_unregister: + platform_device_unregister(&device->pdev); +out_free_netdev: + free_netdev(dev); +out_free_device: ; + kfree(device); } static struct uml_net *find_device(int n) diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c index a1747dc0ff6f..dc0a903ef9a6 100644 --- a/arch/um/drivers/pcap_user.c +++ b/arch/um/drivers/pcap_user.c @@ -18,7 +18,7 @@ #define PCAP_FD(p) (*(int *)(p)) -static void pcap_user_init(void *data, void *dev) +static int pcap_user_init(void *data, void *dev) { struct pcap_data *pri = data; pcap_t *p; @@ -28,11 +28,12 @@ static void pcap_user_init(void *data, void *dev) if(p == NULL){ printk("pcap_user_init : pcap_open_live failed - '%s'\n", errors); - return; + return -EINVAL; } pri->dev = dev; pri->pcap = p; + return 0; } static int pcap_open(void *data) diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index 7eddacc53b6e..329c072d17d1 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -17,11 +17,12 @@ #include "os.h" #include "um_malloc.h" -void slip_user_init(void *data, void *dev) +static int slip_user_init(void *data, void *dev) { struct slip_data *pri = data; pri->dev = dev; + return 0; } static int set_up_tty(int fd) diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c index ce5e85d1de3d..f0a40abc8abf 100644 --- a/arch/um/drivers/slirp_user.c +++ b/arch/um/drivers/slirp_user.c @@ -15,11 +15,12 @@ #include "slip_common.h" #include "os.h" -void slirp_user_init(void *data, void *dev) +static int slirp_user_init(void *data, void *dev) { struct slirp_data *pri = data; pri->dev = dev; + return 0; } struct slirp_pre_exec_data { diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h index 19f207cd70fe..cfe7c50634b9 100644 --- a/arch/um/include/net_user.h +++ b/arch/um/include/net_user.h @@ -14,7 +14,7 @@ #define UML_NET_VERSION (4) struct net_user_info { - void (*init)(void *, void *); + int (*init)(void *, void *); int (*open)(void *); void (*close)(int, void *); void (*remove)(void *); diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index f3ad0dac7cdc..2cc2d3ea2e6d 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -24,11 +24,12 @@ #define MAX_PACKET ETH_MAX_PACKET -void etap_user_init(void *data, void *dev) +static int etap_user_init(void *data, void *dev) { struct ethertap_data *pri = data; pri->dev = dev; + return 0; } struct addr_change { diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index ab63fb6f9992..506ef09d83a0 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -24,11 +24,12 @@ #define MAX_PACKET ETH_MAX_PACKET -void tuntap_user_init(void *data, void *dev) +static int tuntap_user_init(void *data, void *dev) { struct tuntap_data *pri = data; pri->dev = dev; + return 0; } static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask, -- cgit v1.2.3-59-g8ed1b From c5e631cf65f4d6875efcd571275436f2964a8b48 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 6 May 2007 14:51:05 -0700 Subject: ARRAY_SIZE: check for type We can use a gcc extension to ensure that ARRAY_SIZE() is handed an array, not a pointer. This is especially important when code is changed from a fixed array to a pointer. I assume the Intel compiler doesn't support __builtin_types_compatible_p. [jdike@addtoit.com: uml: update UML definition of ARRAY_SIZE] Signed-off-by: Rusty Russell Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/user_util.h | 15 +++++++++++++-- include/linux/compiler-gcc.h | 3 +++ include/linux/compiler-intel.h | 3 +++ include/linux/kernel.h | 3 ++- 4 files changed, 21 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index 73ffea1829fc..b52bc4084830 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -8,8 +8,19 @@ #include "sysdep/ptrace.h" -/* Copied from kernel.h */ -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +/* Copied from kernel.h and compiler-gcc.h */ + +/* Force a compilation error if condition is true, but also produce a + result (of value 0 and type size_t), so the expression can be used + e.g. in a structure initializer (or where-ever else comma expressions + aren't permitted). */ +#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1) + +/* &a[0] degrades to a pointer: a different type from an array */ +#define __must_be_array(a) \ + BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0]))) + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) #define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 9008eabb9c3d..a9f794716a81 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -22,6 +22,9 @@ __asm__ ("" : "=r"(__ptr) : "0"(ptr)); \ (typeof(ptr)) (__ptr + (off)); }) +/* &a[0] degrades to a pointer: a different type from an array */ +#define __must_be_array(a) \ + BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0]))) #define inline inline __attribute__((always_inline)) #define __inline__ __inline__ __attribute__((always_inline)) diff --git a/include/linux/compiler-intel.h b/include/linux/compiler-intel.h index a436eea43912..b769961e6f23 100644 --- a/include/linux/compiler-intel.h +++ b/include/linux/compiler-intel.h @@ -21,6 +21,9 @@ __ptr = (unsigned long) (ptr); \ (typeof(ptr)) (__ptr + (off)); }) +/* Intel ECC compiler doesn't support __builtin_types_compatible_p() */ +#define __must_be_array(a) 0 + #endif #define uninitialized_var(x) x diff --git a/include/linux/kernel.h b/include/linux/kernel.h index e2f41b051b12..144b615f3a89 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -35,7 +35,8 @@ extern const char linux_proc_banner[]; #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) + #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) -- cgit v1.2.3-59-g8ed1b From c65badbdf5dc117e45873e760f807063ad59a854 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:06 -0700 Subject: uml: move SIGIO testing to sigio.c This patch narrows the sigio interface. The boot-time SIGIO testing used to be in start_up.c, which meant that pty_output_sigio and pty_close_sigio needed to be global. By moving that code here, those can become static and the declarations moved from user_util.h. os_check_bugs is also here because it only does the SIGIO checking. If it does more, it'll probably move back to start_up.c. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/user_util.h | 3 - arch/um/os-Linux/sigio.c | 145 ++++++++++++++++++++++++++++++++++++++++++++ arch/um/os-Linux/start_up.c | 145 -------------------------------------------- 3 files changed, 145 insertions(+), 148 deletions(-) (limited to 'arch') diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index b52bc4084830..df4869aa9406 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -51,9 +51,6 @@ extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; extern unsigned long _unprotected_end; extern unsigned long brk_start; -extern int pty_output_sigio; -extern int pty_close_sigio; - extern void *add_signal_handler(int sig, void (*handler)(int)); extern int linux_main(int argc, char **argv); extern void set_cmdline(char *cmd); diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 3fc43b33db66..c61d01bf46e4 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -20,6 +21,7 @@ #include "sigio.h" #include "os.h" #include "um_malloc.h" +#include "init.h" /* Protected by sigio_lock(), also used by sigio_cleanup, which is an * exitcall. @@ -320,6 +322,10 @@ out_close1: close(l_write_sigio_fds[1]); } +/* Changed during early boot */ +static int pty_output_sigio = 0; +static int pty_close_sigio = 0; + void maybe_sigio_broken(int fd, int read) { int err; @@ -357,3 +363,142 @@ static void sigio_cleanup(void) } __uml_exitcall(sigio_cleanup); + +/* Used as a flag during SIGIO testing early in boot */ +static volatile int got_sigio = 0; + +static void __init handler(int sig) +{ + got_sigio = 1; +} + +struct openpty_arg { + int master; + int slave; + int err; +}; + +static void openpty_cb(void *arg) +{ + struct openpty_arg *info = arg; + + info->err = 0; + if(openpty(&info->master, &info->slave, NULL, NULL, NULL)) + info->err = -errno; +} + +static int async_pty(int master, int slave) +{ + int flags; + + flags = fcntl(master, F_GETFL); + if(flags < 0) + return -errno; + + if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || + (fcntl(master, F_SETOWN, os_getpid()) < 0)) + return -errno; + + if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)) + return -errno; + + return(0); +} + +static void __init check_one_sigio(void (*proc)(int, int)) +{ + struct sigaction old, new; + struct openpty_arg pty = { .master = -1, .slave = -1 }; + int master, slave, err; + + initial_thread_cb(openpty_cb, &pty); + if(pty.err){ + printk("openpty failed, errno = %d\n", -pty.err); + return; + } + + master = pty.master; + slave = pty.slave; + + if((master == -1) || (slave == -1)){ + printk("openpty failed to allocate a pty\n"); + return; + } + + /* Not now, but complain so we now where we failed. */ + err = raw(master); + if (err < 0) + panic("check_sigio : __raw failed, errno = %d\n", -err); + + err = async_pty(master, slave); + if(err < 0) + panic("tty_fds : sigio_async failed, err = %d\n", -err); + + if(sigaction(SIGIO, NULL, &old) < 0) + panic("check_sigio : sigaction 1 failed, errno = %d\n", errno); + new = old; + new.sa_handler = handler; + if(sigaction(SIGIO, &new, NULL) < 0) + panic("check_sigio : sigaction 2 failed, errno = %d\n", errno); + + got_sigio = 0; + (*proc)(master, slave); + + close(master); + close(slave); + + if(sigaction(SIGIO, &old, NULL) < 0) + panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); +} + +static void tty_output(int master, int slave) +{ + int n; + char buf[512]; + + printk("Checking that host ptys support output SIGIO..."); + + memset(buf, 0, sizeof(buf)); + + while(os_write_file(master, buf, sizeof(buf)) > 0) ; + if(errno != EAGAIN) + panic("check_sigio : write failed, errno = %d\n", errno); + while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; + + if(got_sigio){ + printk("Yes\n"); + pty_output_sigio = 1; + } + else if(n == -EAGAIN) printk("No, enabling workaround\n"); + else panic("check_sigio : read failed, err = %d\n", n); +} + +static void tty_close(int master, int slave) +{ + printk("Checking that host ptys support SIGIO on close..."); + + close(slave); + if(got_sigio){ + printk("Yes\n"); + pty_close_sigio = 1; + } + else printk("No, enabling workaround\n"); +} + +void __init check_sigio(void) +{ + if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) && + (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){ + printk("No pseudo-terminals available - skipping pty SIGIO " + "check\n"); + return; + } + check_one_sigio(tty_output); + check_one_sigio(tty_close); +} + +/* Here because it only does the SIGIO testing for now */ +void __init os_check_bugs(void) +{ + check_sigio(); +} diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 1244179e6c83..1540f21d6997 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -553,148 +553,3 @@ int __init parse_iomem(char *str, int *add) out: return 1; } - - -/* Changed during early boot */ -int pty_output_sigio = 0; -int pty_close_sigio = 0; - -/* Used as a flag during SIGIO testing early in boot */ -static volatile int got_sigio = 0; - -static void __init handler(int sig) -{ - got_sigio = 1; -} - -struct openpty_arg { - int master; - int slave; - int err; -}; - -static void openpty_cb(void *arg) -{ - struct openpty_arg *info = arg; - - info->err = 0; - if(openpty(&info->master, &info->slave, NULL, NULL, NULL)) - info->err = -errno; -} - -static int async_pty(int master, int slave) -{ - int flags; - - flags = fcntl(master, F_GETFL); - if(flags < 0) - return -errno; - - if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || - (fcntl(master, F_SETOWN, os_getpid()) < 0)) - return -errno; - - if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)) - return -errno; - - return(0); -} - -static void __init check_one_sigio(void (*proc)(int, int)) -{ - struct sigaction old, new; - struct openpty_arg pty = { .master = -1, .slave = -1 }; - int master, slave, err; - - initial_thread_cb(openpty_cb, &pty); - if(pty.err){ - printk("openpty failed, errno = %d\n", -pty.err); - return; - } - - master = pty.master; - slave = pty.slave; - - if((master == -1) || (slave == -1)){ - printk("openpty failed to allocate a pty\n"); - return; - } - - /* Not now, but complain so we now where we failed. */ - err = raw(master); - if (err < 0) - panic("check_sigio : __raw failed, errno = %d\n", -err); - - err = async_pty(master, slave); - if(err < 0) - panic("tty_fds : sigio_async failed, err = %d\n", -err); - - if(sigaction(SIGIO, NULL, &old) < 0) - panic("check_sigio : sigaction 1 failed, errno = %d\n", errno); - new = old; - new.sa_handler = handler; - if(sigaction(SIGIO, &new, NULL) < 0) - panic("check_sigio : sigaction 2 failed, errno = %d\n", errno); - - got_sigio = 0; - (*proc)(master, slave); - - close(master); - close(slave); - - if(sigaction(SIGIO, &old, NULL) < 0) - panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); -} - -static void tty_output(int master, int slave) -{ - int n; - char buf[512]; - - printk("Checking that host ptys support output SIGIO..."); - - memset(buf, 0, sizeof(buf)); - - while(os_write_file(master, buf, sizeof(buf)) > 0) ; - if(errno != EAGAIN) - panic("check_sigio : write failed, errno = %d\n", errno); - while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; - - if(got_sigio){ - printk("Yes\n"); - pty_output_sigio = 1; - } - else if(n == -EAGAIN) printk("No, enabling workaround\n"); - else panic("check_sigio : read failed, err = %d\n", n); -} - -static void tty_close(int master, int slave) -{ - printk("Checking that host ptys support SIGIO on close..."); - - close(slave); - if(got_sigio){ - printk("Yes\n"); - pty_close_sigio = 1; - } - else printk("No, enabling workaround\n"); -} - -void __init check_sigio(void) -{ - if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) && - (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){ - printk("No pseudo-terminals available - skipping pty SIGIO " - "check\n"); - return; - } - check_one_sigio(tty_output); - check_one_sigio(tty_close); -} - -void os_check_bugs(void) -{ - check_ptrace(); - check_sigio(); -} - -- cgit v1.2.3-59-g8ed1b From eb8307595baa729a12db0fec9a80910b13bd6fc8 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:07 -0700 Subject: uml: create arch.h This patch moves the declarations of the architecture hooks from user_util.h to a new header, arch.c, and adds the necessary includes to files which need those declarations. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/arch.h | 15 +++++++++++++++ arch/um/include/user_util.h | 4 ---- arch/um/kernel/trap.c | 1 + arch/um/kernel/um_arch.c | 1 + 4 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 arch/um/include/arch.h (limited to 'arch') diff --git a/arch/um/include/arch.h b/arch/um/include/arch.h new file mode 100644 index 000000000000..8e11dd7c1adb --- /dev/null +++ b/arch/um/include/arch.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#ifndef __ARCH_H__ +#define __ARCH_H__ + +#include "sysdep/ptrace.h" + +extern void arch_check_bugs(void); +extern int arch_fixup(unsigned long address, void *sc_ptr); +extern int arch_handle_signal(int sig, union uml_pt_regs *regs); + +#endif diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index df4869aa9406..fabad2372af0 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -65,10 +65,6 @@ extern int attach(int pid); extern void kill_child_dead(int pid); extern int cont(int pid); extern void check_sigio(void); -extern void arch_check_bugs(void); -extern int arch_handle_signal(int sig, union uml_pt_regs *regs); -extern int arch_fixup(unsigned long address, void *sc_ptr); -extern void arch_init_thread(void); extern int raw(int fd); #endif diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 26f15c458574..e27b898412fc 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -20,6 +20,7 @@ #include "sysdep/sigcontext.h" #include "user_util.h" #include "kern_util.h" +#include "arch.h" #include "kern.h" #include "chan_kern.h" #include "mconsole_kern.h" diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 613fb082bbd5..8eefb5202c50 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -28,6 +28,7 @@ #include "asm/current.h" #include "user_util.h" #include "kern_util.h" +#include "arch.h" #include "kern.h" #include "mem_user.h" #include "mem.h" -- cgit v1.2.3-59-g8ed1b From 4ff83ce1114827f707b7f1f4f2e5f69de9df94ac Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:08 -0700 Subject: uml: create as-layout.h This patch moves all the the symbols defined in um_arch.c, which are mostly boundaries between different parts of the UML kernel address space, to a new header, as-layout.h. There are also a few things here which aren't really related to address space layout, but which don't really have a better place to go. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/as-layout.h | 35 +++++++++++++++++++++++++++++++++++ arch/um/include/user_util.h | 23 ----------------------- arch/um/kernel/exec.c | 1 + arch/um/kernel/ksyms.c | 1 + arch/um/kernel/mem.c | 1 + arch/um/kernel/physmem.c | 1 + arch/um/kernel/process.c | 1 + arch/um/kernel/skas/process.c | 1 + arch/um/kernel/tlb.c | 1 + arch/um/kernel/trap.c | 1 + arch/um/kernel/um_arch.c | 1 + arch/um/os-Linux/main.c | 1 + arch/um/os-Linux/skas/trap.c | 1 + 13 files changed, 46 insertions(+), 23 deletions(-) create mode 100644 arch/um/include/as-layout.h (limited to 'arch') diff --git a/arch/um/include/as-layout.h b/arch/um/include/as-layout.h new file mode 100644 index 000000000000..fccf187bf4e1 --- /dev/null +++ b/arch/um/include/as-layout.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#ifndef __START_H__ +#define __START_H__ + +#include "sysdep/ptrace.h" + +struct cpu_task { + int pid; + void *task; +}; + +extern struct cpu_task cpu_tasks[]; + +extern unsigned long low_physmem; +extern unsigned long high_physmem; +extern unsigned long uml_physmem; +extern unsigned long uml_reserved; +extern unsigned long end_vm; +extern unsigned long start_vm; +extern unsigned long long highmem; + +extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; +extern unsigned long _unprotected_end; +extern unsigned long brk_start; + +extern int linux_main(int argc, char **argv); +extern void set_cmdline(char *cmd); + +extern void (*sig_info[])(int, union uml_pt_regs *); + +#endif diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index fabad2372af0..f04776e2436f 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -30,30 +30,7 @@ extern int grantpt(int __fd); extern int unlockpt(int __fd); extern char *ptsname(int __fd); -struct cpu_task { - int pid; - void *task; -}; - -extern struct cpu_task cpu_tasks[]; - -extern void (*sig_info[])(int, union uml_pt_regs *); - -extern unsigned long low_physmem; -extern unsigned long high_physmem; -extern unsigned long uml_physmem; -extern unsigned long uml_reserved; -extern unsigned long end_vm; -extern unsigned long start_vm; -extern unsigned long long highmem; - -extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; -extern unsigned long _unprotected_end; -extern unsigned long brk_start; - extern void *add_signal_handler(int sig, void (*handler)(int)); -extern int linux_main(int argc, char **argv); -extern void set_cmdline(char *cmd); extern void input_cb(void (*proc)(void *), void *arg, int arg_len); extern int get_pty(void); extern int switcheroo(int fd, int prot, void *from, void *to, int size); diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 121166400e25..1ada13ea84e4 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -12,6 +12,7 @@ #include "asm/uaccess.h" #include "user_util.h" #include "kern_util.h" +#include "as-layout.h" #include "mem_user.h" #include "kern.h" #include "irq_user.h" diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 0e00cf93f900..288b4ee2041a 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c @@ -16,6 +16,7 @@ #include "asm/page.h" #include "asm/tlbflush.h" #include "kern_util.h" +#include "as-layout.h" #include "user_util.h" #include "mem_user.h" #include "os.h" diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index df7d662b98ce..3a13d41c28d0 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -15,6 +15,7 @@ #include "asm/pgalloc.h" #include "user_util.h" #include "kern_util.h" +#include "as-layout.h" #include "kern.h" #include "mem_user.h" #include "uml_uaccess.h" diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index 638f3b5f6094..f92f06c35db7 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -13,6 +13,7 @@ #include "asm/types.h" #include "asm/pgtable.h" #include "kern_util.h" +#include "as-layout.h" #include "user_util.h" #include "mode_kern.h" #include "mem.h" diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 348b272bb766..e4208386e7af 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -34,6 +34,7 @@ #include "asm/user.h" #include "user_util.h" #include "kern_util.h" +#include "as-layout.h" #include "kern.h" #include "signal_kern.h" #include "init.h" diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index ae4fa71d3b8b..9c2a7d8c56fb 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c @@ -13,6 +13,7 @@ #include "asm/uaccess.h" #include "asm/atomic.h" #include "kern_util.h" +#include "as-layout.h" #include "skas.h" #include "os.h" #include "user_util.h" diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 54a5ff25645a..b8b3cff0668a 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -9,6 +9,7 @@ #include "asm/tlbflush.h" #include "choose-mode.h" #include "mode_kern.h" +#include "as-layout.h" #include "user_util.h" #include "tlb.h" #include "mem.h" diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index e27b898412fc..552bcfc7c085 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -20,6 +20,7 @@ #include "sysdep/sigcontext.h" #include "user_util.h" #include "kern_util.h" +#include "as-layout.h" #include "arch.h" #include "kern.h" #include "chan_kern.h" diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 8eefb5202c50..20684c04d5d5 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -28,6 +28,7 @@ #include "asm/current.h" #include "user_util.h" #include "kern_util.h" +#include "as-layout.h" #include "arch.h" #include "kern.h" #include "mem_user.h" diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 2c089c2c63bf..25261d6c7bf2 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -15,6 +15,7 @@ #include #include "user_util.h" #include "kern_util.h" +#include "as-layout.h" #include "mem_user.h" #include "irq_user.h" #include "user.h" diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c index 9ad5fbec4593..19ff04bdec90 100644 --- a/arch/um/os-Linux/skas/trap.c +++ b/arch/um/os-Linux/skas/trap.c @@ -7,6 +7,7 @@ #include #include "user_util.h" #include "kern_util.h" +#include "as-layout.h" #include "task.h" #include "sigcontext.h" #include "skas.h" -- cgit v1.2.3-59-g8ed1b From 24fa6c0832f4513ac897082d7d803970a40cc1b0 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:09 -0700 Subject: uml: move remaining useful contents of user_util.h Rescue the useful contents of the soon-to-be-gone user-util.h. pty.c now gets ptsname from stdlib.h like it should have always done. CATCH_EINTR is now in os.h, although perhaps all usage should be under os-Linux at some point. get_pty is also in os.h. This patch restores the old definition of ARRAY_SIZE in user.h. This file is included only in userspace files, so there will be no conflict with the kernel's new ARRAY_SIZE. The copy of the kernel's ARRAY_SIZE and associated infrastructure is now gone. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/pty.c | 1 + arch/um/include/os.h | 6 ++++++ arch/um/include/user.h | 19 ++++++++----------- arch/um/include/user_util.h | 18 ------------------ arch/um/os-Linux/sys-i386/tls.c | 1 + 5 files changed, 16 insertions(+), 29 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c index 829a5eca8c07..aa311afa9667 100644 --- a/arch/um/drivers/pty.c +++ b/arch/um/drivers/pty.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 22666b4a8be7..394adcded0bf 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -16,6 +16,8 @@ #include "sysdep/tls.h" #include "sysdep/archsetjmp.h" +#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) + #define OS_TYPE_FILE 1 #define OS_TYPE_DIR 2 #define OS_TYPE_SYMLINK 3 @@ -341,6 +343,10 @@ extern void maybe_sigio_broken(int fd, int read); extern void sig_handler_common_skas(int sig, void *sc_ptr); extern void user_signal(int sig, union uml_pt_regs *regs, int pid); +/* sys-x86_64/prctl.c */ extern int os_arch_prctl(int pid, int code, unsigned long *addr); +/* tty.c */ +int get_pty(void); + #endif diff --git a/arch/um/include/user.h b/arch/um/include/user.h index acadce3f271f..a6da62608254 100644 --- a/arch/um/include/user.h +++ b/arch/um/include/user.h @@ -6,6 +6,14 @@ #ifndef __USER_H__ #define __USER_H__ +/* + * The usual definition - copied here because the kernel provides its own, + * fancier, type-safe, definition. Using that one would require + * copying too much infrastructure for my taste, so userspace files + * get less checking than kernel files. + */ +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + extern void panic(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); extern int printk(const char *fmt, ...) @@ -18,14 +26,3 @@ extern unsigned long strlcpy(char *, const char *, unsigned long); extern unsigned long strlcat(char *, const char *, unsigned long); #endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index f04776e2436f..7fa5c68f0620 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -8,31 +8,13 @@ #include "sysdep/ptrace.h" -/* Copied from kernel.h and compiler-gcc.h */ - -/* Force a compilation error if condition is true, but also produce a - result (of value 0 and type size_t), so the expression can be used - e.g. in a structure initializer (or where-ever else comma expressions - aren't permitted). */ -#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1) - -/* &a[0] degrades to a pointer: a different type from an array */ -#define __must_be_array(a) \ - BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0]))) - -#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) - -#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) - extern int mode_tt; extern int grantpt(int __fd); extern int unlockpt(int __fd); -extern char *ptsname(int __fd); extern void *add_signal_handler(int sig, void (*handler)(int)); extern void input_cb(void (*proc)(void *), void *arg, int arg_len); -extern int get_pty(void); extern int switcheroo(int fd, int prot, void *from, void *to, int size); extern void do_exec(int old_pid, int new_pid); extern void tracer_panic(char *msg, ...) diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c index 256532034c62..8ba132482970 100644 --- a/arch/um/os-Linux/sys-i386/tls.c +++ b/arch/um/os-Linux/sys-i386/tls.c @@ -5,6 +5,7 @@ #include #include "sysdep/tls.h" +#include "user.h" #include "user_util.h" /* Checks whether host supports TLS, and sets *tls_min according to the value -- cgit v1.2.3-59-g8ed1b From 9218b1714949095bff9d9739d80f431d58e561d6 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:10 -0700 Subject: uml: remove user_util.h user_util.h isn't needed any more, so delete it and remove all includes of it. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_kern.c | 1 - arch/um/drivers/chan_user.c | 1 - arch/um/drivers/cow_sys.h | 1 - arch/um/drivers/daemon_user.c | 1 - arch/um/drivers/fd.c | 1 - arch/um/drivers/harddog_user.c | 1 - arch/um/drivers/line.c | 1 - arch/um/drivers/mcast_user.c | 1 - arch/um/drivers/mconsole_kern.c | 1 - arch/um/drivers/mconsole_user.c | 1 - arch/um/drivers/mmapper_kern.c | 1 - arch/um/drivers/net_kern.c | 1 - arch/um/drivers/net_user.c | 1 - arch/um/drivers/port_user.c | 1 - arch/um/drivers/pty.c | 1 - arch/um/drivers/slip_user.c | 1 - arch/um/drivers/slirp_user.c | 1 - arch/um/drivers/ssl.c | 1 - arch/um/drivers/stdio_console.c | 1 - arch/um/drivers/tty.c | 1 - arch/um/drivers/ubd_kern.c | 1 - arch/um/drivers/ubd_user.c | 1 - arch/um/drivers/xterm.c | 1 - arch/um/include/user_util.h | 29 ----------------------------- arch/um/kernel/exec.c | 1 - arch/um/kernel/init_task.c | 1 - arch/um/kernel/initrd.c | 1 - arch/um/kernel/irq.c | 1 - arch/um/kernel/ksyms.c | 1 - arch/um/kernel/mem.c | 1 - arch/um/kernel/physmem.c | 1 - arch/um/kernel/process.c | 1 - arch/um/kernel/reboot.c | 1 - arch/um/kernel/signal.c | 1 - arch/um/kernel/skas/process.c | 1 - arch/um/kernel/skas/tlb.c | 1 - arch/um/kernel/smp.c | 1 - arch/um/kernel/syscall.c | 1 - arch/um/kernel/sysrq.c | 1 - arch/um/kernel/time.c | 1 - arch/um/kernel/tlb.c | 1 - arch/um/kernel/trap.c | 1 - arch/um/kernel/tt/exec_kern.c | 1 - arch/um/kernel/tt/exec_user.c | 1 - arch/um/kernel/tt/gdb.c | 1 - arch/um/kernel/tt/mem.c | 1 - arch/um/kernel/tt/mem_user.c | 1 - arch/um/kernel/tt/process_kern.c | 1 - arch/um/kernel/tt/ptproxy/proxy.c | 1 - arch/um/kernel/tt/ptproxy/ptrace.c | 1 - arch/um/kernel/tt/ptproxy/sysdep.c | 1 - arch/um/kernel/tt/ptproxy/wait.c | 1 - arch/um/kernel/tt/syscall_user.c | 1 - arch/um/kernel/tt/tlb.c | 1 - arch/um/kernel/tt/tracer.c | 1 - arch/um/kernel/tt/trap_user.c | 1 - arch/um/kernel/tt/uaccess_user.c | 1 - arch/um/kernel/um_arch.c | 1 - arch/um/os-Linux/drivers/ethertap_user.c | 1 - arch/um/os-Linux/drivers/tuntap_user.c | 1 - arch/um/os-Linux/file.c | 1 - arch/um/os-Linux/helper.c | 1 - arch/um/os-Linux/irq.c | 1 - arch/um/os-Linux/main.c | 1 - arch/um/os-Linux/mem.c | 1 - arch/um/os-Linux/process.c | 1 - arch/um/os-Linux/sigio.c | 1 - arch/um/os-Linux/signal.c | 1 - arch/um/os-Linux/skas/mem.c | 1 - arch/um/os-Linux/skas/process.c | 1 - arch/um/os-Linux/skas/trap.c | 1 - arch/um/os-Linux/start_up.c | 1 - arch/um/os-Linux/sys-i386/tls.c | 1 - arch/um/os-Linux/time.c | 1 - arch/um/os-Linux/trap.c | 1 - arch/um/os-Linux/tt.c | 1 - arch/um/os-Linux/util.c | 1 - arch/um/sys-i386/bugs.c | 1 - arch/um/sys-i386/ptrace_user.c | 1 - arch/um/sys-ppc/sigcontext.c | 1 - 80 files changed, 108 deletions(-) delete mode 100644 arch/um/include/user_util.h (limited to 'arch') diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 9fdfad649536..3aa351611763 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -12,7 +12,6 @@ #include #include #include "chan_kern.h" -#include "user_util.h" #include "kern.h" #include "irq_user.h" #include "sigio.h" diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index ed24eab647dd..ee53cf882f42 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -14,7 +14,6 @@ #include #include #include "kern_util.h" -#include "user_util.h" #include "chan_user.h" #include "user.h" #include "os.h" diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index c6a308464acb..c702943769cb 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h @@ -2,7 +2,6 @@ #define __COW_SYS_H__ #include "kern_util.h" -#include "user_util.h" #include "os.h" #include "user.h" #include "um_malloc.h" diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index d0b656a517d3..b869e3899683 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -14,7 +14,6 @@ #include "net_user.h" #include "daemon.h" #include "kern_util.h" -#include "user_util.h" #include "user.h" #include "os.h" #include "um_malloc.h" diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c index 218aa0e9b792..7f083ec47a4f 100644 --- a/arch/um/drivers/fd.c +++ b/arch/um/drivers/fd.c @@ -9,7 +9,6 @@ #include #include #include "user.h" -#include "user_util.h" #include "chan_user.h" #include "os.h" #include "um_malloc.h" diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c index c495ecf263b1..5eeecf8917c3 100644 --- a/arch/um/drivers/harddog_user.c +++ b/arch/um/drivers/harddog_user.c @@ -6,7 +6,6 @@ #include #include #include -#include "user_util.h" #include "user.h" #include "mconsole.h" #include "os.h" diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index f75d7b05c481..ced99106f798 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -13,7 +13,6 @@ #include "irq_user.h" #include "line.h" #include "kern.h" -#include "user_util.h" #include "kern_util.h" #include "os.h" #include "irq_kern.h" diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c index 0f64d9467286..d319db16d4ec 100644 --- a/arch/um/drivers/mcast_user.c +++ b/arch/um/drivers/mcast_user.c @@ -20,7 +20,6 @@ #include "net_user.h" #include "mcast.h" #include "kern_util.h" -#include "user_util.h" #include "user.h" #include "os.h" #include "um_malloc.h" diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 65ad2932672c..542c9ef858f8 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -25,7 +25,6 @@ #include "linux/console.h" #include "asm/irq.h" #include "asm/uaccess.h" -#include "user_util.h" #include "kern_util.h" #include "kern.h" #include "mconsole.h" diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c index f02634fbf32a..62e5ad63181a 100644 --- a/arch/um/drivers/mconsole_user.c +++ b/arch/um/drivers/mconsole_user.c @@ -17,7 +17,6 @@ #include "sysdep/ptrace.h" #include "mconsole.h" #include "os.h" -#include "user_util.h" static struct mconsole_command commands[] = { /* With uts namespaces, uts information becomes process-specific, so diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index df3516e47d4d..e41a08f04694 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c @@ -15,7 +15,6 @@ #include #include #include "mem_user.h" -#include "user_util.h" /* These are set in mmapper_init, which is called at boot time */ static unsigned long mmapper_size; diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index ac746fb5d10f..20963f106c34 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -21,7 +21,6 @@ #include "linux/ethtool.h" #include "linux/platform_device.h" #include "asm/uaccess.h" -#include "user_util.h" #include "kern_util.h" #include "net_kern.h" #include "net_user.h" diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 0ffd7ac295d4..b63a86046374 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -14,7 +14,6 @@ #include #include #include "user.h" -#include "user_util.h" #include "kern_util.h" #include "net_user.h" #include "os.h" diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c index 80508023054f..3f6357d24bee 100644 --- a/arch/um/drivers/port_user.c +++ b/arch/um/drivers/port_user.c @@ -13,7 +13,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "chan_user.h" diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c index aa311afa9667..df4976c9eef2 100644 --- a/arch/um/drivers/pty.c +++ b/arch/um/drivers/pty.c @@ -11,7 +11,6 @@ #include #include "chan_user.h" #include "user.h" -#include "user_util.h" #include "kern_util.h" #include "os.h" #include "um_malloc.h" diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index 329c072d17d1..9f41cece0916 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -8,7 +8,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "net_user.h" diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c index f0a40abc8abf..39f889fe9949 100644 --- a/arch/um/drivers/slirp_user.c +++ b/arch/um/drivers/slirp_user.c @@ -7,7 +7,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "net_user.h" diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index 4b382a6e710f..94faadc5ea1b 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c @@ -15,7 +15,6 @@ #include "line.h" #include "ssl.h" #include "chan_kern.h" -#include "user_util.h" #include "kern_util.h" #include "kern.h" #include "init.h" diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 76d1f1c980ef..90a2c5cc17d4 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c @@ -22,7 +22,6 @@ #include "stdio_console.h" #include "line.h" #include "chan_kern.h" -#include "user_util.h" #include "kern_util.h" #include "irq_user.h" #include "mconsole_kern.h" diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c index d95d64309eaf..c07d0d562780 100644 --- a/arch/um/drivers/tty.c +++ b/arch/um/drivers/tty.c @@ -8,7 +8,6 @@ #include #include #include "chan_user.h" -#include "user_util.h" #include "user.h" #include "os.h" #include "um_malloc.h" diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 53c36d1770c5..962b8fb35f80 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -39,7 +39,6 @@ #include "asm/irq.h" #include "asm/types.h" #include "asm/tlbflush.h" -#include "user_util.h" #include "mem_user.h" #include "kern_util.h" #include "kern.h" diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index 039572cbedfe..4707b3f14c2f 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -16,7 +16,6 @@ #include #include #include "asm/types.h" -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "ubd_user.h" diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c index 850221d9b4c9..571c2b3325d5 100644 --- a/arch/um/drivers/xterm.c +++ b/arch/um/drivers/xterm.c @@ -14,7 +14,6 @@ #include #include "kern_util.h" #include "chan_user.h" -#include "user_util.h" #include "user.h" #include "os.h" #include "xterm.h" diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h deleted file mode 100644 index 7fa5c68f0620..000000000000 --- a/arch/um/include/user_util.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __USER_UTIL_H__ -#define __USER_UTIL_H__ - -#include "sysdep/ptrace.h" - -extern int mode_tt; - -extern int grantpt(int __fd); -extern int unlockpt(int __fd); - -extern void *add_signal_handler(int sig, void (*handler)(int)); -extern void input_cb(void (*proc)(void *), void *arg, int arg_len); -extern int switcheroo(int fd, int prot, void *from, void *to, int size); -extern void do_exec(int old_pid, int new_pid); -extern void tracer_panic(char *msg, ...) - __attribute__ ((format (printf, 1, 2))); -extern int detach(int pid, int sig); -extern int attach(int pid); -extern void kill_child_dead(int pid); -extern int cont(int pid); -extern void check_sigio(void); -extern int raw(int fd); - -#endif diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 1ada13ea84e4..356e50f5aaed 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -10,7 +10,6 @@ #include "asm/pgtable.h" #include "asm/tlbflush.h" #include "asm/uaccess.h" -#include "user_util.h" #include "kern_util.h" #include "as-layout.h" #include "mem_user.h" diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c index 8cde431348cc..cda91aa8e703 100644 --- a/arch/um/kernel/init_task.c +++ b/arch/um/kernel/init_task.c @@ -10,7 +10,6 @@ #include "linux/mqueue.h" #include "asm/uaccess.h" #include "asm/pgtable.h" -#include "user_util.h" #include "mem_user.h" #include "os.h" diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index 82ecf904b09c..6ab1539108e1 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c @@ -7,7 +7,6 @@ #include "linux/bootmem.h" #include "linux/initrd.h" #include "asm/types.h" -#include "user_util.h" #include "kern_util.h" #include "initrd.h" #include "init.h" diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index dbf2f5bc842f..a1e8c460b755 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -25,7 +25,6 @@ #include "asm/system.h" #include "asm/errno.h" #include "asm/uaccess.h" -#include "user_util.h" #include "kern_util.h" #include "irq_user.h" #include "irq_kern.h" diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 288b4ee2041a..7b3e53fb8070 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c @@ -17,7 +17,6 @@ #include "asm/tlbflush.h" #include "kern_util.h" #include "as-layout.h" -#include "user_util.h" #include "mem_user.h" #include "os.h" diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 3a13d41c28d0..5e93bbf6e482 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -13,7 +13,6 @@ #include "asm/page.h" #include "asm/fixmap.h" #include "asm/pgalloc.h" -#include "user_util.h" #include "kern_util.h" #include "as-layout.h" #include "kern.h" diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index f92f06c35db7..df1ad3ba130c 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -14,7 +14,6 @@ #include "asm/pgtable.h" #include "kern_util.h" #include "as-layout.h" -#include "user_util.h" #include "mode_kern.h" #include "mem.h" #include "mem_user.h" diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index e4208386e7af..90c9ffafc659 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -32,7 +32,6 @@ #include "asm/tlbflush.h" #include "asm/uaccess.h" #include "asm/user.h" -#include "user_util.h" #include "kern_util.h" #include "as-layout.h" #include "kern.h" diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c index f602623644aa..7e4305a1fd3c 100644 --- a/arch/um/kernel/reboot.c +++ b/arch/um/kernel/reboot.c @@ -6,7 +6,6 @@ #include "linux/module.h" #include "linux/sched.h" #include "asm/smp.h" -#include "user_util.h" #include "kern_util.h" #include "kern.h" #include "os.h" diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c index 3c798cdde550..c4020c3d7857 100644 --- a/arch/um/kernel/signal.c +++ b/arch/um/kernel/signal.c @@ -17,7 +17,6 @@ #include "asm/signal.h" #include "asm/uaccess.h" #include "asm/unistd.h" -#include "user_util.h" #include "asm/ucontext.h" #include "kern_util.h" #include "signal_kern.h" diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index 9c2a7d8c56fb..ef36facd8fe9 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c @@ -16,7 +16,6 @@ #include "as-layout.h" #include "skas.h" #include "os.h" -#include "user_util.h" #include "tlb.h" #include "kern.h" #include "mode.h" diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c index 27eb29ce666b..304a5b0695ab 100644 --- a/arch/um/kernel/skas/tlb.c +++ b/arch/um/kernel/skas/tlb.c @@ -10,7 +10,6 @@ #include "asm/page.h" #include "asm/pgtable.h" #include "asm/mmu.h" -#include "user_util.h" #include "mem_user.h" #include "mem.h" #include "skas.h" diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index 759b07053160..62dd093cbcd7 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c @@ -21,7 +21,6 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); #include "asm/smp.h" #include "asm/processor.h" #include "asm/spinlock.h" -#include "user_util.h" #include "kern_util.h" #include "kern.h" #include "irq_user.h" diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index 2828c5283227..237c4eab7cfd 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c @@ -18,7 +18,6 @@ #include "asm/mman.h" #include "asm/uaccess.h" #include "kern_util.h" -#include "user_util.h" #include "sysdep/syscalls.h" #include "mode_kern.h" #include "choose-mode.h" diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c index f9e02b31a97a..93263571d813 100644 --- a/arch/um/kernel/sysrq.c +++ b/arch/um/kernel/sysrq.c @@ -10,7 +10,6 @@ #include "asm/page.h" #include "asm/processor.h" #include "sysrq.h" -#include "user_util.h" /* Catch non-i386 SUBARCH's. */ #if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT) diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index b1f8b0752419..9fd80ee3eef6 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -18,7 +18,6 @@ #include "asm/param.h" #include "asm/current.h" #include "kern_util.h" -#include "user_util.h" #include "mode.h" #include "os.h" diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index b8b3cff0668a..e40f3352bd29 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -10,7 +10,6 @@ #include "choose-mode.h" #include "mode_kern.h" #include "as-layout.h" -#include "user_util.h" #include "tlb.h" #include "mem.h" #include "mem_user.h" diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 552bcfc7c085..2de81d4d9b57 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -18,7 +18,6 @@ #include "asm/current.h" #include "asm/irq.h" #include "sysdep/sigcontext.h" -#include "user_util.h" #include "kern_util.h" #include "as-layout.h" #include "arch.h" diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c index ad66df17d9d7..98e21743e604 100644 --- a/arch/um/kernel/tt/exec_kern.c +++ b/arch/um/kernel/tt/exec_kern.c @@ -10,7 +10,6 @@ #include "asm/uaccess.h" #include "asm/pgalloc.h" #include "asm/tlbflush.h" -#include "user_util.h" #include "kern_util.h" #include "irq_user.h" #include "mem_user.h" diff --git a/arch/um/kernel/tt/exec_user.c b/arch/um/kernel/tt/exec_user.c index a92c02ff2ce3..7b5f2181cf51 100644 --- a/arch/um/kernel/tt/exec_user.c +++ b/arch/um/kernel/tt/exec_user.c @@ -10,7 +10,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "ptrace_user.h" diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c index d284f69f04ee..030e4658f36b 100644 --- a/arch/um/kernel/tt/gdb.c +++ b/arch/um/kernel/tt/gdb.c @@ -17,7 +17,6 @@ #include "user.h" #include "debug.h" #include "kern_util.h" -#include "user_util.h" #include "tt.h" #include "sysdep/thread.h" #include "os.h" diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c index 4d1929dfa285..d0c3c4975f28 100644 --- a/arch/um/kernel/tt/mem.c +++ b/arch/um/kernel/tt/mem.c @@ -8,7 +8,6 @@ #include "asm/uaccess.h" #include "mem_user.h" #include "kern_util.h" -#include "user_util.h" #include "kern.h" #include "tt.h" diff --git a/arch/um/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c index 03e589895388..9774f6360c32 100644 --- a/arch/um/kernel/tt/mem_user.c +++ b/arch/um/kernel/tt/mem_user.c @@ -11,7 +11,6 @@ #include #include "tt.h" #include "mem_user.h" -#include "user_util.h" #include "os.h" void remap_data(void *segment_start, void *segment_end, int w) diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index 1e86f0bfef72..8029f72afaa7 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c @@ -14,7 +14,6 @@ #include "asm/tlbflush.h" #include "irq_user.h" #include "kern_util.h" -#include "user_util.h" #include "os.h" #include "kern.h" #include "sigcontext.h" diff --git a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c index 58800c50b10e..c88e7b5d8a76 100644 --- a/arch/um/kernel/tt/ptproxy/proxy.c +++ b/arch/um/kernel/tt/ptproxy/proxy.c @@ -26,7 +26,6 @@ Jeff Dike (jdike@karaya.com) : Modified for integration into uml #include "sysdep.h" #include "wait.h" -#include "user_util.h" #include "user.h" #include "os.h" #include "tempfile.h" diff --git a/arch/um/kernel/tt/ptproxy/ptrace.c b/arch/um/kernel/tt/ptproxy/ptrace.c index 03774427d468..4b4f6179b212 100644 --- a/arch/um/kernel/tt/ptproxy/ptrace.c +++ b/arch/um/kernel/tt/ptproxy/ptrace.c @@ -16,7 +16,6 @@ Jeff Dike (jdike@karaya.com) : Modified for integration into uml #include "ptproxy.h" #include "debug.h" -#include "user_util.h" #include "kern_util.h" #include "ptrace_user.h" #include "tt.h" diff --git a/arch/um/kernel/tt/ptproxy/sysdep.c b/arch/um/kernel/tt/ptproxy/sysdep.c index 99f178319d03..e0e1ab0588ad 100644 --- a/arch/um/kernel/tt/ptproxy/sysdep.c +++ b/arch/um/kernel/tt/ptproxy/sysdep.c @@ -13,7 +13,6 @@ terms and conditions. #include #include #include "ptrace_user.h" -#include "user_util.h" #include "user.h" #include "os.h" diff --git a/arch/um/kernel/tt/ptproxy/wait.c b/arch/um/kernel/tt/ptproxy/wait.c index 12f6319d8d76..bdd4af4b65fc 100644 --- a/arch/um/kernel/tt/ptproxy/wait.c +++ b/arch/um/kernel/tt/ptproxy/wait.c @@ -13,7 +13,6 @@ terms and conditions. #include "ptproxy.h" #include "sysdep.h" #include "wait.h" -#include "user_util.h" #include "ptrace_user.h" #include "sysdep/ptrace.h" #include "sysdep/sigcontext.h" diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c index 902987bf379b..f52b47aff1d2 100644 --- a/arch/um/kernel/tt/syscall_user.c +++ b/arch/um/kernel/tt/syscall_user.c @@ -11,7 +11,6 @@ #include "sigcontext.h" #include "ptrace_user.h" #include "task.h" -#include "user_util.h" #include "kern_util.h" #include "syscall.h" #include "tt.h" diff --git a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c index ae6217c86135..7caa24fe05df 100644 --- a/arch/um/kernel/tt/tlb.c +++ b/arch/um/kernel/tt/tlb.c @@ -12,7 +12,6 @@ #include "asm/pgtable.h" #include "asm/uaccess.h" #include "asm/tlbflush.h" -#include "user_util.h" #include "mem_user.h" #include "os.h" #include "tlb.h" diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c index b9195355075a..c23588393f6e 100644 --- a/arch/um/kernel/tt/tracer.c +++ b/arch/um/kernel/tt/tracer.c @@ -19,7 +19,6 @@ #include "sigcontext.h" #include "sysdep/sigcontext.h" #include "os.h" -#include "user_util.h" #include "mem_user.h" #include "process.h" #include "kern_util.h" diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c index b5d9d64d91e4..3032eb5e2467 100644 --- a/arch/um/kernel/tt/trap_user.c +++ b/arch/um/kernel/tt/trap_user.c @@ -8,7 +8,6 @@ #include #include "sysdep/ptrace.h" #include "sysdep/sigcontext.h" -#include "user_util.h" #include "kern_util.h" #include "task.h" #include "tt.h" diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c index ed1abcf4d057..0e5c82c5e5b7 100644 --- a/arch/um/kernel/tt/uaccess_user.c +++ b/arch/um/kernel/tt/uaccess_user.c @@ -5,7 +5,6 @@ */ #include -#include "user_util.h" #include "uml_uaccess.h" #include "task.h" #include "kern_util.h" diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 20684c04d5d5..cfa35763405f 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -26,7 +26,6 @@ #include "asm/setup.h" #include "ubd_user.h" #include "asm/current.h" -#include "user_util.h" #include "kern_util.h" #include "as-layout.h" #include "arch.h" diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index 2cc2d3ea2e6d..4e38ccf35129 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -16,7 +16,6 @@ #include #include "user.h" #include "kern_util.h" -#include "user_util.h" #include "net_user.h" #include "etap.h" #include "os.h" diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index 506ef09d83a0..11a9779dc9f1 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -18,7 +18,6 @@ #include "net_user.h" #include "tuntap.h" #include "kern_util.h" -#include "user_util.h" #include "user.h" #include "os.h" diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 371b4335f46d..4a9510c67622 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -18,7 +18,6 @@ #include "os.h" #include "user.h" #include "kern_util.h" -#include "user_util.h" static void copy_stat(struct uml_stat *dst, struct stat64 *src) { diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index a375cc138c2c..f35220c72042 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -13,7 +13,6 @@ #include #include "user.h" #include "kern_util.h" -#include "user_util.h" #include "os.h" #include "um_malloc.h" diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index d1b61d474e0a..a633fa8e0a94 100644 --- a/arch/um/os-Linux/irq.c +++ b/arch/um/os-Linux/irq.c @@ -11,7 +11,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "process.h" diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 25261d6c7bf2..4b6e122ff17b 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -13,7 +13,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "as-layout.h" #include "mem_user.h" diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index f1ea169db85e..dcaca0e190de 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c @@ -11,7 +11,6 @@ #include #include "kern_util.h" #include "user.h" -#include "user_util.h" #include "mem_user.h" #include "init.h" #include "os.h" diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 76bdd6712417..697828220af2 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -14,7 +14,6 @@ #include "ptrace_user.h" #include "os.h" #include "user.h" -#include "user_util.h" #include "process.h" #include "irq_user.h" #include "kern_util.h" diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index c61d01bf46e4..f77ce3d6f7cc 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -17,7 +17,6 @@ #include "init.h" #include "user.h" #include "kern_util.h" -#include "user_util.h" #include "sigio.h" #include "os.h" #include "um_malloc.h" diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 266768629fee..48d493415301 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -11,7 +11,6 @@ #include #include #include -#include "user_util.h" #include "user.h" #include "signal_kern.h" #include "sysdep/sigcontext.h" diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index 9383e8751ae7..470ec531aa5d 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -17,7 +17,6 @@ #include "os.h" #include "proc_mm.h" #include "ptrace_user.h" -#include "user_util.h" #include "kern_util.h" #include "task.h" #include "registers.h" diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 0564422c155f..6554ff530128 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -18,7 +18,6 @@ #include #include "user.h" #include "sysdep/ptrace.h" -#include "user_util.h" #include "kern_util.h" #include "skas.h" #include "stub-data.h" diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c index 19ff04bdec90..f104427d2caf 100644 --- a/arch/um/os-Linux/skas/trap.c +++ b/arch/um/os-Linux/skas/trap.c @@ -5,7 +5,6 @@ #include #include -#include "user_util.h" #include "kern_util.h" #include "as-layout.h" #include "task.h" diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 1540f21d6997..3380a13986ef 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -21,7 +21,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "signal_kern.h" diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c index 8ba132482970..32ed41ec1a3d 100644 --- a/arch/um/os-Linux/sys-i386/tls.c +++ b/arch/um/os-Linux/sys-i386/tls.c @@ -6,7 +6,6 @@ #include "sysdep/tls.h" #include "user.h" -#include "user_util.h" /* Checks whether host supports TLS, and sets *tls_min according to the value * valid on the host. diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 2115b8beb541..5de169b168f6 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -10,7 +10,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "process.h" diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c index d221214d2ed5..295da657931a 100644 --- a/arch/um/os-Linux/trap.c +++ b/arch/um/os-Linux/trap.c @@ -6,7 +6,6 @@ #include #include #include "kern_util.h" -#include "user_util.h" #include "os.h" #include "mode.h" #include "longjmp.h" diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c index 3dc3a02d6263..00e14f446f16 100644 --- a/arch/um/os-Linux/tt.c +++ b/arch/um/os-Linux/tt.c @@ -18,7 +18,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "signal_kern.h" diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 125854a2aa22..0e771bb04dd2 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -21,7 +21,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "mem_user.h" diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c index cae0af14903a..0393e44813e7 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/um/sys-i386/bugs.c @@ -13,7 +13,6 @@ #include "sysdep/ptrace.h" #include "task.h" #include "os.h" -#include "user_util.h" #define MAXTOKEN 64 diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c index 95dd309ff69a..40ff0c831bd0 100644 --- a/arch/um/sys-i386/ptrace_user.c +++ b/arch/um/sys-i386/ptrace_user.c @@ -15,7 +15,6 @@ #include "user.h" #include "os.h" #include "uml-config.h" -#include "user_util.h" int ptrace_getregs(long pid, unsigned long *regs_out) { diff --git a/arch/um/sys-ppc/sigcontext.c b/arch/um/sys-ppc/sigcontext.c index 5d430fc994af..4bdc15c89edd 100644 --- a/arch/um/sys-ppc/sigcontext.c +++ b/arch/um/sys-ppc/sigcontext.c @@ -1,7 +1,6 @@ #include "asm/ptrace.h" #include "asm/sigcontext.h" #include "sysdep/ptrace.h" -#include "user_util.h" /* * Overrides for Emacs so that we follow Linus's tabbing style. -- cgit v1.2.3-59-g8ed1b From 36e454630473caa178bcbc4982ed6a68cf002e95 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:11 -0700 Subject: uml: add missing __init declarations The build started finding calls from non-init to init functions. These are just cases of init functions not being properly marked, so this patch fixes that. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/mem.c | 2 +- arch/um/os-Linux/main.c | 2 +- arch/um/os-Linux/mem.c | 9 +++++---- arch/um/os-Linux/process.c | 5 +++-- arch/um/os-Linux/start_up.c | 4 ++-- 5 files changed, 12 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 5e93bbf6e482..72ff85693a39 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -216,7 +216,7 @@ static void __init fixaddr_user_init( void) #endif } -void paging_init(void) +void __init paging_init(void) { unsigned long zones_size[MAX_NR_ZONES], vaddr; int i; diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 4b6e122ff17b..ea9a23696f36 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -120,7 +120,7 @@ extern int uml_exitcode; extern void scan_elf_aux( char **envp); -int main(int argc, char **argv, char **envp) +int __init main(int argc, char **argv, char **envp) { char **new_argv; int ret, i, err; diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index dcaca0e190de..77d16023c286 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c @@ -164,7 +164,8 @@ found: * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger). * So it isn't 'static' yet. */ -int make_tempfile(const char *template, char **out_tempname, int do_unlink) +int __init make_tempfile(const char *template, char **out_tempname, + int do_unlink) { char *tempname; int fd; @@ -205,7 +206,7 @@ out: * This proc is used in start_up.c * So it isn't 'static'. */ -int create_tmp_file(unsigned long long len) +int __init create_tmp_file(unsigned long long len) { int fd, err; char zero; @@ -241,7 +242,7 @@ int create_tmp_file(unsigned long long len) return fd; } -int create_mem_file(unsigned long long len) +int __init create_mem_file(unsigned long long len) { int err, fd; @@ -256,7 +257,7 @@ int create_mem_file(unsigned long long len) } -void check_tmpexec(void) +void __init check_tmpexec(void) { void *addr; int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 697828220af2..2babea30345e 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -21,6 +21,7 @@ #include "skas_ptrace.h" #include "kern_constants.h" #include "uml-config.h" +#include "init.h" #define ARBITRARY_ADDR -1 #define FAILURE_PID -1 @@ -192,7 +193,7 @@ int os_unmap_memory(void *addr, int len) #define MADV_REMOVE KERNEL_MADV_REMOVE #endif -int os_drop_memory(void *addr, int length) +int __init os_drop_memory(void *addr, int length) { int err; @@ -202,7 +203,7 @@ int os_drop_memory(void *addr, int length) return err; } -int can_drop_memory(void) +int __init can_drop_memory(void) { void *addr; int fd, ok = 0; diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 3380a13986ef..79471f85eb89 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -329,7 +329,7 @@ static void __init check_ptrace(void) extern void check_tmpexec(void); -static void check_coredump_limit(void) +static void __init check_coredump_limit(void) { struct rlimit lim; int err = getrlimit(RLIMIT_CORE, &lim); @@ -350,7 +350,7 @@ static void check_coredump_limit(void) else printf("%lu\n", lim.rlim_max); } -void os_early_checks(void) +void __init os_early_checks(void) { /* Print out the core dump limits early */ check_coredump_limit(); -- cgit v1.2.3-59-g8ed1b From 85ee2ce8ae7d6716beffc84451dd65cd217dbf7a Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sun, 6 May 2007 14:51:12 -0700 Subject: remove unused header file: arch/um/kernel/tt/include/mode_kern-tt.h Signed-off-by: Robert P. J. Day Acked-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/tt/include/mode_kern-tt.h | 52 -------------------------------- 1 file changed, 52 deletions(-) delete mode 100644 arch/um/kernel/tt/include/mode_kern-tt.h (limited to 'arch') diff --git a/arch/um/kernel/tt/include/mode_kern-tt.h b/arch/um/kernel/tt/include/mode_kern-tt.h deleted file mode 100644 index 2a35b15c5fef..000000000000 --- a/arch/um/kernel/tt/include/mode_kern-tt.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __TT_MODE_KERN_H__ -#define __TT_MODE_KERN_H__ - -#include "linux/sched.h" -#include "asm/page.h" -#include "asm/ptrace.h" -#include "asm/uaccess.h" - -extern void switch_to_tt(void *prev, void *next); -extern void flush_thread_tt(void); -extern void start_thread_tt(struct pt_regs *regs, unsigned long eip, - unsigned long esp); -extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, - unsigned long stack_top, struct task_struct *p, - struct pt_regs *regs); -extern void release_thread_tt(struct task_struct *task); -extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); -extern void init_idle_tt(void); -extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); -extern void flush_tlb_kernel_vm_tt(void); -extern void __flush_tlb_one_tt(unsigned long addr); -extern void flush_tlb_range_tt(struct vm_area_struct *vma, - unsigned long start, unsigned long end); -extern void flush_tlb_mm_tt(struct mm_struct *mm); -extern void force_flush_all_tt(void); -extern long execute_syscall_tt(void *r); -extern void before_mem_tt(unsigned long brk_start); -extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, - unsigned long *task_size_out); -extern int start_uml_tt(void); -extern int external_pid_tt(struct task_struct *task); -extern int thread_pid_tt(struct task_struct *task); - -#define kmem_end_tt (host_task_size - ABOVE_KMEM) - -#endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ -- cgit v1.2.3-59-g8ed1b From e024715f5f6250179a31716a898800a48cf23b39 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Sun, 6 May 2007 14:51:13 -0700 Subject: uml: improve checking and diagnostics of ethernet MACs Improve checking and diagnostics for broadcast and multicast Ethernet MAC addresses, and distinguish between those cases in output; also make sure the device is assigned a MAC address valid only locally to avoid collisions. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/net_kern.c | 38 +++++++++++++++++++++++++++++--------- include/linux/etherdevice.h | 12 ++++++++++++ 2 files changed, 41 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 20963f106c34..cd466e30af67 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -283,7 +283,7 @@ void uml_net_user_timer_expire(unsigned long _conn) #endif } -static void setup_etheraddr(char *str, unsigned char *addr) +static void setup_etheraddr(char *str, unsigned char *addr, char *name) { char *end; int i; @@ -302,15 +302,32 @@ static void setup_etheraddr(char *str, unsigned char *addr) } str = end + 1; } - if(addr[0] & 1){ + if (is_multicast_ether_addr(addr)) { printk(KERN_ERR - "Attempt to assign a broadcast ethernet address to a " + "Attempt to assign a multicast ethernet address to a " "device disallowed\n"); goto random; } + if (!is_valid_ether_addr(addr)) { + printk(KERN_ERR + "Attempt to assign an invalid ethernet address to a " + "device disallowed\n"); + goto random; + } + if (!is_local_ether_addr(addr)) { + printk(KERN_WARNING + "Warning: attempt to assign a globally valid ethernet address to a " + "device\n"); + printk(KERN_WARNING "You should better enable the 2nd rightmost bit " + "in the first byte of the MAC, i.e. " + "%02x:%02x:%02x:%02x:%02x:%02x\n", + addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4], addr[5]); + } return; random: + printk(KERN_INFO + "Choosing a random ethernet address for device %s\n", name); random_ether_addr(addr); } @@ -331,6 +348,7 @@ static void eth_configure(int n, void *init, char *mac, struct net_device *dev; struct uml_net_private *lp; int save, err, size; + char name[sizeof(dev->name)]; size = transport->private_size + sizeof(struct uml_net_private) + sizeof(((struct uml_net_private *) 0)->user); @@ -344,7 +362,13 @@ static void eth_configure(int n, void *init, char *mac, INIT_LIST_HEAD(&device->list); device->index = n; - setup_etheraddr(mac, device->mac); + /* If this name ends up conflicting with an existing registered + * netdevice, that is OK, register_netdev{,ice}() will notice this + * and fail. + */ + snprintf(name, sizeof(name), "eth%d", n); + + setup_etheraddr(mac, device->mac, name); printk(KERN_INFO "Netdevice %d ", n); printk("(%02x:%02x:%02x:%02x:%02x:%02x) ", @@ -375,11 +399,7 @@ static void eth_configure(int n, void *init, char *mac, goto out_free_netdev; SET_NETDEV_DEV(dev,&device->pdev.dev); - /* If this name ends up conflicting with an existing registered - * netdevice, that is OK, register_netdev{,ice}() will notice this - * and fail. - */ - snprintf(dev->name, sizeof(dev->name), "eth%d", n); + strcpy(dev->name, name); device->dev = dev; /* diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 745c988359c0..071c67abed86 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -70,6 +70,18 @@ static inline int is_multicast_ether_addr(const u8 *addr) return (0x01 & addr[0]); } +/** + * is_local_ether_addr - Determine if the Ethernet address is locally-assigned + * one (IEEE 802). + * @addr: Pointer to a six-byte array containing the Ethernet address + * + * Return true if the address is a local address. + */ +static inline int is_local_ether_addr(const u8 *addr) +{ + return (0x02 & addr[0]); +} + /** * is_broadcast_ether_addr - Determine if the Ethernet address is broadcast * @addr: Pointer to a six-byte array containing the Ethernet address -- cgit v1.2.3-59-g8ed1b From 8c8408358f19a386298744829bf67b90c129ff18 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Sun, 6 May 2007 14:51:14 -0700 Subject: uml: Eliminate temporary buffer in eth_configure Avoid using the temporary buffer introduced by previous patch to hold the device name. Btw, avoid leaking device on an error path. Other error paths may need cleanup. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/net_kern.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index cd466e30af67..3f5e8e634308 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -348,17 +348,24 @@ static void eth_configure(int n, void *init, char *mac, struct net_device *dev; struct uml_net_private *lp; int save, err, size; - char name[sizeof(dev->name)]; size = transport->private_size + sizeof(struct uml_net_private) + sizeof(((struct uml_net_private *) 0)->user); device = kzalloc(sizeof(*device), GFP_KERNEL); if (device == NULL) { - printk(KERN_ERR "eth_configure failed to allocate uml_net\n"); + printk(KERN_ERR "eth_configure failed to allocate struct " + "uml_net\n"); return; } + dev = alloc_etherdev(size); + if (dev == NULL) { + printk(KERN_ERR "eth_configure: failed to allocate struct " + "net_device for eth%d\n", n); + goto out_free_device; + } + INIT_LIST_HEAD(&device->list); device->index = n; @@ -366,9 +373,9 @@ static void eth_configure(int n, void *init, char *mac, * netdevice, that is OK, register_netdev{,ice}() will notice this * and fail. */ - snprintf(name, sizeof(name), "eth%d", n); + snprintf(dev->name, sizeof(dev->name), "eth%d", n); - setup_etheraddr(mac, device->mac, name); + setup_etheraddr(mac, device->mac, dev->name); printk(KERN_INFO "Netdevice %d ", n); printk("(%02x:%02x:%02x:%02x:%02x:%02x) ", @@ -376,11 +383,6 @@ static void eth_configure(int n, void *init, char *mac, device->mac[2], device->mac[3], device->mac[4], device->mac[5]); printk(": "); - dev = alloc_etherdev(size); - if (dev == NULL) { - printk(KERN_ERR "eth_configure: failed to allocate device\n"); - goto out_free_device; - } lp = dev->priv; /* This points to the transport private data. It's still clear, but we @@ -399,7 +401,6 @@ static void eth_configure(int n, void *init, char *mac, goto out_free_netdev; SET_NETDEV_DEV(dev,&device->pdev.dev); - strcpy(dev->name, name); device->dev = dev; /* @@ -466,13 +467,13 @@ static void eth_configure(int n, void *init, char *mac, return; out_undo_user_init: - if (transport->user->init != NULL) + if (transport->user->remove != NULL) (*transport->user->remove)(&lp->user); out_unregister: platform_device_unregister(&device->pdev); out_free_netdev: free_netdev(dev); -out_free_device: ; +out_free_device: kfree(device); } -- cgit v1.2.3-59-g8ed1b From c74c69b442364125fd13259ecaa4cd2ee43b9172 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Sun, 6 May 2007 14:51:15 -0700 Subject: uml: Replace one-element array with zero-element array To look at users I did: $ find arch/um/ include/asm-um -name '*.[ch]'|xargs grep -r 'net_kern\.h' +-l|xargs grep '\' Most users just cast user to the appropriate pointer, the remaining ones are fixed here. In net_kern.c, I'm almost sure that save trick is not needed anymore, but I've not verified it. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/net_kern.c | 14 +++----------- arch/um/include/net_kern.h | 2 +- 2 files changed, 4 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 3f5e8e634308..b2c292a66218 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -347,10 +347,9 @@ static void eth_configure(int n, void *init, char *mac, struct uml_net *device; struct net_device *dev; struct uml_net_private *lp; - int save, err, size; + int err, size; - size = transport->private_size + sizeof(struct uml_net_private) + - sizeof(((struct uml_net_private *) 0)->user); + size = transport->private_size + sizeof(struct uml_net_private); device = kzalloc(sizeof(*device), GFP_KERNEL); if (device == NULL) { @@ -409,12 +408,6 @@ static void eth_configure(int n, void *init, char *mac, */ (*transport->kern->init)(dev, init); - /* lp.user is the first four bytes of the transport data, which - * has already been initialized. This structure assignment will - * overwrite that, so we make sure that .user gets overwritten with - * what it already has. - */ - save = lp->user[0]; *lp = ((struct uml_net_private) { .list = LIST_HEAD_INIT(lp->list), .dev = dev, @@ -428,8 +421,7 @@ static void eth_configure(int n, void *init, char *mac, .write = transport->kern->write, .add_address = transport->user->add_address, .delete_address = transport->user->delete_address, - .set_mtu = transport->user->set_mtu, - .user = { save } }); + .set_mtu = transport->user->set_mtu }); init_timer(&lp->tl); spin_lock_init(&lp->lock); diff --git a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h index 125ab42df18a..9237056b9103 100644 --- a/arch/um/include/net_kern.h +++ b/arch/um/include/net_kern.h @@ -40,7 +40,7 @@ struct uml_net_private { void (*add_address)(unsigned char *, unsigned char *, void *); void (*delete_address)(unsigned char *, unsigned char *, void *); int (*set_mtu)(int mtu, void *); - int user[1]; + char user[0]; }; struct net_kern_info { -- cgit v1.2.3-59-g8ed1b From 57ac895a7f22d235f637317f58a2d9ba6ec91a27 Mon Sep 17 00:00:00 2001 From: Davide Brini Date: Sun, 6 May 2007 14:51:16 -0700 Subject: uml: fix umid in xterm titles Calls lines_init() *after* xterm_title is modified to include umid. Signed-off-by: Davide Brini Signed-off-by: Jeff Dike Acked-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ssl.c | 4 ++-- arch/um/drivers/stdio_console.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index 94faadc5ea1b..fd09ad9e9c0a 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c @@ -191,12 +191,12 @@ static int ssl_init(void) ssl_driver = register_lines(&driver, &ssl_ops, serial_lines, ARRAY_SIZE(serial_lines)); - lines_init(serial_lines, ARRAY_SIZE(serial_lines), &opts); - new_title = add_xterm_umid(opts.xterm_title); if (new_title != NULL) opts.xterm_title = new_title; + lines_init(serial_lines, ARRAY_SIZE(serial_lines), &opts); + ssl_init_done = 1; register_console(&ssl_cons); return 0; diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 90a2c5cc17d4..2bb4193ac1aa 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c @@ -166,12 +166,12 @@ int stdio_init(void) return -1; printk(KERN_INFO "Initialized stdio console driver\n"); - lines_init(vts, ARRAY_SIZE(vts), &opts); - new_title = add_xterm_umid(opts.xterm_title); if(new_title != NULL) opts.xterm_title = new_title; + lines_init(vts, ARRAY_SIZE(vts), &opts); + con_init_done = 1; register_console(&stdiocons); return 0; -- cgit v1.2.3-59-g8ed1b From a18ff1bde0c3da9ece3ba60e6eae2ef87f91a12e Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:19 -0700 Subject: uml: speed up exec flush_thread doesn't need to do a full page table walk in order to clear the address space. It knows what the end result needs to be, so it can call unmap directly. This results in a 10-20% speedup in an exec from bash. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/skas/exec.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/um/kernel/skas/exec.c b/arch/um/kernel/skas/exec.c index 54b795951372..580eb6468949 100644 --- a/arch/um/kernel/skas/exec.c +++ b/arch/um/kernel/skas/exec.c @@ -17,7 +17,17 @@ void flush_thread_skas(void) { - force_flush_all(); + void *data = NULL; + unsigned long end = proc_mm ? task_size : CONFIG_STUB_START; + int ret; + + ret = unmap(¤t->mm->context.skas.id, 0, end, 1, &data); + if(ret){ + printk("flush_thread_skas - clearing address space failed, " + "err = %d\n", ret); + force_sig(SIGKILL, current); + } + switch_mm_skas(¤t->mm->context.skas.id); } -- cgit v1.2.3-59-g8ed1b From 65a58ab044308ae65ca06c50fb10be5e0e080989 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:20 -0700 Subject: uml: no locking needed in tls.c Comment the lack of locking on a couple of globals. Also fix the formatting of __setup_host_supports_tls. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-i386/tls.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c index 643dab585727..fea8e5e15cc4 100644 --- a/arch/um/sys-i386/tls.c +++ b/arch/um/sys-i386/tls.c @@ -23,9 +23,13 @@ #include "skas.h" #endif -/* If needed we can detect when it's uninitialized. */ +/* + * If needed we can detect when it's uninitialized. + * + * These are initialized in an initcall and unchanged thereafter. + */ static int host_supports_tls = -1; -int host_gdt_entry_tls_min = -1; +int host_gdt_entry_tls_min; #ifdef CONFIG_MODE_SKAS int do_set_thread_area_skas(struct user_desc *info) @@ -361,7 +365,8 @@ out: /* XXX: This part is probably common to i386 and x86-64. Don't create a common * file for now, do that when implementing x86-64 support.*/ -static int __init __setup_host_supports_tls(void) { +static int __init __setup_host_supports_tls(void) +{ check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min); if (host_supports_tls) { printk(KERN_INFO "Host TLS support detected\n"); -- cgit v1.2.3-59-g8ed1b From 6e21aec3fcf6c8862b755d45c0af45acdefff976 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:21 -0700 Subject: uml: tidy process.c Clean up arch/um/kernel/process.c: - lots of return(x); -> return x; conversions - a number of the small functions are either unused, in which case they are gone, along any declarations in a header, or could be made static. - current_pid is ifdefed on CONFIG_MODE_TT and its declaration is ifdefed on both CONFIG_MODE_TT and UML_CONFIG_MODE_TT because we don't know whether it's being used in a userspace or kernel file. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/kern_util.h | 7 +-- arch/um/include/tt/uaccess-tt.h | 2 - arch/um/include/um_malloc.h | 1 - arch/um/kernel/process.c | 118 ++++++++++++---------------------------- 4 files changed, 38 insertions(+), 90 deletions(-) (limited to 'arch') diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index be850b9ec947..09810bc48e5b 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h @@ -8,6 +8,7 @@ #include "sysdep/ptrace.h" #include "sysdep/faultinfo.h" +#include "uml-config.h" typedef void (*kern_hndl)(int, union uml_pt_regs *); @@ -33,7 +34,9 @@ extern int nsyscalls; UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1) extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg); +#ifdef UML_CONFIG_MODE_TT extern unsigned long stack_sp(unsigned long page); +#endif extern int kernel_thread_proc(void *data); extern void syscall_segv(int sig); extern int current_pid(void); @@ -57,7 +60,6 @@ extern void add_input_request(int op, void (*proc)(int), void *arg); extern char *current_cmd(void); extern void timer_handler(int sig, union uml_pt_regs *regs); extern int set_signals(int enable); -extern void force_sigbus(void); extern int pid_to_processor_id(int pid); extern void deliver_signals(void *t); extern int next_trap_index(int max); @@ -69,7 +71,6 @@ extern void *syscall_sp(void *t); extern void syscall_trace(union uml_pt_regs *regs, int entryexit); extern int hz(void); extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs); -extern int external_pid(void *t); extern void interrupt_end(void); extern void initial_thread_cb(void (*proc)(void *), void *arg); extern int debugger_signal(int status, int pid); @@ -80,7 +81,6 @@ extern int init_parent_proxy(int pid); extern int singlestepping(void *t); extern void check_stack_overflow(void *ptr); extern void relay_signal(int sig, union uml_pt_regs *regs); -extern void not_implemented(void); extern int user_context(unsigned long sp); extern void timer_irq(union uml_pt_regs *regs); extern void unprotect_stack(unsigned long stack); @@ -92,7 +92,6 @@ extern char *uml_strdup(char *string); extern void unprotect_kernel_mem(void); extern void protect_kernel_mem(void); extern void uml_cleanup(void); -extern void set_current(void *t); extern void lock_signalled_task(void *t); extern void IPI_handler(int cpu); extern int jail_setup(char *line, int *add); diff --git a/arch/um/include/tt/uaccess-tt.h b/arch/um/include/tt/uaccess-tt.h index b19645f32f24..13a64f61fcf4 100644 --- a/arch/um/include/tt/uaccess-tt.h +++ b/arch/um/include/tt/uaccess-tt.h @@ -27,8 +27,6 @@ extern unsigned long uml_physmem; #define access_ok_tt(type, addr, size) \ (is_stack(addr, size)) -extern unsigned long get_fault_addr(void); - extern int __do_copy_from_user(void *to, const void *from, int n, void **fault_addr, void **fault_catcher); extern int __do_strncpy_from_user(char *dst, const char *src, size_t n, diff --git a/arch/um/include/um_malloc.h b/arch/um/include/um_malloc.h index 0363a9b53f8d..e6d7c5aa3f4e 100644 --- a/arch/um/include/um_malloc.h +++ b/arch/um/include/um_malloc.h @@ -11,7 +11,6 @@ extern void *um_kmalloc_atomic(int size); extern void kfree(const void *ptr); extern void *um_vmalloc(int size); -extern void *um_vmalloc_atomic(int size); extern void vfree(void *ptr); #endif /* __UM_MALLOC_H__ */ diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 90c9ffafc659..d6d3319b3670 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -54,11 +54,9 @@ */ struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; -int external_pid(void *t) +static inline int external_pid(struct task_struct *task) { - struct task_struct *task = t ? t : current; - - return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task)); + return CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task); } int pid_to_processor_id(int pid) @@ -66,9 +64,10 @@ int pid_to_processor_id(int pid) int i; for(i = 0; i < ncpus; i++){ - if(cpu_tasks[i].pid == pid) return(i); + if(cpu_tasks[i].pid == pid) + return i; } - return(-1); + return -1; } void free_stack(unsigned long stack, int order) @@ -85,9 +84,9 @@ unsigned long alloc_stack(int order, int atomic) flags = GFP_ATOMIC; page = __get_free_pages(flags, order); if(page == 0) - return(0); + return 0; stack_protections(page); - return(page); + return page; } int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) @@ -100,13 +99,11 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) ¤t->thread.regs, 0, NULL, NULL); if(pid < 0) panic("do_fork failed in kernel_thread, errno = %d", pid); - return(pid); + return pid; } -void set_current(void *t) +static inline void set_current(struct task_struct *task) { - struct task_struct *task = t; - cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task) { external_pid(task), task }); } @@ -128,14 +125,16 @@ void *_switch_to(void *prev, void *next, void *last) prev= current; } while(current->thread.saved_task); - return(current->thread.prev_sched); + return current->thread.prev_sched; } void interrupt_end(void) { - if(need_resched()) schedule(); - if(test_tsk_thread_flag(current, TIF_SIGPENDING)) do_signal(); + if(need_resched()) + schedule(); + if(test_tsk_thread_flag(current, TIF_SIGPENDING)) + do_signal(); } void release_thread(struct task_struct *task) @@ -150,7 +149,7 @@ void exit_thread(void) void *get_current(void) { - return(current); + return current; } int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, @@ -188,15 +187,12 @@ void initial_thread_cb(void (*proc)(void *), void *arg) kmalloc_ok = save_kmalloc_ok; } +#ifdef CONFIG_MODE_TT unsigned long stack_sp(unsigned long page) { - return(page + PAGE_SIZE - sizeof(void *)); -} - -int current_pid(void) -{ - return(current->pid); + return page + PAGE_SIZE - sizeof(void *); } +#endif void default_idle(void) { @@ -223,7 +219,7 @@ void cpu_idle(void) int page_size(void) { - return(PAGE_SIZE); + return PAGE_SIZE; } void *um_virt_to_phys(struct task_struct *task, unsigned long addr, @@ -236,68 +232,43 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr, pte_t ptent; if(task->mm == NULL) - return(ERR_PTR(-EINVAL)); + return ERR_PTR(-EINVAL); pgd = pgd_offset(task->mm, addr); if(!pgd_present(*pgd)) - return(ERR_PTR(-EINVAL)); + return ERR_PTR(-EINVAL); pud = pud_offset(pgd, addr); if(!pud_present(*pud)) - return(ERR_PTR(-EINVAL)); + return ERR_PTR(-EINVAL); pmd = pmd_offset(pud, addr); if(!pmd_present(*pmd)) - return(ERR_PTR(-EINVAL)); + return ERR_PTR(-EINVAL); pte = pte_offset_kernel(pmd, addr); ptent = *pte; if(!pte_present(ptent)) - return(ERR_PTR(-EINVAL)); + return ERR_PTR(-EINVAL); if(pte_out != NULL) *pte_out = ptent; - return((void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK)); + return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK); } char *current_cmd(void) { #if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM) - return("(Unknown)"); + return "(Unknown)"; #else void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL); return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr); #endif } -void force_sigbus(void) -{ - printk(KERN_ERR "Killing pid %d because of a lack of memory\n", - current->pid); - lock_kernel(); - sigaddset(¤t->pending.signal, SIGBUS); - recalc_sigpending(); - current->flags |= PF_SIGNALED; - do_exit(SIGBUS | 0x80); -} - void dump_thread(struct pt_regs *regs, struct user *u) { } -void enable_hlt(void) -{ - panic("enable_hlt"); -} - -EXPORT_SYMBOL(enable_hlt); - -void disable_hlt(void) -{ - panic("disable_hlt"); -} - -EXPORT_SYMBOL(disable_hlt); - void *um_kmalloc(int size) { return kmalloc(size, GFP_KERNEL); @@ -313,36 +284,17 @@ void *um_vmalloc(int size) return vmalloc(size); } -void *um_vmalloc_atomic(int size) -{ - return __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, PAGE_KERNEL); -} - int __cant_sleep(void) { return in_atomic() || irqs_disabled() || in_interrupt(); /* Is in_interrupt() really needed? */ } -unsigned long get_fault_addr(void) -{ - return((unsigned long) current->thread.fault_addr); -} - -EXPORT_SYMBOL(get_fault_addr); - -void not_implemented(void) -{ - printk(KERN_DEBUG "Something isn't implemented in here\n"); -} - -EXPORT_SYMBOL(not_implemented); - int user_context(unsigned long sp) { unsigned long stack; stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER); - return(stack != (unsigned long) current_thread); + return stack != (unsigned long) current_thread; } extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end; @@ -363,22 +315,22 @@ char *uml_strdup(char *string) int copy_to_user_proc(void __user *to, void *from, int size) { - return(copy_to_user(to, from, size)); + return copy_to_user(to, from, size); } int copy_from_user_proc(void *to, void __user *from, int size) { - return(copy_from_user(to, from, size)); + return copy_from_user(to, from, size); } int clear_user_proc(void __user *buf, int size) { - return(clear_user(buf, size)); + return clear_user(buf, size); } int strlen_user_proc(char __user *str) { - return(strlen_user(str)); + return strlen_user(str); } int smp_sigio_handler(void) @@ -387,14 +339,14 @@ int smp_sigio_handler(void) int cpu = current_thread->cpu; IPI_handler(cpu); if(cpu != 0) - return(1); + return 1; #endif - return(0); + return 0; } int cpu(void) { - return(current_thread->cpu); + return current_thread->cpu; } static atomic_t using_sysemu = ATOMIC_INIT(0); @@ -443,7 +395,7 @@ int __init make_proc_sysemu(void) if (ent == NULL) { printk(KERN_WARNING "Failed to register /proc/sysemu\n"); - return(0); + return 0; } ent->read_proc = proc_read_sysemu; -- cgit v1.2.3-59-g8ed1b From 1ffb9164f51094b7105ce9f81600b222ddf5b82c Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:22 -0700 Subject: uml: remove page_size() userspace code used to have to call the kernelspace function page_size() in order to determine the value of the kernel's PAGE_SIZE. Since this is now available directly from kern_constants.h as UM_KERN_PAGE_SIZE, page_size() can be deleted and calls changed to use the constant. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/net_user.c | 3 ++- arch/um/drivers/slip_user.c | 3 ++- arch/um/include/kern_util.h | 1 - arch/um/kernel/process.c | 5 ----- arch/um/os-Linux/drivers/ethertap_user.c | 7 ++++--- arch/um/os-Linux/helper.c | 5 +++-- arch/um/os-Linux/process.c | 2 +- arch/um/os-Linux/skas/process.c | 9 +++++---- arch/um/os-Linux/tt.c | 3 ++- arch/um/os-Linux/util.c | 11 ++++++----- 10 files changed, 25 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index b63a86046374..3503cff867c3 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -18,6 +18,7 @@ #include "net_user.h" #include "os.h" #include "um_malloc.h" +#include "kern_constants.h" int tap_open_common(void *dev, char *gate_addr) { @@ -215,7 +216,7 @@ static void change(char *dev, char *what, unsigned char *addr, sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1], netmask[2], netmask[3]); - output_len = page_size(); + output_len = UM_KERN_PAGE_SIZE; output = um_kmalloc(output_len); if(output == NULL) printk("change : failed to allocate output buffer\n"); diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index 9f41cece0916..78f0e515da8f 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -15,6 +15,7 @@ #include "slip_common.h" #include "os.h" #include "um_malloc.h" +#include "kern_constants.h" static int slip_user_init(void *data, void *dev) { @@ -89,7 +90,7 @@ static int slip_tramp(char **argv, int fd) goto out_close; pid = err; - output_len = page_size(); + output_len = UM_KERN_PAGE_SIZE; output = um_kmalloc(output_len); if(output == NULL){ printk("slip_tramp : failed to allocate output buffer\n"); diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index 09810bc48e5b..ae434a9b400d 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h @@ -52,7 +52,6 @@ extern void set_tracing(void *t, int tracing); extern int is_tracing(void *task); extern int segv_syscall(void); extern void kern_finish_exec(void *task, int new_pid, unsigned long stack); -extern int page_size(void); extern unsigned long page_mask(void); extern int need_finish_fork(void); extern void free_stack(unsigned long stack, int order); diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index d6d3319b3670..9ac9944aa2c7 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -217,11 +217,6 @@ void cpu_idle(void) CHOOSE_MODE(init_idle_tt(), init_idle_skas()); } -int page_size(void) -{ - return PAGE_SIZE; -} - void *um_virt_to_phys(struct task_struct *task, unsigned long addr, pte_t *pte_out) { diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index 4e38ccf35129..96e12ea8172c 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -20,6 +20,7 @@ #include "etap.h" #include "os.h" #include "um_malloc.h" +#include "kern_constants.h" #define MAX_PACKET ETH_MAX_PACKET @@ -50,10 +51,10 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask, n = os_write_file(fd, &change, sizeof(change)); if(n != sizeof(change)) printk("etap_change - request failed, err = %d\n", -n); - output = um_kmalloc(page_size()); + output = um_kmalloc(UM_KERN_PAGE_SIZE); if(output == NULL) printk("etap_change : Failed to allocate output buffer\n"); - read_output(fd, output, page_size()); + read_output(fd, output, UM_KERN_PAGE_SIZE); if(output != NULL){ printk("%s", output); kfree(output); @@ -159,7 +160,7 @@ static int etap_open(void *data) err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], control_fds[1], data_fds[0], data_fds[1]); - output_len = page_size(); + output_len = UM_KERN_PAGE_SIZE; output = um_kmalloc(output_len); read_output(control_fds[0], output, output_len); diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index f35220c72042..2184ddb9cb31 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -15,6 +15,7 @@ #include "kern_util.h" #include "os.h" #include "um_malloc.h" +#include "kern_constants.h" struct helper_data { void (*pre_exec)(void*); @@ -69,7 +70,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, goto out_close; } - sp = stack + page_size() - sizeof(void *); + sp = stack + UM_KERN_PAGE_SIZE - sizeof(void *); data.pre_exec = pre_exec; data.pre_data = pre_data; data.argv = argv; @@ -123,7 +124,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, if (stack == 0) return -ENOMEM; - sp = stack + (page_size() << stack_order) - sizeof(void *); + sp = stack + (UM_KERN_PAGE_SIZE << stack_order) - sizeof(void *); pid = clone(proc, (void *) sp, flags | SIGCHLD, arg); if (pid < 0) { err = -errno; diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 2babea30345e..37933d3f92b8 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -244,7 +244,7 @@ void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) if(sig_stack != NULL){ pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER); - set_sigstack(sig_stack, pages * page_size()); + set_sigstack(sig_stack, pages * UM_KERN_PAGE_SIZE); flags = SA_ONSTACK; } if(usr1_handler){ diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 6554ff530128..29fd079c30b1 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -33,6 +33,7 @@ #include "uml-config.h" #include "process.h" #include "longjmp.h" +#include "kern_constants.h" int is_skas_winch(int pid, int fd, void *data) { @@ -171,7 +172,7 @@ static int userspace_tramp(void *stack) int fd; __u64 offset; fd = phys_mapping(to_phys(&__syscall_stub_start), &offset); - addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(), + addr = mmap64((void *) UML_CONFIG_STUB_CODE, UM_KERN_PAGE_SIZE, PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset); if(addr == MAP_FAILED){ printk("mapping mmap stub failed, errno = %d\n", @@ -181,8 +182,8 @@ static int userspace_tramp(void *stack) if(stack != NULL){ fd = phys_mapping(to_phys(stack), &offset); - addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(), - PROT_READ | PROT_WRITE, + addr = mmap((void *) UML_CONFIG_STUB_DATA, + UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, offset); if(addr == MAP_FAILED){ printk("mapping segfault stack failed, " @@ -198,7 +199,7 @@ static int userspace_tramp(void *stack) (unsigned long) stub_segv_handler - (unsigned long) &__syscall_stub_start; - set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size()); + set_sigstack((void *) UML_CONFIG_STUB_DATA, UM_KERN_PAGE_SIZE); sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGIO); sigaddset(&sa.sa_mask, SIGWINCH); diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c index 00e14f446f16..bcf9359c4e9f 100644 --- a/arch/um/os-Linux/tt.c +++ b/arch/um/os-Linux/tt.c @@ -31,6 +31,7 @@ #include "choose-mode.h" #include "mode.h" #include "tempfile.h" +#include "kern_constants.h" int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x, int must_succeed) @@ -142,7 +143,7 @@ int outer_tramp(void *arg) int sig = sigkill; t = arg; - t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2, + t->pid = clone(t->tramp, (void *) t->temp_stack + UM_KERN_PAGE_SIZE/2, t->flags, t->tramp_data); if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL); kill(os_getpid(), sig); diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 0e771bb04dd2..48bc4927b996 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -29,28 +29,29 @@ #include "uml-config.h" #include "os.h" #include "longjmp.h" +#include "kern_constants.h" void stack_protections(unsigned long address) { int prot = PROT_READ | PROT_WRITE | PROT_EXEC; - if(mprotect((void *) address, page_size(), prot) < 0) + if(mprotect((void *) address, UM_KERN_PAGE_SIZE, prot) < 0) panic("protecting stack failed, errno = %d", errno); } void task_protections(unsigned long address) { - unsigned long guard = address + page_size(); - unsigned long stack = guard + page_size(); + unsigned long guard = address + UM_KERN_PAGE_SIZE; + unsigned long stack = guard + UM_KERN_PAGE_SIZE; int prot = 0, pages; #ifdef notdef - if(mprotect((void *) stack, page_size(), prot) < 0) + if(mprotect((void *) stack, UM_KERN_PAGE_SIZE, prot) < 0) panic("protecting guard page failed, errno = %d", errno); #endif pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2; prot = PROT_READ | PROT_WRITE | PROT_EXEC; - if(mprotect((void *) stack, pages * page_size(), prot) < 0) + if(mprotect((void *) stack, pages * UM_KERN_PAGE_SIZE, prot) < 0) panic("protecting stack failed, errno = %d", errno); } -- cgit v1.2.3-59-g8ed1b From ccdddb57874522e6b267204f9c5e94ba7d9d66b0 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:23 -0700 Subject: uml: kernel_thread shouldn't panic kernel_thread() should just return an error value on do_fork failure, not panic. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/process.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 9ac9944aa2c7..8d2c5496532b 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -97,8 +97,6 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) current->thread.request.u.thread.arg = arg; pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, ¤t->thread.regs, 0, NULL, NULL); - if(pid < 0) - panic("do_fork failed in kernel_thread, errno = %d", pid); return pid; } -- cgit v1.2.3-59-g8ed1b From 5d86456d3852cb95a38d2b23fe01cede54984ba5 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:24 -0700 Subject: uml: tidy fault code Tidying in preparation for the segfault register dumping patch which follows. void * pointers are changed to union uml_pt_regs *. This makes the types match reality, except in arch_fixup, which is changed to operate on a union uml_pt_regs. This fixes a bug in the call from segv_handler, which passes a union uml_pt_regs, to segv, which expects to pass a struct sigcontext to arch_fixup. Whitespace and other style fixes. There's also a errno printk fix. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/arch.h | 2 +- arch/um/include/kern_util.h | 2 +- arch/um/kernel/trap.c | 35 ++++++++++++++++++----------------- arch/um/os-Linux/skas/trap.c | 17 ++++++++--------- arch/um/sys-i386/fault.c | 18 ++---------------- arch/um/sys-i386/signal.c | 41 +++++++++++++++-------------------------- arch/um/sys-x86_64/fault.c | 30 +++++++++++++++++------------- arch/um/sys-x86_64/signal.c | 2 +- 8 files changed, 63 insertions(+), 84 deletions(-) (limited to 'arch') diff --git a/arch/um/include/arch.h b/arch/um/include/arch.h index 8e11dd7c1adb..10ad52daa8c5 100644 --- a/arch/um/include/arch.h +++ b/arch/um/include/arch.h @@ -9,7 +9,7 @@ #include "sysdep/ptrace.h" extern void arch_check_bugs(void); -extern int arch_fixup(unsigned long address, void *sc_ptr); +extern int arch_fixup(unsigned long address, union uml_pt_regs *regs); extern int arch_handle_signal(int sig, union uml_pt_regs *regs); #endif diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index ae434a9b400d..092a2841556f 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h @@ -44,7 +44,7 @@ extern unsigned long alloc_stack(int order, int atomic); extern int do_signal(void); extern int is_stack_fault(unsigned long sp); extern unsigned long segv(struct faultinfo fi, unsigned long ip, - int is_user, void *sc); + int is_user, union uml_pt_regs *regs); extern int handle_page_fault(unsigned long address, unsigned long ip, int is_write, int is_user, int *code_out); extern void syscall_ready(void); diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 2de81d4d9b57..c3e62e634c0a 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -72,8 +72,8 @@ good_area: goto out; /* Don't require VM_READ|VM_EXEC for write faults! */ - if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC))) - goto out; + if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC))) + goto out; do { survive: @@ -157,18 +157,19 @@ static void segv_handler(int sig, union uml_pt_regs *regs) * the info in the regs. A pointer to the info then would * give us bad data! */ -unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) +unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, + union uml_pt_regs *regs) { struct siginfo si; void *catcher; int err; - int is_write = FAULT_WRITE(fi); - unsigned long address = FAULT_ADDRESS(fi); + int is_write = FAULT_WRITE(fi); + unsigned long address = FAULT_ADDRESS(fi); - if(!is_user && (address >= start_vm) && (address < end_vm)){ - flush_tlb_kernel_vm(); - return(0); - } + if(!is_user && (address >= start_vm) && (address < end_vm)){ + flush_tlb_kernel_vm(); + return 0; + } else if(current->mm == NULL) panic("Segfault with no mm"); @@ -183,17 +184,17 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) catcher = current->thread.fault_catcher; if(!err) - return(0); + return 0; else if(catcher != NULL){ current->thread.fault_addr = (void *) address; do_longjmp(catcher, 1); } else if(current->thread.fault_addr != NULL) panic("fault_addr set but no fault catcher"); - else if(!is_user && arch_fixup(ip, sc)) - return(0); + else if(!is_user && arch_fixup(ip, regs)) + return 0; - if(!is_user) + if(!is_user) panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", address, ip); @@ -202,7 +203,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) si.si_errno = 0; si.si_code = BUS_ADRERR; si.si_addr = (void __user *)address; - current->thread.arch.faultinfo = fi; + current->thread.arch.faultinfo = fi; force_sig_info(SIGBUS, &si, current); } else if (err == -ENOMEM) { printk("VM: killing process %s\n", current->comm); @@ -211,10 +212,10 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) BUG_ON(err != -EFAULT); si.si_signo = SIGSEGV; si.si_addr = (void __user *) address; - current->thread.arch.faultinfo = fi; + current->thread.arch.faultinfo = fi; force_sig_info(SIGSEGV, &si, current); } - return(0); + return 0; } void relay_signal(int sig, union uml_pt_regs *regs) @@ -229,7 +230,7 @@ void relay_signal(int sig, union uml_pt_regs *regs) panic("Kernel mode signal %d", sig); } - current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); + current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); force_sig(sig, current); } diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c index f104427d2caf..6a20d08caf91 100644 --- a/arch/um/os-Linux/skas/trap.c +++ b/arch/um/os-Linux/skas/trap.c @@ -18,10 +18,9 @@ void sig_handler_common_skas(int sig, void *sc_ptr) { struct sigcontext *sc = sc_ptr; - struct skas_regs *r; + union uml_pt_regs *r; void (*handler)(int, union uml_pt_regs *); - int save_errno = errno; - int save_user; + int save_user, save_errno = errno; /* This is done because to allow SIGSEGV to be delivered inside a SEGV * handler. This can happen in copy_user, and if SEGV is disabled, @@ -31,13 +30,13 @@ void sig_handler_common_skas(int sig, void *sc_ptr) if(sig == SIGSEGV) change_sig(SIGSEGV, 1); - r = &TASK_REGS(get_current())->skas; - save_user = r->is_user; - r->is_user = 0; + r = TASK_REGS(get_current()); + save_user = r->skas.is_user; + r->skas.is_user = 0; if ( sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || sig == SIGTRAP ) { - GET_FAULTINFO_FROM_SC(r->faultinfo, sc); + GET_FAULTINFO_FROM_SC(r->skas.faultinfo, sc); } change_sig(SIGUSR1, 1); @@ -49,10 +48,10 @@ void sig_handler_common_skas(int sig, void *sc_ptr) sig != SIGVTALRM && sig != SIGALRM) unblock_signals(); - handler(sig, (union uml_pt_regs *) r); + handler(sig, r); errno = save_errno; - r->is_user = save_user; + r->skas.is_user = save_user; } extern int ptrace_faultinfo; diff --git a/arch/um/sys-i386/fault.c b/arch/um/sys-i386/fault.c index d0bbcdfdb53f..745b4fd49e9f 100644 --- a/arch/um/sys-i386/fault.c +++ b/arch/um/sys-i386/fault.c @@ -3,9 +3,7 @@ * Licensed under the GPL */ -#include #include "sysdep/ptrace.h" -#include "sysdep/sigcontext.h" /* These two are from asm-um/uaccess.h and linux/module.h, check them. */ struct exception_table_entry @@ -17,26 +15,14 @@ struct exception_table_entry const struct exception_table_entry *search_exception_tables(unsigned long add); /* Compare this to arch/i386/mm/extable.c:fixup_exception() */ -int arch_fixup(unsigned long address, void *sc_ptr) +int arch_fixup(unsigned long address, union uml_pt_regs *regs) { - struct sigcontext *sc = sc_ptr; const struct exception_table_entry *fixup; fixup = search_exception_tables(address); if(fixup != 0){ - sc->eip = fixup->fixup; + UPT_IP(regs) = fixup->fixup; return(1); } return(0); } - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index 3f6acd667717..42ecf8e8ad08 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c @@ -28,7 +28,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, err = copy_from_user(&sc, from, sizeof(sc)); err |= copy_from_user(fpregs, sc.fpstate, sizeof(fpregs)); if(err) - return(err); + return err; REGS_GS(regs->regs.skas.regs) = sc.gs; REGS_FS(regs->regs.skas.regs) = sc.fs; @@ -50,11 +50,11 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, err = restore_fp_registers(userspace_pid[0], fpregs); if(err < 0){ printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, " - "errno = %d\n", err); - return(1); + "errno = %d\n", -err); + return err; } - return(0); + return 0; } int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *to_fp, @@ -90,16 +90,16 @@ int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *t if(err < 0){ printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, " "errno = %d\n", err); - return(1); + return 1; } to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1)); sc.fpstate = to_fp; if(err) - return(err); + return err; - return(copy_to_user(to, &sc, sizeof(sc)) || - copy_to_user(to_fp, fpregs, sizeof(fpregs))); + return copy_to_user(to, &sc, sizeof(sc)) || + copy_to_user(to_fp, fpregs, sizeof(fpregs)); } #endif @@ -129,7 +129,7 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from, to->fpstate = to_fp; if(to_fp != NULL) err |= copy_from_user(to_fp, from_fp, fpsize); - return(err); + return err; } int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp, @@ -164,15 +164,15 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from) ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, sizeof(struct _fpstate)), copy_sc_from_user_skas(to, from)); - return(ret); + return ret; } static int copy_sc_to_user(struct sigcontext __user *to, struct _fpstate __user *fp, struct pt_regs *from, unsigned long sp) { - return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), + return CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), sizeof(*fp), sp), - copy_sc_to_user_skas(to, fp, from, sp))); + copy_sc_to_user_skas(to, fp, from, sp)); } static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __user *fp, @@ -185,7 +185,7 @@ static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __u err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size); err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->thread.regs, sp); err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set)); - return(err); + return err; } struct sigframe @@ -359,7 +359,7 @@ long sys_sigreturn(struct pt_regs regs) /* Avoid ERESTART handling */ PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return(PT_REGS_SYSCALL_RET(¤t->thread.regs)); + return PT_REGS_SYSCALL_RET(¤t->thread.regs); segfault: force_sig(SIGSEGV, current); @@ -389,20 +389,9 @@ long sys_rt_sigreturn(struct pt_regs regs) /* Avoid ERESTART handling */ PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return(PT_REGS_SYSCALL_RET(¤t->thread.regs)); + return PT_REGS_SYSCALL_RET(¤t->thread.regs); segfault: force_sig(SIGSEGV, current); return 0; } - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/sys-x86_64/fault.c b/arch/um/sys-x86_64/fault.c index cee1513c5c31..4636b1465b6c 100644 --- a/arch/um/sys-x86_64/fault.c +++ b/arch/um/sys-x86_64/fault.c @@ -4,20 +4,24 @@ * Licensed under the GPL */ -#include "user.h" +#include "sysdep/ptrace.h" -int arch_fixup(unsigned long address, void *sc_ptr) +/* These two are from asm-um/uaccess.h and linux/module.h, check them. */ +struct exception_table_entry { - /* XXX search_exception_tables() */ + unsigned long insn; + unsigned long fixup; +}; + +const struct exception_table_entry *search_exception_tables(unsigned long add); +int arch_fixup(unsigned long address, union uml_pt_regs *regs) +{ + const struct exception_table_entry *fixup; + + fixup = search_exception_tables(address); + if(fixup != 0){ + UPT_IP(regs) = fixup->fixup; + return(1); + } return(0); } - -/* Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index af2f017617b4..068006213598 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -51,7 +51,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, #undef GETREG - return(err); + return err; } int copy_sc_to_user_skas(struct sigcontext __user *to, -- cgit v1.2.3-59-g8ed1b From 377fad3acbb7e94ab9942a74e0d9ede8eeb2f039 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:25 -0700 Subject: uml: kernel segfaults should dump proper registers If there's a segfault inside the kernel, we want a dump of the registers at the point of the segfault, not the registers at the point of calling panic or the last userspace registers. sig_handler_common_skas now uses a static register set in the case of a SIGSEGV to avoid messing up the process registers if the segfault turns out to be non-fatal. The architecture sigcontext-to-pt_regs copying code was repurposed to copy data out of the SEGV stack frame. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/common-offsets.h | 2 ++ arch/um/include/kern_util.h | 2 ++ arch/um/kernel/trap.c | 10 +++++++--- arch/um/os-Linux/skas/trap.c | 15 +++++++++++++-- arch/um/sys-i386/signal.c | 41 +++++++++++++++++++++++----------------- arch/um/sys-x86_64/signal.c | 30 +++++++++++++++++++++++++++++ 6 files changed, 78 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h index 461175f8b1d9..5593a8027083 100644 --- a/arch/um/include/common-offsets.h +++ b/arch/um/include/common-offsets.h @@ -24,5 +24,7 @@ DEFINE(UM_ELF_CLASS, ELF_CLASS); DEFINE(UM_ELFCLASS32, ELFCLASS32); DEFINE(UM_ELFCLASS64, ELFCLASS64); +DEFINE(UM_NR_CPUS, NR_CPUS); + /* For crypto assembler code. */ DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index 092a2841556f..50a49691e0e6 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h @@ -115,4 +115,6 @@ extern void time_init_kern(void); extern int __cant_sleep(void); extern void sigio_handler(int sig, union uml_pt_regs *regs); +extern void copy_sc(union uml_pt_regs *regs, void *from); + #endif diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index c3e62e634c0a..0c467fa08870 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -170,8 +170,10 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, flush_tlb_kernel_vm(); return 0; } - else if(current->mm == NULL) - panic("Segfault with no mm"); + else if(current->mm == NULL) { + show_regs(container_of(regs, struct pt_regs, regs)); + panic("Segfault with no mm"); + } if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi)) err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); @@ -194,9 +196,11 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, else if(!is_user && arch_fixup(ip, regs)) return 0; - if(!is_user) + if(!is_user) { + show_regs(container_of(regs, struct pt_regs, regs)); panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", address, ip); + } if (err == -EACCES) { si.si_signo = SIGBUS; diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c index 6a20d08caf91..5110eff51b90 100644 --- a/arch/um/os-Linux/skas/trap.c +++ b/arch/um/os-Linux/skas/trap.c @@ -15,6 +15,8 @@ #include "sysdep/ptrace_user.h" #include "os.h" +static union uml_pt_regs ksig_regs[UM_NR_CPUS]; + void sig_handler_common_skas(int sig, void *sc_ptr) { struct sigcontext *sc = sc_ptr; @@ -27,10 +29,19 @@ void sig_handler_common_skas(int sig, void *sc_ptr) * the process will die. * XXX Figure out why this is better than SA_NODEFER */ - if(sig == SIGSEGV) + if(sig == SIGSEGV) { change_sig(SIGSEGV, 1); + /* For segfaults, we want the data from the + * sigcontext. In this case, we don't want to mangle + * the process registers, so use a static set of + * registers. For other signals, the process + * registers are OK. + */ + r = &ksig_regs[cpu()]; + copy_sc(r, sc_ptr); + } + else r = TASK_REGS(get_current()); - r = TASK_REGS(get_current()); save_user = r->skas.is_user; r->skas.is_user = 0; if ( sig == SIGFPE || sig == SIGSEGV || diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index 42ecf8e8ad08..1cbf95f6858a 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c @@ -18,6 +18,28 @@ #include "skas.h" +void copy_sc(union uml_pt_regs *regs, void *from) +{ + struct sigcontext *sc = from; + + REGS_GS(regs->skas.regs) = sc->gs; + REGS_FS(regs->skas.regs) = sc->fs; + REGS_ES(regs->skas.regs) = sc->es; + REGS_DS(regs->skas.regs) = sc->ds; + REGS_EDI(regs->skas.regs) = sc->edi; + REGS_ESI(regs->skas.regs) = sc->esi; + REGS_EBP(regs->skas.regs) = sc->ebp; + REGS_SP(regs->skas.regs) = sc->esp; + REGS_EBX(regs->skas.regs) = sc->ebx; + REGS_EDX(regs->skas.regs) = sc->edx; + REGS_ECX(regs->skas.regs) = sc->ecx; + REGS_EAX(regs->skas.regs) = sc->eax; + REGS_IP(regs->skas.regs) = sc->eip; + REGS_CS(regs->skas.regs) = sc->cs; + REGS_EFLAGS(regs->skas.regs) = sc->eflags; + REGS_SS(regs->skas.regs) = sc->ss; +} + static int copy_sc_from_user_skas(struct pt_regs *regs, struct sigcontext __user *from) { @@ -30,25 +52,10 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, if(err) return err; - REGS_GS(regs->regs.skas.regs) = sc.gs; - REGS_FS(regs->regs.skas.regs) = sc.fs; - REGS_ES(regs->regs.skas.regs) = sc.es; - REGS_DS(regs->regs.skas.regs) = sc.ds; - REGS_EDI(regs->regs.skas.regs) = sc.edi; - REGS_ESI(regs->regs.skas.regs) = sc.esi; - REGS_EBP(regs->regs.skas.regs) = sc.ebp; - REGS_SP(regs->regs.skas.regs) = sc.esp; - REGS_EBX(regs->regs.skas.regs) = sc.ebx; - REGS_EDX(regs->regs.skas.regs) = sc.edx; - REGS_ECX(regs->regs.skas.regs) = sc.ecx; - REGS_EAX(regs->regs.skas.regs) = sc.eax; - REGS_IP(regs->regs.skas.regs) = sc.eip; - REGS_CS(regs->regs.skas.regs) = sc.cs; - REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags; - REGS_SS(regs->regs.skas.regs) = sc.ss; + copy_sc(®s->regs, &sc); err = restore_fp_registers(userspace_pid[0], fpregs); - if(err < 0){ + if(err < 0) { printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, " "errno = %d\n", -err); return err; diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index 068006213598..fe8ec04d35bb 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -20,6 +20,36 @@ #include "skas.h" +void copy_sc(union uml_pt_regs *regs, void *from) +{ + struct sigcontext *sc = from; + +#define GETREG(regs, regno, sc, regname) \ + (regs)->skas.regs[(regno) / sizeof(unsigned long)] = (sc)->regname + + GETREG(regs, R8, sc, r8); + GETREG(regs, R9, sc, r9); + GETREG(regs, R10, sc, r10); + GETREG(regs, R11, sc, r11); + GETREG(regs, R12, sc, r12); + GETREG(regs, R13, sc, r13); + GETREG(regs, R14, sc, r14); + GETREG(regs, R15, sc, r15); + GETREG(regs, RDI, sc, rdi); + GETREG(regs, RSI, sc, rsi); + GETREG(regs, RBP, sc, rbp); + GETREG(regs, RBX, sc, rbx); + GETREG(regs, RDX, sc, rdx); + GETREG(regs, RAX, sc, rax); + GETREG(regs, RCX, sc, rcx); + GETREG(regs, RSP, sc, rsp); + GETREG(regs, RIP, sc, rip); + GETREG(regs, EFLAGS, sc, eflags); + GETREG(regs, CS, sc, cs); + +#undef GETREG +} + static int copy_sc_from_user_skas(struct pt_regs *regs, struct sigcontext __user *from) { -- cgit v1.2.3-59-g8ed1b From 1d1497e1f9ffe2f7198c916abd112226a7a503f2 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:26 -0700 Subject: uml: comment early boot locking Commentary about missing locking. Also got rid of uml_start because it was pointless. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/um_arch.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index cfa35763405f..9bf31533a8fd 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -44,7 +44,7 @@ #define DEFAULT_COMMAND_LINE "root=98:0" -/* Changed in linux_main and setup_arch, which run before SMP is started */ +/* Changed in add_arg and setup_arch, which run before SMP is started */ static char __initdata command_line[COMMAND_LINE_SIZE] = { 0 }; static void __init add_arg(char *arg) @@ -58,7 +58,12 @@ static void __init add_arg(char *arg) strcat(command_line, arg); } -struct cpuinfo_um boot_cpu_data = { +/* + * These fields are initialized at boot time and not changed. + * XXX This structure is used only in the non-SMP case. Maybe this + * should be moved to smp.c. + */ +struct cpuinfo_um boot_cpu_data = { .loops_per_jiffy = 0, .ipi_pipe = { -1, -1 } }; @@ -119,14 +124,12 @@ const struct seq_operations cpuinfo_op = { /* Set in linux_main */ unsigned long host_task_size; unsigned long task_size; - -unsigned long uml_start; - -/* Set in early boot */ unsigned long uml_physmem; -unsigned long uml_reserved; +unsigned long uml_reserved; /* Also modified in mem_init */ unsigned long start_vm; unsigned long end_vm; + +/* Set in uml_ncpus_setup */ int ncpus = 1; #ifdef CONFIG_CMDLINE_ON_HOST @@ -140,6 +143,8 @@ static char *argv1_end = NULL; /* Set in early boot */ static int have_root __initdata = 0; + +/* Set in uml_mem_setup and modified in linux_main */ long long physmem_size = 32 * 1024 * 1024; void set_cmdline(char *cmd) @@ -378,7 +383,6 @@ int __init linux_main(int argc, char **argv) printf("UML running in %s mode\n", mode); - uml_start = (unsigned long) &__binary_start; host_task_size = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, &task_size); @@ -400,7 +404,7 @@ int __init linux_main(int argc, char **argv) physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); } - uml_physmem = uml_start & PAGE_MASK; + uml_physmem = (unsigned long) &__binary_start & PAGE_MASK; /* Reserve up to 4M after the current brk */ uml_reserved = ROUND_4M(brk_start) + (1 << 22); -- cgit v1.2.3-59-g8ed1b From d973a77bdb3ade9240173b6ed6e003a319499211 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:27 -0700 Subject: uml: irq locking commentary Locking commentary. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/irq.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'arch') diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index a1e8c460b755..8f2ed3690315 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -78,6 +78,14 @@ skip: return 0; } +/* + * This list is accessed under irq_lock, except in sigio_handler, + * where it is safe from being modified. IRQ handlers won't change it - + * if an IRQ source has vanished, it will be freed by free_irqs just + * before returning from sigio_handler. That will process a separate + * list of irqs to free, with its own locking, coming back here to + * remove list elements, taking the irq_lock to do so. + */ static struct irq_fd *active_fds = NULL; static struct irq_fd **last_irq_ptr = &active_fds; @@ -243,6 +251,7 @@ void free_irq_by_fd(int fd) free_irq_by_cb(same_fd, &fd); } +/* Must be called with irq_lock held */ static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out) { struct irq_fd *irq; @@ -308,6 +317,12 @@ void deactivate_fd(int fd, int irqnum) ignore_sigio_fd(fd); } +/* + * Called just before shutdown in order to provide a clean exec + * environment in case the system is rebooting. No locking because + * that would cause a pointless shutdown hang if something hadn't + * released the lock. + */ int deactivate_all_fds(void) { struct irq_fd *irq; -- cgit v1.2.3-59-g8ed1b From d8839354a04181b4cc95cebf7f7622cf336bd58e Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:28 -0700 Subject: uml: delete HOST_FRAME_SIZE HOST_FRAME_SIZE isn't used any more. It has been replaced with MAX_REG_NR. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-i386/user-offsets.c | 1 - arch/um/sys-x86_64/user-offsets.c | 1 - 2 files changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c index 447306b20aea..ee42c27abd3a 100644 --- a/arch/um/sys-i386/user-offsets.c +++ b/arch/um/sys-i386/user-offsets.c @@ -47,7 +47,6 @@ void foo(void) OFFSET(HOST_SC_FP_ST, _fpstate, _st); OFFSET(HOST_SC_FXSR_ENV, _fpstate, _fxsr_env); - DEFINE(HOST_FRAME_SIZE, FRAME_SIZE); DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_i387_struct)); DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fxsr_struct)); diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c index 899cebb57c3f..7bb532567c47 100644 --- a/arch/um/sys-x86_64/user-offsets.c +++ b/arch/um/sys-x86_64/user-offsets.c @@ -57,7 +57,6 @@ void foo(void) OFFSET(HOST_SC_SS, sigcontext, ss); #endif - DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE); DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); DEFINE(HOST_XFP_SIZE, 0); DEFINE_LONGS(HOST_RBX, RBX); -- cgit v1.2.3-59-g8ed1b From 2e3f5251ac716879df6b6271f243f657c6e02e9a Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:29 -0700 Subject: uml: drivers get release methods Define release methods for the ubd and net drivers. They contain as much of the remove methods as make sense. All error checking must have already been done as well as anything else that might be holding a reference on the device kobject. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/net_kern.c | 19 +++++++++++++++---- arch/um/drivers/ubd_kern.c | 17 ++++++++++++----- 2 files changed, 27 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index b2c292a66218..baac4ad5e68e 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -341,6 +341,19 @@ static struct platform_driver uml_net_driver = { }; static int driver_registered; +static void net_device_release(struct device *dev) +{ + struct uml_net *device = dev->driver_data; + struct net_device *netdev = device->dev; + struct uml_net_private *lp = netdev->priv; + + if(lp->remove != NULL) + (*lp->remove)(&lp->user); + list_del(&device->list); + kfree(device); + free_netdev(netdev); +} + static void eth_configure(int n, void *init, char *mac, struct transport *transport) { @@ -396,6 +409,8 @@ static void eth_configure(int n, void *init, char *mac, } device->pdev.id = n; device->pdev.name = DRIVER_NAME; + device->pdev.dev.release = net_device_release; + device->pdev.dev.driver_data = device; if(platform_device_register(&device->pdev)) goto out_free_netdev; SET_NETDEV_DEV(dev,&device->pdev.dev); @@ -689,13 +704,9 @@ static int net_remove(int n, char **error_out) lp = dev->priv; if(lp->fd > 0) return -EBUSY; - if(lp->remove != NULL) (*lp->remove)(&lp->user); unregister_netdev(dev); platform_device_unregister(&device->pdev); - list_del(&device->list); - kfree(device); - free_netdev(dev); return 0; } diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 962b8fb35f80..83189e188c3f 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -622,6 +622,14 @@ static int ubd_open_dev(struct ubd *ubd_dev) return(err); } +static void ubd_device_release(struct device *dev) +{ + struct ubd *ubd_dev = dev->driver_data; + + blk_cleanup_queue(ubd_dev->queue); + *ubd_dev = ((struct ubd) DEFAULT_UBD); +} + static int ubd_disk_register(int major, u64 size, int unit, struct gendisk **disk_out) { @@ -644,6 +652,8 @@ static int ubd_disk_register(int major, u64 size, int unit, if (major == MAJOR_NR) { ubd_devs[unit].pdev.id = unit; ubd_devs[unit].pdev.name = DRIVER_NAME; + ubd_devs[unit].pdev.dev.release = ubd_device_release; + ubd_devs[unit].pdev.dev.driver_data = &ubd_devs[unit]; platform_device_register(&ubd_devs[unit].pdev); disk->driverfs_dev = &ubd_devs[unit].pdev.dev; } @@ -787,7 +797,7 @@ static int ubd_id(char **str, int *start_out, int *end_out) static int ubd_remove(int n, char **error_out) { - struct gendisk *disk; + struct gendisk *disk = ubd_gendisk[n]; struct ubd *ubd_dev; int err = -ENODEV; @@ -803,7 +813,6 @@ static int ubd_remove(int n, char **error_out) if(ubd_dev->count > 0) goto out; - disk = ubd_gendisk[n]; ubd_gendisk[n] = NULL; if(disk != NULL){ del_gendisk(disk); @@ -816,10 +825,8 @@ static int ubd_remove(int n, char **error_out) fake_gendisk[n] = NULL; } - blk_cleanup_queue(ubd_dev->queue); - platform_device_unregister(&ubd_dev->pdev); - *ubd_dev = ((struct ubd) DEFAULT_UBD); err = 0; + platform_device_unregister(&ubd_dev->pdev); out: mutex_unlock(&ubd_lock); return err; -- cgit v1.2.3-59-g8ed1b From f30c2c983e09470446ee00472f9d4a927fe2e9cb Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:29 -0700 Subject: uml: dump registers on ptrace or wait failure Provide a register dump if handle_trap fails. Abstract out ptrace_dump_regs since it now has two callers. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/skas/process.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 29fd079c30b1..41bf8d1e14e0 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -44,6 +44,22 @@ int is_skas_winch(int pid, int fd, void *data) return(1); } +static int ptrace_dump_regs(int pid) +{ + unsigned long regs[MAX_REG_NR]; + int i; + + if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) + return -errno; + else { + printk("Stub registers -\n"); + for(i = 0; i < ARRAY_SIZE(regs); i++) + printk("\t%d - %lx\n", i, regs[i]); + } + + return 0; +} + void wait_stub_done(int pid, int sig, char * fname) { int n, status, err; @@ -67,18 +83,10 @@ void wait_stub_done(int pid, int sig, char * fname) if((n < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){ - unsigned long regs[MAX_REG_NR]; - - if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) + err = ptrace_dump_regs(pid); + if(err) printk("Failed to get registers from stub, " - "errno = %d\n", errno); - else { - int i; - - printk("Stub registers -\n"); - for(i = 0; i < ARRAY_SIZE(regs); i++) - printk("\t%d - %lx\n", i, regs[i]); - } + "errno = %d\n", -err); panic("%s : failed to wait for SIGUSR1/SIGTRAP, " "pid = %d, n = %d, errno = %d, status = 0x%x\n", fname, pid, n, errno, status); @@ -142,9 +150,14 @@ static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); if((err < 0) || !WIFSTOPPED(status) || - (WSTOPSIG(status) != SIGTRAP + 0x80)) + (WSTOPSIG(status) != SIGTRAP + 0x80)){ + err = ptrace_dump_regs(pid); + if(err) + printk("Failed to get registers from process, " + "errno = %d\n", -err); panic("handle_trap - failed to wait at end of syscall, " "errno = %d, status = %d\n", errno, status); + } } handle_syscall(regs); -- cgit v1.2.3-59-g8ed1b From 7f0536f80cfbefd753eb123ed20940978f223900 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:30 -0700 Subject: uml: speed up page table walking The previous page table walking code was horribly inefficient. This patch replaces it with code taken from elsewhere in the kernel. Forking from bash is now ~5% faster and page faults are handled ~10% faster. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/tlb.c | 202 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 120 insertions(+), 82 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index e40f3352bd29..153dec13cf97 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -6,6 +6,7 @@ #include "linux/mm.h" #include "asm/page.h" #include "asm/pgalloc.h" +#include "asm/pgtable.h" #include "asm/tlbflush.h" #include "choose-mode.h" #include "mode_kern.h" @@ -123,106 +124,143 @@ static int add_mprotect(unsigned long addr, unsigned long len, int r, int w, #define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1)) +static inline int update_pte_range(pmd_t *pmd, unsigned long addr, + unsigned long end, struct host_vm_op *ops, + int last_op, int *op_index, int force, + union mm_context *mmu, void **flush, + int (*do_ops)(union mm_context *, + struct host_vm_op *, int, int, + void **)) +{ + pte_t *pte; + int r, w, x, ret = 0; + + pte = pte_offset_kernel(pmd, addr); + do { + r = pte_read(*pte); + w = pte_write(*pte); + x = pte_exec(*pte); + if (!pte_young(*pte)) { + r = 0; + w = 0; + } else if (!pte_dirty(*pte)) { + w = 0; + } + if(force || pte_newpage(*pte)){ + if(pte_present(*pte)) + ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK, + PAGE_SIZE, r, w, x, ops, + op_index, last_op, mmu, flush, + do_ops); + else ret = add_munmap(addr, PAGE_SIZE, ops, op_index, + last_op, mmu, flush, do_ops); + } + else if(pte_newprot(*pte)) + ret = add_mprotect(addr, PAGE_SIZE, r, w, x, ops, + op_index, last_op, mmu, flush, + do_ops); + *pte = pte_mkuptodate(*pte); + } while (pte++, addr += PAGE_SIZE, ((addr != end) && !ret)); + return ret; +} + +static inline int update_pmd_range(pud_t *pud, unsigned long addr, + unsigned long end, struct host_vm_op *ops, + int last_op, int *op_index, int force, + union mm_context *mmu, void **flush, + int (*do_ops)(union mm_context *, + struct host_vm_op *, int, int, + void **)) +{ + pmd_t *pmd; + unsigned long next; + int ret = 0; + + pmd = pmd_offset(pud, addr); + do { + next = pmd_addr_end(addr, end); + if(!pmd_present(*pmd)){ + if(force || pmd_newpage(*pmd)){ + ret = add_munmap(addr, next - addr, ops, + op_index, last_op, mmu, + flush, do_ops); + pmd_mkuptodate(*pmd); + } + } + else ret = update_pte_range(pmd, addr, next, ops, last_op, + op_index, force, mmu, flush, + do_ops); + } while (pmd++, addr = next, ((addr != end) && !ret)); + return ret; +} + +static inline int update_pud_range(pgd_t *pgd, unsigned long addr, + unsigned long end, struct host_vm_op *ops, + int last_op, int *op_index, int force, + union mm_context *mmu, void **flush, + int (*do_ops)(union mm_context *, + struct host_vm_op *, int, int, + void **)) +{ + pud_t *pud; + unsigned long next; + int ret = 0; + + pud = pud_offset(pgd, addr); + do { + next = pud_addr_end(addr, end); + if(!pud_present(*pud)){ + if(force || pud_newpage(*pud)){ + ret = add_munmap(addr, next - addr, ops, + op_index, last_op, mmu, + flush, do_ops); + pud_mkuptodate(*pud); + } + } + else ret = update_pmd_range(pud, addr, next, ops, last_op, + op_index, force, mmu, flush, + do_ops); + } while (pud++, addr = next, ((addr != end) && !ret)); + return ret; +} + void fix_range_common(struct mm_struct *mm, unsigned long start_addr, unsigned long end_addr, int force, int (*do_ops)(union mm_context *, struct host_vm_op *, int, int, void **)) { - pgd_t *npgd; - pud_t *npud; - pmd_t *npmd; - pte_t *npte; + pgd_t *pgd; union mm_context *mmu = &mm->context; - unsigned long addr, end; - int r, w, x; struct host_vm_op ops[1]; + unsigned long addr = start_addr, next; + int ret = 0, last_op = ARRAY_SIZE(ops) - 1, op_index = -1; void *flush = NULL; - int op_index = -1, last_op = ARRAY_SIZE(ops) - 1; - int ret = 0; - - if(mm == NULL) - return; + unsigned long long start_time, end_time; + start_time = os_nsecs(); ops[0].type = NONE; - for(addr = start_addr; addr < end_addr && !ret;){ - npgd = pgd_offset(mm, addr); - if(!pgd_present(*npgd)){ - end = ADD_ROUND(addr, PGDIR_SIZE); - if(end > end_addr) - end = end_addr; - if(force || pgd_newpage(*npgd)){ - ret = add_munmap(addr, end - addr, ops, - &op_index, last_op, mmu, - &flush, do_ops); - pgd_mkuptodate(*npgd); - } - addr = end; - continue; - } - - npud = pud_offset(npgd, addr); - if(!pud_present(*npud)){ - end = ADD_ROUND(addr, PUD_SIZE); - if(end > end_addr) - end = end_addr; - if(force || pud_newpage(*npud)){ - ret = add_munmap(addr, end - addr, ops, - &op_index, last_op, mmu, - &flush, do_ops); - pud_mkuptodate(*npud); - } - addr = end; - continue; - } - - npmd = pmd_offset(npud, addr); - if(!pmd_present(*npmd)){ - end = ADD_ROUND(addr, PMD_SIZE); - if(end > end_addr) - end = end_addr; - if(force || pmd_newpage(*npmd)){ - ret = add_munmap(addr, end - addr, ops, + pgd = pgd_offset(mm, addr); + do { + next = pgd_addr_end(addr, end_addr); + if(!pgd_present(*pgd)){ + if (force || pgd_newpage(*pgd)){ + ret = add_munmap(addr, next - addr, ops, &op_index, last_op, mmu, &flush, do_ops); - pmd_mkuptodate(*npmd); + pgd_mkuptodate(*pgd); } - addr = end; - continue; } + else ret = update_pud_range(pgd, addr, next, ops, last_op, + &op_index, force, mmu, &flush, + do_ops); + } while (pgd++, addr = next, ((addr != end_addr) && !ret)); + end_time = os_nsecs(); + log_info("total flush time - %Ld nsecs\n", end_time - start_time); - npte = pte_offset_kernel(npmd, addr); - r = pte_read(*npte); - w = pte_write(*npte); - x = pte_exec(*npte); - if (!pte_young(*npte)) { - r = 0; - w = 0; - } else if (!pte_dirty(*npte)) { - w = 0; - } - if(force || pte_newpage(*npte)){ - if(pte_present(*npte)) - ret = add_mmap(addr, - pte_val(*npte) & PAGE_MASK, - PAGE_SIZE, r, w, x, ops, - &op_index, last_op, mmu, - &flush, do_ops); - else ret = add_munmap(addr, PAGE_SIZE, ops, - &op_index, last_op, mmu, - &flush, do_ops); - } - else if(pte_newprot(*npte)) - ret = add_mprotect(addr, PAGE_SIZE, r, w, x, ops, - &op_index, last_op, mmu, - &flush, do_ops); - - *npte = pte_mkuptodate(*npte); - addr += PAGE_SIZE; - } if(!ret) ret = (*do_ops)(mmu, ops, op_index, 1, &flush); -/* This is not an else because ret is modified above */ + /* This is not an else because ret is modified above */ if(ret) { printk("fix_range_common: failed, killing current process\n"); force_sig(SIGKILL, current); -- cgit v1.2.3-59-g8ed1b From f9d6e5f83b40d8ff73a74d4bba2c5f51d6048b12 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:31 -0700 Subject: uml: remove unused x86_64 code It turns out that essentially none of the x86_64 bugs.c is needed. So, we can delete most of it. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-x86_64/bugs.c | 69 ----------------------------------------------- 1 file changed, 69 deletions(-) (limited to 'arch') diff --git a/arch/um/sys-x86_64/bugs.c b/arch/um/sys-x86_64/bugs.c index 9fa5392e3122..095478890371 100644 --- a/arch/um/sys-x86_64/bugs.c +++ b/arch/um/sys-x86_64/bugs.c @@ -4,12 +4,7 @@ * Licensed under the GPL */ -#include "linux/sched.h" -#include "linux/errno.h" -#include "asm/system.h" -#include "asm/pda.h" #include "sysdep/ptrace.h" -#include "os.h" void arch_init_thread(void) { @@ -23,67 +18,3 @@ int arch_handle_signal(int sig, union uml_pt_regs *regs) { return 0; } - -#define MAXTOKEN 64 - -/* Set during early boot */ -int host_has_cmov = 1; -int host_has_xmm = 0; - -static char token(int fd, char *buf, int len, char stop) -{ - int n; - char *ptr, *end, c; - - ptr = buf; - end = &buf[len]; - do { - n = os_read_file(fd, ptr, sizeof(*ptr)); - c = *ptr++; - if(n != sizeof(*ptr)){ - if(n == 0) - return 0; - printk("Reading /proc/cpuinfo failed, err = %d\n", -n); - if(n < 0) - return n; - else return -EIO; - } - } while((c != '\n') && (c != stop) && (ptr < end)); - - if(ptr == end){ - printk("Failed to find '%c' in /proc/cpuinfo\n", stop); - return -1; - } - *(ptr - 1) = '\0'; - return c; -} - -static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) -{ - int n; - char c; - - scratch[len - 1] = '\0'; - while(1){ - c = token(fd, scratch, len - 1, ':'); - if(c <= 0) - return 0; - else if(c != ':'){ - printk("Failed to find ':' in /proc/cpuinfo\n"); - return 0; - } - - if(!strncmp(scratch, key, strlen(key))) - return 1; - - do { - n = os_read_file(fd, &c, sizeof(c)); - if(n != sizeof(c)){ - printk("Failed to find newline in " - "/proc/cpuinfo, err = %d\n", -n); - return 0; - } - } while(c != '\n'); - } - return 0; -} -- cgit v1.2.3-59-g8ed1b From 3d564047a5f45cb628ec72514f68076e532988f3 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:32 -0700 Subject: uml: start fixing os_read_file and os_write_file This patch starts the removal of a very old, very broken piece of code. This stems from the problem of passing a userspace buffer into read() or write() on the host. If that buffer had not yet been faulted in, read and write will return -EFAULT. To avoid this problem, the solution was to fault the buffer in before the system call by touching the pages that hold the buffer by doing a copy-user of a byte to each page. This is obviously bogus, but it does usually work, in tt mode, since the kernel and process are in the same address space and userspace addresses can be accessed directly in the kernel. In skas mode, where the kernel and process are in separate address spaces, it is completely bogus because the userspace address, which is invalid in the kernel, is passed into the system call instead of the corresponding physical address, which would be valid. Here, it appears that this code, on every host read() or write(), tries to fault in a random process page. This doesn't seem to cause any correctness problems, but there is a performance impact. This patch, and the ones following, result in a 10-15% performance gain on a kernel build. This code can't be immediately tossed out because when it is, you can't log in. Apparently, there is some code in the console driver which depends on this somehow. However, we can start removing it by switching the code which does I/O using kernel addresses to using plain read() and write(). This patch introduces os_read_file_k and os_write_file_k for use with kernel buffers and converts all call locations which use obvious kernel buffers to use them. These include I/O using buffers which are local variables which are on the stack or kmalloc-ed. Later patches will handle the less obvious cases, followed by a mass conversion back to the original interface. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_user.c | 10 +++++----- arch/um/drivers/daemon_user.c | 4 ++-- arch/um/drivers/harddog_user.c | 4 ++-- arch/um/drivers/hostaudio_kern.c | 4 ++-- arch/um/drivers/net_user.c | 2 +- arch/um/drivers/port_kern.c | 2 +- arch/um/drivers/random.c | 2 +- arch/um/drivers/ubd_kern.c | 17 ++++++++--------- arch/um/include/os.h | 2 ++ arch/um/kernel/ksyms.c | 2 ++ arch/um/kernel/physmem.c | 2 +- arch/um/kernel/sigio.c | 2 +- arch/um/kernel/smp.c | 12 ++++++------ arch/um/kernel/tt/process_kern.c | 7 ++++--- arch/um/kernel/tt/ptproxy/proxy.c | 9 +++++---- arch/um/kernel/tt/tracer.c | 2 +- arch/um/os-Linux/file.c | 18 ++++++++++++++++++ arch/um/sys-i386/bugs.c | 2 +- arch/um/sys-i386/ldt.c | 2 +- 19 files changed, 64 insertions(+), 41 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index ee53cf882f42..d226f103462e 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -85,7 +85,7 @@ static int winch_thread(void *arg) pty_fd = data->pty_fd; pipe_fd = data->pipe_fd; - count = os_write_file(pipe_fd, &c, sizeof(c)); + count = os_write_file_k(pipe_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("winch_thread : failed to write synchronization " "byte, err = %d\n", -count); @@ -120,7 +120,7 @@ static int winch_thread(void *arg) * host - since they are not different kernel threads, we cannot use * kernel semaphores. We don't use SysV semaphores because they are * persistent. */ - count = os_read_file(pipe_fd, &c, sizeof(c)); + count = os_read_file_k(pipe_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("winch_thread : failed to read synchronization byte, " "err = %d\n", -count); @@ -130,7 +130,7 @@ static int winch_thread(void *arg) * are blocked.*/ sigsuspend(&sigs); - count = os_write_file(pipe_fd, &c, sizeof(c)); + count = os_write_file_k(pipe_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("winch_thread : write failed, err = %d\n", -count); @@ -162,7 +162,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) } *fd_out = fds[0]; - n = os_read_file(fds[0], &c, sizeof(c)); + n = os_read_file_k(fds[0], &c, sizeof(c)); if(n != sizeof(c)){ printk("winch_tramp : failed to read synchronization byte\n"); printk("read failed, err = %d\n", -n); @@ -195,7 +195,7 @@ void register_winch(int fd, struct tty_struct *tty) if(thread > 0){ register_winch_irq(thread_fd, fd, thread, tty); - count = os_write_file(thread_fd, &c, sizeof(c)); + count = os_write_file_k(thread_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("register_winch : failed to write " "synchronization byte, err = %d\n", diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index b869e3899683..e1fd26c1b728 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -94,7 +94,7 @@ static int connect_to_switch(struct daemon_data *pri) req.version = SWITCH_VERSION; req.type = REQ_NEW_CONTROL; req.sock = *local_addr; - n = os_write_file(pri->control, &req, sizeof(req)); + n = os_write_file_k(pri->control, &req, sizeof(req)); if(n != sizeof(req)){ printk("daemon_open : control setup request failed, err = %d\n", -n); @@ -102,7 +102,7 @@ static int connect_to_switch(struct daemon_data *pri) goto out_free; } - n = os_read_file(pri->control, sun, sizeof(*sun)); + n = os_read_file_k(pri->control, sun, sizeof(*sun)); if(n != sizeof(*sun)){ printk("daemon_open : read of data socket failed, err = %d\n", -n); diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c index 5eeecf8917c3..0fbb1615171e 100644 --- a/arch/um/drivers/harddog_user.c +++ b/arch/um/drivers/harddog_user.c @@ -79,7 +79,7 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) goto out_close_out; } - n = os_read_file(in_fds[0], &c, sizeof(c)); + n = os_read_file_k(in_fds[0], &c, sizeof(c)); if(n == 0){ printk("harddog_open - EOF on watchdog pipe\n"); helper_wait(pid); @@ -118,7 +118,7 @@ int ping_watchdog(int fd) int n; char c = '\n'; - n = os_write_file(fd, &c, sizeof(c)); + n = os_write_file_k(fd, &c, sizeof(c)); if(n != sizeof(c)){ printk("ping_watchdog - write failed, err = %d\n", -n); if(n < 0) diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c index 10e08a8c17c3..bd6688ea96de 100644 --- a/arch/um/drivers/hostaudio_kern.c +++ b/arch/um/drivers/hostaudio_kern.c @@ -84,7 +84,7 @@ static ssize_t hostaudio_read(struct file *file, char __user *buffer, if(kbuf == NULL) return(-ENOMEM); - err = os_read_file(state->fd, kbuf, count); + err = os_read_file_k(state->fd, kbuf, count); if(err < 0) goto out; @@ -115,7 +115,7 @@ static ssize_t hostaudio_write(struct file *file, const char __user *buffer, if(copy_from_user(kbuf, buffer, count)) goto out; - err = os_write_file(state->fd, kbuf, count); + err = os_write_file_k(state->fd, kbuf, count); if(err < 0) goto out; *ppos += err; diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 3503cff867c3..2dc57a37e4b7 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -63,7 +63,7 @@ void read_output(int fd, char *output, int len) } *output = '\0'; - ret = os_read_file(fd, &remain, sizeof(remain)); + ret = os_read_file_k(fd, &remain, sizeof(remain)); if (ret != sizeof(remain)) { expected = sizeof(remain); diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index 1c8efd95c421..75bb40126c2e 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -113,7 +113,7 @@ static int port_accept(struct port_list *port) } if(atomic_read(&port->wait_count) == 0){ - os_write_file(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG)); + os_write_file_k(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG)); printk("No one waiting for port\n"); } list_add(&conn->list, &port->pending); diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index e942e836f995..94838f4c1645 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c @@ -44,7 +44,7 @@ static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size, int n, ret = 0, have_data; while(size){ - n = os_read_file(random_fd, &data, sizeof(data)); + n = os_read_file_k(random_fd, &data, sizeof(data)); if(n > 0){ have_data = n; while (have_data && size) { diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 83189e188c3f..6d163c9e2885 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -504,7 +504,7 @@ static void ubd_handler(void) struct ubd *dev; int n; - n = os_read_file(thread_fd, &req, sizeof(req)); + n = os_read_file_k(thread_fd, &req, sizeof(req)); if(n != sizeof(req)){ printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, " "err = %d\n", os_getpid(), -n); @@ -1092,8 +1092,7 @@ static void do_ubd_request(request_queue_t *q) err = prepare_request(req, &io_req); if(!err){ dev->active = 1; - n = os_write_file(thread_fd, (char *) &io_req, - sizeof(io_req)); + n = os_write_file_k(thread_fd, &io_req, sizeof(io_req)); if(n != sizeof(io_req)) printk("write to io thread failed, " "errno = %d\n", -n); @@ -1336,8 +1335,8 @@ static int update_bitmap(struct io_thread_req *req) return(1); } - n = os_write_file(req->fds[1], &req->bitmap_words, - sizeof(req->bitmap_words)); + n = os_write_file_k(req->fds[1], &req->bitmap_words, + sizeof(req->bitmap_words)); if(n != sizeof(req->bitmap_words)){ printk("do_io - bitmap update failed, err = %d fd = %d\n", -n, req->fds[1]); @@ -1381,7 +1380,7 @@ void do_io(struct io_thread_req *req) do { buf = &buf[n]; len -= n; - n = os_read_file(req->fds[bit], buf, len); + n = os_read_file_k(req->fds[bit], buf, len); if (n < 0) { printk("do_io - read failed, err = %d " "fd = %d\n", -n, req->fds[bit]); @@ -1391,7 +1390,7 @@ void do_io(struct io_thread_req *req) } while((n < len) && (n != 0)); if (n < len) memset(&buf[n], 0, len - n); } else { - n = os_write_file(req->fds[bit], buf, len); + n = os_write_file_k(req->fds[bit], buf, len); if(n != len){ printk("do_io - write failed err = %d " "fd = %d\n", -n, req->fds[bit]); @@ -1421,7 +1420,7 @@ int io_thread(void *arg) ignore_sigwinch_sig(); while(1){ - n = os_read_file(kernel_fd, &req, sizeof(req)); + n = os_read_file_k(kernel_fd, &req, sizeof(req)); if(n != sizeof(req)){ if(n < 0) printk("io_thread - read failed, fd = %d, " @@ -1434,7 +1433,7 @@ int io_thread(void *arg) } io_count++; do_io(&req); - n = os_write_file(kernel_fd, &req, sizeof(req)); + n = os_write_file_k(kernel_fd, &req, sizeof(req)); if(n != sizeof(req)) printk("io_thread - write failed, fd = %d, err = %d\n", kernel_fd, -n); diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 394adcded0bf..b463170a5308 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -144,7 +144,9 @@ extern int os_mode_fd(int fd, int mode); extern int os_seek_file(int fd, __u64 offset); extern int os_open_file(char *file, struct openflags flags, int mode); extern int os_read_file(int fd, void *buf, int len); +extern int os_read_file_k(int fd, void *buf, int len); extern int os_write_file(int fd, const void *buf, int count); +extern int os_write_file_k(int fd, const void *buf, int len); extern int os_file_size(char *file, unsigned long long *size_out); extern int os_file_modtime(char *file, unsigned long *modtime); extern int os_pipe(int *fd, int stream, int close_on_exec); diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 7b3e53fb8070..7c158448b9fd 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c @@ -62,7 +62,9 @@ EXPORT_SYMBOL(os_get_exec_close); EXPORT_SYMBOL(os_set_exec_close); EXPORT_SYMBOL(os_getpid); EXPORT_SYMBOL(os_open_file); +EXPORT_SYMBOL(os_read_file_k); EXPORT_SYMBOL(os_read_file); +EXPORT_SYMBOL(os_write_file_k); EXPORT_SYMBOL(os_write_file); EXPORT_SYMBOL(os_seek_file); EXPORT_SYMBOL(os_lock_file); diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index df1ad3ba130c..a9856209006b 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -341,7 +341,7 @@ void setup_physmem(unsigned long start, unsigned long reserve_end, * from physmem_fd, so it needs to be written out there. */ os_seek_file(physmem_fd, __pa(&__syscall_stub_start)); - os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE); + os_write_file_k(physmem_fd, &__syscall_stub_start, PAGE_SIZE); bootmap_size = init_bootmem(pfn, pfn + delta); free_bootmem(__pa(reserve_end) + bootmap_size, diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c index 89f9866a1354..f756e78085e4 100644 --- a/arch/um/kernel/sigio.c +++ b/arch/um/kernel/sigio.c @@ -21,7 +21,7 @@ static irqreturn_t sigio_interrupt(int irq, void *data) { char c; - os_read_file(sigio_irq_fd, &c, sizeof(c)); + os_read_file_k(sigio_irq_fd, &c, sizeof(c)); reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ); return IRQ_HANDLED; } diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index 62dd093cbcd7..47b690893c06 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c @@ -47,7 +47,7 @@ struct task_struct *idle_threads[NR_CPUS]; void smp_send_reschedule(int cpu) { - os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1); + os_write_file_k(cpu_data[cpu].ipi_pipe[1], "R", 1); num_reschedules_sent++; } @@ -59,7 +59,7 @@ void smp_send_stop(void) for(i = 0; i < num_online_cpus(); i++){ if(i == current_thread->cpu) continue; - os_write_file(cpu_data[i].ipi_pipe[1], "S", 1); + os_write_file_k(cpu_data[i].ipi_pipe[1], "S", 1); } printk("done\n"); } @@ -108,8 +108,8 @@ static struct task_struct *idle_thread(int cpu) { .pid = new_task->thread.mode.tt.extern_pid, .task = new_task } ); idle_threads[cpu] = new_task; - CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, - sizeof(c)), + CHOOSE_MODE(os_write_file_k(new_task->thread.mode.tt.switch_pipe[1], &c, + sizeof(c)), ({ panic("skas mode doesn't support SMP"); })); return(new_task); } @@ -179,7 +179,7 @@ void IPI_handler(int cpu) int fd; fd = cpu_data[cpu].ipi_pipe[0]; - while (os_read_file(fd, &c, 1) == 1) { + while (os_read_file_k(fd, &c, 1) == 1) { switch (c) { case 'C': smp_call_function_slave(cpu); @@ -239,7 +239,7 @@ int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, info = _info; for_each_online_cpu(i) - os_write_file(cpu_data[i].ipi_pipe[1], "C", 1); + os_write_file_k(cpu_data[i].ipi_pipe[1], "C", 1); while (atomic_read(&scf_started) != cpus) barrier(); diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index 8029f72afaa7..c81bd2074930 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c @@ -57,14 +57,15 @@ void switch_to_tt(void *prev, void *next) * nor the value in "to" (since it was the task which stole us the CPU, * which we don't care about). */ - err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); + err = os_write_file_k(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); if(err != sizeof(c)) panic("write of switch_pipe failed, err = %d", -err); if(from->thread.mode.tt.switch_pipe[0] == -1) os_kill_process(os_getpid(), 0); - err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); + err = os_read_file_k(from->thread.mode.tt.switch_pipe[0], &c, + sizeof(c)); if(err != sizeof(c)) panic("read of switch_pipe failed, errno = %d", -err); @@ -113,7 +114,7 @@ void suspend_new_thread(int fd) char c; os_stop_process(os_getpid()); - err = os_read_file(fd, &c, sizeof(c)); + err = os_read_file_k(fd, &c, sizeof(c)); if(err != sizeof(c)) panic("read failed in suspend_new_thread, err = %d", -err); } diff --git a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c index c88e7b5d8a76..007beb6b7c00 100644 --- a/arch/um/kernel/tt/ptproxy/proxy.c +++ b/arch/um/kernel/tt/ptproxy/proxy.c @@ -338,13 +338,14 @@ int start_debugger(char *prog, int startup, int stop, int *fd_out) "err = %d\n", -fd); exit(1); } - os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1); + os_write_file_k(fd, gdb_init_string, + sizeof(gdb_init_string) - 1); if(startup){ if(stop){ - os_write_file(fd, "b start_kernel\n", - strlen("b start_kernel\n")); + os_write_file_k(fd, "b start_kernel\n", + strlen("b start_kernel\n")); } - os_write_file(fd, "c\n", strlen("c\n")); + os_write_file_k(fd, "c\n", strlen("c\n")); } if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ printk("start_debugger : PTRACE_TRACEME failed, " diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c index c23588393f6e..264da6c5a5c3 100644 --- a/arch/um/kernel/tt/tracer.c +++ b/arch/um/kernel/tt/tracer.c @@ -44,7 +44,7 @@ static void tracer_winch_handler(int sig) int n; char c = 1; - n = os_write_file(tracer_winch[1], &c, sizeof(c)); + n = os_write_file_k(tracer_winch[1], &c, sizeof(c)); if(n != sizeof(c)) printk("tracer_winch_handler - write failed, err = %d\n", -n); } diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 4a9510c67622..5e9b8dcf34d4 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -334,12 +334,30 @@ int os_read_file(int fd, void *buf, int len) copy_from_user_proc); } +int os_read_file_k(int fd, void *buf, int len) +{ + int n = read(fd, buf, len); + + if(n < 0) + return -errno; + return n; +} + int os_write_file(int fd, const void *buf, int len) { return file_io(fd, (void *) buf, len, (int (*)(int, void *, int)) write, copy_to_user_proc); } +int os_write_file_k(int fd, const void *buf, int len) +{ + int n = write(fd, (void *) buf, len); + + if(n < 0) + return -errno; + return n; +} + int os_file_size(char *file, unsigned long long *size_out) { struct uml_stat buf; diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c index 0393e44813e7..74fd062b201b 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/um/sys-i386/bugs.c @@ -67,7 +67,7 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) return 1; do { - n = os_read_file(fd, &c, sizeof(c)); + n = os_read_file_k(fd, &c, sizeof(c)); if(n != sizeof(c)){ printk("Failed to find newline in " "/proc/cpuinfo, err = %d\n", -n); diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c index a939a7ef0227..d031a13bd969 100644 --- a/arch/um/sys-i386/ldt.c +++ b/arch/um/sys-i386/ldt.c @@ -517,7 +517,7 @@ long init_new_ldt(struct mmu_context_skas * new_mm, .u = { .copy_segments = from_mm->id.u.mm_fd } } ); - i = os_write_file(new_mm->id.u.mm_fd, ©, sizeof(copy)); + i = os_write_file_k(new_mm->id.u.mm_fd, ©, sizeof(copy)); if(i != sizeof(copy)) printk("new_mm : /proc/mm copy_segments failed, " "err = %d\n", -i); -- cgit v1.2.3-59-g8ed1b From ef0470c053274c343b2be8737e0146d65e17f9be Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:33 -0700 Subject: uml: tidy libc code This patch lays some groundwork for the next one, which converts calls to os_{read,write}_file into {read,write}, by doing some tidying in the affected areas. do_not_aio gets restructured to make the final result a bit cleaner. There are also whitespace and other formatting fixes, fixes in error messages, and a typo fix. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/aio.c | 20 ++++++-------------- arch/um/os-Linux/drivers/ethertap_user.c | 10 +++++++--- arch/um/os-Linux/helper.c | 9 ++++++--- arch/um/os-Linux/process.c | 29 +++++++++++++++-------------- arch/um/os-Linux/sigio.c | 7 ++++--- arch/um/os-Linux/skas/process.c | 2 +- arch/um/os-Linux/tty_log.c | 16 ++++++++-------- 7 files changed, 47 insertions(+), 46 deletions(-) (limited to 'arch') diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index 6ff12743a0bd..c1f0f76291cf 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -146,28 +146,21 @@ static int aio_thread(void *arg) static int do_not_aio(struct aio_thread_req *req) { char c; + unsigned long long actual; int err; + actual = lseek64(req->io_fd, req->offset, SEEK_SET); + if(actual != req->offset) + return -errno; + switch(req->type){ case AIO_READ: - err = os_seek_file(req->io_fd, req->offset); - if(err) - goto out; - err = os_read_file(req->io_fd, req->buf, req->len); break; case AIO_WRITE: - err = os_seek_file(req->io_fd, req->offset); - if(err) - goto out; - err = os_write_file(req->io_fd, req->buf, req->len); break; case AIO_MMAP: - err = os_seek_file(req->io_fd, req->offset); - if(err) - goto out; - err = os_read_file(req->io_fd, &c, sizeof(c)); break; default: @@ -176,7 +169,6 @@ static int do_not_aio(struct aio_thread_req *req) break; } -out: return err; } @@ -207,7 +199,7 @@ static int not_aio_thread(void *arg) } err = do_not_aio(&req); reply = ((struct aio_thread_reply) { .data = req.aio, - .err = err }); + .err = err }); err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply)); if(err != sizeof(reply)) printk("not_aio_thread - write failed, fd = %d, " diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index 96e12ea8172c..fd6cfa5b4a78 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and * James Leu (jleu@mindspring.net). * Copyright (C) 2001 by various other people who didn't put their name here. * Licensed under the GPL. @@ -49,8 +49,11 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask, memcpy(change.addr, addr, sizeof(change.addr)); memcpy(change.netmask, netmask, sizeof(change.netmask)); n = os_write_file(fd, &change, sizeof(change)); - if(n != sizeof(change)) + if(n != sizeof(change)){ printk("etap_change - request failed, err = %d\n", -n); + return; + } + output = um_kmalloc(UM_KERN_PAGE_SIZE); if(output == NULL) printk("etap_change : Failed to allocate output buffer\n"); @@ -116,7 +119,8 @@ static int etap_tramp(char *dev, char *gate, int control_me, pe_data.data_me = data_me; pid = run_helper(etap_pre_exec, &pe_data, args, NULL); - if(pid < 0) err = pid; + if(pid < 0) + err = pid; os_close_file(data_remote); os_close_file(control_remote); n = os_read_file(control_me, &c, sizeof(c)); diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index 2184ddb9cb31..8a4c9e47326c 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -34,7 +34,8 @@ static int helper_child(void *arg) if (data->pre_exec != NULL) (*data->pre_exec)(data->pre_data); errval = execvp_noalloc(data->buf, argv[0], argv); - printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], -errval); + printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], + -errval); os_write_file(data->fd, &errval, sizeof(errval)); kill(os_getpid(), SIGKILL); return 0; @@ -87,8 +88,10 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, close(fds[1]); fds[1] = -1; - /* Read the errno value from the child, if the exec failed, or get 0 if - * the exec succeeded because the pipe fd was set as close-on-exec. */ + /* + * Read the errno value from the child, if the exec failed, or get 0 if + * the exec succeeded because the pipe fd was set as close-on-exec. + */ n = os_read_file(fds[0], &ret, sizeof(ret)); if (n == 0) { ret = pid; diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 37933d3f92b8..a84a45843f83 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -40,14 +40,14 @@ unsigned long os_process_pc(int pid) if(fd < 0){ printk("os_process_pc - couldn't open '%s', err = %d\n", proc_stat, -fd); - return(ARBITRARY_ADDR); + return ARBITRARY_ADDR; } err = os_read_file(fd, buf, sizeof(buf)); if(err < 0){ printk("os_process_pc - couldn't read '%s', err = %d\n", proc_stat, -err); os_close_file(fd); - return(ARBITRARY_ADDR); + return ARBITRARY_ADDR; } os_close_file(fd); pc = ARBITRARY_ADDR; @@ -56,7 +56,7 @@ unsigned long os_process_pc(int pid) "%*d %*d %*d %*d %*d %lu", &pc) != 1){ printk("os_process_pc - couldn't find pc in '%s'\n", buf); } - return(pc); + return pc; } int os_process_parent(int pid) @@ -65,13 +65,14 @@ int os_process_parent(int pid) char data[256]; int parent, n, fd; - if(pid == -1) return(-1); + if(pid == -1) + return -1; snprintf(stat, sizeof(stat), "/proc/%d/stat", pid); fd = os_open_file(stat, of_read(OPENFLAGS()), 0); if(fd < 0){ printk("Couldn't open '%s', err = %d\n", stat, -fd); - return(FAILURE_PID); + return FAILURE_PID; } n = os_read_file(fd, data, sizeof(data)); @@ -79,7 +80,7 @@ int os_process_parent(int pid) if(n < 0){ printk("Couldn't read '%s', err = %d\n", stat, -n); - return(FAILURE_PID); + return FAILURE_PID; } parent = FAILURE_PID; @@ -87,7 +88,7 @@ int os_process_parent(int pid) if(n != 1) printk("Failed to scan '%s'\n", data); - return(parent); + return parent; } void os_stop_process(int pid) @@ -145,7 +146,7 @@ void os_usr1_process(int pid) int os_getpid(void) { - return(syscall(__NR_getpid)); + return syscall(__NR_getpid); } int os_getpgrp(void) @@ -165,8 +166,8 @@ int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, fd, off); if(loc == MAP_FAILED) - return(-errno); - return(0); + return -errno; + return 0; } int os_protect_memory(void *addr, unsigned long len, int r, int w, int x) @@ -175,8 +176,8 @@ int os_protect_memory(void *addr, unsigned long len, int r, int w, int x) (x ? PROT_EXEC : 0)); if(mprotect(addr, len, prot) < 0) - return(-errno); - return(0); + return -errno; + return 0; } int os_unmap_memory(void *addr, int len) @@ -185,8 +186,8 @@ int os_unmap_memory(void *addr, int len) err = munmap(addr, len); if(err < 0) - return(-errno); - return(0); + return -errno; + return 0; } #ifndef MADV_REMOVE diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index f77ce3d6f7cc..8ccf6a36f1c6 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -461,15 +461,16 @@ static void tty_output(int master, int slave) while(os_write_file(master, buf, sizeof(buf)) > 0) ; if(errno != EAGAIN) - panic("check_sigio : write failed, errno = %d\n", errno); + panic("tty_output : write failed, errno = %d\n", errno); while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; if(got_sigio){ printk("Yes\n"); pty_output_sigio = 1; } - else if(n == -EAGAIN) printk("No, enabling workaround\n"); - else panic("check_sigio : read failed, err = %d\n", n); + else if(n == -EAGAIN) + printk("No, enabling workaround\n"); + else panic("tty_output : read failed, err = %d\n", n); } static void tty_close(int master, int slave) diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 41bf8d1e14e0..47852698d5e1 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -409,7 +409,7 @@ int copy_context_skas0(unsigned long new_stack, int pid) /* * This is used only, if stub pages are needed, while proc_mm is - * availabl. Opening /proc/mm creates a new mm_context, which lacks + * available. Opening /proc/mm creates a new mm_context, which lacks * the stub-pages. Thus, we map them using /proc/mm-fd */ void map_stub_pages(int fd, unsigned long code, diff --git a/arch/um/os-Linux/tty_log.c b/arch/um/os-Linux/tty_log.c index c6ba56c1560f..ae9adb1b74f2 100644 --- a/arch/um/os-Linux/tty_log.c +++ b/arch/um/os-Linux/tty_log.c @@ -55,7 +55,7 @@ int open_tty_log(void *tty, void *current_tty) .usec = tv.tv_usec } ); os_write_file(tty_log_fd, &data, sizeof(data)); os_write_file(tty_log_fd, ¤t_tty, data.len); - return(tty_log_fd); + return tty_log_fd; } sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, @@ -67,7 +67,7 @@ int open_tty_log(void *tty, void *current_tty) printk("open_tty_log : couldn't open '%s', errno = %d\n", buf, -fd); } - return(fd); + return fd; } void close_tty_log(int fd, void *tty) @@ -101,18 +101,18 @@ static int log_chunk(int fd, const char *buf, int len) n = os_write_file(fd, chunk, try); if(n != try) { if(n < 0) - return(n); - return(-EIO); + return n; + return -EIO; } if(missed != 0) - return(-EFAULT); + return -EFAULT; len -= try; total += try; buf += try; } - return(total); + return total; } int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read) @@ -133,7 +133,7 @@ int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read) os_write_file(tty_log_fd, &data, sizeof(data)); } - return(log_chunk(fd, buf, len)); + return log_chunk(fd, buf, len); } void log_exec(char **argv, void *tty) @@ -179,7 +179,7 @@ extern void register_tty_logger(int (*opener)(void *, void *), static int register_logger(void) { register_tty_logger(open_tty_log, write_tty_log, close_tty_log); - return(0); + return 0; } __uml_initcall(register_logger); -- cgit v1.2.3-59-g8ed1b From a61f334fd2864b9b040f7e882726426ed7e8a317 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:35 -0700 Subject: uml: convert libc layer to call read and write This patch converts calls in the os layer to os_{read,write}_file to calls directly to libc read() and write() where it is clear that the I/O buffer is in the kernel. We can do that here instead of calling os_{read,write}_file_k since we are in libc code and can call libc directly. With the change in the calls, error handling needs to be changed to refer to errno directly rather than the return value of the call. CATCH_EINTR wrappers were also added where needed. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/aio.c | 36 ++++++++++++++++++-------------- arch/um/os-Linux/drivers/ethertap_user.c | 11 +++++----- arch/um/os-Linux/helper.c | 5 +++-- arch/um/os-Linux/mem.c | 5 ++--- arch/um/os-Linux/process.c | 8 +++---- arch/um/os-Linux/sigio.c | 21 ++++++++++--------- arch/um/os-Linux/skas/mem.c | 19 +++++++++++------ arch/um/os-Linux/skas/process.c | 9 ++++---- arch/um/os-Linux/tty_log.c | 14 ++++++------- 9 files changed, 71 insertions(+), 57 deletions(-) (limited to 'arch') diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index c1f0f76291cf..5d258eb4f506 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -132,10 +132,10 @@ static int aio_thread(void *arg) { .data = (void *) (long) event.data, .err = event.res }); reply_fd = ((struct aio_context *) reply.data)->reply_fd; - err = os_write_file(reply_fd, &reply, sizeof(reply)); + err = write(reply_fd, &reply, sizeof(reply)); if(err != sizeof(reply)) printk("aio_thread - write failed, fd = %d, " - "err = %d\n", reply_fd, -err); + "err = %d\n", reply_fd, errno); } } return 0; @@ -147,7 +147,7 @@ static int do_not_aio(struct aio_thread_req *req) { char c; unsigned long long actual; - int err; + int n; actual = lseek64(req->io_fd, req->offset, SEEK_SET); if(actual != req->offset) @@ -155,21 +155,22 @@ static int do_not_aio(struct aio_thread_req *req) switch(req->type){ case AIO_READ: - err = os_read_file(req->io_fd, req->buf, req->len); + n = read(req->io_fd, req->buf, req->len); break; case AIO_WRITE: - err = os_write_file(req->io_fd, req->buf, req->len); + n = write(req->io_fd, req->buf, req->len); break; case AIO_MMAP: - err = os_read_file(req->io_fd, &c, sizeof(c)); + n = read(req->io_fd, &c, sizeof(c)); break; default: printk("do_not_aio - bad request type : %d\n", req->type); - err = -EINVAL; - break; + return -EINVAL; } - return err; + if(n < 0) + return -errno; + return 0; } /* These are initialized in initcalls and not changed */ @@ -185,12 +186,12 @@ static int not_aio_thread(void *arg) signal(SIGWINCH, SIG_IGN); while(1){ - err = os_read_file(aio_req_fd_r, &req, sizeof(req)); + err = read(aio_req_fd_r, &req, sizeof(req)); if(err != sizeof(req)){ if(err < 0) printk("not_aio_thread - read failed, " "fd = %d, err = %d\n", aio_req_fd_r, - -err); + errno); else { printk("not_aio_thread - short read, fd = %d, " "length = %d\n", aio_req_fd_r, err); @@ -200,10 +201,10 @@ static int not_aio_thread(void *arg) err = do_not_aio(&req); reply = ((struct aio_thread_reply) { .data = req.aio, .err = err }); - err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply)); + err = write(req.aio->reply_fd, &reply, sizeof(reply)); if(err != sizeof(reply)) printk("not_aio_thread - write failed, fd = %d, " - "err = %d\n", req.aio->reply_fd, -err); + "err = %d\n", req.aio->reply_fd, errno); } return 0; @@ -277,10 +278,12 @@ static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, if(err){ reply = ((struct aio_thread_reply) { .data = aio, .err = err }); - err = os_write_file(aio->reply_fd, &reply, sizeof(reply)); - if(err != sizeof(reply)) + err = write(aio->reply_fd, &reply, sizeof(reply)); + if(err != sizeof(reply)){ + err = -errno; printk("submit_aio_26 - write failed, " "fd = %d, err = %d\n", aio->reply_fd, -err); + } else err = 0; } @@ -375,9 +378,10 @@ static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len, }; int err; - err = os_write_file(aio_req_fd_w, &req, sizeof(req)); + err = write(aio_req_fd_w, &req, sizeof(req)); if(err == sizeof(req)) err = 0; + else err = -errno; return err; } diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index fd6cfa5b4a78..acba30161287 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -48,9 +48,9 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask, change.what = op; memcpy(change.addr, addr, sizeof(change.addr)); memcpy(change.netmask, netmask, sizeof(change.netmask)); - n = os_write_file(fd, &change, sizeof(change)); + CATCH_EINTR(n = write(fd, &change, sizeof(change))); if(n != sizeof(change)){ - printk("etap_change - request failed, err = %d\n", -n); + printk("etap_change - request failed, err = %d\n", errno); return; } @@ -123,10 +123,11 @@ static int etap_tramp(char *dev, char *gate, int control_me, err = pid; os_close_file(data_remote); os_close_file(control_remote); - n = os_read_file(control_me, &c, sizeof(c)); + CATCH_EINTR(n = read(control_me, &c, sizeof(c))); if(n != sizeof(c)){ - printk("etap_tramp : read of status failed, err = %d\n", -n); - return -EINVAL; + err = -errno; + printk("etap_tramp : read of status failed, err = %d\n", -err); + return err; } if(c != 1){ printk("etap_tramp : uml_net failed\n"); diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index 8a4c9e47326c..97bed16bf4c7 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -36,7 +36,7 @@ static int helper_child(void *arg) errval = execvp_noalloc(data->buf, argv[0], argv); printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], -errval); - os_write_file(data->fd, &errval, sizeof(errval)); + write(data->fd, &errval, sizeof(errval)); kill(os_getpid(), SIGKILL); return 0; } @@ -92,11 +92,12 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, * Read the errno value from the child, if the exec failed, or get 0 if * the exec succeeded because the pipe fd was set as close-on-exec. */ - n = os_read_file(fds[0], &ret, sizeof(ret)); + n = read(fds[0], &ret, sizeof(ret)); if (n == 0) { ret = pid; } else { if (n < 0) { + n = -errno; printk("run_helper : read on pipe failed, ret = %d\n", -n); ret = n; diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index 77d16023c286..c6378c6d10d2 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c @@ -232,10 +232,9 @@ int __init create_tmp_file(unsigned long long len) zero = 0; - err = os_write_file(fd, &zero, 1); + err = write(fd, &zero, 1); if(err != 1){ - errno = -err; - perror("os_write_file"); + perror("write"); exit(1); } diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index a84a45843f83..92a7b59120d6 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -42,10 +42,10 @@ unsigned long os_process_pc(int pid) proc_stat, -fd); return ARBITRARY_ADDR; } - err = os_read_file(fd, buf, sizeof(buf)); + CATCH_EINTR(err = read(fd, buf, sizeof(buf))); if(err < 0){ printk("os_process_pc - couldn't read '%s', err = %d\n", - proc_stat, -err); + proc_stat, errno); os_close_file(fd); return ARBITRARY_ADDR; } @@ -75,11 +75,11 @@ int os_process_parent(int pid) return FAILURE_PID; } - n = os_read_file(fd, data, sizeof(data)); + CATCH_EINTR(n = read(fd, data, sizeof(data))); os_close_file(fd); if(n < 0){ - printk("Couldn't read '%s', err = %d\n", stat, -n); + printk("Couldn't read '%s', err = %d\n", stat, errno); return FAILURE_PID; } diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 8ccf6a36f1c6..8d4e0c6b8c92 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -69,11 +69,12 @@ static int write_sigio_thread(void *unused) p = &fds->poll[i]; if(p->revents == 0) continue; if(p->fd == sigio_private[1]){ - n = os_read_file(sigio_private[1], &c, sizeof(c)); + CATCH_EINTR(n = read(sigio_private[1], &c, + sizeof(c))); if(n != sizeof(c)) printk("write_sigio_thread : " "read on socket failed, " - "err = %d\n", -n); + "err = %d\n", errno); tmp = current_poll; current_poll = next_poll; next_poll = tmp; @@ -86,10 +87,10 @@ static int write_sigio_thread(void *unused) (fds->used - i) * sizeof(*fds->poll)); } - n = os_write_file(respond_fd, &c, sizeof(c)); + CATCH_EINTR(n = write(respond_fd, &c, sizeof(c))); if(n != sizeof(c)) printk("write_sigio_thread : write on socket " - "failed, err = %d\n", -n); + "failed, err = %d\n", errno); } } @@ -127,15 +128,15 @@ static void update_thread(void) char c; flags = set_signals(0); - n = os_write_file(sigio_private[0], &c, sizeof(c)); + n = write(sigio_private[0], &c, sizeof(c)); if(n != sizeof(c)){ - printk("update_thread : write failed, err = %d\n", -n); + printk("update_thread : write failed, err = %d\n", errno); goto fail; } - n = os_read_file(sigio_private[0], &c, sizeof(c)); + CATCH_EINTR(n = read(sigio_private[0], &c, sizeof(c))); if(n != sizeof(c)){ - printk("update_thread : read failed, err = %d\n", -n); + printk("update_thread : read failed, err = %d\n", errno); goto fail; } @@ -459,10 +460,10 @@ static void tty_output(int master, int slave) memset(buf, 0, sizeof(buf)); - while(os_write_file(master, buf, sizeof(buf)) > 0) ; + while(write(master, buf, sizeof(buf)) > 0) ; if(errno != EAGAIN) panic("tty_output : write failed, errno = %d\n", errno); - while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; + while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; if(got_sigio){ printk("Yes\n"); diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index 470ec531aa5d..6cdfda807b65 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -199,9 +200,11 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, .fd = phys_fd, .offset= offset } } } ); - ret = os_write_file(fd, &map, sizeof(map)); - if(ret != sizeof(map)) + CATCH_EINTR(ret = write(fd, &map, sizeof(map))); + if(ret != sizeof(map)){ + ret = -errno; printk("map : /proc/mm map failed, err = %d\n", -ret); + } else ret = 0; } else { @@ -231,9 +234,11 @@ int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done, { .addr = (unsigned long) addr, .len = len } } } ); - ret = os_write_file(fd, &unmap, sizeof(unmap)); - if(ret != sizeof(unmap)) + CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap))); + if(ret != sizeof(unmap)){ + ret = -errno; printk("unmap - proc_mm write returned %d\n", ret); + } else ret = 0; } else { @@ -266,9 +271,11 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, .len = len, .prot = prot } } } ); - ret = os_write_file(fd, &protect, sizeof(protect)); - if(ret != sizeof(protect)) + CATCH_EINTR(ret = write(fd, &protect, sizeof(protect))); + if(ret != sizeof(protect)){ + ret = -errno; printk("protect failed, err = %d", -ret); + } else ret = 0; } else { diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 47852698d5e1..5b1943dc15e9 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -431,12 +431,13 @@ void map_stub_pages(int fd, unsigned long code, .fd = code_fd, .offset = code_offset } } }); - n = os_write_file(fd, &mmop, sizeof(mmop)); + CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); if(n != sizeof(mmop)){ + n = errno; printk("mmap args - addr = 0x%lx, fd = %d, offset = %llx\n", code, code_fd, (unsigned long long) code_offset); panic("map_stub_pages : /proc/mm map for code failed, " - "err = %d\n", -n); + "err = %d\n", n); } if ( stack ) { @@ -453,10 +454,10 @@ void map_stub_pages(int fd, unsigned long code, .fd = map_fd, .offset = map_offset } } }); - n = os_write_file(fd, &mmop, sizeof(mmop)); + CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); if(n != sizeof(mmop)) panic("map_stub_pages : /proc/mm map for data failed, " - "err = %d\n", -n); + "err = %d\n", errno); } } diff --git a/arch/um/os-Linux/tty_log.c b/arch/um/os-Linux/tty_log.c index ae9adb1b74f2..d11a55baa6bd 100644 --- a/arch/um/os-Linux/tty_log.c +++ b/arch/um/os-Linux/tty_log.c @@ -53,8 +53,8 @@ int open_tty_log(void *tty, void *current_tty) .direction = 0, .sec = tv.tv_sec, .usec = tv.tv_usec } ); - os_write_file(tty_log_fd, &data, sizeof(data)); - os_write_file(tty_log_fd, ¤t_tty, data.len); + write(tty_log_fd, &data, sizeof(data)); + write(tty_log_fd, ¤t_tty, data.len); return tty_log_fd; } @@ -83,7 +83,7 @@ void close_tty_log(int fd, void *tty) .direction = 0, .sec = tv.tv_sec, .usec = tv.tv_usec } ); - os_write_file(tty_log_fd, &data, sizeof(data)); + write(tty_log_fd, &data, sizeof(data)); return; } os_close_file(fd); @@ -98,10 +98,10 @@ static int log_chunk(int fd, const char *buf, int len) try = (len > sizeof(chunk)) ? sizeof(chunk) : len; missed = copy_from_user_proc(chunk, (char *) buf, try); try -= missed; - n = os_write_file(fd, chunk, try); + n = write(fd, chunk, try); if(n != try) { if(n < 0) - return n; + return -errno; return -EIO; } if(missed != 0) @@ -130,7 +130,7 @@ int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read) .direction = direction, .sec = tv.tv_sec, .usec = tv.tv_usec } ); - os_write_file(tty_log_fd, &data, sizeof(data)); + write(tty_log_fd, &data, sizeof(data)); } return log_chunk(fd, buf, len); @@ -161,7 +161,7 @@ void log_exec(char **argv, void *tty) .direction = 0, .sec = tv.tv_sec, .usec = tv.tv_usec } ); - os_write_file(tty_log_fd, &data, sizeof(data)); + write(tty_log_fd, &data, sizeof(data)); for(ptr = argv; ; ptr++){ if(copy_from_user_proc(&arg, ptr, sizeof(arg))) -- cgit v1.2.3-59-g8ed1b From a0044bdf60c212366a314da09ca624cb315906e2 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:36 -0700 Subject: uml: batch I/O requests Send as many I/O requests to the I/O thread as possible, even though it will still only handle one at a time. This provides an opportunity to reduce latency by starting one request before the previous one has been finished in the driver. Request handling is somewhat modernized by requesting sg pieces of a request and handling them separately, finishing off the entire request after all the pieces are done. When a request queue stalls, normally because its pipe to the I/O thread is full, it is put on the restart list. This list is processed by starting up the queues on it whenever there is some indication that progress might be possible again. Currently, this happens in the driver interrupt routine. Some requests have been finished, so there is likely to be room in the pipe again. This almost doubles throughput when copying data between devices, but made no noticable difference on anything else I tried. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 176 +++++++++++++++++++++++++-------------------- 1 file changed, 99 insertions(+), 77 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 6d163c9e2885..5ef47b73ce99 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -149,7 +149,10 @@ struct cow { int data_offset; }; +#define MAX_SG 64 + struct ubd { + struct list_head restart; /* name (and fd, below) of the file opened for writing, either the * backing or the cow file. */ char *file; @@ -164,7 +167,9 @@ struct ubd { struct platform_device pdev; struct request_queue *queue; spinlock_t lock; - int active; + struct scatterlist sg[MAX_SG]; + struct request *request; + int start_sg, end_sg; }; #define DEFAULT_COW { \ @@ -186,7 +191,9 @@ struct ubd { .shared = 0, \ .cow = DEFAULT_COW, \ .lock = SPIN_LOCK_UNLOCKED, \ - .active = 0, \ + .request = NULL, \ + .start_sg = 0, \ + .end_sg = 0, \ } /* Protected by ubd_lock */ @@ -466,60 +473,67 @@ static void do_ubd_request(request_queue_t * q); /* Only changed by ubd_init, which is an initcall. */ int thread_fd = -1; -/* call ubd_finish if you need to serialize */ -static void __ubd_finish(struct request *req, int error) +static void ubd_end_request(struct request *req, int bytes, int uptodate) { - int nsect; - - if(error){ - end_request(req, 0); - return; + if (!end_that_request_first(req, uptodate, bytes >> 9)) { + struct ubd *dev = req->rq_disk->private_data; + unsigned long flags; + + add_disk_randomness(req->rq_disk); + spin_lock_irqsave(&dev->lock, flags); + end_that_request_last(req, uptodate); + spin_unlock_irqrestore(&dev->lock, flags); } - nsect = req->current_nr_sectors; - req->sector += nsect; - req->buffer += nsect << 9; - req->errors = 0; - req->nr_sectors -= nsect; - req->current_nr_sectors = 0; - end_request(req, 1); } /* Callable only from interrupt context - otherwise you need to do * spin_lock_irq()/spin_lock_irqsave() */ -static inline void ubd_finish(struct request *req, int error) +static inline void ubd_finish(struct request *req, int bytes) { - struct ubd *dev = req->rq_disk->private_data; - - spin_lock(&dev->lock); - __ubd_finish(req, error); - spin_unlock(&dev->lock); + if(bytes < 0){ + ubd_end_request(req, 0, 0); + return; + } + ubd_end_request(req, bytes, 1); } +static LIST_HEAD(restart); + /* XXX - move this inside ubd_intr. */ /* Called without dev->lock held, and only in interrupt context. */ static void ubd_handler(void) { struct io_thread_req req; struct request *rq; - struct ubd *dev; + struct ubd *ubd; + struct list_head *list, *next_ele; + unsigned long flags; int n; - n = os_read_file_k(thread_fd, &req, sizeof(req)); - if(n != sizeof(req)){ - printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, " - "err = %d\n", os_getpid(), -n); - return; - } - - rq = req.req; - dev = rq->rq_disk->private_data; - dev->active = 0; + while(1){ + n = os_read_file_k(thread_fd, &req, sizeof(req)); + if(n != sizeof(req)){ + if(n == -EAGAIN) + break; + printk(KERN_ERR "spurious interrupt in ubd_handler, " + "err = %d\n", -n); + return; + } - ubd_finish(rq, req.error); + rq = req.req; + rq->nr_sectors -= req.length >> 9; + if(rq->nr_sectors == 0) + ubd_finish(rq, rq->hard_nr_sectors << 9); + } reactivate_fd(thread_fd, UBD_IRQ); - spin_lock(&dev->lock); - do_ubd_request(dev->queue); - spin_unlock(&dev->lock); + + list_for_each_safe(list, next_ele, &restart){ + ubd = container_of(list, struct ubd, restart); + list_del_init(&ubd->restart); + spin_lock_irqsave(&ubd->lock, flags); + do_ubd_request(ubd->queue); + spin_unlock_irqrestore(&ubd->lock, flags); + } } static irqreturn_t ubd_intr(int irq, void *dev) @@ -684,6 +698,8 @@ static int ubd_add(int n, char **error_out) ubd_dev->size = ROUND_BLOCK(ubd_dev->size); + INIT_LIST_HEAD(&ubd_dev->restart); + err = -ENOMEM; ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock); if (ubd_dev->queue == NULL) { @@ -692,6 +708,7 @@ static int ubd_add(int n, char **error_out) } ubd_dev->queue->queuedata = ubd_dev; + blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG); err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]); if(err){ *error_out = "Failed to register device"; @@ -1029,26 +1046,16 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, } /* Called with dev->lock held */ -static int prepare_request(struct request *req, struct io_thread_req *io_req) +static void prepare_request(struct request *req, struct io_thread_req *io_req, + unsigned long long offset, int page_offset, + int len, struct page *page) { struct gendisk *disk = req->rq_disk; struct ubd *ubd_dev = disk->private_data; - __u64 offset; - int len; - - /* This should be impossible now */ - if((rq_data_dir(req) == WRITE) && !ubd_dev->openflags.w){ - printk("Write attempted on readonly ubd device %s\n", - disk->disk_name); - end_request(req, 0); - return(1); - } - - offset = ((__u64) req->sector) << 9; - len = req->current_nr_sectors << 9; io_req->req = req; - io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : ubd_dev->fd; + io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : + ubd_dev->fd; io_req->fds[1] = ubd_dev->fd; io_req->cow_offset = -1; io_req->offset = offset; @@ -1059,14 +1066,13 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req) io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE; io_req->offsets[0] = 0; io_req->offsets[1] = ubd_dev->cow.data_offset; - io_req->buffer = req->buffer; + io_req->buffer = page_address(page) + page_offset; io_req->sectorsize = 1 << 9; if(ubd_dev->cow.file != NULL) - cowify_req(io_req, ubd_dev->cow.bitmap, ubd_dev->cow.bitmap_offset, - ubd_dev->cow.bitmap_len); + cowify_req(io_req, ubd_dev->cow.bitmap, + ubd_dev->cow.bitmap_offset, ubd_dev->cow.bitmap_len); - return(0); } /* Called with dev->lock held */ @@ -1074,29 +1080,45 @@ static void do_ubd_request(request_queue_t *q) { struct io_thread_req io_req; struct request *req; - int err, n; - - if(thread_fd == -1){ - while((req = elv_next_request(q)) != NULL){ - err = prepare_request(req, &io_req); - if(!err){ - do_io(&io_req); - __ubd_finish(req, io_req.error); - } - } - } - else { + int n; + + while(1){ struct ubd *dev = q->queuedata; - if(dev->active || (req = elv_next_request(q)) == NULL) - return; - err = prepare_request(req, &io_req); - if(!err){ - dev->active = 1; - n = os_write_file_k(thread_fd, &io_req, sizeof(io_req)); - if(n != sizeof(io_req)) - printk("write to io thread failed, " - "errno = %d\n", -n); + if(dev->end_sg == 0){ + struct request *req = elv_next_request(q); + if(req == NULL) + return; + + dev->request = req; + blkdev_dequeue_request(req); + dev->start_sg = 0; + dev->end_sg = blk_rq_map_sg(q, req, dev->sg); + } + + req = dev->request; + while(dev->start_sg < dev->end_sg){ + struct scatterlist *sg = &dev->sg[dev->start_sg]; + + prepare_request(req, &io_req, + (unsigned long long) req->sector << 9, + sg->offset, sg->length, sg->page); + + n = os_write_file_k(thread_fd, (char *) &io_req, + sizeof(io_req)); + if(n != sizeof(io_req)){ + if(n != -EAGAIN) + printk("write to io thread failed, " + "errno = %d\n", -n); + else if(list_empty(&dev->restart)) + list_add(&dev->restart, &restart); + return; + } + + req->sector += sg->length >> 9; + dev->start_sg++; } + dev->end_sg = 0; + dev->request = NULL; } } -- cgit v1.2.3-59-g8ed1b From 2adcec2197897365e0a0f657f1098cbfdb44bc8b Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:37 -0700 Subject: uml: send pointers instead of structures to I/O thread Instead of writing entire structures between UML and the I/O thread, we send pointers. This cuts down on the amount of data being copied and possibly allows more requests to be pending between the two. This requires that the requests be kmalloced and freed instead of living on the stack. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 5ef47b73ce99..9200a457eb98 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -503,7 +503,7 @@ static LIST_HEAD(restart); /* Called without dev->lock held, and only in interrupt context. */ static void ubd_handler(void) { - struct io_thread_req req; + struct io_thread_req *req; struct request *rq; struct ubd *ubd; struct list_head *list, *next_ele; @@ -511,7 +511,8 @@ static void ubd_handler(void) int n; while(1){ - n = os_read_file_k(thread_fd, &req, sizeof(req)); + n = os_read_file_k(thread_fd, &req, + sizeof(struct io_thread_req *)); if(n != sizeof(req)){ if(n == -EAGAIN) break; @@ -520,10 +521,11 @@ static void ubd_handler(void) return; } - rq = req.req; - rq->nr_sectors -= req.length >> 9; + rq = req->req; + rq->nr_sectors -= req->length >> 9; if(rq->nr_sectors == 0) ubd_finish(rq, rq->hard_nr_sectors << 9); + kfree(req); } reactivate_fd(thread_fd, UBD_IRQ); @@ -1078,7 +1080,7 @@ static void prepare_request(struct request *req, struct io_thread_req *io_req, /* Called with dev->lock held */ static void do_ubd_request(request_queue_t *q) { - struct io_thread_req io_req; + struct io_thread_req *io_req; struct request *req; int n; @@ -1099,13 +1101,20 @@ static void do_ubd_request(request_queue_t *q) while(dev->start_sg < dev->end_sg){ struct scatterlist *sg = &dev->sg[dev->start_sg]; - prepare_request(req, &io_req, + io_req = kmalloc(sizeof(struct io_thread_req), + GFP_KERNEL | GFP_ATOMIC); + if(io_req == NULL){ + if(list_empty(&dev->restart)) + list_add(&dev->restart, &restart); + return; + } + prepare_request(req, io_req, (unsigned long long) req->sector << 9, sg->offset, sg->length, sg->page); - n = os_write_file_k(thread_fd, (char *) &io_req, - sizeof(io_req)); - if(n != sizeof(io_req)){ + n = os_write_file_k(thread_fd, &io_req, + sizeof(struct io_thread_req *)); + if(n != sizeof(struct io_thread_req *)){ if(n != -EAGAIN) printk("write to io thread failed, " "errno = %d\n", -n); @@ -1437,13 +1446,14 @@ static int io_count = 0; int io_thread(void *arg) { - struct io_thread_req req; + struct io_thread_req *req; int n; ignore_sigwinch_sig(); while(1){ - n = os_read_file_k(kernel_fd, &req, sizeof(req)); - if(n != sizeof(req)){ + n = os_read_file_k(kernel_fd, &req, + sizeof(struct io_thread_req *)); + if(n != sizeof(struct io_thread_req *)){ if(n < 0) printk("io_thread - read failed, fd = %d, " "err = %d\n", kernel_fd, -n); @@ -1454,9 +1464,10 @@ int io_thread(void *arg) continue; } io_count++; - do_io(&req); - n = os_write_file_k(kernel_fd, &req, sizeof(req)); - if(n != sizeof(req)) + do_io(req); + n = os_write_file_k(kernel_fd, &req, + sizeof(struct io_thread_req *)); + if(n != sizeof(struct io_thread_req *)) printk("io_thread - write failed, fd = %d, err = %d\n", kernel_fd, -n); } -- cgit v1.2.3-59-g8ed1b From 990c55871b655156ffd7787af791be977d946ef6 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 6 May 2007 14:51:38 -0700 Subject: uml: fixup allocation in the ubd driver Sanitise gfp flags; it actually is an atomic context, so drop the GFP_KERNEL part. Signed-off-by: Peter Zijlstra Acked-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 9200a457eb98..88a246edb61e 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1102,7 +1102,7 @@ static void do_ubd_request(request_queue_t *q) struct scatterlist *sg = &dev->sg[dev->start_sg]; io_req = kmalloc(sizeof(struct io_thread_req), - GFP_KERNEL | GFP_ATOMIC); + GFP_ATOMIC); if(io_req == NULL){ if(list_empty(&dev->restart)) list_add(&dev->restart, &restart); -- cgit v1.2.3-59-g8ed1b From 63843c265fd0e0c7894f713e0db5777560e756ae Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:39 -0700 Subject: uml: dump core on panic Dump core after a panic. This will provide better debugging information than is currently available. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/os.h | 1 + arch/um/kernel/um_arch.c | 2 +- arch/um/os-Linux/util.c | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/um/include/os.h b/arch/um/include/os.h index b463170a5308..901804db3c35 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -279,6 +279,7 @@ extern int raw(int fd); extern void setup_machinename(char *machine_out); extern void setup_hostinfo(char *buf, int len); extern int setjmp_wrapper(void (*proc)(void *, void *), ...); +extern void os_dump_core(void); /* time.c */ #define BILLION (1000 * 1000 * 1000) diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 9bf31533a8fd..1cf954a47fd7 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -474,7 +474,7 @@ static int panic_exit(struct notifier_block *self, unsigned long unused1, show_regs(&(current->thread.regs)); bust_spinlocks(0); uml_exitcode = 1; - machine_halt(); + os_dump_core(); return 0; } diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 48bc4927b996..c307a89ed259 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -119,3 +119,9 @@ int setjmp_wrapper(void (*proc)(void *, void *), ...) va_end(args); return n; } + +void os_dump_core(void) +{ + signal(SIGSEGV, SIG_DFL); + abort(); +} -- cgit v1.2.3-59-g8ed1b From 77f6af778dc23514d897f4fdc7935329285ecb1b Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:40 -0700 Subject: uml: don't try to handle signals on initial process stack Code running on the initial UML stack can't receive or process signals since current must be valid when IRQs are handled, and there is no current for this stack. So, instead of using UML_LONGJMP and UML_SETJMP, which are careful to save and restore signal state, and, as a side-effect, handle any deferred signals, start_idle_thread must use the bare equivalents, which don't do anything with signals. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/skas/process.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 5b1943dc15e9..1f39f2bf7ce9 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -494,7 +494,15 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, SIGVTALRM, -1); - n = UML_SETJMP(&initial_jmpbuf); + /* + * Can't use UML_SETJMP or UML_LONGJMP here because they save + * and restore signals, with the possible side-effect of + * trying to handle any signals which came when they were + * blocked, which can't be done on this stack. + * Signals must be blocked when jumping back here and restored + * after returning to the jumper. + */ + n = setjmp(initial_jmpbuf); switch(n){ case INIT_JMP_NEW_THREAD: (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler; @@ -504,7 +512,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) break; case INIT_JMP_CALLBACK: (*cb_proc)(cb_arg); - UML_LONGJMP(cb_back, 1); + longjmp(*cb_back, 1); break; case INIT_JMP_HALT: kmalloc_ok = 0; @@ -515,7 +523,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) default: panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); } - UML_LONGJMP(switch_buf, 1); + longjmp(*switch_buf, 1); } void initial_thread_cb_skas(void (*proc)(void *), void *arg) -- cgit v1.2.3-59-g8ed1b From fda83a99b2b49016b9d7ed562745969db25c4ef9 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:41 -0700 Subject: uml: change remaining callers of os_{read_write}_file Convert all remaining os_{read_write}_file users to use the simple {read,write} wrappers, os_{read_write}_file_k. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_kern.c | 4 ++-- arch/um/drivers/cow_sys.h | 2 +- arch/um/drivers/net_user.c | 6 +++--- arch/um/drivers/ubd_kern.c | 2 +- arch/um/kernel/initrd.c | 2 +- arch/um/kernel/physmem.c | 2 +- arch/um/sys-i386/bugs.c | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 3aa351611763..92e069e8253f 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -98,7 +98,7 @@ int generic_read(int fd, char *c_out, void *unused) { int n; - n = os_read_file(fd, c_out, sizeof(*c_out)); + n = os_read_file_k(fd, c_out, sizeof(*c_out)); if(n == -EAGAIN) return 0; @@ -111,7 +111,7 @@ int generic_read(int fd, char *c_out, void *unused) int generic_write(int fd, const char *buf, int n, void *unused) { - return os_write_file(fd, buf, n); + return os_write_file_k(fd, buf, n); } int generic_window_size(int fd, void *unused, unsigned short *rows_out, diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index c702943769cb..3255583eccba 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h @@ -35,7 +35,7 @@ static inline int cow_file_size(char *file, unsigned long long *size_out) static inline int cow_write_file(int fd, void *buf, int size) { - return(os_write_file(fd, buf, size)); + return(os_write_file_k(fd, buf, size)); } #endif diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 2dc57a37e4b7..8bc6688c4f0f 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -73,7 +73,7 @@ void read_output(int fd, char *output, int len) while(remain != 0){ expected = (remain < len) ? remain : len; - ret = os_read_file(fd, output, expected); + ret = os_read_file_k(fd, output, expected); if (ret != expected) { str = "data"; goto err; @@ -94,7 +94,7 @@ int net_read(int fd, void *buf, int len) { int n; - n = os_read_file(fd, buf, len); + n = os_read_file_k(fd, buf, len); if(n == -EAGAIN) return 0; @@ -122,7 +122,7 @@ int net_write(int fd, void *buf, int len) { int n; - n = os_write_file(fd, buf, len); + n = os_write_file_k(fd, buf, len); if(n == -EAGAIN) return 0; diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 88a246edb61e..2a00203e1017 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1246,7 +1246,7 @@ int read_cow_bitmap(int fd, void *buf, int offset, int len) if(err < 0) return(err); - err = os_read_file(fd, buf, len); + err = os_read_file_k(fd, buf, len); if(err < 0) return(err); diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index 6ab1539108e1..bf3dd9659865 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c @@ -55,7 +55,7 @@ int load_initrd(char *filename, void *buf, int size) printk("Opening '%s' failed - err = %d\n", filename, -fd); return(-1); } - n = os_read_file(fd, buf, size); + n = os_read_file_k(fd, buf, size); if(n != size){ printk("Read of %d bytes from '%s' failed, err = %d\n", size, filename, -n); diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index a9856209006b..77021a627da6 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -211,7 +211,7 @@ void physmem_forget_descriptor(int fd) panic("physmem_forget_descriptor - failed to seek " "to %lld in fd %d, error = %d\n", offset, fd, -err); - err = os_read_file(fd, addr, PAGE_SIZE); + err = os_read_file_k(fd, addr, PAGE_SIZE); if(err < 0) panic("physmem_forget_descriptor - failed to read " "from fd %d to 0x%p, error = %d\n", diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c index 74fd062b201b..f5dfe49c8442 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/um/sys-i386/bugs.c @@ -28,7 +28,7 @@ static char token(int fd, char *buf, int len, char stop) ptr = buf; end = &buf[len]; do { - n = os_read_file(fd, ptr, sizeof(*ptr)); + n = os_read_file_k(fd, ptr, sizeof(*ptr)); c = *ptr++; if(n != sizeof(*ptr)){ if(n == 0) -- cgit v1.2.3-59-g8ed1b From dc764e5087bceeb26714bb7975b711062b39d804 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:41 -0700 Subject: uml: formatting fixes around os_{read_write}_file callers Formatting fixes ahead of renaming os_{read_write}_file_k to os_{read_write}_file and fixing all the callers. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_user.c | 11 ---- arch/um/drivers/cow_sys.h | 17 ++---- arch/um/drivers/ubd_kern.c | 124 ++++++++++++++++++++++---------------------- arch/um/kernel/initrd.c | 32 ++++++------ arch/um/kernel/smp.c | 25 +++------ 5 files changed, 89 insertions(+), 120 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index d226f103462e..a15be1720e03 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -203,14 +203,3 @@ void register_winch(int fd, struct tty_struct *tty) } } } - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index 3255583eccba..aa7bef9c38d9 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h @@ -8,7 +8,7 @@ static inline void *cow_malloc(int size) { - return(um_kmalloc(size)); + return um_kmalloc(size); } static inline void cow_free(void *ptr) @@ -20,29 +20,22 @@ static inline void cow_free(void *ptr) static inline char *cow_strdup(char *str) { - return(uml_strdup(str)); + return uml_strdup(str); } static inline int cow_seek_file(int fd, __u64 offset) { - return(os_seek_file(fd, offset)); + return os_seek_file(fd, offset); } static inline int cow_file_size(char *file, unsigned long long *size_out) { - return(os_file_size(file, size_out)); + return os_file_size(file, size_out); } static inline int cow_write_file(int fd, void *buf, int size) { - return(os_write_file_k(fd, buf, size)); + return os_write_file_k(fd, buf, size); } #endif - -/* - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 2a00203e1017..614fe25a31bd 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -89,7 +89,7 @@ static inline int ubd_test_bit(__u64 bit, unsigned char *data) bits = sizeof(data[0]) * 8; n = bit / bits; off = bit % bits; - return((data[n] & (1 << off)) != 0); + return (data[n] & (1 << off)) != 0; } static inline void ubd_set_bit(__u64 bit, unsigned char *data) @@ -146,7 +146,7 @@ struct cow { unsigned long *bitmap; unsigned long bitmap_len; int bitmap_offset; - int data_offset; + int data_offset; }; #define MAX_SG 64 @@ -174,10 +174,10 @@ struct ubd { #define DEFAULT_COW { \ .file = NULL, \ - .fd = -1, \ - .bitmap = NULL, \ + .fd = -1, \ + .bitmap = NULL, \ .bitmap_offset = 0, \ - .data_offset = 0, \ + .data_offset = 0, \ } #define DEFAULT_UBD { \ @@ -187,9 +187,9 @@ struct ubd { .size = -1, \ .boot_openflags = OPEN_FLAGS, \ .openflags = OPEN_FLAGS, \ - .no_cow = 0, \ + .no_cow = 0, \ .shared = 0, \ - .cow = DEFAULT_COW, \ + .cow = DEFAULT_COW, \ .lock = SPIN_LOCK_UNLOCKED, \ .request = NULL, \ .start_sg = 0, \ @@ -249,7 +249,7 @@ static void make_ide_entries(char *dev_name) static int fake_ide_setup(char *str) { fake_ide = 1; - return(1); + return 1; } __setup("fake_ide", fake_ide_setup); @@ -267,7 +267,7 @@ static int parse_unit(char **ptr) if(isdigit(*str)) { n = simple_strtoul(str, &end, 0); if(end == str) - return(-1); + return -1; *ptr = end; } else if (('a' <= *str) && (*str <= 'z')) { @@ -275,7 +275,7 @@ static int parse_unit(char **ptr) str++; *ptr = str; } - return(n); + return n; } /* If *index_out == -1 at exit, the passed option was a general one; @@ -442,7 +442,7 @@ static int udb_setup(char *str) { printk("udb%s specified on command line is almost certainly a ubd -> " "udb TYPO\n", str); - return(1); + return 1; } __setup("udb", udb_setup); @@ -541,7 +541,7 @@ static void ubd_handler(void) static irqreturn_t ubd_intr(int irq, void *dev) { ubd_handler(); - return(IRQ_HANDLED); + return IRQ_HANDLED; } /* Only changed by ubd_init, which is an initcall. */ @@ -560,7 +560,7 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) char *file; file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file; - return(os_file_size(file, size_out)); + return os_file_size(file, size_out); } static void ubd_close_dev(struct ubd *ubd_dev) @@ -632,10 +632,10 @@ static int ubd_open_dev(struct ubd *ubd_dev) if(err < 0) goto error; ubd_dev->cow.fd = err; } - return(0); + return 0; error: os_close_file(ubd_dev->fd); - return(err); + return err; } static void ubd_device_release(struct device *dev) @@ -653,7 +653,7 @@ static int ubd_disk_register(int major, u64 size, int unit, disk = alloc_disk(1 << UBD_SHIFT); if(disk == NULL) - return(-ENOMEM); + return -ENOMEM; disk->major = major; disk->first_minor = unit << UBD_SHIFT; @@ -758,14 +758,14 @@ static int ubd_config(char *str, char **error_out) goto err_free; } - mutex_lock(&ubd_lock); + mutex_lock(&ubd_lock); ret = ubd_add(n, error_out); if (ret) ubd_devs[n].file = NULL; - mutex_unlock(&ubd_lock); + mutex_unlock(&ubd_lock); out: - return ret; + return ret; err_free: kfree(str); @@ -780,7 +780,7 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out) n = parse_unit(&name); if((n >= MAX_DEV) || (n < 0)){ *error_out = "ubd_get_config : device number out of range"; - return(-1); + return -1; } ubd_dev = &ubd_devs[n]; @@ -801,17 +801,17 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out) out: mutex_unlock(&ubd_lock); - return(len); + return len; } static int ubd_id(char **str, int *start_out, int *end_out) { - int n; + int n; n = parse_unit(str); - *start_out = 0; - *end_out = MAX_DEV - 1; - return n; + *start_out = 0; + *end_out = MAX_DEV - 1; + return n; } static int ubd_remove(int n, char **error_out) @@ -832,7 +832,7 @@ static int ubd_remove(int n, char **error_out) if(ubd_dev->count > 0) goto out; - ubd_gendisk[n] = NULL; + ubd_gendisk[n] = NULL; if(disk != NULL){ del_gendisk(disk); put_disk(disk); @@ -858,7 +858,7 @@ static struct mc_device ubd_mc = { .list = LIST_HEAD_INIT(ubd_mc.list), .name = "ubd", .config = ubd_config, - .get_config = ubd_get_config, + .get_config = ubd_get_config, .id = ubd_id, .remove = ubd_remove, }; @@ -880,7 +880,7 @@ static int __init ubd0_init(void) ubd_dev->file = "root_fs"; mutex_unlock(&ubd_lock); - return(0); + return 0; } __initcall(ubd0_init); @@ -908,14 +908,14 @@ static int __init ubd_init(void) return -1; } platform_driver_register(&ubd_driver); - mutex_lock(&ubd_lock); + mutex_lock(&ubd_lock); for (i = 0; i < MAX_DEV; i++){ err = ubd_add(i, &error); if(err) printk(KERN_ERR "Failed to initialize ubd device %d :" "%s\n", i, error); } - mutex_unlock(&ubd_lock); + mutex_unlock(&ubd_lock); return 0; } @@ -939,7 +939,7 @@ static int __init ubd_driver_init(void){ "ubd : Failed to start I/O thread (errno = %d) - " "falling back to synchronous I/O\n", -io_pid); io_pid = -1; - return(0); + return 0; } err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, IRQF_DISABLED, "ubd", ubd_devs); @@ -974,7 +974,7 @@ static int ubd_open(struct inode *inode, struct file *filp) err = -EROFS; }*/ out: - return(err); + return err; } static int ubd_release(struct inode * inode, struct file * file) @@ -984,7 +984,7 @@ static int ubd_release(struct inode * inode, struct file * file) if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev); - return(0); + return 0; } static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask, @@ -1040,7 +1040,7 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, if(ubd_test_bit(sector + i, (unsigned char *) bitmap)) ubd_set_bit(i, (unsigned char *) &req->sector_mask); - } + } } else cowify_bitmap(req->offset, req->length, &req->sector_mask, &req->cow_offset, bitmap, bitmap_offset, @@ -1157,21 +1157,21 @@ static int ubd_ioctl(struct inode * inode, struct file * file, ubd_id.cyls = ubd_dev->size / (128 * 32 * 512); if(copy_to_user((char __user *) arg, (char *) &ubd_id, sizeof(ubd_id))) - return(-EFAULT); - return(0); + return -EFAULT; + return 0; case CDROMVOLREAD: if(copy_from_user(&volume, (char __user *) arg, sizeof(volume))) - return(-EFAULT); + return -EFAULT; volume.channel0 = 255; volume.channel1 = 255; volume.channel2 = 255; volume.channel3 = 255; if(copy_to_user((char __user *) arg, &volume, sizeof(volume))) - return(-EFAULT); - return(0); + return -EFAULT; + return 0; } - return(-EINVAL); + return -EINVAL; } static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow) @@ -1213,29 +1213,29 @@ static int backing_file_mismatch(char *file, __u64 size, time_t mtime) if(err < 0){ printk("Failed to get modification time of backing file " "\"%s\", err = %d\n", file, -err); - return(err); + return err; } err = os_file_size(file, &actual); if(err < 0){ printk("Failed to get size of backing file \"%s\", " "err = %d\n", file, -err); - return(err); + return err; } - if(actual != size){ + if(actual != size){ /*__u64 can be a long on AMD64 and with %lu GCC complains; so * the typecast.*/ printk("Size mismatch (%llu vs %llu) of COW header vs backing " "file\n", (unsigned long long) size, actual); - return(-EINVAL); + return -EINVAL; } if(modtime != mtime){ printk("mtime mismatch (%ld vs %ld) of COW header vs backing " "file\n", mtime, modtime); - return(-EINVAL); + return -EINVAL; } - return(0); + return 0; } int read_cow_bitmap(int fd, void *buf, int offset, int len) @@ -1244,13 +1244,13 @@ int read_cow_bitmap(int fd, void *buf, int offset, int len) err = os_seek_file(fd, offset); if(err < 0) - return(err); + return err; - err = os_read_file_k(fd, buf, len); + err = os_read_file(fd, buf, len); if(err < 0) - return(err); + return err; - return(0); + return 0; } int open_ubd_file(char *file, struct openflags *openflags, int shared, @@ -1268,14 +1268,14 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared, if (fd < 0) { if ((fd == -ENOENT) && (create_cow_out != NULL)) *create_cow_out = 1; - if (!openflags->w || - ((fd != -EROFS) && (fd != -EACCES))) + if (!openflags->w || + ((fd != -EROFS) && (fd != -EACCES))) return fd; openflags->w = 0; fd = os_open_file(file, *openflags, mode); if (fd < 0) return fd; - } + } if(shared) printk("Not locking \"%s\" on the host\n", file); @@ -1289,7 +1289,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared, /* Successful return case! */ if(backing_file_out == NULL) - return(fd); + return fd; err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime, &size, §orsize, &align, bitmap_offset_out); @@ -1299,7 +1299,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared, goto out_close; } if(err) - return(fd); + return fd; asked_switch = path_requires_switch(*backing_file_out, backing_file, file); @@ -1322,7 +1322,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared, cow_sizes(version, size, sectorsize, align, *bitmap_offset_out, bitmap_len_out, data_offset_out); - return fd; + return fd; out_close: os_close_file(fd); return err; @@ -1347,10 +1347,10 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags, bitmap_offset_out, bitmap_len_out, data_offset_out); if(!err) - return(fd); + return fd; os_close_file(fd); out: - return(err); + return err; } static int update_bitmap(struct io_thread_req *req) @@ -1358,12 +1358,12 @@ static int update_bitmap(struct io_thread_req *req) int n; if(req->cow_offset == -1) - return(0); + return 0; n = os_seek_file(req->fds[1], req->cow_offset); if(n < 0){ printk("do_io - bitmap lseek failed : err = %d\n", -n); - return(1); + return 1; } n = os_write_file_k(req->fds[1], &req->bitmap_words, @@ -1371,10 +1371,10 @@ static int update_bitmap(struct io_thread_req *req) if(n != sizeof(req->bitmap_words)){ printk("do_io - bitmap update failed, err = %d fd = %d\n", -n, req->fds[1]); - return(1); + return 1; } - return(0); + return 0; } void do_io(struct io_thread_req *req) diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index bf3dd9659865..cff73faae991 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c @@ -21,12 +21,20 @@ static int __init read_initrd(void) long long size; int err; - if(initrd == NULL) return 0; + if(initrd == NULL) + return 0; + err = os_file_size(initrd, &size); - if(err) return 0; + if(err) + return 0; + area = alloc_bootmem(size); - if(area == NULL) return 0; - if(load_initrd(initrd, area, size) == -1) return 0; + if(area == NULL) + return 0; + + if(load_initrd(initrd, area, size) == -1) + return 0; + initrd_start = (unsigned long) area; initrd_end = initrd_start + size; return 0; @@ -53,25 +61,15 @@ int load_initrd(char *filename, void *buf, int size) fd = os_open_file(filename, of_read(OPENFLAGS()), 0); if(fd < 0){ printk("Opening '%s' failed - err = %d\n", filename, -fd); - return(-1); + return -1; } n = os_read_file_k(fd, buf, size); if(n != size){ printk("Read of %d bytes from '%s' failed, err = %d\n", size, filename, -n); - return(-1); + return -1; } os_close_file(fd); - return(0); + return 0; } -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index 47b690893c06..9ac562124654 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c @@ -89,7 +89,7 @@ static int idle_proc(void *cpup) cpu_set(cpu, cpu_online_map); default_idle(); - return(0); + return 0; } static struct task_struct *idle_thread(int cpu) @@ -97,8 +97,8 @@ static struct task_struct *idle_thread(int cpu) struct task_struct *new_task; unsigned char c; - current->thread.request.u.thread.proc = idle_proc; - current->thread.request.u.thread.arg = (void *) cpu; + current->thread.request.u.thread.proc = idle_proc; + current->thread.request.u.thread.arg = (void *) cpu; new_task = fork_idle(cpu); if(IS_ERR(new_task)) panic("copy_process failed in idle_thread, error = %ld", @@ -111,7 +111,7 @@ static struct task_struct *idle_thread(int cpu) CHOOSE_MODE(os_write_file_k(new_task->thread.mode.tt.switch_pipe[1], &c, sizeof(c)), ({ panic("skas mode doesn't support SMP"); })); - return(new_task); + return new_task; } void smp_prepare_cpus(unsigned int maxcpus) @@ -162,13 +162,13 @@ int __cpu_up(unsigned int cpu) cpu_set(cpu, smp_commenced_mask); while (!cpu_isset(cpu, cpu_online_map)) mb(); - return(0); + return 0; } int setup_profiling_timer(unsigned int multiplier) { printk(KERN_INFO "setup_profiling_timer\n"); - return(0); + return 0; } void smp_call_function_slave(int cpu); @@ -204,7 +204,7 @@ void IPI_handler(int cpu) int hard_smp_processor_id(void) { - return(pid_to_processor_id(os_getpid())); + return pid_to_processor_id(os_getpid()); } static DEFINE_SPINLOCK(call_lock); @@ -253,14 +253,3 @@ int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, } #endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ -- cgit v1.2.3-59-g8ed1b From a263672424e591067e42e1d8371e56927fe73af8 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:42 -0700 Subject: uml: remove debugging remnants I accidentally left the remnants of some debugging in an earlier patch. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/tlb.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 153dec13cf97..e201ccf0ec89 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -235,9 +235,7 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, unsigned long addr = start_addr, next; int ret = 0, last_op = ARRAY_SIZE(ops) - 1, op_index = -1; void *flush = NULL; - unsigned long long start_time, end_time; - start_time = os_nsecs(); ops[0].type = NONE; pgd = pgd_offset(mm, addr); do { @@ -254,7 +252,6 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, &op_index, force, mmu, &flush, do_ops); } while (pgd++, addr = next, ((addr != end_addr) && !ret)); - end_time = os_nsecs(); log_info("total flush time - %Ld nsecs\n", end_time - start_time); if(!ret) -- cgit v1.2.3-59-g8ed1b From a6ea4cceed18edebe1eb6001cb9e0f88cd741a6c Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:43 -0700 Subject: uml: rename os_{read_write}_file_k back to os_{read_write}_file Rename os_{read_write}_file_k back to os_{read_write}_file, delete the originals and their bogus infrastructure, and fix all the callers. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_kern.c | 4 ++-- arch/um/drivers/chan_user.c | 10 ++++---- arch/um/drivers/cow_sys.h | 2 +- arch/um/drivers/daemon_user.c | 4 ++-- arch/um/drivers/harddog_user.c | 4 ++-- arch/um/drivers/hostaudio_kern.c | 4 ++-- arch/um/drivers/net_user.c | 8 +++---- arch/um/drivers/port_kern.c | 2 +- arch/um/drivers/random.c | 2 +- arch/um/drivers/ubd_kern.c | 20 ++++++++-------- arch/um/include/os.h | 2 -- arch/um/kernel/initrd.c | 2 +- arch/um/kernel/ksyms.c | 2 -- arch/um/kernel/physmem.c | 4 ++-- arch/um/kernel/sigio.c | 2 +- arch/um/kernel/smp.c | 12 +++++----- arch/um/kernel/tt/process_kern.c | 6 ++--- arch/um/kernel/tt/ptproxy/proxy.c | 8 +++---- arch/um/kernel/tt/tracer.c | 2 +- arch/um/os-Linux/file.c | 50 --------------------------------------- arch/um/sys-i386/bugs.c | 4 ++-- arch/um/sys-i386/ldt.c | 2 +- 22 files changed, 51 insertions(+), 105 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 92e069e8253f..3aa351611763 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -98,7 +98,7 @@ int generic_read(int fd, char *c_out, void *unused) { int n; - n = os_read_file_k(fd, c_out, sizeof(*c_out)); + n = os_read_file(fd, c_out, sizeof(*c_out)); if(n == -EAGAIN) return 0; @@ -111,7 +111,7 @@ int generic_read(int fd, char *c_out, void *unused) int generic_write(int fd, const char *buf, int n, void *unused) { - return os_write_file_k(fd, buf, n); + return os_write_file(fd, buf, n); } int generic_window_size(int fd, void *unused, unsigned short *rows_out, diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index a15be1720e03..13f0bf852b2a 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -85,7 +85,7 @@ static int winch_thread(void *arg) pty_fd = data->pty_fd; pipe_fd = data->pipe_fd; - count = os_write_file_k(pipe_fd, &c, sizeof(c)); + count = os_write_file(pipe_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("winch_thread : failed to write synchronization " "byte, err = %d\n", -count); @@ -120,7 +120,7 @@ static int winch_thread(void *arg) * host - since they are not different kernel threads, we cannot use * kernel semaphores. We don't use SysV semaphores because they are * persistent. */ - count = os_read_file_k(pipe_fd, &c, sizeof(c)); + count = os_read_file(pipe_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("winch_thread : failed to read synchronization byte, " "err = %d\n", -count); @@ -130,7 +130,7 @@ static int winch_thread(void *arg) * are blocked.*/ sigsuspend(&sigs); - count = os_write_file_k(pipe_fd, &c, sizeof(c)); + count = os_write_file(pipe_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("winch_thread : write failed, err = %d\n", -count); @@ -162,7 +162,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) } *fd_out = fds[0]; - n = os_read_file_k(fds[0], &c, sizeof(c)); + n = os_read_file(fds[0], &c, sizeof(c)); if(n != sizeof(c)){ printk("winch_tramp : failed to read synchronization byte\n"); printk("read failed, err = %d\n", -n); @@ -195,7 +195,7 @@ void register_winch(int fd, struct tty_struct *tty) if(thread > 0){ register_winch_irq(thread_fd, fd, thread, tty); - count = os_write_file_k(thread_fd, &c, sizeof(c)); + count = os_write_file(thread_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("register_winch : failed to write " "synchronization byte, err = %d\n", diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index aa7bef9c38d9..15453845d2ba 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h @@ -35,7 +35,7 @@ static inline int cow_file_size(char *file, unsigned long long *size_out) static inline int cow_write_file(int fd, void *buf, int size) { - return os_write_file_k(fd, buf, size); + return os_write_file(fd, buf, size); } #endif diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index e1fd26c1b728..b869e3899683 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -94,7 +94,7 @@ static int connect_to_switch(struct daemon_data *pri) req.version = SWITCH_VERSION; req.type = REQ_NEW_CONTROL; req.sock = *local_addr; - n = os_write_file_k(pri->control, &req, sizeof(req)); + n = os_write_file(pri->control, &req, sizeof(req)); if(n != sizeof(req)){ printk("daemon_open : control setup request failed, err = %d\n", -n); @@ -102,7 +102,7 @@ static int connect_to_switch(struct daemon_data *pri) goto out_free; } - n = os_read_file_k(pri->control, sun, sizeof(*sun)); + n = os_read_file(pri->control, sun, sizeof(*sun)); if(n != sizeof(*sun)){ printk("daemon_open : read of data socket failed, err = %d\n", -n); diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c index 0fbb1615171e..5eeecf8917c3 100644 --- a/arch/um/drivers/harddog_user.c +++ b/arch/um/drivers/harddog_user.c @@ -79,7 +79,7 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) goto out_close_out; } - n = os_read_file_k(in_fds[0], &c, sizeof(c)); + n = os_read_file(in_fds[0], &c, sizeof(c)); if(n == 0){ printk("harddog_open - EOF on watchdog pipe\n"); helper_wait(pid); @@ -118,7 +118,7 @@ int ping_watchdog(int fd) int n; char c = '\n'; - n = os_write_file_k(fd, &c, sizeof(c)); + n = os_write_file(fd, &c, sizeof(c)); if(n != sizeof(c)){ printk("ping_watchdog - write failed, err = %d\n", -n); if(n < 0) diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c index bd6688ea96de..10e08a8c17c3 100644 --- a/arch/um/drivers/hostaudio_kern.c +++ b/arch/um/drivers/hostaudio_kern.c @@ -84,7 +84,7 @@ static ssize_t hostaudio_read(struct file *file, char __user *buffer, if(kbuf == NULL) return(-ENOMEM); - err = os_read_file_k(state->fd, kbuf, count); + err = os_read_file(state->fd, kbuf, count); if(err < 0) goto out; @@ -115,7 +115,7 @@ static ssize_t hostaudio_write(struct file *file, const char __user *buffer, if(copy_from_user(kbuf, buffer, count)) goto out; - err = os_write_file_k(state->fd, kbuf, count); + err = os_write_file(state->fd, kbuf, count); if(err < 0) goto out; *ppos += err; diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 8bc6688c4f0f..3503cff867c3 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -63,7 +63,7 @@ void read_output(int fd, char *output, int len) } *output = '\0'; - ret = os_read_file_k(fd, &remain, sizeof(remain)); + ret = os_read_file(fd, &remain, sizeof(remain)); if (ret != sizeof(remain)) { expected = sizeof(remain); @@ -73,7 +73,7 @@ void read_output(int fd, char *output, int len) while(remain != 0){ expected = (remain < len) ? remain : len; - ret = os_read_file_k(fd, output, expected); + ret = os_read_file(fd, output, expected); if (ret != expected) { str = "data"; goto err; @@ -94,7 +94,7 @@ int net_read(int fd, void *buf, int len) { int n; - n = os_read_file_k(fd, buf, len); + n = os_read_file(fd, buf, len); if(n == -EAGAIN) return 0; @@ -122,7 +122,7 @@ int net_write(int fd, void *buf, int len) { int n; - n = os_write_file_k(fd, buf, len); + n = os_write_file(fd, buf, len); if(n == -EAGAIN) return 0; diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index 75bb40126c2e..1c8efd95c421 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -113,7 +113,7 @@ static int port_accept(struct port_list *port) } if(atomic_read(&port->wait_count) == 0){ - os_write_file_k(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG)); + os_write_file(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG)); printk("No one waiting for port\n"); } list_add(&conn->list, &port->pending); diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index 94838f4c1645..e942e836f995 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c @@ -44,7 +44,7 @@ static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size, int n, ret = 0, have_data; while(size){ - n = os_read_file_k(random_fd, &data, sizeof(data)); + n = os_read_file(random_fd, &data, sizeof(data)); if(n > 0){ have_data = n; while (have_data && size) { diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 614fe25a31bd..70509ddaac03 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -511,8 +511,8 @@ static void ubd_handler(void) int n; while(1){ - n = os_read_file_k(thread_fd, &req, - sizeof(struct io_thread_req *)); + n = os_read_file(thread_fd, &req, + sizeof(struct io_thread_req *)); if(n != sizeof(req)){ if(n == -EAGAIN) break; @@ -1112,8 +1112,8 @@ static void do_ubd_request(request_queue_t *q) (unsigned long long) req->sector << 9, sg->offset, sg->length, sg->page); - n = os_write_file_k(thread_fd, &io_req, - sizeof(struct io_thread_req *)); + n = os_write_file(thread_fd, &io_req, + sizeof(struct io_thread_req *)); if(n != sizeof(struct io_thread_req *)){ if(n != -EAGAIN) printk("write to io thread failed, " @@ -1366,8 +1366,8 @@ static int update_bitmap(struct io_thread_req *req) return 1; } - n = os_write_file_k(req->fds[1], &req->bitmap_words, - sizeof(req->bitmap_words)); + n = os_write_file(req->fds[1], &req->bitmap_words, + sizeof(req->bitmap_words)); if(n != sizeof(req->bitmap_words)){ printk("do_io - bitmap update failed, err = %d fd = %d\n", -n, req->fds[1]); @@ -1411,7 +1411,7 @@ void do_io(struct io_thread_req *req) do { buf = &buf[n]; len -= n; - n = os_read_file_k(req->fds[bit], buf, len); + n = os_read_file(req->fds[bit], buf, len); if (n < 0) { printk("do_io - read failed, err = %d " "fd = %d\n", -n, req->fds[bit]); @@ -1421,7 +1421,7 @@ void do_io(struct io_thread_req *req) } while((n < len) && (n != 0)); if (n < len) memset(&buf[n], 0, len - n); } else { - n = os_write_file_k(req->fds[bit], buf, len); + n = os_write_file(req->fds[bit], buf, len); if(n != len){ printk("do_io - write failed err = %d " "fd = %d\n", -n, req->fds[bit]); @@ -1451,7 +1451,7 @@ int io_thread(void *arg) ignore_sigwinch_sig(); while(1){ - n = os_read_file_k(kernel_fd, &req, + n = os_read_file(kernel_fd, &req, sizeof(struct io_thread_req *)); if(n != sizeof(struct io_thread_req *)){ if(n < 0) @@ -1465,7 +1465,7 @@ int io_thread(void *arg) } io_count++; do_io(req); - n = os_write_file_k(kernel_fd, &req, + n = os_write_file(kernel_fd, &req, sizeof(struct io_thread_req *)); if(n != sizeof(struct io_thread_req *)) printk("io_thread - write failed, fd = %d, err = %d\n", diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 901804db3c35..d66380908703 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -144,9 +144,7 @@ extern int os_mode_fd(int fd, int mode); extern int os_seek_file(int fd, __u64 offset); extern int os_open_file(char *file, struct openflags flags, int mode); extern int os_read_file(int fd, void *buf, int len); -extern int os_read_file_k(int fd, void *buf, int len); extern int os_write_file(int fd, const void *buf, int count); -extern int os_write_file_k(int fd, const void *buf, int len); extern int os_file_size(char *file, unsigned long long *size_out); extern int os_file_modtime(char *file, unsigned long *modtime); extern int os_pipe(int *fd, int stream, int close_on_exec); diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index cff73faae991..16dc43e9d940 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c @@ -63,7 +63,7 @@ int load_initrd(char *filename, void *buf, int size) printk("Opening '%s' failed - err = %d\n", filename, -fd); return -1; } - n = os_read_file_k(fd, buf, size); + n = os_read_file(fd, buf, size); if(n != size){ printk("Read of %d bytes from '%s' failed, err = %d\n", size, filename, -n); diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 7c158448b9fd..7b3e53fb8070 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c @@ -62,9 +62,7 @@ EXPORT_SYMBOL(os_get_exec_close); EXPORT_SYMBOL(os_set_exec_close); EXPORT_SYMBOL(os_getpid); EXPORT_SYMBOL(os_open_file); -EXPORT_SYMBOL(os_read_file_k); EXPORT_SYMBOL(os_read_file); -EXPORT_SYMBOL(os_write_file_k); EXPORT_SYMBOL(os_write_file); EXPORT_SYMBOL(os_seek_file); EXPORT_SYMBOL(os_lock_file); diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index 77021a627da6..df1ad3ba130c 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -211,7 +211,7 @@ void physmem_forget_descriptor(int fd) panic("physmem_forget_descriptor - failed to seek " "to %lld in fd %d, error = %d\n", offset, fd, -err); - err = os_read_file_k(fd, addr, PAGE_SIZE); + err = os_read_file(fd, addr, PAGE_SIZE); if(err < 0) panic("physmem_forget_descriptor - failed to read " "from fd %d to 0x%p, error = %d\n", @@ -341,7 +341,7 @@ void setup_physmem(unsigned long start, unsigned long reserve_end, * from physmem_fd, so it needs to be written out there. */ os_seek_file(physmem_fd, __pa(&__syscall_stub_start)); - os_write_file_k(physmem_fd, &__syscall_stub_start, PAGE_SIZE); + os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE); bootmap_size = init_bootmem(pfn, pfn + delta); free_bootmem(__pa(reserve_end) + bootmap_size, diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c index f756e78085e4..89f9866a1354 100644 --- a/arch/um/kernel/sigio.c +++ b/arch/um/kernel/sigio.c @@ -21,7 +21,7 @@ static irqreturn_t sigio_interrupt(int irq, void *data) { char c; - os_read_file_k(sigio_irq_fd, &c, sizeof(c)); + os_read_file(sigio_irq_fd, &c, sizeof(c)); reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ); return IRQ_HANDLED; } diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index 9ac562124654..e6a7778006ad 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c @@ -47,7 +47,7 @@ struct task_struct *idle_threads[NR_CPUS]; void smp_send_reschedule(int cpu) { - os_write_file_k(cpu_data[cpu].ipi_pipe[1], "R", 1); + os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1); num_reschedules_sent++; } @@ -59,7 +59,7 @@ void smp_send_stop(void) for(i = 0; i < num_online_cpus(); i++){ if(i == current_thread->cpu) continue; - os_write_file_k(cpu_data[i].ipi_pipe[1], "S", 1); + os_write_file(cpu_data[i].ipi_pipe[1], "S", 1); } printk("done\n"); } @@ -108,8 +108,8 @@ static struct task_struct *idle_thread(int cpu) { .pid = new_task->thread.mode.tt.extern_pid, .task = new_task } ); idle_threads[cpu] = new_task; - CHOOSE_MODE(os_write_file_k(new_task->thread.mode.tt.switch_pipe[1], &c, - sizeof(c)), + CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, + sizeof(c)), ({ panic("skas mode doesn't support SMP"); })); return new_task; } @@ -179,7 +179,7 @@ void IPI_handler(int cpu) int fd; fd = cpu_data[cpu].ipi_pipe[0]; - while (os_read_file_k(fd, &c, 1) == 1) { + while (os_read_file(fd, &c, 1) == 1) { switch (c) { case 'C': smp_call_function_slave(cpu); @@ -239,7 +239,7 @@ int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, info = _info; for_each_online_cpu(i) - os_write_file_k(cpu_data[i].ipi_pipe[1], "C", 1); + os_write_file(cpu_data[i].ipi_pipe[1], "C", 1); while (atomic_read(&scf_started) != cpus) barrier(); diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index c81bd2074930..c631303cb800 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c @@ -57,14 +57,14 @@ void switch_to_tt(void *prev, void *next) * nor the value in "to" (since it was the task which stole us the CPU, * which we don't care about). */ - err = os_write_file_k(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); + err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); if(err != sizeof(c)) panic("write of switch_pipe failed, err = %d", -err); if(from->thread.mode.tt.switch_pipe[0] == -1) os_kill_process(os_getpid(), 0); - err = os_read_file_k(from->thread.mode.tt.switch_pipe[0], &c, + err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); if(err != sizeof(c)) panic("read of switch_pipe failed, errno = %d", -err); @@ -114,7 +114,7 @@ void suspend_new_thread(int fd) char c; os_stop_process(os_getpid()); - err = os_read_file_k(fd, &c, sizeof(c)); + err = os_read_file(fd, &c, sizeof(c)); if(err != sizeof(c)) panic("read failed in suspend_new_thread, err = %d", -err); } diff --git a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c index 007beb6b7c00..420c23f311f3 100644 --- a/arch/um/kernel/tt/ptproxy/proxy.c +++ b/arch/um/kernel/tt/ptproxy/proxy.c @@ -338,14 +338,14 @@ int start_debugger(char *prog, int startup, int stop, int *fd_out) "err = %d\n", -fd); exit(1); } - os_write_file_k(fd, gdb_init_string, - sizeof(gdb_init_string) - 1); + os_write_file(fd, gdb_init_string, + sizeof(gdb_init_string) - 1); if(startup){ if(stop){ - os_write_file_k(fd, "b start_kernel\n", + os_write_file(fd, "b start_kernel\n", strlen("b start_kernel\n")); } - os_write_file_k(fd, "c\n", strlen("c\n")); + os_write_file(fd, "c\n", strlen("c\n")); } if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ printk("start_debugger : PTRACE_TRACEME failed, " diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c index 264da6c5a5c3..c23588393f6e 100644 --- a/arch/um/kernel/tt/tracer.c +++ b/arch/um/kernel/tt/tracer.c @@ -44,7 +44,7 @@ static void tracer_winch_handler(int sig) int n; char c = 1; - n = os_write_file_k(tracer_winch[1], &c, sizeof(c)); + n = os_write_file(tracer_winch[1], &c, sizeof(c)); if(n != sizeof(c)) printk("tracer_winch_handler - write failed, err = %d\n", -n); } diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 5e9b8dcf34d4..6f92f732d253 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -290,51 +290,7 @@ int os_seek_file(int fd, __u64 offset) return 0; } -static int fault_buffer(void *start, int len, - int (*copy_proc)(void *addr, void *buf, int len)) -{ - int page = getpagesize(), i; - char c; - - for(i = 0; i < len; i += page){ - if((*copy_proc)(start + i, &c, sizeof(c))) - return -EFAULT; - } - if((len % page) != 0){ - if((*copy_proc)(start + len - 1, &c, sizeof(c))) - return -EFAULT; - } - return 0; -} - -static int file_io(int fd, void *buf, int len, - int (*io_proc)(int fd, void *buf, int len), - int (*copy_user_proc)(void *addr, void *buf, int len)) -{ - int n, err; - - do { - n = (*io_proc)(fd, buf, len); - if((n < 0) && (errno == EFAULT)){ - err = fault_buffer(buf, len, copy_user_proc); - if(err) - return err; - n = (*io_proc)(fd, buf, len); - } - } while((n < 0) && (errno == EINTR)); - - if(n < 0) - return -errno; - return n; -} - int os_read_file(int fd, void *buf, int len) -{ - return file_io(fd, buf, len, (int (*)(int, void *, int)) read, - copy_from_user_proc); -} - -int os_read_file_k(int fd, void *buf, int len) { int n = read(fd, buf, len); @@ -344,12 +300,6 @@ int os_read_file_k(int fd, void *buf, int len) } int os_write_file(int fd, const void *buf, int len) -{ - return file_io(fd, (void *) buf, len, - (int (*)(int, void *, int)) write, copy_to_user_proc); -} - -int os_write_file_k(int fd, const void *buf, int len) { int n = write(fd, (void *) buf, len); diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c index f5dfe49c8442..0393e44813e7 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/um/sys-i386/bugs.c @@ -28,7 +28,7 @@ static char token(int fd, char *buf, int len, char stop) ptr = buf; end = &buf[len]; do { - n = os_read_file_k(fd, ptr, sizeof(*ptr)); + n = os_read_file(fd, ptr, sizeof(*ptr)); c = *ptr++; if(n != sizeof(*ptr)){ if(n == 0) @@ -67,7 +67,7 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) return 1; do { - n = os_read_file_k(fd, &c, sizeof(c)); + n = os_read_file(fd, &c, sizeof(c)); if(n != sizeof(c)){ printk("Failed to find newline in " "/proc/cpuinfo, err = %d\n", -n); diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c index d031a13bd969..a939a7ef0227 100644 --- a/arch/um/sys-i386/ldt.c +++ b/arch/um/sys-i386/ldt.c @@ -517,7 +517,7 @@ long init_new_ldt(struct mmu_context_skas * new_mm, .u = { .copy_segments = from_mm->id.u.mm_fd } } ); - i = os_write_file_k(new_mm->id.u.mm_fd, ©, sizeof(copy)); + i = os_write_file(new_mm->id.u.mm_fd, ©, sizeof(copy)); if(i != sizeof(copy)) printk("new_mm : /proc/mm copy_segments failed, " "err = %d\n", -i); -- cgit v1.2.3-59-g8ed1b From 8603ec81487a5fefbc29611ff0d635b33b6da990 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:44 -0700 Subject: uml: aIO deadlock avoidance Allow deadlocks to be avoided in the AIO code by setting the pipe to the I/O thread non-blocking. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/aio.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index 5d258eb4f506..9bf944f6a1db 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -221,6 +221,11 @@ static int init_aio_24(void) aio_req_fd_w = fds[0]; aio_req_fd_r = fds[1]; + + err = os_set_fd_block(aio_req_fd_w, 0); + if(err) + goto out_close_pipe; + err = run_helper_thread(not_aio_thread, NULL, CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0); if(err < 0) -- cgit v1.2.3-59-g8ed1b From 64f60841c096594b8073e408cd9b40d7d08dcfdd Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:45 -0700 Subject: uml: speed page fault path Give the page fault code a specialized path. There is only one page to look at, so there's no point in going into the general page table walking code. There's only going to be one host operation, so there are no opportunities for merging. So, we go straight to the pte we want, figure out what needs doing, and do it. While I was in here, I fixed the wart where the address passed to unmap was a void *, but an unsigned long to map and protect. This gives me just under 10% on a kernel build. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/os.h | 2 +- arch/um/include/skas/mode_kern_skas.h | 2 ++ arch/um/kernel/skas/tlb.c | 66 +++++++++++++++++++++++++++++++++-- arch/um/kernel/tlb.c | 4 ++- arch/um/os-Linux/skas/mem.c | 4 +-- 5 files changed, 72 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/um/include/os.h b/arch/um/include/os.h index d66380908703..e11bdcd8afc2 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -302,7 +302,7 @@ extern long syscall_stub_data(struct mm_id * mm_idp, extern int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int r, int w, int x, int phys_fd, unsigned long long offset, int done, void **data); -extern int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, +extern int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, int done, void **data); extern int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, int r, int w, int x, int done, diff --git a/arch/um/include/skas/mode_kern_skas.h b/arch/um/include/skas/mode_kern_skas.h index 9cd9c6ec9a63..8ee6285dfacc 100644 --- a/arch/um/include/skas/mode_kern_skas.h +++ b/arch/um/include/skas/mode_kern_skas.h @@ -33,6 +33,8 @@ extern unsigned long set_task_sizes_skas(unsigned long *task_size_out); extern int start_uml_skas(void); extern int external_pid_skas(struct task_struct *task); extern int thread_pid_skas(struct task_struct *task); +extern void flush_tlb_page_skas(struct vm_area_struct *vma, + unsigned long address); #define kmem_end_skas (host_task_size - 1024 * 1024) diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c index 304a5b0695ab..c43901aa9368 100644 --- a/arch/um/kernel/skas/tlb.c +++ b/arch/um/kernel/skas/tlb.c @@ -32,8 +32,7 @@ static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last, op->u.mmap.offset, finished, flush); break; case MUNMAP: - ret = unmap(&mmu->skas.id, - (void *) op->u.munmap.addr, + ret = unmap(&mmu->skas.id, op->u.munmap.addr, op->u.munmap.len, finished, flush); break; case MPROTECT: @@ -94,3 +93,66 @@ void force_flush_all_skas(void) unsigned long end = proc_mm ? task_size : CONFIG_STUB_START; fix_range(current->mm, 0, end, 1); } + +void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address) +{ + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + struct mm_struct *mm = vma->vm_mm; + void *flush = NULL; + int r, w, x, err = 0; + struct mm_id *mm_id; + + pgd = pgd_offset(vma->vm_mm, address); + if(!pgd_present(*pgd)) + goto kill; + + pud = pud_offset(pgd, address); + if(!pud_present(*pud)) + goto kill; + + pmd = pmd_offset(pud, address); + if(!pmd_present(*pmd)) + goto kill; + + pte = pte_offset_kernel(pmd, address); + + r = pte_read(*pte); + w = pte_write(*pte); + x = pte_exec(*pte); + if (!pte_young(*pte)) { + r = 0; + w = 0; + } else if (!pte_dirty(*pte)) { + w = 0; + } + + mm_id = &mm->context.skas.id; + if(pte_newpage(*pte)){ + if(pte_present(*pte)){ + unsigned long long offset; + int fd; + + fd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset); + err = map(mm_id, address, PAGE_SIZE, r, w, x, fd, + offset, 1, &flush); + } + else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush); + } + else if(pte_newprot(*pte)) + err = protect(mm_id, address, PAGE_SIZE, r, w, x, 1, &flush); + + if(err) + goto kill; + + *pte = pte_mkuptodate(*pte); + + return; + +kill: + printk("Failed to flush page for address 0x%lx\n", address); + force_sig(SIGKILL, current); +} + diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index e201ccf0ec89..00de86efccaa 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -381,7 +381,9 @@ pte_t *addr_pte(struct task_struct *task, unsigned long addr) void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) { address &= PAGE_MASK; - flush_tlb_range(vma, address, address + PAGE_SIZE); + + CHOOSE_MODE(flush_tlb_range(vma, address, address + PAGE_SIZE), + flush_tlb_page_skas(vma, address)); } void flush_tlb_all(void) diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index 6cdfda807b65..af0790719b77 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -219,8 +219,8 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, return ret; } -int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done, - void **data) +int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, + int done, void **data) { int ret; -- cgit v1.2.3-59-g8ed1b From 3ec704e6660aa58505110a50102e57cdb9daa044 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:47 -0700 Subject: uml: eliminate a piece of debugging code I missed removing another piece of debugging in an earlier patch. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/tlb.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 00de86efccaa..4a39d50d2d62 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -252,7 +252,6 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, &op_index, force, mmu, &flush, do_ops); } while (pgd++, addr = next, ((addr != end_addr) && !ret)); - log_info("total flush time - %Ld nsecs\n", end_time - start_time); if(!ret) ret = (*do_ops)(mmu, ops, op_index, 1, &flush); -- cgit v1.2.3-59-g8ed1b From 16dd07bc6404c8da0bdfeb7a5cde4e4a63991c00 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:48 -0700 Subject: uml: more page fault path trimming More trimming of the page fault path. Permissions are passed around in a single int rather than one bit per int. The permission values are copied from libc so that they can be passed to mmap and mprotect without any further conversion. The register sets used by do_syscall_stub and copy_context_skas0 are initialized once, at boot time, rather than once per call. wait_stub_done checks whether it is getting the signals it expects by comparing the wait status to a mask containing bits for the signals of interest rather than comparing individually to the signal numbers. It also has one check for a wait failure instead of two. The caller is expected to do the initial continue of the stub. This gets rid of an argument and some logic. The fname argument is gone, as that can be had from a stack trace. user_signal() is collapsed into userspace() as it is basically one or two lines of code afterwards. The physical memory remapping stuff is gone, as it is unused. flush_tlb_page is inlined. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/os.h | 6 +- arch/um/include/tlb.h | 8 +- arch/um/kernel/physmem.c | 228 +------------------------------------- arch/um/kernel/skas/tlb.c | 21 ++-- arch/um/kernel/tlb.c | 42 +++---- arch/um/os-Linux/skas/mem.c | 51 +++++---- arch/um/os-Linux/skas/process.c | 122 ++++++++++++-------- arch/um/os-Linux/skas/trap.c | 17 --- arch/um/sys-i386/user-offsets.c | 9 +- arch/um/sys-x86_64/user-offsets.c | 5 + include/asm-um/page.h | 3 - include/asm-um/tlbflush.h | 24 ++-- 12 files changed, 158 insertions(+), 378 deletions(-) (limited to 'arch') diff --git a/arch/um/include/os.h b/arch/um/include/os.h index e11bdcd8afc2..688d181b5f8a 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -300,13 +300,12 @@ extern long syscall_stub_data(struct mm_id * mm_idp, unsigned long *data, int data_count, void **addr, void **stub_addr); extern int map(struct mm_id * mm_idp, unsigned long virt, - unsigned long len, int r, int w, int x, int phys_fd, + unsigned long len, int prot, int phys_fd, unsigned long long offset, int done, void **data); extern int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, int done, void **data); extern int protect(struct mm_id * mm_idp, unsigned long addr, - unsigned long len, int r, int w, int x, int done, - void **data); + unsigned long len, unsigned int prot, int done, void **data); /* skas/process.c */ extern int is_skas_winch(int pid, int fd, void *data); @@ -342,7 +341,6 @@ extern void maybe_sigio_broken(int fd, int read); /* skas/trap */ extern void sig_handler_common_skas(int sig, void *sc_ptr); -extern void user_signal(int sig, union uml_pt_regs *regs, int pid); /* sys-x86_64/prctl.c */ extern int os_arch_prctl(int pid, int code, unsigned long *addr); diff --git a/arch/um/include/tlb.h b/arch/um/include/tlb.h index 8efc1e0f1b84..bcd1a4afb842 100644 --- a/arch/um/include/tlb.h +++ b/arch/um/include/tlb.h @@ -14,9 +14,7 @@ struct host_vm_op { struct { unsigned long addr; unsigned long len; - unsigned int r:1; - unsigned int w:1; - unsigned int x:1; + unsigned int prot; int fd; __u64 offset; } mmap; @@ -27,9 +25,7 @@ struct host_vm_op { struct { unsigned long addr; unsigned long len; - unsigned int r:1; - unsigned int w:1; - unsigned int x:1; + unsigned int prot; } mprotect; } u; }; diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index df1ad3ba130c..3ba6e4c841da 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -21,229 +21,8 @@ #include "kern.h" #include "init.h" -struct phys_desc { - struct rb_node rb; - int fd; - __u64 offset; - void *virt; - unsigned long phys; - struct list_head list; -}; - -static struct rb_root phys_mappings = RB_ROOT; - -static struct rb_node **find_rb(void *virt) -{ - struct rb_node **n = &phys_mappings.rb_node; - struct phys_desc *d; - - while(*n != NULL){ - d = rb_entry(*n, struct phys_desc, rb); - if(d->virt == virt) - return n; - - if(d->virt > virt) - n = &(*n)->rb_left; - else - n = &(*n)->rb_right; - } - - return n; -} - -static struct phys_desc *find_phys_mapping(void *virt) -{ - struct rb_node **n = find_rb(virt); - - if(*n == NULL) - return NULL; - - return rb_entry(*n, struct phys_desc, rb); -} - -static void insert_phys_mapping(struct phys_desc *desc) -{ - struct rb_node **n = find_rb(desc->virt); - - if(*n != NULL) - panic("Physical remapping for %p already present", - desc->virt); - - rb_link_node(&desc->rb, rb_parent(*n), n); - rb_insert_color(&desc->rb, &phys_mappings); -} - -LIST_HEAD(descriptor_mappings); - -struct desc_mapping { - int fd; - struct list_head list; - struct list_head pages; -}; - -static struct desc_mapping *find_mapping(int fd) -{ - struct desc_mapping *desc; - struct list_head *ele; - - list_for_each(ele, &descriptor_mappings){ - desc = list_entry(ele, struct desc_mapping, list); - if(desc->fd == fd) - return desc; - } - - return NULL; -} - -static struct desc_mapping *descriptor_mapping(int fd) -{ - struct desc_mapping *desc; - - desc = find_mapping(fd); - if(desc != NULL) - return desc; - - desc = kmalloc(sizeof(*desc), GFP_ATOMIC); - if(desc == NULL) - return NULL; - - *desc = ((struct desc_mapping) - { .fd = fd, - .list = LIST_HEAD_INIT(desc->list), - .pages = LIST_HEAD_INIT(desc->pages) }); - list_add(&desc->list, &descriptor_mappings); - - return desc; -} - -int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w) -{ - struct desc_mapping *fd_maps; - struct phys_desc *desc; - unsigned long phys; - int err; - - fd_maps = descriptor_mapping(fd); - if(fd_maps == NULL) - return -ENOMEM; - - phys = __pa(virt); - desc = find_phys_mapping(virt); - if(desc != NULL) - panic("Address 0x%p is already substituted\n", virt); - - err = -ENOMEM; - desc = kmalloc(sizeof(*desc), GFP_ATOMIC); - if(desc == NULL) - goto out; - - *desc = ((struct phys_desc) - { .fd = fd, - .offset = offset, - .virt = virt, - .phys = __pa(virt), - .list = LIST_HEAD_INIT(desc->list) }); - insert_phys_mapping(desc); - - list_add(&desc->list, &fd_maps->pages); - - virt = (void *) ((unsigned long) virt & PAGE_MASK); - err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0); - if(!err) - goto out; - - rb_erase(&desc->rb, &phys_mappings); - kfree(desc); - out: - return err; -} - static int physmem_fd = -1; -static void remove_mapping(struct phys_desc *desc) -{ - void *virt = desc->virt; - int err; - - rb_erase(&desc->rb, &phys_mappings); - list_del(&desc->list); - kfree(desc); - - err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0); - if(err) - panic("Failed to unmap block device page from physical memory, " - "errno = %d", -err); -} - -int physmem_remove_mapping(void *virt) -{ - struct phys_desc *desc; - - virt = (void *) ((unsigned long) virt & PAGE_MASK); - desc = find_phys_mapping(virt); - if(desc == NULL) - return 0; - - remove_mapping(desc); - return 1; -} - -void physmem_forget_descriptor(int fd) -{ - struct desc_mapping *desc; - struct phys_desc *page; - struct list_head *ele, *next; - __u64 offset; - void *addr; - int err; - - desc = find_mapping(fd); - if(desc == NULL) - return; - - list_for_each_safe(ele, next, &desc->pages){ - page = list_entry(ele, struct phys_desc, list); - offset = page->offset; - addr = page->virt; - remove_mapping(page); - err = os_seek_file(fd, offset); - if(err) - panic("physmem_forget_descriptor - failed to seek " - "to %lld in fd %d, error = %d\n", - offset, fd, -err); - err = os_read_file(fd, addr, PAGE_SIZE); - if(err < 0) - panic("physmem_forget_descriptor - failed to read " - "from fd %d to 0x%p, error = %d\n", - fd, addr, -err); - } - - list_del(&desc->list); - kfree(desc); -} - -EXPORT_SYMBOL(physmem_forget_descriptor); -EXPORT_SYMBOL(physmem_remove_mapping); -EXPORT_SYMBOL(physmem_subst_mapping); - -void arch_free_page(struct page *page, int order) -{ - void *virt; - int i; - - for(i = 0; i < (1 << order); i++){ - virt = __va(page_to_phys(page + i)); - physmem_remove_mapping(virt); - } -} - -int is_remapped(void *virt) -{ - struct phys_desc *desc = find_phys_mapping(virt); - - return desc != NULL; -} - /* Changed during early boot */ unsigned long high_physmem; @@ -350,14 +129,9 @@ void setup_physmem(unsigned long start, unsigned long reserve_end, int phys_mapping(unsigned long phys, __u64 *offset_out) { - struct phys_desc *desc = find_phys_mapping(__va(phys & PAGE_MASK)); int fd = -1; - if(desc != NULL){ - fd = desc->fd; - *offset_out = desc->offset; - } - else if(phys < physmem_size){ + if(phys < physmem_size){ fd = physmem_fd; *offset_out = phys; } diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c index c43901aa9368..b3d722ddde31 100644 --- a/arch/um/kernel/skas/tlb.c +++ b/arch/um/kernel/skas/tlb.c @@ -27,9 +27,9 @@ static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last, switch(op->type){ case MMAP: ret = map(&mmu->skas.id, op->u.mmap.addr, - op->u.mmap.len, op->u.mmap.r, op->u.mmap.w, - op->u.mmap.x, op->u.mmap.fd, - op->u.mmap.offset, finished, flush); + op->u.mmap.len, op->u.mmap.prot, + op->u.mmap.fd, op->u.mmap.offset, finished, + flush); break; case MUNMAP: ret = unmap(&mmu->skas.id, op->u.munmap.addr, @@ -37,8 +37,7 @@ static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last, break; case MPROTECT: ret = protect(&mmu->skas.id, op->u.mprotect.addr, - op->u.mprotect.len, op->u.mprotect.r, - op->u.mprotect.w, op->u.mprotect.x, + op->u.mprotect.len, op->u.mprotect.prot, finished, flush); break; default: @@ -102,10 +101,10 @@ void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address) pte_t *pte; struct mm_struct *mm = vma->vm_mm; void *flush = NULL; - int r, w, x, err = 0; + int r, w, x, prot, err = 0; struct mm_id *mm_id; - pgd = pgd_offset(vma->vm_mm, address); + pgd = pgd_offset(mm, address); if(!pgd_present(*pgd)) goto kill; @@ -130,19 +129,21 @@ void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address) } mm_id = &mm->context.skas.id; + prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | + (x ? UM_PROT_EXEC : 0)); if(pte_newpage(*pte)){ if(pte_present(*pte)){ unsigned long long offset; int fd; fd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset); - err = map(mm_id, address, PAGE_SIZE, r, w, x, fd, - offset, 1, &flush); + err = map(mm_id, address, PAGE_SIZE, prot, fd, offset, + 1, &flush); } else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush); } else if(pte_newprot(*pte)) - err = protect(mm_id, address, PAGE_SIZE, r, w, x, 1, &flush); + err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush); if(err) goto kill; diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 4a39d50d2d62..8a8d52851443 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -17,7 +17,7 @@ #include "os.h" static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, - int r, int w, int x, struct host_vm_op *ops, int *index, + unsigned int prot, struct host_vm_op *ops, int *index, int last_filled, union mm_context *mmu, void **flush, int (*do_ops)(union mm_context *, struct host_vm_op *, int, int, void **)) @@ -31,8 +31,7 @@ static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, last = &ops[*index]; if((last->type == MMAP) && (last->u.mmap.addr + last->u.mmap.len == virt) && - (last->u.mmap.r == r) && (last->u.mmap.w == w) && - (last->u.mmap.x == x) && (last->u.mmap.fd == fd) && + (last->u.mmap.prot == prot) && (last->u.mmap.fd == fd) && (last->u.mmap.offset + last->u.mmap.len == offset)){ last->u.mmap.len += len; return 0; @@ -48,9 +47,7 @@ static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, .u = { .mmap = { .addr = virt, .len = len, - .r = r, - .w = w, - .x = x, + .prot = prot, .fd = fd, .offset = offset } } }); @@ -87,8 +84,8 @@ static int add_munmap(unsigned long addr, unsigned long len, return ret; } -static int add_mprotect(unsigned long addr, unsigned long len, int r, int w, - int x, struct host_vm_op *ops, int *index, +static int add_mprotect(unsigned long addr, unsigned long len, + unsigned int prot, struct host_vm_op *ops, int *index, int last_filled, union mm_context *mmu, void **flush, int (*do_ops)(union mm_context *, struct host_vm_op *, int, int, void **)) @@ -100,8 +97,7 @@ static int add_mprotect(unsigned long addr, unsigned long len, int r, int w, last = &ops[*index]; if((last->type == MPROTECT) && (last->u.mprotect.addr + last->u.mprotect.len == addr) && - (last->u.mprotect.r == r) && (last->u.mprotect.w == w) && - (last->u.mprotect.x == x)){ + (last->u.mprotect.prot == prot)){ last->u.mprotect.len += len; return 0; } @@ -116,9 +112,7 @@ static int add_mprotect(unsigned long addr, unsigned long len, int r, int w, .u = { .mprotect = { .addr = addr, .len = len, - .r = r, - .w = w, - .x = x } } }); + .prot = prot } } }); return ret; } @@ -133,7 +127,7 @@ static inline int update_pte_range(pmd_t *pmd, unsigned long addr, void **)) { pte_t *pte; - int r, w, x, ret = 0; + int r, w, x, prot, ret = 0; pte = pte_offset_kernel(pmd, addr); do { @@ -146,19 +140,19 @@ static inline int update_pte_range(pmd_t *pmd, unsigned long addr, } else if (!pte_dirty(*pte)) { w = 0; } + prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | + (x ? UM_PROT_EXEC : 0)); if(force || pte_newpage(*pte)){ if(pte_present(*pte)) ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK, - PAGE_SIZE, r, w, x, ops, - op_index, last_op, mmu, flush, - do_ops); + PAGE_SIZE, prot, ops, op_index, + last_op, mmu, flush, do_ops); else ret = add_munmap(addr, PAGE_SIZE, ops, op_index, last_op, mmu, flush, do_ops); } else if(pte_newprot(*pte)) - ret = add_mprotect(addr, PAGE_SIZE, r, w, x, ops, - op_index, last_op, mmu, flush, - do_ops); + ret = add_mprotect(addr, PAGE_SIZE, prot, ops, op_index, + last_op, mmu, flush, do_ops); *pte = pte_mkuptodate(*pte); } while (pte++, addr += PAGE_SIZE, ((addr != end) && !ret)); return ret; @@ -377,14 +371,6 @@ pte_t *addr_pte(struct task_struct *task, unsigned long addr) return(pte_offset_map(pmd, addr)); } -void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) -{ - address &= PAGE_MASK; - - CHOOSE_MODE(flush_tlb_range(vma, address, address + PAGE_SIZE), - flush_tlb_page_skas(vma, address)); -} - void flush_tlb_all(void) { flush_tlb_mm(current->mm); diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index af0790719b77..8e490fff3d47 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -24,10 +24,11 @@ #include "uml-config.h" #include "sysdep/ptrace.h" #include "sysdep/stub.h" +#include "init.h" extern unsigned long batch_syscall_stub, __syscall_stub_start; -extern void wait_stub_done(int pid, int sig, char * fname); +extern void wait_stub_done(int pid); static inline unsigned long *check_init_stack(struct mm_id * mm_idp, unsigned long *stack) @@ -39,6 +40,19 @@ static inline unsigned long *check_init_stack(struct mm_id * mm_idp, return stack; } +static unsigned long syscall_regs[MAX_REG_NR]; + +static int __init init_syscall_regs(void) +{ + get_safe_registers(syscall_regs, NULL); + syscall_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + + ((unsigned long) &batch_syscall_stub - + (unsigned long) &__syscall_stub_start); + return 0; +} + +__initcall(init_syscall_regs); + extern int proc_mm; int single_count = 0; @@ -47,12 +61,11 @@ int multi_op_count = 0; static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) { - unsigned long regs[MAX_REG_NR]; int n, i; long ret, offset; unsigned long * data; unsigned long * syscall; - int pid = mm_idp->u.pid; + int err, pid = mm_idp->u.pid; if(proc_mm) #warning Need to look up userspace_pid by cpu @@ -60,21 +73,21 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) multi_count++; - get_safe_registers(regs, NULL); - regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + - ((unsigned long) &batch_syscall_stub - - (unsigned long) &__syscall_stub_start); - - n = ptrace_setregs(pid, regs); + n = ptrace_setregs(pid, syscall_regs); if(n < 0){ printk("Registers - \n"); for(i = 0; i < MAX_REG_NR; i++) - printk("\t%d\t0x%lx\n", i, regs[i]); + printk("\t%d\t0x%lx\n", i, syscall_regs[i]); panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n", -n); } - wait_stub_done(pid, 0, "do_syscall_stub"); + err = ptrace(PTRACE_CONT, pid, 0, 0); + if(err) + panic("Failed to continue stub, pid = %d, errno = %d\n", pid, + errno); + + wait_stub_done(pid); /* When the stub stops, we find the following values on the * beginning of the stack: @@ -176,14 +189,10 @@ long syscall_stub_data(struct mm_id * mm_idp, return 0; } -int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, - int r, int w, int x, int phys_fd, unsigned long long offset, - int done, void **data) +int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot, + int phys_fd, unsigned long long offset, int done, void **data) { - int prot, ret; - - prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | - (x ? PROT_EXEC : 0); + int ret; if(proc_mm){ struct proc_mm_op map; @@ -253,13 +262,11 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, } int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, - int r, int w, int x, int done, void **data) + unsigned int prot, int done, void **data) { struct proc_mm_op protect; - int prot, ret; + int ret; - prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | - (x ? PROT_EXEC : 0); if(proc_mm){ int fd = mm_idp->u.mm_fd; diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 1f39f2bf7ce9..5c088a55396c 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -34,6 +34,7 @@ #include "process.h" #include "longjmp.h" #include "kern_constants.h" +#include "as-layout.h" int is_skas_winch(int pid, int fd, void *data) { @@ -60,37 +61,42 @@ static int ptrace_dump_regs(int pid) return 0; } -void wait_stub_done(int pid, int sig, char * fname) +/* + * Signals that are OK to receive in the stub - we'll just continue it. + * SIGWINCH will happen when UML is inside a detached screen. + */ +#define STUB_SIG_MASK ((1 << SIGVTALRM) | (1 << SIGWINCH)) + +/* Signals that the stub will finish with - anything else is an error */ +#define STUB_DONE_MASK ((1 << SIGUSR1) | (1 << SIGTRAP)) + +void wait_stub_done(int pid) { int n, status, err; - do { - if ( sig != -1 ) { - err = ptrace(PTRACE_CONT, pid, 0, sig); - if(err) - panic("%s : continue failed, errno = %d\n", - fname, errno); - } - sig = 0; - + while(1){ CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - } while((n >= 0) && WIFSTOPPED(status) && - ((WSTOPSIG(status) == SIGVTALRM) || - /* running UML inside a detached screen can cause - * SIGWINCHes - */ - (WSTOPSIG(status) == SIGWINCH))); - - if((n < 0) || !WIFSTOPPED(status) || - (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){ - err = ptrace_dump_regs(pid); + if((n < 0) || !WIFSTOPPED(status)) + goto bad_wait; + + if(((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0) + break; + + err = ptrace(PTRACE_CONT, pid, 0, 0); if(err) - printk("Failed to get registers from stub, " - "errno = %d\n", -err); - panic("%s : failed to wait for SIGUSR1/SIGTRAP, " - "pid = %d, n = %d, errno = %d, status = 0x%x\n", - fname, pid, n, errno, status); + panic("wait_stub_done : continue failed, errno = %d\n", + errno); } + + if(((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0) + return; + +bad_wait: + err = ptrace_dump_regs(pid); + if(err) + printk("Failed to get registers from stub, errno = %d\n", -err); + panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, " + "n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status); } extern unsigned long current_stub_stack(void); @@ -112,7 +118,11 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi) sizeof(struct ptrace_faultinfo)); } else { - wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo"); + err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV); + if(err) + panic("Failed to continue stub, pid = %d, errno = %d\n", + pid, errno); + wait_stub_done(pid); /* faultinfo is prepared by the stub-segv-handler at start of * the stub stack page. We just have to copy it. @@ -304,10 +314,13 @@ void userspace(union uml_pt_regs *regs) UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ if(WIFSTOPPED(status)){ - switch(WSTOPSIG(status)){ + int sig = WSTOPSIG(status); + switch(sig){ case SIGSEGV: - if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo) - user_signal(SIGSEGV, regs, pid); + if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo){ + get_skas_faultinfo(pid, ®s->skas.faultinfo); + (*sig_info[SIGSEGV])(SIGSEGV, regs); + } else handle_segv(pid, regs); break; case SIGTRAP + 0x80: @@ -322,11 +335,13 @@ void userspace(union uml_pt_regs *regs) case SIGBUS: case SIGFPE: case SIGWINCH: - user_signal(WSTOPSIG(status), regs, pid); + block_signals(); + (*sig_info[sig])(sig, regs); + unblock_signals(); break; default: printk("userspace - child stopped with signal " - "%d\n", WSTOPSIG(status)); + "%d\n", sig); } pid = userspace_pid[0]; interrupt_end(); @@ -338,11 +353,29 @@ void userspace(union uml_pt_regs *regs) } } +static unsigned long thread_regs[MAX_REG_NR]; +static unsigned long thread_fp_regs[HOST_FP_SIZE]; + +static int __init init_thread_regs(void) +{ + get_safe_registers(thread_regs, thread_fp_regs); + /* Set parent's instruction pointer to start of clone-stub */ + thread_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + + (unsigned long) stub_clone_handler - + (unsigned long) &__syscall_stub_start; + thread_regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE - + sizeof(void *); +#ifdef __SIGNAL_FRAMESIZE + thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE; +#endif + return 0; +} + +__initcall(init_thread_regs); + int copy_context_skas0(unsigned long new_stack, int pid) { int err; - unsigned long regs[MAX_REG_NR]; - unsigned long fp_regs[HOST_FP_SIZE]; unsigned long current_stack = current_stub_stack(); struct stub_data *data = (struct stub_data *) current_stack; struct stub_data *child_data = (struct stub_data *) new_stack; @@ -357,23 +390,12 @@ int copy_context_skas0(unsigned long new_stack, int pid) .timer = ((struct itimerval) { { 0, 1000000 / hz() }, { 0, 1000000 / hz() }})}); - get_safe_registers(regs, fp_regs); - - /* Set parent's instruction pointer to start of clone-stub */ - regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + - (unsigned long) stub_clone_handler - - (unsigned long) &__syscall_stub_start; - regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE - - sizeof(void *); -#ifdef __SIGNAL_FRAMESIZE - regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE; -#endif - err = ptrace_setregs(pid, regs); + err = ptrace_setregs(pid, thread_regs); if(err < 0) panic("copy_context_skas0 : PTRACE_SETREGS failed, " "pid = %d, errno = %d\n", pid, -err); - err = ptrace_setfpregs(pid, fp_regs); + err = ptrace_setfpregs(pid, thread_fp_regs); if(err < 0) panic("copy_context_skas0 : PTRACE_SETFPREGS failed, " "pid = %d, errno = %d\n", pid, -err); @@ -384,7 +406,11 @@ int copy_context_skas0(unsigned long new_stack, int pid) /* Wait, until parent has finished its work: read child's pid from * parent's stack, and check, if bad result. */ - wait_stub_done(pid, 0, "copy_context_skas0"); + err = ptrace(PTRACE_CONT, pid, 0, 0); + if(err) + panic("Failed to continue new process, pid = %d, " + "errno = %d\n", pid, errno); + wait_stub_done(pid); pid = data->err; if(pid < 0) @@ -394,7 +420,7 @@ int copy_context_skas0(unsigned long new_stack, int pid) /* Wait, until child has finished too: read child's result from * child's stack and check it. */ - wait_stub_done(pid, -1, "copy_context_skas0"); + wait_stub_done(pid); if (child_data->err != UML_CONFIG_STUB_DATA) panic("copy_context_skas0 - stub-child reports error %ld\n", child_data->err); diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c index 5110eff51b90..3b600c2e63b8 100644 --- a/arch/um/os-Linux/skas/trap.c +++ b/arch/um/os-Linux/skas/trap.c @@ -64,20 +64,3 @@ void sig_handler_common_skas(int sig, void *sc_ptr) errno = save_errno; r->skas.is_user = save_user; } - -extern int ptrace_faultinfo; - -void user_signal(int sig, union uml_pt_regs *regs, int pid) -{ - void (*handler)(int, union uml_pt_regs *); - int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || - (sig == SIGILL) || (sig == SIGTRAP)); - - if (segv) - get_skas_faultinfo(pid, ®s->skas.faultinfo); - - handler = sig_info[sig]; - handler(sig, (union uml_pt_regs *) regs); - - unblock_signals(); -} diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c index ee42c27abd3a..29118cf5ff25 100644 --- a/arch/um/sys-i386/user-offsets.c +++ b/arch/um/sys-i386/user-offsets.c @@ -1,9 +1,10 @@ #include +#include #include +#include +#include #include #include -#include -#include #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -72,4 +73,8 @@ void foo(void) DEFINE(UM_POLLIN, POLLIN); DEFINE(UM_POLLPRI, POLLPRI); DEFINE(UM_POLLOUT, POLLOUT); + + DEFINE(UM_PROT_READ, PROT_READ); + DEFINE(UM_PROT_WRITE, PROT_WRITE); + DEFINE(UM_PROT_EXEC, PROT_EXEC); } diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c index 7bb532567c47..0d5fd764c21f 100644 --- a/arch/um/sys-x86_64/user-offsets.c +++ b/arch/um/sys-x86_64/user-offsets.c @@ -2,6 +2,7 @@ #include #include #include +#include #define __FRAME_OFFSETS #include #include @@ -93,4 +94,8 @@ void foo(void) DEFINE(UM_POLLIN, POLLIN); DEFINE(UM_POLLPRI, POLLPRI); DEFINE(UM_POLLOUT, POLLOUT); + + DEFINE(UM_PROT_READ, PROT_READ); + DEFINE(UM_PROT_WRITE, PROT_WRITE); + DEFINE(UM_PROT_EXEC, PROT_EXEC); } diff --git a/include/asm-um/page.h b/include/asm-um/page.h index 4296d3135aa9..8e310d81e5b4 100644 --- a/include/asm-um/page.h +++ b/include/asm-um/page.h @@ -114,9 +114,6 @@ extern unsigned long uml_physmem; extern struct page *arch_validate(struct page *page, gfp_t mask, int order); #define HAVE_ARCH_VALIDATE -extern void arch_free_page(struct page *page, int order); -#define HAVE_ARCH_FREE_PAGE - #include #include diff --git a/include/asm-um/tlbflush.h b/include/asm-um/tlbflush.h index 522aa30f7eaa..e78c28c1f350 100644 --- a/include/asm-um/tlbflush.h +++ b/include/asm-um/tlbflush.h @@ -7,6 +7,7 @@ #define __UM_TLBFLUSH_H #include +#include "choose-mode.h" /* * TLB flushing: @@ -24,6 +25,18 @@ extern void flush_tlb_all(void); extern void flush_tlb_mm(struct mm_struct *mm); extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); +extern void flush_tlb_page_skas(struct vm_area_struct *vma, + unsigned long address); + +static inline void flush_tlb_page(struct vm_area_struct *vma, + unsigned long address) +{ + address &= PAGE_MASK; + + CHOOSE_MODE(flush_tlb_range(vma, address, address + PAGE_SIZE), + flush_tlb_page_skas(vma, address)); +} + extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); extern void flush_tlb_kernel_vm(void); extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); @@ -35,14 +48,3 @@ static inline void flush_tlb_pgtables(struct mm_struct *mm, } #endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ -- cgit v1.2.3-59-g8ed1b From 1e7371c1a11f041d641cc0ff113bf1daa1bd98b9 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:49 -0700 Subject: uml: only flush areas covered by VMA When doing a full address space flush, only look at areas covered by a VMA. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/skas/tlb.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c index b3d722ddde31..c0f0693743ba 100644 --- a/arch/um/kernel/skas/tlb.c +++ b/arch/um/kernel/skas/tlb.c @@ -89,8 +89,13 @@ void flush_tlb_mm_skas(struct mm_struct *mm) void force_flush_all_skas(void) { - unsigned long end = proc_mm ? task_size : CONFIG_STUB_START; - fix_range(current->mm, 0, end, 1); + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma = mm->mmap; + + while(vma != NULL) { + fix_range(mm, vma->vm_start, vma->vm_end, 1); + vma = vma->vm_next; + } } void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address) -- cgit v1.2.3-59-g8ed1b From 83ff7df5f1c1c44efd84d7341211aa0138fd9504 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:50 -0700 Subject: uml: out of tmpfs space error clarification It turns out that the message complaining about a lack of tmpfs space on the host can be misunderstood as referring to the UML. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/trap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 0c467fa08870..abab90c3803f 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -229,8 +229,8 @@ void relay_signal(int sig, union uml_pt_regs *regs) if(!UPT_IS_USER(regs)){ if(sig == SIGBUS) - printk("Bus error - the /dev/shm or /tmp mount likely " - "just ran out of space\n"); + printk("Bus error - the host /dev/shm or /tmp mount " + "likely just ran out of space\n"); panic("Kernel mode signal %d", sig); } -- cgit v1.2.3-59-g8ed1b From b7ec15bd004f4524bf091f851348da2ccb519e4f Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:51 -0700 Subject: uml: virtualized time fix With the current timekeeping, !CONFIG_UML_REAL_TIME_CLOCK has inconsistent behavior. Previously, gettimeofday could be (and was) isolated from the clock ticking. Now, it's not, so when CONFIG_UML_REAL_TIME_CLOCK is disabled, gettimeofday must progress in lockstep with the clock, making it fully virtual. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/time.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index 9fd80ee3eef6..cd7349de8ca6 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -34,8 +34,8 @@ unsigned long long sched_clock(void) return (unsigned long long)jiffies_64 * (1000000000 / HZ); } -static unsigned long long prev_nsecs[NR_CPUS]; #ifdef CONFIG_UML_REAL_TIME_CLOCK +static unsigned long long prev_nsecs[NR_CPUS]; static long long delta[NR_CPUS]; /* Deviation per interval */ #endif @@ -94,7 +94,12 @@ irqreturn_t um_timer(int irq, void *dev) do_timer(1); +#ifdef CONFIG_UML_REAL_TIME_CLOCK nsecs = get_time(); +#else + nsecs = (unsigned long long) xtime.tv_sec * BILLION + xtime.tv_nsec + + BILLION / HZ; +#endif xtime.tv_sec = nsecs / NSEC_PER_SEC; xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC; @@ -127,13 +132,18 @@ void time_init(void) nsecs = os_nsecs(); set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION, -nsecs % BILLION); + set_normalized_timespec(&xtime, nsecs / BILLION, nsecs % BILLION); late_time_init = register_timer; } void do_gettimeofday(struct timeval *tv) { +#ifdef CONFIG_UML_REAL_TIME_CLOCK unsigned long long nsecs = get_time(); - +#else + unsigned long long nsecs = (unsigned long long) xtime.tv_sec * BILLION + + xtime.tv_nsec; +#endif tv->tv_sec = nsecs / NSEC_PER_SEC; /* Careful about calculations here - this was originally done as * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC -- cgit v1.2.3-59-g8ed1b From c2f239d93e8af991392871c57465cb2ac556b482 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Sun, 6 May 2007 14:51:52 -0700 Subject: uml: fix prototypes Declare strlcpy and strlcat more correctly. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/user.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/um/include/user.h b/arch/um/include/user.h index a6da62608254..d380e6d91a90 100644 --- a/arch/um/include/user.h +++ b/arch/um/include/user.h @@ -14,6 +14,11 @@ */ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +/* + * This will provide the size_t definition in both kernel and userspace builds + */ +#include + extern void panic(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); extern int printk(const char *fmt, ...) @@ -21,8 +26,7 @@ extern int printk(const char *fmt, ...) extern void schedule(void); extern int in_aton(char *str); extern int open_gdb_chan(void); -/* These use size_t, however unsigned long is correct on both i386 and x86_64. */ -extern unsigned long strlcpy(char *, const char *, unsigned long); -extern unsigned long strlcat(char *, const char *, unsigned long); +extern size_t strlcpy(char *, const char *, size_t); +extern size_t strlcat(char *, const char *, size_t); #endif -- cgit v1.2.3-59-g8ed1b From ee17b36fd0dc2af37ea92548595e30964674ded8 Mon Sep 17 00:00:00 2001 From: john stultz Date: Sun, 6 May 2007 14:51:53 -0700 Subject: v850: generic timekeeping conversion Convert an arch that does not currently implement sub-jiffy timekeeping to use the generic timekeeping code. v850 looks like it has some intent to implement sub-jiffy timekeeping, so it may not yet be appropriate to try to convert, but I figured I'd get the maintainer's input and submit the patch for comment. Signed-off-by: John Stultz Cc: Miles Bader Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/v850/Kconfig | 4 +++ arch/v850/kernel/time.c | 75 ------------------------------------------------- 2 files changed, 4 insertions(+), 75 deletions(-) (limited to 'arch') diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig index 50ccc7f57cd0..5f54c1236c18 100644 --- a/arch/v850/Kconfig +++ b/arch/v850/Kconfig @@ -37,6 +37,10 @@ config GENERIC_IRQ_PROBE bool default y +config GENERIC_TIME + bool + default y + config TIME_LOW_RES bool default y diff --git a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c index 486e3a441c86..f0905b03523b 100644 --- a/arch/v850/kernel/time.c +++ b/arch/v850/kernel/time.c @@ -90,81 +90,6 @@ static irqreturn_t timer_interrupt (int irq, void *dummy, struct pt_regs *regs) return IRQ_HANDLED; } -/* - * This version of gettimeofday has near microsecond resolution. - */ -void do_gettimeofday (struct timeval *tv) -{ -#if 0 /* DAVIDM later if possible */ - extern volatile unsigned long lost_ticks; - unsigned long lost; -#endif - unsigned long flags; - unsigned long usec, sec; - unsigned long seq; - - do { - seq = read_seqbegin_irqsave(&xtime_lock, flags); - -#if 0 - usec = mach_gettimeoffset ? mach_gettimeoffset () : 0; -#else - usec = 0; -#endif -#if 0 /* DAVIDM later if possible */ - lost = lost_ticks; - if (lost) - usec += lost * (1000000/HZ); -#endif - sec = xtime.tv_sec; - usec += xtime.tv_nsec / 1000; - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - - while (usec >= 1000000) { - usec -= 1000000; - sec++; - } - - tv->tv_sec = sec; - tv->tv_usec = usec; -} - -EXPORT_SYMBOL(do_gettimeofday); - -int do_settimeofday(struct timespec *tv) -{ - if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) - return -EINVAL; - - write_seqlock_irq (&xtime_lock); - - /* This is revolting. We need to set the xtime.tv_nsec - * correctly. However, the value in this location is - * is value at the last tick. - * Discover what correction gettimeofday - * would have done, and then undo it! - */ -#if 0 - tv->tv_nsec -= mach_gettimeoffset() * 1000; -#endif - - while (tv->tv_nsec < 0) { - tv->tv_nsec += NSEC_PER_SEC; - tv->tv_sec--; - } - - xtime.tv_sec = tv->tv_sec; - xtime.tv_nsec = tv->tv_nsec; - - ntp_clear(); - - write_sequnlock_irq (&xtime_lock); - clock_was_set(); - return 0; -} - -EXPORT_SYMBOL(do_settimeofday); - static int timer_dev_id; static struct irqaction timer_irqaction = { timer_interrupt, -- cgit v1.2.3-59-g8ed1b From 0ddb16cfb05c04d644b4ba8e36e780b15f47a191 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 6 May 2007 14:51:54 -0700 Subject: xtensa: strlcpy is smart enough strlcpy already accounts for the trailing zero in its length computation, so there is no need to substract one to the buffer size. Signed-off-by: Jean Delvare Cc: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/xtensa/platform-iss/network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c index ab05bff40104..4bfe333be229 100644 --- a/arch/xtensa/platform-iss/network.c +++ b/arch/xtensa/platform-iss/network.c @@ -251,7 +251,7 @@ static int tuntap_open(struct iss_net_private *lp) memset(&ifr, 0, sizeof ifr); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - strlcpy(ifr.ifr_name, dev_name, sizeof ifr.ifr_name - 1); + strlcpy(ifr.ifr_name, dev_name, sizeof ifr.ifr_name); if ((err = simc_ioctl(fd, TUNSETIFF, (void*) &ifr)) < 0) { printk("Failed to set interface, returned %d " -- cgit v1.2.3-59-g8ed1b