Commit 1acbef74 authored by Jaroslav Kysela's avatar Jaroslav Kysela

Merge suse.cz:/home/perex/bk/linux-sound/linux-2.5

into suse.cz:/home/perex/bk/linux-sound/linux-sound
parents fcc58f6a 5c4ac43f
......@@ -173,6 +173,9 @@ filled out, however:
2 bootsect-loader
3 SYSLINUX
4 EtherBoot
5 ELILO
7 GRuB
8 U-BOOT
Please contact <hpa@zytor.com> if you need a bootloader ID
value assigned.
......
......@@ -74,6 +74,10 @@ Offset Type Description
0x21c unsigned long INITRD_SIZE, size in bytes of ramdisk image
0x220 4 bytes (setup.S)
0x224 unsigned short setup.S heap end pointer
0x226 unsigned short zero_pad
0x228 unsigned long cmd_line_ptr
0x22c unsigned long ramdisk_max
0x230 16 bytes trampoline
0x290 - 0x2cf EDD_MBR_SIG_BUFFER (edd.S)
0x2d0 - 0x600 E820MAP
0x600 - 0x7ff EDDBUF (edd.S) for disk signature read sector
......
......@@ -50,6 +50,7 @@ restrictions referred to are that the relevant option is valid if:
MOUSE Appropriate mouse support is enabled.
MTD MTD support is enabled.
NET Appropriate network support is enabled.
NUMA NUMA support is enabled.
NFS Appropriate NFS support is enabled.
OSS OSS sound support is enabled.
PARIDE The ParIDE subsystem is enabled.
......@@ -476,6 +477,10 @@ running once the system is up.
gvp11= [HW,SCSI]
hashdist= [KNL,NUMA] Large hashes allocated during boot
are distributed across NUMA nodes. Defaults on
for IA-64, off otherwise.
hcl= [IA-64] SGI's Hardware Graph compatibility layer
hd= [EIDE] (E)IDE hard drive subsystem geometry
......
......@@ -5,6 +5,9 @@ please mail me.
00-INDEX
- this file
cpu_features.txt
- info on how we support a variety of CPUs with minimal compile-time
options.
ppc_htab.txt
- info about the Linux/PPC /proc/ppc_htab entry
smp.txt
......
Hollis Blanchard <hollis@austin.ibm.com>
5 Jun 2002
This document describes the system (including self-modifying code) used in the
PPC Linux kernel to support a variety of PowerPC CPUs without requiring
compile-time selection.
Early in the boot process the ppc32 kernel detects the current CPU type and
chooses a set of features accordingly. Some examples include Altivec support,
split instruction and data caches, and if the CPU supports the DOZE and NAP
sleep modes.
Detection of the feature set is simple. A list of processors can be found in
arch/ppc/kernel/cputable.c. The PVR register is masked and compared with each
value in the list. If a match is found, the cpu_features of cur_cpu_spec is
assigned to the feature bitmask for this processor and a __setup_cpu function
is called.
C code may test 'cur_cpu_spec[smp_processor_id()]->cpu_features' for a
particular feature bit. This is done in quite a few places, for example
in ppc_setup_l2cr().
Implementing cpufeatures in assembly is a little more involved. There are
several paths that are performance-critical and would suffer if an array
index, structure dereference, and conditional branch were added. To avoid the
performance penalty but still allow for runtime (rather than compile-time) CPU
selection, unused code is replaced by 'nop' instructions. This nop'ing is
based on CPU 0's capabilities, so a multi-processor system with non-identical
processors will not work (but such a system would likely have other problems
anyways).
After detecting the processor type, the kernel patches out sections of code
that shouldn't be used by writing nop's over it. Using cpufeatures requires
just 2 macros (found in include/asm-ppc/cputable.h), as seen in head.S
transfer_to_handler:
#ifdef CONFIG_ALTIVEC
BEGIN_FTR_SECTION
mfspr r22,SPRN_VRSAVE /* if G4, save vrsave register value */
stw r22,THREAD_VRSAVE(r23)
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
#endif /* CONFIG_ALTIVEC */
If CPU 0 supports Altivec, the code is left untouched. If it doesn't, both
instructions are replaced with nop's.
The END_FTR_SECTION macro has two simpler variations: END_FTR_SECTION_IFSET
and END_FTR_SECTION_IFCLR. These simply test if a flag is set (in
cur_cpu_spec[0]->cpu_features) or is cleared, respectively. These two macros
should be used in the majority of cases.
The END_FTR_SECTION macros are implemented by storing information about this
code in the '__ftr_fixup' ELF section. When do_cpu_ftr_fixups
(arch/ppc/kernel/misc.S) is invoked, it will iterate over the records in
__ftr_fixup, and if the required feature is not present it will loop writing
nop's from each BEGIN_FTR_SECTION to END_FTR_SECTION.
......@@ -21,6 +21,8 @@
#include <asm/uaccess.h>
#include <asm/rtc.h>
#include <asm/mach/time.h>
#define RTC_DR (0)
#define RTC_MR (4)
#define RTC_STAT (8)
......
......@@ -92,7 +92,7 @@ EXPORT_SYMBOL(pxa_set_cken);
*/
static struct map_desc standard_io_desc[] __initdata = {
/* virtual physical length type */
{ 0xf2000000, 0x40000000, 0x01800000, MT_DEVICE }, /* Devs */
{ 0xf2000000, 0x40000000, 0x02000000, MT_DEVICE }, /* Devs */
{ 0xf4000000, 0x44000000, 0x00100000, MT_DEVICE }, /* LCD */
{ 0xf6000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Mem Ctl */
{ 0xf8000000, 0x4c000000, 0x00100000, MT_DEVICE }, /* USB host */
......
......@@ -17,7 +17,8 @@
*
* Revision history:
* 22nd Aug 2003 Initial version.
*
* 20th Dec 2004 Added ssp_config for changing port config without
* closing the port.
*/
#include <linux/module.h>
......@@ -34,6 +35,11 @@
#include <asm/arch/ssp.h>
#include <asm/arch/pxa-regs.h>
#define PXA_SSP_PORTS 3
static DECLARE_MUTEX(sem);
static int use_count[PXA_SSP_PORTS] = {0, 0, 0};
static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct ssp_dev *dev = (struct ssp_dev*) dev_id;
......@@ -170,6 +176,30 @@ void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp)
SSCR0_P(dev->port) = ssp->cr0;
}
/**
* ssp_config - configure SSP port settings
* @mode: port operating mode
* @flags: port config flags
* @psp_flags: port PSP config flags
* @speed: port speed
*
* Port MUST be disabled by ssp_disable before making any config changes.
*/
int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed)
{
dev->mode = mode;
dev->flags = flags;
dev->psp_flags = psp_flags;
dev->speed = speed;
/* set up port type, speed, port settings */
SSCR0_P(dev->port) = (dev->speed | dev->mode);
SSCR1_P(dev->port) = dev->flags;
SSPSP_P(dev->port) = dev->psp_flags;
return 0;
}
/**
* ssp_init - setup the SSP port
*
......@@ -180,12 +210,23 @@ void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp)
* %-EBUSY if the resources are already in use
* %0 on success
*/
int ssp_init(struct ssp_dev *dev, u32 port, u32 mode, u32 flags, u32 psp_flags,
u32 speed)
int ssp_init(struct ssp_dev *dev, u32 port)
{
int ret, irq;
if (port > PXA_SSP_PORTS || port == 0)
return -ENODEV;
down(&sem);
if (use_count[port - 1]) {
up(&sem);
return -EBUSY;
}
use_count[port - 1]++;
if (!request_mem_region(__PREG(SSCR0_P(port)), 0x2c, "SSP")) {
use_count[port - 1]--;
up(&sem);
return -EBUSY;
}
......@@ -213,15 +254,6 @@ int ssp_init(struct ssp_dev *dev, u32 port, u32 mode, u32 flags, u32 psp_flags,
}
dev->port = port;
dev->mode = mode;
dev->flags = flags;
dev->psp_flags = psp_flags;
dev->speed = speed;
/* set up port type, speed, port settings */
SSCR0_P(dev->port) = (dev->speed | dev->mode);
SSCR1_P(dev->port) = dev->flags;
SSPSP_P(dev->port) = dev->psp_flags;
ret = request_irq(irq, ssp_interrupt, 0, "SSP", dev);
if (ret)
......@@ -252,10 +284,13 @@ int ssp_init(struct ssp_dev *dev, u32 port, u32 mode, u32 flags, u32 psp_flags,
#endif
}
up(&sem);
return 0;
out_region:
release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c);
release_mem_region(__PREG(SSCR0_P(port)), 0x2c);
use_count[port - 1]--;
up(&sem);
return ret;
}
......@@ -268,6 +303,7 @@ void ssp_exit(struct ssp_dev *dev)
{
int irq;
down(&sem);
SSCR0_P(dev->port) &= ~SSCR0_SSE;
/* find irq, save power and turn off SSP port clock */
......@@ -306,6 +342,8 @@ void ssp_exit(struct ssp_dev *dev)
free_irq(irq, dev);
release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c);
use_count[dev->port - 1]--;
up(&sem);
}
EXPORT_SYMBOL(ssp_write_word);
......@@ -317,3 +355,9 @@ EXPORT_SYMBOL(ssp_save_state);
EXPORT_SYMBOL(ssp_restore_state);
EXPORT_SYMBOL(ssp_init);
EXPORT_SYMBOL(ssp_exit);
EXPORT_SYMBOL(ssp_config);
MODULE_DESCRIPTION("PXA SSP driver");
MODULE_AUTHOR("Liam Girdwood");
MODULE_LICENSE("GPL");
......@@ -15,6 +15,8 @@ Philip Blundell
Russell King
Keith Owens
also thanks to Nicholas Pitre for hints, and for the basis or our XIP support.
Currently maintaing the code are
Ian Molton (Maintainer / Archimedes)
......
......@@ -6,6 +6,7 @@
# for more details.
#
# Copyright (C) 1995-2001 by Russell King
# Copyright (c) 2004 Ian Molton
LDFLAGS_vmlinux :=-p -X
CPPFLAGS_vmlinux.lds = -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
......@@ -20,13 +21,9 @@ ifeq ($(CONFIG_DEBUG_INFO),y)
CFLAGS +=-g
endif
# Force -mno-fpu to be passed to the assembler. Some versions of gcc don't
# do this with -msoft-float
CFLAGS_BOOT :=-mapcs-26 -mcpu=arm3 -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm
CFLAGS +=-mapcs-26 -mcpu=arm3 -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm
AFLAGS +=-mapcs-26 -mcpu=arm3 -mno-fpu -msoft-float -Wa,-mno-fpu
head-y := arch/arm26/machine/head.o arch/arm26/kernel/init_task.o
CFLAGS_BOOT :=-mapcs-26 -mcpu=arm3 -msoft-float -Uarm
CFLAGS +=-mapcs-26 -mcpu=arm3 -msoft-float -Uarm
AFLAGS +=-mapcs-26 -mcpu=arm3 -msoft-float
ifeq ($(CONFIG_XIP_KERNEL),y)
TEXTADDR := 0x03880000
......@@ -36,6 +33,8 @@ else
DATAADDR := .
endif
head-y := arch/arm26/kernel/head.o arch/arm26/kernel/init_task.o
ifeq ($(incdir-y),)
incdir-y :=
endif
......@@ -109,6 +108,7 @@ define archhelp
echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
echo ' bootpImage - Combined zImage and initial RAM disk'
echo ' xipImage - eXecute In Place capable image for ROM use (arch/$(ARCH)/boot/xipImage)'
echo ' initrd - Create an initial image'
echo ' install - Install uncompressed kernel'
echo ' zinstall - Install compressed kernel'
......
#
# arch/arm/boot/Makefile
# arch/arm26/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
......@@ -51,8 +51,10 @@ $(obj)/compressed/vmlinux: vmlinux FORCE
ifeq ($(CONFIG_XIP_KERNEL),y)
$(obj)/xipImage: vmlinux FORCE
$(OBJCOPY) -S -O binary -R .data -R .comment vmlinux vmlinux-text.bin
$(OBJCOPY) -S -O binary -R .init -R .text -R .comment -R __ex_table -R __ksymtab vmlinux vmlinux-data.bin
# $(OBJCOPY) -S -O binary -R .data -R .comment vmlinux vmlinux-text.bin
# FIXME - where has .pci_fixup crept in from?
$(OBJCOPY) -S -O binary -R .data -R .pci_fixup -R .comment vmlinux vmlinux-text.bin
$(OBJCOPY) -S -O binary -R .init -R .text -R __ex_table -R .pci_fixup -R __ksymtab -R __ksymtab_gpl -R __kcrctab -R __kcrctab_gpl -R __param -R .comment vmlinux vmlinux-data.bin
cat vmlinux-text.bin vmlinux-data.bin > $@
$(RM) -f vmlinux-text.bin vmlinux-data.bin
@echo ' Kernel: $@ is ready'
......
/*
* linux/arch/arm/boot/compressed/head.S
* linux/arch/arm26/boot/compressed/head.S
*
* Copyright (C) 1996-2002 Russell King
*
......
/*
* linux/arch/arm/lib/ll_char_wr.S
* linux/arch/arm26/lib/ll_char_wr.S
*
* Copyright (C) 1995, 1996 Russell King.
*
......
/*
* linux/arch/arm/boot/compressed/ofw-shark.c
*
* by Alexander Schulz
*
* This file is used to get some basic information
* about the memory layout of the shark we are running
* on. Memory is usually divided in blocks a 8 MB.
* And bootargs are copied from OpenFirmware.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/setup.h>
#include <asm/page.h>
asmlinkage void
create_params (unsigned long *buffer)
{
/* Is there a better address? Also change in mach-shark/core.c */
struct tag *tag = (struct tag *) 0x08003000;
int j,i,m,k,nr_banks,size;
unsigned char *c;
/* Head of the taglist */
tag->hdr.tag = ATAG_CORE;
tag->hdr.size = tag_size(tag_core);
tag->u.core.flags = FLAG_READONLY;
tag->u.core.pagesize = PAGE_SIZE;
tag->u.core.rootdev = 0;
/* Build up one tagged block for each memory region */
size=0;
nr_banks=(unsigned int) buffer[0];
for (j=0;j<nr_banks;j++){
/* search the lowest address and put it into the next entry */
/* not a fast sort algorithm, but there are at most 8 entries */
/* and this is used only once anyway */
m=0xffffffff;
for (i=0;i<(unsigned int) buffer[0];i++){
if (buffer[2*i+1]<m) {
m=buffer[2*i+1];
k=i;
}
}
tag = tag_next(tag);
tag->hdr.tag = ATAG_MEM;
tag->hdr.size = tag_size(tag_mem32);
tag->u.mem.size = buffer[2*k+2];
tag->u.mem.start = buffer[2*k+1];
size += buffer[2*k+2];
buffer[2*k+1]=0xffffffff; /* mark as copied */
}
/* The command line */
tag = tag_next(tag);
tag->hdr.tag = ATAG_CMDLINE;
c=(unsigned char *)(&buffer[34]);
j=0;
while (*c) tag->u.cmdline.cmdline[j++]=*c++;
tag->u.cmdline.cmdline[j]=0;
tag->hdr.size = (j + 7 + sizeof(struct tag_header)) >> 2;
/* Hardware revision */
tag = tag_next(tag);
tag->hdr.tag = ATAG_REVISION;
tag->hdr.size = tag_size(tag_revision);
tag->u.revision.rev = ((unsigned char) buffer[33])-'0';
/* End of the taglist */
tag = tag_next(tag);
tag->hdr.tag = 0;
tag->hdr.size = 0;
}
typedef int (*ofw_handle_t)(void *);
/* Everything below is called with a wrong MMU setting.
* This means: no string constants, no initialization of
* arrays, no global variables! This is ugly but I didn't
* want to write this in assembler :-)
*/
int
of_decode_int(const unsigned char *p)
{
unsigned int i = *p++ << 8;
i = (i + *p++) << 8;
i = (i + *p++) << 8;
return (i + *p);
}
int
OF_finddevice(ofw_handle_t openfirmware, char *name)
{
unsigned int args[8];
char service[12];
service[0]='f';
service[1]='i';
service[2]='n';
service[3]='d';
service[4]='d';
service[5]='e';
service[6]='v';
service[7]='i';
service[8]='c';
service[9]='e';
service[10]='\0';
args[0]=(unsigned int)service;
args[1]=1;
args[2]=1;
args[3]=(unsigned int)name;
if (openfirmware(args) == -1)
return -1;
return args[4];
}
int
OF_getproplen(ofw_handle_t openfirmware, int handle, char *prop)
{
unsigned int args[8];
char service[12];
service[0]='g';
service[1]='e';
service[2]='t';
service[3]='p';
service[4]='r';
service[5]='o';
service[6]='p';
service[7]='l';
service[8]='e';
service[9]='n';
service[10]='\0';
args[0] = (unsigned int)service;
args[1] = 2;
args[2] = 1;
args[3] = (unsigned int)handle;
args[4] = (unsigned int)prop;
if (openfirmware(args) == -1)
return -1;
return args[5];
}
int
OF_getprop(ofw_handle_t openfirmware, int handle, char *prop, void *buf, unsigned int buflen)
{
unsigned int args[8];
char service[8];
service[0]='g';
service[1]='e';
service[2]='t';
service[3]='p';
service[4]='r';
service[5]='o';
service[6]='p';
service[7]='\0';
args[0] = (unsigned int)service;
args[1] = 4;
args[2] = 1;
args[3] = (unsigned int)handle;
args[4] = (unsigned int)prop;
args[5] = (unsigned int)buf;
args[6] = buflen;
if (openfirmware(args) == -1)
return -1;
return args[7];
}
asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer)
{
int phandle,i,mem_len,buffer[32];
char temp[15];
temp[0]='/';
temp[1]='m';
temp[2]='e';
temp[3]='m';
temp[4]='o';
temp[5]='r';
temp[6]='y';
temp[7]='\0';
phandle=OF_finddevice(o,temp);
temp[0]='r';
temp[1]='e';
temp[2]='g';
temp[3]='\0';
mem_len = OF_getproplen(o,phandle, temp);
OF_getprop(o,phandle, temp, buffer, mem_len);
*nomr=mem_len >> 3;
for (i=0; i<=mem_len/4; i++) pointer[i]=of_decode_int((const unsigned char *)&buffer[i]);
temp[0]='/';
temp[1]='c';
temp[2]='h';
temp[3]='o';
temp[4]='s';
temp[5]='e';
temp[6]='n';
temp[7]='\0';
phandle=OF_finddevice(o,temp);
temp[0]='b';
temp[1]='o';
temp[2]='o';
temp[3]='t';
temp[4]='a';
temp[5]='r';
temp[6]='g';
temp[7]='s';
temp[8]='\0';
mem_len = OF_getproplen(o,phandle, temp);
OF_getprop(o,phandle, temp, buffer, mem_len);
if (mem_len > 128) mem_len=128;
for (i=0; i<=mem_len/4; i++) pointer[i+33]=buffer[i];
pointer[i+33]=0;
temp[0]='/';
temp[1]='\0';
phandle=OF_finddevice(o,temp);
temp[0]='b';
temp[1]='a';
temp[2]='n';
temp[3]='n';
temp[4]='e';
temp[5]='r';
temp[6]='-';
temp[7]='n';
temp[8]='a';
temp[9]='m';
temp[10]='e';
temp[11]='\0';
mem_len = OF_getproplen(o,phandle, temp);
OF_getprop(o,phandle, temp, buffer, mem_len);
(unsigned char) pointer[32] = ((unsigned char *) buffer)[mem_len-2];
}
/*
* linux/include/asm-arm/arch-arc/uncompress.h
*
* Copyright (C) 1996 Russell King
*
......
/*
* linux/arch/arm/boot/compressed/vmlinux.lds.in
* linux/arch/arm26/boot/compressed/vmlinux.lds.in
*
* Copyright (C) 2000 Russell King
*
......
#!/bin/sh
#
# arch/arm/boot/install.sh
# arch/arm26/boot/install.sh
#
# 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
......@@ -10,7 +10,7 @@
#
# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
# Adapted from code in arch/i386/boot/install.sh by Russell King
# Stolen from arch/arm/boot/install.sh by Ian Molton
# Stolen from arm32 by Ian Molton
#
# "make install" script for arm architecture
#
......
......@@ -2,17 +2,16 @@
# Makefile for the linux kernel.
#
ENTRY_OBJ = entry.o
# Object file lists.
obj-y := compat.o dma.o entry.o irq.o \
process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
time.o traps.o ecard.o time-acorn.o dma.o \
ecard.o fiq.o time.o
AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR)
obj-y := compat.o dma.o entry.o irq.o process.o ptrace.o \
semaphore.o setup.o signal.o sys_arm.o time.o traps.o \
ecard.o dma.o ecard.o fiq.o time.o
extra-y := head.o init_task.o vmlinux.lds
obj-$(CONFIG_FIQ) += fiq.o
obj-$(CONFIG_MODULES) += armksyms.o
extra-y := init_task.o vmlinux.lds
......@@ -7,6 +7,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/config.h>
#include <linux/module.h>
#include <linux/user.h>
......@@ -27,8 +28,6 @@
#include <asm/elf.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/pgalloc.h>
//#include <asm/proc-fns.h>
#include <asm/processor.h>
#include <asm/semaphore.h>
#include <asm/system.h>
......@@ -69,8 +68,9 @@ extern void fp_enter(void);
/*
* This has a special calling convention; it doesn't
* modify any of the usual registers, except for LR.
* FIXME - we used to use our own local version - looks to be in kernel/softirq now
*/
extern void __do_softirq(void);
//extern void __do_softirq(void);
#define EXPORT_SYMBOL_ALIAS(sym,orig) \
const char __kstrtab_##sym[] \
......@@ -95,7 +95,7 @@ EXPORT_SYMBOL(ret_from_exception);
EXPORT_SYMBOL(kd_mksound);
#endif
EXPORT_SYMBOL(__do_softirq);
//EXPORT_SYMBOL(__do_softirq);
/* platform dependent support */
EXPORT_SYMBOL(dump_thread);
......@@ -213,12 +213,6 @@ EXPORT_SYMBOL(sys_open);
EXPORT_SYMBOL(sys_exit);
EXPORT_SYMBOL(sys_wait4);
/* semaphores */
EXPORT_SYMBOL(__down_failed);
EXPORT_SYMBOL(__down_interruptible_failed);
EXPORT_SYMBOL(__down_trylock_failed);
EXPORT_SYMBOL(__up_wakeup);
EXPORT_SYMBOL(get_wchan);
#ifdef CONFIG_PREEMPT
......
/*
* linux/arch/arm26/lib/calls.h
* linux/arch/arm26/kernel/calls.S
*
* Copyright (C) 2003 Ian Molton
*
......@@ -8,8 +8,11 @@
* published by the Free Software Foundation.
*
* FIXME
* This file is included twice in entry-common.S which may not be necessary
* This file is included twice in entry.S which may not be necessary
*/
//FIXME - clearly NR_syscalls is never defined here
#ifndef NR_syscalls
#define NR_syscalls 256
#else
......
/*
* linux/arch/arm/kernel/compat.c
* linux/arch/arm26/kernel/compat.c
*
* Copyright (C) 2001 Russell King
* 2003 Ian Molton
......
/*
* linux/arch/arm/kernel/dma.c
* linux/arch/arm26/kernel/dma.c
*
* Copyright (C) 1995-2000 Russell King
* 2003 Ian Molton
......@@ -24,8 +24,6 @@
spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED;
#if MAX_DMA_CHANNELS > 0
static dma_t dma_chan[MAX_DMA_CHANNELS];
/*
......@@ -260,33 +258,6 @@ void __init init_dma(void)
arch_dma_init(dma_chan);
}
#else
int request_dma(dmach_t channel, const char *device_id)
{
return -EINVAL;
}
int get_dma_residue(dmach_t channel)
{
return 0;
}
#define GLOBAL_ALIAS(_a,_b) asm (".set " #_a "," #_b "; .globl " #_a)
GLOBAL_ALIAS(disable_dma, get_dma_residue);
GLOBAL_ALIAS(enable_dma, get_dma_residue);
GLOBAL_ALIAS(free_dma, get_dma_residue);
GLOBAL_ALIAS(get_dma_list, get_dma_residue);
GLOBAL_ALIAS(set_dma_mode, get_dma_residue);
GLOBAL_ALIAS(set_dma_page, get_dma_residue);
GLOBAL_ALIAS(set_dma_count, get_dma_residue);
GLOBAL_ALIAS(set_dma_addr, get_dma_residue);
GLOBAL_ALIAS(set_dma_sg, get_dma_residue);
GLOBAL_ALIAS(set_dma_speed, get_dma_residue);
GLOBAL_ALIAS(init_dma, get_dma_residue);
#endif
EXPORT_SYMBOL(request_dma);
EXPORT_SYMBOL(free_dma);
EXPORT_SYMBOL(enable_dma);
......
......@@ -42,9 +42,7 @@
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
#include <asm/irq.h>
#include <asm/irqchip.h>
#include <asm/tlbflush.h>
......@@ -137,65 +135,23 @@ ecard_task_readbytes(struct ecard_request *req)
unsigned int len = req->length;
unsigned int off = req->address;
if (req->ec->slot_no == 8) {
/*
* The card maintains an index which increments the address
* into a 4096-byte page on each access. We need to keep
* track of the counter.
*/
static unsigned int index;
unsigned int page;
page = (off >> 12) * 4;
if (page > 256 * 4)
return;
off &= 4095;
/*
* If we are reading offset 0, or our current index is
* greater than the offset, reset the hardware index counter.
*/
if (off == 0 || index > off) {
*base_addr = 0;
index = 0;
}
/*
* Increment the hardware index counter until we get to the
* required offset. The read bytes are discarded.
*/
while (index < off) {
unsigned char byte;
byte = base_addr[page];
index += 1;
}
if (!req->use_loader || !req->ec->loader) {
off *= 4;
while (len--) {
*buf++ = base_addr[page];
index += 1;
*buf++ = base_addr[off];
off += 4;
}
} else {
if (!req->use_loader || !req->ec->loader) {
off *= 4;
while (len--) {
*buf++ = base_addr[off];
off += 4;
}
} else {
while(len--) {
/*
* The following is required by some
* expansion card loader programs.
*/
*(unsigned long *)0x108 = 0;
*buf++ = ecard_loader_read(off++, base_addr,
req->ec->loader);
}
while(len--) {
/*
* The following is required by some
* expansion card loader programs.
*/
*(unsigned long *)0x108 = 0;
*buf++ = ecard_loader_read(off++, base_addr,
req->ec->loader);
}
}
}
static void ecard_do_request(struct ecard_request *req)
......@@ -466,7 +422,7 @@ ecard_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
for (ec = cards; ec; ec = ec->next) {
int pending;
if (!ec->claimed || ec->irq == NO_IRQ || ec->slot_no == 8)
if (!ec->claimed || ec->irq == NO_IRQ)
continue;
if (ec->ops && ec->ops->irqpending)
......@@ -494,22 +450,15 @@ unsigned int ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
unsigned long address = 0;
int slot = ec->slot_no;
if (ec->slot_no == 8)
return 0;
ectcr &= ~(1 << slot);
switch (type) {
case ECARD_MEMC:
if (slot < 4)
address = IO_EC_MEMC_BASE + (slot << 12);
address = IO_EC_MEMC_BASE + (slot << 12);
break;
case ECARD_IOC:
if (slot < 4)
address = IO_EC_IOC_BASE + (slot << 12);
if (address)
address += speed << 17;
address = IO_EC_IOC_BASE + (slot << 12) + (speed << 17);
break;
default:
......@@ -592,11 +541,9 @@ static void __init ecard_init_resources(struct expansion_card *ec)
unsigned int slot = ec->slot_no;
int i;
if (slot < 4) {
ec_set_resource(ec, ECARD_RES_MEMC,
PODSLOT_MEMC_BASE + (slot << 14),
PODSLOT_MEMC_SIZE, IORESOURCE_MEM);
}
ec_set_resource(ec, ECARD_RES_MEMC,
PODSLOT_MEMC_BASE + (slot << 14),
PODSLOT_MEMC_SIZE, IORESOURCE_MEM);
for (i = 0; i < ECARD_RES_IOCSYNC - ECARD_RES_IOCSLOW; i++) {
ec_set_resource(ec, i + ECARD_RES_IOCSLOW,
......@@ -739,12 +686,10 @@ ecard_probe(int slot, card_type_t type)
/*
* hook the interrupt handlers
*/
if (slot < 8) {
ec->irq = 32 + slot;
set_irq_chip(ec->irq, &ecard_chip);
set_irq_handler(ec->irq, do_level_IRQ);
set_irq_flags(ec->irq, IRQF_VALID);
}
ec->irq = 32 + slot;
set_irq_chip(ec->irq, &ecard_chip);
set_irq_handler(ec->irq, do_level_IRQ);
set_irq_flags(ec->irq, IRQF_VALID);
for (ecp = &cards; *ecp; ecp = &(*ecp)->next);
......@@ -777,7 +722,7 @@ static int __init ecard_init(void)
printk("Probing expansion cards\n");
for (slot = 0; slot < 4; slot ++) {
for (slot = 0; slot < MAX_ECARDS; slot ++) {
ecard_probe(slot, ECARD_IOC);
}
......
This diff is collapsed.
/*
* linux/arch/arm/kernel/head-armo.S
* linux/arch/arm26/kernel/head.S
*
* Copyright (C) 1994-2000 Russell King
* Copyright (C) 2003 Ian Molton
......@@ -22,10 +22,13 @@
*/
.section ".init.text",#alloc,#execinstr
ENTRY(stext)
__entry: cmp pc, #0x02000000
__entry:
cmp pc, #0x02000000
ldrlt pc, LC0 @ if 0x01800000, call at 0x02080000
teq r0, #0 @ Check for old calling method
blne oldparams @ Move page if old
adr r0, LC0
ldmib r0, {r2-r5, sp} @ Setup stack (and fetch other values)
......@@ -49,7 +52,6 @@ __entry: cmp pc, #0x02000000
cmp r4, r5
blt 1b
#endif
mov fp, #0
b start_kernel
......@@ -69,7 +71,7 @@ arm2_id: .long 0x41560200 @ ARM2 and 250 dont have a CPUID
arm250_id: .long 0x41560250 @ So we create some after probing for them
.align
oldparams: mov r4, #0x02000000
oldparams: mov r4, #0x02000000
add r3, r4, #0x00080000
add r4, r4, #0x0007c000
1: ldmia r0!, {r5 - r12}
......
/*
* linux/arch/arm/kernel/init_task.c
* linux/arch/arm26/kernel/init_task.c
*
* Copyright (C) 2003 Ian Molton
*
......@@ -29,7 +29,9 @@ EXPORT_SYMBOL(init_mm);
* We need to make sure that this is 8192-byte aligned due to the
* way process stacks are handled. This is done by making sure
* the linker maps this in the .text segment right after head.S,
* and making head.S ensure the proper alignment.
* and making the linker scripts ensure the proper alignment.
*
* FIXME - should this be 32K alignment on arm26?
*
* The things we do for performance...
*/
......
......@@ -67,42 +67,22 @@ static int __init hlt_setup(char *__unused)
__setup("nohlt", nohlt_setup);
__setup("hlt", hlt_setup);
/*
* The following aren't currently used.
*/
void (*pm_idle)(void);
void (*pm_power_off)(void);
/*
* This is our default idle handler. We need to disable
* interrupts here to ensure we don't miss a wakeup call.
*/
void default_idle(void)
{
local_irq_disable();
if (!need_resched() && !hlt_counter)
local_irq_enable();
}
/*
* The idle thread. We try to conserve power, while trying to keep
* overall latency low. The architecture specific idle is passed
* a value to indicate the level of "idleness" of the system.
*/
void cpu_idle(void)
{
/* endless idle loop with no priority at all */
preempt_disable();
while (1) {
void (*idle)(void) = pm_idle;
if (!idle)
idle = default_idle;
leds_event(led_idle_start);
while (!need_resched())
idle();
leds_event(led_idle_end);
schedule();
while (!need_resched()) {
local_irq_disable();
if (!need_resched() && !hlt_counter)
local_irq_enable();
}
}
schedule();
}
static char reboot_mode = 'h';
......@@ -115,20 +95,15 @@ int __init reboot_setup(char *str)
__setup("reboot=", reboot_setup);
/* ARM26 cant do these but we still need to define them. */
void machine_halt(void)
{
leds_event(led_halted);
}
EXPORT_SYMBOL(machine_halt);
void machine_power_off(void)
{
leds_event(led_halted);
if (pm_power_off)
pm_power_off();
}
EXPORT_SYMBOL(machine_halt);
EXPORT_SYMBOL(machine_power_off);
void machine_restart(char * __unused)
......@@ -306,7 +281,7 @@ void release_thread(struct task_struct *dead_task)
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
int
copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
unsigned long unused, struct task_struct *p, struct pt_regs *regs)
{
struct thread_info *thread = p->thread_info;
......@@ -315,7 +290,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
childregs = __get_user_regs(thread);
*childregs = *regs;
childregs->ARM_r0 = 0;
childregs->ARM_sp = esp;
childregs->ARM_sp = stack_start;
memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
thread->cpu_context.sp = (unsigned long)childregs;
......@@ -367,35 +342,42 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
}
/*
* This is the mechanism for creating a new kernel thread.
*
* NOTE! Only a kernel-only process(ie the swapper or direct descendants
* who haven't done an "execve()") should use this: it will work within
* a system call from a "real" process, but the process memory space will
* not be free'd until both the parent and the child have exited.
* FIXME - taken from arm32
* Shuffle the argument into the correct register before calling the
* thread function. r1 is the thread argument, r2 is the pointer to
* the thread function, and r3 points to the exit function.
* FIXME - make sure this is right - the older code used to zero fp
* and cause the parent to call sys_exit (do_exit in this version)
*/
extern void kernel_thread_helper(void);
asm( ".section .text\n"
" .align\n"
" .type kernel_thread_helper, #function\n"
"kernel_thread_helper:\n"
" mov r0, r1\n"
" mov lr, r3\n"
" mov pc, r2\n"
" .size kernel_thread_helper, . - kernel_thread_helper\n"
" .previous");
/*
* Create a kernel thread.
*/
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
register unsigned int r0 asm("r0") = flags | CLONE_VM | CLONE_UNTRACED;
register unsigned int r1 asm("r1") = 0;
register pid_t __ret asm("r0");
__asm__ __volatile__(
__syscall(clone)" @ kernel_thread sys_clone \n\
movs %0, r0 @ if we are the child \n\
bne 1f \n\
mov fp, #0 @ ensure that fp is zero \n\
mov r0, %4 \n\
mov lr, pc \n\
mov pc, %3 \n\
b sys_exit \n\
1: "
: "=r" (__ret)
: "0" (r0), "r" (r1), "r" (fn), "r" (arg)
: "lr");
return __ret;
struct pt_regs regs;
memset(&regs, 0, sizeof(regs));
regs.ARM_r1 = (unsigned long)arg;
regs.ARM_r2 = (unsigned long)fn;
regs.ARM_r3 = (unsigned long)do_exit;
regs.ARM_pc = (unsigned long)kernel_thread_helper | MODE_SVC26;
return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
}
EXPORT_SYMBOL(kernel_thread);
unsigned long get_wchan(struct task_struct *p)
{
......
......@@ -12,6 +12,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/errno.h>
......@@ -179,7 +180,7 @@ int __down_trylock(struct semaphore * sem)
* registers (r0 to r3 and lr), but not ip, as we use it as a return
* value in some cases..
*/
asm(" .section .sched.text \n\
asm(" .section .sched.text , #alloc, #execinstr \n\
.align 5 \n\
.globl __down_failed \n\
__down_failed: \n\
......@@ -215,3 +216,8 @@ __up_wakeup: \n\
ldmfd sp!, {r0 - r3, pc}^ \n\
");
EXPORT_SYMBOL(__down_failed);
EXPORT_SYMBOL(__down_interruptible_failed);
EXPORT_SYMBOL(__down_trylock_failed);
EXPORT_SYMBOL(__up_wakeup);
/*
* linux/arch/arm/kernel/setup.c
* linux/arch/arm26/kernel/setup.c
*
* Copyright (C) 1995-2001 Russell King
* Copyright (C) 2003 Ian Molton
......@@ -119,7 +119,7 @@ static void __init setup_processor(void)
/*
* locate processor in the list of supported processor
* types. The linker builds this table for us from the
* entries in arch/arm/mm/proc-*.S
* entries in arch/arm26/mm/proc-*.S
*/
for (list = &__proc_info_begin; list < &__proc_info_end ; list++)
if ((processor_id & list->cpu_mask) == list->cpu_val)
......
......@@ -13,6 +13,7 @@
* have a non-standard calling sequence on the Linux/arm
* platform.
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/slab.h>
......@@ -281,3 +282,43 @@ asmlinkage int sys_execve(char *filenamei, char **argv, char **envp, struct pt_r
out:
return error;
}
/* FIXME - see if this is correct for arm26 */
long execve(const char *filename, char **argv, char **envp)
{
struct pt_regs regs;
int ret;
memset(&regs, 0, sizeof(struct pt_regs));
ret = do_execve((char *)filename, (char __user * __user *)argv, (char __user * __user *)envp, &regs);
if (ret < 0)
goto out;
/*
* Save argc to the register structure for userspace.
*/
regs.ARM_r0 = ret;
/*
* We were successful. We won't be returning to our caller, but
* instead to user space by manipulating the kernel stack.
*/
asm( "add r0, %0, %1\n\t"
"mov r1, %2\n\t"
"mov r2, %3\n\t"
"bl memmove\n\t" /* copy regs to top of stack */
"mov r8, #0\n\t" /* not a syscall */
"mov r9, %0\n\t" /* thread structure */
"mov sp, r0\n\t" /* reposition stack pointer */
"b ret_to_user"
:
: "r" (current_thread_info()),
"Ir" (THREAD_SIZE - 8 - sizeof(regs)),
"r" (&regs),
"Ir" (sizeof(regs))
: "r0", "r1", "r2", "r3", "ip", "memory");
out:
return ret;
}
EXPORT_SYMBOL(execve);
/*
* linux/arch/arm/kernel/time-acorn.c
*
* Copyright (c) 1996-2000 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.
*
* Changelog:
* 24-Sep-1996 RMK Created
* 10-Oct-1996 RMK Brought up to date with arch-sa110eval
* 04-Dec-1997 RMK Updated for new arch/arm/time.c
* 13-May-2003 IM Brought over to ARM26
*/
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/ioc.h>
extern unsigned long (*gettimeoffset)(void);
static unsigned long ioctime_gettimeoffset(void)
{
unsigned int count1, count2, status;
long offset;
ioc_writeb (0, IOC_T0LATCH);
barrier ();
count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
barrier ();
status = ioc_readb(IOC_IRQREQA);
barrier ();
ioc_writeb (0, IOC_T0LATCH);
barrier ();
count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
offset = count2;
if (count2 < count1) {
/*
* We have not had an interrupt between reading count1
* and count2.
*/
if (status & (1 << 5))
offset -= LATCH;
} else if (count2 > count1) {
/*
* We have just had another interrupt between reading
* count1 and count2.
*/
offset -= LATCH;
}
offset = (LATCH - offset) * (tick_nsec / 1000);
return (offset + LATCH/2) / LATCH;
}
void __init ioctime_init(void)
{
ioc_writeb(LATCH & 255, IOC_T0LTCHL);
ioc_writeb(LATCH >> 8, IOC_T0LTCHH);
ioc_writeb(0, IOC_T0GO);
gettimeoffset = ioctime_gettimeoffset;
}
......@@ -32,7 +32,7 @@
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/ioc.h>
u64 jiffies_64 = INITIAL_JIFFIES;
......@@ -56,16 +56,53 @@ static int dummy_set_rtc(void)
*/
int (*set_rtc)(void) = dummy_set_rtc;
static unsigned long dummy_gettimeoffset(void)
/*
* Get time offset based on IOCs timer.
* FIXME - if this is called with interrutps off, why the shennanigans
* below ?
*/
static unsigned long gettimeoffset(void)
{
return 0;
unsigned int count1, count2, status;
long offset;
ioc_writeb (0, IOC_T0LATCH);
barrier ();
count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
barrier ();
status = ioc_readb(IOC_IRQREQA);
barrier ();
ioc_writeb (0, IOC_T0LATCH);
barrier ();
count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
offset = count2;
if (count2 < count1) {
/*
* We have not had an interrupt between reading count1
* and count2.
*/
if (status & (1 << 5))
offset -= LATCH;
} else if (count2 > count1) {
/*
* We have just had another interrupt between reading
* count1 and count2.
*/
offset -= LATCH;
}
offset = (LATCH - offset) * (tick_nsec / 1000);
return (offset + LATCH/2) / LATCH;
}
/*
* hook for getting the time offset. Note that it is
* always called with interrupts disabled.
* Scheduler clock - returns current time in nanosec units.
*/
unsigned long (*gettimeoffset)(void) = dummy_gettimeoffset;
unsigned long long sched_clock(void)
{
return (unsigned long long)jiffies * (1000000000 / HZ);
}
static unsigned long next_rtc_update;
......@@ -187,7 +224,10 @@ extern void ioctime_init(void);
*/
void __init time_init(void)
{
ioctime_init();
ioc_writeb(LATCH & 255, IOC_T0LTCHL);
ioc_writeb(LATCH >> 8, IOC_T0LTCHH);
ioc_writeb(0, IOC_T0GO);
setup_irq(IRQ_TIMER, &timer_irq);
}
......
/*
* linux/arch/arm/kernel/traps.c
* linux/arch/arm26/kernel/traps.c
*
* Copyright (C) 1995-2002 Russell King
* Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
......@@ -10,9 +10,11 @@
* published by the Free Software Foundation.
*
* 'traps.c' handles hardware exceptions after we have saved some state in
* 'linux/arch/arm/lib/traps.S'. Mostly a debugging aid, but will probably
* 'linux/arch/arm26/lib/traps.S'. Mostly a debugging aid, but will probably
* kill the offending process.
*/
#include <linux/module.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
......@@ -28,7 +30,6 @@
#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/uaccess.h>
......@@ -134,8 +135,6 @@ static void dump_instr(struct pt_regs *regs)
dump_mem("Stack: ", sp, 8192+(unsigned long)tsk->thread_info);
}
EXPORT_SYMBOL(dump_stack);
void dump_stack(void)
{
#ifdef CONFIG_DEBUG_ERRORS
......@@ -143,6 +142,8 @@ void dump_stack(void)
#endif
}
EXPORT_SYMBOL(dump_stack);
//FIXME - was a static fn
void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
{
......@@ -425,7 +426,6 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
return 0;
case NR(usr26):
case NR(usr32):
break;
default:
......
......@@ -64,6 +64,7 @@ SECTIONS
_text = .; /* Text and read-only data */
*(.text)
SCHED_TEXT
LOCK_TEXT /* FIXME - borrowed from arm32 - check*/
*(.fixup)
*(.gnu.warning)
*(.rodata)
......@@ -91,9 +92,11 @@ SECTIONS
_sdata = .;
.data : {
. = ALIGN(8192);
/*
* first, the init thread union, aligned
* to an 8192 byte boundary.
* to an 8192 byte boundary. (see arm26/kernel/init_task.c)
* FIXME - sould this be 32K aligned on arm26?
*/
*(.init.task)
......
......@@ -65,6 +65,7 @@ SECTIONS
_text = .; /* Text and read-only data */
*(.text)
SCHED_TEXT
LOCK_TEXT
*(.fixup)
*(.gnu.warning)
*(.rodata)
......@@ -90,7 +91,7 @@ SECTIONS
.data : {
/*
* first, the init task union, aligned
* to an 8192 byte boundary.
* to an 8192 byte boundary. (see arm26/kernel/init_task.c)
*/
*(.init.task)
......
#
# linux/arch/arm/lib/Makefile
# linux/arch/arm26/lib/Makefile
#
# Copyright (C) 1995-2000 Russell King
#
......@@ -7,15 +7,15 @@
lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
csumpartialcopy.o csumpartialcopyuser.o clearbit.o \
copy_page.o delay.o findbit.o memchr.o memcpy.o \
memset.o memzero.o setbit.o \
strchr.o strrchr.o testchangebit.o \
memset.o memzero.o setbit.o \
strchr.o strrchr.o testchangebit.o \
testclearbit.o testsetbit.o getuser.o \
putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
ucmpdi2.o udivdi3.o lib1funcs.o ecard.o io-acorn.o \
floppydma.o io-readsb.o io-writesb.o io-writesl.o \
uaccess-kernel.o uaccess-user.o io-readsw-armv3.o \
io-writesw-armv3.o io-readsl-armv3.o ecard.o \
io-acorn.o floppydma.o
uaccess-kernel.o uaccess-user.o io-readsw.o \
io-writesw.o io-readsl.o ecard.o io-acorn.o \
floppydma.o
lib-n :=
......
/*
* linux/arch/arm/lib/backtrace.S
* linux/arch/arm26/lib/backtrace.S
*
* Copyright (C) 1995, 1996 Russell King
*
......
/*
* linux/arch/arm/lib/changebit.S
* linux/arch/arm26/lib/changebit.S
*
* Copyright (C) 1995-1996 Russell King
*
......
/*
* linux/arch/arm/lib/clearbit.S
* linux/arch/arm26/lib/clearbit.S
*
* Copyright (C) 1995-1996 Russell King
*
......
/*
* linux/arch/arm/lib/copypage.S
* linux/arch/arm26/lib/copypage.S
*
* Copyright (C) 1995-1999 Russell King
*
......
/*
* linux/arch/arm/lib/csumipv6.S
* linux/arch/arm26/lib/csumipv6.S
*
* Copyright (C) 1995-1998 Russell King
*
......
/*
* linux/arch/arm/lib/csumpartial.S
* linux/arch/arm26/lib/csumpartial.S
*
* Copyright (C) 1995-1998 Russell King
*
......
/*
* linux/arch/arm/lib/csumpartialcopy.S
* linux/arch/arm26/lib/csumpartialcopy.S
*
* Copyright (C) 1995-1998 Russell King
*
......
/*
* linux/arch/arm/lib/csumpartialcopygeneric.S
* linux/arch/arm26/lib/csumpartialcopygeneric.S
*
* Copyright (C) 1995-2001 Russell King
*
......
/*
* linux/arch/arm/lib/delay.S
* linux/arch/arm26/lib/delay.S
*
* Copyright (C) 1995, 1996 Russell King
*
......
/*
* linux/arch/arm/lib/ecard.S
* linux/arch/arm26/lib/ecard.S
*
* Copyright (C) 1995, 1996 Russell King
*
......
/*
* linux/arch/arm/lib/floppydma.S
* linux/arch/arm26/lib/floppydma.S
*
* Copyright (C) 1995, 1996 Russell King
*
......
/*
* linux/arch/arm/lib/getuser.S
* linux/arch/arm26/lib/getuser.S
*
* Copyright (C) 2001 Russell King
*
......@@ -28,6 +28,7 @@
*/
#include <asm/asm_offsets.h>
#include <asm/thread_info.h>
#include <asm/errno.h>
.global __get_user_1
__get_user_1:
......@@ -98,7 +99,7 @@ __get_user_bad_8:
mov r2, #0
__get_user_bad:
mov r1, #0
mov r0, #-14
mov r0, #-EFAULT
ldmfd sp!, {pc}^
.section __ex_table, "a"
......
/*
* linux/arch/arm/lib/io-acorn.S
* linux/arch/arm26/lib/io-acorn.S
*
* Copyright (C) 1995, 1996 Russell King
*
......
/*
* linux/arch/arm/lib/io-readsb.S
* linux/arch/arm26/lib/io-readsb.S
*
* Copyright (C) 1995-2000 Russell King
*
......
/*
* linux/arch/arm/lib/io-readsl-armv3.S
* linux/arch/arm26/lib/io-readsl.S
*
* Copyright (C) 1995-2000 Russell King
*
......
/*
* linux/arch/arm/lib/io-readsw-armv3.S
* linux/arch/arm26/lib/io-readsw.S
*
* Copyright (C) 1995-2000 Russell King
*
......
/*
* linux/arch/arm/lib/io-writesb.S
* linux/arch/arm26/lib/io-writesb.S
*
* Copyright (C) 1995-2000 Russell King
*
......
/*
* linux/arch/arm/lib/io-writesl.S
* linux/arch/arm26/lib/io-writesl.S
*
* Copyright (C) 1995-2000 Russell King
*
......
/*
* linux/arch/arm/lib/io-writesw-armv3.S
* linux/arch/arm26/lib/io-writesw.S
*
* Copyright (C) 1995-2000 Russell King
*
......
/*
* linux/arch/arm/lib/memchr.S
* linux/arch/arm26/lib/memchr.S
*
* Copyright (C) 1995-2000 Russell King
*
......
/*
* linux/arch/arm/lib/memcpy.S
* linux/arch/arm26/lib/memcpy.S
*
* Copyright (C) 1995-1999 Russell King
*
......
/*
* linux/arch/arm/lib/memset.S
* linux/arch/arm26/lib/memset.S
*
* Copyright (C) 1995-2000 Russell King
*
......
/*
* linux/arch/arm/lib/memzero.S
* linux/arch/arm26/lib/memzero.S
*
* Copyright (C) 1995-2000 Russell King
*
......
/*
* linux/arch/arm/lib/putuser.S
* linux/arch/arm26/lib/putuser.S
*
* Copyright (C) 2001 Russell King
*
......@@ -28,6 +28,7 @@
*/
#include <asm/asm_offsets.h>
#include <asm/thread_info.h>
#include <asm/errno.h>
.global __put_user_1
__put_user_1:
......@@ -95,7 +96,7 @@ __put_user_8:
ldmfd sp!, {pc}^
__put_user_bad:
mov r0, #-14
mov r0, #-EFAULT
mov pc, lr
.section __ex_table, "a"
......
/*
* linux/arch/arm/lib/setbit.S
* linux/arch/arm26/lib/setbit.S
*
* Copyright (C) 1995-1996 Russell King
*
......
/*
* linux/arch/arm/lib/strchr.S
* linux/arch/arm26/lib/strchr.S
*
* Copyright (C) 1995-2000 Russell King
*
......
/*
* linux/arch/arm/lib/strrchr.S
* linux/arch/arm26/lib/strrchr.S
*
* Copyright (C) 1995-2000 Russell King
*
......
/*
* linux/arch/arm/lib/testchangebit.S
* linux/arch/arm26/lib/testchangebit.S
*
* Copyright (C) 1995-1996 Russell King
*
......
/*
* linux/arch/arm/lib/testclearbit.S
* linux/arch/arm26/lib/testclearbit.S
*
* Copyright (C) 1995-1996 Russell King
*
......
/*
* linux/arch/arm/lib/testsetbit.S
* linux/arch/arm26/lib/testsetbit.S
*
* Copyright (C) 1995-1996 Russell King
*
......
......@@ -4,9 +4,5 @@
# Object file lists.
obj-y := dma.o irq.o oldlatches.o \
small_page.o
obj-y := dma.o irq.o latches.o
extra-y := head.o
AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR)
/*
* linux/arch/arm/kernel/dma-arc.c
* linux/arch/arm26/kernel/dma.c
*
* Copyright (C) 1998-1999 Dave Gilbert / Russell King
* Copyright (C) 2003 Ian Molton
......
/*
* linux/arch/arm/mach-arc/irq.c
* linux/arch/arm26/mach-arc/irq.c
*
* Copyright (C) 1996 Russell King
*
......
/*
* linux/arch/arm/kernel/oldlatches.c
* linux/arch/arm26/kernel/latches.c
*
* Copyright (C) David Alan Gilbert 1995/1996,2000
* Copyright (C) Ian Molton 2003
......@@ -46,7 +46,7 @@ void oldlatch_bupdate(unsigned char mask,unsigned char newdata)
unsigned long flags;
BUG_ON(!machine_is_archimedes());
local_irq_save(flags);//FIXME: was local_save_flags
latch_b_copy = (latch_b_copy & ~mask) | newdata;
......
......@@ -2,4 +2,5 @@
# Makefile for the linux arm26-specific parts of the memory manager.
#
obj-y := init.o extable.o proc-funcs.o mm-memc.o fault.o
obj-y := init.o extable.o proc-funcs.o memc.o fault.o \
small_page.o
/*
* linux/arch/arm/mm/extable.c
* linux/arch/arm26/mm/extable.c
*/
#include <linux/config.h>
......@@ -11,6 +11,12 @@ int fixup_exception(struct pt_regs *regs)
const struct exception_table_entry *fixup;
fixup = search_exception_tables(instruction_pointer(regs));
/*
* The kernel runs in SVC mode - make sure we keep running in SVC mode
* by frobbing the PSR appropriately (PSR and PC are in the same reg.
* on ARM26)
*/
if (fixup)
regs->ARM_pc = fixup->fixup | PSR_I_BIT | MODE_SVC26;
......
/*
* linux/arch/arm/mm/fault-common.c
* linux/arch/arm26/mm/fault.c
*
* Copyright (C) 1995 Linus Torvalds
* Modifications for ARM processor (c) 1995-2001 Russell King
......@@ -212,7 +212,6 @@ int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
tsk = current;
mm = tsk->mm;
printk("do_page_fault: pid: %d %08x\n", tsk->pid, addr);
/*
* If we're in an interrupt or have no user
* context, we must not take the fault..
......
/*
* linux/arch/arm/mm/init.c
* linux/arch/arm26/mm/init.c
*
* Copyright (C) 1995-2002 Russell King
*
......@@ -26,7 +26,6 @@
#include <asm/segment.h>
#include <asm/mach-types.h>
#include <asm/pgalloc.h>
#include <asm/dma.h>
#include <asm/hardware.h>
#include <asm/setup.h>
......@@ -84,7 +83,7 @@ void show_mem(void)
else if (!page_count(page))
free++;
else
shared += atomic_read(&page->count) - 1;
shared += page_count(page) - 1;
page++;
} while (page < end);
......
/*
* linux/arch/arm/mm/mm-armo.c
* linux/arch/arm26/mm/memc.c
*
* Copyright (C) 1998-2000 Russell King
*
......
/*
* linux/arch/arm/mm/proc-arm2,3.S
* linux/arch/arm26/mm/proc-arm2,3.S
*
* Copyright (C) 1997-1999 Russell King
*
......
/*
* linux/arch/arm/mm/small_page.c
* linux/arch/arm26/mm/small_page.c
*
* Copyright (C) 1996 Russell King
* Copyright (C) 2003 Ian Molton
......@@ -12,6 +12,8 @@
* 26/01/1996 RMK Cleaned up various areas to make little more generic
* 07/02/1999 RMK Support added for 16K and 32K page sizes
* containing 8K blocks
* 23/05/2004 IM Fixed to use struct page->lru (thanks wli)
*
*/
#include <linux/signal.h>
#include <linux/sched.h>
......@@ -36,6 +38,7 @@
* granularity than the page size. This is typically used for the
* second level page tables on 32-bit ARMs.
*
* FIXME - this comment is *out of date*
* Theory:
* We "misuse" the Linux memory management system. We use alloc_page
* to allocate a page and then mark it as reserved. The Linux memory
......@@ -86,7 +89,7 @@ static unsigned long __get_small_page(int priority, struct order *order)
if (list_empty(&order->queue))
goto need_new_page;
page = list_entry(order->queue.next, struct page, list);
page = list_entry(order->queue.next, struct page, lru);
again:
#ifdef PEDANTIC
if (USED_MAP(page) & ~order->all_used)
......
......@@ -289,6 +289,21 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_utimes)
.long SYMBOL_NAME(sys_fadvise64_64)
.long SYMBOL_NAME(sys_ni_syscall) /* sys_vserver */
.long SYMBOL_NAME(sys_mbind)
.long SYMBOL_NAME(sys_get_mempolicy)
.long SYMBOL_NAME(sys_set_mempolicy)
.long SYMBOL_NAME(sys_mq_open)
.long SYMBOL_NAME(sys_mq_unlink)
.long SYMBOL_NAME(sys_mq_timedsend)
.long SYMBOL_NAME(sys_mq_timedreceive) /* 280 */
.long SYMBOL_NAME(sys_mq_notify)
.long SYMBOL_NAME(sys_mq_getsetattr)
.long SYMBOL_NAME(sys_ni_syscall) /* reserved for kexec */
.long SYMBOL_NAME(sys_waitid)
.long SYMBOL_NAME(sys_ni_syscall) /* 285 */ /* available */
.long SYMBOL_NAME(sys_add_key)
.long SYMBOL_NAME(sys_request_key)
.long SYMBOL_NAME(sys_keyctl)
.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
.long SYMBOL_NAME(sys_ni_syscall)
......
......@@ -162,7 +162,9 @@ ramdisk_max: .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
# the contents of an initrd
trampoline: call start_of_setup
.space 1024
.align 16
# The offset at this point is 0x240
.space (0x7ff-0x240+1) # E820 & EDD space (ending at 0x7ff)
# End of setup header #####################################################
start_of_setup:
......
......@@ -810,13 +810,16 @@ acpi_process_madt(void)
}
/*
* acpi_boot_init()
* acpi_boot_table_init() and acpi_boot_init()
* called from setup_arch(), always.
* 1. checksums all tables
* 2. enumerates lapics
* 3. enumerates io-apics
*
* side effects:
* acpi_table_init() is separate to allow reading SRAT without
* other side effects.
*
* side effects of acpi_boot_init:
* acpi_lapic = 1 if LAPIC found
* acpi_ioapic = 1 if IOAPIC found
* if (acpi_lapic && acpi_ioapic) smp_found_config = 1;
......@@ -830,7 +833,7 @@ acpi_process_madt(void)
*/
int __init
acpi_boot_init (void)
acpi_boot_table_init(void)
{
int error;
......@@ -872,6 +875,21 @@ acpi_boot_init (void)
}
}
return 0;
}
int __init acpi_boot_init(void)
{
/*
* If acpi_disabled, bail out
* One exception: acpi=ht continues far enough to enumerate LAPICs
*/
if (acpi_disabled && !acpi_ht)
return 1;
acpi_table_parse(ACPI_BOOT, acpi_parse_sbf);
/*
* set sci_int and PM timer address
*/
......
......@@ -334,21 +334,19 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
generic_identify(c);
printk(KERN_DEBUG "CPU: After generic identify, caps: %08lx %08lx %08lx %08lx\n",
c->x86_capability[0],
c->x86_capability[1],
c->x86_capability[2],
c->x86_capability[3]);
printk(KERN_DEBUG "CPU: After generic identify, caps:");
for (i = 0; i < NCAPINTS; i++)
printk(" %08lx", c->x86_capability[i]);
printk("\n");
if (this_cpu->c_identify) {
this_cpu->c_identify(c);
printk(KERN_DEBUG "CPU: After vendor identify, caps: %08lx %08lx %08lx %08lx\n",
c->x86_capability[0],
c->x86_capability[1],
c->x86_capability[2],
c->x86_capability[3]);
}
printk(KERN_DEBUG "CPU: After vendor identify, caps:");
for (i = 0; i < NCAPINTS; i++)
printk(" %08lx", c->x86_capability[i]);
printk("\n");
}
/*
* Vendor-specific initialization. In this section we
......@@ -398,11 +396,10 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
/* Now the feature flags better reflect actual CPU features! */
printk(KERN_DEBUG "CPU: After all inits, caps: %08lx %08lx %08lx %08lx\n",
c->x86_capability[0],
c->x86_capability[1],
c->x86_capability[2],
c->x86_capability[3]);
printk(KERN_DEBUG "CPU: After all inits, caps:");
for (i = 0; i < NCAPINTS; i++)
printk(" %08lx", c->x86_capability[i]);
printk("\n");
/*
* On SMP, boot_cpu_data holds the common feature set between
......
......@@ -128,9 +128,6 @@ ENTRY(startup_32_smp)
movl %eax,%fs
movl %eax,%gs
xorl %ebx,%ebx
incl %ebx /* This is a secondary processor (AP) */
/*
* New page tables may be in 4Mbyte page mode and may
* be using the global pages.
......@@ -148,7 +145,7 @@ ENTRY(startup_32_smp)
#define cr4_bits mmu_cr4_features-__PAGE_OFFSET
movl cr4_bits,%edx
andl %edx,%edx
jz 3f
jz 6f
movl %cr4,%eax # Turn on paging options (PSE,PAE,..)
orl %edx,%eax
movl %eax,%cr4
......@@ -176,9 +173,10 @@ ENTRY(startup_32_smp)
wrmsr
6:
/* cpuid clobbered ebx, set it up again: */
/* This is a secondary processor (AP) */
xorl %ebx,%ebx
incl %ebx
3:
#endif /* CONFIG_SMP */
......
......@@ -97,6 +97,9 @@ unsigned int mca_pentium_flag;
/* For PCI or other memory-mapped resources */
unsigned long pci_mem_start = 0x10000000;
/* Boot loader ID as an integer, for the benefit of proc_dointvec */
int bootloader_type;
/* user-defined highmem size */
static unsigned int highmem_pages = -1;
......@@ -737,6 +740,10 @@ static void __init parse_cmdline_early (char ** cmdline_p)
}
}
else if (!memcmp(from, "noexec=", 7))
noexec_setup(from + 7);
#ifdef CONFIG_X86_SMP
/*
* If the BIOS enumerates physical processors before logical,
......@@ -1338,6 +1345,7 @@ void __init setup_arch(char **cmdline_p)
BIOS_revision = SYS_DESC_TABLE.table[2];
}
aux_device_present = AUX_DEVICE_INFO;
bootloader_type = LOADER_TYPE;
#ifdef CONFIG_BLK_DEV_RAM
rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
......@@ -1413,6 +1421,7 @@ void __init setup_arch(char **cmdline_p)
/*
* Parse the ACPI tables for possible boot-time SMP configuration.
*/
acpi_boot_table_init();
acpi_boot_init();
#ifdef CONFIG_X86_LOCAL_APIC
......
......@@ -51,8 +51,14 @@ r_base = .
movl $0xA5A5A5A5, trampoline_data - r_base
# write marker for master knows we're running
lidt boot_idt - r_base # load idt with 0, 0
lgdt boot_gdt - r_base # load gdt with whatever is appropriate
/* 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
* operand size is 16bit. Use lgdtl instead to force operand size
* to 32 bit.
*/
lidtl boot_idt - r_base # load idt with 0, 0
lgdtl boot_gdt - r_base # load gdt with whatever is appropriate
xor %ax, %ax
inc %ax # protected mode (PE) bit
......
......@@ -464,11 +464,6 @@ void __init set_highmem_pages_init(int bad_ppro)
void __init set_max_mapnr_init(void)
{
#ifdef CONFIG_HIGHMEM
struct zone *high0 = &NODE_DATA(0)->node_zones[ZONE_HIGHMEM];
if (high0->spanned_pages > 0)
highmem_start_page = high0->zone_mem_map;
else
highmem_start_page = pfn_to_page(max_low_pfn - 1) + 1;
num_physpages = highend_pfn;
#else
num_physpages = max_low_pfn;
......
......@@ -3,7 +3,7 @@
void *kmap(struct page *page)
{
might_sleep();
if (page < highmem_start_page)
if (!PageHighMem(page))
return page_address(page);
return kmap_high(page);
}
......@@ -12,7 +12,7 @@ void kunmap(struct page *page)
{
if (in_interrupt())
BUG();
if (page < highmem_start_page)
if (!PageHighMem(page))
return;
kunmap_high(page);
}
......@@ -32,7 +32,7 @@ void *kmap_atomic(struct page *page, enum km_type type)
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
inc_preempt_count();
if (page < highmem_start_page)
if (!PageHighMem(page))
return page_address(page);
idx = type + KM_TYPE_NR*smp_processor_id();
......
......@@ -130,7 +130,7 @@ static void __init page_table_range_init (unsigned long start, unsigned long end
static inline int is_kernel_text(unsigned long addr)
{
if (addr >= (unsigned long)_stext && addr <= (unsigned long)__init_end)
if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
return 1;
return 0;
}
......@@ -430,7 +430,7 @@ u64 __supported_pte_mask = ~_PAGE_NX;
* on Enable
* off Disable
*/
static int __init noexec_setup(char *str)
void __init noexec_setup(const char *str)
{
if (!strncmp(str, "on",2) && cpu_has_nx) {
__supported_pte_mask |= _PAGE_NX;
......@@ -439,11 +439,8 @@ static int __init noexec_setup(char *str)
disable_nx = 1;
__supported_pte_mask &= ~_PAGE_NX;
}
return 1;
}
__setup("noexec=", noexec_setup);
int nx_enabled = 0;
#ifdef CONFIG_X86_PAE
......@@ -555,7 +552,6 @@ void __init test_wp_bit(void)
static void __init set_max_mapnr_init(void)
{
#ifdef CONFIG_HIGHMEM
highmem_start_page = pfn_to_page(highstart_pfn);
max_mapnr = num_physpages = highend_pfn;
#else
max_mapnr = num_physpages = max_low_pfn;
......
......@@ -135,7 +135,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
/*
* Don't allow anybody to remap normal RAM that we're using..
*/
if (phys_addr < virt_to_phys(high_memory)) {
if (phys_addr <= virt_to_phys(high_memory - 1)) {
char *t_addr, *t_end;
struct page *page;
......@@ -202,7 +202,7 @@ void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)
/* Guaranteed to be > phys_addr, as per __ioremap() */
last_addr = phys_addr + size - 1;
if (last_addr < virt_to_phys(high_memory)) {
if (last_addr < virt_to_phys(high_memory) - 1) {
struct page *ppage = virt_to_page(__va(phys_addr));
unsigned long npages;
......@@ -237,7 +237,7 @@ void iounmap(volatile void __iomem *addr)
return;
}
if (p->flags && p->phys_addr < virt_to_phys(high_memory)) {
if (p->flags && p->phys_addr < virt_to_phys(high_memory) - 1) {
change_page_attr(virt_to_page(__va(p->phys_addr)),
p->size >> PAGE_SHIFT,
PAGE_KERNEL);
......
......@@ -111,10 +111,7 @@ __change_page_attr(struct page *page, pgprot_t prot)
unsigned long address;
struct page *kpte_page;
#ifdef CONFIG_HIGHMEM
if (page >= highmem_start_page)
BUG();
#endif
BUG_ON(PageHighMem(page));
address = (unsigned long)page_address(page);
kpte = lookup_address(address);
......
......@@ -20,9 +20,13 @@ config GENERIC_ISA_DMA
bool
default y
#config GENERIC_HARDIRQS
# bool
# default y
config GENERIC_HARDIRQS
bool
default y
config GENERIC_IRQ_PROBE
bool
default y
source "init/Kconfig"
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
* linux/arch/m32r/kernel/ptrace.c
*
* Copyright (C) 2002 Hirokazu Takata, Takeo Takahashi
* Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org>
* Copyright (C) 2004 Hirokazu Takata, Kei Sakamoto
*
* Original x86 implementation:
* By Ross Biro 1/23/92
......@@ -450,13 +450,13 @@ register_debug_trap(struct task_struct *child, unsigned long next_pc,
struct debug_trap *p = &child->thread.debug_trap;
unsigned long addr = next_pc & ~3;
if (p->nr_trap != 0) {
if (p->nr_trap == MAX_TRAPS) {
printk("kernel BUG at %s %d: p->nr_trap = %d\n",
__FILE__, __LINE__, p->nr_trap);
return -1;
}
p->addr = addr;
p->insn = next_insn;
p->addr[p->nr_trap] = addr;
p->insn[p->nr_trap] = next_insn;
p->nr_trap++;
if (next_pc & 3) {
*code = (next_insn & 0xffff0000) | 0x10f1;
......@@ -473,35 +473,34 @@ register_debug_trap(struct task_struct *child, unsigned long next_pc,
return 0;
}
int withdraw_debug_trap_for_signal(struct task_struct *child)
{
struct debug_trap *p = &child->thread.debug_trap;
int nr_trap = p->nr_trap;
if (nr_trap) {
access_process_vm(child, p->addr, &p->insn, sizeof(p->insn), 1);
p->nr_trap = 0;
p->addr = 0;
p->insn = 0;
}
return nr_trap;
}
static int
unregister_debug_trap(struct task_struct *child, unsigned long addr,
unsigned long *code)
{
struct debug_trap *p = &child->thread.debug_trap;
int i;
if (p->nr_trap != 1 || p->addr != addr) {
/* Search debug trap entry. */
for (i = 0; i < p->nr_trap; i++) {
if (p->addr[i] == addr)
break;
}
if (i >= p->nr_trap) {
/* The trap may be requested from debugger.
* ptrace should do nothing in this case.
*/
return 0;
}
*code = p->insn;
p->insn = 0;
p->addr = 0;
/* Recover orignal instruction code. */
*code = p->insn[i];
/* Shift debug trap entries. */
while (i < p->nr_trap - 1) {
p->insn[i] = p->insn[i + 1];
p->addr[i] = p->addr[i + 1];
i++;
}
p->nr_trap--;
return 1;
}
......@@ -510,13 +509,11 @@ static void
unregister_all_debug_traps(struct task_struct *child)
{
struct debug_trap *p = &child->thread.debug_trap;
int i;
if (p->nr_trap) {
access_process_vm(child, p->addr, &p->insn, sizeof(p->insn), 1);
p->addr = 0;
p->insn = 0;
p->nr_trap = 0;
}
for (i = 0; i < p->nr_trap; i++)
access_process_vm(child, p->addr[i], &p->insn[i], sizeof(p->insn[i]), 1);
p->nr_trap = 0;
}
static inline void
......@@ -575,34 +572,6 @@ embed_debug_trap(struct task_struct *child, unsigned long next_pc)
return 0; /* success */
}
void
embed_debug_trap_for_signal(struct task_struct *child)
{
unsigned long next_pc;
unsigned long pc, insn;
int ret;
pc = get_stack_long(child, PT_BPC);
ret = access_process_vm(child, pc&~3, &insn, sizeof(insn), 0);
if (ret != sizeof(insn)) {
printk("kernel BUG at %s %d: access_process_vm returns %d\n",
__FILE__, __LINE__, ret);
return;
}
compute_next_pc(insn, pc, &next_pc, child);
if (next_pc & 0x80000000) {
printk("kernel BUG at %s %d: next_pc = 0x%08x\n",
__FILE__, __LINE__, (int)next_pc);
return;
}
if (embed_debug_trap(child, next_pc)) {
printk("kernel BUG at %s %d: embed_debug_trap error\n",
__FILE__, __LINE__);
return;
}
invalidate_cache();
}
void
withdraw_debug_trap(struct pt_regs *regs)
{
......@@ -621,9 +590,12 @@ static void
init_debug_traps(struct task_struct *child)
{
struct debug_trap *p = &child->thread.debug_trap;
int i;
p->nr_trap = 0;
p->addr = 0;
p->insn = 0;
for (i = 0; i < MAX_TRAPS; i++) {
p->addr[i] = 0;
p->insn[i] = 0;
}
}
......@@ -855,4 +827,3 @@ void do_syscall_trace(void)
current->exit_code = 0;
}
}
......@@ -2,13 +2,12 @@
* linux/arch/m32r/mm/fault.c
*
* Copyright (c) 2001, 2002 Hitoshi Yamamoto, and H. Kondo
* Copyright (c) 2004 Naoto Sugai, NIIBE Yutaka
*
* Some code taken from i386 version.
* Copyright (C) 1995 Linus Torvalds
*/
/* $Id$ */
#include <linux/config.h>
#include <linux/signal.h>
#include <linux/sched.h>
......@@ -96,6 +95,11 @@ void bust_spinlocks(int yes)
* bit 2 == 0 means kernel, 1 means user-mode
* bit 3 == 0 means data, 1 means instruction
*======================================================================*/
#define ACE_PROTECTION 1
#define ACE_WRITE 2
#define ACE_USERMODE 4
#define ACE_INSTRUCTION 8
asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
unsigned long address)
{
......@@ -126,10 +130,10 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
* nothing more.
*
* This verifies that the fault happens in kernel space
* (error_code & 4) == 0, and that the fault was not a
* protection error (error_code & 1) == 0.
* (error_code & ACE_USERMODE) == 0, and that the fault was not a
* protection error (error_code & ACE_PROTECTION) == 0.
*/
if (address >= TASK_SIZE && !(error_code & 4))
if (address >= TASK_SIZE && !(error_code & ACE_USERMODE))
goto vmalloc_fault;
mm = tsk->mm;
......@@ -157,7 +161,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
* thus avoiding the deadlock.
*/
if (!down_read_trylock(&mm->mmap_sem)) {
if ((error_code & 4) == 0 &&
if ((error_code & ACE_USERMODE) == 0 &&
!search_exception_tables(regs->psw))
goto bad_area_nosemaphore;
down_read(&mm->mmap_sem);
......@@ -171,7 +175,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
#if 0
if (error_code & 4) {
if (error_code & ACE_USERMODE) {
/*
* accessing the stack below "spu" is always a bug.
* The "+ 4" is there due to the push instruction
......@@ -191,27 +195,34 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
good_area:
info.si_code = SEGV_ACCERR;
write = 0;
switch (error_code & 3) {
switch (error_code & (ACE_WRITE|ACE_PROTECTION)) {
default: /* 3: write, present */
/* fall through */
case 2: /* write, not present */
case ACE_WRITE: /* write, not present */
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
write++;
break;
case 1: /* read, present */
case ACE_PROTECTION: /* read, present */
case 0: /* read, not present */
if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
}
/*
* For instruction access exception, check if the area is executable
*/
if ((error_code & ACE_INSTRUCTION) && !(vma->vm_flags & VM_EXEC))
goto bad_area;
survive:
/*
* If for any reason at all we couldn't handle the fault,
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
addr = (address & PAGE_MASK) | (error_code & 8);
addr = (address & PAGE_MASK);
set_thread_fault_code(error_code);
switch (handle_mm_fault(mm, vma, addr, write)) {
case VM_FAULT_MINOR:
tsk->min_flt++;
......@@ -226,7 +237,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
default:
BUG();
}
set_thread_fault_code(0);
up_read(&mm->mmap_sem);
return;
......@@ -239,7 +250,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
bad_area_nosemaphore:
/* User mode accesses just cause a SIGSEGV */
if (error_code & 4) {
if (error_code & ACE_USERMODE) {
tsk->thread.address = address;
tsk->thread.error_code = error_code | (address >= TASK_SIZE);
tsk->thread.trap_no = 14;
......@@ -295,7 +306,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
goto survive;
}
printk("VM: killing process %s\n", tsk->comm);
if (error_code & 4)
if (error_code & ACE_USERMODE)
do_exit(SIGKILL);
goto no_context;
......@@ -303,7 +314,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
up_read(&mm->mmap_sem);
/* Kernel mode? Handle exception or die */
if (!(error_code & 4))
if (!(error_code & ACE_USERMODE))
goto no_context;
tsk->thread.address = address;
......@@ -352,7 +363,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
if (!pte_present(*pte_k))
goto no_context;
addr = (address & PAGE_MASK) | (error_code & 8);
addr = (address & PAGE_MASK) | (error_code & ACE_INSTRUCTION);
update_mmu_cache(NULL, addr, *pte_k);
return;
}
......@@ -370,7 +381,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr,
unsigned long *entry1, *entry2;
unsigned long pte_data, flags;
unsigned int *entry_dat;
int inst = vaddr & 8;
int inst = get_thread_fault_code() & ACE_INSTRUCTION;
int i;
/* Ptrace may call this routine. */
......
......@@ -8,7 +8,7 @@ void *__kmap(struct page *page)
void *addr;
might_sleep();
if (page < highmem_start_page)
if (!PageHighMem(page))
return page_address(page);
addr = kmap_high(page);
flush_tlb_one((unsigned long)addr);
......@@ -20,7 +20,7 @@ void __kunmap(struct page *page)
{
if (in_interrupt())
BUG();
if (page < highmem_start_page)
if (!PageHighMem(page))
return;
kunmap_high(page);
}
......@@ -41,7 +41,7 @@ void *__kmap_atomic(struct page *page, enum km_type type)
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
inc_preempt_count();
if (page < highmem_start_page)
if (!PageHighMem(page))
return page_address(page);
idx = type + KM_TYPE_NR*smp_processor_id();
......
......@@ -204,7 +204,6 @@ void __init mem_init(void)
unsigned long tmp, ram;
#ifdef CONFIG_HIGHMEM
highmem_start_page = mem_map + highstart_pfn;
#ifdef CONFIG_DISCONTIGMEM
#error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet"
#endif
......
......@@ -97,6 +97,11 @@ config PTE_64BIT
depends on 44x
default y
config PHYS_64BIT
bool
depends on 44x
default y
config ALTIVEC
bool "AltiVec Support"
depends on 6xx || POWER4
......@@ -500,21 +505,41 @@ config APUS
More information is available at:
<http://linux-apus.sourceforge.net/>.
config KATANA
bool "Artesyn-Katana"
help
Select KATANA if configuring an Artesyn KATANA 750i or 3750
cPCI board.
config WILLOW
bool "Cogent-Willow"
config CPCI690
bool "Force-CPCI690"
help
Select CPCI690 if configuring a Force CPCI690 cPCI board.
config PCORE
bool "Force-PowerCore"
config POWERPMC250
bool "Force-PowerPMC250"
config EV64260
bool "Galileo-EV-64260-BP"
config CHESTNUT
bool "IBM 750FX Eval board or 750GX Eval board"
help
Select CHESTNUT if configuring an IBM 750FX Eval Board or a
IBM 750GX Eval board.
config SPRUCE
bool "IBM-Spruce"
config EV64260
bool "Marvell-EV64260BP"
help
Select EV64260 if configuring a Marvell (formerly Galileo)
EV64260BP Evaluation platform.
config LOPEC
bool "Motorola-LoPEC"
......@@ -679,7 +704,8 @@ config PPC_OF
config PPC_GEN550
bool
depends on SANDPOINT || MCPN765 || SPRUCE || PPLUS || PCORE || \
PRPMC750 || K2 || PRPMC800 || LOPEC
PRPMC750 || K2 || PRPMC800 || LOPEC || \
(EV64260 && !SERIAL_MPSC) || CHESTNUT
default y
config FORCE
......@@ -689,9 +715,53 @@ config FORCE
config GT64260
bool
depends on EV64260
depends on EV64260 || CPCI690
default y
config MV64360
bool
depends on KATANA
default y
config MV64360
bool
depends on CHESTNUT
default y
config MV64X60
bool
depends on (GT64260 || MV64360)
default y
menu "Set bridge options"
depends on MV64X60
config NOT_COHERENT_CACHE
bool "Turn off Cache Coherency"
default n
help
Some 64x60 bridges lock up when trying to enforce cache coherency.
When this option is selected, cache coherency will be turned off.
Note that this can cause other problems (e.g., stale data being
speculatively loaded via a cached mapping). Use at your own risk.
config MV64X60_BASE
hex "Set bridge base used by firmware"
default "0xf1000000"
help
A firmware can leave the base address of the bridge's registers at
a non-standard location. If so, set this value to reflect the
address of that non-standard location.
config MV64X60_NEW_BASE
hex "Set bridge base used by kernel"
default "0xf1000000"
help
If the current base address of the bridge's registers is not where
you want it, set this value to the address that you want it moved to.
endmenu
config NONMONARCH_SUPPORT
bool "Enable Non-Monarch Support"
depends on PRPMC800
......
......@@ -42,6 +42,9 @@ cpu-as-$(CONFIG_E500) += -Wa,-me500
AFLAGS += $(cpu-as-y)
CFLAGS += $(cpu-as-y)
# Default to the common case.
KBUILD_DEFCONFIG := common_defconfig
head-y := arch/ppc/kernel/head.o
head-$(CONFIG_8xx) := arch/ppc/kernel/head_8xx.o
head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o
......@@ -68,7 +71,7 @@ BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
.PHONY: $(BOOT_TARGETS)
all: zImage
all: uImage zImage
CPPFLAGS_vmlinux.lds := -Upowerpc
......
/*
* drivers/serial/mpsc/mpsc_defs.h
*
* Register definitions for the Marvell Multi-Protocol Serial Controller (MPSC),
* Serial DMA Controller (SDMA), and Baud Rate Generator (BRG).
*
* Author: Mark A. Greer <mgreer@mvista.com>
*
* 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 _PPC_BOOT_MPSC_DEFS_H__
#define _PPC_BOOT_MPSC_DEFS_H__
#define MPSC_NUM_CTLRS 2
/*
*****************************************************************************
*
* Multi-Protocol Serial Controller Interface Registers
*
*****************************************************************************
*/
/* Main Configuratino Register Offsets */
#define MPSC_MMCRL 0x0000
#define MPSC_MMCRH 0x0004
#define MPSC_MPCR 0x0008
#define MPSC_CHR_1 0x000c
#define MPSC_CHR_2 0x0010
#define MPSC_CHR_3 0x0014
#define MPSC_CHR_4 0x0018
#define MPSC_CHR_5 0x001c
#define MPSC_CHR_6 0x0020
#define MPSC_CHR_7 0x0024
#define MPSC_CHR_8 0x0028
#define MPSC_CHR_9 0x002c
#define MPSC_CHR_10 0x0030
#define MPSC_CHR_11 0x0034
#define MPSC_MPCR_CL_5 0
#define MPSC_MPCR_CL_6 1
#define MPSC_MPCR_CL_7 2
#define MPSC_MPCR_CL_8 3
#define MPSC_MPCR_SBL_1 0
#define MPSC_MPCR_SBL_2 3
#define MPSC_CHR_2_TEV (1<<1)
#define MPSC_CHR_2_TA (1<<7)
#define MPSC_CHR_2_TTCS (1<<9)
#define MPSC_CHR_2_REV (1<<17)
#define MPSC_CHR_2_RA (1<<23)
#define MPSC_CHR_2_CRD (1<<25)
#define MPSC_CHR_2_EH (1<<31)
#define MPSC_CHR_2_PAR_ODD 0
#define MPSC_CHR_2_PAR_SPACE 1
#define MPSC_CHR_2_PAR_EVEN 2
#define MPSC_CHR_2_PAR_MARK 3
/* MPSC Signal Routing */
#define MPSC_MRR 0x0000
#define MPSC_RCRR 0x0004
#define MPSC_TCRR 0x0008
/*
*****************************************************************************
*
* Serial DMA Controller Interface Registers
*
*****************************************************************************
*/
#define SDMA_SDC 0x0000
#define SDMA_SDCM 0x0008
#define SDMA_RX_DESC 0x0800
#define SDMA_RX_BUF_PTR 0x0808
#define SDMA_SCRDP 0x0810
#define SDMA_TX_DESC 0x0c00
#define SDMA_SCTDP 0x0c10
#define SDMA_SFTDP 0x0c14
#define SDMA_DESC_CMDSTAT_PE (1<<0)
#define SDMA_DESC_CMDSTAT_CDL (1<<1)
#define SDMA_DESC_CMDSTAT_FR (1<<3)
#define SDMA_DESC_CMDSTAT_OR (1<<6)
#define SDMA_DESC_CMDSTAT_BR (1<<9)
#define SDMA_DESC_CMDSTAT_MI (1<<10)
#define SDMA_DESC_CMDSTAT_A (1<<11)
#define SDMA_DESC_CMDSTAT_AM (1<<12)
#define SDMA_DESC_CMDSTAT_CT (1<<13)
#define SDMA_DESC_CMDSTAT_C (1<<14)
#define SDMA_DESC_CMDSTAT_ES (1<<15)
#define SDMA_DESC_CMDSTAT_L (1<<16)
#define SDMA_DESC_CMDSTAT_F (1<<17)
#define SDMA_DESC_CMDSTAT_P (1<<18)
#define SDMA_DESC_CMDSTAT_EI (1<<23)
#define SDMA_DESC_CMDSTAT_O (1<<31)
#define SDMA_DESC_DFLT (SDMA_DESC_CMDSTAT_O | \
SDMA_DESC_CMDSTAT_EI)
#define SDMA_SDC_RFT (1<<0)
#define SDMA_SDC_SFM (1<<1)
#define SDMA_SDC_BLMR (1<<6)
#define SDMA_SDC_BLMT (1<<7)
#define SDMA_SDC_POVR (1<<8)
#define SDMA_SDC_RIFB (1<<9)
#define SDMA_SDCM_ERD (1<<7)
#define SDMA_SDCM_AR (1<<15)
#define SDMA_SDCM_STD (1<<16)
#define SDMA_SDCM_TXD (1<<23)
#define SDMA_SDCM_AT (1<<31)
#define SDMA_0_CAUSE_RXBUF (1<<0)
#define SDMA_0_CAUSE_RXERR (1<<1)
#define SDMA_0_CAUSE_TXBUF (1<<2)
#define SDMA_0_CAUSE_TXEND (1<<3)
#define SDMA_1_CAUSE_RXBUF (1<<8)
#define SDMA_1_CAUSE_RXERR (1<<9)
#define SDMA_1_CAUSE_TXBUF (1<<10)
#define SDMA_1_CAUSE_TXEND (1<<11)
#define SDMA_CAUSE_RX_MASK (SDMA_0_CAUSE_RXBUF | SDMA_0_CAUSE_RXERR | \
SDMA_1_CAUSE_RXBUF | SDMA_1_CAUSE_RXERR)
#define SDMA_CAUSE_TX_MASK (SDMA_0_CAUSE_TXBUF | SDMA_0_CAUSE_TXEND | \
SDMA_1_CAUSE_TXBUF | SDMA_1_CAUSE_TXEND)
/* SDMA Interrupt registers */
#define SDMA_INTR_CAUSE 0x0000
#define SDMA_INTR_MASK 0x0080
/*
*****************************************************************************
*
* Baud Rate Generator Interface Registers
*
*****************************************************************************
*/
#define BRG_BCR 0x0000
#define BRG_BTR 0x0004
#endif /*_PPC_BOOT_MPSC_DEFS_H__ */
......@@ -47,6 +47,12 @@ clear_L2_L3 := $(srctree)/$(boot)/simple/clear.S
# See arch/ppc/kconfig and arch/ppc/platforms/Kconfig
# for definition of what platform each config option refer to.
#----------------------------------------------------------------------------
zimage-$(CONFIG_CPCI690) := zImage-STRIPELF
zimageinitrd-$(CONFIG_CPCI690) := zImage.initrd-STRIPELF
extra.o-$(CONFIG_CPCI690) := misc-cpci690.o mv64x60_stub.o
end-$(CONFIG_CPCI690) := cpci690
cacheflag-$(CONFIG_CPCI690) := -include $(clear_L2_L3)
zimage-$(CONFIG_IBM_OPENBIOS) := zImage-TREE
zimageinitrd-$(CONFIG_IBM_OPENBIOS) := zImage.initrd-TREE
end-$(CONFIG_IBM_OPENBIOS) := treeboot
......@@ -66,10 +72,13 @@ zimageinitrd-$(CONFIG_OCOTEA) := zImage.initrd-TREE
entrypoint-$(CONFIG_OCOTEA) := 0x01000000
extra.o-$(CONFIG_OCOTEA) := pibs.o
extra.o-$(CONFIG_EV64260) := direct.o misc-ev64260.o
extra.o-$(CONFIG_EV64260) := misc-ev64260.o
end-$(CONFIG_EV64260) := ev64260
cacheflag-$(CONFIG_EV64260) := -include $(clear_L2_L3)
extra.o-$(CONFIG_CHESTNUT) := misc-chestnut.o
end-$(CONFIG_CHESTNUT) := chestnut
zimage-$(CONFIG_GEMINI) := zImage-STRIPELF
zimageinitrd-$(CONFIG_GEMINI) := zImage.initrd-STRIPELF
end-$(CONFIG_GEMINI) := gemini
......@@ -78,6 +87,10 @@ zimageinitrd-$(CONFIG_GEMINI) := zImage.initrd-STRIPELF
end-$(CONFIG_K2) := k2
cacheflag-$(CONFIG_K2) := -include $(clear_L2_L3)
extra.o-$(CONFIG_KATANA) := misc-katana.o mv64x60_stub.o
end-$(CONFIG_KATANA) := katana
cacheflag-$(CONFIG_KATANA) := -include $(clear_L2_L3)
# kconfig 'feature', only one of these will ever be 'y' at a time.
# The rest will be unset.
motorola := $(CONFIG_MCPN765)$(CONFIG_MVME5100)$(CONFIG_PRPMC750) \
......@@ -143,6 +156,7 @@ boot-$(CONFIG_8xx) += embed_config.o
boot-$(CONFIG_8260) += embed_config.o
boot-$(CONFIG_BSEIP) += iic.o
boot-$(CONFIG_MBX) += iic.o pci.o qspan_pci.o
boot-$(CONFIG_MV64X60) += misc-mv64x60.o
boot-$(CONFIG_RPXCLASSIC) += iic.o pci.o qspan_pci.o
boot-$(CONFIG_RPXLITE) += iic.o
# Different boards need different serial implementations.
......@@ -150,8 +164,8 @@ ifeq ($(CONFIG_SERIAL_CPM_CONSOLE),y)
boot-$(CONFIG_8xx) += m8xx_tty.o
boot-$(CONFIG_8260) += m8260_tty.o
endif
boot-$(CONFIG_SERIAL_MPC52xx_CONSOLE) += mpc52xx_tty.o
boot-$(CONFIG_GT64260_CONSOLE) += gt64260_tty.o
boot-$(CONFIG_SERIAL_MPC52xx_CONSOLE) += mpc52xx_tty.o
boot-$(CONFIG_SERIAL_MPSC_CONSOLE) += mv64x60_tty.o
LIBS := $(common)/lib.a $(bootlib)/lib.a
ifeq ($(CONFIG_PPC_PREP),y)
......
/*
* arch/ppc/boot/simple/gt64260_tty.c
*
* Bootloader version of the embedded MPSC/UART driver for the GT64260[A].
* Note: Due to 64260A errata, DMA will be used for UART input (via SDMA).
*
* Author: Mark A. Greer <mgreer@mvista.com>
*
* 2001 (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.
*/
/* This code assumes that the data cache has been disabled (L1, L2, L3). */
#include <linux/config.h>
#include <linux/serialP.h>
#include <linux/serial_reg.h>
#include <asm/serial.h>
#include <asm/gt64260_defs.h>
extern void udelay(long);
static void stop_dma(int chan);
static u32 gt64260_base = EV64260_BRIDGE_REG_BASE; /* base addr of 64260 */
inline unsigned
gt64260_in_le32(volatile unsigned *addr)
{
unsigned ret;
__asm__ __volatile__("lwbrx %0,0,%1; eieio" : "=r" (ret) :
"r" (addr), "m" (*addr));
return ret;
}
inline void
gt64260_out_le32(volatile unsigned *addr, int val)
{
__asm__ __volatile__("stwbrx %1,0,%2; eieio" : "=m" (*addr) :
"r" (val), "r" (addr));
}
#define GT64260_REG_READ(offs) \
(gt64260_in_le32((volatile uint *)(gt64260_base + (offs))))
#define GT64260_REG_WRITE(offs, d) \
(gt64260_out_le32((volatile uint *)(gt64260_base + (offs)), (int)(d)))
static struct {
u32 sdc;
u32 sdcm;
u32 rx_desc;
u32 rx_buf_ptr;
u32 scrdp;
u32 tx_desc;
u32 sctdp;
u32 sftdp;
} sdma_regs;
#define SDMA_REGS_INIT(chan) { \
sdma_regs.sdc = GT64260_SDMA_##chan##_SDC; \
sdma_regs.sdcm = GT64260_SDMA_##chan##_SDCM; \
sdma_regs.rx_desc = GT64260_SDMA_##chan##_RX_DESC; \
sdma_regs.rx_buf_ptr = GT64260_SDMA_##chan##_RX_BUF_PTR; \
sdma_regs.scrdp = GT64260_SDMA_##chan##_SCRDP; \
sdma_regs.tx_desc = GT64260_SDMA_##chan##_TX_DESC; \
sdma_regs.sctdp = GT64260_SDMA_##chan##_SCTDP; \
sdma_regs.sftdp = GT64260_SDMA_##chan##_SFTDP; \
}
typedef struct {
volatile u16 bufsize;
volatile u16 bytecnt;
volatile u32 cmd_stat;
volatile u32 next_desc_ptr;
volatile u32 buffer;
} gt64260_rx_desc_t;
typedef struct {
volatile u16 bytecnt;
volatile u16 shadow;
volatile u32 cmd_stat;
volatile u32 next_desc_ptr;
volatile u32 buffer;
} gt64260_tx_desc_t;
#define MAX_RESET_WAIT 10000
#define MAX_TX_WAIT 10000
#define RX_NUM_DESC 2
#define TX_NUM_DESC 2
#define RX_BUF_SIZE 16
#define TX_BUF_SIZE 16
static gt64260_rx_desc_t rd[RX_NUM_DESC] __attribute__ ((aligned(32)));
static gt64260_tx_desc_t td[TX_NUM_DESC] __attribute__ ((aligned(32)));
static char rx_buf[RX_NUM_DESC * RX_BUF_SIZE] __attribute__ ((aligned(32)));
static char tx_buf[TX_NUM_DESC * TX_BUF_SIZE] __attribute__ ((aligned(32)));
static int cur_rd = 0;
static int cur_td = 0;
#define RX_INIT_RDP(rdp) { \
(rdp)->bufsize = 2; \
(rdp)->bytecnt = 0; \
(rdp)->cmd_stat = GT64260_SDMA_DESC_CMDSTAT_L | \
GT64260_SDMA_DESC_CMDSTAT_F | \
GT64260_SDMA_DESC_CMDSTAT_O; \
}
unsigned long
serial_init(int chan, void *ignored)
{
u32 mpsc_adjust, sdma_adjust, brg_bcr;
int i;
stop_dma(0);
stop_dma(1);
if (chan != 1) {
chan = 0; /* default to chan 0 if anything but 1 */
mpsc_adjust = 0;
sdma_adjust = 0;
brg_bcr = GT64260_BRG_0_BCR;
SDMA_REGS_INIT(0);
}
else {
mpsc_adjust = 0x1000;
sdma_adjust = 0x2000;
brg_bcr = GT64260_BRG_1_BCR;
SDMA_REGS_INIT(1);
}
/* Set up ring buffers */
for (i=0; i<RX_NUM_DESC; i++) {
RX_INIT_RDP(&rd[i]);
rd[i].buffer = (u32)&rx_buf[i * RX_BUF_SIZE];
rd[i].next_desc_ptr = (u32)&rd[i+1];
}
rd[RX_NUM_DESC - 1].next_desc_ptr = (u32)&rd[0];
for (i=0; i<TX_NUM_DESC; i++) {
td[i].bytecnt = 0;
td[i].shadow = 0;
td[i].buffer = (u32)&tx_buf[i * TX_BUF_SIZE];
td[i].cmd_stat = GT64260_SDMA_DESC_CMDSTAT_F |
GT64260_SDMA_DESC_CMDSTAT_L;
td[i].next_desc_ptr = (u32)&td[i+1];
}
td[TX_NUM_DESC - 1].next_desc_ptr = (u32)&td[0];
/* Set MPSC Routing */
GT64260_REG_WRITE(GT64260_MPSC_MRR, 0x3ffffe38);
GT64260_REG_WRITE(GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102);
/* MPSC 0/1 Rx & Tx get clocks BRG0/1 */
GT64260_REG_WRITE(GT64260_MPSC_RCRR, 0x00000100);
GT64260_REG_WRITE(GT64260_MPSC_TCRR, 0x00000100);
/* clear pending interrupts */
GT64260_REG_WRITE(GT64260_SDMA_INTR_MASK, 0);
GT64260_REG_WRITE(GT64260_SDMA_0_SCRDP + sdma_adjust, &rd[0]);
GT64260_REG_WRITE(GT64260_SDMA_0_SCTDP + sdma_adjust,
&td[TX_NUM_DESC - 1]);
GT64260_REG_WRITE(GT64260_SDMA_0_SFTDP + sdma_adjust,
&td[TX_NUM_DESC - 1]);
GT64260_REG_WRITE(GT64260_SDMA_0_SDC + sdma_adjust,
GT64260_SDMA_SDC_RFT | GT64260_SDMA_SDC_SFM |
GT64260_SDMA_SDC_BLMR | GT64260_SDMA_SDC_BLMT |
(3 << 12));
/* Set BRG to generate proper baud rate */
GT64260_REG_WRITE(brg_bcr, ((8 << 18) | (1 << 16) | 36));
/* Put MPSC into UART mode, no null modem, 16x clock mode */
GT64260_REG_WRITE(GT64260_MPSC_0_MMCRL + mpsc_adjust, 0x000004c4);
GT64260_REG_WRITE(GT64260_MPSC_0_MMCRH + mpsc_adjust, 0x04400400);
GT64260_REG_WRITE(GT64260_MPSC_0_CHR_1 + mpsc_adjust, 0);
GT64260_REG_WRITE(GT64260_MPSC_0_CHR_9 + mpsc_adjust, 0);
GT64260_REG_WRITE(GT64260_MPSC_0_CHR_10 + mpsc_adjust, 0);
GT64260_REG_WRITE(GT64260_MPSC_0_CHR_3 + mpsc_adjust, 4);
GT64260_REG_WRITE(GT64260_MPSC_0_CHR_4 + mpsc_adjust, 0);
GT64260_REG_WRITE(GT64260_MPSC_0_CHR_5 + mpsc_adjust, 0);
GT64260_REG_WRITE(GT64260_MPSC_0_CHR_6 + mpsc_adjust, 0);
GT64260_REG_WRITE(GT64260_MPSC_0_CHR_7 + mpsc_adjust, 0);
GT64260_REG_WRITE(GT64260_MPSC_0_CHR_8 + mpsc_adjust, 0);
/* 8 data bits, 1 stop bit */
GT64260_REG_WRITE(GT64260_MPSC_0_MPCR + mpsc_adjust, (3 << 12));
GT64260_REG_WRITE(GT64260_SDMA_0_SDCM + sdma_adjust,
GT64260_SDMA_SDCM_ERD);
GT64260_REG_WRITE(GT64260_MPSC_0_CHR_2 + sdma_adjust,
GT64260_MPSC_UART_CR_EH);
udelay(100);
return (ulong)chan;
}
static void
stop_dma(int chan)
{
u32 sdma_sdcm = GT64260_SDMA_0_SDCM;
int i;
if (chan == 1) {
sdma_sdcm = GT64260_SDMA_1_SDCM;
}
/* Abort SDMA Rx, Tx */
GT64260_REG_WRITE(sdma_sdcm,
GT64260_SDMA_SDCM_AR | GT64260_SDMA_SDCM_STD);
for (i=0; i<MAX_RESET_WAIT; i++) {
if ((GT64260_REG_READ(sdma_sdcm) & (GT64260_SDMA_SDCM_AR |
GT64260_SDMA_SDCM_AT)) == 0) break;
udelay(100);
}
return;
}
static int
wait_for_ownership(void)
{
int i;
for (i=0; i<MAX_TX_WAIT; i++) {
if ((GT64260_REG_READ(sdma_regs.sdcm) &
GT64260_SDMA_SDCM_TXD) == 0) break;
udelay(1000);
}
return (i < MAX_TX_WAIT);
}
void
serial_putc(unsigned long com_port, unsigned char c)
{
gt64260_tx_desc_t *tdp;
if (wait_for_ownership() == 0) return;
tdp = &td[cur_td];
if (++cur_td >= TX_NUM_DESC) cur_td = 0;
*(unchar *)(tdp->buffer ^ 7) = c;
tdp->bytecnt = 1;
tdp->shadow = 1;
tdp->cmd_stat = GT64260_SDMA_DESC_CMDSTAT_L |
GT64260_SDMA_DESC_CMDSTAT_F | GT64260_SDMA_DESC_CMDSTAT_O;
GT64260_REG_WRITE(sdma_regs.sctdp, tdp);
GT64260_REG_WRITE(sdma_regs.sftdp, tdp);
GT64260_REG_WRITE(sdma_regs.sdcm,
GT64260_REG_READ(sdma_regs.sdcm) | GT64260_SDMA_SDCM_TXD);
return;
}
unsigned char
serial_getc(unsigned long com_port)
{
gt64260_rx_desc_t *rdp;
unchar c = '\0';
rdp = &rd[cur_rd];
if ((rdp->cmd_stat & (GT64260_SDMA_DESC_CMDSTAT_O |
GT64260_SDMA_DESC_CMDSTAT_ES)) == 0) {
c = *(unchar *)(rdp->buffer ^ 7);
RX_INIT_RDP(rdp);
if (++cur_rd >= RX_NUM_DESC) cur_rd = 0;
}
return c;
}
int
serial_tstc(unsigned long com_port)
{
gt64260_rx_desc_t *rdp;
int loop_count = 0;
int rc = 0;
rdp = &rd[cur_rd];
/* Go thru rcv desc's until empty looking for one with data (no error)*/
while (((rdp->cmd_stat & GT64260_SDMA_DESC_CMDSTAT_O) == 0) &&
(loop_count++ < RX_NUM_DESC)) {
/* If there was an error, reinit the desc & continue */
if ((rdp->cmd_stat & GT64260_SDMA_DESC_CMDSTAT_ES) != 0) {
RX_INIT_RDP(rdp);
if (++cur_rd >= RX_NUM_DESC) cur_rd = 0;
rdp = (gt64260_rx_desc_t *)rdp->next_desc_ptr;
}
else {
rc = 1;
break;
}
}
return rc;
}
void
serial_close(unsigned long com_port)
{
stop_dma(com_port);
return;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment