diff options
| author | Mikael Starvik <mikael.starvik@axis.com> | 2003-07-09 20:30:06 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-07-09 20:30:06 -0700 |
| commit | 3d10ee29052913cb98b0fdef2b8e3225eac89170 (patch) | |
| tree | 40441df68ada0229de5ca6696b7673758edc6158 /include | |
| parent | 495c3da118c8b380933cee1dc2a77a8f334ad579 (diff) | |
[PATCH] CRIS architecture update for 2.5.74
This brings the chris architecture up to date with 2.5.
The patch is huge because files have been moved to prepare
for future subarchitechtures.
Diffstat (limited to 'include')
78 files changed, 3013 insertions, 3211 deletions
diff --git a/include/asm-cris/arch-v10/bitops.h b/include/asm-cris/arch-v10/bitops.h new file mode 100644 index 000000000000..21b7ae8c9bb3 --- /dev/null +++ b/include/asm-cris/arch-v10/bitops.h @@ -0,0 +1,73 @@ +/* asm/arch/bitops.h for Linux/CRISv10 */ + +#ifndef _CRIS_ARCH_BITOPS_H +#define _CRIS_ARCH_BITOPS_H + +/* + * Helper functions for the core of the ff[sz] functions, wrapping the + * syntactically awkward asms. The asms compute the number of leading + * zeroes of a bits-in-byte and byte-in-word and word-in-dword-swapped + * number. They differ in that the first function also inverts all bits + * in the input. + */ +extern inline unsigned long cris_swapnwbrlz(unsigned long w) +{ + /* Let's just say we return the result in the same register as the + input. Saying we clobber the input but can return the result + in another register: + ! __asm__ ("swapnwbr %2\n\tlz %2,%0" + ! : "=r,r" (res), "=r,X" (dummy) : "1,0" (w)); + confuses gcc (sched.c, gcc from cris-dist-1.14). */ + + unsigned long res; + __asm__ ("swapnwbr %0 \n\t" + "lz %0,%0" + : "=r" (res) : "0" (w)); + return res; +} + +extern inline unsigned long cris_swapwbrlz(unsigned long w) +{ + unsigned res; + __asm__ ("swapwbr %0 \n\t" + "lz %0,%0" + : "=r" (res) + : "0" (w)); + return res; +} + +/* + * ffz = Find First Zero in word. Undefined if no zero exists, + * so code should check against ~0UL first.. + */ +extern inline unsigned long ffz(unsigned long w) +{ + return cris_swapnwbrlz(w); +} + +/** + * __ffs - find first bit in word. + * @word: The word to search + * + * Undefined if no bit exists, so code should check against 0 first. + */ +extern __inline__ unsigned long __ffs(unsigned long word) +{ + return cris_swapnwbrlz(~word); +} + +/** + * ffs - find first bit set + * @x: the word to search + * + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ + +extern inline unsigned long kernel_ffs(unsigned long w) +{ + return w ? cris_swapwbrlz (w) + 1 : 0; +} + +#endif diff --git a/include/asm-cris/arch-v10/byteorder.h b/include/asm-cris/arch-v10/byteorder.h new file mode 100644 index 000000000000..bac946459b81 --- /dev/null +++ b/include/asm-cris/arch-v10/byteorder.h @@ -0,0 +1,25 @@ +#ifndef _CRIS_ARCH_BYTEORDER_H +#define _CRIS_ARCH_BYTEORDER_H + +#include <asm/types.h> + +/* we just define these two (as we can do the swap in a single + * asm instruction in CRIS) and the arch-independent files will put + * them together into ntohl etc. + */ + +extern __inline__ __const__ __u32 ___arch__swab32(__u32 x) +{ + __asm__ ("swapwb %0" : "=r" (x) : "0" (x)); + + return(x); +} + +extern __inline__ __const__ __u16 ___arch__swab16(__u16 x) +{ + __asm__ ("swapb %0" : "=r" (x) : "0" (x)); + + return(x); +} + +#endif diff --git a/include/asm-cris/arch-v10/cache.h b/include/asm-cris/arch-v10/cache.h new file mode 100644 index 000000000000..1e796271ea5e --- /dev/null +++ b/include/asm-cris/arch-v10/cache.h @@ -0,0 +1,8 @@ +#ifndef _ASM_ARCH_CACHE_H +#define _ASM_ARCH_CACHE_H + +/* Etrax 100LX have 32-byte cache-lines. */ +#define L1_CACHE_BYTES 32 +#define L1_CACHE_SHIFT_MAX 5 + +#endif /* _ASM_ARCH_CACHE_H */ diff --git a/include/asm-cris/arch-v10/checksum.h b/include/asm-cris/arch-v10/checksum.h new file mode 100644 index 000000000000..fde1d00aaa90 --- /dev/null +++ b/include/asm-cris/arch-v10/checksum.h @@ -0,0 +1,29 @@ +#ifndef _CRIS_ARCH_CHECKSUM_H +#define _CRIS_ARCH_CHECKSUM_H + +/* Checksum some values used in TCP/UDP headers. + * + * The gain by doing this in asm is that C will not generate carry-additions + * for the 32-bit components of the checksum, so otherwise we would have had + * to split all of those into 16-bit components, then add. + */ + +extern inline unsigned int +csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len, + unsigned short proto, unsigned int sum) +{ + int res; + __asm__ ("add.d %2, %0\n\t" + "ax\n\t" + "add.d %3, %0\n\t" + "ax\n\t" + "add.d %4, %0\n\t" + "ax\n\t" + "addq 0, %0\n" + : "=r" (res) + : "0" (sum), "r" (daddr), "r" (saddr), "r" ((ntohs(len) << 16) + (proto << 8))); + + return res; +} + +#endif diff --git a/include/asm-cris/arch-v10/delay.h b/include/asm-cris/arch-v10/delay.h new file mode 100644 index 000000000000..cfedae0d2f53 --- /dev/null +++ b/include/asm-cris/arch-v10/delay.h @@ -0,0 +1,20 @@ +#ifndef _CRIS_ARCH_DELAY_H +#define _CRIS_ARCH_DELAY_H + +extern __inline__ void __delay(int loops) +{ + __asm__ __volatile__ ( + "move.d %0,$r9\n\t" + "beq 2f\n\t" + "subq 1,$r9\n\t" + "1:\n\t" + "bne 1b\n\t" + "subq 1,$r9\n" + "2:" + : : "g" (loops) : "r9"); +} + +#endif /* defined(_CRIS_ARCH_DELAY_H) */ + + + diff --git a/include/asm-cris/arch-v10/dma.h b/include/asm-cris/arch-v10/dma.h new file mode 100644 index 000000000000..9e078b9bc934 --- /dev/null +++ b/include/asm-cris/arch-v10/dma.h @@ -0,0 +1,46 @@ +/* Defines for using and allocating dma channels. */ + +#ifndef _ASM_ARCH_DMA_H +#define _ASM_ARCH_DMA_H + +#define MAX_DMA_CHANNELS 10 + +/* dma0 and dma1 used for network (ethernet) */ +#define NETWORK_TX_DMA_NBR 0 +#define NETWORK_RX_DMA_NBR 1 + +/* dma2 and dma3 shared by par0, scsi0, ser2 and ata */ +#define PAR0_TX_DMA_NBR 2 +#define PAR0_RX_DMA_NBR 3 +#define SCSI0_TX_DMA_NBR 2 +#define SCSI0_RX_DMA_NBR 3 +#define SER2_TX_DMA_NBR 2 +#define SER2_RX_DMA_NBR 3 +#define ATA_TX_DMA_NBR 2 +#define ATA_RX_DMA_NBR 3 + +/* dma4 and dma5 shared by par1, scsi1, ser3 and extdma0 */ +#define PAR1_TX_DMA_NBR 4 +#define PAR1_RX_DMA_NBR 5 +#define SCSI1_TX_DMA_NBR 4 +#define SCSI1_RX_DMA_NBR 5 +#define SER3_TX_DMA_NBR 4 +#define SER3_RX_DMA_NBR 5 +#define EXTDMA0_TX_DMA_NBR 4 +#define EXTDMA0_RX_DMA_NBR 5 + +/* dma6 and dma7 shared by ser0, extdma1 and mem2mem */ +#define SER0_TX_DMA_NBR 6 +#define SER0_RX_DMA_NBR 7 +#define EXTDMA1_TX_DMA_NBR 6 +#define EXTDMA1_RX_DMA_NBR 7 +#define MEM2MEM_TX_DMA_NBR 6 +#define MEM2MEM_RX_DMA_NBR 7 + +/* dma8 and dma9 shared by ser1 and usb */ +#define SER1_TX_DMA_NBR 8 +#define SER1_RX_DMA_NBR 9 +#define USB_TX_DMA_NBR 8 +#define USB_RX_DMA_NBR 9 + +#endif diff --git a/include/asm-cris/arch-v10/elf.h b/include/asm-cris/arch-v10/elf.h new file mode 100644 index 000000000000..2a2201ca538e --- /dev/null +++ b/include/asm-cris/arch-v10/elf.h @@ -0,0 +1,71 @@ +#ifndef __ASMCRIS_ARCH_ELF_H +#define __ASMCRIS_ARCH_ELF_H + +/* + * ELF register definitions.. + */ + +#include <asm/ptrace.h> + +/* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program + starts (a register; assume first param register for CRIS) + contains a pointer to a function which might be + registered using `atexit'. This provides a mean for the + dynamic linker to call DT_FINI functions for shared libraries + that have been loaded before the code runs. + + A value of 0 tells we have no such handler. */ + +/* Explicitly set registers to 0 to increase determinism. */ +#define ELF_PLAT_INIT(_r, load_addr) do { \ + (_r)->r13 = 0; (_r)->r12 = 0; (_r)->r11 = 0; (_r)->r10 = 0; \ + (_r)->r9 = 0; (_r)->r8 = 0; (_r)->r7 = 0; (_r)->r6 = 0; \ + (_r)->r5 = 0; (_r)->r4 = 0; (_r)->r3 = 0; (_r)->r2 = 0; \ + (_r)->r1 = 0; (_r)->r0 = 0; (_r)->mof = 0; (_r)->srp = 0; \ +} while (0) + +/* The additional layer below is because the stack pointer is missing in + the pt_regs struct, but needed in a core dump. pr_reg is a elf_gregset_t, + and should be filled in according to the layout of the user_regs_struct + struct; regs is a pt_regs struct. We dump all registers, though several are + obviously unnecessary. That way there's less need for intelligence at + the receiving end (i.e. gdb). */ +#define ELF_CORE_COPY_REGS(pr_reg, regs) \ + pr_reg[0] = regs->r0; \ + pr_reg[1] = regs->r1; \ + pr_reg[2] = regs->r2; \ + pr_reg[3] = regs->r3; \ + pr_reg[4] = regs->r4; \ + pr_reg[5] = regs->r5; \ + pr_reg[6] = regs->r6; \ + pr_reg[7] = regs->r7; \ + pr_reg[8] = regs->r8; \ + pr_reg[9] = regs->r9; \ + pr_reg[10] = regs->r10; \ + pr_reg[11] = regs->r11; \ + pr_reg[12] = regs->r12; \ + pr_reg[13] = regs->r13; \ + pr_reg[14] = rdusp(); /* sp */ \ + pr_reg[15] = regs->irp; /* pc */ \ + pr_reg[16] = 0; /* p0 */ \ + pr_reg[17] = rdvr(); /* vr */ \ + pr_reg[18] = 0; /* p2 */ \ + pr_reg[19] = 0; /* p3 */ \ + pr_reg[20] = 0; /* p4 */ \ + pr_reg[21] = (regs->dccr & 0xffff); /* ccr */ \ + pr_reg[22] = 0; /* p6 */ \ + pr_reg[23] = regs->mof; /* mof */ \ + pr_reg[24] = 0; /* p8 */ \ + pr_reg[25] = 0; /* ibr */ \ + pr_reg[26] = 0; /* irp */ \ + pr_reg[27] = regs->srp; /* srp */ \ + pr_reg[28] = 0; /* bar */ \ + pr_reg[29] = regs->dccr; /* dccr */ \ + pr_reg[30] = 0; /* brp */ \ + pr_reg[31] = rdusp(); /* usp */ \ + pr_reg[32] = 0; /* csrinstr */ \ + pr_reg[33] = 0; /* csraddr */ \ + pr_reg[34] = 0; /* csrdata */ + + +#endif diff --git a/include/asm-cris/arch-v10/io.h b/include/asm-cris/arch-v10/io.h new file mode 100644 index 000000000000..0bc38a0313c1 --- /dev/null +++ b/include/asm-cris/arch-v10/io.h @@ -0,0 +1,193 @@ +#ifndef _ASM_ARCH_CRIS_IO_H +#define _ASM_ARCH_CRIS_IO_H + +#include <asm/arch/svinto.h> +#include <linux/config.h> + +/* Etrax shadow registers - which live in arch/cris/kernel/shadows.c */ + +extern unsigned long port_g_data_shadow; +extern unsigned char port_pa_dir_shadow; +extern unsigned char port_pa_data_shadow; +extern unsigned char port_pb_i2c_shadow; +extern unsigned char port_pb_config_shadow; +extern unsigned char port_pb_dir_shadow; +extern unsigned char port_pb_data_shadow; +extern unsigned long r_timer_ctrl_shadow; + +extern unsigned long port_cse1_shadow; +extern unsigned long port_csp0_shadow; +extern unsigned long port_csp4_shadow; + +extern volatile unsigned long *port_cse1_addr; +extern volatile unsigned long *port_csp0_addr; +extern volatile unsigned long *port_csp4_addr; + +/* macro for setting regs through a shadow - + * r = register name (like R_PORT_PA_DATA) + * s = shadow name (like port_pa_data_shadow) + * b = bit number + * v = value (0 or 1) + */ + +#define REG_SHADOW_SET(r,s,b,v) *r = s = (s & ~(1 << (b))) | ((v) << (b)) + +/* The LED's on various Etrax-based products are set differently. */ + +#if defined(CONFIG_ETRAX_NO_LEDS) || defined(CONFIG_SVINTO_SIM) +#undef CONFIG_ETRAX_PA_LEDS +#undef CONFIG_ETRAX_PB_LEDS +#undef CONFIG_ETRAX_CSP0_LEDS +#define LED_NETWORK_SET_G(x) +#define LED_NETWORK_SET_R(x) +#define LED_ACTIVE_SET_G(x) +#define LED_ACTIVE_SET_R(x) +#define LED_DISK_WRITE(x) +#define LED_DISK_READ(x) +#endif + +#if !defined(CONFIG_ETRAX_CSP0_LEDS) +#define LED_BIT_SET(x) +#define LED_BIT_CLR(x) +#endif + +#define LED_OFF 0x00 +#define LED_GREEN 0x01 +#define LED_RED 0x02 +#define LED_ORANGE (LED_GREEN | LED_RED) + +#if CONFIG_ETRAX_LED1G == CONFIG_ETRAX_LED1R +#define LED_NETWORK_SET(x) \ + do { \ + LED_NETWORK_SET_G((x) & LED_GREEN); \ + } while (0) +#else +#define LED_NETWORK_SET(x) \ + do { \ + LED_NETWORK_SET_G((x) & LED_GREEN); \ + LED_NETWORK_SET_R((x) & LED_RED); \ + } while (0) +#endif +#if CONFIG_ETRAX_LED2G == CONFIG_ETRAX_LED2R +#define LED_ACTIVE_SET(x) \ + do { \ + LED_ACTIVE_SET_G((x) & LED_GREEN); \ + } while (0) +#else +#define LED_ACTIVE_SET(x) \ + do { \ + LED_ACTIVE_SET_G((x) & LED_GREEN); \ + LED_ACTIVE_SET_R((x) & LED_RED); \ + } while (0) +#endif + +#ifdef CONFIG_ETRAX_PA_LEDS +#define LED_NETWORK_SET_G(x) \ + REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED1G, !(x)) +#define LED_NETWORK_SET_R(x) \ + REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED1R, !(x)) +#define LED_ACTIVE_SET_G(x) \ + REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED2G, !(x)) +#define LED_ACTIVE_SET_R(x) \ + REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED2R, !(x)) +#define LED_DISK_WRITE(x) \ + do{\ + REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED3G, !(x));\ + REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED3R, !(x));\ + }while(0) +#define LED_DISK_READ(x) \ + REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED3G, !(x)) +#endif + +#ifdef CONFIG_ETRAX_PB_LEDS +#define LED_NETWORK_SET_G(x) \ + REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED1G, !(x)) +#define LED_NETWORK_SET_R(x) \ + REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED1R, !(x)) +#define LED_ACTIVE_SET_G(x) \ + REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED2G, !(x)) +#define LED_ACTIVE_SET_R(x) \ + REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED2R, !(x)) +#define LED_DISK_WRITE(x) \ + do{\ + REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED3G, !(x));\ + REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED3R, !(x));\ + }while(0) +#define LED_DISK_READ(x) \ + REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED3G, !(x)) +#endif + +#ifdef CONFIG_ETRAX_CSP0_LEDS +#define CONFIGURABLE_LEDS\ + ((1 << CONFIG_ETRAX_LED1G ) | (1 << CONFIG_ETRAX_LED1R ) |\ + (1 << CONFIG_ETRAX_LED2G ) | (1 << CONFIG_ETRAX_LED2R ) |\ + (1 << CONFIG_ETRAX_LED3G ) | (1 << CONFIG_ETRAX_LED3R ) |\ + (1 << CONFIG_ETRAX_LED4G ) | (1 << CONFIG_ETRAX_LED4R ) |\ + (1 << CONFIG_ETRAX_LED5G ) | (1 << CONFIG_ETRAX_LED5R ) |\ + (1 << CONFIG_ETRAX_LED6G ) | (1 << CONFIG_ETRAX_LED6R ) |\ + (1 << CONFIG_ETRAX_LED7G ) | (1 << CONFIG_ETRAX_LED7R ) |\ + (1 << CONFIG_ETRAX_LED8Y ) | (1 << CONFIG_ETRAX_LED9Y ) |\ + (1 << CONFIG_ETRAX_LED10Y ) |(1 << CONFIG_ETRAX_LED11Y )|\ + (1 << CONFIG_ETRAX_LED12R )) + +#define LED_NETWORK_SET_G(x) \ + REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED1G, !(x)) +#define LED_NETWORK_SET_R(x) \ + REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED1R, !(x)) +#define LED_ACTIVE_SET_G(x) \ + REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED2G, !(x)) +#define LED_ACTIVE_SET_R(x) \ + REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED2R, !(x)) +#define LED_DISK_WRITE(x) \ + do{\ + REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED3G, !(x));\ + REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED3R, !(x));\ + }while(0) +#define LED_DISK_READ(x) \ + REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED3G, !(x)) +#define LED_BIT_SET(x)\ + do{\ + if((( 1 << x) & CONFIGURABLE_LEDS) != 0)\ + REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, x, 1);\ + }while(0) +#define LED_BIT_CLR(x)\ + do{\ + if((( 1 << x) & CONFIGURABLE_LEDS) != 0)\ + REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, x, 0);\ + }while(0) +#endif + +# +#ifdef CONFIG_ETRAX_SOFT_SHUTDOWN +#define SOFT_SHUTDOWN() \ + REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_SHUTDOWN_BIT, 1) +#else +#define SOFT_SHUTDOWN() +#endif + +/* Console I/O for simulated etrax100. Use #ifdef so erroneous + use will be evident. */ +#ifdef CONFIG_SVINTO_SIM + /* Let's use the ucsim interface since it lets us do write(2, ...) */ +#define SIMCOUT(s,len) \ + asm ("moveq 4,$r9 \n\t" \ + "moveq 2,$r10 \n\t" \ + "move.d %0,$r11 \n\t" \ + "move.d %1,$r12 \n\t" \ + "push $irp \n\t" \ + "move 0f,$irp \n\t" \ + "jump -6809 \n" \ + "0: \n\t" \ + "pop $irp" \ + : : "rm" (s), "rm" (len) : "r9","r10","r11","r12","memory") +#define TRACE_ON() __extension__ \ + ({ int _Foofoo; __asm__ volatile ("bmod [%0],%0" : "=r" (_Foofoo) : "0" \ + (255)); _Foofoo; }) + +#define TRACE_OFF() do { __asm__ volatile ("bmod [%0],%0" :: "r" (254)); } while (0) +#define SIM_END() do { __asm__ volatile ("bmod [%0],%0" :: "r" (28)); } while (0) +#define CRIS_CYCLES() __extension__ \ + ({ unsigned long c; asm ("bmod [%1],%0" : "=r" (c) : "r" (27)); c;}) +#endif /* ! defined CONFIG_SVINTO_SIM */ + +#endif diff --git a/include/asm-cris/arch-v10/irq.h b/include/asm-cris/arch-v10/irq.h new file mode 100644 index 000000000000..f657c75ddcfa --- /dev/null +++ b/include/asm-cris/arch-v10/irq.h @@ -0,0 +1,176 @@ +/* + * Interrupt handling assembler and defines for Linux/CRISv10 + */ + +#ifndef _ASM_ARCH_IRQ_H +#define _ASM_ARCH_IRQ_H + +#include <asm/arch/sv_addr_ag.h> + +#define NR_IRQS 32 +#define SOME_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, some) /* 0 ? */ +#define NMI_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, nmi) /* 1 */ +#define TIMER0_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, timer0) /* 2 */ +#define TIMER1_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, timer1) /* 3 */ +/* mio, ata, par0, scsi0 on 4 */ +/* par1, scsi1 on 5 */ +#define NETWORK_STATUS_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, network) /* 6 */ + +#define SERIAL_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, serial) /* 8 */ +#define PA_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, pa) /* 11 */ +/* extdma0 and extdma1 is at irq 12 and 13 and/or same as dma5 and dma6 ? */ +#define EXTDMA0_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, ext_dma0) +#define EXTDMA1_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, ext_dma1) + +/* dma0-9 is irq 16..25 */ +/* 16,17: network */ +#define DMA0_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma0) +#define DMA1_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma1) +#define NETWORK_DMA_TX_IRQ_NBR DMA0_TX_IRQ_NBR +#define NETWORK_DMA_RX_IRQ_NBR DMA1_RX_IRQ_NBR + +/* 18,19: dma2 and dma3 shared by par0, scsi0, ser2 and ata */ +#define DMA2_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma2) +#define DMA3_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma3) +#define SER2_DMA_TX_IRQ_NBR DMA2_TX_IRQ_NBR +#define SER2_DMA_RX_IRQ_NBR DMA3_RX_IRQ_NBR + +/* 20,21: dma4 and dma5 shared by par1, scsi1, ser3 and extdma0 */ +#define DMA4_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma4) +#define DMA5_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma5) +#define SER3_DMA_TX_IRQ_NBR DMA4_TX_IRQ_NBR +#define SER3_DMA_RX_IRQ_NBR DMA5_RX_IRQ_NBR + +/* 22,23: dma6 and dma7 shared by ser0, extdma1 and mem2mem */ +#define DMA6_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma6) +#define DMA7_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma7) +#define SER0_DMA_TX_IRQ_NBR DMA6_TX_IRQ_NBR +#define SER0_DMA_RX_IRQ_NBR DMA7_RX_IRQ_NBR +#define MEM2MEM_DMA_TX_IRQ_NBR DMA6_TX_IRQ_NBR +#define MEM2MEM_DMA_RX_IRQ_NBR DMA7_RX_IRQ_NBR + +/* 24,25: dma8 and dma9 shared by ser1 and usb */ +#define DMA8_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma8) +#define DMA9_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma9) +#define SER1_DMA_TX_IRQ_NBR DMA8_TX_IRQ_NBR +#define SER1_DMA_RX_IRQ_NBR DMA9_RX_IRQ_NBR +#define USB_DMA_TX_IRQ_NBR DMA8_TX_IRQ_NBR +#define USB_DMA_RX_IRQ_NBR DMA9_RX_IRQ_NBR + +/* usb: controller at irq 31 + uses DMA8 and DMA9 */ +#define USB_HC_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, usb) + +/* our fine, global, etrax irq vector! the pointer lives in the head.S file. */ + +typedef void (*irqvectptr)(void); + +struct etrax_interrupt_vector { + irqvectptr v[256]; +}; + +extern struct etrax_interrupt_vector *etrax_irv; +void set_int_vector(int n, irqvectptr addr, irqvectptr saddr); +void set_break_vector(int n, irqvectptr addr); + +#define mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); +#define unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); + +#define __STR(x) #x +#define STR(x) __STR(x) + +/* SAVE_ALL saves registers so they match pt_regs */ + +#define SAVE_ALL \ + "move $irp,[$sp=$sp-16]\n\t" /* push instruction pointer and fake SBFS struct */ \ + "push $srp\n\t" /* push subroutine return pointer */ \ + "push $dccr\n\t" /* push condition codes */ \ + "push $mof\n\t" /* push multiply overflow reg */ \ + "di\n\t" /* need to disable irq's at this point */\ + "subq 14*4,$sp\n\t" /* make room for r0-r13 */ \ + "movem $r13,[$sp]\n\t" /* push the r0-r13 registers */ \ + "push $r10\n\t" /* push orig_r10 */ \ + "clear.d [$sp=$sp-4]\n\t" /* frametype - this is a normal stackframe */ + + /* BLOCK_IRQ and UNBLOCK_IRQ do the same as mask_irq and unmask_irq */ + +#define BLOCK_IRQ(mask,nr) \ + "move.d " #mask ",$r0\n\t" \ + "move.d $r0,[0xb00000d8]\n\t" + +#define UNBLOCK_IRQ(mask) \ + "move.d " #mask ",$r0\n\t" \ + "move.d $r0,[0xb00000dc]\n\t" + +#define IRQ_NAME2(nr) nr##_interrupt(void) +#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) +#define sIRQ_NAME(nr) IRQ_NAME2(sIRQ##nr) +#define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr) + + /* the asm IRQ handler makes sure the causing IRQ is blocked, then it calls + * do_IRQ (with irq disabled still). after that it unblocks and jumps to + * ret_from_intr (entry.S) + * + * The reason the IRQ is blocked is to allow an sti() before the handler which + * will acknowledge the interrupt is run. + */ + +#define BUILD_IRQ(nr,mask) \ +void IRQ_NAME(nr); \ +void sIRQ_NAME(nr); \ +void BAD_IRQ_NAME(nr); \ +__asm__ ( \ + ".text\n\t" \ + "IRQ" #nr "_interrupt:\n\t" \ + SAVE_ALL \ + "sIRQ" #nr "_interrupt:\n\t" /* shortcut for the multiple irq handler */ \ + BLOCK_IRQ(mask,nr) /* this must be done to prevent irq loops when we ei later */ \ + "moveq "#nr",$r10\n\t" \ + "move.d $sp,$r11\n\t" \ + "jsr do_IRQ\n\t" /* irq.c, r10 and r11 are arguments */ \ + UNBLOCK_IRQ(mask) \ + "moveq 0,$r9\n\t" /* make ret_from_intr realise we came from an irq */ \ + "jump ret_from_intr\n\t" \ + "bad_IRQ" #nr "_interrupt:\n\t" \ + "push $r0\n\t" \ + BLOCK_IRQ(mask,nr) \ + "pop $r0\n\t" \ + "reti\n\t" \ + "nop\n"); + +/* This is subtle. The timer interrupt is crucial and it should not be disabled for + * too long. However, if it had been a normal interrupt as per BUILD_IRQ, it would + * have been BLOCK'ed, and then softirq's are run before we return here to UNBLOCK. + * If the softirq's take too much time to run, the timer irq won't run and the + * watchdog will kill us. + * + * Furthermore, if a lot of other irq's occur before we return here, the multiple_irq + * handler is run and it prioritizes the timer interrupt. However if we had BLOCK'ed + * it here, we would not get the multiple_irq at all. + * + * The non-blocking here is based on the knowledge that the timer interrupt is + * registred as a fast interrupt (SA_INTERRUPT) so that we _know_ there will not + * be an sti() before the timer irq handler is run to acknowledge the interrupt. + */ + +#define BUILD_TIMER_IRQ(nr,mask) \ +void IRQ_NAME(nr); \ +void sIRQ_NAME(nr); \ +void BAD_IRQ_NAME(nr); \ +__asm__ ( \ + ".text\n\t" \ + "IRQ" #nr "_interrupt:\n\t" \ + SAVE_ALL \ + "sIRQ" #nr "_interrupt:\n\t" /* shortcut for the multiple irq handler */ \ + "moveq "#nr",$r10\n\t" \ + "move.d $sp,$r11\n\t" \ + "jsr do_IRQ\n\t" /* irq.c, r10 and r11 are arguments */ \ + "moveq 0,$r9\n\t" /* make ret_from_intr realise we came from an irq */ \ + "jump ret_from_intr\n\t" \ + "bad_IRQ" #nr "_interrupt:\n\t" \ + "push $r0\n\t" \ + BLOCK_IRQ(mask,nr) \ + "pop $r0\n\t" \ + "reti\n\t" \ + "nop\n"); + +#endif diff --git a/include/asm-cris/arch-v10/mmu.h b/include/asm-cris/arch-v10/mmu.h new file mode 100644 index 000000000000..d18aa00e50bc --- /dev/null +++ b/include/asm-cris/arch-v10/mmu.h @@ -0,0 +1,106 @@ +/* + * CRIS MMU constants and PTE layout + */ + +#ifndef _CRIS_ARCH_MMU_H +#define _CRIS_ARCH_MMU_H + +/* type used in struct mm to couple an MMU context to an active mm */ + +typedef unsigned int mm_context_t; + +/* kernel memory segments */ + +#define KSEG_F 0xf0000000UL +#define KSEG_E 0xe0000000UL +#define KSEG_D 0xd0000000UL +#define KSEG_C 0xc0000000UL +#define KSEG_B 0xb0000000UL +#define KSEG_A 0xa0000000UL +#define KSEG_9 0x90000000UL +#define KSEG_8 0x80000000UL +#define KSEG_7 0x70000000UL +#define KSEG_6 0x60000000UL +#define KSEG_5 0x50000000UL +#define KSEG_4 0x40000000UL +#define KSEG_3 0x30000000UL +#define KSEG_2 0x20000000UL +#define KSEG_1 0x10000000UL +#define KSEG_0 0x00000000UL + +/* CRIS PTE bits (see R_TLB_LO in the register description) + * + * Bit: 31-13 12-------4 3 2 1 0 + * ________________________________________________ + * | pfn | reserved | global | valid | kernel | we | + * |_____|__________|________|_______|________|_____| + * + * (pfn = physical frame number) + */ + +/* Real HW-based PTE bits. We use some synonym names so that + * things become less confusing in combination with the SW-based + * bits further below. + * + */ + +#define _PAGE_WE (1<<0) /* page is write-enabled */ +#define _PAGE_SILENT_WRITE (1<<0) /* synonym */ +#define _PAGE_KERNEL (1<<1) /* page is kernel only */ +#define _PAGE_VALID (1<<2) /* page is valid */ +#define _PAGE_SILENT_READ (1<<2) /* synonym */ +#define _PAGE_GLOBAL (1<<3) /* global page - context is ignored */ + +/* Bits the HW doesn't care about but the kernel uses them in SW */ + +#define _PAGE_PRESENT (1<<4) /* page present in memory */ +#define _PAGE_FILE (1<<5) /* set: pagecache, unset: swap (when !PRESENT) */ +#define _PAGE_ACCESSED (1<<5) /* simulated in software using valid bit */ +#define _PAGE_MODIFIED (1<<6) /* simulated in software using we bit */ +#define _PAGE_READ (1<<7) /* read-enabled */ +#define _PAGE_WRITE (1<<8) /* write-enabled */ + +/* Define some higher level generic page attributes. */ + +#define __READABLE (_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED) +#define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED) + +#define _PAGE_TABLE (_PAGE_PRESENT | __READABLE | __WRITEABLE) +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED) + +#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | __READABLE | _PAGE_WRITE | \ + _PAGE_ACCESSED) +#define PAGE_COPY __pgprot(_PAGE_PRESENT | __READABLE) // | _PAGE_COW +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | __READABLE) +#define PAGE_KERNEL __pgprot(_PAGE_GLOBAL | _PAGE_KERNEL | \ + _PAGE_PRESENT | __READABLE | __WRITEABLE) +#define _KERNPG_TABLE (_PAGE_TABLE | _PAGE_KERNEL) + +/* + * CRIS can't do page protection for execute, and considers read the same. + * Also, write permissions imply read permissions. This is the closest we can + * get.. + */ + +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY +#define __P101 PAGE_READONLY +#define __P110 PAGE_COPY +#define __P111 PAGE_COPY + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY +#define __S101 PAGE_READONLY +#define __S110 PAGE_SHARED +#define __S111 PAGE_SHARED + +#define PTE_FILE_MAX_BITS 26 + +#endif diff --git a/include/asm-cris/arch-v10/offset.h b/include/asm-cris/arch-v10/offset.h new file mode 100644 index 000000000000..87901a752746 --- /dev/null +++ b/include/asm-cris/arch-v10/offset.h @@ -0,0 +1,33 @@ +#ifndef __ASM_OFFSETS_H__ +#define __ASM_OFFSETS_H__ +/* + * DO NOT MODIFY. + * + * This file was generated by arch/cris/Makefile + * + */ + +#define PT_orig_r10 4 /* offsetof(struct pt_regs, orig_r10) */ +#define PT_r13 8 /* offsetof(struct pt_regs, r13) */ +#define PT_r12 12 /* offsetof(struct pt_regs, r12) */ +#define PT_r11 16 /* offsetof(struct pt_regs, r11) */ +#define PT_r10 20 /* offsetof(struct pt_regs, r10) */ +#define PT_r9 24 /* offsetof(struct pt_regs, r9) */ +#define PT_mof 64 /* offsetof(struct pt_regs, mof) */ +#define PT_dccr 68 /* offsetof(struct pt_regs, dccr) */ +#define PT_srp 72 /* offsetof(struct pt_regs, srp) */ + +#define TI_task 0 /* offsetof(struct thread_info, task) */ +#define TI_flags 8 /* offsetof(struct thread_info, flags) */ +#define TI_preempt_count 16 /* offsetof(struct thread_info, preempt_count) */ + +#define THREAD_ksp 0 /* offsetof(struct thread_struct, ksp) */ +#define THREAD_usp 4 /* offsetof(struct thread_struct, usp) */ +#define THREAD_dccr 8 /* offsetof(struct thread_struct, dccr) */ + +#define TASK_pid 121 /* offsetof(struct task_struct, pid) */ + +#define LCLONE_VM 256 /* CLONE_VM */ +#define LCLONE_UNTRACED 8388608 /* CLONE_UNTRACED */ + +#endif diff --git a/include/asm-cris/arch-v10/page.h b/include/asm-cris/arch-v10/page.h new file mode 100644 index 000000000000..407e6e68f49e --- /dev/null +++ b/include/asm-cris/arch-v10/page.h @@ -0,0 +1,31 @@ +#ifndef _CRIS_ARCH_PAGE_H +#define _CRIS_ARCH_PAGE_H + +#include <linux/config.h> + +#ifdef __KERNEL__ + +/* This handles the memory map.. */ +#ifdef CONFIG_CRIS_LOW_MAP +#define PAGE_OFFSET KSEG_6 /* kseg_6 is mapped to physical ram */ +#else +#define PAGE_OFFSET KSEG_C /* kseg_c is mapped to physical ram */ +#endif + +/* macros to convert between really physical and virtual addresses + * by stripping a selected bit, we can convert between KSEG_x and 0x40000000 where + * the DRAM really resides + */ + +#ifdef CONFIG_CRIS_LOW_MAP +/* we have DRAM virtually at 0x6 */ +#define __pa(x) ((unsigned long)(x) & 0xdfffffff) +#define __va(x) ((void *)((unsigned long)(x) | 0x20000000)) +#else +/* we have DRAM virtually at 0xc */ +#define __pa(x) ((unsigned long)(x) & 0x7fffffff) +#define __va(x) ((void *)((unsigned long)(x) | 0x80000000)) +#endif + +#endif +#endif diff --git a/include/asm-cris/arch-v10/pgtable.h b/include/asm-cris/arch-v10/pgtable.h new file mode 100644 index 000000000000..65eecd1e6538 --- /dev/null +++ b/include/asm-cris/arch-v10/pgtable.h @@ -0,0 +1,19 @@ +#ifndef _CRIS_ARCH_PGTABLE_H +#define _CRIS_ARCH_PGTABLE_H + +/* + * Kernels own virtual memory area. + */ + +#ifdef CONFIG_CRIS_LOW_MAP +#define VMALLOC_START KSEG_7 +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) +#define VMALLOC_END KSEG_8 +#else +#define VMALLOC_START KSEG_D +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) +#define VMALLOC_END KSEG_E +#endif + +#endif + diff --git a/include/asm-cris/arch-v10/processor.h b/include/asm-cris/arch-v10/processor.h new file mode 100644 index 000000000000..9355d8675a58 --- /dev/null +++ b/include/asm-cris/arch-v10/processor.h @@ -0,0 +1,62 @@ +#ifndef __ASM_CRIS_ARCH_PROCESSOR_H +#define __ASM_CRIS_ARCH_PROCESSOR_H + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({void *pc; __asm__ ("move.d $pc,%0" : "=rm" (pc)); pc; }) + +/* CRIS has no problems with write protection */ +#define wp_works_ok 1 + +/* CRIS thread_struct. this really has nothing to do with the processor itself, since + * CRIS does not do any hardware task-switching, but it's here for legacy reasons. + * The thread_struct here is used when task-switching using _resume defined in entry.S. + * The offsets here are hardcoded into _resume - if you change this struct, you need to + * change them as well!!! +*/ + +struct thread_struct { + unsigned long ksp; /* kernel stack pointer */ + unsigned long usp; /* user stack pointer */ + unsigned long dccr; /* saved flag register */ +}; + +/* + * User space process size. This is hardcoded into a few places, + * so don't change it unless you know what you are doing. + */ + +#ifdef CONFIG_CRIS_LOW_MAP +#define TASK_SIZE (0x50000000UL) /* 1.25 GB */ +#else +#define TASK_SIZE (0xA0000000UL) /* 2.56 GB */ +#endif + +#define INIT_THREAD { \ + 0, 0, 0x20 } /* ccr = int enable, nothing else */ + +#define KSTK_EIP(tsk) \ +({ \ + unsigned long eip = 0; \ + unsigned long regs = (unsigned long)user_regs(tsk); \ + if (regs > PAGE_SIZE && \ + virt_addr_valid(regs)) \ + eip = ((struct pt_regs *)regs)->irp; \ + eip; \ +}) + +/* give the thread a program location + * set user-mode (The 'U' flag (User mode flag) is CCR/DCCR bit 8) + * switch user-stackpointer + */ + +#define start_thread(regs, ip, usp) do { \ + set_fs(USER_DS); \ + regs->irp = ip; \ + regs->dccr |= 1 << U_DCCR_BITNR; \ + wrusp(usp); \ +} while(0) + +#endif diff --git a/include/asm-cris/arch-v10/ptrace.h b/include/asm-cris/arch-v10/ptrace.h new file mode 100644 index 000000000000..939d9846477e --- /dev/null +++ b/include/asm-cris/arch-v10/ptrace.h @@ -0,0 +1,114 @@ +#ifndef _CRIS_ARCH_PTRACE_H +#define _CRIS_ARCH_PTRACE_H + +/* Frame types */ + +#define CRIS_FRAME_NORMAL 0 /* normal frame without SBFS stacking */ +#define CRIS_FRAME_BUSFAULT 1 /* frame stacked using SBFS, need RBF return + path */ + +/* Register numbers in the ptrace system call interface */ + +#define PT_FRAMETYPE 0 +#define PT_ORIG_R10 1 +#define PT_R13 2 +#define PT_R12 3 +#define PT_R11 4 +#define PT_R10 5 +#define PT_R9 6 +#define PT_R8 7 +#define PT_R7 8 +#define PT_R6 9 +#define PT_R5 10 +#define PT_R4 11 +#define PT_R3 12 +#define PT_R2 13 +#define PT_R1 14 +#define PT_R0 15 +#define PT_MOF 16 +#define PT_DCCR 17 +#define PT_SRP 18 +#define PT_IRP 19 /* This is actually the debugged process' PC */ +#define PT_CSRINSTR 20 /* CPU Status record remnants - + valid if frametype == busfault */ +#define PT_CSRADDR 21 +#define PT_CSRDATA 22 +#define PT_USP 23 /* special case - USP is not in the pt_regs */ +#define PT_MAX 23 + +/* Condition code bit numbers. The same numbers apply to CCR of course, + but we use DCCR everywhere else, so let's try and be consistent. */ +#define C_DCCR_BITNR 0 +#define V_DCCR_BITNR 1 +#define Z_DCCR_BITNR 2 +#define N_DCCR_BITNR 3 +#define X_DCCR_BITNR 4 +#define I_DCCR_BITNR 5 +#define B_DCCR_BITNR 6 +#define M_DCCR_BITNR 7 +#define U_DCCR_BITNR 8 +#define P_DCCR_BITNR 9 +#define F_DCCR_BITNR 10 + +/* pt_regs not only specifices the format in the user-struct during + * ptrace but is also the frame format used in the kernel prologue/epilogues + * themselves + */ + +struct pt_regs { + unsigned long frametype; /* type of stackframe */ + unsigned long orig_r10; + /* pushed by movem r13, [sp] in SAVE_ALL, movem pushes backwards */ + unsigned long r13; + unsigned long r12; + unsigned long r11; + unsigned long r10; + unsigned long r9; + unsigned long r8; + unsigned long r7; + unsigned long r6; + unsigned long r5; + unsigned long r4; + unsigned long r3; + unsigned long r2; + unsigned long r1; + unsigned long r0; + unsigned long mof; + unsigned long dccr; + unsigned long srp; + unsigned long irp; /* This is actually the debugged process' PC */ + unsigned long csrinstr; + unsigned long csraddr; + unsigned long csrdata; +}; + +/* switch_stack is the extra stuff pushed onto the stack in _resume (entry.S) + * when doing a context-switch. it is used (apart from in resume) when a new + * thread is made and we need to make _resume (which is starting it for the + * first time) realise what is going on. + * + * Actually, the use is very close to the thread struct (TSS) in that both the + * switch_stack and the TSS are used to keep thread stuff when switching in + * _resume. + */ + +struct switch_stack { + unsigned long r9; + unsigned long r8; + unsigned long r7; + unsigned long r6; + unsigned long r5; + unsigned long r4; + unsigned long r3; + unsigned long r2; + unsigned long r1; + unsigned long r0; + unsigned long return_ip; /* ip that _resume will return to */ +}; + +/* bit 8 is user-mode flag */ +#define user_mode(regs) (((regs)->dccr & 0x100) != 0) +#define instruction_pointer(regs) ((regs)->irp) +extern void show_regs(struct pt_regs *); + +#endif diff --git a/include/asm-cris/sv_addr.agh b/include/asm-cris/arch-v10/sv_addr.agh index ddaf91fa38cf..6ac3a7bc9760 100644 --- a/include/asm-cris/sv_addr.agh +++ b/include/asm-cris/arch-v10/sv_addr.agh @@ -691,10 +691,10 @@ #define R_GEN_CONFIG__g24dir__WIDTH 1 #define R_GEN_CONFIG__g24dir__in 0 #define R_GEN_CONFIG__g24dir__out 1 -#define R_GEN_CONFIG__g16_20dir__BITNR 26 -#define R_GEN_CONFIG__g16_20dir__WIDTH 1 -#define R_GEN_CONFIG__g16_20dir__in 0 -#define R_GEN_CONFIG__g16_20dir__out 1 +#define R_GEN_CONFIG__g16_23dir__BITNR 26 +#define R_GEN_CONFIG__g16_23dir__WIDTH 1 +#define R_GEN_CONFIG__g16_23dir__in 0 +#define R_GEN_CONFIG__g16_23dir__out 1 #define R_GEN_CONFIG__g8_15dir__BITNR 25 #define R_GEN_CONFIG__g8_15dir__WIDTH 1 #define R_GEN_CONFIG__g8_15dir__in 0 @@ -1142,7 +1142,7 @@ #define R_SERIAL0_CTRL__rec_stick_par__BITNR 19 #define R_SERIAL0_CTRL__rec_stick_par__WIDTH 1 #define R_SERIAL0_CTRL__rec_stick_par__normal 0 -#define R_SERIAL0_CTRL__rec_stick_parlocal_irq_enableck 1 +#define R_SERIAL0_CTRL__rec_stick_par__stick 1 #define R_SERIAL0_CTRL__rec_par__BITNR 18 #define R_SERIAL0_CTRL__rec_par__WIDTH 1 #define R_SERIAL0_CTRL__rec_par__even 0 @@ -1172,7 +1172,7 @@ #define R_SERIAL0_CTRL__tr_stick_par__BITNR 11 #define R_SERIAL0_CTRL__tr_stick_par__WIDTH 1 #define R_SERIAL0_CTRL__tr_stick_par__normal 0 -#define R_SERIAL0_CTRL__tr_stick_parlocal_irq_enableck 1 +#define R_SERIAL0_CTRL__tr_stick_par__stick 1 #define R_SERIAL0_CTRL__tr_par__BITNR 10 #define R_SERIAL0_CTRL__tr_par__WIDTH 1 #define R_SERIAL0_CTRL__tr_par__even 0 @@ -1246,7 +1246,7 @@ #define R_SERIAL0_REC_CTRL__rec_stick_par__BITNR 3 #define R_SERIAL0_REC_CTRL__rec_stick_par__WIDTH 1 #define R_SERIAL0_REC_CTRL__rec_stick_par__normal 0 -#define R_SERIAL0_REC_CTRL__rec_stick_parlocal_irq_enableck 1 +#define R_SERIAL0_REC_CTRL__rec_stick_par__stick 1 #define R_SERIAL0_REC_CTRL__rec_par__BITNR 2 #define R_SERIAL0_REC_CTRL__rec_par__WIDTH 1 #define R_SERIAL0_REC_CTRL__rec_par__even 0 @@ -1278,7 +1278,7 @@ #define R_SERIAL0_TR_CTRL__tr_stick_par__BITNR 3 #define R_SERIAL0_TR_CTRL__tr_stick_par__WIDTH 1 #define R_SERIAL0_TR_CTRL__tr_stick_par__normal 0 -#define R_SERIAL0_TR_CTRL__tr_stick_parlocal_irq_enableck 1 +#define R_SERIAL0_TR_CTRL__tr_stick_par__stick 1 #define R_SERIAL0_TR_CTRL__tr_par__BITNR 2 #define R_SERIAL0_TR_CTRL__tr_par__WIDTH 1 #define R_SERIAL0_TR_CTRL__tr_par__even 0 @@ -1434,7 +1434,7 @@ #define R_SERIAL1_CTRL__rec_stick_par__BITNR 19 #define R_SERIAL1_CTRL__rec_stick_par__WIDTH 1 #define R_SERIAL1_CTRL__rec_stick_par__normal 0 -#define R_SERIAL1_CTRL__rec_stick_parlocal_irq_enableck 1 +#define R_SERIAL1_CTRL__rec_stick_par__stick 1 #define R_SERIAL1_CTRL__rec_par__BITNR 18 #define R_SERIAL1_CTRL__rec_par__WIDTH 1 #define R_SERIAL1_CTRL__rec_par__even 0 @@ -1464,7 +1464,7 @@ #define R_SERIAL1_CTRL__tr_stick_par__BITNR 11 #define R_SERIAL1_CTRL__tr_stick_par__WIDTH 1 #define R_SERIAL1_CTRL__tr_stick_par__normal 0 -#define R_SERIAL1_CTRL__tr_stick_parlocal_irq_enableck 1 +#define R_SERIAL1_CTRL__tr_stick_par__stick 1 #define R_SERIAL1_CTRL__tr_par__BITNR 10 #define R_SERIAL1_CTRL__tr_par__WIDTH 1 #define R_SERIAL1_CTRL__tr_par__even 0 @@ -1538,7 +1538,7 @@ #define R_SERIAL1_REC_CTRL__rec_stick_par__BITNR 3 #define R_SERIAL1_REC_CTRL__rec_stick_par__WIDTH 1 #define R_SERIAL1_REC_CTRL__rec_stick_par__normal 0 -#define R_SERIAL1_REC_CTRL__rec_stick_parlocal_irq_enableck 1 +#define R_SERIAL1_REC_CTRL__rec_stick_par__stick 1 #define R_SERIAL1_REC_CTRL__rec_par__BITNR 2 #define R_SERIAL1_REC_CTRL__rec_par__WIDTH 1 #define R_SERIAL1_REC_CTRL__rec_par__even 0 @@ -1570,7 +1570,7 @@ #define R_SERIAL1_TR_CTRL__tr_stick_par__BITNR 3 #define R_SERIAL1_TR_CTRL__tr_stick_par__WIDTH 1 #define R_SERIAL1_TR_CTRL__tr_stick_par__normal 0 -#define R_SERIAL1_TR_CTRL__tr_stick_parlocal_irq_enableck 1 +#define R_SERIAL1_TR_CTRL__tr_stick_par__stick 1 #define R_SERIAL1_TR_CTRL__tr_par__BITNR 2 #define R_SERIAL1_TR_CTRL__tr_par__WIDTH 1 #define R_SERIAL1_TR_CTRL__tr_par__even 0 @@ -1726,7 +1726,7 @@ #define R_SERIAL2_CTRL__rec_stick_par__BITNR 19 #define R_SERIAL2_CTRL__rec_stick_par__WIDTH 1 #define R_SERIAL2_CTRL__rec_stick_par__normal 0 -#define R_SERIAL2_CTRL__rec_stick_parlocal_irq_enableck 1 +#define R_SERIAL2_CTRL__rec_stick_par__stick 1 #define R_SERIAL2_CTRL__rec_par__BITNR 18 #define R_SERIAL2_CTRL__rec_par__WIDTH 1 #define R_SERIAL2_CTRL__rec_par__even 0 @@ -1756,7 +1756,7 @@ #define R_SERIAL2_CTRL__tr_stick_par__BITNR 11 #define R_SERIAL2_CTRL__tr_stick_par__WIDTH 1 #define R_SERIAL2_CTRL__tr_stick_par__normal 0 -#define R_SERIAL2_CTRL__tr_stick_parlocal_irq_enableck 1 +#define R_SERIAL2_CTRL__tr_stick_par__stick 1 #define R_SERIAL2_CTRL__tr_par__BITNR 10 #define R_SERIAL2_CTRL__tr_par__WIDTH 1 #define R_SERIAL2_CTRL__tr_par__even 0 @@ -1830,7 +1830,7 @@ #define R_SERIAL2_REC_CTRL__rec_stick_par__BITNR 3 #define R_SERIAL2_REC_CTRL__rec_stick_par__WIDTH 1 #define R_SERIAL2_REC_CTRL__rec_stick_par__normal 0 -#define R_SERIAL2_REC_CTRL__rec_stick_parlocal_irq_enableck 1 +#define R_SERIAL2_REC_CTRL__rec_stick_par__stick 1 #define R_SERIAL2_REC_CTRL__rec_par__BITNR 2 #define R_SERIAL2_REC_CTRL__rec_par__WIDTH 1 #define R_SERIAL2_REC_CTRL__rec_par__even 0 @@ -1862,7 +1862,7 @@ #define R_SERIAL2_TR_CTRL__tr_stick_par__BITNR 3 #define R_SERIAL2_TR_CTRL__tr_stick_par__WIDTH 1 #define R_SERIAL2_TR_CTRL__tr_stick_par__normal 0 -#define R_SERIAL2_TR_CTRL__tr_stick_parlocal_irq_enableck 1 +#define R_SERIAL2_TR_CTRL__tr_stick_par__stick 1 #define R_SERIAL2_TR_CTRL__tr_par__BITNR 2 #define R_SERIAL2_TR_CTRL__tr_par__WIDTH 1 #define R_SERIAL2_TR_CTRL__tr_par__even 0 @@ -2018,7 +2018,7 @@ #define R_SERIAL3_CTRL__rec_stick_par__BITNR 19 #define R_SERIAL3_CTRL__rec_stick_par__WIDTH 1 #define R_SERIAL3_CTRL__rec_stick_par__normal 0 -#define R_SERIAL3_CTRL__rec_stick_parlocal_irq_enableck 1 +#define R_SERIAL3_CTRL__rec_stick_par__stick 1 #define R_SERIAL3_CTRL__rec_par__BITNR 18 #define R_SERIAL3_CTRL__rec_par__WIDTH 1 #define R_SERIAL3_CTRL__rec_par__even 0 @@ -2048,7 +2048,7 @@ #define R_SERIAL3_CTRL__tr_stick_par__BITNR 11 #define R_SERIAL3_CTRL__tr_stick_par__WIDTH 1 #define R_SERIAL3_CTRL__tr_stick_par__normal 0 -#define R_SERIAL3_CTRL__tr_stick_parlocal_irq_enableck 1 +#define R_SERIAL3_CTRL__tr_stick_par__stick 1 #define R_SERIAL3_CTRL__tr_par__BITNR 10 #define R_SERIAL3_CTRL__tr_par__WIDTH 1 #define R_SERIAL3_CTRL__tr_par__even 0 @@ -2122,7 +2122,7 @@ #define R_SERIAL3_REC_CTRL__rec_stick_par__BITNR 3 #define R_SERIAL3_REC_CTRL__rec_stick_par__WIDTH 1 #define R_SERIAL3_REC_CTRL__rec_stick_par__normal 0 -#define R_SERIAL3_REC_CTRL__rec_stick_parlocal_irq_enableck 1 +#define R_SERIAL3_REC_CTRL__rec_stick_par__stick 1 #define R_SERIAL3_REC_CTRL__rec_par__BITNR 2 #define R_SERIAL3_REC_CTRL__rec_par__WIDTH 1 #define R_SERIAL3_REC_CTRL__rec_par__even 0 @@ -2154,7 +2154,7 @@ #define R_SERIAL3_TR_CTRL__tr_stick_par__BITNR 3 #define R_SERIAL3_TR_CTRL__tr_stick_par__WIDTH 1 #define R_SERIAL3_TR_CTRL__tr_stick_par__normal 0 -#define R_SERIAL3_TR_CTRL__tr_stick_parlocal_irq_enableck 1 +#define R_SERIAL3_TR_CTRL__tr_stick_par__stick 1 #define R_SERIAL3_TR_CTRL__tr_par__BITNR 2 #define R_SERIAL3_TR_CTRL__tr_par__WIDTH 1 #define R_SERIAL3_TR_CTRL__tr_par__even 0 diff --git a/include/asm-cris/sv_addr_ag.h b/include/asm-cris/arch-v10/sv_addr_ag.h index c80826bf9410..e4a6b68b8982 100644 --- a/include/asm-cris/sv_addr_ag.h +++ b/include/asm-cris/arch-v10/sv_addr_ag.h @@ -25,33 +25,41 @@ /* IO_MASK returns a mask for a specified bitfield in a register. Note that this macro doesn't work when field width is 32 bits. */ -#define IO_MASK(reg,field) \ - ( ( ( 1 << reg##__##field##__WIDTH ) - 1 ) << reg##__##field##__BITNR ) +#define IO_MASK(reg, field) IO_MASK_ (reg##_, field##_) +#define IO_MASK_(reg_, field_) \ + ( ( ( 1 << reg_##_##field_##_WIDTH ) - 1 ) << reg_##_##field_##_BITNR ) /* IO_STATE returns a constant corresponding to a one of the symbolic states that the bitfield can have. (Shifted to correct position) */ -#define IO_STATE(reg,field,state) \ - ( reg##__##field##__##state << reg##__##field##__BITNR ) +#define IO_STATE(reg, field, state) IO_STATE_ (reg##_, field##_, _##state) +#define IO_STATE_(reg_, field_, _state) \ + ( reg_##_##field_##_state << reg_##_##field_##_BITNR ) /* IO_EXTRACT returns the masked and shifted value corresponding to the bitfield can have. */ -#define IO_EXTRACT(reg,field,val) ( (( ( ( 1 << reg##__##field##__WIDTH ) \ - - 1 ) << reg##__##field##__BITNR ) & (val)) >> reg##__##field##__BITNR ) +#define IO_EXTRACT(reg, field, val) IO_EXTRACT_ (reg##_, field##_, val) +#define IO_EXTRACT_(reg_, field_, val) ( (( ( ( 1 << reg_##_##field_##_WIDTH ) \ + - 1 ) << reg_##_##field_##_BITNR ) & (val)) >> reg_##_##field_##_BITNR ) /* IO_STATE_VALUE returns a constant corresponding to a one of the symbolic states that the bitfield can have. (Not shifted) */ -#define IO_STATE_VALUE(reg,field,state) ( reg##__##field##__##state ) +#define IO_STATE_VALUE(reg, field, state) \ + IO_STATE_VALUE_ (reg##_, field##_, _##state) +#define IO_STATE_VALUE_(reg_, field_, _state) ( reg_##_##field_##_state ) /* IO_FIELD shifts the val parameter to be aligned with the bitfield specified. */ -#define IO_FIELD(reg,field,val) ((val) << reg##__##field##__BITNR) +#define IO_FIELD(reg, field, val) IO_FIELD_ (reg##_, field##_, val) +#define IO_FIELD_(reg_, field_, val) ((val) << reg_##_##field_##_BITNR) /* IO_BITNR returns the starting bitnumber of a bitfield. Bit 0 is LSB and the returned bitnumber is LSB of the field. */ -#define IO_BITNR(reg,field) (reg##__##field##__BITNR) +#define IO_BITNR(reg, field) IO_BITNR_ (reg##_, field##_) +#define IO_BITNR_(reg_, field_) (reg_##_##field_##_BITNR) /* IO_WIDTH returns the width, in bits, of a bitfield. */ -#define IO_WIDTH(reg,field) (reg##__##field##__WIDTH) +#define IO_WIDTH(reg, field) IO_WIDTH_ (reg##_, field##_) +#define IO_WIDTH_(reg_, field_) (reg_##_##field_##_WIDTH) /*--- Obsolete. Kept for backw compatibility. ---*/ /* Reads (or writes) a byte/uword/udword from the specified mode @@ -66,7 +74,9 @@ !*-----------------------------------------------------------*/ #define MEM_CSE0_START (0x00000000) +#define MEM_CSE0_SIZE (0x04000000) #define MEM_CSE1_START (0x04000000) +#define MEM_CSE1_SIZE (0x04000000) #define MEM_CSR0_START (0x08000000) #define MEM_CSR1_START (0x0c000000) #define MEM_CSP0_START (0x10000000) diff --git a/include/asm-cris/svinto.h b/include/asm-cris/arch-v10/svinto.h index c0a16650a20e..0881a1af7cee 100644 --- a/include/asm-cris/svinto.h +++ b/include/asm-cris/arch-v10/svinto.h @@ -58,4 +58,7 @@ typedef struct etrax_dma_descr { */ #define WAIT_DMA( n ) WAIT_DMA_NUM( n ) +extern void prepare_rx_descriptor(struct etrax_dma_descr *desc); +extern void flush_etrax_cache(void); + #endif diff --git a/include/asm-cris/arch-v10/system.h b/include/asm-cris/arch-v10/system.h new file mode 100644 index 000000000000..781ca30229a8 --- /dev/null +++ b/include/asm-cris/arch-v10/system.h @@ -0,0 +1,62 @@ +#ifndef __ASM_CRIS_ARCH_SYSTEM_H +#define __ASM_CRIS_ARCH_SYSTEM_H + +#include <linux/config.h> + +/* read the CPU version register */ + +extern inline unsigned long rdvr(void) { + unsigned char vr; + __asm__ volatile ("move $vr,%0" : "=rm" (vr)); + return vr; +} + +/* read/write the user-mode stackpointer */ + +extern inline unsigned long rdusp(void) { + unsigned long usp; + __asm__ __volatile__("move $usp,%0" : "=rm" (usp)); + return usp; +} + +#define wrusp(usp) \ + __asm__ __volatile__("move %0,$usp" : /* no outputs */ : "rm" (usp)) + +/* read the current stackpointer */ + +extern inline unsigned long rdsp(void) { + unsigned long sp; + __asm__ __volatile__("move.d $sp,%0" : "=rm" (sp)); + return sp; +} + +extern inline unsigned long _get_base(char * addr) +{ + return 0; +} + +#define nop() __asm__ __volatile__ ("nop"); + +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define tas(ptr) (xchg((ptr),1)) + +struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((struct __xchg_dummy *)(x)) + +/* interrupt control.. */ +#define local_save_flags(x) __asm__ __volatile__ ("move $ccr,%0" : "=rm" (x) : : "memory"); +#define local_irq_restore(x) __asm__ __volatile__ ("move %0,$ccr" : : "rm" (x) : "memory"); +#define local_irq_disable() __asm__ __volatile__ ( "di" : : :"memory"); +#define local_irq_enable() __asm__ __volatile__ ( "ei" : : :"memory"); + +#define irqs_disabled() \ +({ \ + unsigned long flags; \ + local_save_flags(flags); \ + !(flags & (1<<5)); \ +}) + +/* For spinlocks etc */ +#define local_irq_save(x) __asm__ __volatile__ ("move $ccr,%0\n\tdi" : "=rm" (x) : : "memory"); + +#endif diff --git a/include/asm-cris/arch-v10/thread_info.h b/include/asm-cris/arch-v10/thread_info.h new file mode 100644 index 000000000000..357f5df0c907 --- /dev/null +++ b/include/asm-cris/arch-v10/thread_info.h @@ -0,0 +1,12 @@ +#ifndef _ASM_ARCH_THREAD_INFO_H +#define _ASM_ARCH_THREAD_INFO_H + +/* how to get the thread information struct from C */ +extern inline struct thread_info *current_thread_info(void) +{ + struct thread_info *ti; + __asm__("and.d $sp,%0; ":"=r" (ti) : "0" (~8191UL)); + return ti; +} + +#endif diff --git a/include/asm-cris/arch-v10/timex.h b/include/asm-cris/arch-v10/timex.h new file mode 100644 index 000000000000..ecfc553c06a5 --- /dev/null +++ b/include/asm-cris/arch-v10/timex.h @@ -0,0 +1,30 @@ +/* + * Use prescale timer at 25000 Hz instead of the baudrate timer at + * 19200 to get rid of the 64ppm to fast timer (and we get better + * resolution within a jiffie as well. + */ +#ifndef _ASM_CRIS_ARCH_TIMEX_H +#define _ASM_CRIS_ARCH_TIMEX_H + +/* The prescaler clock runs at 25MHz, we divide it by 1000 in the prescaler */ +/* If you change anything here you must check time.c as well... */ +#define PRESCALE_FREQ 25000000 +#define PRESCALE_VALUE 1000 +#define CLOCK_TICK_RATE 25000 /* Underlying frequency of the HZ timer */ +/* The timer0 values gives 40us resolution (1/25000) but interrupts at HZ*/ +#define TIMER0_FREQ (CLOCK_TICK_RATE) +#define TIMER0_CLKSEL flexible +#define TIMER0_DIV (TIMER0_FREQ/(HZ)) + + +#define GET_JIFFIES_USEC() \ + ( (TIMER0_DIV - *R_TIMER0_DATA) * (1000000/HZ)/TIMER0_DIV ) + +unsigned long get_ns_in_jiffie(void); + +extern inline unsigned long get_us_in_jiffie_highres(void) +{ + return get_ns_in_jiffie()/1000; +} + +#endif diff --git a/include/asm-cris/arch-v10/tlb.h b/include/asm-cris/arch-v10/tlb.h new file mode 100644 index 000000000000..31525bbe75c3 --- /dev/null +++ b/include/asm-cris/arch-v10/tlb.h @@ -0,0 +1,13 @@ +#ifndef _CRIS_ARCH_TLB_H +#define _CRIS_ARCH_TLB_H + +/* The TLB can host up to 64 different mm contexts at the same time. + * The last page_id is never running - it is used as an invalid page_id + * so we can make TLB entries that will never match. + */ +#define NUM_TLB_ENTRIES 64 +#define NUM_PAGEID 64 +#define INVALID_PAGEID 63 +#define NO_CONTEXT -1 + +#endif diff --git a/include/asm-cris/arch-v10/uaccess.h b/include/asm-cris/arch-v10/uaccess.h new file mode 100644 index 000000000000..787d2e60c83c --- /dev/null +++ b/include/asm-cris/arch-v10/uaccess.h @@ -0,0 +1,660 @@ +/* + * Authors: Bjorn Wesen (bjornw@axis.com) + * Hans-Peter Nilsson (hp@axis.com) + * + */ +#ifndef _CRIS_ARCH_UACCESS_H +#define _CRIS_ARCH_UACCESS_H + +/* + * We don't tell gcc that we are accessing memory, but this is OK + * because we do not write to any memory gcc knows about, so there + * are no aliasing issues. + * + * Note that PC at a fault is the address *after* the faulting + * instruction. + */ +#define __put_user_asm(x, addr, err, op) \ + __asm__ __volatile__( \ + " "op" %1,[%2]\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + "3: move.d %3,%0\n" \ + " jump 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .dword 2b,3b\n" \ + " .previous\n" \ + : "=r" (err) \ + : "r" (x), "r" (addr), "g" (-EFAULT), "0" (err)) + +#define __put_user_asm_64(x, addr, err) \ + __asm__ __volatile__( \ + " move.d %M1,[%2]\n" \ + "2: move.d %H1,[%2+4]\n" \ + "4:\n" \ + " .section .fixup,\"ax\"\n" \ + "3: move.d %3,%0\n" \ + " jump 4b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .dword 2b,3b\n" \ + " .dword 4b,3b\n" \ + " .previous\n" \ + : "=r" (err) \ + : "r" (x), "r" (addr), "g" (-EFAULT), "0" (err)) + +/* See comment before __put_user_asm. */ + +#define __get_user_asm(x, addr, err, op) \ + __asm__ __volatile__( \ + " "op" [%2],%1\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + "3: move.d %3,%0\n" \ + " moveq 0,%1\n" \ + " jump 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .dword 2b,3b\n" \ + " .previous\n" \ + : "=r" (err), "=r" (x) \ + : "r" (addr), "g" (-EFAULT), "0" (err)) + +#define __get_user_asm_64(x, addr, err) \ + __asm__ __volatile__( \ + " move.d [%2],%M1\n" \ + "2: move.d [%2+4],%H1\n" \ + "4:\n" \ + " .section .fixup,\"ax\"\n" \ + "3: move.d %3,%0\n" \ + " moveq 0,%1\n" \ + " jump 4b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .dword 2b,3b\n" \ + " .dword 4b,3b\n" \ + " .previous\n" \ + : "=r" (err), "=r" (x) \ + : "r" (addr), "g" (-EFAULT), "0" (err)) + +/* + * Copy a null terminated string from userspace. + * + * Must return: + * -EFAULT for an exception + * count if we hit the buffer limit + * bytes copied if we hit a null byte + * (without the null byte) + */ +extern inline long +__do_strncpy_from_user(char *dst, const char *src, long count) +{ + long res; + + if (count == 0) + return 0; + + /* + * Currently, in 2.4.0-test9, most ports use a simple byte-copy loop. + * So do we. + * + * This code is deduced from: + * + * char tmp2; + * long tmp1, tmp3 + * tmp1 = count; + * while ((*dst++ = (tmp2 = *src++)) != 0 + * && --tmp1) + * ; + * + * res = count - tmp1; + * + * with tweaks. + */ + + __asm__ __volatile__ ( + " move.d %3,%0\n" + " move.b [%2+],$r9\n" + "1: beq 2f\n" + " move.b $r9,[%1+]\n" + + " subq 1,%0\n" + " bne 1b\n" + " move.b [%2+],$r9\n" + + "2: sub.d %3,%0\n" + " neg.d %0,%0\n" + "3:\n" + " .section .fixup,\"ax\"\n" + "4: move.d %7,%0\n" + " jump 3b\n" + + /* There's one address for a fault at the first move, and + two possible PC values for a fault at the second move, + being a delay-slot filler. However, the branch-target + for the second move is the same as the first address. + Just so you don't get confused... */ + " .previous\n" + " .section __ex_table,\"a\"\n" + " .dword 1b,4b\n" + " .dword 2b,4b\n" + " .previous" + : "=r" (res), "=r" (dst), "=r" (src), "=r" (count) + : "3" (count), "1" (dst), "2" (src), "g" (-EFAULT) + : "r9"); + + return res; +} + +/* A few copy asms to build up the more complex ones from. + + Note again, a post-increment is performed regardless of whether a bus + fault occurred in that instruction, and PC for a faulted insn is the + address *after* the insn. */ + +#define __asm_copy_user_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm__ __volatile__ ( \ + COPY \ + "1:\n" \ + " .section .fixup,\"ax\"\n" \ + FIXUP \ + " jump 1b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + TENTRY \ + " .previous\n" \ + : "=r" (to), "=r" (from), "=r" (ret) \ + : "0" (to), "1" (from), "2" (ret) \ + : "r9", "memory") + +#define __asm_copy_from_user_1(to, from, ret) \ + __asm_copy_user_cont(to, from, ret, \ + " move.b [%1+],$r9\n" \ + "2: move.b $r9,[%0+]\n", \ + "3: addq 1,%2\n" \ + " clear.b [%0+]\n", \ + " .dword 2b,3b\n") + +#define __asm_copy_from_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_user_cont(to, from, ret, \ + " move.w [%1+],$r9\n" \ + "2: move.w $r9,[%0+]\n" COPY, \ + "3: addq 2,%2\n" \ + " clear.w [%0+]\n" FIXUP, \ + " .dword 2b,3b\n" TENTRY) + +#define __asm_copy_from_user_2(to, from, ret) \ + __asm_copy_from_user_2x_cont(to, from, ret, "", "", "") + +#define __asm_copy_from_user_3(to, from, ret) \ + __asm_copy_from_user_2x_cont(to, from, ret, \ + " move.b [%1+],$r9\n" \ + "4: move.b $r9,[%0+]\n", \ + "5: addq 1,%2\n" \ + " clear.b [%0+]\n", \ + " .dword 4b,5b\n") + +#define __asm_copy_from_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_user_cont(to, from, ret, \ + " move.d [%1+],$r9\n" \ + "2: move.d $r9,[%0+]\n" COPY, \ + "3: addq 4,%2\n" \ + " clear.d [%0+]\n" FIXUP, \ + " .dword 2b,3b\n" TENTRY) + +#define __asm_copy_from_user_4(to, from, ret) \ + __asm_copy_from_user_4x_cont(to, from, ret, "", "", "") + +#define __asm_copy_from_user_5(to, from, ret) \ + __asm_copy_from_user_4x_cont(to, from, ret, \ + " move.b [%1+],$r9\n" \ + "4: move.b $r9,[%0+]\n", \ + "5: addq 1,%2\n" \ + " clear.b [%0+]\n", \ + " .dword 4b,5b\n") + +#define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_from_user_4x_cont(to, from, ret, \ + " move.w [%1+],$r9\n" \ + "4: move.w $r9,[%0+]\n" COPY, \ + "5: addq 2,%2\n" \ + " clear.w [%0+]\n" FIXUP, \ + " .dword 4b,5b\n" TENTRY) + +#define __asm_copy_from_user_6(to, from, ret) \ + __asm_copy_from_user_6x_cont(to, from, ret, "", "", "") + +#define __asm_copy_from_user_7(to, from, ret) \ + __asm_copy_from_user_6x_cont(to, from, ret, \ + " move.b [%1+],$r9\n" \ + "6: move.b $r9,[%0+]\n", \ + "7: addq 1,%2\n" \ + " clear.b [%0+]\n", \ + " .dword 6b,7b\n") + +#define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_from_user_4x_cont(to, from, ret, \ + " move.d [%1+],$r9\n" \ + "4: move.d $r9,[%0+]\n" COPY, \ + "5: addq 4,%2\n" \ + " clear.d [%0+]\n" FIXUP, \ + " .dword 4b,5b\n" TENTRY) + +#define __asm_copy_from_user_8(to, from, ret) \ + __asm_copy_from_user_8x_cont(to, from, ret, "", "", "") + +#define __asm_copy_from_user_9(to, from, ret) \ + __asm_copy_from_user_8x_cont(to, from, ret, \ + " move.b [%1+],$r9\n" \ + "6: move.b $r9,[%0+]\n", \ + "7: addq 1,%2\n" \ + " clear.b [%0+]\n", \ + " .dword 6b,7b\n") + +#define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_from_user_8x_cont(to, from, ret, \ + " move.w [%1+],$r9\n" \ + "6: move.w $r9,[%0+]\n" COPY, \ + "7: addq 2,%2\n" \ + " clear.w [%0+]\n" FIXUP, \ + " .dword 6b,7b\n" TENTRY) + +#define __asm_copy_from_user_10(to, from, ret) \ + __asm_copy_from_user_10x_cont(to, from, ret, "", "", "") + +#define __asm_copy_from_user_11(to, from, ret) \ + __asm_copy_from_user_10x_cont(to, from, ret, \ + " move.b [%1+],$r9\n" \ + "8: move.b $r9,[%0+]\n", \ + "9: addq 1,%2\n" \ + " clear.b [%0+]\n", \ + " .dword 8b,9b\n") + +#define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_from_user_8x_cont(to, from, ret, \ + " move.d [%1+],$r9\n" \ + "6: move.d $r9,[%0+]\n" COPY, \ + "7: addq 4,%2\n" \ + " clear.d [%0+]\n" FIXUP, \ + " .dword 6b,7b\n" TENTRY) + +#define __asm_copy_from_user_12(to, from, ret) \ + __asm_copy_from_user_12x_cont(to, from, ret, "", "", "") + +#define __asm_copy_from_user_13(to, from, ret) \ + __asm_copy_from_user_12x_cont(to, from, ret, \ + " move.b [%1+],$r9\n" \ + "8: move.b $r9,[%0+]\n", \ + "9: addq 1,%2\n" \ + " clear.b [%0+]\n", \ + " .dword 8b,9b\n") + +#define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_from_user_12x_cont(to, from, ret, \ + " move.w [%1+],$r9\n" \ + "8: move.w $r9,[%0+]\n" COPY, \ + "9: addq 2,%2\n" \ + " clear.w [%0+]\n" FIXUP, \ + " .dword 8b,9b\n" TENTRY) + +#define __asm_copy_from_user_14(to, from, ret) \ + __asm_copy_from_user_14x_cont(to, from, ret, "", "", "") + +#define __asm_copy_from_user_15(to, from, ret) \ + __asm_copy_from_user_14x_cont(to, from, ret, \ + " move.b [%1+],$r9\n" \ + "10: move.b $r9,[%0+]\n", \ + "11: addq 1,%2\n" \ + " clear.b [%0+]\n", \ + " .dword 10b,11b\n") + +#define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_from_user_12x_cont(to, from, ret, \ + " move.d [%1+],$r9\n" \ + "8: move.d $r9,[%0+]\n" COPY, \ + "9: addq 4,%2\n" \ + " clear.d [%0+]\n" FIXUP, \ + " .dword 8b,9b\n" TENTRY) + +#define __asm_copy_from_user_16(to, from, ret) \ + __asm_copy_from_user_16x_cont(to, from, ret, "", "", "") + +#define __asm_copy_from_user_20x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_from_user_16x_cont(to, from, ret, \ + " move.d [%1+],$r9\n" \ + "10: move.d $r9,[%0+]\n" COPY, \ + "11: addq 4,%2\n" \ + " clear.d [%0+]\n" FIXUP, \ + " .dword 10b,11b\n" TENTRY) + +#define __asm_copy_from_user_20(to, from, ret) \ + __asm_copy_from_user_20x_cont(to, from, ret, "", "", "") + +#define __asm_copy_from_user_24x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_from_user_20x_cont(to, from, ret, \ + " move.d [%1+],$r9\n" \ + "12: move.d $r9,[%0+]\n" COPY, \ + "13: addq 4,%2\n" \ + " clear.d [%0+]\n" FIXUP, \ + " .dword 12b,13b\n" TENTRY) + +#define __asm_copy_from_user_24(to, from, ret) \ + __asm_copy_from_user_24x_cont(to, from, ret, "", "", "") + +/* And now, the to-user ones. */ + +#define __asm_copy_to_user_1(to, from, ret) \ + __asm_copy_user_cont(to, from, ret, \ + " move.b [%1+],$r9\n" \ + " move.b $r9,[%0+]\n2:\n", \ + "3: addq 1,%2\n", \ + " .dword 2b,3b\n") + +#define __asm_copy_to_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_user_cont(to, from, ret, \ + " move.w [%1+],$r9\n" \ + " move.w $r9,[%0+]\n2:\n" COPY, \ + "3: addq 2,%2\n" FIXUP, \ + " .dword 2b,3b\n" TENTRY) + +#define __asm_copy_to_user_2(to, from, ret) \ + __asm_copy_to_user_2x_cont(to, from, ret, "", "", "") + +#define __asm_copy_to_user_3(to, from, ret) \ + __asm_copy_to_user_2x_cont(to, from, ret, \ + " move.b [%1+],$r9\n" \ + " move.b $r9,[%0+]\n4:\n", \ + "5: addq 1,%2\n", \ + " .dword 4b,5b\n") + +#define __asm_copy_to_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_user_cont(to, from, ret, \ + " move.d [%1+],$r9\n" \ + " move.d $r9,[%0+]\n2:\n" COPY, \ + "3: addq 4,%2\n" FIXUP, \ + " .dword 2b,3b\n" TENTRY) + +#define __asm_copy_to_user_4(to, from, ret) \ + __asm_copy_to_user_4x_cont(to, from, ret, "", "", "") + +#define __asm_copy_to_user_5(to, from, ret) \ + __asm_copy_to_user_4x_cont(to, from, ret, \ + " move.b [%1+],$r9\n" \ + " move.b $r9,[%0+]\n4:\n", \ + "5: addq 1,%2\n", \ + " .dword 4b,5b\n") + +#define __asm_copy_to_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_to_user_4x_cont(to, from, ret, \ + " move.w [%1+],$r9\n" \ + " move.w $r9,[%0+]\n4:\n" COPY, \ + "5: addq 2,%2\n" FIXUP, \ + " .dword 4b,5b\n" TENTRY) + +#define __asm_copy_to_user_6(to, from, ret) \ + __asm_copy_to_user_6x_cont(to, from, ret, "", "", "") + +#define __asm_copy_to_user_7(to, from, ret) \ + __asm_copy_to_user_6x_cont(to, from, ret, \ + " move.b [%1+],$r9\n" \ + " move.b $r9,[%0+]\n6:\n", \ + "7: addq 1,%2\n", \ + " .dword 6b,7b\n") + +#define __asm_copy_to_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_to_user_4x_cont(to, from, ret, \ + " move.d [%1+],$r9\n" \ + " move.d $r9,[%0+]\n4:\n" COPY, \ + "5: addq 4,%2\n" FIXUP, \ + " .dword 4b,5b\n" TENTRY) + +#define __asm_copy_to_user_8(to, from, ret) \ + __asm_copy_to_user_8x_cont(to, from, ret, "", "", "") + +#define __asm_copy_to_user_9(to, from, ret) \ + __asm_copy_to_user_8x_cont(to, from, ret, \ + " move.b [%1+],$r9\n" \ + " move.b $r9,[%0+]\n6:\n", \ + "7: addq 1,%2\n", \ + " .dword 6b,7b\n") + +#define __asm_copy_to_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_to_user_8x_cont(to, from, ret, \ + " move.w [%1+],$r9\n" \ + " move.w $r9,[%0+]\n6:\n" COPY, \ + "7: addq 2,%2\n" FIXUP, \ + " .dword 6b,7b\n" TENTRY) + +#define __asm_copy_to_user_10(to, from, ret) \ + __asm_copy_to_user_10x_cont(to, from, ret, "", "", "") + +#define __asm_copy_to_user_11(to, from, ret) \ + __asm_copy_to_user_10x_cont(to, from, ret, \ + " move.b [%1+],$r9\n" \ + " move.b $r9,[%0+]\n8:\n", \ + "9: addq 1,%2\n", \ + " .dword 8b,9b\n") + +#define __asm_copy_to_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_to_user_8x_cont(to, from, ret, \ + " move.d [%1+],$r9\n" \ + " move.d $r9,[%0+]\n6:\n" COPY, \ + "7: addq 4,%2\n" FIXUP, \ + " .dword 6b,7b\n" TENTRY) + +#define __asm_copy_to_user_12(to, from, ret) \ + __asm_copy_to_user_12x_cont(to, from, ret, "", "", "") + +#define __asm_copy_to_user_13(to, from, ret) \ + __asm_copy_to_user_12x_cont(to, from, ret, \ + " move.b [%1+],$r9\n" \ + " move.b $r9,[%0+]\n8:\n", \ + "9: addq 1,%2\n", \ + " .dword 8b,9b\n") + +#define __asm_copy_to_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_to_user_12x_cont(to, from, ret, \ + " move.w [%1+],$r9\n" \ + " move.w $r9,[%0+]\n8:\n" COPY, \ + "9: addq 2,%2\n" FIXUP, \ + " .dword 8b,9b\n" TENTRY) + +#define __asm_copy_to_user_14(to, from, ret) \ + __asm_copy_to_user_14x_cont(to, from, ret, "", "", "") + +#define __asm_copy_to_user_15(to, from, ret) \ + __asm_copy_to_user_14x_cont(to, from, ret, \ + " move.b [%1+],$r9\n" \ + " move.b $r9,[%0+]\n10:\n", \ + "11: addq 1,%2\n", \ + " .dword 10b,11b\n") + +#define __asm_copy_to_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_to_user_12x_cont(to, from, ret, \ + " move.d [%1+],$r9\n" \ + " move.d $r9,[%0+]\n8:\n" COPY, \ + "9: addq 4,%2\n" FIXUP, \ + " .dword 8b,9b\n" TENTRY) + +#define __asm_copy_to_user_16(to, from, ret) \ + __asm_copy_to_user_16x_cont(to, from, ret, "", "", "") + +#define __asm_copy_to_user_20x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_to_user_16x_cont(to, from, ret, \ + " move.d [%1+],$r9\n" \ + " move.d $r9,[%0+]\n10:\n" COPY, \ + "11: addq 4,%2\n" FIXUP, \ + " .dword 10b,11b\n" TENTRY) + +#define __asm_copy_to_user_20(to, from, ret) \ + __asm_copy_to_user_20x_cont(to, from, ret, "", "", "") + +#define __asm_copy_to_user_24x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_to_user_20x_cont(to, from, ret, \ + " move.d [%1+],$r9\n" \ + " move.d $r9,[%0+]\n12:\n" COPY, \ + "13: addq 4,%2\n" FIXUP, \ + " .dword 12b,13b\n" TENTRY) + +#define __asm_copy_to_user_24(to, from, ret) \ + __asm_copy_to_user_24x_cont(to, from, ret, "", "", "") + +/* Define a few clearing asms with exception handlers. */ + +/* This frame-asm is like the __asm_copy_user_cont one, but has one less + input. */ + +#define __asm_clear(to, ret, CLEAR, FIXUP, TENTRY) \ + __asm__ __volatile__ ( \ + CLEAR \ + "1:\n" \ + " .section .fixup,\"ax\"\n" \ + FIXUP \ + " jump 1b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + TENTRY \ + " .previous" \ + : "=r" (to), "=r" (ret) \ + : "0" (to), "1" (ret) \ + : "memory") + +#define __asm_clear_1(to, ret) \ + __asm_clear(to, ret, \ + " clear.b [%0+]\n2:\n", \ + "3: addq 1,%1\n", \ + " .dword 2b,3b\n") + +#define __asm_clear_2(to, ret) \ + __asm_clear(to, ret, \ + " clear.w [%0+]\n2:\n", \ + "3: addq 2,%1\n", \ + " .dword 2b,3b\n") + +#define __asm_clear_3(to, ret) \ + __asm_clear(to, ret, \ + " clear.w [%0+]\n" \ + "2: clear.b [%0+]\n3:\n", \ + "4: addq 2,%1\n" \ + "5: addq 1,%1\n", \ + " .dword 2b,4b\n" \ + " .dword 3b,5b\n") + +#define __asm_clear_4x_cont(to, ret, CLEAR, FIXUP, TENTRY) \ + __asm_clear(to, ret, \ + " clear.d [%0+]\n2:\n" CLEAR, \ + "3: addq 4,%1\n" FIXUP, \ + " .dword 2b,3b\n" TENTRY) + +#define __asm_clear_4(to, ret) \ + __asm_clear_4x_cont(to, ret, "", "", "") + +#define __asm_clear_8x_cont(to, ret, CLEAR, FIXUP, TENTRY) \ + __asm_clear_4x_cont(to, ret, \ + " clear.d [%0+]\n4:\n" CLEAR, \ + "5: addq 4,%1\n" FIXUP, \ + " .dword 4b,5b\n" TENTRY) + +#define __asm_clear_8(to, ret) \ + __asm_clear_8x_cont(to, ret, "", "", "") + +#define __asm_clear_12x_cont(to, ret, CLEAR, FIXUP, TENTRY) \ + __asm_clear_8x_cont(to, ret, \ + " clear.d [%0+]\n6:\n" CLEAR, \ + "7: addq 4,%1\n" FIXUP, \ + " .dword 6b,7b\n" TENTRY) + +#define __asm_clear_12(to, ret) \ + __asm_clear_12x_cont(to, ret, "", "", "") + +#define __asm_clear_16x_cont(to, ret, CLEAR, FIXUP, TENTRY) \ + __asm_clear_12x_cont(to, ret, \ + " clear.d [%0+]\n8:\n" CLEAR, \ + "9: addq 4,%1\n" FIXUP, \ + " .dword 8b,9b\n" TENTRY) + +#define __asm_clear_16(to, ret) \ + __asm_clear_16x_cont(to, ret, "", "", "") + +#define __asm_clear_20x_cont(to, ret, CLEAR, FIXUP, TENTRY) \ + __asm_clear_16x_cont(to, ret, \ + " clear.d [%0+]\n10:\n" CLEAR, \ + "11: addq 4,%1\n" FIXUP, \ + " .dword 10b,11b\n" TENTRY) + +#define __asm_clear_20(to, ret) \ + __asm_clear_20x_cont(to, ret, "", "", "") + +#define __asm_clear_24x_cont(to, ret, CLEAR, FIXUP, TENTRY) \ + __asm_clear_20x_cont(to, ret, \ + " clear.d [%0+]\n12:\n" CLEAR, \ + "13: addq 4,%1\n" FIXUP, \ + " .dword 12b,13b\n" TENTRY) + +#define __asm_clear_24(to, ret) \ + __asm_clear_24x_cont(to, ret, "", "", "") + +/* + * Return the size of a string (including the ending 0) + * + * Return length of string in userspace including terminating 0 + * or 0 for error. Return a value greater than N if too long. + */ + +extern inline long +strnlen_user(const char *s, long n) +{ + long res, tmp1; + + if (!access_ok(VERIFY_READ, s, 0)) + return 0; + + /* + * This code is deduced from: + * + * tmp1 = n; + * while (tmp1-- > 0 && *s++) + * ; + * + * res = n - tmp1; + * + * (with tweaks). + */ + + __asm__ __volatile__ ( + " move.d %1,$r9\n" + "0:\n" + " ble 1f\n" + " subq 1,$r9\n" + + " test.b [%0+]\n" + " bne 0b\n" + " test.d $r9\n" + "1:\n" + " move.d %1,%0\n" + " sub.d $r9,%0\n" + "2:\n" + " .section .fixup,\"ax\"\n" + + "3: clear.d %0\n" + " jump 2b\n" + + /* There's one address for a fault at the first move, and + two possible PC values for a fault at the second move, + being a delay-slot filler. However, the branch-target + for the second move is the same as the first address. + Just so you don't get confused... */ + " .previous\n" + " .section __ex_table,\"a\"\n" + " .dword 0b,3b\n" + " .dword 1b,3b\n" + " .previous\n" + : "=r" (res), "=r" (tmp1) + : "0" (s), "1" (n) + : "r9"); + + return res; +} + +#endif diff --git a/include/asm-cris/arch-v10/unistd.h b/include/asm-cris/arch-v10/unistd.h new file mode 100644 index 000000000000..d1a38b9e6264 --- /dev/null +++ b/include/asm-cris/arch-v10/unistd.h @@ -0,0 +1,148 @@ +#ifndef _ASM_CRIS_ARCH_UNISTD_H_ +#define _ASM_CRIS_ARCH_UNISTD_H_ + +/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ +/* + * Don't remove the .ifnc tests; they are an insurance against + * any hard-to-spot gcc register allocation bugs. + */ +#define _syscall0(type,name) \ +type name(void) \ +{ \ + register long __a __asm__ ("r10"); \ + register long __n_ __asm__ ("r9") = (__NR_##name); \ + __asm__ __volatile__ (".ifnc %0%1,$r10$r9\n\t" \ + ".err\n\t" \ + ".endif\n\t" \ + "break 13" \ + : "=r" (__a) \ + : "r" (__n_)); \ + if (__a >= 0) \ + return (type) __a; \ + errno = -__a; \ + return (type) -1; \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ + register long __a __asm__ ("r10") = (long) arg1; \ + register long __n_ __asm__ ("r9") = (__NR_##name); \ + __asm__ __volatile__ (".ifnc %0%1,$r10$r9\n\t" \ + ".err\n\t" \ + ".endif\n\t" \ + "break 13" \ + : "=r" (__a) \ + : "r" (__n_), "0" (__a)); \ + if (__a >= 0) \ + return (type) __a; \ + errno = -__a; \ + return (type) -1; \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ + register long __a __asm__ ("r10") = (long) arg1; \ + register long __b __asm__ ("r11") = (long) arg2; \ + register long __n_ __asm__ ("r9") = (__NR_##name); \ + __asm__ __volatile__ (".ifnc %0%1%3,$r10$r9$r11\n\t" \ + ".err\n\t" \ + ".endif\n\t" \ + "break 13" \ + : "=r" (__a) \ + : "r" (__n_), "0" (__a), "r" (__b)); \ + if (__a >= 0) \ + return (type) __a; \ + errno = -__a; \ + return (type) -1; \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ + register long __a __asm__ ("r10") = (long) arg1; \ + register long __b __asm__ ("r11") = (long) arg2; \ + register long __c __asm__ ("r12") = (long) arg3; \ + register long __n_ __asm__ ("r9") = (__NR_##name); \ + __asm__ __volatile__ (".ifnc %0%1%3%4,$r10$r9$r11$r12\n\t" \ + ".err\n\t" \ + ".endif\n\t" \ + "break 13" \ + : "=r" (__a) \ + : "r" (__n_), "0" (__a), "r" (__b), "r" (__c)); \ + if (__a >= 0) \ + return (type) __a; \ + errno = -__a; \ + return (type) -1; \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ + register long __a __asm__ ("r10") = (long) arg1; \ + register long __b __asm__ ("r11") = (long) arg2; \ + register long __c __asm__ ("r12") = (long) arg3; \ + register long __d __asm__ ("r13") = (long) arg4; \ + register long __n_ __asm__ ("r9") = (__NR_##name); \ + __asm__ __volatile__ (".ifnc %0%1%3%4%5,$r10$r9$r11$r12$r13\n\t" \ + ".err\n\t" \ + ".endif\n\t" \ + "break 13" \ + : "=r" (__a) \ + : "r" (__n_), "0" (__a), "r" (__b), \ + "r" (__c), "r" (__d)); \ + if (__a >= 0) \ + return (type) __a; \ + errno = -__a; \ + return (type) -1; \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ + register long __a __asm__ ("r10") = (long) arg1; \ + register long __b __asm__ ("r11") = (long) arg2; \ + register long __c __asm__ ("r12") = (long) arg3; \ + register long __d __asm__ ("r13") = (long) arg4; \ + register long __n_ __asm__ ("r9") = (__NR_##name); \ + __asm__ __volatile__ (".ifnc %0%1%3%4%5,$r10$r9$r11$r12$r13\n\t" \ + ".err\n\t" \ + ".endif\n\t" \ + "move %6,$mof\n\t" \ + "break 13" \ + : "=r" (__a) \ + : "r" (__n_), "0" (__a), "r" (__b), \ + "r" (__c), "r" (__d), "g" (arg5)); \ + if (__a >= 0) \ + return (type) __a; \ + errno = -__a; \ + return (type) -1; \ +} + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5,type6,arg6) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ +{ \ + register long __a __asm__ ("r10") = (long) arg1; \ + register long __b __asm__ ("r11") = (long) arg2; \ + register long __c __asm__ ("r12") = (long) arg3; \ + register long __d __asm__ ("r13") = (long) arg4; \ + register long __n_ __asm__ ("r9") = (__NR_##name); \ + __asm__ __volatile__ (".ifnc %0%1%3%4%5,$r10$r9$r11$r12$r13\n\t" \ + ".err\n\t" \ + ".endif\n\t" \ + "move %6,$mof\n\tmove %7,$srp\n\t" \ + "break 13" \ + : "=r" (__a) \ + : "r" (__n_), "0" (__a), "r" (__b), \ + "r" (__c), "r" (__d), "g" (arg5), "g" (arg6)\ + : "srp"); \ + if (__a >= 0) \ + return (type) __a; \ + errno = -__a; \ + return (type) -1; \ +} + +#endif diff --git a/include/asm-cris/arch-v10/user.h b/include/asm-cris/arch-v10/user.h new file mode 100644 index 000000000000..9303ea77c915 --- /dev/null +++ b/include/asm-cris/arch-v10/user.h @@ -0,0 +1,46 @@ +#ifndef __ASM_CRIS_ARCH_USER_H +#define __ASM_CRIS_ARCH_USER_H + +/* User mode registers, used for core dumps. In order to keep ELF_NGREG + sensible we let all registers be 32 bits. The csr registers are included + for future use. */ +struct user_regs_struct { + unsigned long r0; /* General registers. */ + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long r11; + unsigned long r12; + unsigned long r13; + unsigned long sp; /* Stack pointer. */ + unsigned long pc; /* Program counter. */ + unsigned long p0; /* Constant zero (only 8 bits). */ + unsigned long vr; /* Version register (only 8 bits). */ + unsigned long p2; /* Reserved. */ + unsigned long p3; /* Reserved. */ + unsigned long p4; /* Constant zero (only 16 bits). */ + unsigned long ccr; /* Condition code register (only 16 bits). */ + unsigned long p6; /* Reserved. */ + unsigned long mof; /* Multiply overflow register. */ + unsigned long p8; /* Constant zero. */ + unsigned long ibr; /* Not accessible. */ + unsigned long irp; /* Not accessible. */ + unsigned long srp; /* Subroutine return pointer. */ + unsigned long bar; /* Not accessible. */ + unsigned long dccr; /* Dword condition code register. */ + unsigned long brp; /* Not accessible. */ + unsigned long usp; /* User-mode stack pointer. Same as sp when + in user mode. */ + unsigned long csrinstr; /* Internal status registers. */ + unsigned long csraddr; + unsigned long csrdata; +}; + +#endif diff --git a/include/asm-cris/atomic.h b/include/asm-cris/atomic.h index f2f51505d6dc..19ae993cb561 100644 --- a/include/asm-cris/atomic.h +++ b/include/asm-cris/atomic.h @@ -27,115 +27,115 @@ typedef struct { int counter; } atomic_t; /* These should be written in asm but we do it in C for now. */ -static __inline__ void atomic_add(int i, volatile atomic_t *v) +extern __inline__ void atomic_add(int i, volatile atomic_t *v) { unsigned long flags; - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); v->counter += i; - restore_flags(flags); + local_irq_restore(flags); } -static __inline__ void atomic_sub(int i, volatile atomic_t *v) +extern __inline__ void atomic_sub(int i, volatile atomic_t *v) { unsigned long flags; - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); v->counter -= i; - restore_flags(flags); + local_irq_restore(flags); } -static __inline__ int atomic_add_return(int i, volatile atomic_t *v) +extern __inline__ int atomic_add_return(int i, volatile atomic_t *v) { unsigned long flags; int retval; - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); retval = (v->counter += i); - restore_flags(flags); + local_irq_restore(flags); return retval; } -static __inline__ int atomic_sub_return(int i, volatile atomic_t *v) +extern __inline__ int atomic_sub_return(int i, volatile atomic_t *v) { unsigned long flags; int retval; - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); retval = (v->counter -= i); - restore_flags(flags); + local_irq_restore(flags); return retval; } -static __inline__ int atomic_sub_and_test(int i, volatile atomic_t *v) +extern __inline__ int atomic_sub_and_test(int i, volatile atomic_t *v) { int retval; unsigned long flags; - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); retval = (v->counter -= i) == 0; - restore_flags(flags); + local_irq_restore(flags); return retval; } -static __inline__ void atomic_inc(volatile atomic_t *v) +extern __inline__ void atomic_inc(volatile atomic_t *v) { unsigned long flags; - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); (v->counter)++; - restore_flags(flags); + local_irq_restore(flags); } -static __inline__ void atomic_dec(volatile atomic_t *v) +extern __inline__ void atomic_dec(volatile atomic_t *v) { unsigned long flags; - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); (v->counter)--; - restore_flags(flags); + local_irq_restore(flags); } -static __inline__ int atomic_inc_return(volatile atomic_t *v) +extern __inline__ int atomic_inc_return(volatile atomic_t *v) { unsigned long flags; int retval; - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); retval = (v->counter)++; - restore_flags(flags); + local_irq_restore(flags); return retval; } -static __inline__ int atomic_dec_return(volatile atomic_t *v) +extern __inline__ int atomic_dec_return(volatile atomic_t *v) { unsigned long flags; int retval; - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); retval = (v->counter)--; - restore_flags(flags); + local_irq_restore(flags); return retval; } -static __inline__ int atomic_dec_and_test(volatile atomic_t *v) +extern __inline__ int atomic_dec_and_test(volatile atomic_t *v) { int retval; unsigned long flags; - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); retval = --(v->counter) == 0; - restore_flags(flags); + local_irq_restore(flags); return retval; } -static __inline__ int atomic_inc_and_test(volatile atomic_t *v) +extern __inline__ int atomic_inc_and_test(volatile atomic_t *v) { int retval; unsigned long flags; - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); retval = ++(v->counter) == 0; - restore_flags(flags); + local_irq_restore(flags); return retval; } diff --git a/include/asm-cris/axisflashmap.h b/include/asm-cris/axisflashmap.h index c54f65d4a4a7..600bb8715d89 100644 --- a/include/asm-cris/axisflashmap.h +++ b/include/asm-cris/axisflashmap.h @@ -9,25 +9,6 @@ * and it has nothing to do with the partition table. */ - -/* the partitiontable consists of some "jump over" code, a head and - * then the actual entries. - * tools/mkptable is used to generate the ptable. - */ - -/* The partition table starts with code to "jump over" it. The ba - instruction and delay-slot is modified elsewhere (for example the - mkptable script); don't change this to fill the delay-slot. */ -#define PARTITIONTABLE_CODE_START { \ - 0x0f, 0x05, /* nop 0 */\ - 0x25, 0xf0, /* di 2 */\ - 0xed, 0xff /* ba 4 */ } - -/* The actual offset depend on the number of entries */ -#define PARTITIONTABLE_CODE_END { \ - 0x00, 0x00, /* ba offset 6 */\ - 0x0f, 0x05 /* nop 8 */} - #define PARTITION_TABLE_OFFSET 10 #define PARTITION_TABLE_MAGIC 0xbeef /* Not a good magic */ diff --git a/include/asm-cris/bitops.h b/include/asm-cris/bitops.h index 563cc9f6a998..10de1ccd1e01 100644 --- a/include/asm-cris/bitops.h +++ b/include/asm-cris/bitops.h @@ -1,9 +1,6 @@ /* asm/bitops.h for Linux/CRIS * * TODO: asm versions if speed is needed - * set_bit, clear_bit and change_bit wastes cycles being only - * macros into test_and_set_bit etc. - * kernel-doc things (**) for macros are disabled * * All bit operations return 0 if the bit was cleared before the * operation and != 0 if it was not. @@ -17,11 +14,8 @@ /* Currently this is unsuitable for consumption outside the kernel. */ #ifdef __KERNEL__ +#include <asm/arch/bitops.h> #include <asm/system.h> - -/* We use generic_ffs so get it; include guards resolve the possible - mutually inclusion. */ -#include <linux/bitops.h> #include <linux/compiler.h> /* @@ -63,7 +57,7 @@ struct __dummy { unsigned long a[100]; }; /* * change_bit - Toggle a bit in memory - * @nr: Bit to clear + * @nr: Bit to change * @addr: Address to start counting from * * change_bit() is atomic and may not be reordered. @@ -75,7 +69,7 @@ struct __dummy { unsigned long a[100]; }; /* * __change_bit - Toggle a bit in memory - * @nr: the bit to set + * @nr: the bit to change * @addr: the address to start counting from * * Unlike change_bit(), this function is non-atomic and may be reordered. @@ -94,7 +88,7 @@ struct __dummy { unsigned long a[100]; }; * It also implies a memory barrier. */ -static inline int test_and_set_bit(int nr, void *addr) +extern inline int test_and_set_bit(int nr, void *addr) { unsigned int mask, retval; unsigned long flags; @@ -102,15 +96,15 @@ static inline int test_and_set_bit(int nr, void *addr) adr += nr >> 5; mask = 1 << (nr & 0x1f); - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); retval = (mask & *adr) != 0; *adr |= mask; - restore_flags(flags); + local_irq_restore(flags); return retval; } -static inline int __test_and_set_bit(int nr, void *addr) +extern inline int __test_and_set_bit(int nr, void *addr) { unsigned int mask, retval; unsigned int *adr = (unsigned int *)addr; @@ -130,14 +124,14 @@ static inline int __test_and_set_bit(int nr, void *addr) /** * test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set + * @nr: Bit to clear * @addr: Address to count from * * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -static inline int test_and_clear_bit(int nr, void *addr) +extern inline int test_and_clear_bit(int nr, void *addr) { unsigned int mask, retval; unsigned long flags; @@ -145,17 +139,17 @@ static inline int test_and_clear_bit(int nr, void *addr) adr += nr >> 5; mask = 1 << (nr & 0x1f); - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); retval = (mask & *adr) != 0; *adr &= ~mask; - restore_flags(flags); + local_irq_restore(flags); return retval; } /** * __test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set + * @nr: Bit to clear * @addr: Address to count from * * This operation is non-atomic and can be reordered. @@ -163,7 +157,7 @@ static inline int test_and_clear_bit(int nr, void *addr) * but actually fail. You must protect multiple accesses with a lock. */ -static inline int __test_and_clear_bit(int nr, void *addr) +extern inline int __test_and_clear_bit(int nr, void *addr) { unsigned int mask, retval; unsigned int *adr = (unsigned int *)addr; @@ -176,31 +170,31 @@ static inline int __test_and_clear_bit(int nr, void *addr) } /** * test_and_change_bit - Change a bit and return its new value - * @nr: Bit to set + * @nr: Bit to change * @addr: Address to count from * * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -static inline int test_and_change_bit(int nr, void *addr) +extern inline int test_and_change_bit(int nr, void *addr) { unsigned int mask, retval; unsigned long flags; unsigned int *adr = (unsigned int *)addr; adr += nr >> 5; mask = 1 << (nr & 0x1f); - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); retval = (mask & *adr) != 0; *adr ^= mask; - restore_flags(flags); + local_irq_restore(flags); return retval; } /* WARNING: non atomic and it can be reordered! */ -static inline int __test_and_change_bit(int nr, void *addr) +extern inline int __test_and_change_bit(int nr, void *addr) { unsigned int mask, retval; unsigned int *adr = (unsigned int *)addr; @@ -221,7 +215,7 @@ static inline int __test_and_change_bit(int nr, void *addr) * This routine doesn't need to be atomic. */ -static inline int test_bit(int nr, const void *addr) +extern inline int test_bit(int nr, const void *addr) { unsigned int mask; unsigned int *adr = (unsigned int *)addr; @@ -236,63 +230,28 @@ static inline int test_bit(int nr, const void *addr) */ /* - * Helper functions for the core of the ff[sz] functions, wrapping the - * syntactically awkward asms. The asms compute the number of leading - * zeroes of a bits-in-byte and byte-in-word and word-in-dword-swapped - * number. They differ in that the first function also inverts all bits - * in the input. + * Since we define it "external", it collides with the built-in + * definition, which doesn't have the same semantics. We don't want to + * use -fno-builtin, so just hide the name ffs. */ -static inline unsigned long cris_swapnwbrlz(unsigned long w) -{ - /* Let's just say we return the result in the same register as the - input. Saying we clobber the input but can return the result - in another register: - ! __asm__ ("swapnwbr %2\n\tlz %2,%0" - ! : "=r,r" (res), "=r,X" (dummy) : "1,0" (w)); - confuses gcc (sched.c, gcc from cris-dist-1.14). */ - - unsigned long res; - __asm__ ("swapnwbr %0 \n\t" - "lz %0,%0" - : "=r" (res) : "0" (w)); - return res; -} - -static inline unsigned long cris_swapwbrlz(unsigned long w) -{ - unsigned res; - __asm__ ("swapwbr %0 \n\t" - "lz %0,%0" - : "=r" (res) - : "0" (w)); - return res; -} +#define ffs kernel_ffs /* - * ffz = Find First Zero in word. Undefined if no zero exists, - * so code should check against ~0UL first.. + * fls: find last bit set. */ -static inline unsigned long ffz(unsigned long w) -{ - /* The generic_ffs function is used to avoid the asm when the - argument is a constant. */ - return __builtin_constant_p (w) - ? (~w ? (unsigned long) generic_ffs ((int) ~w) - 1 : 32) - : cris_swapnwbrlz (w); -} + +#define fls(x) generic_fls(x) /* - * Somewhat like ffz but the equivalent of generic_ffs: in contrast to - * ffz we return the first one-bit *plus one*. + * hweightN - returns the hamming weight of a N-bit word + * @x: the word to weigh + * + * The Hamming Weight of a number is the total number of bits set in it. */ -static inline unsigned long ffs(unsigned long w) -{ - /* The generic_ffs function is used to avoid the asm when the - argument is a constant. */ - return __builtin_constant_p (w) - ? (unsigned long) generic_ffs ((int) w) - : w ? cris_swapwbrlz (w) + 1 : 0; -} + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) /** * find_next_zero_bit - find the first zero bit in a memory region @@ -300,7 +259,7 @@ static inline unsigned long ffs(unsigned long w) * @offset: The bitnumber to start searching at * @size: The maximum size to search */ -static inline int find_next_zero_bit (void * addr, int size, int offset) +extern inline int find_next_zero_bit (void * addr, int size, int offset) { unsigned long *p = ((unsigned long *) addr) + (offset >> 5); unsigned long result = offset & ~31UL; @@ -348,17 +307,6 @@ static inline int find_next_zero_bit (void * addr, int size, int offset) #define find_first_zero_bit(addr, size) \ find_next_zero_bit((addr), (size), 0) -/* - * hweightN - returns the hamming weight of a N-bit word - * @x: the word to weigh - * - * The Hamming Weight of a number is the total number of bits set in it. - */ - -#define hweight32(x) generic_hweight32(x) -#define hweight16(x) generic_hweight16(x) -#define hweight8(x) generic_hweight8(x) - #define ext2_set_bit test_and_set_bit #define ext2_set_bit_atomic(l,n,a) test_and_set_bit(n,a) #define ext2_clear_bit test_and_clear_bit @@ -373,44 +321,20 @@ static inline int find_next_zero_bit (void * addr, int size, int offset) #define minix_test_bit(nr,addr) test_bit(nr,addr) #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) -#if 0 -/* TODO: see below */ -#define sched_find_first_zero_bit(addr) find_first_zero_bit(addr, 168) - -#else -/* TODO: left out pending where to put it.. (there are .h dependencies) */ - - /* - * Every architecture must define this function. It's the fastest - * way of searching a 168-bit bitmap where the first 128 bits are - * unlikely to be set. It's guaranteed that at least one of the 168 - * bits is cleared. - */ -#if 0 -#if MAX_RT_PRIO != 128 || MAX_PRIO != 168 -# error update this function. -#endif -#else -#define MAX_RT_PRIO 128 -#define MAX_PRIO 168 -#endif - -static inline int sched_find_first_zero_bit(char *bitmap) +extern inline int sched_find_first_bit(unsigned long *b) { - unsigned int *b = (unsigned int *)bitmap; - unsigned int rt; - - rt = b[0] & b[1] & b[2] & b[3]; - if (unlikely(rt != 0xffffffff)) - return find_first_zero_bit(bitmap, MAX_RT_PRIO); - - if (b[4] != ~0) - return ffz(b[4]) + MAX_RT_PRIO; - return ffz(b[5]) + 32 + MAX_RT_PRIO; + if (unlikely(b[0])) + return __ffs(b[0]); + if (unlikely(b[1])) + return __ffs(b[1]) + 32; + if (unlikely(b[2])) + return __ffs(b[2]) + 64; + if (unlikely(b[3])) + return __ffs(b[3]) + 96; + if (b[4]) + return __ffs(b[4]) + 128; + return __ffs(b[5]) + 32 + 128; } -#undef MAX_PRIO -#undef MAX_RT_PRIO -#endif #endif /* __KERNEL__ */ diff --git a/include/asm-cris/byteorder.h b/include/asm-cris/byteorder.h index 64275f6045ef..a1a222adaa9f 100644 --- a/include/asm-cris/byteorder.h +++ b/include/asm-cris/byteorder.h @@ -1,30 +1,9 @@ -/* $Id: byteorder.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $ */ - #ifndef _CRIS_BYTEORDER_H #define _CRIS_BYTEORDER_H -#include <asm/types.h> - #ifdef __GNUC__ -/* we just define these two (as we can do the swap in a single - * asm instruction in CRIS) and the arch-independent files will put - * them together into ntohl etc. - */ - -static __inline__ __const__ __u32 ___arch__swab32(__u32 x) -{ - __asm__ ("swapwb %0" : "=r" (x) : "0" (x)); - - return(x); -} - -static __inline__ __const__ __u16 ___arch__swab16(__u16 x) -{ - __asm__ ("swapb %0" : "=r" (x) : "0" (x)); - - return(x); -} +#include <asm/arch/byteorder.h> /* defines are necessary because the other files detect the presence * of a defined __arch_swab32, not an inline diff --git a/include/asm-cris/cache.h b/include/asm-cris/cache.h index 1899bd77461d..46a3b26e205a 100644 --- a/include/asm-cris/cache.h +++ b/include/asm-cris/cache.h @@ -1,12 +1,6 @@ #ifndef _ASM_CACHE_H #define _ASM_CACHE_H -/* Etrax 100LX have 32-byte cache-lines. When we add support for future chips - * here should be a check for CPU type. - */ - -#define L1_CACHE_BYTES 32 - -#define L1_CACHE_SHIFT_MAX 5 /* largest L1 which this arch supports */ +#include <asm/arch/cache.h> #endif /* _ASM_CACHE_H */ diff --git a/include/asm-cris/cacheflush.h b/include/asm-cris/cacheflush.h new file mode 100644 index 000000000000..6be38857a0ae --- /dev/null +++ b/include/asm-cris/cacheflush.h @@ -0,0 +1,23 @@ +#ifndef _CRIS_CACHEFLUSH_H +#define _CRIS_CACHEFLUSH_H + +/* Keep includes the same across arches. */ +#include <linux/mm.h> + +/* The cache doesn't need to be flushed when TLB entries change because + * the cache is mapped to physical memory, not virtual memory + */ +#define flush_cache_all() 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_page_to_ram(page) do { } while (0) +#define flush_dcache_page(page) do { } while (0) +#define flush_icache_range(start, end) do { } while (0) +#define flush_icache_page(vma,pg) do { } while (0) +#define flush_icache_user_range(vma,pg,adr,len) do { } while (0) + +void global_flush_tlb(void); +int change_page_attr(struct page *page, int numpages, pgprot_t prot); + +#endif /* _CRIS_CACHEFLUSH_H */ diff --git a/include/asm-cris/checksum.h b/include/asm-cris/checksum.h index 589eb323eba3..15ca8aec5c63 100644 --- a/include/asm-cris/checksum.h +++ b/include/asm-cris/checksum.h @@ -3,6 +3,8 @@ #ifndef _CRIS_CHECKSUM_H #define _CRIS_CHECKSUM_H +#include <asm/arch/checksum.h> + /* * computes the checksum of a memory block at buff, length len, * and adds in "sum" (32-bit) @@ -32,7 +34,7 @@ unsigned int csum_partial_copy_nocheck(const char *src, char *dst, * Fold a partial checksum into a word */ -static inline unsigned int csum_fold(unsigned int sum) +extern inline unsigned int csum_fold(unsigned int sum) { /* the while loop is unnecessary really, it's always enough with two iterations */ @@ -43,31 +45,6 @@ static inline unsigned int csum_fold(unsigned int sum) return ~sum; } -/* Checksum some values used in TCP/UDP headers. - * - * The gain by doing this in asm is that C will not generate carry-additions - * for the 32-bit components of the checksum, so otherwise we would have had - * to split all of those into 16-bit components, then add. - */ - -static inline unsigned int -csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len, - unsigned short proto, unsigned int sum) -{ - int res; - __asm__ ("add.d %2, %0\n\t" - "ax\n\t" - "add.d %3, %0\n\t" - "ax\n\t" - "add.d %4, %0\n\t" - "ax\n\t" - "addq 0, %0\n" - : "=r" (res) - : "0" (sum), "r" (daddr), "r" (saddr), "r" ((ntohs(len) << 16) + (proto << 8))); - - return res; -} - extern unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len, unsigned int sum, int *errptr); @@ -78,7 +55,7 @@ extern unsigned int csum_partial_copy_from_user(const char *src, char *dst, * */ -static inline unsigned short ip_fast_csum(unsigned char * iph, +extern inline unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl) { return csum_fold(csum_partial(iph, ihl * 4, 0)); @@ -89,7 +66,7 @@ static inline unsigned short ip_fast_csum(unsigned char * iph, * returns a 16-bit checksum, already complemented */ -static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, +extern inline unsigned short int csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len, unsigned short proto, @@ -103,7 +80,7 @@ static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, * in icmp.c */ -static inline unsigned short ip_compute_csum(unsigned char * buff, int len) { +extern inline unsigned short ip_compute_csum(unsigned char * buff, int len) { return csum_fold (csum_partial(buff, len, 0)); } diff --git a/include/asm-cris/current.h b/include/asm-cris/current.h index c5cc44d537d6..dce69c99da39 100644 --- a/include/asm-cris/current.h +++ b/include/asm-cris/current.h @@ -1,14 +1,14 @@ #ifndef _CRIS_CURRENT_H #define _CRIS_CURRENT_H +#include <linux/thread_info.h> + struct task_struct; -static inline struct task_struct * get_current(void) +extern inline struct task_struct * get_current(void) { - struct task_struct *current; - __asm__("and.d $sp,%0; ":"=r" (current) : "0" (~8191UL)); - return current; - } + return current_thread_info()->task; +} #define current get_current() diff --git a/include/asm-cris/delay.h b/include/asm-cris/delay.h index 632c369c41b9..efc41aad4845 100644 --- a/include/asm-cris/delay.h +++ b/include/asm-cris/delay.h @@ -2,33 +2,12 @@ #define _CRIS_DELAY_H /* - * Copyright (C) 1998, 1999, 2000, 2001 Axis Communications AB + * Copyright (C) 1998-2002 Axis Communications AB * * Delay routines, using a pre-computed "loops_per_second" value. */ -#include <linux/config.h> -#include <linux/linkage.h> - -#ifdef CONFIG_SMP -#include <asm/smp.h> -#endif - -extern void __do_delay(void); /* Special register call calling convention */ - -extern __inline__ void __delay(int loops) -{ - __asm__ __volatile__ ( - "move.d %0,$r9\n\t" - "beq 2f\n\t" - "subq 1,$r9\n\t" - "1:\n\t" - "bne 1b\n\t" - "subq 1,$r9\n" - "2:" - : : "g" (loops) : "r9"); -} - +#include <asm/arch/delay.h> /* Use only for very small delays ( < 1 msec). */ diff --git a/include/asm-cris/dma.h b/include/asm-cris/dma.h index fde1cbf1a803..c229fac35cdc 100644 --- a/include/asm-cris/dma.h +++ b/include/asm-cris/dma.h @@ -1,59 +1,13 @@ -/* $Id: dma.h,v 1.2 2001/05/09 12:17:42 johana Exp $ - * linux/include/asm/dma.h: Defines for using and allocating dma channels. - */ +/* $Id: dma.h,v 1.2 2001/05/09 12:17:42 johana Exp $ */ #ifndef _ASM_DMA_H #define _ASM_DMA_H +#include <asm/arch/dma.h> + /* it's useless on the Etrax, but unfortunately needed by the new bootmem allocator (but this should do it for this) */ #define MAX_DMA_ADDRESS PAGE_OFFSET -/* TODO: check nbr of channels on Etrax-100LX */ - -#define MAX_DMA_CHANNELS 10 - -/* dma0 and dma1 used for network (ethernet) */ -#define NETWORK_TX_DMA_NBR 0 -#define NETWORK_RX_DMA_NBR 1 - -/* dma2 and dma3 shared by par0, scsi0, ser2 and ata */ -#define PAR0_TX_DMA_NBR 2 -#define PAR0_RX_DMA_NBR 3 -#define SCSI0_TX_DMA_NBR 2 -#define SCSI0_RX_DMA_NBR 3 -#define SER2_TX_DMA_NBR 2 -#define SER2_RX_DMA_NBR 3 -#define ATA_TX_DMA_NBR 2 -#define ATA_RX_DMA_NBR 3 - -/* dma4 and dma5 shared by par1, scsi1, ser3 and extdma0 */ -#define PAR1_TX_DMA_NBR 4 -#define PAR1_RX_DMA_NBR 5 -#define SCSI1_TX_DMA_NBR 4 -#define SCSI1_RX_DMA_NBR 5 -#define SER3_TX_DMA_NBR 4 -#define SER3_RX_DMA_NBR 5 -#define EXTDMA0_TX_DMA_NBR 4 -#define EXTDMA0_RX_DMA_NBR 5 - -/* dma6 and dma7 shared by ser0, extdma1 and mem2mem */ -#define SER0_TX_DMA_NBR 6 -#define SER0_RX_DMA_NBR 7 -#define EXTDMA1_TX_DMA_NBR 6 -#define EXTDMA1_RX_DMA_NBR 7 -#define MEM2MEM_TX_DMA_NBR 6 -#define MEM2MEM_RX_DMA_NBR 7 - -/* dma8 and dma9 shared by ser1 and usb */ -#define SER1_TX_DMA_NBR 8 -#define SER1_RX_DMA_NBR 9 -#define USB_TX_DMA_NBR 8 -#define USB_RX_DMA_NBR 9 - -/* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ -extern void free_dma(unsigned int dmanr); /* release it */ - #endif /* _ASM_DMA_H */ diff --git a/include/asm-cris/elf.h b/include/asm-cris/elf.h index 798aeaeaabd1..d37fd5c4a567 100644 --- a/include/asm-cris/elf.h +++ b/include/asm-cris/elf.h @@ -5,7 +5,8 @@ * ELF register definitions.. */ -#include <asm/ptrace.h> +#include <asm/arch/elf.h> +#include <asm/user.h> typedef unsigned long elf_greg_t; @@ -29,69 +30,8 @@ typedef unsigned long elf_fpregset_t; #define ELF_DATA ELFDATA2LSB; #define ELF_ARCH EM_CRIS - /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program - starts (a register; assume first param register for CRIS) - contains a pointer to a function which might be - registered using `atexit'. This provides a mean for the - dynamic linker to call DT_FINI functions for shared libraries - that have been loaded before the code runs. - - A value of 0 tells we have no such handler. */ - - /* Explicitly set registers to 0 to increase determinism. */ -#define ELF_PLAT_INIT(_r, load_addr) do { \ - (_r)->r13 = 0; (_r)->r12 = 0; (_r)->r11 = 0; (_r)->r10 = 0; \ - (_r)->r9 = 0; (_r)->r8 = 0; (_r)->r7 = 0; (_r)->r6 = 0; \ - (_r)->r5 = 0; (_r)->r4 = 0; (_r)->r3 = 0; (_r)->r2 = 0; \ - (_r)->r1 = 0; (_r)->r0 = 0; (_r)->mof = 0; (_r)->srp = 0; \ -} while (0) - #define USE_ELF_CORE_DUMP -/* The additional layer below is because the stack pointer is missing in - the pt_regs struct, but needed in a core dump. pr_reg is a elf_gregset_t, - and should be filled in according to the layout of the user_regs_struct - struct; regs is a pt_regs struct. We dump all registers, though several are - obviously unnecessary. That way there's less need for intelligence at - the receiving end (i.e. gdb). */ -#define ELF_CORE_COPY_REGS(pr_reg, regs) \ - pr_reg[0] = regs->r0; \ - pr_reg[1] = regs->r1; \ - pr_reg[2] = regs->r2; \ - pr_reg[3] = regs->r3; \ - pr_reg[4] = regs->r4; \ - pr_reg[5] = regs->r5; \ - pr_reg[6] = regs->r6; \ - pr_reg[7] = regs->r7; \ - pr_reg[8] = regs->r8; \ - pr_reg[9] = regs->r9; \ - pr_reg[10] = regs->r10; \ - pr_reg[11] = regs->r11; \ - pr_reg[12] = regs->r12; \ - pr_reg[13] = regs->r13; \ - pr_reg[14] = rdusp(); /* sp */ \ - pr_reg[15] = regs->irp; /* pc */ \ - pr_reg[16] = 0; /* p0 */ \ - pr_reg[17] = rdvr(); /* vr */ \ - pr_reg[18] = 0; /* p2 */ \ - pr_reg[19] = 0; /* p3 */ \ - pr_reg[20] = 0; /* p4 */ \ - pr_reg[21] = (regs->dccr & 0xffff); /* ccr */ \ - pr_reg[22] = 0; /* p6 */ \ - pr_reg[23] = regs->mof; /* mof */ \ - pr_reg[24] = 0; /* p8 */ \ - pr_reg[25] = 0; /* ibr */ \ - pr_reg[26] = 0; /* irp */ \ - pr_reg[27] = regs->srp; /* srp */ \ - pr_reg[28] = 0; /* bar */ \ - pr_reg[29] = regs->dccr; /* dccr */ \ - pr_reg[30] = 0; /* brp */ \ - pr_reg[31] = rdusp(); /* usp */ \ - pr_reg[32] = 0; /* csrinstr */ \ - pr_reg[33] = 0; /* csraddr */ \ - pr_reg[34] = 0; /* csrdata */ - - #define ELF_EXEC_PAGESIZE 8192 /* This is the location that an ET_DYN program is loaded if exec'ed. Typical diff --git a/include/asm-cris/etraxgpio.h b/include/asm-cris/etraxgpio.h index 0395953e883e..cf04af9635cc 100644 --- a/include/asm-cris/etraxgpio.h +++ b/include/asm-cris/etraxgpio.h @@ -1,13 +1,54 @@ +/* $Id: etraxgpio.h,v 1.8 2002/06/17 15:53:07 johana Exp $ */ +/* + * The following devices are accessable using this driver using + * GPIO_MAJOR (120) and a couple of minor numbers: + * For ETRAX 100LX (ARCH_V10): + * /dev/gpioa minor 0, 8 bit GPIO, each bit can change direction + * /dev/gpiob minor 1, 8 bit GPIO, each bit can change direction + * /dev/leds minor 2, Access to leds depending on kernelconfig + * /dev/gpiog minor 3 + g0dir, g8_15dir, g16_23dir, g24 dir configurable in R_GEN_CONFIG + g1-g7 and g25-g31 is both input and outputs but on different pins + Also note that some bits change pins depending on what interfaces + are enabled. + * + * + * For ETRAX 200 (ARCH_V32): + * /dev/gpioa minor 0, 8 bit GPIO, each bit can change direction + * /dev/gpiob minor 1, 18 bit GPIO, each bit can change direction + * /dev/gpioc minor 2, 18 bit GPIO, each bit can change direction + * /dev/gpiod minor 3, 18 bit GPIO, each bit can change direction + * /dev/gpioe minor 4, 18 bit GPIO, each bit can change direction + * /dev/leds minor 5, Access to leds depending on kernelconfig + * + */ #ifndef _ASM_ETRAXGPIO_H #define _ASM_ETRAXGPIO_H +#include <linux/config.h> /* etraxgpio _IOC_TYPE, bits 8 to 15 in ioctl cmd */ - +#ifdef CONFIG_ETRAX_ARCH_V10 +#define ETRAXGPIO_IOCTYPE 43 +#define GPIO_MINOR_A 0 +#define GPIO_MINOR_B 1 +#define GPIO_MINOR_LEDS 2 +#define GPIO_MINOR_G 3 +#define GPIO_MINOR_LAST 3 +#endif +#ifdef CONFIG_ETRAX_ARCH_V32 #define ETRAXGPIO_IOCTYPE 43 +#define GPIO_MINOR_A 0 +#define GPIO_MINOR_B 1 +#define GPIO_MINOR_C 2 +#define GPIO_MINOR_D 3 +#define GPIO_MINOR_E 4 +#define GPIO_MINOR_LEDS 5 +#define GPIO_MINOR_LAST 5 +#endif /* supported ioctl _IOC_NR's */ -#define IO_READBITS 0x1 /* read and return current port bits */ +#define IO_READBITS 0x1 /* read and return current port bits (obsolete) */ #define IO_SETBITS 0x2 /* set the bits marked by 1 in the argument */ #define IO_CLRBITS 0x3 /* clear the bits marked by 1 in the argument */ @@ -22,11 +63,11 @@ * 0=off, 1=green, 2=red, 3=yellow */ /* GPIO direction ioctl's */ -#define IO_READDIR 0x8 /* Read direction 0=input 1=output */ -#define IO_SETINPUT 0x9 /* Set direction 0=unchanged 1=input, - returns current dir */ -#define IO_SETOUTPUT 0xA /* Set direction 0=unchanged 1=output, - returns current dir */ +#define IO_READDIR 0x8 /* Read direction 0=input 1=output (obsolete) */ +#define IO_SETINPUT 0x9 /* Set direction for bits set, 0=unchanged 1=input, + returns mask with current inputs (obsolete) */ +#define IO_SETOUTPUT 0xA /* Set direction for bits set, 0=unchanged 1=output, + returns mask with current outputs (obsolete)*/ /* LED ioctl extended */ #define IO_LED_SETBIT 0xB @@ -45,5 +86,19 @@ #define IO_CFG_WRITE_MODE_VALUE(msb, data_mask, clk_mask) \ ( (((msb)&1) << 16) | (((data_mask) &0xFF) << 8) | ((clk_mask) & 0xFF) ) +/* The following 4 ioctl's take a pointer as argument and handles + * 32 bit ports (port G) properly. + * These replaces IO_READBITS,IO_SETINPUT AND IO_SETOUTPUT + */ +#define IO_READ_INBITS 0x10 /* *arg is result of reading the input pins */ +#define IO_READ_OUTBITS 0x11 /* *arg is result of reading the output shadow */ +#define IO_SETGET_INPUT 0x12 /* bits set in *arg is set to input, + * *arg updated with current input pins. + */ +#define IO_SETGET_OUTPUT 0x13 /* bits set in *arg is set to output, + * *arg updated with current output pins. + */ + + #endif diff --git a/include/asm-cris/fasttimer.h b/include/asm-cris/fasttimer.h new file mode 100644 index 000000000000..10a770647870 --- /dev/null +++ b/include/asm-cris/fasttimer.h @@ -0,0 +1,42 @@ +/* $Id: fasttimer.h,v 1.2 2002/12/11 13:03:43 starvik Exp $ + * linux/include/asm-cris/fasttimer.h + * + * Fast timers for ETRAX100LX + * This may be useful in other OS than Linux so use 2 space indentation... + * Copyright (C) 2000, 2002 Axis Communications AB + */ +#include <linux/config.h> +#include <linux/time.h> /* struct timeval */ +#include <linux/timex.h> + +#ifdef CONFIG_ETRAX_FAST_TIMER + +typedef void fast_timer_function_type(unsigned long); + +struct fast_timer{ /* Close to timer_list */ + struct fast_timer *next; + struct fast_timer *prev; + struct timeval tv_set; + struct timeval tv_expires; + unsigned long delay_us; + fast_timer_function_type *function; + unsigned long data; + const char *name; +}; + +void start_one_shot_timer(struct fast_timer *t, + fast_timer_function_type *function, + unsigned long data, + unsigned long delay_us, + const char *name); + +int del_fast_timer(struct fast_timer * t); +/* return 1 if deleted */ + + +void schedule_usleep(unsigned long us); + + +void fast_timer_init(void); + +#endif diff --git a/include/asm-cris/hardirq.h b/include/asm-cris/hardirq.h index 4a13a2445d5b..c75100f8359b 100644 --- a/include/asm-cris/hardirq.h +++ b/include/asm-cris/hardirq.h @@ -4,6 +4,7 @@ /* only non-SMP supported */ #include <linux/threads.h> +#include <linux/cache.h> /* entry.S is sensitive to the offsets of these fields */ typedef struct { @@ -17,19 +18,80 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ /* - * Are we in an interrupt context? Either doing bottom half - * or hardware interrupt processing? + * 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 + * SOFTIRQ_MASK: 0x0000ff00 + * HARDIRQ_MASK: 0x00ff0000 */ -#define in_interrupt() ((local_irq_count(smp_processor_id()) + \ - local_bh_count(smp_processor_id())) != 0) -#define in_irq() (local_irq_count(smp_processor_id()) != 0) -#define hardirq_trylock(cpu) (local_irq_count(cpu) == 0) -#define hardirq_endlock(cpu) do { (void)(cpu); } while (0) +#define PREEMPT_BITS 8 +#define SOFTIRQ_BITS 8 +#define HARDIRQ_BITS 8 -#define irq_enter(cpu) (local_irq_count(cpu)++) -#define irq_exit(cpu) (local_irq_count(cpu)--) +#define PREEMPT_SHIFT 0 +#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) +#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) -#define synchronize_irq() barrier() +#define __MASK(x) ((1UL << (x))-1) + +#define PREEMPT_MASK (__MASK(PREEMPT_BITS) << PREEMPT_SHIFT) +#define HARDIRQ_MASK (__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) +#define SOFTIRQ_MASK (__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) + +#define hardirq_count() (preempt_count() & HARDIRQ_MASK) +#define softirq_count() (preempt_count() & SOFTIRQ_MASK) +#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK)) + +#define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) +#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) +#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) + +/* + * The hardirq mask has to be large enough to have + * space for potentially all IRQ sources in the system + * nesting on a single CPU: + */ +#if (1 << HARDIRQ_BITS) < NR_IRQS +# error HARDIRQ_BITS is too low! +#endif + +/* + * Are we doing bottom half or hardware interrupt processing? + * Are we in a softirq context? Interrupt context? + */ +#define in_irq() (hardirq_count()) +#define in_softirq() (softirq_count()) +#define in_interrupt() (irq_count()) + + +#define hardirq_trylock() (!in_interrupt()) +#define hardirq_endlock() do { } while (0) + +#define irq_enter() (preempt_count() += HARDIRQ_OFFSET) + +#ifdef CONFIG_PREEMPT +# define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked()) +# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) +#else +# define in_atomic() (preempt_count() != 0) +# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET +#endif +#define irq_exit() \ +do { \ + preempt_count() -= IRQ_EXIT_OFFSET; \ + if (!in_interrupt() && softirq_pending(smp_processor_id())) \ + do_softirq(); \ + preempt_enable_no_resched(); \ +} while (0) + +#define synchronize_irq(irq) barrier() #endif /* __ASM_HARDIRQ_H */ diff --git a/include/asm-cris/hdreg.h b/include/asm-cris/hdreg.h deleted file mode 100644 index 382a8e64ce8b..000000000000 --- a/include/asm-cris/hdreg.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * linux/include/asm-cris/hdreg.h - * - */ - -#ifndef __ASMCRIS_HDREG_H -#define __ASMCRIS_HDREG_H - -typedef unsigned long ide_ioreg_t; - -#endif /* __ASMCRIS_HDREG_H */ diff --git a/include/asm-cris/ide.h b/include/asm-cris/ide.h deleted file mode 100644 index 8f4bd8c131f4..000000000000 --- a/include/asm-cris/ide.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * linux/include/asm-cris/ide.h - * - * Copyright (C) 2000 Axis Communications AB - * - * Authors: Bjorn Wesen - * - */ - -/* - * This file contains the ETRAX 100LX specific IDE code. - */ - -#ifndef __ASMCRIS_IDE_H -#define __ASMCRIS_IDE_H - -#ifdef __KERNEL__ - -#include <asm/svinto.h> - -/* ETRAX 100 can support 4 IDE busses on the same pins (serialized) */ - -#define MAX_HWIFS 4 - -static __inline__ int ide_default_irq(ide_ioreg_t base) -{ - /* all IDE busses share the same IRQ, number 4. - * this has the side-effect that ide-probe.c will cluster our 4 interfaces - * together in a hwgroup, and will serialize accesses. this is good, because - * we can't access more than one interface at the same time on ETRAX100. - */ - return 4; -} - -static __inline__ ide_ioreg_t ide_default_io_base(int index) -{ - /* we have no real I/O base address per interface, since all go through the - * same register. but in a bitfield in that register, we have the i/f number. - * so we can use the io_base to remember that bitfield. - */ - static const unsigned long io_bases[MAX_HWIFS] = { - IO_FIELD(R_ATA_CTRL_DATA, sel, 0), - IO_FIELD(R_ATA_CTRL_DATA, sel, 1), - IO_FIELD(R_ATA_CTRL_DATA, sel, 2), - IO_FIELD(R_ATA_CTRL_DATA, sel, 3) - }; - return io_bases[index]; -} - -/* this is called once for each interface, to setup the port addresses. data_port is the result - * of the ide_default_io_base call above. ctrl_port will be 0, but that is don't care for us. - */ - -static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) -{ - int i; - - /* fill in ports for ATA addresses 0 to 7 */ - - for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { - hw->io_ports[i] = data_port | - IO_FIELD(R_ATA_CTRL_DATA, addr, i) | - IO_STATE(R_ATA_CTRL_DATA, cs0, active); - } - - /* the IDE control register is at ATA address 6, with CS1 active instead of CS0 */ - - hw->io_ports[IDE_CONTROL_OFFSET] = data_port | - IO_FIELD(R_ATA_CTRL_DATA, addr, 6) | - IO_STATE(R_ATA_CTRL_DATA, cs1, active); - - /* whats this for ? */ - - hw->io_ports[IDE_IRQ_OFFSET] = 0; -} - -static __inline__ void ide_init_default_hwifs(void) -{ - hw_regs_t hw; - int index; - - for(index = 0; index < MAX_HWIFS; index++) { - ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL); - hw.irq = ide_default_irq(ide_default_io_base(index)); - ide_register_hw(&hw); - } -} - -/* some configuration options we don't need */ - -#undef SUPPORT_SLOW_DATA_PORTS -#define SUPPORT_SLOW_DATA_PORTS 0 - -/* the drive addressing is done through a controller register on the Etrax CPU */ -void OUT_BYTE(unsigned char data, ide_ioreg_t reg); -unsigned char IN_BYTE(ide_ioreg_t reg); - -/* this tells ide.h not to define the standard macros */ -#define HAVE_ARCH_IN_OUT 1 - -#endif /* __KERNEL__ */ - -#endif /* __ASMCRIS_IDE_H */ diff --git a/include/asm-cris/io.h b/include/asm-cris/io.h index 82a06f841c9f..8604f0e9a69d 100644 --- a/include/asm-cris/io.h +++ b/include/asm-cris/io.h @@ -2,209 +2,18 @@ #define _ASM_CRIS_IO_H #include <asm/page.h> /* for __va, __pa */ -#include <asm/svinto.h> -#include <linux/config.h> - -/* Console I/O for simulated etrax100. Use #ifdef so erroneous - use will be evident. */ -#ifdef CONFIG_SVINTO_SIM - /* Let's use the ucsim interface since it lets us do write(2, ...) */ -#define SIMCOUT(s,len) \ - asm ("moveq 4,$r9 \n\t" \ - "moveq 2,$r10 \n\t" \ - "move.d %0,$r11 \n\t" \ - "move.d %1,$r12 \n\t" \ - "push $irp \n\t" \ - "move 0f,$irp \n\t" \ - "jump -6809 \n" \ - "0: \n\t" \ - "pop $irp" \ - : : "rm" (s), "rm" (len) : "r9","r10","r11","r12","memory") -#define TRACE_ON() __extension__ \ - ({ int _Foofoo; __asm__ volatile ("bmod [%0],%0" : "=r" (_Foofoo) : "0" \ - (255)); _Foofoo; }) - -#define TRACE_OFF() do { __asm__ volatile ("bmod [%0],%0" :: "r" (254)); } while (0) -#define SIM_END() do { __asm__ volatile ("bmod [%0],%0" :: "r" (28)); } while (0) -#define CRIS_CYCLES() __extension__ \ - ({ unsigned long c; asm ("bmod [%1],%0" : "=r" (c) : "r" (27)); c;}) -#else /* ! defined CONFIG_SVINTO_SIM */ -/* FIXME: Is there a reliable cycle counter available in some chip? Use - that then. */ -#define CRIS_CYCLES() 0 -#endif /* ! defined CONFIG_SVINTO_SIM */ - -/* Etrax shadow registers - which live in arch/cris/kernel/shadows.c */ - -extern unsigned long port_g_data_shadow; -extern unsigned char port_pa_dir_shadow; -extern unsigned char port_pa_data_shadow; -extern unsigned char port_pb_i2c_shadow; -extern unsigned char port_pb_config_shadow; -extern unsigned char port_pb_dir_shadow; -extern unsigned char port_pb_data_shadow; -extern unsigned long r_timer_ctrl_shadow; - -extern unsigned long port_cse1_shadow; -extern unsigned long port_csp0_shadow; -extern unsigned long port_csp4_shadow; - -extern volatile unsigned long *port_cse1_addr; -extern volatile unsigned long *port_csp0_addr; -extern volatile unsigned long *port_csp4_addr; - -/* macro for setting regs through a shadow - - * r = register name (like R_PORT_PA_DATA) - * s = shadow name (like port_pa_data_shadow) - * b = bit number - * v = value (0 or 1) - */ - -#define REG_SHADOW_SET(r,s,b,v) *r = s = (s & ~(1 << (b))) | ((v) << (b)) - -/* The LED's on various Etrax-based products are set differently. */ - -#if defined(CONFIG_ETRAX_NO_LEDS) || defined(CONFIG_SVINTO_SIM) -#undef CONFIG_ETRAX_PA_LEDS -#undef CONFIG_ETRAX_PB_LEDS -#undef CONFIG_ETRAX_CSP0_LEDS -#define LED_NETWORK_SET_G(x) -#define LED_NETWORK_SET_R(x) -#define LED_ACTIVE_SET_G(x) -#define LED_ACTIVE_SET_R(x) -#define LED_DISK_WRITE(x) -#define LED_DISK_READ(x) -#endif - -#if !defined(CONFIG_ETRAX_CSP0_LEDS) -#define LED_BIT_SET(x) -#define LED_BIT_CLR(x) -#endif - -#define LED_OFF 0x00 -#define LED_GREEN 0x01 -#define LED_RED 0x02 -#define LED_ORANGE (LED_GREEN | LED_RED) - -#if CONFIG_ETRAX_LED1G == CONFIG_ETRAX_LED1R -#define LED_NETWORK_SET(x) \ - do { \ - LED_NETWORK_SET_G((x) & LED_GREEN); \ - } while (0) -#else -#define LED_NETWORK_SET(x) \ - do { \ - LED_NETWORK_SET_G((x) & LED_GREEN); \ - LED_NETWORK_SET_R((x) & LED_RED); \ - } while (0) -#endif -#if CONFIG_ETRAX_LED2G == CONFIG_ETRAX_LED2R -#define LED_ACTIVE_SET(x) \ - do { \ - LED_ACTIVE_SET_G((x) & LED_GREEN); \ - } while (0) -#else -#define LED_ACTIVE_SET(x) \ - do { \ - LED_ACTIVE_SET_G((x) & LED_GREEN); \ - LED_ACTIVE_SET_R((x) & LED_RED); \ - } while (0) -#endif - -#ifdef CONFIG_ETRAX_PA_LEDS -#define LED_NETWORK_SET_G(x) \ - REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED1G, !(x)) -#define LED_NETWORK_SET_R(x) \ - REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED1R, !(x)) -#define LED_ACTIVE_SET_G(x) \ - REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED2G, !(x)) -#define LED_ACTIVE_SET_R(x) \ - REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED2R, !(x)) -#define LED_DISK_WRITE(x) \ - do{\ - REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED3G, !(x));\ - REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED3R, !(x));\ - }while(0) -#define LED_DISK_READ(x) \ - REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED3G, !(x)) -#endif - -#ifdef CONFIG_ETRAX_PB_LEDS -#define LED_NETWORK_SET_G(x) \ - REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED1G, !(x)) -#define LED_NETWORK_SET_R(x) \ - REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED1R, !(x)) -#define LED_ACTIVE_SET_G(x) \ - REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED2G, !(x)) -#define LED_ACTIVE_SET_R(x) \ - REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED2R, !(x)) -#define LED_DISK_WRITE(x) \ - do{\ - REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED3G, !(x));\ - REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED3R, !(x));\ - }while(0) -#define LED_DISK_READ(x) \ - REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED3G, !(x)) -#endif - -#ifdef CONFIG_ETRAX_CSP0_LEDS -#define CONFIGURABLE_LEDS\ - ((1 << CONFIG_ETRAX_LED1G ) | (1 << CONFIG_ETRAX_LED1R ) |\ - (1 << CONFIG_ETRAX_LED2G ) | (1 << CONFIG_ETRAX_LED2R ) |\ - (1 << CONFIG_ETRAX_LED3G ) | (1 << CONFIG_ETRAX_LED3R ) |\ - (1 << CONFIG_ETRAX_LED4G ) | (1 << CONFIG_ETRAX_LED4R ) |\ - (1 << CONFIG_ETRAX_LED5G ) | (1 << CONFIG_ETRAX_LED5R ) |\ - (1 << CONFIG_ETRAX_LED6G ) | (1 << CONFIG_ETRAX_LED6R ) |\ - (1 << CONFIG_ETRAX_LED7G ) | (1 << CONFIG_ETRAX_LED7R ) |\ - (1 << CONFIG_ETRAX_LED8Y ) | (1 << CONFIG_ETRAX_LED9Y ) |\ - (1 << CONFIG_ETRAX_LED10Y ) |(1 << CONFIG_ETRAX_LED11Y )|\ - (1 << CONFIG_ETRAX_LED12R )) - -#define LED_NETWORK_SET_G(x) \ - REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED1G, !(x)) -#define LED_NETWORK_SET_R(x) \ - REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED1R, !(x)) -#define LED_ACTIVE_SET_G(x) \ - REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED2G, !(x)) -#define LED_ACTIVE_SET_R(x) \ - REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED2R, !(x)) -#define LED_DISK_WRITE(x) \ - do{\ - REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED3G, !(x));\ - REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED3R, !(x));\ - }while(0) -#define LED_DISK_READ(x) \ - REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED3G, !(x)) -#define LED_BIT_SET(x)\ - do{\ - if((( 1 << x) & CONFIGURABLE_LEDS) != 0)\ - REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, x, 1);\ - }while(0) -#define LED_BIT_CLR(x)\ - do{\ - if((( 1 << x) & CONFIGURABLE_LEDS) != 0)\ - REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, x, 0);\ - }while(0) -#endif - -# -#ifdef CONFIG_ETRAX_SOFT_SHUTDOWN -#define SOFT_SHUTDOWN() \ - REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_SHUTDOWN_BIT, 1) -#else -#define SOFT_SHUTDOWN() -#endif +#include <asm/arch/io.h> /* * Change virtual addresses to physical addresses and vv. */ -static inline unsigned long virt_to_phys(volatile void * address) +extern inline unsigned long virt_to_phys(volatile void * address) { return __pa(address); } -static inline void * phys_to_virt(unsigned long address) +extern inline void * phys_to_virt(unsigned long address) { return __va(address); } @@ -216,6 +25,8 @@ extern inline void * ioremap (unsigned long offset, unsigned long size) return __ioremap(offset, size, 0); } +extern void iounmap(void *addr); + /* * IO bus memory addresses are also 1:1 with the physical address */ @@ -231,10 +42,16 @@ extern inline void * ioremap (unsigned long offset, unsigned long size) #define readb(addr) (*(volatile unsigned char *) (addr)) #define readw(addr) (*(volatile unsigned short *) (addr)) #define readl(addr) (*(volatile unsigned int *) (addr)) +#define __raw_readb readb +#define __raw_readw readw +#define __raw_readl readl #define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b)) #define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b)) #define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b)) +#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)) diff --git a/include/asm-cris/ioctls.h b/include/asm-cris/ioctls.h index 1628ad265a89..97787c3c575f 100644 --- a/include/asm-cris/ioctls.h +++ b/include/asm-cris/ioctls.h @@ -70,6 +70,9 @@ #define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ #define FIOQSIZE 0x5460 +#define TIOCSERSETRS485 0x5461 /* enable rs-485 */ +#define TIOCSERWRRS485 0x5462 /* write rs-485 */ + /* Used for packet mode */ #define TIOCPKT_DATA 0 #define TIOCPKT_FLUSHREAD 1 diff --git a/include/asm-cris/ipc.h b/include/asm-cris/ipc.h index 07e51a11d50d..f086af6fa03f 100644 --- a/include/asm-cris/ipc.h +++ b/include/asm-cris/ipc.h @@ -17,6 +17,7 @@ struct ipc_kludge { #define SEMOP 1 #define SEMGET 2 #define SEMCTL 3 +#define SEMTIMEDOP 4 #define MSGSND 11 #define MSGRCV 12 #define MSGGET 13 diff --git a/include/asm-cris/irq.h b/include/asm-cris/irq.h index 5e4fb8db6735..caa45facb1b2 100644 --- a/include/asm-cris/irq.h +++ b/include/asm-cris/irq.h @@ -1,78 +1,12 @@ -/* - * Interrupt handling assembler and defines for Linux/CRIS - * - * Copyright (c) 2000, 2001 Axis Communications AB - * - */ - #ifndef _ASM_IRQ_H #define _ASM_IRQ_H -/* - * linux/include/asm-cris/irq.h - */ - -#include <linux/linkage.h> -#include <asm/segment.h> - -#include <asm/sv_addr_ag.h> - -#define NR_IRQS 32 -#define SOME_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, some) /* 0 ? */ -#define NMI_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, nmi) /* 1 */ -#define TIMER0_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, timer0) /* 2 */ -#define TIMER1_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, timer1) /* 3 */ -/* mio, ata, par0, scsi0 on 4 */ -/* par1, scsi1 on 5 */ -#define NETWORK_STATUS_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, network) /* 6 */ - -#define SERIAL_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, serial) /* 8 */ -#define PA_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, pa) /* 11 */ -/* extdma0 and extdma1 is at irq 12 and 13 and/or same as dma5 and dma6 ? */ -#define EXTDMA0_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, ext_dma0) -#define EXTDMA1_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, ext_dma1) - -/* dma0-9 is irq 16..25 */ -/* 16,17: network */ -#define DMA0_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma0) -#define DMA1_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma1) -#define NETWORK_DMA_TX_IRQ_NBR DMA0_TX_IRQ_NBR -#define NETWORK_DMA_RX_IRQ_NBR DMA1_RX_IRQ_NBR - -/* 18,19: dma2 and dma3 shared by par0, scsi0, ser2 and ata */ -#define DMA2_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma2) -#define DMA3_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma3) -#define SER2_DMA_TX_IRQ_NBR DMA2_TX_IRQ_NBR -#define SER2_DMA_RX_IRQ_NBR DMA3_RX_IRQ_NBR - -/* 20,21: dma4 and dma5 shared by par1, scsi1, ser3 and extdma0 */ -#define DMA4_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma4) -#define DMA5_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma5) -#define SER3_DMA_TX_IRQ_NBR DMA4_TX_IRQ_NBR -#define SER3_DMA_RX_IRQ_NBR DMA5_RX_IRQ_NBR - -/* 22,23: dma6 and dma7 shared by ser0, extdma1 and mem2mem */ -#define DMA6_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma6) -#define DMA7_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma7) -#define SER0_DMA_TX_IRQ_NBR DMA6_TX_IRQ_NBR -#define SER0_DMA_RX_IRQ_NBR DMA7_RX_IRQ_NBR -#define MEM2MEM_DMA_TX_IRQ_NBR DMA6_TX_IRQ_NBR -#define MEM2MEM_DMA_RX_IRQ_NBR DMA7_RX_IRQ_NBR - -/* 24,25: dma8 and dma9 shared by ser1 and usb */ -#define DMA8_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma8) -#define DMA9_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma9) -#define SER1_DMA_TX_IRQ_NBR DMA8_TX_IRQ_NBR -#define SER1_DMA_RX_IRQ_NBR DMA9_RX_IRQ_NBR -#define USB_DMA_TX_IRQ_NBR DMA8_TX_IRQ_NBR -#define USB_DMA_RX_IRQ_NBR DMA9_RX_IRQ_NBR - -/* usb: controller at irq 31 + uses DMA8 and DMA9 */ -#define USB_HC_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, usb) - - - +#include <asm/arch/irq.h> +extern __inline__ int irq_canonicalize(int irq) +{ + return irq; +} extern void disable_irq(unsigned int); extern void enable_irq(unsigned int); @@ -80,116 +14,6 @@ extern void enable_irq(unsigned int); #define disable_irq_nosync disable_irq #define enable_irq_nosync enable_irq -/* our fine, global, etrax irq vector! the pointer lives in the head.S file. */ - -typedef void (*irqvectptr)(void); - -struct etrax_interrupt_vector { - irqvectptr v[256]; -}; - -extern struct etrax_interrupt_vector *etrax_irv; -void set_int_vector(int n, irqvectptr addr, irqvectptr saddr); -void set_break_vector(int n, irqvectptr addr); - -#define __STR(x) #x -#define STR(x) __STR(x) - -/* SAVE_ALL saves registers so they match pt_regs */ - -#define SAVE_ALL \ - "move $irp,[$sp=$sp-16]\n\t" /* push instruction pointer and fake SBFS struct */ \ - "push $srp\n\t" /* push subroutine return pointer */ \ - "push $dccr\n\t" /* push condition codes */ \ - "push $mof\n\t" /* push multiply overflow reg */ \ - "di\n\t" /* need to disable irq's at this point */\ - "subq 14*4,$sp\n\t" /* make room for r0-r13 */ \ - "movem $r13,[$sp]\n\t" /* push the r0-r13 registers */ \ - "push $r10\n\t" /* push orig_r10 */ \ - "clear.d [$sp=$sp-4]\n\t" /* frametype - this is a normal stackframe */ - - /* BLOCK_IRQ and UNBLOCK_IRQ do the same as mask_irq and unmask_irq in irq.c */ - -#define BLOCK_IRQ(mask,nr) \ - "move.d " #mask ",$r0\n\t" \ - "move.d $r0,[0xb00000d8]\n\t" - -#define UNBLOCK_IRQ(mask) \ - "move.d " #mask ",$r0\n\t" \ - "move.d $r0,[0xb00000dc]\n\t" - -#define IRQ_NAME2(nr) nr##_interrupt(void) -#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) -#define sIRQ_NAME(nr) IRQ_NAME2(sIRQ##nr) -#define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr) - - /* the asm IRQ handler makes sure the causing IRQ is blocked, then it calls - * do_IRQ (with irq disabled still). after that it unblocks and jumps to - * ret_from_intr (entry.S) - * - * The reason the IRQ is blocked is to allow an sti() before the handler which - * will acknowledge the interrupt is run. - */ - -#define BUILD_IRQ(nr,mask) \ -void IRQ_NAME(nr); \ -void sIRQ_NAME(nr); \ -void BAD_IRQ_NAME(nr); \ -__asm__ ( \ - ".text\n\t" \ - "IRQ" #nr "_interrupt:\n\t" \ - SAVE_ALL \ - "sIRQ" #nr "_interrupt:\n\t" /* shortcut for the multiple irq handler */ \ - BLOCK_IRQ(mask,nr) /* this must be done to prevent irq loops when we ei later */ \ - "moveq "#nr",$r10\n\t" \ - "move.d $sp,$r11\n\t" \ - "jsr do_IRQ\n\t" /* irq.c, r10 and r11 are arguments */ \ - UNBLOCK_IRQ(mask) \ - "moveq 0,$r9\n\t" /* make ret_from_intr realise we came from an irq */ \ - "jump ret_from_intr\n\t" \ - "bad_IRQ" #nr "_interrupt:\n\t" \ - "push $r0\n\t" \ - BLOCK_IRQ(mask,nr) \ - "pop $r0\n\t" \ - "reti\n\t" \ - "nop\n"); - -/* This is subtle. The timer interrupt is crucial and it should not be disabled for - * too long. However, if it had been a normal interrupt as per BUILD_IRQ, it would - * have been BLOCK'ed, and then softirq's are run before we return here to UNBLOCK. - * If the softirq's take too much time to run, the timer irq won't run and the - * watchdog will kill us. - * - * Furthermore, if a lot of other irq's occur before we return here, the multiple_irq - * handler is run and it prioritizes the timer interrupt. However if we had BLOCK'ed - * it here, we would not get the multiple_irq at all. - * - * The non-blocking here is based on the knowledge that the timer interrupt is - * registred as a fast interrupt (SA_INTERRUPT) so that we _know_ there will not - * be an sti() before the timer irq handler is run to acknowledge the interrupt. - */ - -#define BUILD_TIMER_IRQ(nr,mask) \ -void IRQ_NAME(nr); \ -void sIRQ_NAME(nr); \ -void BAD_IRQ_NAME(nr); \ -__asm__ ( \ - ".text\n\t" \ - "IRQ" #nr "_interrupt:\n\t" \ - SAVE_ALL \ - "sIRQ" #nr "_interrupt:\n\t" /* shortcut for the multiple irq handler */ \ - "moveq "#nr",$r10\n\t" \ - "move.d $sp,$r11\n\t" \ - "jsr do_IRQ\n\t" /* irq.c, r10 and r11 are arguments */ \ - "moveq 0,$r9\n\t" /* make ret_from_intr realise we came from an irq */ \ - "jump ret_from_intr\n\t" \ - "bad_IRQ" #nr "_interrupt:\n\t" \ - "push $r0\n\t" \ - BLOCK_IRQ(mask,nr) \ - "pop $r0\n\t" \ - "reti\n\t" \ - "nop\n"); - #endif /* _ASM_IRQ_H */ diff --git a/include/asm-cris/kmap_types.h b/include/asm-cris/kmap_types.h new file mode 100644 index 000000000000..eec0974c2417 --- /dev/null +++ b/include/asm-cris/kmap_types.h @@ -0,0 +1,25 @@ +#ifndef _ASM_KMAP_TYPES_H +#define _ASM_KMAP_TYPES_H + +/* Dummy header just to define km_type. None of this + * is actually used on cris. + */ + +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_CRYPTO_USER, + KM_CRYPTO_SOFTIRQ, + KM_TYPE_NR +}; + +#endif diff --git a/include/asm-cris/mman.h b/include/asm-cris/mman.h index 827849b9f7f1..4de58ad6efa1 100644 --- a/include/asm-cris/mman.h +++ b/include/asm-cris/mman.h @@ -6,6 +6,7 @@ #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 MAP_SHARED 0x01 /* Share changes */ @@ -19,6 +20,8 @@ #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 MS_ASYNC 1 /* sync memory asynchronously */ #define MS_INVALIDATE 2 /* invalidate the caches */ diff --git a/include/asm-cris/mmu.h b/include/asm-cris/mmu.h index df2d5ee85c7b..c40a1bcad06c 100644 --- a/include/asm-cris/mmu.h +++ b/include/asm-cris/mmu.h @@ -5,58 +5,6 @@ #ifndef _CRIS_MMU_H #define _CRIS_MMU_H -/* type used in struct mm to couple an MMU context to an active mm */ - -typedef unsigned int mm_context_t; - -/* kernel memory segments */ - -#define KSEG_F 0xf0000000UL -#define KSEG_E 0xe0000000UL -#define KSEG_D 0xd0000000UL -#define KSEG_C 0xc0000000UL -#define KSEG_B 0xb0000000UL -#define KSEG_A 0xa0000000UL -#define KSEG_9 0x90000000UL -#define KSEG_8 0x80000000UL -#define KSEG_7 0x70000000UL -#define KSEG_6 0x60000000UL -#define KSEG_5 0x50000000UL -#define KSEG_4 0x40000000UL -#define KSEG_3 0x30000000UL -#define KSEG_2 0x20000000UL -#define KSEG_1 0x10000000UL -#define KSEG_0 0x00000000UL - -/* CRIS PTE bits (see R_TLB_LO in the register description) - * - * Bit: 31-13 12-------4 3 2 1 0 - * ________________________________________________ - * | pfn | reserved | global | valid | kernel | we | - * |_____|__________|________|_______|________|_____| - * - * (pfn = physical frame number) - */ - -/* Real HW-based PTE bits. We use some synonym names so that - * things become less confusing in combination with the SW-based - * bits further below. - * - */ - -#define _PAGE_WE (1<<0) /* page is write-enabled */ -#define _PAGE_SILENT_WRITE (1<<0) /* synonym */ -#define _PAGE_KERNEL (1<<1) /* page is kernel only */ -#define _PAGE_VALID (1<<2) /* page is valid */ -#define _PAGE_SILENT_READ (1<<2) /* synonym */ -#define _PAGE_GLOBAL (1<<3) /* global page - context is ignored */ - -/* Bits the HW doesn't care about but the kernel uses them in SW */ - -#define _PAGE_PRESENT (1<<4) /* page present in memory */ -#define _PAGE_ACCESSED (1<<5) /* simulated in software using valid bit */ -#define _PAGE_MODIFIED (1<<6) /* simulated in software using we bit */ -#define _PAGE_READ (1<<7) /* read-enabled */ -#define _PAGE_WRITE (1<<8) /* write-enabled */ +#include <asm/arch/mmu.h> #endif diff --git a/include/asm-cris/mmu_context.h b/include/asm-cris/mmu_context.h index 6a6ea71a85cd..dd1db4e98fcc 100644 --- a/include/asm-cris/mmu_context.h +++ b/include/asm-cris/mmu_context.h @@ -17,7 +17,7 @@ extern void switch_mm(struct mm_struct *prev, struct mm_struct *next, extern volatile pgd_t *current_pgd; /* defined in arch/cris/mm/fault.c */ -static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu) +extern inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu) { } diff --git a/include/asm-cris/module.h b/include/asm-cris/module.h index 5853a11d6163..7ee72311bd78 100644 --- a/include/asm-cris/module.h +++ b/include/asm-cris/module.h @@ -1,12 +1,9 @@ #ifndef _ASM_CRIS_MODULE_H #define _ASM_CRIS_MODULE_H -/* - * This file contains the CRIS architecture specific module code. - */ - -#define module_map(x) vmalloc(x) -#define module_unmap(x) vfree(x) -#define module_arch_init(x) (0) -#define arch_init_modules(x) do { } while (0) +/* cris is simple */ +struct mod_arch_specific { }; +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr #endif /* _ASM_CRIS_MODULE_H */ diff --git a/include/asm-cris/page.h b/include/asm-cris/page.h index 47c83465c2af..05dc15526aa3 100644 --- a/include/asm-cris/page.h +++ b/include/asm-cris/page.h @@ -2,7 +2,7 @@ #define _CRIS_PAGE_H #include <linux/config.h> -#include <asm/mmu.h> +#include <asm/arch/page.h> /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT 13 @@ -14,12 +14,9 @@ #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) #define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) -#define clear_user_page(page, vaddr) clear_page(page) -#define copy_user_page(to, from, vaddr) copy_page(to, from) +#define clear_user_page(page, vaddr, pg) clear_page(page) +#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) -#define STRICT_MM_TYPECHECKS - -#ifdef STRICT_MM_TYPECHECKS /* * These are used to make use of C type-checking.. */ @@ -38,52 +35,11 @@ typedef struct { unsigned long pgprot; } pgprot_t; #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) -#else -/* - * .. while these make it easier on the compiler - */ -typedef unsigned long pte_t; -typedef unsigned long pmd_t; -typedef unsigned long pgd_t; -typedef unsigned long pgprot_t; - -#define pte_val(x) (x) -#define pmd_val(x) (x) -#define pgd_val(x) (x) -#define pgprot_val(x) (x) - -#define __pte(x) (x) -#define __pmd(x) (x) -#define __pgd(x) (x) -#define __pgprot(x) (x) - -#endif - -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - -/* This handles the memory map.. */ - -#ifdef CONFIG_CRIS_LOW_MAP -#define PAGE_OFFSET KSEG_6 /* kseg_6 is mapped to physical ram */ -#else -#define PAGE_OFFSET KSEG_C /* kseg_c is mapped to physical ram */ -#endif - -/* macros to convert between really physical and virtual addresses - * by stripping a selected bit, we can convert between KSEG_x and 0x40000000 where - * the DRAM really resides - */ - -#ifdef CONFIG_CRIS_LOW_MAP -/* we have DRAM virtually at 0x6 */ -#define __pa(x) ((unsigned long)(x) & 0xdfffffff) -#define __va(x) ((void *)((unsigned long)(x) | 0x20000000)) -#else -/* we have DRAM virtually at 0xc */ -#define __pa(x) ((unsigned long)(x) & 0x7fffffff) -#define __va(x) ((void *)((unsigned long)(x) | 0x80000000)) -#endif +/* On CRIS the PFN numbers doesn't start at 0 so we have to compensate */ +/* for that before indexing into the page table starting at mem_map */ +#define pfn_to_page(pfn) (mem_map + ((pfn) - (PAGE_OFFSET >> PAGE_SHIFT))) +#define page_to_pfn(page) ((unsigned long)((page) - mem_map) + (PAGE_OFFSET >> PAGE_SHIFT)) +#define pfn_valid(pfn) (((pfn) - (PAGE_OFFSET >> PAGE_SHIFT)) < max_mapnr) /* to index into the page map. our pages all start at physical addr PAGE_OFFSET so * we can let the map start there. notice that we subtract PAGE_OFFSET because @@ -95,6 +51,7 @@ typedef unsigned long pgprot_t; #define virt_to_page(kaddr) (mem_map + (((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT)) #define VALID_PAGE(page) (((page) - mem_map) < max_mapnr) +#define virt_addr_valid(kaddr) pfn_valid((kaddr) >> PAGE_SHIFT) /* convert a page (based on mem_map and forward) to a physical address * do this by figuring out the virtual address and then use __pa @@ -102,9 +59,34 @@ typedef unsigned long pgprot_t; #define page_to_phys(page) __pa((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET) -/* from linker script */ +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +#ifndef __ASSEMBLY__ + +#define BUG() do { \ + printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ +} while (0) + +#define PAGE_BUG(page) do { \ + BUG(); \ +} while (0) + +#endif /* __ASSEMBLY__ */ + +/* Pure 2^n version of get_order */ +static inline int get_order(unsigned long size) +{ + int order; -extern unsigned long dram_start, dram_end; + size = (size-1) >> (PAGE_SHIFT-1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) diff --git a/include/asm-cris/param.h b/include/asm-cris/param.h index 50fe5729b29e..a9f71dbedb39 100644 --- a/include/asm-cris/param.h +++ b/include/asm-cris/param.h @@ -1,6 +1,13 @@ #ifndef _ASMCRIS_PARAM_H #define _ASMCRIS_PARAM_H +/* Currently we assume that HZ=100 is good for CRIS. */ +#ifdef __KERNEL__ +# define HZ 100 /* Internal kernel timer frequency */ +# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ +# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ +#endif + #ifndef HZ #define HZ 100 #endif @@ -17,8 +24,4 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ -#ifdef __KERNEL__ -# define CLOCKS_PER_SEC 100 /* frequency at which times() counts */ -#endif - #endif diff --git a/include/asm-cris/percpu.h b/include/asm-cris/percpu.h new file mode 100644 index 000000000000..6db9b43cf80a --- /dev/null +++ b/include/asm-cris/percpu.h @@ -0,0 +1,6 @@ +#ifndef _CRIS_PERCPU_H +#define _CRIS_PERCPU_H + +#include <asm-generic/percpu.h> + +#endif /* _CRIS_PERCPU_H */ diff --git a/include/asm-cris/pgalloc.h b/include/asm-cris/pgalloc.h index 75dde6f4a42f..ca769e060298 100644 --- a/include/asm-cris/pgalloc.h +++ b/include/asm-cris/pgalloc.h @@ -3,113 +3,65 @@ #include <asm/page.h> #include <linux/threads.h> +#include <linux/mm.h> -extern struct pgtable_cache_struct { - unsigned long *pgd_cache; - unsigned long *pte_cache; - unsigned long pgtable_cache_sz; -} quicklists; - -#define pgd_quicklist (quicklists.pgd_cache) -#define pmd_quicklist ((unsigned long *)0) -#define pte_quicklist (quicklists.pte_cache) -#define pgtable_cache_size (quicklists.pgtable_cache_sz) - -#define pmd_populate(mm, pmd, pte) pmd_set(pmd, pte) +#define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, pte) +#define pmd_populate(mm, pmd, pte) pmd_set(pmd, page_address(pte)) /* * Allocate and free page tables. */ -static inline pgd_t *get_pgd_slow(void) -{ - pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL); - - if (ret) { - memset(ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); - memcpy(ret + USER_PTRS_PER_PGD, swapper_pg_dir + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); - } - return ret; -} - -static inline void free_pgd_slow(pgd_t *pgd) +extern inline pgd_t *pgd_alloc (struct mm_struct *mm) { - free_page((unsigned long)pgd); + return (pgd_t *)get_zeroed_page(GFP_KERNEL); } -static inline pgd_t *get_pgd_fast(void) +extern inline void pgd_free (pgd_t *pgd) { - unsigned long *ret; - - if ((ret = pgd_quicklist) != NULL) { - pgd_quicklist = (unsigned long *)(*ret); - ret[0] = 0; - pgtable_cache_size--; - } else - ret = (unsigned long *)get_pgd_slow(); - return (pgd_t *)ret; + free_page((unsigned long)pgd); } -static inline void free_pgd_fast(pgd_t *pgd) +extern inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - *(unsigned long *)pgd = (unsigned long) pgd_quicklist; - pgd_quicklist = (unsigned long *) pgd; - pgtable_cache_size++; + pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); + if (pte) + clear_page(pte); + return pte; } -static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address) +extern inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) { - pte_t *pte; - - pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); - if (pte) - clear_page(pte); - return pte; + struct page *pte; + pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0); + if (pte) + clear_page(page_address(pte)); + return pte; } -static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address) +extern inline void pte_free_kernel(pte_t *pte) { - unsigned long *ret; - - if((ret = (unsigned long *)pte_quicklist) != NULL) { - pte_quicklist = (unsigned long *)(*ret); - ret[0] = ret[1]; - pgtable_cache_size--; - } - return (pte_t *)ret; + free_page((unsigned long)pte); } -static __inline__ void pte_free_fast(pte_t *pte) +extern inline void pte_free(struct page *pte) { - *(unsigned long *)pte = (unsigned long) pte_quicklist; - pte_quicklist = (unsigned long *) pte; - pgtable_cache_size++; + __free_page(pte); } -static __inline__ void pte_free_slow(pte_t *pte) -{ - free_page((unsigned long)pte); -} -#define pte_free(pte) pte_free_slow(pte) -#define pgd_free(pgd) free_pgd_slow(pgd) -#define pgd_alloc(mm) get_pgd_fast() +#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) /* * We don't have any real pmd's, and this code never triggers because * the pgd will always be present.. */ -#define pmd_alloc_one_fast(mm, addr) ({ BUG(); ((pmd_t *)1); }) -#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) -#define pmd_free_slow(x) do { } while (0) -#define pmd_free_fast(x) do { } while (0) -#define pmd_free(x) do { } while (0) -#define pgd_populate(mm, pmd, pte) BUG() - -/* other stuff */ +#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) +#define pmd_free(x) do { } while (0) +#define __pmd_free_tlb(tlb,x) do { } while (0) +#define pgd_populate(mm, pmd, pte) BUG() -extern int do_check_pgt_cache(int, int); +#define check_pgt_cache() do { } while (0) #endif diff --git a/include/asm-cris/pgtable.h b/include/asm-cris/pgtable.h index d3ffca513750..25b2b51b55b3 100644 --- a/include/asm-cris/pgtable.h +++ b/include/asm-cris/pgtable.h @@ -1,104 +1,14 @@ -/* CRIS pgtable.h - macros and functions to manipulate page tables - * - * HISTORY: - * - * $Log: pgtable.h,v $ - * Revision 1.14 2001/12/10 03:08:50 bjornw - * Added pgtable_cache_init dummy - * - * Revision 1.13 2001/11/12 18:05:38 pkj - * Added declaration of paging_init(). - * - * Revision 1.12 2001/08/11 00:28:00 bjornw - * PAGE_CHG_MASK and PAGE_NONE had somewhat untraditional values - * - * Revision 1.11 2001/04/04 14:38:36 bjornw - * Removed bad_pagetable handling and the _kernel functions - * - * Revision 1.10 2001/03/23 07:46:42 starvik - * Corrected according to review remarks - * - * Revision 1.9 2000/11/22 14:57:53 bjornw - * * extern inline -> static inline - * * include asm-generic/pgtable.h - * - * Revision 1.8 2000/11/21 13:56:16 bjornw - * Use CONFIG_CRIS_LOW_MAP for the low VM map instead of explicit CPU type - * - * Revision 1.7 2000/10/06 15:05:32 bjornw - * VMALLOC area changed in memory mapping change - * - * Revision 1.6 2000/10/04 16:59:14 bjornw - * Changed comments - * - * Revision 1.5 2000/09/13 14:39:53 bjornw - * New macros - * - * Revision 1.4 2000/08/17 15:38:48 bjornw - * 2.4.0-test6 modifications: - * * flush_dcache_page added - * * MAP_NR removed - * * virt_to_page added - * - * Plus some comments and type-clarifications. - * - * Revision 1.3 2000/08/15 16:33:35 bjornw - * pmd_bad should recognize both kernel and user page-tables - * - * Revision 1.2 2000/07/10 17:06:01 bjornw - * Fixed warnings - * - * Revision 1.1.1.1 2000/07/10 16:32:31 bjornw - * CRIS architecture, working draft - * - * - * Revision 1.11 2000/05/29 14:55:56 bjornw - * Small tweaks of pte_mk routines - * - * Revision 1.10 2000/01/27 01:49:06 bjornw - * * Ooops. The physical frame number in a PTE entry needs to point to the - * DRAM directly, not to what the kernel thinks is DRAM (due to KSEG mapping). - * Hence we need to strip bit 31 so 0xcXXXXXXX -> 0x4XXXXXXX. - * - * Revision 1.9 2000/01/26 16:25:50 bjornw - * Fixed PAGE_KERNEL bits - * - * Revision 1.8 2000/01/23 22:53:22 bjornw - * Correct flush_tlb_* macros and externs - * - * Revision 1.7 2000/01/18 16:22:55 bjornw - * Use PAGE_MASK instead of PFN_MASK. - * - * Revision 1.6 2000/01/17 02:42:53 bjornw - * Added the pmd_set macro. - * - * Revision 1.5 2000/01/16 19:53:42 bjornw - * Removed VMALLOC_OFFSET. Changed definitions of swapper_pg_dir and zero_page. - * - * Revision 1.4 2000/01/14 16:38:20 bjornw - * PAGE_DIRTY -> PAGE_SILENT_WRITE, removed PAGE_COW from PAGE_COPY. - * - * Revision 1.3 1999/12/04 20:12:21 bjornw - * * PTE bits have moved to asm/mmu.h - * * Fixed definitions of the higher level page protection bits - * * Added the pte_* functions, including dirty/accessed SW simulation - * (these are exactly the same as for the MIPS port) - * - * Revision 1.2 1999/12/04 00:41:54 bjornw - * * Fixed page table offsets, sizes and shifts - * * Removed reference to i386 SMP stuff - * * Added stray comments about Linux/CRIS mm design - * * Include asm/mmu.h which will contain MMU details - * - * Revision 1.1 1999/12/03 15:04:02 bjornw - * Copied from include/asm-etrax100. For the new CRIS architecture. +/* + * CRIS pgtable.h - macros and functions to manipulate page tables. */ #ifndef _CRIS_PGTABLE_H #define _CRIS_PGTABLE_H #include <linux/config.h> +#include <linux/sched.h> #include <asm/mmu.h> +#include <asm/arch/pgtable.h> /* * The Linux memory management assumes a three-level page table setup. On @@ -114,49 +24,6 @@ extern void paging_init(void); -/* The cache doesn't need to be flushed when TLB entries change because - * the cache is mapped to physical memory, not virtual memory - */ -#define flush_cache_all() 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_dcache_page(page) do { } while (0) -#define flush_icache_range(start, end) do { } while (0) -#define flush_icache_page(vma,pg) do { } while (0) -#define flush_icache_user_range(vma,pg,adr,len) do { } while (0) - -/* - * TLB flushing (implemented in arch/cris/mm/tlb.c): - * - * - flush_tlb() flushes the current mm struct TLBs - * - flush_tlb_all() flushes all processes TLBs - * - flush_tlb_mm(mm) flushes the specified mm context TLB's - * - flush_tlb_page(vma, vmaddr) flushes one page - * - flush_tlb_range(vma, start, end) flushes a range of pages - * - */ - -extern void flush_tlb_all(void); -extern void flush_tlb_mm(struct mm_struct *mm); -extern void flush_tlb_page(struct vm_area_struct *vma, - unsigned long addr); -extern void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, - unsigned long end); - -static inline void flush_tlb_pgtables(struct mm_struct *mm, - unsigned long start, unsigned long end) -{ - /* CRIS does not keep any page table caches in TLB */ -} - - -static inline void flush_tlb(void) -{ - flush_tlb_mm(current->mm); -} - /* Certain architectures need to do special things when pte's * within a page table are directly modified. Thus, the following * hook is made available. @@ -204,63 +71,6 @@ static inline void flush_tlb(void) #define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) #define FIRST_USER_PGD_NR 0 -/* - * Kernels own virtual memory area. - */ - -#ifdef CONFIG_CRIS_LOW_MAP -#define VMALLOC_START KSEG_7 -#define VMALLOC_VMADDR(x) ((unsigned long)(x)) -#define VMALLOC_END KSEG_8 -#else -#define VMALLOC_START KSEG_D -#define VMALLOC_VMADDR(x) ((unsigned long)(x)) -#define VMALLOC_END KSEG_E -#endif - -/* Define some higher level generic page attributes. The PTE bits are - * defined in asm-cris/mmu.h, and these are just combinations of those. - */ - -#define __READABLE (_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED) -#define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED) - -#define _PAGE_TABLE (_PAGE_PRESENT | __READABLE | __WRITEABLE) -#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED) - -#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) -#define PAGE_SHARED __pgprot(_PAGE_PRESENT | __READABLE | _PAGE_WRITE | \ - _PAGE_ACCESSED) -#define PAGE_COPY __pgprot(_PAGE_PRESENT | __READABLE) // | _PAGE_COW -#define PAGE_READONLY __pgprot(_PAGE_PRESENT | __READABLE) -#define PAGE_KERNEL __pgprot(_PAGE_GLOBAL | _PAGE_KERNEL | \ - _PAGE_PRESENT | __READABLE | __WRITEABLE) -#define _KERNPG_TABLE (_PAGE_TABLE | _PAGE_KERNEL) - -/* - * CRIS can't do page protection for execute, and considers read the same. - * Also, write permissions imply read permissions. This is the closest we can - * get.. - */ - -#define __P000 PAGE_NONE -#define __P001 PAGE_READONLY -#define __P010 PAGE_COPY -#define __P011 PAGE_COPY -#define __P100 PAGE_READONLY -#define __P101 PAGE_READONLY -#define __P110 PAGE_COPY -#define __P111 PAGE_COPY - -#define __S000 PAGE_NONE -#define __S001 PAGE_READONLY -#define __S010 PAGE_SHARED -#define __S011 PAGE_SHARED -#define __S100 PAGE_READONLY -#define __S101 PAGE_READONLY -#define __S110 PAGE_SHARED -#define __S111 PAGE_SHARED - /* zero page used for uninitialized stuff */ extern unsigned long empty_zero_page; #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) @@ -299,53 +109,54 @@ extern unsigned long empty_zero_page; * setup: the pgd is never bad, and a pmd always exists (as it's folded * into the pgd entry) */ -static inline int pgd_none(pgd_t pgd) { return 0; } -static inline int pgd_bad(pgd_t pgd) { return 0; } -static inline int pgd_present(pgd_t pgd) { return 1; } -static inline void pgd_clear(pgd_t * pgdp) { } +extern inline int pgd_none(pgd_t pgd) { return 0; } +extern inline int pgd_bad(pgd_t pgd) { return 0; } +extern inline int pgd_present(pgd_t pgd) { return 1; } +extern inline void pgd_clear(pgd_t * pgdp) { } /* * The following only work if pte_present() is true. * Undefined behaviour if not.. */ -static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_READ; } -static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } -static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_READ; } -static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; } -static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_READ; } +extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } +extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_READ; } +extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; } +extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +extern inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } -static inline pte_t pte_wrprotect(pte_t pte) +extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE); return pte; } -static inline pte_t pte_rdprotect(pte_t pte) +extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ); return pte; } -static inline pte_t pte_exprotect(pte_t pte) +extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ); return pte; } -static inline pte_t pte_mkclean(pte_t pte) +extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE); return pte; } -static inline pte_t pte_mkold(pte_t pte) +extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~(_PAGE_ACCESSED | _PAGE_SILENT_READ); return pte; } -static inline pte_t pte_mkwrite(pte_t pte) +extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; if (pte_val(pte) & _PAGE_MODIFIED) @@ -353,7 +164,7 @@ static inline pte_t pte_mkwrite(pte_t pte) return pte; } -static inline pte_t pte_mkread(pte_t pte) +extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_READ; if (pte_val(pte) & _PAGE_ACCESSED) @@ -361,7 +172,7 @@ static inline pte_t pte_mkread(pte_t pte) return pte; } -static inline pte_t pte_mkexec(pte_t pte) +extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) |= _PAGE_READ; if (pte_val(pte) & _PAGE_ACCESSED) @@ -369,7 +180,7 @@ static inline pte_t pte_mkexec(pte_t pte) return pte; } -static inline pte_t pte_mkdirty(pte_t pte) +extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_MODIFIED; if (pte_val(pte) & _PAGE_WRITE) @@ -377,7 +188,7 @@ static inline pte_t pte_mkdirty(pte_t pte) return pte; } -static inline pte_t pte_mkyoung(pte_t pte) +extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; if (pte_val(pte) & _PAGE_READ) @@ -401,7 +212,7 @@ static inline pte_t pte_mkyoung(pte_t pte) * addresses (the 0xc0xxxxxx's) goes as void *'s. */ -static inline pte_t __mk_pte(void * page, pgprot_t pgprot) +extern inline pte_t __mk_pte(void * page, pgprot_t pgprot) { pte_t pte; /* the PTE needs a physical address */ @@ -419,7 +230,7 @@ static inline pte_t __mk_pte(void * page, pgprot_t pgprot) __pte; \ }) -static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } @@ -428,7 +239,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) * pte_pagenr refers to the page-number counted starting from the virtual DRAM start */ -static inline unsigned long __pte_page(pte_t pte) +extern inline unsigned long __pte_page(pte_t pte) { /* the PTE contains a physical address */ return (unsigned long)__va(pte_val(pte) & PAGE_MASK); @@ -446,17 +257,17 @@ static inline unsigned long __pte_page(pte_t pte) * don't need the __pa and __va transformations. */ -static inline unsigned long pmd_page(pmd_t pmd) -{ return pmd_val(pmd) & PAGE_MASK; } - -static inline void pmd_set(pmd_t * pmdp, pte_t * ptep) +extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep) { pmd_val(*pmdp) = _PAGE_TABLE | (unsigned long) ptep; } +#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)) +#define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) + /* to find an entry in a page-table-directory. */ #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) /* to find an entry in a page-table-directory */ -static inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) +extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) { return mm->pgd + pgd_index(address); } @@ -465,16 +276,24 @@ static inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) #define pgd_offset_k(address) pgd_offset(&init_mm, address) /* Find an entry in the second-level page table.. */ -static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) +extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) { return (pmd_t *) dir; } -/* Find an entry in the third-level page table.. */ -static inline pte_t * pte_offset(pmd_t * dir, unsigned long address) -{ - return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); -} +/* Find an entry in the third-level page table.. */ +#define __pte_offset(address) \ + (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +#define pte_offset_kernel(dir, address) \ + ((pte_t *) pmd_page_kernel(*(dir)) + __pte_offset(address)) +#define pte_offset_map(dir, address) \ + ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address)) +#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address) + +#define pte_unmap(pte) do { } while (0) +#define pte_unmap_nested(pte) do { } while (0) +#define pte_pfn(x) ((unsigned long)(__va((x).pte)) >> PAGE_SHIFT) +#define pfn_pte(pfn, prot) __pte((__pa((pfn) << PAGE_SHIFT)) | pgprot_val(prot)) #define pte_ERROR(e) \ printk("%s:%d: bad pte %p(%08lx).\n", __FILE__, __LINE__, &(e), pte_val(e)) @@ -483,6 +302,7 @@ static inline pte_t * pte_offset(pmd_t * dir, unsigned long address) #define pgd_ERROR(e) \ printk("%s:%d: bad pgd %p(%08lx).\n", __FILE__, __LINE__, &(e), pgd_val(e)) + extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; /* defined in head.S */ /* @@ -491,7 +311,7 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; /* defined in head.S */ * * Actually I am not sure on what this could be used for. */ -static inline void update_mmu_cache(struct vm_area_struct * vma, +extern inline void update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t pte) { } @@ -514,6 +334,9 @@ static inline void update_mmu_cache(struct vm_area_struct * vma, */ #define pgtable_cache_init() do { } while (0) +#define pte_to_pgoff(x) (pte_val(x) >> 6) +#define pgoff_to_pte(x) __pte(((x) << 6) | _PAGE_FILE) + typedef pte_t *pte_addr_t; #endif /* _CRIS_PGTABLE_H */ diff --git a/include/asm-cris/poll.h b/include/asm-cris/poll.h index 8699d59dad74..1c0efc3e4be7 100644 --- a/include/asm-cris/poll.h +++ b/include/asm-cris/poll.h @@ -14,6 +14,7 @@ #define POLLWRNORM 256 #define POLLWRBAND 512 #define POLLMSG 1024 +#define POLLREMOVE 4096 struct pollfd { int fd; diff --git a/include/asm-cris/posix_types.h b/include/asm-cris/posix_types.h index d10e9fc65c32..d1c87c652619 100644 --- a/include/asm-cris/posix_types.h +++ b/include/asm-cris/posix_types.h @@ -23,12 +23,14 @@ typedef int __kernel_pid_t; typedef unsigned short __kernel_ipc_pid_t; typedef unsigned short __kernel_uid_t; typedef unsigned short __kernel_gid_t; -typedef unsigned long __kernel_size_t; +typedef __SIZE_TYPE__ __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; diff --git a/include/asm-cris/processor.h b/include/asm-cris/processor.h index 0a8c08fa93b5..623bdf06d911 100644 --- a/include/asm-cris/processor.h +++ b/include/asm-cris/processor.h @@ -14,32 +14,12 @@ #include <asm/system.h> #include <asm/page.h> #include <asm/ptrace.h> - -/* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). - */ -#define current_text_addr() ({void *pc; __asm__ ("move.d $pc,%0" : "=rm" (pc)); pc; }) - -/* CRIS has no problems with write protection */ - -#define wp_works_ok 1 - -/* - * User space process size. This is hardcoded into a few places, - * so don't change it unless you know what you are doing. - */ - -#ifdef CONFIG_CRIS_LOW_MAP -#define TASK_SIZE (0x50000000UL) /* 1.25 GB */ -#else -#define TASK_SIZE (0xB0000000UL) /* 2.75 GB */ -#endif +#include <asm/arch/processor.h> /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ -#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) +#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3)) /* THREAD_SIZE is the size of the task_struct/kernel_stack combo. * normally, the stack is found by doing something like p + THREAD_SIZE @@ -49,19 +29,6 @@ #define THREAD_SIZE PAGE_SIZE #define KERNEL_STACK_SIZE PAGE_SIZE -/* CRIS thread_struct. this really has nothing to do with the processor itself, since - * CRIS does not do any hardware task-switching, but it's here for legacy reasons. - * The thread_struct here is used when task-switching using _resume defined in entry.S. - * The offsets here are hardcoded into _resume - if you change this struct, you need to - * change them as well!!! -*/ - -struct thread_struct { - unsigned long ksp; /* kernel stack pointer */ - unsigned long usp; /* user stack pointer */ - unsigned long dccr; /* saved flag register */ -}; - /* * At user->kernel entry, the pt_regs struct is stacked on the top of the kernel-stack. * This macro allows us to find those regs for a task. @@ -70,76 +37,42 @@ struct thread_struct { * registers are reached by this. */ -#define user_regs(task) (((struct pt_regs *)((unsigned long)(task) + THREAD_SIZE)) - 1) +#define user_regs(thread_info) (((struct pt_regs *)((unsigned long)(thread_info) + THREAD_SIZE)) - 1) /* * Dito but for the currently running task */ -#define current_regs() user_regs(current) +#define current_regs() user_regs(current->thread_info) -#define INIT_THREAD { \ - 0, 0, 0x20 } /* ccr = int enable, nothing else */ +extern inline void prepare_to_copy(struct task_struct *tsk) +{ +} extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); -/* give the thread a program location - * set user-mode (The 'U' flag (User mode flag) is CCR/DCCR bit 8) - * switch user-stackpointer - */ - -#define start_thread(regs, ip, usp) do { \ - set_fs(USER_DS); \ - regs->irp = ip; \ - regs->dccr |= 1 << U_DCCR_BITNR; \ - wrusp(usp); \ -} while(0) - unsigned long get_wchan(struct task_struct *p); -#define KSTK_EIP(tsk) \ - ({ \ - unsigned long eip = 0; \ - unsigned long regs = (unsigned long)user_regs(tsk); \ - if (regs > PAGE_SIZE && \ - virt_addr_valid(regs)) \ - eip = ((struct pt_regs *)regs)->irp; \ - eip; }) - #define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) /* * Free current thread data structures etc.. */ -static inline void exit_thread(void) +extern inline void exit_thread(void) { /* Nothing needs to be done. */ } +extern unsigned long thread_saved_pc(struct task_struct *tsk); + /* Free all resources held by a thread. */ -static inline void release_thread(struct task_struct *dead_task) +extern inline void release_thread(struct task_struct *dead_task) { /* Nothing needs to be done. */ } -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy(tsk) do { } while (0) - -/* - * Return saved PC of a blocked thread. - */ -extern inline unsigned long thread_saved_pc(struct thread_struct *t) -{ - return (unsigned long)user_regs(t)->irp; -} - -#define alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) -#define free_task_struct(p) free_pages((unsigned long) (p), 1) -#define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count) - -#define init_task (init_task_union.task) -#define init_stack (init_task_union.stack) +#define init_stack (init_thread_union.stack) #define cpu_relax() barrier() diff --git a/include/asm-cris/ptrace.h b/include/asm-cris/ptrace.h index b7391cc079dc..79045e36d0a9 100644 --- a/include/asm-cris/ptrace.h +++ b/include/asm-cris/ptrace.h @@ -1,120 +1,10 @@ #ifndef _CRIS_PTRACE_H #define _CRIS_PTRACE_H -/* Register numbers in the ptrace system call interface */ +#include <asm/arch/ptrace.h> -#define PT_FRAMETYPE 0 -#define PT_ORIG_R10 1 -#define PT_R13 2 -#define PT_R12 3 -#define PT_R11 4 -#define PT_R10 5 -#define PT_R9 6 -#define PT_R8 7 -#define PT_R7 8 -#define PT_R6 9 -#define PT_R5 10 -#define PT_R4 11 -#define PT_R3 12 -#define PT_R2 13 -#define PT_R1 14 -#define PT_R0 15 -#define PT_MOF 16 -#define PT_DCCR 17 -#define PT_SRP 18 -#define PT_IRP 19 /* This is actually the debugged process' PC */ -#define PT_CSRINSTR 20 /* CPU Status record remnants - - valid if frametype == busfault */ -#define PT_CSRADDR 21 -#define PT_CSRDATA 22 -#define PT_USP 23 /* special case - USP is not in the pt_regs */ -#define PT_MAX 23 - -/* Condition code bit numbers. The same numbers apply to CCR of course, - but we use DCCR everywhere else, so let's try and be consistent. */ -#define C_DCCR_BITNR 0 -#define V_DCCR_BITNR 1 -#define Z_DCCR_BITNR 2 -#define N_DCCR_BITNR 3 -#define X_DCCR_BITNR 4 -#define I_DCCR_BITNR 5 -#define B_DCCR_BITNR 6 -#define M_DCCR_BITNR 7 -#define U_DCCR_BITNR 8 -#define P_DCCR_BITNR 9 -#define F_DCCR_BITNR 10 - -/* Frame types */ - -#define CRIS_FRAME_NORMAL 0 /* normal frame without SBFS stacking */ -#define CRIS_FRAME_BUSFAULT 1 /* frame stacked using SBFS, need RBF return - path */ - -/* pt_regs not only specifices the format in the user-struct during - * ptrace but is also the frame format used in the kernel prologue/epilogues - * themselves - */ - -struct pt_regs { - unsigned long frametype; /* type of stackframe */ - unsigned long orig_r10; - /* pushed by movem r13, [sp] in SAVE_ALL, movem pushes backwards */ - unsigned long r13; - unsigned long r12; - unsigned long r11; - unsigned long r10; - unsigned long r9; - unsigned long r8; - unsigned long r7; - unsigned long r6; - unsigned long r5; - unsigned long r4; - unsigned long r3; - unsigned long r2; - unsigned long r1; - unsigned long r0; - unsigned long mof; - unsigned long dccr; - unsigned long srp; - unsigned long irp; /* This is actually the debugged process' PC */ - unsigned long csrinstr; - unsigned long csraddr; - unsigned long csrdata; -}; - -/* switch_stack is the extra stuff pushed onto the stack in _resume (entry.S) - * when doing a context-switch. it is used (apart from in resume) when a new - * thread is made and we need to make _resume (which is starting it for the - * first time) realise what is going on. - * - * Actually, the use is very close to the thread struct (TSS) in that both the - * switch_stack and the TSS are used to keep thread stuff when switching in - * _resume. - */ - -struct switch_stack { - unsigned long r9; - unsigned long r8; - unsigned long r7; - unsigned long r6; - unsigned long r5; - unsigned long r4; - unsigned long r3; - unsigned long r2; - unsigned long r1; - unsigned long r0; - unsigned long return_ip; /* ip that _resume will return to */ -}; - -#ifdef __KERNEL__ /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ #define PTRACE_GETREGS 12 #define PTRACE_SETREGS 13 -/* bit 8 is user-mode flag */ -#define user_mode(regs) (((regs)->dccr & 0x100) != 0) -#define instruction_pointer(regs) ((regs)->irp) -extern void show_regs(struct pt_regs *); -#endif - #endif /* _CRIS_PTRACE_H */ diff --git a/include/asm-cris/rs485.h b/include/asm-cris/rs485.h new file mode 100644 index 000000000000..c331c51b0c2b --- /dev/null +++ b/include/asm-cris/rs485.h @@ -0,0 +1,20 @@ +/* RS-485 structures */ + +/* RS-485 support */ +/* Used with ioctl() TIOCSERSETRS485 */ +struct rs485_control { + unsigned short rts_on_send; + unsigned short rts_after_sent; + unsigned long delay_rts_before_send; + unsigned short enabled; +#ifdef __KERNEL__ + int disable_serial_loopback; +#endif +}; + +/* Used with ioctl() TIOCSERWRRS485 */ +struct rs485_write { + unsigned short outc_size; + unsigned char *outc; +}; + diff --git a/include/asm-cris/rtc.h b/include/asm-cris/rtc.h index 72ff33a48a8d..382081c4ab52 100644 --- a/include/asm-cris/rtc.h +++ b/include/asm-cris/rtc.h @@ -1,42 +1,81 @@ -/* $Id: rtc.h,v 1.3 2001/03/21 09:56:31 magnusmn Exp $ */ +/* $Id: rtc.h,v 1.7 2002/11/04 07:32:09 starvik Exp $ */ + +#ifndef __RTC_H__ +#define __RTC_H__ -#ifndef RTC_H -#define RTC_H #include <linux/config.h> -/* Dallas DS1302 clock/calendar register numbers */ +#ifdef CONFIG_ETRAX_DS1302 + /* Dallas DS1302 clock/calendar register numbers. */ +# define RTC_SECONDS 0 +# define RTC_MINUTES 1 +# define RTC_HOURS 2 +# define RTC_DAY_OF_MONTH 3 +# define RTC_MONTH 4 +# define RTC_WEEKDAY 5 +# define RTC_YEAR 6 +# define RTC_CONTROL 7 + + /* Bits in CONTROL register. */ +# define RTC_CONTROL_WRITEPROTECT 0x80 +# define RTC_TRICKLECHARGER 8 + + /* Bits in TRICKLECHARGER register TCS TCS TCS TCS DS DS RS RS. */ +# define RTC_TCR_PATTERN 0xA0 /* 1010xxxx */ +# define RTC_TCR_1DIOD 0x04 /* xxxx01xx */ +# define RTC_TCR_2DIOD 0x08 /* xxxx10xx */ +# define RTC_TCR_DISABLED 0x00 /* xxxxxx00 Disabled */ +# define RTC_TCR_2KOHM 0x01 /* xxxxxx01 2KOhm */ +# define RTC_TCR_4KOHM 0x02 /* xxxxxx10 4kOhm */ +# define RTC_TCR_8KOHM 0x03 /* xxxxxx11 8kOhm */ + +#elif defined(CONFIG_ETRAX_PCF8563) + /* I2C bus slave registers. */ +# define RTC_I2C_READ 0xa3 +# define RTC_I2C_WRITE 0xa2 -#define RTC_SECONDS 0 -#define RTC_MINUTES 1 -#define RTC_HOURS 2 -#define RTC_DAY_OF_MONTH 3 -#define RTC_MONTH 4 -#define RTC_WEEKDAY 5 -#define RTC_YEAR 6 -#define RTC_CONTROL 7 + /* Phillips PCF8563 registers. */ +# define RTC_CONTROL1 0x00 /* Control/Status register 1. */ +# define RTC_CONTROL2 0x01 /* Control/Status register 2. */ +# define RTC_CLOCKOUT_FREQ 0x0d /* CLKOUT frequency. */ +# define RTC_TIMER_CONTROL 0x0e /* Timer control. */ +# define RTC_TIMER_CNTDOWN 0x0f /* Timer countdown. */ -/* Bits in CONTROL register */ -#define RTC_CONTROL_WRITEPROTECT 0x80 -#define RTC_TRICKLECHARGER 8 -/* Bits in TRICKLECHARGER register TCS TCS TCS TCS DS DS RS RS */ -#define RTC_TCR_PATTERN 0xA0 /* 1010xxxx */ -#define RTC_TCR_1DIOD 0x04 /* xxxx01xx */ -#define RTC_TCR_2DIOD 0x08 /* xxxx10xx */ -#define RTC_TCR_DISABLED 0x00 /* xxxxxx00 Disabled */ -#define RTC_TCR_2KOHM 0x01 /* xxxxxx01 2KOhm */ -#define RTC_TCR_4KOHM 0x02 /* xxxxxx10 4kOhm */ -#define RTC_TCR_8KOHM 0x03 /* xxxxxx11 8kOhm */ + /* BCD encoded clock registers. */ +# define RTC_SECONDS 0x02 +# define RTC_MINUTES 0x03 +# define RTC_HOURS 0x04 +# define RTC_DAY_OF_MONTH 0x05 +# define RTC_WEEKDAY 0x06 /* Not coded in BCD! */ +# define RTC_MONTH 0x07 +# define RTC_YEAR 0x08 +# define RTC_MINUTE_ALARM 0x09 +# define RTC_HOUR_ALARM 0x0a +# define RTC_DAY_ALARM 0x0b +# define RTC_WEEKDAY_ALARM 0x0c + +#endif #ifdef CONFIG_ETRAX_DS1302 -#define CMOS_READ(x) ds1302_readreg(x) -#define CMOS_WRITE(val,reg) ds1302_writereg(reg,val) -#define RTC_INIT() ds1302_init() +extern unsigned char ds1302_readreg(int reg); +extern void ds1302_writereg(int reg, unsigned char val); +extern int ds1302_init(void); +# define CMOS_READ(x) ds1302_readreg(x) +# define CMOS_WRITE(val,reg) ds1302_writereg(reg,val) +# define RTC_INIT() ds1302_init() +#elif defined(CONFIG_ETRAX_PCF8563) +extern unsigned char pcf8563_readreg(int reg); +extern void pcf8563_writereg(int reg, unsigned char val); +extern int pcf8563_init(void); +# define CMOS_READ(x) pcf8563_readreg(x) +# define CMOS_WRITE(val,reg) pcf8563_writereg(reg,val) +# define RTC_INIT() pcf8563_init() #else -/* no RTC configured so we shouldn't try to access any */ -#define CMOS_READ(x) 42 -#define CMOS_WRITE(x,y) -#define RTC_INIT() (-1) + /* No RTC configured so we shouldn't try to access any. */ +# define CMOS_READ(x) 42 +# define CMOS_WRITE(x,y) +# define RTC_INIT() (-1) #endif /* @@ -44,7 +83,6 @@ * struct tm in <time.h>, but it needs to be here so that the kernel * source is self contained, allowing cross-compiles, etc. etc. */ - struct rtc_time { int tm_sec; int tm_min; @@ -57,14 +95,11 @@ struct rtc_time { int tm_isdst; }; -/* - * ioctl calls that are permitted to the /dev/rtc interface - */ - -#define RTC_RD_TIME _IOR('p', 0x09, struct rtc_time) /* Read RTC time */ -#define RTC_SET_TIME _IOW('p', 0x0a, struct rtc_time) /* Set RTC time */ -#define RTC_SET_CHARGE _IOW('p', 0x0b, int) /* Set CHARGE mode */ - -#endif - +/* ioctl() calls that are permitted to the /dev/rtc interface. */ +#define RTC_MAGIC 'p' +#define RTC_RD_TIME _IOR(RTC_MAGIC, 0x09, struct rtc_time) /* Read RTC time. */ +#define RTC_SET_TIME _IOW(RTC_MAGIC, 0x0a, struct rtc_time) /* Set RTC time. */ +#define RTC_SET_CHARGE _IOW(RTC_MAGIC, 0x0b, int) +#define RTC_MAX_IOCTL 0x0b +#endif /* __RTC_H__ */ diff --git a/include/asm-cris/scatterlist.h b/include/asm-cris/scatterlist.h index 11a64f5fe30b..4bdc44c4ac3d 100644 --- a/include/asm-cris/scatterlist.h +++ b/include/asm-cris/scatterlist.h @@ -11,6 +11,8 @@ struct scatterlist { }; +#define sg_dma_address(sg) ((sg)->address) +#define sg_dma_len(sg) ((sg)->length) /* i386 junk */ #define ISA_DMA_THRESHOLD (0x1fffffff) diff --git a/include/asm-cris/semaphore-helper.h b/include/asm-cris/semaphore-helper.h index 3453c88c2f2e..461c5e4fc7b8 100644 --- a/include/asm-cris/semaphore-helper.h +++ b/include/asm-cris/semaphore-helper.h @@ -9,6 +9,7 @@ #define _ASM_SEMAPHORE_HELPER_H #include <asm/atomic.h> +#include <linux/errno.h> #define read(a) ((a)->counter) #define inc(a) (((a)->counter)++) @@ -19,32 +20,34 @@ /* * These two _must_ execute atomically wrt each other. */ -static inline void wake_one_more(struct semaphore * sem) +extern inline void wake_one_more(struct semaphore * sem) { atomic_inc(&sem->waking); } -static inline int waking_non_zero(struct semaphore *sem) +extern inline int waking_non_zero(struct semaphore *sem) { unsigned long flags; int ret = 0; - save_and_cli(flags); + local_save_flags(flags); + local_irq_disable(); if (read(&sem->waking) > 0) { dec(&sem->waking); ret = 1; } - restore_flags(flags); + local_irq_restore(flags); return ret; } -static inline int waking_non_zero_interruptible(struct semaphore *sem, +extern inline int waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk) { int ret = 0; unsigned long flags; - save_and_cli(flags); + local_save_flags(flags); + local_irq_disable(); if (read(&sem->waking) > 0) { dec(&sem->waking); ret = 1; @@ -52,23 +55,24 @@ static inline int waking_non_zero_interruptible(struct semaphore *sem, count_inc(&sem->count); ret = -EINTR; } - restore_flags(flags); + local_irq_restore(flags); return ret; } -static inline int waking_non_zero_trylock(struct semaphore *sem) +extern inline int waking_non_zero_trylock(struct semaphore *sem) { int ret = 1; unsigned long flags; - save_and_cli(flags); + local_save_flags(flags); + local_irq_disable(); if (read(&sem->waking) <= 0) count_inc(&sem->count); else { dec(&sem->waking); ret = 0; } - restore_flags(flags); + local_irq_restore(flags); return ret; } diff --git a/include/asm-cris/semaphore.h b/include/asm-cris/semaphore.h index f55edcd2f8d2..011a3bdc9ca7 100644 --- a/include/asm-cris/semaphore.h +++ b/include/asm-cris/semaphore.h @@ -54,12 +54,12 @@ extern inline void sema_init(struct semaphore *sem, int val) *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); } -static inline void init_MUTEX (struct semaphore *sem) +extern inline void init_MUTEX (struct semaphore *sem) { sema_init(sem, 1); } -static inline void init_MUTEX_LOCKED (struct semaphore *sem) +extern inline void init_MUTEX_LOCKED (struct semaphore *sem) { sema_init(sem, 0); } @@ -81,10 +81,10 @@ extern inline void down(struct semaphore * sem) #endif /* atomically decrement the semaphores count, and if its negative, we wait */ - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); failed = --(sem->count) < 0; - restore_flags(flags); + local_irq_restore(flags); if(failed) { __down(sem); } @@ -106,10 +106,10 @@ extern inline int down_interruptible(struct semaphore * sem) #endif /* atomically decrement the semaphores count, and if its negative, we wait */ - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); failed = --(sem->count) < 0; - restore_flags(flags); + local_irq_restore(flags); if(failed) failed = __down_interruptible(sem); return(failed); @@ -124,10 +124,10 @@ extern inline int down_trylock(struct semaphore * sem) CHECK_MAGIC(sem->__magic); #endif - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); failed = --(sem->count) < 0; - restore_flags(flags); + local_irq_restore(flags); if(failed) failed = __down_trylock(sem); return(failed); @@ -149,10 +149,10 @@ extern inline void up(struct semaphore * sem) #endif /* atomically increment the semaphores count, and if it was negative, we wake people */ - save_flags(flags); - cli(); + local_save_flags(flags); + local_irq_disable(); wakeup = ++(sem->count) <= 0; - restore_flags(flags); + local_irq_restore(flags); if(wakeup) { __up(sem); } diff --git a/include/asm-cris/setup.h b/include/asm-cris/setup.h index f382d3b4d282..832c197edf48 100644 --- a/include/asm-cris/setup.h +++ b/include/asm-cris/setup.h @@ -1,405 +1,3 @@ -/* -** asm/setup.h -- Definition of the Linux/m68k boot information structure -** -** Copyright 1992 by Greg Harp -** -** 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. -** -** Created 09/29/92 by Greg Harp -** -** 5/2/94 Roman Hodek: -** Added bi_atari part of the machine dependent union bi_un; for now it -** contains just a model field to distinguish between TT and Falcon. -** 26/7/96 Roman Zippel: -** Renamed to setup.h; added some useful macros to allow gcc some -** optimizations if possible. -*/ - -#ifndef _M68K_SETUP_H -#define _M68K_SETUP_H - -#include <linux/config.h> - -#define CL_SIZE (256) - -#if 0 - -#include <asm/zorro.h> - -/* - * Amiga specific part of bootinfo structure. - */ - -#define NUM_AUTO 16 - -#ifndef __ASSEMBLY__ - -#define AMIGAHW_DECLARE(name) unsigned name : 1 -#define AMIGAHW_SET(name) (boot_info.bi_amiga.hw_present.name = 1) -#define AMIGAHW_PRESENT(name) (boot_info.bi_amiga.hw_present.name) - -struct bi_Amiga { - int model; /* Amiga Model (3000?) */ - int num_autocon; /* # of autoconfig devices found */ - struct ConfigDev autocon[NUM_AUTO]; /* up to 16 autoconfig devices */ -#ifdef HACKER_KERNEL - void (*exit_func)(void); /* addr of function to exit kernel */ - unsigned long chip_addr; /* start of chip memory (bytes) */ +#ifndef _CRIS_SETUP_H +#define _CRIS_SETUP_H #endif - unsigned long chip_size; /* size of chip memory (bytes) */ - unsigned char vblank; /* VBLANK frequency */ - unsigned char psfreq; /* power supply frequency */ - unsigned long eclock; /* EClock frequency */ - unsigned long chipset; /* native chipset present */ - struct { - /* video hardware */ - AMIGAHW_DECLARE(AMI_VIDEO); /* Amiga Video */ - AMIGAHW_DECLARE(AMI_BLITTER); /* Amiga Blitter */ - AMIGAHW_DECLARE(AMBER_FF); /* Amber Flicker Fixer */ - /* sound hardware */ - AMIGAHW_DECLARE(AMI_AUDIO); /* Amiga Audio */ - /* disk storage interfaces */ - AMIGAHW_DECLARE(AMI_FLOPPY); /* Amiga Floppy */ - AMIGAHW_DECLARE(A3000_SCSI); /* SCSI (wd33c93, A3000 alike) */ - AMIGAHW_DECLARE(A4000_SCSI); /* SCSI (ncr53c710, A4000T alike) */ - AMIGAHW_DECLARE(A1200_IDE); /* IDE (A1200 alike) */ - AMIGAHW_DECLARE(A4000_IDE); /* IDE (A4000 alike) */ - AMIGAHW_DECLARE(CD_ROM); /* CD ROM drive */ - /* other I/O hardware */ - AMIGAHW_DECLARE(AMI_KEYBOARD); /* Amiga Keyboard */ - AMIGAHW_DECLARE(AMI_MOUSE); /* Amiga Mouse */ - AMIGAHW_DECLARE(AMI_SERIAL); /* Amiga Serial */ - AMIGAHW_DECLARE(AMI_PARALLEL); /* Amiga Parallel */ - /* real time clocks */ - AMIGAHW_DECLARE(A2000_CLK); /* Hardware Clock (A2000 alike) */ - AMIGAHW_DECLARE(A3000_CLK); /* Hardware Clock (A3000 alike) */ - /* supporting hardware */ - AMIGAHW_DECLARE(CHIP_RAM); /* Chip RAM */ - AMIGAHW_DECLARE(PAULA); /* Paula (8364) */ - AMIGAHW_DECLARE(DENISE); /* Denise (8362) */ - AMIGAHW_DECLARE(DENISE_HR); /* Denise (8373) */ - AMIGAHW_DECLARE(LISA); /* Lisa (8375) */ - AMIGAHW_DECLARE(AGNUS_PAL); /* Normal/Fat PAL Agnus (8367/8371) */ - AMIGAHW_DECLARE(AGNUS_NTSC); /* Normal/Fat NTSC Agnus (8361/8370) */ - AMIGAHW_DECLARE(AGNUS_HR_PAL); /* Fat Hires PAL Agnus (8372) */ - AMIGAHW_DECLARE(AGNUS_HR_NTSC); /* Fat Hires NTSC Agnus (8372) */ - AMIGAHW_DECLARE(ALICE_PAL); /* PAL Alice (8374) */ - AMIGAHW_DECLARE(ALICE_NTSC); /* NTSC Alice (8374) */ - AMIGAHW_DECLARE(MAGIC_REKICK); /* A3000 Magic Hard Rekick */ - AMIGAHW_DECLARE(ZORRO); /* Zorro AutoConfig */ - } hw_present; -}; - -#else /* __ASSEMBLY__ */ - -BI_amiga_model = BI_un -BI_amiga_num_autcon = BI_amiga_model+4 -BI_amiga_autocon = BI_amiga_num_autcon+4 -#ifdef HACKER_KERNEL -BI_amiga_exit_func = BI_amiga_autocon+(CD_sizeof*NUM_AUTO) -BI_amiga_chip_addr = BI_amiga_exit_func+4 -BI_amiga_chip_size = BI_amiga_chip_addr+4 -#else -BI_amiga_chip_size = BI_amiga_autocon+(CD_sizeof*NUM_AUTO) -#endif -BI_amiga_vblank = BI_amiga_chip_size+4 -BI_amiga_psfreq = BI_amiga_vblank+1 -BI_amiga_eclock = BI_amiga_psfreq+1 -BI_amiga_chipset = BI_amiga_eclock+4 -BI_amiga_hw_present = BI_amiga_chipset+4 - -#endif /* __ASSEMBLY__ */ - -/* Atari specific part of bootinfo */ - -/* - * Define several Hardware-Chips for indication so that for the ATARI we do - * no longer decide whether it is a Falcon or other machine . It's just - * important what hardware the machine uses - */ - -/* ++roman 08/08/95: rewritten from ORing constants to a C bitfield */ - -#ifndef __ASSEMBLY__ - -#define ATARIHW_DECLARE(name) unsigned name : 1 -#define ATARIHW_SET(name) (boot_info.bi_atari.hw_present.name = 1) -#define ATARIHW_PRESENT(name) (boot_info.bi_atari.hw_present.name) - -struct bi_Atari { - struct { - /* video hardware */ - ATARIHW_DECLARE(STND_SHIFTER); /* ST-Shifter - no base low ! */ - ATARIHW_DECLARE(EXTD_SHIFTER); /* STe-Shifter - 24 bit address */ - ATARIHW_DECLARE(TT_SHIFTER); /* TT-Shifter */ - ATARIHW_DECLARE(VIDEL_SHIFTER); /* Falcon-Shifter */ - /* sound hardware */ - ATARIHW_DECLARE(YM_2149); /* Yamaha YM 2149 */ - ATARIHW_DECLARE(PCM_8BIT); /* PCM-Sound in STe-ATARI */ - ATARIHW_DECLARE(CODEC); /* CODEC Sound (Falcon) */ - /* disk storage interfaces */ - ATARIHW_DECLARE(TT_SCSI); /* Directly mapped NCR5380 */ - ATARIHW_DECLARE(ST_SCSI); /* NCR5380 via ST-DMA (Falcon) */ - ATARIHW_DECLARE(ACSI); /* Standard ACSI like in STs */ - ATARIHW_DECLARE(IDE); /* IDE Interface */ - ATARIHW_DECLARE(FDCSPEED); /* 8/16 MHz switch for FDC */ - /* other I/O hardware */ - ATARIHW_DECLARE(ST_MFP); /* The ST-MFP (there should - be no Atari without - it... but who knows?) */ - ATARIHW_DECLARE(TT_MFP); /* 2nd MFP */ - ATARIHW_DECLARE(SCC); /* Serial Communications Contr. */ - ATARIHW_DECLARE(ST_ESCC); /* SCC Z83230 in an ST */ - ATARIHW_DECLARE(ANALOG_JOY); /* Paddle Interface for STe - and Falcon */ - ATARIHW_DECLARE(MICROWIRE); /* Microwire Interface */ - /* DMA */ - ATARIHW_DECLARE(STND_DMA); /* 24 Bit limited ST-DMA */ - ATARIHW_DECLARE(EXTD_DMA); /* 32 Bit ST-DMA */ - ATARIHW_DECLARE(SCSI_DMA); /* DMA for the NCR5380 */ - ATARIHW_DECLARE(SCC_DMA); /* DMA for the SCC */ - /* real time clocks */ - ATARIHW_DECLARE(TT_CLK); /* TT compatible clock chip */ - ATARIHW_DECLARE(MSTE_CLK); /* Mega ST(E) clock chip */ - /* supporting hardware */ - ATARIHW_DECLARE(SCU); /* System Control Unit */ - ATARIHW_DECLARE(BLITTER); /* Blitter */ - ATARIHW_DECLARE(VME); /* VME Bus */ - } hw_present; - unsigned long mch_cookie; /* _MCH cookie from TOS */ -}; - -/* mch_cookie values (upper word) */ -#define ATARI_MCH_ST 0 -#define ATARI_MCH_STE 1 -#define ATARI_MCH_TT 2 -#define ATARI_MCH_FALCON 3 - -struct mem_info { - unsigned long addr; /* physical address of memory chunk */ - unsigned long size; /* length of memory chunk (in bytes) */ -}; - -#else /* __ASSEMBLY__ */ - -MI_addr = 0 -MI_size = MI_addr+4 -MI_sizeof = MI_size+4 - -#endif /* __ASSEMBLY__ */ - -#define NUM_MEMINFO 4 - -#define MACH_AMIGA 1 -#define MACH_ATARI 2 -#define MACH_MAC 3 - -/* - * CPU and FPU types - */ - -#define CPUB_68020 0 -#define CPUB_68030 1 -#define CPUB_68040 2 -#define CPUB_68060 3 -#define FPUB_68881 5 -#define FPUB_68882 6 -#define FPUB_68040 7 /* Internal FPU */ -#define FPUB_68060 8 /* Internal FPU */ - -#define CPU_68020 (1<<CPUB_68020) -#define CPU_68030 (1<<CPUB_68030) -#define CPU_68040 (1<<CPUB_68040) -#define CPU_68060 (1<<CPUB_68060) -#define CPU_MASK (31) -#define FPU_68881 (1<<FPUB_68881) -#define FPU_68882 (1<<FPUB_68882) -#define FPU_68040 (1<<FPUB_68040) /* Internal FPU */ -#define FPU_68060 (1<<FPUB_68060) /* Internal FPU */ -#define FPU_MASK (0xfe0) - -#define CL_SIZE (256) - -/* - * machine type definitions - */ - -#if !defined(CONFIG_AMIGA) -# define MACH_IS_AMIGA (0) -#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) -# define MACH_IS_AMIGA (boot_info.machtype == MACH_AMIGA) -#else -# define CONFIG_AMIGA_ONLY -# define MACH_IS_AMIGA (1) -# define MACH_TYPE (MACH_AMIGA) -#endif - -#if !defined(CONFIG_ATARI) -# define MACH_IS_ATARI (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) -# define MACH_IS_ATARI (boot_info.machtype == MACH_ATARI) -#else -# define CONFIG_ATARI_ONLY -# define MACH_IS_ATARI (1) -# define MACH_TYPE (MACH_ATARI) -#endif - -#if defined(CONFIG_MAC) -# error Currently no Mac support! -#endif - -#ifndef MACH_TYPE -# define MACH_TYPE (boot_info.machtype) -#endif - -/* - * cpu type definitions - */ - -#if !defined(CONFIG_M68020) -# define CPU_IS_020 (0) -#elif defined(CONFIG_M68030) || defined(CONFIG_M68040) || defined(CONFIG_M68060) -# define CPU_IS_020 (boot_info.cputype & CPU_68020) -#else -# define CONFIG_M68020_ONLY -# define CPU_IS_020 (1) -#endif - -#if !defined(CONFIG_M68030) -# define CPU_IS_030 (0) -#elif defined(CONFIG_M68020) || defined(CONFIG_M68040) || defined(CONFIG_M68060) -# define CPU_IS_030 (boot_info.cputype & CPU_68030) -#else -# define CONFIG_M68030_ONLY -# define CPU_IS_030 (1) -#endif - -#if !defined(CONFIG_M68040) -# define CPU_IS_040 (0) -#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68060) -# define CPU_IS_040 (boot_info.cputype & CPU_68040) -#else -# define CONFIG_M68040_ONLY -# define CPU_IS_040 (1) -#endif - -#if !defined(CONFIG_M68060) -# define CPU_IS_060 (0) -#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68040) -# define CPU_IS_060 (boot_info.cputype & CPU_68060) -#else -# define CONFIG_M68060_ONLY -# define CPU_IS_060 (1) -#endif - -#if !defined(CONFIG_M68020) && !defined(CONFIG_M68030) -# define CPU_IS_020_OR_030 (0) -#else -# define CONFIG_M68020_OR_M68030 -# if defined(CONFIG_M68040) || defined(CONFIG_M68060) -# define CPU_IS_020_OR_030 (!m68k_is040or060) -# else -# define CONFIG_M68020_OR_M68030_ONLY -# define CPU_IS_020_OR_030 (1) -# endif -#endif - -#if !defined(CONFIG_M68040) && !defined(CONFIG_M68060) -# define CPU_IS_040_OR_060 (0) -#else -# define CONFIG_M68040_OR_M68060 -# if defined(CONFIG_M68020) || defined(CONFIG_M68030) -# define CPU_IS_040_OR_060 (m68k_is040or060) -# else -# define CONFIG_M68040_OR_M68060_ONLY -# define CPU_IS_040_OR_060 (1) -# endif -#endif - -#define CPU_TYPE (boot_info.cputype) - -#ifndef __ASSEMBLY__ -#ifdef __KERNEL__ - /* - * m68k_is040or060 is != 0 for a '040 or higher; - * used numbers are 4 for 68040 and 6 for 68060. - */ - -extern int m68k_is040or060; -#endif - -struct bootinfo { - unsigned long machtype; /* machine type */ - unsigned long cputype; /* system CPU & FPU */ - struct mem_info memory[NUM_MEMINFO]; /* memory description */ - int num_memory; /* # of memory blocks found */ - unsigned long ramdisk_size; /* ramdisk size in 1024 byte blocks */ - unsigned long ramdisk_addr; /* address of the ram disk in mem */ - char command_line[CL_SIZE]; /* kernel command line parameters */ - union { - struct bi_Amiga bi_ami; /* Amiga specific information */ - struct bi_Atari bi_ata; /* Atari specific information */ - } bi_un; -}; -#define bi_amiga bi_un.bi_ami -#define bi_atari bi_un.bi_ata -#define bi_mac bi_un.bi_mac - -extern struct bootinfo - boot_info; - -#else /* __ASSEMBLY__ */ - -BI_machtype = 0 -BI_cputype = BI_machtype+4 -BI_memory = BI_cputype+4 -BI_num_memory = BI_memory+(MI_sizeof*NUM_MEMINFO) -BI_ramdisk_size = BI_num_memory+4 -BI_ramdisk_addr = BI_ramdisk_size+4 -BI_command_line = BI_ramdisk_addr+4 -BI_un = BI_command_line+CL_SIZE - -#endif /* __ASSEMBLY__ */ - - -/* - * Stuff for bootinfo interface versioning - * - * At the start of kernel code, a 'struct bootversion' is located. bootstrap - * checks for a matching version of the interface before booting a kernel, to - * avoid user confusion if kernel and bootstrap don't work together :-) - * - * If incompatible changes are made to the bootinfo interface, the major - * number below should be stepped (and the minor reset to 0) for the - * appropriate machine. If a change is backward-compatible, the minor should - * be stepped. "Backwards-compatible" means that booting will work, but - * certain features may not. - */ - -#define BOOTINFOV_MAGIC 0x4249561A /* 'BIV^Z' */ -#define MK_BI_VERSION(major,minor) (((major)<<16)+(minor)) -#define BI_VERSION_MAJOR(v) (((v) >> 16) & 0xffff) -#define BI_VERSION_MINOR(v) ((v) & 0xffff) - -#ifndef __ASSEMBLY__ - -struct bootversion { - unsigned short branch; - unsigned long magic; - struct { - unsigned long machtype; - unsigned long version; - } machversions[0]; -}; - -#endif /* __ASSEMBLY__ */ - -#define AMIGA_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) -#define ATARI_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) - -#endif - - -#endif /* _M68K_SETUP_H */ diff --git a/include/asm-cris/signal.h b/include/asm-cris/signal.h index bd6f9484dbfc..1335bf27d8e2 100644 --- a/include/asm-cris/signal.h +++ b/include/asm-cris/signal.h @@ -85,13 +85,13 @@ typedef unsigned long sigset_t; * Unix names RESETHAND and NODEFER respectively. */ -#define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 -#define SA_SIGINFO 0x00000004 -#define SA_ONSTACK 0x08000000 -#define SA_RESTART 0x10000000 -#define SA_NODEFER 0x40000000 -#define SA_RESETHAND 0x80000000 +#define SA_NOCLDSTOP 0x00000001u +#define SA_NOCLDWAIT 0x00000002u +#define SA_SIGINFO 0x00000004u +#define SA_ONSTACK 0x08000000u +#define SA_RESTART 0x10000000u +#define SA_NODEFER 0x40000000u +#define SA_RESETHAND 0x80000000u #define SA_NOMASK SA_NODEFER #define SA_ONESHOT SA_RESETHAND diff --git a/include/asm-cris/smp_lock.h b/include/asm-cris/smp_lock.h deleted file mode 100644 index 085543014cd5..000000000000 --- a/include/asm-cris/smp_lock.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef __CRIS_SMPLOCK_H -#define __CRIS_SMPLOCK_H - -#include <linux/config.h> - -#ifdef CONFIG_SMP - -#error "SMP is not supported for CRIS" - -/* - * Locking the kernel - */ - -extern __inline void lock_kernel(void) -{ - unsigned long flags; - int proc = smp_processor_id(); - - save_flags(flags); - cli(); - /* set_bit works atomic in SMP machines */ - while(set_bit(0, (void *)&kernel_flag)) - { - /* - * We just start another level if we have the lock - */ - if (proc == active_kernel_processor) - break; - do - { -#ifdef __SMP_PROF__ - smp_spins[smp_processor_id()]++; -#endif - /* - * Doing test_bit here doesn't lock the bus - */ - if (test_bit(proc, (void *)&smp_invalidate_needed)) - if (clear_bit(proc, (void *)&smp_invalidate_needed)) - local_flush_tlb(); - } - while(test_bit(0, (void *)&kernel_flag)); - } - /* - * We got the lock, so tell the world we are here and increment - * the level counter - */ - active_kernel_processor = proc; - kernel_counter++; - restore_flags(flags); -} - -extern __inline void unlock_kernel(void) -{ - unsigned long flags; - save_flags(flags); - cli(); - /* - * If it's the last level we have in the kernel, then - * free the lock - */ - if (kernel_counter == 0) - panic("Kernel counter wrong.\n"); /* FIXME: Why is kernel_counter sometimes 0 here? */ - - if(! --kernel_counter) - { - active_kernel_processor = NO_PROC_ID; - clear_bit(0, (void *)&kernel_flag); - } - restore_flags(flags); -} - -#endif -#endif diff --git a/include/asm-cris/sync_serial.h b/include/asm-cris/sync_serial.h deleted file mode 100644 index 423b46175e5d..000000000000 --- a/include/asm-cris/sync_serial.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * ioctl defines for synchrnous serial port driver - * - * Copyright (c) 2001 Axis Communications AB - * - * Author: Mikael Starvik - * - */ - -#ifndef SYNC_SERIAL_H -#define SYNC_SERIAL_H - -#include <linux/ioctl.h> - -#define SSP_SPEED _IOR('S', 0, unsigned int) -#define SSP_MODE _IOR('S', 1, unsigned int) -#define SSP_FRAME_SYNC _IOR('S', 2, unsigned int) -#define SSP_IPOLARITY _IOR('S', 3, unsigned int) -#define SSP_OPOLARITY _IOR('S', 4, unsigned int) -#define SSP_SPI _IOR('S', 5, unsigned int) - -/* Values for SSP_SPEED */ -#define SSP150 0 -#define SSP300 1 -#define SSP600 2 -#define SSP1200 3 -#define SSP2400 4 -#define SSP4800 5 -#define SSP9600 6 -#define SSP19200 7 -#define SSP28800 8 -#define SSP57600 9 -#define SSP115200 10 -#define SSP230400 11 -#define SSP460800 12 -#define SSP921600 13 -#define SSP3125000 14 -#define CODEC 15 - -#define FREQ_4MHz 0 -#define FREQ_2MHz 1 -#define FREQ_1MHz 2 -#define FREQ_512kHz 3 -#define FREQ_256kHz 4 -#define FREQ_128kHz 5 -#define FREQ_64kHz 6 -#define FREQ_32kHz 7 - -/* Used by application to set CODEC divider, word rate and frame rate */ -#define CODEC_VAL(freq, word, frame) (CODEC | (freq << 8) | (word << 16) | (frame << 28)) - -/* Used by driver to extract speed */ -#define GET_SPEED(x) (x & 0xff) -#define GET_FREQ(x) ((x & 0xff00) >> 8) -#define GET_WORD_RATE(x) (((x & 0x0fff0000) >> 16) - 1) -#define GET_FRAME_RATE(x) (((x & 0xf0000000) >> 28) - 1) - -/* Values for SSP_MODE */ -#define MASTER_OUTPUT 0 -#define SLAVE_OUTPUT 1 -#define MASTER_INPUT 2 -#define SLAVE_INPUT 3 -#define MASTER_BIDIR 4 -#define SLAVE_BIDIR 5 - -/* Values for SSP_FRAME_SYNC */ -#define NORMAL_SYNC 1 -#define EARLY_SYNC 2 -#define BIT_SYNC 4 -#define WORD_SYNC 8 -#define EXTENDED_SYNC 0x10 -#define SYNC_OFF 0x20 -#define SYNC_ON 0x40 -#define WORD_SIZE_8 0x80 -#define WORD_SIZE_12 0x100 -#define WORD_SIZE_16 0x200 -#define WORD_SIZE_24 0x300 -#define WORD_SIZE_32 0x800 -#define BIT_ORDER_LSB 0x1000 -#define BIT_ORDER_MSB 0x2000 -#define FLOW_CONTROL_ENABLE 0x4000 -#define FLOW_CONTROL_DISABLE 0x8000 -#define CLOCK_GATED 0x10000 -#define CLOCK_NOT_GATED 0x20000 - -/* Values for SSP_IPOLARITY and SSP_OPOLARITY */ -#define CLOCK_NORMAL 1 -#define CLOCK_INVERT 2 -#define FRAME_NORMAL 4 -#define FRAME_INVERT 8 -#define STATUS_NORMAL 0x10 -#define STATUS_INVERT 0x20 - -/* Values for SSP_SPI */ -#define SPI_MASTER 0 -#define SPI_SLAVE 1 -#endif diff --git a/include/asm-cris/system.h b/include/asm-cris/system.h index 63d2dee8172e..f9cf80262574 100644 --- a/include/asm-cris/system.h +++ b/include/asm-cris/system.h @@ -1,9 +1,7 @@ #ifndef __ASM_CRIS_SYSTEM_H #define __ASM_CRIS_SYSTEM_H -#include <linux/config.h> - -#include <asm/segment.h> +#include <asm/arch/system.h> /* the switch_to macro calls resume, an asm function in entry.S which does the actual * task switching. @@ -14,117 +12,42 @@ extern struct task_struct *resume(struct task_struct *prev, struct task_struct * #define switch_to(prev,next,last) last = resume(prev,next, \ (int)&((struct task_struct *)0)->thread) -/* read the CPU version register */ - -static inline unsigned long rdvr(void) { - unsigned char vr; - __asm__ volatile ("move $vr,%0" : "=rm" (vr)); - return vr; -} - -/* read/write the user-mode stackpointer */ - -static inline unsigned long rdusp(void) { - unsigned long usp; - __asm__ __volatile__("move $usp,%0" : "=rm" (usp)); - return usp; -} - -#define wrusp(usp) \ - __asm__ __volatile__("move %0,$usp" : /* no outputs */ : "rm" (usp)) - -/* read the current stackpointer */ - -static inline unsigned long rdsp(void) { - unsigned long sp; - __asm__ __volatile__("move.d $sp,%0" : "=rm" (sp)); - return sp; -} - -static inline unsigned long _get_base(char * addr) -{ - return 0; -} - -#define nop() __asm__ __volatile__ ("nop"); - -#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) -#define tas(ptr) (xchg((ptr),1)) - -struct __xchg_dummy { unsigned long a[100]; }; -#define __xg(x) ((struct __xchg_dummy *)(x)) +#define barrier() __asm__ __volatile__("": : :"memory") +#define mb() barrier() +#define rmb() mb() +#define wmb() mb() +#define read_barrier_depends() do { } while(0) +#define set_mb(var, value) do { var = value; mb(); } while (0) +#define set_wmb(var, value) do { var = value; wmb(); } while (0) -#if 0 -/* use these and an oscilloscope to see the fraction of time we're running with IRQ's disabled */ -/* it assumes the LED's are on port 0x90000000 of course. */ -#define sti() __asm__ __volatile__ ( "ei\n\tpush $r0\n\tmoveq 0,$r0\n\tmove.d $r0,[0x90000000]\n\tpop $r0" ); -#define cli() __asm__ __volatile__ ( "di\n\tpush $r0\n\tmove.d 0x40000,$r0\n\tmove.d $r0,[0x90000000]\n\tpop $r0"); -#define save_flags(x) __asm__ __volatile__ ("move $ccr,%0" : "=rm" (x) : : "memory"); -#define restore_flags(x) __asm__ __volatile__ ("move %0,$ccr\n\tbtstq 5,%0\n\tbpl 1f\n\tnop\n\tpush $r0\n\tmoveq 0,$r0\n\tmove.d $r0,[0x90000000]\n\tpop $r0\n1:\n" : : "r" (x) : "memory"); +#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 local_irq_disable() __asm__ __volatile__ ( "di"); -#define local_irq_enable() __asm__ __volatile__ ( "ei" ); -#define local_save_flags(x) __asm__ __volatile__ ("move $ccr,%0" : "=rm" (x) : : "memory"); -#define local_irq_restore(x) __asm__ __volatile__ ("move %0,$ccr" : : "rm" (x) : "memory"); - -/* For spinlocks etc */ -#define local_irq_save(x) __asm__ __volatile__ ("move $ccr,%0\n\tdi" : "=rm" (x) : : "memory"); -#define local_irq_restore(x) restore_flags(x) - -#define local_irq_disable() cli() -#define local_irq_enable() sti() - +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define smp_read_barrier_depends() do { } while(0) #endif -#define cli() local_irq_disable() -#define sti() local_irq_enable() -#define save_flags(x) local_save_flags(x) -#define restore_flags(x) local_irq_restore(x) -#define save_and_cli(x) do { local_save_flags(x); cli(); } while(0) +#define iret() -static inline unsigned long __xchg(unsigned long x, void * ptr, int size) +/* + * disable hlt during certain critical i/o operations + */ +#define HAVE_DISABLE_HLT +void disable_hlt(void); +void enable_hlt(void); + +extern inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) { /* since Etrax doesn't have any atomic xchg instructions, we need to disable irq's (if enabled) and do it with move.d's */ -#if 0 - unsigned int flags; - save_flags(flags); /* save flags, including irq enable bit */ - cli(); /* shut off irq's */ - switch (size) { - case 1: - __asm__ __volatile__ ( - "move.b %0,r0\n\t" - "move.b %1,%0\n\t" - "move.b r0,%1\n\t" - : "=r" (x) - : "m" (*__xg(ptr)), "r" (x) - : "memory","r0"); - break; - case 2: - __asm__ __volatile__ ( - "move.w %0,r0\n\t" - "move.w %1,%0\n\t" - "move.w r0,%1\n\t" - : "=r" (x) - : "m" (*__xg(ptr)), "r" (x) - : "memory","r0"); - break; - case 4: - __asm__ __volatile__ ( - "move.d %0,r0\n\t" - "move.d %1,%0\n\t" - "move.d r0,%1\n\t" - : "=r" (x) - : "m" (*__xg(ptr)), "r" (x) - : "memory","r0"); - break; - } - restore_flags(flags); /* restore irq enable bit */ - return x; -#else unsigned long flags,temp; - save_flags(flags); /* save flags, including irq enable bit */ - cli(); /* shut off irq's */ + local_save_flags(flags); /* save flags, including irq enable bit */ + local_irq_disable(); /* shut off irq's */ switch (size) { case 1: *((unsigned char *)&temp) = x; @@ -142,37 +65,8 @@ static inline unsigned long __xchg(unsigned long x, void * ptr, int size) *(unsigned long *)ptr = temp; break; } - restore_flags(flags); /* restore irq enable bit */ + local_irq_restore(flags); /* restore irq enable bit */ return x; -#endif } -#define mb() __asm__ __volatile__ ("" : : : "memory") -#define rmb() mb() -#define wmb() mb() -#define read_barrier_depends() do { } while(0) -#define set_mb(var, value) do { var = value; mb(); } while (0) -#define set_wmb(var, value) do { var = value; wmb(); } 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 iret() - -/* - * disable hlt during certain critical i/o operations - */ -#define HAVE_DISABLE_HLT -void disable_hlt(void); -void enable_hlt(void); - #endif diff --git a/include/asm-cris/termbits.h b/include/asm-cris/termbits.h index cea712a634f1..4f35a7d95443 100644 --- a/include/asm-cris/termbits.h +++ b/include/asm-cris/termbits.h @@ -88,6 +88,30 @@ struct termios { #define FF1 0100000 /* c_cflag bit meaning */ +/* + * 3 2 1 + * 10 987 654 321 098 765 432 109 876 543 210 + * | | ||| CBAUD + * obaud + * + * ||CSIZE + * + * |CSTOP + * |CREAD + * |CPARENB + * + * |CPARODD + * |HUPCL + * |CLOCAL + * |CBAUDEX + * 10 987 654 321 098 765 432 109 876 543 210 + * | || || CIBAUD, IBSHIFT=16 + * ibaud + * |CMSPAR + * | CRTSCTS + * x x xxx xxx x x xx Free bits + */ + #define CBAUD 0010017 #define B0 0000000 /* hang up */ #define B50 0000001 @@ -123,11 +147,18 @@ struct termios { #define B115200 0010002 #define B230400 0010003 #define B460800 0010004 -/* etrax100 supports these additional three baud rates */ -#define B921600 0010005 -#define B1843200 0010006 -#define B6250000 0010007 -#define CIBAUD 002003600000 /* input baud rate (not used) */ +/* etrax supports these additional three baud rates */ +#define B921600 0010005 +#define B1843200 0010006 +#define B6250000 0010007 +/* etrax 200 supports this as well */ +#define B12500000 0010010 +#define CIBAUD 002003600000 /* input baud rate */ +/* The values for CIBAUD bits are the same as the values for CBAUD and CBAUDEX + * shifted left IBSHIFT bits. + */ +#define IBSHIFT 16 +#define CMSPAR 010000000000 /* mark or space (stick) parity - PARODD=space*/ #define CRTSCTS 020000000000 /* flow control */ /* c_lflag bits */ diff --git a/include/asm-cris/termios.h b/include/asm-cris/termios.h index cc60e3781b00..5ce1023c5d7b 100644 --- a/include/asm-cris/termios.h +++ b/include/asm-cris/termios.h @@ -3,6 +3,7 @@ #include <asm/termbits.h> #include <asm/ioctls.h> +#include <asm/rs485.h> struct winsize { unsigned short ws_row; diff --git a/include/asm-cris/thread_info.h b/include/asm-cris/thread_info.h new file mode 100644 index 000000000000..f191637ac9ec --- /dev/null +++ b/include/asm-cris/thread_info.h @@ -0,0 +1,100 @@ +/* thread_info.h: CRIS low-level thread information + * + * Copyright (C) 2002 David Howells (dhowells@redhat.com) + * - Incorporating suggestions made by Linus Torvalds and Dave Miller + * + * CRIS port by Axis Communications + */ + +#ifndef _ASM_THREAD_INFO_H +#define _ASM_THREAD_INFO_H + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ +#include <asm/types.h> +#include <asm/processor.h> +#include <asm/arch/thread_info.h> +#include <asm/segment.h> +#endif + + +/* + * low level task data that entry.S needs immediate access to + * - this struct should fit entirely inside of one cache line + * - this struct shares the supervisor stack pages + * - if the contents of this structure are changed, the assembly constants must also be changed + */ +#ifndef __ASSEMBLY__ +struct thread_info { + struct task_struct *task; /* main task structure */ + struct exec_domain *exec_domain; /* execution domain */ + unsigned long flags; /* low level flags */ + __u32 cpu; /* current CPU */ + __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ + + mm_segment_t addr_limit; /* thread address space: + 0-0xBFFFFFFF for user-thead + 0-0xFFFFFFFF for kernel-thread + */ + struct restart_block restart_block; + __u8 supervisor_stack[0]; +}; + +#endif + +#define PREEMPT_ACTIVE 0x4000000 + +/* + * macros/functions for gaining access to the thread information structure + * + * preempt_count needs to be 1 initially, until the scheduler is functional. + */ +#ifndef __ASSEMBLY__ +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .flags = 0, \ + .cpu = 0, \ + .preempt_count = 1, \ + .addr_limit = KERNEL_DS, \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ +} + +#define init_thread_info (init_thread_union.thread_info) + +/* 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) +#define get_thread_info(ti) get_task_struct((ti)->task) +#define put_thread_info(ti) put_task_struct((ti)->task) + +#endif /* !__ASSEMBLY__ */ + +/* + * thread information flags + * - these are process state flags that various assembly files may need to access + * - pending work-to-be-done flags are in LSW + * - other flags in MSW + */ +#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 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ + +#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) +#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) +#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) +#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) +#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) + +#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ +#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_THREAD_INFO_H */ diff --git a/include/asm-cris/timex.h b/include/asm-cris/timex.h index 5bf3edbd6698..375c41af47de 100644 --- a/include/asm-cris/timex.h +++ b/include/asm-cris/timex.h @@ -3,23 +3,11 @@ * * CRIS architecture timex specifications */ + #ifndef _ASM_CRIS_TIMEX_H #define _ASM_CRIS_TIMEX_H -#define CLOCK_TICK_RATE 19200 /* Underlying frequency of the HZ timer */ - -/* The timer0 values gives ~52.1us resolution (1/19200) but interrupts at HZ*/ -#define TIMER0_FREQ (CLOCK_TICK_RATE) -#define TIMER0_CLKSEL c19k2Hz -#define TIMER0_DIV (TIMER0_FREQ/(HZ)) -/* This is the slow one: */ -/* -#define GET_JIFFIES_USEC() \ - ( (*R_TIMER0_DATA - TIMER0_DIV) * (1000000/HZ)/TIMER0_DIV ) -*/ -/* This is the fast version: */ -extern unsigned short cris_timer0_value_us[TIMER0_DIV+1]; /* in kernel/time.c */ -#define GET_JIFFIES_USEC() (cris_timer0_value_us[*R_TIMER0_DATA]) +#include <asm/arch/timex.h> /* * We don't have a cycle-counter.. but we do not support SMP anyway where this is @@ -28,7 +16,7 @@ extern unsigned short cris_timer0_value_us[TIMER0_DIV+1]; /* in kernel/time.c */ typedef unsigned int cycles_t; -static inline cycles_t get_cycles(void) +extern inline cycles_t get_cycles(void) { return 0; } diff --git a/include/asm-cris/tlb.h b/include/asm-cris/tlb.h index 69c0faa93194..6cc26debe40f 100644 --- a/include/asm-cris/tlb.h +++ b/include/asm-cris/tlb.h @@ -1 +1,17 @@ +#ifndef _CRIS_TLB_H +#define _CRIS_TLB_H + +#include <asm/arch/tlb.h> + +/* + * cris doesn't need any special per-pte or + * per-vma handling.. + */ +#define tlb_start_vma(tlb, vma) do { } while (0) +#define tlb_end_vma(tlb, vma) do { } while (0) +#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) + +#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) #include <asm-generic/tlb.h> + +#endif diff --git a/include/asm-cris/tlbflush.h b/include/asm-cris/tlbflush.h new file mode 100644 index 000000000000..1781fe1a32f6 --- /dev/null +++ b/include/asm-cris/tlbflush.h @@ -0,0 +1,43 @@ +#ifndef _CRIS_TLBFLUSH_H +#define _CRIS_TLBFLUSH_H + +#include <linux/config.h> +#include <linux/mm.h> +#include <asm/processor.h> +#include <asm/pgtable.h> +#include <asm/pgalloc.h> + +/* + * TLB flushing (implemented in arch/cris/mm/tlb.c): + * + * - flush_tlb() flushes the current mm struct TLBs + * - flush_tlb_all() flushes all processes TLBs + * - flush_tlb_mm(mm) flushes the specified mm context TLB's + * - flush_tlb_page(vma, vmaddr) flushes one page + * - flush_tlb_range(mm, start, end) flushes a range of pages + * + */ + +extern void flush_tlb_all(void); +extern void flush_tlb_mm(struct mm_struct *mm); +extern void flush_tlb_page(struct vm_area_struct *vma, + unsigned long addr); +extern void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, + unsigned long end); + +extern inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + /* CRIS does not keep any page table caches in TLB */ +} + + +extern inline void flush_tlb(void) +{ + flush_tlb_mm(current->mm); +} + +#define flush_tlb_kernel_range(start, end) flush_tlb_all() + +#endif /* _CRIS_TLBFLUSH_H */ diff --git a/include/asm-cris/uaccess.h b/include/asm-cris/uaccess.h index 41d66748c16b..7532cd76d0af 100644 --- a/include/asm-cris/uaccess.h +++ b/include/asm-cris/uaccess.h @@ -81,8 +81,8 @@ #define USER_DS MAKE_MM_SEG(TASK_SIZE) #define get_ds() (KERNEL_DS) -#define get_fs() (current->addr_limit) -#define set_fs(x) (current->addr_limit = (x)) +#define get_fs() (current_thread_info()->addr_limit) +#define set_fs(x) (current_thread_info()->addr_limit = (x)) #define segment_eq(a,b) ((a).seg == (b).seg) @@ -91,12 +91,14 @@ #define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size))) #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size)) -extern inline int verify_area(int type, const void * addr, unsigned long size) +extern inline int verify_area(int type, const void __user * addr, unsigned long size) { return access_ok(type,addr,size) ? 0 : -EFAULT; } +#include <asm/arch/uaccess.h> + /* * 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 @@ -115,10 +117,6 @@ 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. @@ -149,6 +147,30 @@ extern unsigned long search_exception_table(unsigned long); extern long __put_user_bad(void); +#define __put_user_size(x,ptr,size,retval) \ +do { \ + retval = 0; \ + switch (size) { \ + case 1: __put_user_asm(x,ptr,retval,"move.b"); break; \ + case 2: __put_user_asm(x,ptr,retval,"move.w"); break; \ + case 4: __put_user_asm(x,ptr,retval,"move.d"); break; \ + case 8: __put_user_asm_64(x,ptr,retval); break; \ + default: __put_user_bad(); \ + } \ +} while (0) + +#define __get_user_size(x,ptr,size,retval) \ +do { \ + retval = 0; \ + switch (size) { \ + case 1: __get_user_asm(x,ptr,retval,"move.b"); break; \ + case 2: __get_user_asm(x,ptr,retval,"move.w"); break; \ + case 4: __get_user_asm(x,ptr,retval,"move.d"); break; \ + case 8: __get_user_asm_64(x,ptr,retval); break; \ + default: (x) = __get_user_bad(); \ + } \ +} while (0) + #define __put_user_nocheck(x,ptr,size) \ ({ \ long __pu_err; \ @@ -165,58 +187,9 @@ extern long __put_user_bad(void); __pu_err; \ }) -#define __put_user_size(x,ptr,size,retval) \ -do { \ - retval = 0; \ - switch (size) { \ - case 1: __put_user_asm(x,ptr,retval,"move.b"); break; \ - case 2: __put_user_asm(x,ptr,retval,"move.w"); break; \ - case 4: __put_user_asm(x,ptr,retval,"move.d"); break; \ - case 8: __put_user_asm_64(x,ptr,retval); break; \ - default: __put_user_bad(); \ - } \ -} while (0) - struct __large_struct { unsigned long buf[100]; }; #define __m(x) (*(struct __large_struct *)(x)) -/* - * We don't tell gcc that we are accessing memory, but this is OK - * because we do not write to any memory gcc knows about, so there - * are no aliasing issues. - * - * Note that PC at a fault is the address *after* the faulting - * instruction. - */ -#define __put_user_asm(x, addr, err, op) \ - __asm__ __volatile__( \ - " "op" %1,[%2]\n" \ - "2:\n" \ - " .section .fixup,\"ax\"\n" \ - "3: move.d %3,%0\n" \ - " jump 2b\n" \ - " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - " .dword 2b,3b\n" \ - " .previous\n" \ - : "=r" (err) \ - : "r" (x), "r" (addr), "g" (-EFAULT), "0" (err)) - -#define __put_user_asm_64(x, addr, err) \ - __asm__ __volatile__( \ - " move.d %M1,[%2]\n" \ - "2: move.d %H1,[%2+4]\n" \ - "4:\n" \ - " .section .fixup,\"ax\"\n" \ - "3: move.d %3,%0\n" \ - " jump 4b\n" \ - " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - " .dword 2b,3b\n" \ - " .dword 4b,3b\n" \ - " .previous\n" \ - : "=r" (err) \ - : "r" (x), "r" (addr), "g" (-EFAULT), "0" (err)) #define __get_user_nocheck(x,ptr,size) \ @@ -239,52 +212,6 @@ struct __large_struct { unsigned long buf[100]; }; extern long __get_user_bad(void); -#define __get_user_size(x,ptr,size,retval) \ -do { \ - retval = 0; \ - switch (size) { \ - case 1: __get_user_asm(x,ptr,retval,"move.b"); break; \ - case 2: __get_user_asm(x,ptr,retval,"move.w"); break; \ - case 4: __get_user_asm(x,ptr,retval,"move.d"); break; \ - case 8: __get_user_asm_64(x,ptr,retval); break; \ - default: (x) = __get_user_bad(); \ - } \ -} while (0) - -/* See comment before __put_user_asm. */ - -#define __get_user_asm(x, addr, err, op) \ - __asm__ __volatile__( \ - " "op" [%2],%1\n" \ - "2:\n" \ - " .section .fixup,\"ax\"\n" \ - "3: move.d %3,%0\n" \ - " moveq 0,%1\n" \ - " jump 2b\n" \ - " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - " .dword 2b,3b\n" \ - " .previous\n" \ - : "=r" (err), "=r" (x) \ - : "r" (addr), "g" (-EFAULT), "0" (err)) - -#define __get_user_asm_64(x, addr, err) \ - __asm__ __volatile__( \ - " move.d [%2],%M1\n" \ - "2: move.d [%2+4],%H1\n" \ - "4:\n" \ - " .section .fixup,\"ax\"\n" \ - "3: move.d %3,%0\n" \ - " moveq 0,%1\n" \ - " jump 4b\n" \ - " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - " .dword 2b,3b\n" \ - " .dword 4b,3b\n" \ - " .previous\n" \ - : "=r" (err), "=r" (x) \ - : "r" (addr), "g" (-EFAULT), "0" (err)) - /* More complex functions. Most are inline, but some call functions that live in lib/usercopy.c */ @@ -292,108 +219,38 @@ extern unsigned long __copy_user(void *to, const void *from, unsigned long n); extern unsigned long __copy_user_zeroing(void *to, const void *from, unsigned long n); extern unsigned long __do_clear_user(void *to, unsigned long n); -/* - * Copy a null terminated string from userspace. - * - * Must return: - * -EFAULT for an exception - * count if we hit the buffer limit - * bytes copied if we hit a null byte - * (without the null byte) - */ - -static inline long -__do_strncpy_from_user(char *dst, const char *src, long count) -{ - long res; - - if (count == 0) - return 0; - - /* - * Currently, in 2.4.0-test9, most ports use a simple byte-copy loop. - * So do we. - * - * This code is deduced from: - * - * char tmp2; - * long tmp1, tmp3 - * tmp1 = count; - * while ((*dst++ = (tmp2 = *src++)) != 0 - * && --tmp1) - * ; - * - * res = count - tmp1; - * - * with tweaks. - */ - - __asm__ __volatile__ ( - " move.d %3,%0\n" - " move.b [%2+],$r9\n" - "1: beq 2f\n" - " move.b $r9,[%1+]\n" - - " subq 1,%0\n" - " bne 1b\n" - " move.b [%2+],$r9\n" - - "2: sub.d %3,%0\n" - " neg.d %0,%0\n" - "3:\n" - " .section .fixup,\"ax\"\n" - "4: move.d %7,%0\n" - " jump 3b\n" - - /* There's one address for a fault at the first move, and - two possible PC values for a fault at the second move, - being a delay-slot filler. However, the branch-target - for the second move is the same as the first address. - Just so you don't get confused... */ - " .previous\n" - " .section __ex_table,\"a\"\n" - " .dword 1b,4b\n" - " .dword 2b,4b\n" - " .previous" - : "=r" (res), "=r" (dst), "=r" (src), "=r" (count) - : "3" (count), "1" (dst), "2" (src), "g" (-EFAULT) - : "r9"); - - return res; -} - -static inline unsigned long -__generic_copy_to_user(void *to, const void *from, unsigned long n) +extern inline unsigned long +__generic_copy_to_user(void __user *to, const void *from, unsigned long n) { if (access_ok(VERIFY_WRITE, to, n)) return __copy_user(to,from,n); return n; } -static inline unsigned long -__generic_copy_from_user(void *to, const void *from, unsigned long n) +extern inline unsigned long +__generic_copy_from_user(void *to, const void __user *from, unsigned long n) { if (access_ok(VERIFY_READ, from, n)) return __copy_user_zeroing(to,from,n); return n; } -static inline unsigned long -__generic_clear_user(void *to, unsigned long n) +extern inline unsigned long +__generic_clear_user(void __user *to, unsigned long n) { if (access_ok(VERIFY_WRITE, to, n)) return __do_clear_user(to,n); return n; } -static inline long -__strncpy_from_user(char *dst, const char *src, long count) +extern inline long +__strncpy_from_user(char *dst, const char __user *src, long count) { return __do_strncpy_from_user(dst, src, count); } -static inline long -strncpy_from_user(char *dst, const char *src, long count) +extern inline long +strncpy_from_user(char *dst, const char __user *src, long count) { long res = -EFAULT; if (access_ok(VERIFY_READ, src, 1)) @@ -401,459 +258,12 @@ strncpy_from_user(char *dst, const char *src, long count) return res; } -/* A few copy asms to build up the more complex ones from. - - Note again, a post-increment is performed regardless of whether a bus - fault occurred in that instruction, and PC for a faulted insn is the - address *after* the insn. */ - -#define __asm_copy_user_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm__ __volatile__ ( \ - COPY \ - "1:\n" \ - " .section .fixup,\"ax\"\n" \ - FIXUP \ - " jump 1b\n" \ - " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - TENTRY \ - " .previous\n" \ - : "=r" (to), "=r" (from), "=r" (ret) \ - : "0" (to), "1" (from), "2" (ret) \ - : "r9", "memory") - -#define __asm_copy_from_user_1(to, from, ret) \ - __asm_copy_user_cont(to, from, ret, \ - " move.b [%1+],$r9\n" \ - "2: move.b $r9,[%0+]\n", \ - "3: addq 1,%2\n" \ - " clear.b [%0+]\n", \ - " .dword 2b,3b\n") - -#define __asm_copy_from_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_user_cont(to, from, ret, \ - " move.w [%1+],$r9\n" \ - "2: move.w $r9,[%0+]\n" COPY, \ - "3: addq 2,%2\n" \ - " clear.w [%0+]\n" FIXUP, \ - " .dword 2b,3b\n" TENTRY) - -#define __asm_copy_from_user_2(to, from, ret) \ - __asm_copy_from_user_2x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_3(to, from, ret) \ - __asm_copy_from_user_2x_cont(to, from, ret, \ - " move.b [%1+],$r9\n" \ - "4: move.b $r9,[%0+]\n", \ - "5: addq 1,%2\n" \ - " clear.b [%0+]\n", \ - " .dword 4b,5b\n") - -#define __asm_copy_from_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_user_cont(to, from, ret, \ - " move.d [%1+],$r9\n" \ - "2: move.d $r9,[%0+]\n" COPY, \ - "3: addq 4,%2\n" \ - " clear.d [%0+]\n" FIXUP, \ - " .dword 2b,3b\n" TENTRY) - -#define __asm_copy_from_user_4(to, from, ret) \ - __asm_copy_from_user_4x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_5(to, from, ret) \ - __asm_copy_from_user_4x_cont(to, from, ret, \ - " move.b [%1+],$r9\n" \ - "4: move.b $r9,[%0+]\n", \ - "5: addq 1,%2\n" \ - " clear.b [%0+]\n", \ - " .dword 4b,5b\n") - -#define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_4x_cont(to, from, ret, \ - " move.w [%1+],$r9\n" \ - "4: move.w $r9,[%0+]\n" COPY, \ - "5: addq 2,%2\n" \ - " clear.w [%0+]\n" FIXUP, \ - " .dword 4b,5b\n" TENTRY) - -#define __asm_copy_from_user_6(to, from, ret) \ - __asm_copy_from_user_6x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_7(to, from, ret) \ - __asm_copy_from_user_6x_cont(to, from, ret, \ - " move.b [%1+],$r9\n" \ - "6: move.b $r9,[%0+]\n", \ - "7: addq 1,%2\n" \ - " clear.b [%0+]\n", \ - " .dword 6b,7b\n") - -#define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_4x_cont(to, from, ret, \ - " move.d [%1+],$r9\n" \ - "4: move.d $r9,[%0+]\n" COPY, \ - "5: addq 4,%2\n" \ - " clear.d [%0+]\n" FIXUP, \ - " .dword 4b,5b\n" TENTRY) - -#define __asm_copy_from_user_8(to, from, ret) \ - __asm_copy_from_user_8x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_9(to, from, ret) \ - __asm_copy_from_user_8x_cont(to, from, ret, \ - " move.b [%1+],$r9\n" \ - "6: move.b $r9,[%0+]\n", \ - "7: addq 1,%2\n" \ - " clear.b [%0+]\n", \ - " .dword 6b,7b\n") - -#define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_8x_cont(to, from, ret, \ - " move.w [%1+],$r9\n" \ - "6: move.w $r9,[%0+]\n" COPY, \ - "7: addq 2,%2\n" \ - " clear.w [%0+]\n" FIXUP, \ - " .dword 6b,7b\n" TENTRY) - -#define __asm_copy_from_user_10(to, from, ret) \ - __asm_copy_from_user_10x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_11(to, from, ret) \ - __asm_copy_from_user_10x_cont(to, from, ret, \ - " move.b [%1+],$r9\n" \ - "8: move.b $r9,[%0+]\n", \ - "9: addq 1,%2\n" \ - " clear.b [%0+]\n", \ - " .dword 8b,9b\n") - -#define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_8x_cont(to, from, ret, \ - " move.d [%1+],$r9\n" \ - "6: move.d $r9,[%0+]\n" COPY, \ - "7: addq 4,%2\n" \ - " clear.d [%0+]\n" FIXUP, \ - " .dword 6b,7b\n" TENTRY) - -#define __asm_copy_from_user_12(to, from, ret) \ - __asm_copy_from_user_12x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_13(to, from, ret) \ - __asm_copy_from_user_12x_cont(to, from, ret, \ - " move.b [%1+],$r9\n" \ - "8: move.b $r9,[%0+]\n", \ - "9: addq 1,%2\n" \ - " clear.b [%0+]\n", \ - " .dword 8b,9b\n") - -#define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_12x_cont(to, from, ret, \ - " move.w [%1+],$r9\n" \ - "8: move.w $r9,[%0+]\n" COPY, \ - "9: addq 2,%2\n" \ - " clear.w [%0+]\n" FIXUP, \ - " .dword 8b,9b\n" TENTRY) - -#define __asm_copy_from_user_14(to, from, ret) \ - __asm_copy_from_user_14x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_15(to, from, ret) \ - __asm_copy_from_user_14x_cont(to, from, ret, \ - " move.b [%1+],$r9\n" \ - "10: move.b $r9,[%0+]\n", \ - "11: addq 1,%2\n" \ - " clear.b [%0+]\n", \ - " .dword 10b,11b\n") - -#define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_12x_cont(to, from, ret, \ - " move.d [%1+],$r9\n" \ - "8: move.d $r9,[%0+]\n" COPY, \ - "9: addq 4,%2\n" \ - " clear.d [%0+]\n" FIXUP, \ - " .dword 8b,9b\n" TENTRY) - -#define __asm_copy_from_user_16(to, from, ret) \ - __asm_copy_from_user_16x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_20x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_16x_cont(to, from, ret, \ - " move.d [%1+],$r9\n" \ - "10: move.d $r9,[%0+]\n" COPY, \ - "11: addq 4,%2\n" \ - " clear.d [%0+]\n" FIXUP, \ - " .dword 10b,11b\n" TENTRY) - -#define __asm_copy_from_user_20(to, from, ret) \ - __asm_copy_from_user_20x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_24x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_20x_cont(to, from, ret, \ - " move.d [%1+],$r9\n" \ - "12: move.d $r9,[%0+]\n" COPY, \ - "13: addq 4,%2\n" \ - " clear.d [%0+]\n" FIXUP, \ - " .dword 12b,13b\n" TENTRY) - -#define __asm_copy_from_user_24(to, from, ret) \ - __asm_copy_from_user_24x_cont(to, from, ret, "", "", "") - -/* And now, the to-user ones. */ - -#define __asm_copy_to_user_1(to, from, ret) \ - __asm_copy_user_cont(to, from, ret, \ - " move.b [%1+],$r9\n" \ - " move.b $r9,[%0+]\n2:\n", \ - "3: addq 1,%2\n", \ - " .dword 2b,3b\n") - -#define __asm_copy_to_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_user_cont(to, from, ret, \ - " move.w [%1+],$r9\n" \ - " move.w $r9,[%0+]\n2:\n" COPY, \ - "3: addq 2,%2\n" FIXUP, \ - " .dword 2b,3b\n" TENTRY) - -#define __asm_copy_to_user_2(to, from, ret) \ - __asm_copy_to_user_2x_cont(to, from, ret, "", "", "") - -#define __asm_copy_to_user_3(to, from, ret) \ - __asm_copy_to_user_2x_cont(to, from, ret, \ - " move.b [%1+],$r9\n" \ - " move.b $r9,[%0+]\n4:\n", \ - "5: addq 1,%2\n", \ - " .dword 4b,5b\n") - -#define __asm_copy_to_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_user_cont(to, from, ret, \ - " move.d [%1+],$r9\n" \ - " move.d $r9,[%0+]\n2:\n" COPY, \ - "3: addq 4,%2\n" FIXUP, \ - " .dword 2b,3b\n" TENTRY) - -#define __asm_copy_to_user_4(to, from, ret) \ - __asm_copy_to_user_4x_cont(to, from, ret, "", "", "") - -#define __asm_copy_to_user_5(to, from, ret) \ - __asm_copy_to_user_4x_cont(to, from, ret, \ - " move.b [%1+],$r9\n" \ - " move.b $r9,[%0+]\n4:\n", \ - "5: addq 1,%2\n", \ - " .dword 4b,5b\n") - -#define __asm_copy_to_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_to_user_4x_cont(to, from, ret, \ - " move.w [%1+],$r9\n" \ - " move.w $r9,[%0+]\n4:\n" COPY, \ - "5: addq 2,%2\n" FIXUP, \ - " .dword 4b,5b\n" TENTRY) - -#define __asm_copy_to_user_6(to, from, ret) \ - __asm_copy_to_user_6x_cont(to, from, ret, "", "", "") - -#define __asm_copy_to_user_7(to, from, ret) \ - __asm_copy_to_user_6x_cont(to, from, ret, \ - " move.b [%1+],$r9\n" \ - " move.b $r9,[%0+]\n6:\n", \ - "7: addq 1,%2\n", \ - " .dword 6b,7b\n") - -#define __asm_copy_to_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_to_user_4x_cont(to, from, ret, \ - " move.d [%1+],$r9\n" \ - " move.d $r9,[%0+]\n4:\n" COPY, \ - "5: addq 4,%2\n" FIXUP, \ - " .dword 4b,5b\n" TENTRY) - -#define __asm_copy_to_user_8(to, from, ret) \ - __asm_copy_to_user_8x_cont(to, from, ret, "", "", "") - -#define __asm_copy_to_user_9(to, from, ret) \ - __asm_copy_to_user_8x_cont(to, from, ret, \ - " move.b [%1+],$r9\n" \ - " move.b $r9,[%0+]\n6:\n", \ - "7: addq 1,%2\n", \ - " .dword 6b,7b\n") - -#define __asm_copy_to_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_to_user_8x_cont(to, from, ret, \ - " move.w [%1+],$r9\n" \ - " move.w $r9,[%0+]\n6:\n" COPY, \ - "7: addq 2,%2\n" FIXUP, \ - " .dword 6b,7b\n" TENTRY) - -#define __asm_copy_to_user_10(to, from, ret) \ - __asm_copy_to_user_10x_cont(to, from, ret, "", "", "") - -#define __asm_copy_to_user_11(to, from, ret) \ - __asm_copy_to_user_10x_cont(to, from, ret, \ - " move.b [%1+],$r9\n" \ - " move.b $r9,[%0+]\n8:\n", \ - "9: addq 1,%2\n", \ - " .dword 8b,9b\n") - -#define __asm_copy_to_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_to_user_8x_cont(to, from, ret, \ - " move.d [%1+],$r9\n" \ - " move.d $r9,[%0+]\n6:\n" COPY, \ - "7: addq 4,%2\n" FIXUP, \ - " .dword 6b,7b\n" TENTRY) - -#define __asm_copy_to_user_12(to, from, ret) \ - __asm_copy_to_user_12x_cont(to, from, ret, "", "", "") - -#define __asm_copy_to_user_13(to, from, ret) \ - __asm_copy_to_user_12x_cont(to, from, ret, \ - " move.b [%1+],$r9\n" \ - " move.b $r9,[%0+]\n8:\n", \ - "9: addq 1,%2\n", \ - " .dword 8b,9b\n") - -#define __asm_copy_to_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_to_user_12x_cont(to, from, ret, \ - " move.w [%1+],$r9\n" \ - " move.w $r9,[%0+]\n8:\n" COPY, \ - "9: addq 2,%2\n" FIXUP, \ - " .dword 8b,9b\n" TENTRY) - -#define __asm_copy_to_user_14(to, from, ret) \ - __asm_copy_to_user_14x_cont(to, from, ret, "", "", "") - -#define __asm_copy_to_user_15(to, from, ret) \ - __asm_copy_to_user_14x_cont(to, from, ret, \ - " move.b [%1+],$r9\n" \ - " move.b $r9,[%0+]\n10:\n", \ - "11: addq 1,%2\n", \ - " .dword 10b,11b\n") - -#define __asm_copy_to_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_to_user_12x_cont(to, from, ret, \ - " move.d [%1+],$r9\n" \ - " move.d $r9,[%0+]\n8:\n" COPY, \ - "9: addq 4,%2\n" FIXUP, \ - " .dword 8b,9b\n" TENTRY) - -#define __asm_copy_to_user_16(to, from, ret) \ - __asm_copy_to_user_16x_cont(to, from, ret, "", "", "") - -#define __asm_copy_to_user_20x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_to_user_16x_cont(to, from, ret, \ - " move.d [%1+],$r9\n" \ - " move.d $r9,[%0+]\n10:\n" COPY, \ - "11: addq 4,%2\n" FIXUP, \ - " .dword 10b,11b\n" TENTRY) - -#define __asm_copy_to_user_20(to, from, ret) \ - __asm_copy_to_user_20x_cont(to, from, ret, "", "", "") - -#define __asm_copy_to_user_24x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_to_user_20x_cont(to, from, ret, \ - " move.d [%1+],$r9\n" \ - " move.d $r9,[%0+]\n12:\n" COPY, \ - "13: addq 4,%2\n" FIXUP, \ - " .dword 12b,13b\n" TENTRY) - -#define __asm_copy_to_user_24(to, from, ret) \ - __asm_copy_to_user_24x_cont(to, from, ret, "", "", "") - -/* Define a few clearing asms with exception handlers. */ - -/* This frame-asm is like the __asm_copy_user_cont one, but has one less - input. */ - -#define __asm_clear(to, ret, CLEAR, FIXUP, TENTRY) \ - __asm__ __volatile__ ( \ - CLEAR \ - "1:\n" \ - " .section .fixup,\"ax\"\n" \ - FIXUP \ - " jump 1b\n" \ - " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - TENTRY \ - " .previous" \ - : "=r" (to), "=r" (ret) \ - : "0" (to), "1" (ret) \ - : "r9", "memory") - -#define __asm_clear_1(to, ret) \ - __asm_clear(to, ret, \ - " clear.b [%0+]\n2:\n", \ - "3: addq 1,%1\n", \ - " .dword 2b,3b\n") - -#define __asm_clear_2(to, ret) \ - __asm_clear(to, ret, \ - " clear.w [%0+]\n2:\n", \ - "3: addq 2,%1\n", \ - " .dword 2b,3b\n") - -#define __asm_clear_3(to, ret) \ - __asm_clear(to, ret, \ - " clear.w [%0+]\n" \ - "2: clear.b [%0+]\n3:\n", \ - "4: addq 2,%1\n" \ - "5: addq 1,%1\n", \ - " .dword 2b,4b\n" \ - " .dword 3b,5b\n") - -#define __asm_clear_4x_cont(to, ret, CLEAR, FIXUP, TENTRY) \ - __asm_clear(to, ret, \ - " clear.d [%0+]\n2:\n" CLEAR, \ - "3: addq 4,%1\n" FIXUP, \ - " .dword 2b,3b\n" TENTRY) - -#define __asm_clear_4(to, ret) \ - __asm_clear_4x_cont(to, ret, "", "", "") - -#define __asm_clear_8x_cont(to, ret, CLEAR, FIXUP, TENTRY) \ - __asm_clear_4x_cont(to, ret, \ - " clear.d [%0+]\n4:\n" CLEAR, \ - "5: addq 4,%1\n" FIXUP, \ - " .dword 4b,5b\n" TENTRY) - -#define __asm_clear_8(to, ret) \ - __asm_clear_8x_cont(to, ret, "", "", "") - -#define __asm_clear_12x_cont(to, ret, CLEAR, FIXUP, TENTRY) \ - __asm_clear_8x_cont(to, ret, \ - " clear.d [%0+]\n6:\n" CLEAR, \ - "7: addq 4,%1\n" FIXUP, \ - " .dword 6b,7b\n" TENTRY) - -#define __asm_clear_12(to, ret) \ - __asm_clear_12x_cont(to, ret, "", "", "") - -#define __asm_clear_16x_cont(to, ret, CLEAR, FIXUP, TENTRY) \ - __asm_clear_12x_cont(to, ret, \ - " clear.d [%0+]\n8:\n" CLEAR, \ - "9: addq 4,%1\n" FIXUP, \ - " .dword 8b,9b\n" TENTRY) - -#define __asm_clear_16(to, ret) \ - __asm_clear_16x_cont(to, ret, "", "", "") - -#define __asm_clear_20x_cont(to, ret, CLEAR, FIXUP, TENTRY) \ - __asm_clear_16x_cont(to, ret, \ - " clear.d [%0+]\n10:\n" CLEAR, \ - "11: addq 4,%1\n" FIXUP, \ - " .dword 10b,11b\n" TENTRY) - -#define __asm_clear_20(to, ret) \ - __asm_clear_20x_cont(to, ret, "", "", "") - -#define __asm_clear_24x_cont(to, ret, CLEAR, FIXUP, TENTRY) \ - __asm_clear_20x_cont(to, ret, \ - " clear.d [%0+]\n12:\n" CLEAR, \ - "13: addq 4,%1\n" FIXUP, \ - " .dword 12b,13b\n" TENTRY) - -#define __asm_clear_24(to, ret) \ - __asm_clear_24x_cont(to, ret, "", "", "") /* Note that if these expand awfully if made into switch constructs, so don't do that. */ -static inline unsigned long -__constant_copy_from_user(void *to, const void *from, unsigned long n) +extern inline unsigned long +__constant_copy_from_user(void *to, const void __user *from, unsigned long n) { unsigned long ret = 0; if (n == 0) @@ -902,8 +312,8 @@ __constant_copy_from_user(void *to, const void *from, unsigned long n) /* Ditto, don't make a switch out of this. */ -static inline unsigned long -__constant_copy_to_user(void *to, const void *from, unsigned long n) +extern inline unsigned long +__constant_copy_to_user(void __user *to, const void *from, unsigned long n) { unsigned long ret = 0; if (n == 0) @@ -952,8 +362,8 @@ __constant_copy_to_user(void *to, const void *from, unsigned long n) /* No switch, please. */ -static inline unsigned long -__constant_clear_user(void *to, unsigned long n) +extern inline unsigned long +__constant_clear_user(void __user *to, unsigned long n) { unsigned long ret = 0; if (n == 0) @@ -1002,19 +412,19 @@ __constant_clear_user(void *to, unsigned long n) * used in fast paths and have only a small space overhead. */ -static inline unsigned long +extern inline unsigned long __generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n) { return __copy_user_zeroing(to,from,n); } -static inline unsigned long +extern inline unsigned long __generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n) { return __copy_user(to,from,n); } -static inline unsigned long +extern inline unsigned long __generic_clear_user_nocheck(void *to, unsigned long n) { return __do_clear_user(to,n); @@ -1026,68 +436,6 @@ __generic_clear_user_nocheck(void *to, unsigned long n) #define __copy_from_user(to,from,n) __generic_copy_from_user_nocheck((to),(from),(n)) #define __clear_user(to,n) __generic_clear_user_nocheck((to),(n)) -/* - * Return the size of a string (including the ending 0) - * - * Return length of string in userspace including terminating 0 - * or 0 for error. Return a value greater than N if too long. - */ - -static inline long -strnlen_user(const char *s, long n) -{ - long res, tmp1; - - if (!access_ok(VERIFY_READ, s, 0)) - return 0; - - /* - * This code is deduced from: - * - * tmp1 = n; - * while (tmp1-- > 0 && *s++) - * ; - * - * res = n - tmp1; - * - * (with tweaks). - */ - - __asm__ __volatile__ ( - " move.d %1,$r9\n" - "0:\n" - " ble 1f\n" - " subq 1,$r9\n" - - " test.b [%0+]\n" - " bne 0b\n" - " test.d $r9\n" - "1:\n" - " move.d %1,%0\n" - " sub.d $r9,%0\n" - "2:\n" - " .section .fixup,\"ax\"\n" - - "3: clear.d %0\n" - " jump 2b\n" - - /* There's one address for a fault at the first move, and - two possible PC values for a fault at the second move, - being a delay-slot filler. However, the branch-target - for the second move is the same as the first address. - Just so you don't get confused... */ - " .previous\n" - " .section __ex_table,\"a\"\n" - " .dword 0b,3b\n" - " .dword 1b,3b\n" - " .previous\n" - : "=r" (res), "=r" (tmp1) - : "0" (s), "1" (n) - : "r9"); - - return res; -} - #define strlen_user(str) strnlen_user((str), 0x7ffffffe) #endif /* __ASSEMBLY__ */ diff --git a/include/asm-cris/unistd.h b/include/asm-cris/unistd.h index b06623932f47..4911fee80489 100644 --- a/include/asm-cris/unistd.h +++ b/include/asm-cris/unistd.h @@ -1,11 +1,13 @@ #ifndef _ASM_CRIS_UNISTD_H_ #define _ASM_CRIS_UNISTD_H_ +#include <asm/arch/unistd.h> + /* * This file contains the system call numbers, and stub macros for libc. */ -#define __NR_setup 0 /* used only by init, to get system going */ +#define __NR_restart_syscall 0 #define __NR_exit 1 #define __NR_fork 2 #define __NR_read 3 @@ -230,125 +232,54 @@ /* 223 is unused */ #define __NR_gettid 224 #define __NR_readahead 225 -#define __NR_tkill 226 - -/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ -#define _syscall0(type,name) \ -type name(void) \ -{ \ - register long __a __asm__ ("r10"); \ - __asm__ __volatile__ ("movu.w %1,$r9\n\tbreak 13" \ - : "=r" (__a) \ - : "g" (__NR_##name) \ - : "r10", "r9"); \ - if(__a >= 0) \ - return (type) __a; \ - errno = -__a; \ - return (type) -1; \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ - register long __a __asm__ ("r10") = (long) arg1; \ - __asm__ __volatile__ ("movu.w %1,$r9\n\tbreak 13" \ - : "=r" (__a) \ - : "g" (__NR_##name), "0" (__a) \ - : "r10", "r9"); \ - if(__a >= 0) \ - return (type) __a; \ - errno = -__a; \ - return (type) -1; \ -} +#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 +#define __NR_set_thread_area 243 +#define __NR_get_thread_area 244 +#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 +#define __NR_fadvise64 250 +#define __NR_exit_group 252 +#define __NR_lookup_dcookie 253 +#define __NR_epoll_create 254 +#define __NR_epoll_ctl 255 +#define __NR_epoll_wait 256 +#define __NR_remap_file_pages 257 +#define __NR_set_tid_address 258 +#define __NR_timer_create 259 +#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 268 +#define __NR_fstatfs64 269 + +#define NR_syscalls 270 -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) \ -{ \ - register long __a __asm__ ("r10") = (long) arg1; \ - register long __b __asm__ ("r11") = (long) arg2; \ - __asm__ __volatile__ ("movu.w %1,$r9\n\tbreak 13" \ - : "=r" (__a) \ - : "g" (__NR_##name), "0" (__a), "r" (__b) \ - : "r10", "r9"); \ - if(__a >= 0) \ - return (type) __a; \ - errno = -__a; \ - return (type) -1; \ -} -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) \ -{ \ - register long __a __asm__ ("r10") = (long) arg1; \ - register long __b __asm__ ("r11") = (long) arg2; \ - register long __c __asm__ ("r12") = (long) arg3; \ - __asm__ __volatile__ ("movu.w %1,$r9\n\tbreak 13" \ - : "=r" (__a) \ - : "g" (__NR_##name), "0" (__a), "r" (__b), "r" (__c) \ - : "r10", "r9"); \ - if(__a >= 0) \ - return (type) __a; \ - errno = -__a; \ - return (type) -1; \ -} -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ - register long __a __asm__ ("r10") = (long) arg1; \ - register long __b __asm__ ("r11") = (long) arg2; \ - register long __c __asm__ ("r12") = (long) arg3; \ - register long __d __asm__ ("r13") = (long) arg4; \ - __asm__ __volatile__ ("movu.w %1,$r9\n\tbreak 13" \ - : "=r" (__a) \ - : "g" (__NR_##name), "0" (__a), "r" (__b), \ - "r" (__c), "r" (__d) \ - : "r10", "r9"); \ - if(__a >= 0) \ - return (type) __a; \ - errno = -__a; \ - return (type) -1; \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ -{ \ - register long __a __asm__ ("r10") = (long) arg1; \ - register long __b __asm__ ("r11") = (long) arg2; \ - register long __c __asm__ ("r12") = (long) arg3; \ - register long __d __asm__ ("r13") = (long) arg4; \ - __asm__ __volatile__ ("move %6,$mof\n\t" \ - "movu.w %1,$r9\n\tbreak 13" \ - : "=r" (__a) \ - : "g" (__NR_##name), "0" (__a), "r" (__b), \ - "r" (__c), "r" (__d), "g" (arg5) \ - : "r10", "r9"); \ - if(__a >= 0) \ - return (type) __a; \ - errno = -__a; \ - return (type) -1; \ -} - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ -{ \ - register long __a __asm__ ("r10") = (long) arg1; \ - register long __b __asm__ ("r11") = (long) arg2; \ - register long __c __asm__ ("r12") = (long) arg3; \ - register long __d __asm__ ("r13") = (long) arg4; \ - __asm__ __volatile__ ("move %6,$mof\n\tmove %7,$srp\n\t" \ - "movu.w %1,$r9\n\tbreak 13" \ - : "=r" (__a) \ - : "g" (__NR_##name), "0" (__a), "r" (__b), \ - "r" (__c), "r" (__d), "g" (arg5), "g" (arg6)\ - : "r10", "r9", "srp"); \ - if(__a >= 0) \ - return (type) __a; \ - errno = -__a; \ - return (type) -1; \ -} #ifdef __KERNEL_SYSCALLS__ @@ -365,21 +296,28 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ * some others too. */ #define __NR__exit __NR_exit -static inline _syscall0(pid_t,setsid) -static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) -static inline _syscall1(int,dup,int,fd) -static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp) -static inline _syscall3(int,open,const char *,file,int,flag,int,mode) -static inline _syscall1(int,close,int,fd) -static inline _syscall1(int,_exit,int,exitcode) -static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) -static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count) - - /* the following are just while developing the elinux port! */ - -static inline _syscall3(int,read,int,fd,char *,buf,off_t,count) +extern inline _syscall0(pid_t,setsid) +extern inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) +extern inline _syscall3(int,read,int,fd,char *,buf,off_t,count) +extern inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count) +extern inline _syscall1(int,dup,int,fd) +extern inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp) +extern inline _syscall3(int,open,const char *,file,int,flag,int,mode) +extern inline _syscall1(int,close,int,fd) +/* + * Since we define it "external", it collides with the built-in + * definition, which has the "noreturn" attribute and will cause + * complaints. We don't want to use -fno-builtin, so just use a + * different name when in the kernel. + */ +#ifdef __KERNEL__ +#define _exit kernel_syscall_exit #endif +extern inline _syscall1(int,_exit,int,exitcode) +extern inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) +#endif + /* * "Conditional" syscalls diff --git a/include/asm-cris/user.h b/include/asm-cris/user.h index 982f4163bc94..2538e2a003df 100644 --- a/include/asm-cris/user.h +++ b/include/asm-cris/user.h @@ -4,6 +4,7 @@ #include <linux/types.h> #include <asm/ptrace.h> #include <asm/page.h> +#include <asm/arch/user.h> /* * Core file format: The core file is written in such a way that gdb @@ -27,49 +28,6 @@ * current->start_stack, so we round each of these in order to be able * to write an integer number of pages. */ - -/* User mode registers, used for core dumps. In order to keep ELF_NGREG - sensible we let all registers be 32 bits. The csr registers are included - for future use. */ -struct user_regs_struct { - unsigned long r0; /* General registers. */ - unsigned long r1; - unsigned long r2; - unsigned long r3; - unsigned long r4; - unsigned long r5; - unsigned long r6; - unsigned long r7; - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long r11; - unsigned long r12; - unsigned long r13; - unsigned long sp; /* Stack pointer. */ - unsigned long pc; /* Program counter. */ - unsigned long p0; /* Constant zero (only 8 bits). */ - unsigned long vr; /* Version register (only 8 bits). */ - unsigned long p2; /* Reserved. */ - unsigned long p3; /* Reserved. */ - unsigned long p4; /* Constant zero (only 16 bits). */ - unsigned long ccr; /* Condition code register (only 16 bits). */ - unsigned long p6; /* Reserved. */ - unsigned long mof; /* Multiply overflow register. */ - unsigned long p8; /* Constant zero. */ - unsigned long ibr; /* Not accessible. */ - unsigned long irp; /* Not accessible. */ - unsigned long srp; /* Subroutine return pointer. */ - unsigned long bar; /* Not accessible. */ - unsigned long dccr; /* Dword condition code register. */ - unsigned long brp; /* Not accessible. */ - unsigned long usp; /* User-mode stack pointer. Same as sp when - in user mode. */ - unsigned long csrinstr; /* Internal status registers. */ - unsigned long csraddr; - unsigned long csrdata; -}; - struct user { struct user_regs_struct regs; /* entire machine state */ |
