diff options
Diffstat (limited to 'arch/cris/arch-v10')
48 files changed, 899 insertions, 3935 deletions
diff --git a/arch/cris/arch-v10/Kconfig b/arch/cris/arch-v10/Kconfig index adc164e9933..df9a38b4f18 100644 --- a/arch/cris/arch-v10/Kconfig +++ b/arch/cris/arch-v10/Kconfig @@ -24,8 +24,8 @@ config ETRAX_PA_LEDS help The ETRAX network driver is responsible for flashing LED's when packets arrive and are sent. It uses macros defined in - <file:include/asm-cris/io.h>, and those macros are defined after what - YOU choose in this option. The actual bits used are configured + <file:arch/cris/include/asm/io.h>, and those macros are defined after + what YOU choose in this option. The actual bits used are configured separately. Select this if the LEDs are on port PA. Some products put the leds on PB or a memory-mapped latch (CSP0) instead. @@ -34,8 +34,8 @@ config ETRAX_PB_LEDS help The ETRAX network driver is responsible for flashing LED's when packets arrive and are sent. It uses macros defined in - <file:include/asm-cris/io.h>, and those macros are defined after what - YOU choose in this option. The actual bits used are configured + <file:arch/cris/include/asm/io.h>, and those macros are defined after + what YOU choose in this option. The actual bits used are configured separately. Select this if the LEDs are on port PB. Some products put the leds on PA or a memory-mapped latch (CSP0) instead. @@ -44,8 +44,8 @@ config ETRAX_CSP0_LEDS help The ETRAX network driver is responsible for flashing LED's when packets arrive and are sent. It uses macros defined in - <file:include/asm-cris/io.h>, and those macros are defined after what - YOU choose in this option. The actual bits used are configured + <file:arch/cris/include/asm/io.h>, and those macros are defined after + what YOU choose in this option. The actual bits used are configured separately. Select this if the LEDs are on a memory-mapped latch using chip select CSP0, this is mapped at 0x90000000. Some products put the leds on PA or PB instead. diff --git a/arch/cris/arch-v10/README.mm b/arch/cris/arch-v10/README.mm index 517d1f027fe..67731d75cb5 100644 --- a/arch/cris/arch-v10/README.mm +++ b/arch/cris/arch-v10/README.mm @@ -38,7 +38,7 @@ space. We also use it to keep the user-mode virtual mapping in the same map during kernel-mode, so that the kernel easily can access the corresponding user-mode process' data. -As a comparision, the Linux/i386 2.0 puts the kernel and physical RAM at +As a comparison, the Linux/i386 2.0 puts the kernel and physical RAM at address 0, overlapping with the user-mode virtual space, so that descriptor registers are needed for each memory access to specify which MMU space to map through. That changed in 2.2, putting the kernel/physical RAM at diff --git a/arch/cris/arch-v10/boot/.gitignore b/arch/cris/arch-v10/boot/.gitignore deleted file mode 100644 index 171a0853caf..00000000000 --- a/arch/cris/arch-v10/boot/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -Image -zImage diff --git a/arch/cris/arch-v10/boot/Makefile b/arch/cris/arch-v10/boot/Makefile deleted file mode 100644 index 21720301443..00000000000 --- a/arch/cris/arch-v10/boot/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# -# arch/cris/arch-v10/boot/Makefile -# - -OBJCOPYFLAGS = -O binary --remove-section=.bss - -subdir- := compressed rescue -targets := Image - -$(obj)/Image: vmlinux FORCE - $(call if_changed,objcopy) - @echo ' Kernel: $@ is ready' - -$(obj)/compressed/vmlinux: $(obj)/Image FORCE - $(Q)$(MAKE) $(build)=$(obj)/compressed $@ - $(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin - -$(obj)/zImage: $(obj)/compressed/vmlinux - @cp $< $@ - @echo ' Kernel: $@ is ready' diff --git a/arch/cris/arch-v10/boot/compressed/Makefile b/arch/cris/arch-v10/boot/compressed/Makefile deleted file mode 100644 index 6fe0ffaf3be..00000000000 --- a/arch/cris/arch-v10/boot/compressed/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# -# arch/cris/arch-v10/boot/compressed/Makefile -# - -asflags-y += $(LINUXINCLUDE) -ccflags-y += -O2 $(LINUXINCLUDE) -ldflags-y += -T $(srctree)/$(src)/decompress.lds -OBJECTS = $(obj)/head.o $(obj)/misc.o -OBJCOPYFLAGS = -O binary --remove-section=.bss - -quiet_cmd_image = BUILD $@ -cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@ - -targets := vmlinux piggy.gz decompress.o decompress.bin - -$(obj)/decompress.o: $(OBJECTS) FORCE - $(call if_changed,ld) - -$(obj)/decompress.bin: $(obj)/decompress.o FORCE - $(call if_changed,objcopy) - -$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE - $(call if_changed,image) - -$(obj)/piggy.gz: $(obj)/../Image FORCE - $(call if_changed,gzip) - diff --git a/arch/cris/arch-v10/boot/compressed/README b/arch/cris/arch-v10/boot/compressed/README deleted file mode 100644 index 48b3db9924b..00000000000 --- a/arch/cris/arch-v10/boot/compressed/README +++ /dev/null @@ -1,25 +0,0 @@ -Creation of the self-extracting compressed kernel image (vmlinuz) ------------------------------------------------------------------ -$Id: README,v 1.1 2001/12/17 13:59:27 bjornw Exp $ - -This can be slightly confusing because it's a process with many steps. - -The kernel object built by the arch/etrax100/Makefile, vmlinux, is split -by that makefile into text and data binary files, vmlinux.text and -vmlinux.data. - -Those files together with a ROM filesystem can be catted together and -burned into a flash or executed directly at the DRAM origin. - -They can also be catted together and compressed with gzip, which is what -happens in this makefile. Together they make up piggy.img. - -The decompressor is built into the file decompress.o. It is turned into -the binary file decompress.bin, which is catted together with piggy.img -into the file vmlinuz. It can be executed in an arbitrary place in flash. - -Be careful - it assumes some things about free locations in DRAM. It -assumes the DRAM starts at 0x40000000 and that it is at least 8 MB, -so it puts its code at 0x40700000, and initial stack at 0x40800000. - --Bjorn diff --git a/arch/cris/arch-v10/boot/compressed/decompress.lds b/arch/cris/arch-v10/boot/compressed/decompress.lds deleted file mode 100644 index e80f4594d54..00000000000 --- a/arch/cris/arch-v10/boot/compressed/decompress.lds +++ /dev/null @@ -1,30 +0,0 @@ -/* OUTPUT_FORMAT(elf32-us-cris) */ -OUTPUT_FORMAT(elf32-cris) - -MEMORY - { - dram : ORIGIN = 0x40700000, - LENGTH = 0x00100000 - } - -SECTIONS -{ - .text : - { - _stext = . ; - *(.text) - *(.rodata) - *(.rodata.*) - _etext = . ; - } > dram - .data : - { - *(.data) - _edata = . ; - } > dram - .bss : - { - *(.bss) - _end = ALIGN( 0x10 ) ; - } > dram -} diff --git a/arch/cris/arch-v10/boot/compressed/head.S b/arch/cris/arch-v10/boot/compressed/head.S deleted file mode 100644 index 0bb4dcc2925..00000000000 --- a/arch/cris/arch-v10/boot/compressed/head.S +++ /dev/null @@ -1,126 +0,0 @@ -/* - * arch/cris/boot/compressed/head.S - * - * Copyright (C) 1999, 2001 Axis Communications AB - * - * Code that sets up the DRAM registers, calls the - * decompressor to unpack the piggybacked kernel, and jumps. - * - */ - -#define ASSEMBLER_MACROS_ONLY -#include <arch/sv_addr_ag.h> - -#define RAM_INIT_MAGIC 0x56902387 -#define COMMAND_LINE_MAGIC 0x87109563 - - ;; Exported symbols - - .globl input_data - - - .text - - nop - di - -;; We need to initialze DRAM registers before we start using the DRAM - - cmp.d RAM_INIT_MAGIC, $r8 ; Already initialized? - beq dram_init_finished - nop - -#include "../../lib/dram_init.S" - -dram_init_finished: - - ;; Initiate the PA and PB ports - - move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0 - move.b $r0, [R_PORT_PA_DATA] - - move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0 - move.b $r0, [R_PORT_PA_DIR] - - move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0 - move.b $r0, [R_PORT_PB_DATA] - - move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0 - move.b $r0, [R_PORT_PB_DIR] - - ;; Setup the stack to a suitably high address. - ;; We assume 8 MB is the minimum DRAM in an eLinux - ;; product and put the sp at the top for now. - - move.d 0x40800000, $sp - - ;; Figure out where the compressed piggyback image is - ;; in the flash (since we wont try to copy it to DRAM - ;; before unpacking). It is at _edata, but in flash. - ;; Use (_edata - basse) as offset to the current PC. - -basse: move.d $pc, $r5 - and.d 0x7fffffff, $r5 ; strip any non-cache bit - subq 2, $r5 ; compensate for the move.d $pc instr - move.d $r5, $r0 ; save for later - flash address of 'basse' - add.d _edata, $r5 - sub.d basse, $r5 ; $r5 = flash address of '_edata' - - ;; Copy text+data to DRAM - - move.d basse, $r1 ; destination - move.d _edata, $r2 ; end destination -1: move.w [$r0+], $r3 - move.w $r3, [$r1+] - cmp.d $r2, $r1 - bcs 1b - nop - - move.d $r5, [input_data] ; for the decompressor - - - ;; Clear the decompressors BSS (between _edata and _end) - - moveq 0, $r0 - move.d _edata, $r1 - move.d _end, $r2 -1: move.w $r0, [$r1+] - cmp.d $r2, $r1 - bcs 1b - nop - - ;; Save command line magic and address. - move.d _cmd_line_magic, $r12 - move.d $r10, [$r12] - move.d _cmd_line_addr, $r12 - move.d $r11, [$r12] - - ;; Do the decompression and save compressed size in inptr - - jsr decompress_kernel - - ;; Put start address of root partition in $r9 so the kernel can use it - ;; when mounting from flash - - move.d [input_data], $r9 ; flash address of compressed kernel - add.d [inptr], $r9 ; size of compressed kernel - - ;; Restore command line magic and address. - move.d _cmd_line_magic, $r10 - move.d [$r10], $r10 - move.d _cmd_line_addr, $r11 - move.d [$r11], $r11 - - ;; Enter the decompressed kernel - move.d RAM_INIT_MAGIC, $r8 ; Tell kernel that DRAM is initialized - jump 0x40004000 ; kernel is linked to this address - - .data - -input_data: - .dword 0 ; used by the decompressor -_cmd_line_magic: - .dword 0 -_cmd_line_addr: - .dword 0 -#include "../../lib/hw_settings.S" diff --git a/arch/cris/arch-v10/boot/compressed/misc.c b/arch/cris/arch-v10/boot/compressed/misc.c deleted file mode 100644 index a4db1507d3b..00000000000 --- a/arch/cris/arch-v10/boot/compressed/misc.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * misc.c - * - * This is a collection of several routines from gzip-1.0.3 - * adapted for Linux. - * - * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 - * puts by Nick Holloway 1993, better puts by Martin Mares 1995 - * adaptation for Linux/CRIS Axis Communications AB, 1999 - * - */ - -/* where the piggybacked kernel image expects itself to live. - * it is the same address we use when we network load an uncompressed - * image into DRAM, and it is the address the kernel is linked to live - * at by vmlinux.lds.S - */ - -#define KERNEL_LOAD_ADR 0x40004000 - - -#include <linux/types.h> -#include <arch/svinto.h> - -/* - * gzip declarations - */ - -#define OF(args) args -#define STATIC static - -void *memset(void *s, int c, size_t n); -void *memcpy(void *__dest, __const void *__src, size_t __n); - -#define memzero(s, n) memset((s), 0, (n)) - -typedef unsigned char uch; -typedef unsigned short ush; -typedef unsigned long ulg; - -#define WSIZE 0x8000 /* Window size must be at least 32k, */ - /* and a power of two */ - -static uch *inbuf; /* input buffer */ -static uch window[WSIZE]; /* Sliding window buffer */ - -unsigned inptr = 0; /* index of next byte to be processed in inbuf - * After decompression it will contain the - * compressed size, and head.S will read it. - */ - -static unsigned outcnt = 0; /* bytes in output buffer */ - -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ -#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ -#define RESERVED 0xC0 /* bit 6,7: reserved */ - -#define get_byte() (inbuf[inptr++]) - -/* Diagnostic functions */ -#ifdef DEBUG -# define Assert(cond, msg) do { \ - if (!(cond)) \ - error(msg); \ - } while (0) -# define Trace(x) fprintf x -# define Tracev(x) do { \ - if (verbose) \ - fprintf x; \ - } while (0) -# define Tracevv(x) do { \ - if (verbose > 1) \ - fprintf x; \ - } while (0) -# define Tracec(c, x) do { \ - if (verbose && (c)) \ - fprintf x; \ - } while (0) -# define Tracecv(c, x) do { \ - if (verbose > 1 && (c)) \ - fprintf x; \ - } while (0) -#else -# define Assert(cond, msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c, x) -# define Tracecv(c, x) -#endif - -static void flush_window(void); -static void error(char *m); - -extern char *input_data; /* lives in head.S */ - -static long bytes_out = 0; -static uch *output_data; -static unsigned long output_ptr = 0; -static void puts(const char *); - -/* the "heap" is put directly after the BSS ends, at end */ - -extern int _end; -static long free_mem_ptr = (long)&_end; -static long free_mem_end_ptr; - -#include "../../../../../lib/inflate.c" - -/* decompressor info and error messages to serial console */ - -static void -puts(const char *s) -{ -#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL - while (*s) { -#ifdef CONFIG_ETRAX_DEBUG_PORT0 - while (!(*R_SERIAL0_STATUS & (1 << 5))) ; - *R_SERIAL0_TR_DATA = *s++; -#endif -#ifdef CONFIG_ETRAX_DEBUG_PORT1 - while (!(*R_SERIAL1_STATUS & (1 << 5))) ; - *R_SERIAL1_TR_DATA = *s++; -#endif -#ifdef CONFIG_ETRAX_DEBUG_PORT2 - while (!(*R_SERIAL2_STATUS & (1 << 5))) ; - *R_SERIAL2_TR_DATA = *s++; -#endif -#ifdef CONFIG_ETRAX_DEBUG_PORT3 - while (!(*R_SERIAL3_STATUS & (1 << 5))) ; - *R_SERIAL3_TR_DATA = *s++; -#endif - } -#endif -} - -void *memset(void *s, int c, size_t n) -{ - int i; - char *ss = (char *)s; - - for (i = 0; i < n; i++) - ss[i] = c; - - return s; -} - -void *memcpy(void *__dest, __const void *__src, size_t __n) -{ - int i; - char *d = (char *)__dest, *s = (char *)__src; - - for (i = 0; i < __n; i++) - d[i] = s[i]; - - return __dest; -} - -/* =========================================================================== - * Write the output window window[0..outcnt-1] and update crc and bytes_out. - * (Used for the decompressed data only.) - */ - -static void flush_window(void) -{ - ulg c = crc; /* temporary variable */ - unsigned n; - uch *in, *out, ch; - - in = window; - out = &output_data[output_ptr]; - for (n = 0; n < outcnt; n++) { - ch = *out = *in; - out++; - in++; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - output_ptr += (ulg)outcnt; - outcnt = 0; -} - -static void error(char *x) -{ - puts("\n\n"); - puts(x); - puts("\n\n -- System halted\n"); - - while (1); /* Halt */ -} - -void setup_normal_output_buffer(void) -{ - output_data = (char *)KERNEL_LOAD_ADR; -} - -void decompress_kernel(void) -{ - char revision; - - /* input_data is set in head.S */ - inbuf = input_data; - -#ifdef CONFIG_ETRAX_DEBUG_PORT0 - *R_SERIAL0_XOFF = 0; - *R_SERIAL0_BAUD = 0x99; - *R_SERIAL0_TR_CTRL = 0x40; -#endif -#ifdef CONFIG_ETRAX_DEBUG_PORT1 - *R_SERIAL1_XOFF = 0; - *R_SERIAL1_BAUD = 0x99; - *R_SERIAL1_TR_CTRL = 0x40; -#endif -#ifdef CONFIG_ETRAX_DEBUG_PORT2 - *R_GEN_CONFIG = 0x08; - *R_SERIAL2_XOFF = 0; - *R_SERIAL2_BAUD = 0x99; - *R_SERIAL2_TR_CTRL = 0x40; -#endif -#ifdef CONFIG_ETRAX_DEBUG_PORT3 - *R_GEN_CONFIG = 0x100; - *R_SERIAL3_XOFF = 0; - *R_SERIAL3_BAUD = 0x99; - *R_SERIAL3_TR_CTRL = 0x40; -#endif - - setup_normal_output_buffer(); - - makecrc(); - - __asm__ volatile ("move $vr,%0" : "=rm" (revision)); - if (revision < 10) { - puts("You need an ETRAX 100LX to run linux 2.6\n"); - while (1); - } - - puts("Uncompressing Linux...\n"); - gunzip(); - puts("Done. Now booting the kernel.\n"); -} diff --git a/arch/cris/arch-v10/boot/rescue/Makefile b/arch/cris/arch-v10/boot/rescue/Makefile deleted file mode 100644 index 82ab59b968e..00000000000 --- a/arch/cris/arch-v10/boot/rescue/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -# -# Makefile for rescue (bootstrap) code -# - -ccflags-y += -O2 $(LINUXINCLUDE) -asflags-y += $(LINUXINCLUDE) -ldflags-y += -T $(srctree)/$(src)/rescue.lds -OBJCOPYFLAGS = -O binary --remove-section=.bss -obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o -OBJECT := $(obj)/head.o - -targets := rescue.o rescue.bin - -$(obj)/rescue.o: $(OBJECT) FORCE - $(call if_changed,ld) - -$(obj)/rescue.bin: $(obj)/rescue.o FORCE - $(call if_changed,objcopy) - cp -p $(obj)/rescue.bin $(objtree) - -$(obj)/testrescue.bin: $(obj)/testrescue.o - $(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/testrescue.o tr.bin -# Pad it to 784 bytes - dd if=/dev/zero of=tmp2423 bs=1 count=784 - cat tr.bin tmp2423 >testrescue_tmp.bin - dd if=testrescue_tmp.bin of=$(obj)/testrescue.bin bs=1 count=784 - rm tr.bin tmp2423 testrescue_tmp.bin - -$(obj)/kimagerescue.bin: $(obj)/kimagerescue.o - $(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/kimagerescue.o ktr.bin -# Pad it to 784 bytes, that's what the rescue loader expects - dd if=/dev/zero of=tmp2423 bs=1 count=784 - cat ktr.bin tmp2423 >kimagerescue_tmp.bin - dd if=kimagerescue_tmp.bin of=$(obj)/kimagerescue.bin bs=1 count=784 - rm ktr.bin tmp2423 kimagerescue_tmp.bin diff --git a/arch/cris/arch-v10/boot/rescue/head.S b/arch/cris/arch-v10/boot/rescue/head.S deleted file mode 100644 index fb503d1eeea..00000000000 --- a/arch/cris/arch-v10/boot/rescue/head.S +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Rescue code, made to reside at the beginning of the - * flash-memory. when it starts, it checks a partition - * table at the first sector after the rescue sector. - * the partition table was generated by the product builder - * script and contains offsets, lengths, types and checksums - * for each partition that this code should check. - * - * If any of the checksums fail, we assume the flash is so - * corrupt that we cant use it to boot into the ftp flash - * loader, and instead we initialize the serial port to - * receive a flash-loader and new flash image. we dont include - * any flash code here, but just accept a certain amount of - * bytes from the serial port and jump into it. the downloaded - * code is put in the cache. - * - * The partitiontable is designed so that it is transparent to - * code execution - it has a relative branch opcode in the - * beginning that jumps over it. each entry contains extra - * data so we can add stuff later. - * - * Partition table format: - * - * Code transparency: - * - * 2 bytes [opcode 'nop'] - * 2 bytes [opcode 'di'] - * 4 bytes [opcode 'ba <offset>', 8-bit or 16-bit version] - * 2 bytes [opcode 'nop', delay slot] - * - * Table validation (at +10): - * - * 2 bytes [magic/version word for partitiontable - 0xef, 0xbe] - * 2 bytes [length of all entries plus the end marker] - * 4 bytes [checksum for the partitiontable itself] - * - * Entries, each with the following format, last has offset -1: - * - * 4 bytes [offset in bytes, from start of flash] - * 4 bytes [length in bytes of partition] - * 4 bytes [checksum, simple longword sum] - * 2 bytes [partition type] - * 2 bytes [flags, only bit 0 used, ro/rw = 1/0] - * 16 bytes [reserved for future use] - * - * End marker - * - * 4 bytes [-1] - * - * 10 bytes [0, padding] - * - * Bit 0 in flags signifies RW or RO. The rescue code only bothers - * to check the checksum for RO partitions, since the others will - * change their data without updating the checksums. A 1 in bit 0 - * means RO, 0 means RW. That way, it is possible to set a partition - * in RO mode initially, and later mark it as RW, since you can always - * write 0's to the flash. - * - * During the wait for serial input, the status LED will flash so the - * user knows something went wrong. - * - * Copyright (C) 1999-2007 Axis Communications AB - */ - -#ifdef CONFIG_ETRAX_AXISFLASHMAP - -#define ASSEMBLER_MACROS_ONLY -#include <arch/sv_addr_ag.h> - - ;; The partitiontable is looked for at the first sector after the boot - ;; sector. Sector size is 65536 bytes in all flashes we use. - -#define PTABLE_START CONFIG_ETRAX_PTABLE_SECTOR -#define PTABLE_MAGIC 0xbeef - - ;; The normal Etrax100 on-chip boot ROM does serial boot at 0x380000f0. - ;; That is not where we put our downloaded serial boot-code. - ;; The length is enough for downloading code that loads the rest - ;; of itself (after having setup the DRAM etc). - ;; It is the same length as the on-chip ROM loads, so the same - ;; host loader can be used to load a rescued product as well as - ;; one booted through the Etrax serial boot code. - -#define CODE_START 0x40000000 -#define CODE_LENGTH 784 - -#ifdef CONFIG_ETRAX_RESCUE_SER0 -#define SERXOFF R_SERIAL0_XOFF -#define SERBAUD R_SERIAL0_BAUD -#define SERRECC R_SERIAL0_REC_CTRL -#define SERRDAT R_SERIAL0_REC_DATA -#define SERSTAT R_SERIAL0_STATUS -#endif -#ifdef CONFIG_ETRAX_RESCUE_SER1 -#define SERXOFF R_SERIAL1_XOFF -#define SERBAUD R_SERIAL1_BAUD -#define SERRECC R_SERIAL1_REC_CTRL -#define SERRDAT R_SERIAL1_REC_DATA -#define SERSTAT R_SERIAL1_STATUS -#endif -#ifdef CONFIG_ETRAX_RESCUE_SER2 -#define SERXOFF R_SERIAL2_XOFF -#define SERBAUD R_SERIAL2_BAUD -#define SERRECC R_SERIAL2_REC_CTRL -#define SERRDAT R_SERIAL2_REC_DATA -#define SERSTAT R_SERIAL2_STATUS -#endif -#ifdef CONFIG_ETRAX_RESCUE_SER3 -#define SERXOFF R_SERIAL3_XOFF -#define SERBAUD R_SERIAL3_BAUD -#define SERRECC R_SERIAL3_REC_CTRL -#define SERRDAT R_SERIAL3_REC_DATA -#define SERSTAT R_SERIAL3_STATUS -#endif - -#define NOP_DI 0xf025050f -#define RAM_INIT_MAGIC 0x56902387 - - .text - - ;; This is the entry point of the rescue code - ;; 0x80000000 if loaded in flash (as it should be) - ;; Since etrax actually starts at address 2 when booting from flash, we - ;; put a nop (2 bytes) here first so we dont accidentally skip the di - - nop - di - - jump in_cache ; enter cached area instead -in_cache: - - - ;; First put a jump test to give a possibility of upgrading the - ;; rescue code without erasing/reflashing the sector. - ;; We put a longword of -1 here and if it is not -1, we jump using - ;; the value as jump target. Since we can always change 1's to 0's - ;; without erasing the sector, it is possible to add new - ;; code after this and altering the jumptarget in an upgrade. - -jtcd: move.d [jumptarget], $r0 - cmp.d 0xffffffff, $r0 - beq no_newjump - nop - - jump [$r0] - -jumptarget: - .dword 0xffffffff ; can be overwritten later to insert new code - -no_newjump: -#ifdef CONFIG_ETRAX_ETHERNET - ;; Start MII clock to make sure it is running when tranceiver is reset - move.d 0x3, $r0 ; enable = on, phy = mii_clk - move.d $r0, [R_NETWORK_GEN_CONFIG] -#endif - - ;; We need to setup the bus registers before we start using the DRAM -#include "../../lib/dram_init.S" - - ;; we now should go through the checksum-table and check the listed - ;; partitions for errors. - - move.d PTABLE_START, $r3 - move.d [$r3], $r0 - cmp.d NOP_DI, $r0 ; make sure the nop/di is there... - bne do_rescue - nop - - ;; skip the code transparency block (10 bytes). - - addq 10, $r3 - - ;; check for correct magic - - move.w [$r3+], $r0 - cmp.w PTABLE_MAGIC, $r0 - bne do_rescue ; didn't recognize - trig rescue - nop - - ;; check for correct ptable checksum - - movu.w [$r3+], $r2 ; ptable length - move.d $r2, $r8 ; save for later, length of total ptable - addq 28, $r8 ; account for the rest - move.d [$r3+], $r4 ; ptable checksum - move.d $r3, $r1 - jsr checksum ; r1 source, r2 length, returns in r0 - - cmp.d $r0, $r4 - bne do_rescue ; didn't match - trig rescue - nop - - ;; ptable is ok. validate each entry. - - moveq -1, $r7 - -ploop: move.d [$r3+], $r1 ; partition offset (from ptable start) - bne notfirst ; check if it is the partition containing ptable - nop ; yes.. - move.d $r8, $r1 ; for its checksum check, skip the ptable - move.d [$r3+], $r2 ; partition length - sub.d $r8, $r2 ; minus the ptable length - ba bosse - nop -notfirst: - cmp.d -1, $r1 ; the end of the ptable ? - beq flash_ok ; if so, the flash is validated - move.d [$r3+], $r2 ; partition length -bosse: move.d [$r3+], $r5 ; checksum - move.d [$r3+], $r4 ; type and flags - addq 16, $r3 ; skip the reserved bytes - btstq 16, $r4 ; check ro flag - bpl ploop ; rw partition, skip validation - nop - btstq 17, $r4 ; check bootable flag - bpl 1f - nop - move.d $r1, $r7 ; remember boot partition offset -1: - add.d PTABLE_START, $r1 - - jsr checksum ; checksum the partition - - cmp.d $r0, $r5 - beq ploop ; checksums matched, go to next entry - nop - - ;; otherwise fall through to the rescue code. - -do_rescue: - ;; setup port PA and PB default initial directions and data - ;; (so we can flash LEDs, and so that DTR and others are set) - - move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0 - move.b $r0, [R_PORT_PA_DIR] - move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0 - move.b $r0, [R_PORT_PA_DATA] - - move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0 - move.b $r0, [R_PORT_PB_DIR] - move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0 - move.b $r0, [R_PORT_PB_DATA] - - ;; setup the serial port at 115200 baud - - moveq 0, $r0 - move.d $r0, [SERXOFF] - - move.b 0x99, $r0 - move.b $r0, [SERBAUD] ; 115.2kbaud for both transmit and receive - - move.b 0x40, $r0 ; rec enable - move.b $r0, [SERRECC] - - moveq 0, $r1 ; "timer" to clock out a LED red flash - move.d CODE_START, $r3 ; destination counter - movu.w CODE_LENGTH, $r4; length - -wait_ser: - addq 1, $r1 -#ifndef CONFIG_ETRAX_NO_LEDS -#ifdef CONFIG_ETRAX_PA_LEDS - move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r2 -#endif -#ifdef CONFIG_ETRAX_PB_LEDS - move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r2 -#endif - move.d (1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), $r0 - btstq 16, $r1 - bpl 1f - nop - or.d $r0, $r2 ; set bit - ba 2f - nop -1: not $r0 ; clear bit - and.d $r0, $r2 -2: -#ifdef CONFIG_ETRAX_PA_LEDS - move.b $r2, [R_PORT_PA_DATA] -#endif -#ifdef CONFIG_ETRAX_PB_LEDS - move.b $r2, [R_PORT_PB_DATA] -#endif -#ifdef CONFIG_ETRAX_90000000_LEDS - move.b $r2, [0x90000000] -#endif -#endif - - ;; check if we got something on the serial port - - move.b [SERSTAT], $r0 - btstq 0, $r0 ; data_avail - bpl wait_ser - nop - - ;; got something - copy the byte and loop - - move.b [SERRDAT], $r0 - move.b $r0, [$r3+] - - subq 1, $r4 ; decrease length - bne wait_ser - nop - - ;; jump into downloaded code - - move.d RAM_INIT_MAGIC, $r8 ; Tell next product that DRAM is - ; initialized - jump CODE_START - -flash_ok: - ;; check r7, which contains either -1 or the partition to boot from - - cmp.d -1, $r7 - bne 1f - nop - move.d PTABLE_START, $r7; otherwise use the ptable start -1: - move.d RAM_INIT_MAGIC, $r8 ; Tell next product that DRAM is - ; initialized - jump $r7 ; boot! - - - ;; Helper subroutines - - ;; Will checksum by simple addition - ;; r1 - source - ;; r2 - length in bytes - ;; result will be in r0 -checksum: - moveq 0, $r0 - moveq CONFIG_ETRAX_FLASH1_SIZE, $r6 - - ;; If the first physical flash memory is exceeded wrap to the - ;; second one - btstq 26, $r1 ; Are we addressing first flash? - bpl 1f - nop - clear.d $r6 - -1: test.d $r6 ; 0 = no wrapping - beq 2f - nop - lslq 20, $r6 ; Convert MB to bytes - sub.d $r1, $r6 - -2: addu.b [$r1+], $r0 - subq 1, $r6 ; Flash memory left - beq 3f - subq 1, $r2 ; Length left - bne 2b - nop - ret - nop - -3: move.d MEM_CSE1_START, $r1 ; wrap to second flash - ba 2b - nop - -#endif diff --git a/arch/cris/arch-v10/boot/rescue/kimagerescue.S b/arch/cris/arch-v10/boot/rescue/kimagerescue.S deleted file mode 100644 index 6f7b3e61260..00000000000 --- a/arch/cris/arch-v10/boot/rescue/kimagerescue.S +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Rescue code to be prepended on a kimage and copied to the - * rescue serial port. - * This is called from the rescue code, it will copy received data to - * 4004000 and after a timeout jump to it. - */ - -#define ASSEMBLER_MACROS_ONLY -#include <arch/sv_addr_ag.h> - -#define CODE_START 0x40004000 -#define CODE_LENGTH 784 -#define TIMEOUT_VALUE 1000 - - -#ifdef CONFIG_ETRAX_RESCUE_SER0 -#define SERXOFF R_SERIAL0_XOFF -#define SERBAUD R_SERIAL0_BAUD -#define SERRECC R_SERIAL0_REC_CTRL -#define SERRDAT R_SERIAL0_REC_DATA -#define SERSTAT R_SERIAL0_STATUS -#endif -#ifdef CONFIG_ETRAX_RESCUE_SER1 -#define SERXOFF R_SERIAL1_XOFF -#define SERBAUD R_SERIAL1_BAUD -#define SERRECC R_SERIAL1_REC_CTRL -#define SERRDAT R_SERIAL1_REC_DATA -#define SERSTAT R_SERIAL1_STATUS -#endif -#ifdef CONFIG_ETRAX_RESCUE_SER2 -#define SERXOFF R_SERIAL2_XOFF -#define SERBAUD R_SERIAL2_BAUD -#define SERRECC R_SERIAL2_REC_CTRL -#define SERRDAT R_SERIAL2_REC_DATA -#define SERSTAT R_SERIAL2_STATUS -#endif -#ifdef CONFIG_ETRAX_RESCUE_SER3 -#define SERXOFF R_SERIAL3_XOFF -#define SERBAUD R_SERIAL3_BAUD -#define SERRECC R_SERIAL3_REC_CTRL -#define SERRDAT R_SERIAL3_REC_DATA -#define SERSTAT R_SERIAL3_STATUS -#endif - - .text - ;; This is the entry point of the rescue code - ;; 0x80000000 if loaded in flash (as it should be) - ;; since etrax actually starts at address 2 when booting from flash, we - ;; put a nop (2 bytes) here first so we dont accidentally skip the di - - nop - di -#ifndef CONFIG_SVINTO_SIM - ;; setup port PA and PB default initial directions and data - ;; (so we can flash LEDs, and so that DTR and others are set) - - move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0 - move.b $r0, [R_PORT_PA_DIR] - move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0 - move.b $r0, [R_PORT_PA_DATA] - - move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0 - move.b $r0, [R_PORT_PB_DIR] - move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0 - move.b $r0, [R_PORT_PB_DATA] - - ;; We need to setup the bus registers before we start using the DRAM -#include "../../lib/dram_init.S" - -#endif - ;; Setup the stack to a suitably high address. - ;; We assume 8 MB is the minimum DRAM in an eLinux - ;; product and put the sp at the top for now. - - move.d 0x40800000, $sp - - ;; setup the serial port at 115200 baud - - moveq 0, $r0 - move.d $r0, [SERXOFF] - - move.b 0x99, $r0 - move.b $r0, [SERBAUD] ; 115.2kbaud for both transmit - ; and receive - - move.b 0x40, $r0 ; rec enable - move.b $r0, [SERRECC] - - - moveq 0, $r1 ; "timer" to clock out a LED red flash - move.d CODE_START, $r3 ; destination counter - move.d CODE_LENGTH, $r4 ; length - move.d TIMEOUT_VALUE, $r5 ; "timeout" until jump - -wait_ser: - addq 1, $r1 - subq 1, $r5 ; decrease timeout - beq jump_start ; timed out - nop -#ifndef CONFIG_ETRAX_NO_LEDS -#ifdef CONFIG_ETRAX_PA_LEDS - move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r2 -#endif -#ifdef CONFIG_ETRAX_PB_LEDS - move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r2 -#endif - move.d (1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), $r0 - btstq 16, $r1 - bpl 1f - nop - or.d $r0, $r2 ; set bit - ba 2f - nop -1: not $r0 ; clear bit - and.d $r0, $r2 -2: -#ifdef CONFIG_ETRAX_PA_LEDS - move.b $r2, [R_PORT_PA_DATA] -#endif -#ifdef CONFIG_ETRAX_PB_LEDS - move.b $r2, [R_PORT_PB_DATA] -#endif -#endif - - ;; check if we got something on the serial port - - move.b [SERSTAT], $r0 - btstq 0, $r0 ; data_avail - bpl wait_ser - nop - - ;; got something - copy the byte and loop - - move.b [SERRDAT], $r0 - move.b $r0, [$r3+] - move.d TIMEOUT_VALUE, $r5 ; reset "timeout" - subq 1, $r4 ; decrease length - bne wait_ser - nop -jump_start: - ;; jump into downloaded code - - jump CODE_START diff --git a/arch/cris/arch-v10/boot/rescue/rescue.lds b/arch/cris/arch-v10/boot/rescue/rescue.lds deleted file mode 100644 index 0b52a9490db..00000000000 --- a/arch/cris/arch-v10/boot/rescue/rescue.lds +++ /dev/null @@ -1,20 +0,0 @@ -MEMORY - { - flash : ORIGIN = 0x00000000, - LENGTH = 0x00100000 - } - -SECTIONS -{ - .text : - { - stext = . ; - *(.text) - etext = . ; - } > flash - .data : - { - *(.data) - edata = . ; - } > flash -} diff --git a/arch/cris/arch-v10/boot/rescue/testrescue.S b/arch/cris/arch-v10/boot/rescue/testrescue.S deleted file mode 100644 index fc7ec674eca..00000000000 --- a/arch/cris/arch-v10/boot/rescue/testrescue.S +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Simple testcode to download by the rescue block. - * Just lights some LEDs to show it was downloaded correctly. - * - * Copyright (C) 1999 Axis Communications AB - */ - -#define ASSEMBLER_MACROS_ONLY -#include <arch/sv_addr_ag.h> - - .text - - nop - nop - moveq -1, $r2 - move.b $r2, [R_PORT_PA_DIR] - moveq 0, $r2 - move.b $r2, [R_PORT_PA_DATA] - -endless: - nop - ba endless - nop - diff --git a/arch/cris/arch-v10/boot/tools/build.c b/arch/cris/arch-v10/boot/tools/build.c deleted file mode 100644 index c8adef36416..00000000000 --- a/arch/cris/arch-v10/boot/tools/build.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * linux/tools/build.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -/* - * This file builds a disk-image from three different files: - * - * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest - * - setup: 8086 machine code, sets up system parm - * - system: 80386 code for actual system - * - * It does some checking that all files are of the correct type, and - * just writes the result to stdout, removing headers and padding to - * the right amount. It also writes some system data to stderr. - */ - -/* - * Changes by tytso to allow root device specification - * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 - * Cross compiling fixes by Gertjan van Wingerde, July 1996 - */ - -#include <stdio.h> /* fprintf */ -#include <string.h> -#include <stdlib.h> /* contains exit */ -#include <sys/types.h> /* unistd.h needs this */ -#include <sys/stat.h> -#include <sys/sysmacros.h> -#include <unistd.h> /* contains read/write */ -#include <fcntl.h> -#include <errno.h> - -#define MINIX_HEADER 32 - -#define N_MAGIC_OFFSET 1024 -#ifndef __BFD__ -static int GCC_HEADER = sizeof(struct exec); -#endif - -#ifdef __BIG_KERNEL__ -#define SYS_SIZE 0xffff -#else -#define SYS_SIZE DEF_SYSSIZE -#endif - -#define DEFAULT_MAJOR_ROOT 0 -#define DEFAULT_MINOR_ROOT 0 - -/* max nr of sectors of setup: don't change unless you also change - * bootsect etc */ -#define SETUP_SECTS 4 - -#define STRINGIFY(x) #x - -typedef union { - int i; - long l; - short s[2]; - char b[4]; -} conv; - -long intel_long(long l) -{ - conv t; - - t.b[0] = l & 0xff; l >>= 8; - t.b[1] = l & 0xff; l >>= 8; - t.b[2] = l & 0xff; l >>= 8; - t.b[3] = l & 0xff; l >>= 8; - return t.l; -} - -int intel_int(int i) -{ - conv t; - - t.b[0] = i & 0xff; i >>= 8; - t.b[1] = i & 0xff; i >>= 8; - t.b[2] = i & 0xff; i >>= 8; - t.b[3] = i & 0xff; i >>= 8; - return t.i; -} - -short intel_short(short l) -{ - conv t; - - t.b[0] = l & 0xff; l >>= 8; - t.b[1] = l & 0xff; l >>= 8; - return t.s[0]; -} - -void die(const char * str) -{ - fprintf(stderr,"%s\n",str); - exit(1); -} - -void usage(void) -{ - die("Usage: build bootsect setup system [rootdev] [> image]"); -} - -int main(int argc, char ** argv) -{ - int i,c,id,sz,tmp_int; - unsigned long sys_size, tmp_long; - char buf[1024]; -#ifndef __BFD__ - struct exec *ex = (struct exec *)buf; -#endif - char major_root, minor_root; - struct stat sb; - unsigned char setup_sectors; - - if ((argc < 4) || (argc > 5)) - usage(); - if (argc > 4) { - if (!strcmp(argv[4], "CURRENT")) { - if (stat("/", &sb)) { - perror("/"); - die("Couldn't stat /"); - } - major_root = major(sb.st_dev); - minor_root = minor(sb.st_dev); - } else if (strcmp(argv[4], "FLOPPY")) { - if (stat(argv[4], &sb)) { - perror(argv[4]); - die("Couldn't stat root device."); - } - major_root = major(sb.st_rdev); - minor_root = minor(sb.st_rdev); - } else { - major_root = 0; - minor_root = 0; - } - } else { - major_root = DEFAULT_MAJOR_ROOT; - minor_root = DEFAULT_MINOR_ROOT; - } - fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root); - for (i=0;i<sizeof buf; i++) buf[i]=0; - if ((id=open(argv[1],O_RDONLY,0))<0) - die("Unable to open 'boot'"); - if (read(id,buf,MINIX_HEADER) != MINIX_HEADER) - die("Unable to read header of 'boot'"); - if (((long *) buf)[0]!=intel_long(0x04100301)) - die("Non-Minix header of 'boot'"); - if (((long *) buf)[1]!=intel_long(MINIX_HEADER)) - die("Non-Minix header of 'boot'"); - if (((long *) buf)[3] != 0) - die("Illegal data segment in 'boot'"); - if (((long *) buf)[4] != 0) - die("Illegal bss in 'boot'"); - if (((long *) buf)[5] != 0) - die("Non-Minix header of 'boot'"); - if (((long *) buf)[7] != 0) - die("Illegal symbol table in 'boot'"); - i=read(id,buf,sizeof buf); - fprintf(stderr,"Boot sector %d bytes.\n",i); - if (i != 512) - die("Boot block must be exactly 512 bytes"); - if ((*(unsigned short *)(buf+510)) != (unsigned short)intel_short(0xAA55)) - die("Boot block hasn't got boot flag (0xAA55)"); - buf[508] = (char) minor_root; - buf[509] = (char) major_root; - i=write(1,buf,512); - if (i!=512) - die("Write call failed"); - close (id); - - if ((id=open(argv[2],O_RDONLY,0))<0) - die("Unable to open 'setup'"); - if (read(id,buf,MINIX_HEADER) != MINIX_HEADER) - die("Unable to read header of 'setup'"); - if (((long *) buf)[0]!=intel_long(0x04100301)) - die("Non-Minix header of 'setup'"); - if (((long *) buf)[1]!=intel_long(MINIX_HEADER)) - die("Non-Minix header of 'setup'"); - if (((long *) buf)[3] != 0) - die("Illegal data segment in 'setup'"); - if (((long *) buf)[4] != 0) - die("Illegal bss in 'setup'"); - if (((long *) buf)[5] != 0) - die("Non-Minix header of 'setup'"); - if (((long *) buf)[7] != 0) - die("Illegal symbol table in 'setup'"); - for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c ) -#ifdef __BIG_KERNEL__ - { - if (!i) { - /* Working with memcpy because of alignment constraints - on Sparc - Gertjan */ - memcpy(&tmp_long, &buf[2], sizeof(long)); - if (tmp_long != intel_long(0x53726448) ) - die("Wrong magic in loader header of 'setup'"); - memcpy(&tmp_int, &buf[6], sizeof(int)); - if (tmp_int < intel_int(0x200)) - die("Wrong version of loader header of 'setup'"); - buf[0x11] = 1; /* LOADED_HIGH */ - tmp_long = intel_long(0x100000); - memcpy(&buf[0x14], &tmp_long, sizeof(long)); /* code32_start */ - } -#endif - if (write(1,buf,c)!=c) - die("Write call failed"); -#ifdef __BIG_KERNEL__ - } -#endif - if (c != 0) - die("read-error on 'setup'"); - close (id); - setup_sectors = (unsigned char)((i + 511) / 512); - /* for compatibility with LILO */ - if (setup_sectors < SETUP_SECTS) - setup_sectors = SETUP_SECTS; - fprintf(stderr,"Setup is %d bytes.\n",i); - for (c=0 ; c<sizeof(buf) ; c++) - buf[c] = '\0'; - while (i < setup_sectors * 512) { - c = setup_sectors * 512 - i; - if (c > sizeof(buf)) - c = sizeof(buf); - if (write(1,buf,c) != c) - die("Write call failed"); - i += c; - } - - if ((id=open(argv[3],O_RDONLY,0))<0) - die("Unable to open 'system'"); -#ifndef __BFD__ - if (read(id,buf,GCC_HEADER) != GCC_HEADER) - die("Unable to read header of 'system'"); - if (N_MAGIC(*ex) == ZMAGIC) { - GCC_HEADER = N_MAGIC_OFFSET; - lseek(id, GCC_HEADER, SEEK_SET); - } else if (N_MAGIC(*ex) != QMAGIC) - die("Non-GCC header of 'system'"); - fprintf(stderr,"System is %d kB (%d kB code, %d kB data and %d kB bss)\n", - (ex->a_text+ex->a_data+ex->a_bss)/1024, - ex->a_text /1024, - ex->a_data /1024, - ex->a_bss /1024); - sz = N_SYMOFF(*ex) - GCC_HEADER + 4; -#else - if (fstat (id, &sb)) { - perror ("fstat"); - die ("Unable to stat 'system'"); - } - sz = sb.st_size; - fprintf (stderr, "System is %d kB\n", sz/1024); -#endif - sys_size = (sz + 15) / 16; - if (sys_size > SYS_SIZE) - die("System is too big"); - while (sz > 0) { - int l, n; - - l = sz; - if (l > sizeof(buf)) - l = sizeof(buf); - if ((n=read(id, buf, l)) != l) { - if (n == -1) - perror(argv[1]); - else - fprintf(stderr, "Unexpected EOF\n"); - die("Can't read 'system'"); - } - if (write(1, buf, l) != l) - die("Write failed"); - sz -= l; - } - close(id); - if (lseek(1, 497, 0) == 497) { - if (write(1, &setup_sectors, 1) != 1) - die("Write of setup sectors failed"); - } - if (lseek(1,500,0) == 500) { - buf[0] = (sys_size & 0xff); - buf[1] = ((sys_size >> 8) & 0xff); - if (write(1, buf, 2) != 2) - die("Write failed"); - } - return(0); -} diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig index 58f5864a668..239dab0b95c 100644 --- a/arch/cris/arch-v10/drivers/Kconfig +++ b/arch/cris/arch-v10/drivers/Kconfig @@ -2,8 +2,7 @@ if ETRAX_ARCH_V10 config ETRAX_ETHERNET bool "Ethernet support" - depends on ETRAX_ARCH_V10 - select NET_ETHERNET + depends on ETRAX_ARCH_V10 && NETDEVICES select MII help This option enables the ETRAX 100LX built-in 10/100Mbit Ethernet @@ -383,7 +382,7 @@ config ETRAX_RS485 depends on ETRAX_SERIAL help Enables support for RS-485 serial communication. For a primer on - RS-485, see <http://www.hw.cz/english/docs/rs485/rs485.html>. + RS-485, see <http://en.wikipedia.org/wiki/Rs485> config ETRAX_RS485_ON_PA bool "RS-485 mode on PA" @@ -418,16 +417,6 @@ config ETRAX_USB_HOST for CTRL and BULK traffic only, INTR traffic may work as well however (depending on the requirements of timeliness). -config ETRAX_USB_HOST_PORT1 - bool "USB port 1 enabled" - depends on ETRAX_USB_HOST - default n - -config ETRAX_USB_HOST_PORT2 - bool "USB port 2 enabled" - depends on ETRAX_USB_HOST - default n - config ETRAX_PTABLE_SECTOR int "Byte-offset of partition table sector" depends on ETRAX_AXISFLASHMAP @@ -528,19 +517,6 @@ config ETRAX_GPIO Remember that you need to setup the port directions appropriately in the General configuration. -config ETRAX_PA_BUTTON_BITMASK - hex "PA-buttons bitmask" - depends on ETRAX_GPIO - default "02" - help - This is a bitmask with information about what bits on PA that - are used for buttons. - Most products has a so called TEST button on PA1, if that's true - use 02 here. - Use 00 if there are no buttons on PA. - If the bitmask is <> 00 a button driver will be included in the gpio - driver. ETRAX general I/O support must be enabled. - config ETRAX_PA_CHANGEABLE_DIR hex "PA user changeable dir mask" depends on ETRAX_GPIO @@ -581,51 +557,4 @@ config ETRAX_PB_CHANGEABLE_BITS Bit set = changeable. You probably want 00 here. -config ETRAX_DS1302_RST_ON_GENERIC_PORT - bool "DS1302 RST on Generic Port" - depends on ETRAX_DS1302 - help - If your product has the RST signal line for the DS1302 RTC on the - Generic Port then say Y here, otherwise leave it as N in which - case the RST signal line is assumed to be connected to Port PB - (just like the SCL and SDA lines). - -config ETRAX_DS1302_RSTBIT - int "DS1302 RST bit number" - depends on ETRAX_DS1302 - default "2" - help - This is the bit number for the RST signal line of the DS1302 RTC on - the selected port. If you have selected the generic port then it - should be bit 27, otherwise your best bet is bit 5. - -config ETRAX_DS1302_SCLBIT - int "DS1302 SCL bit number" - depends on ETRAX_DS1302 - default "1" - help - This is the bit number for the SCL signal line of the DS1302 RTC on - Port PB. This is probably best left at 3. - -config ETRAX_DS1302_SDABIT - int "DS1302 SDA bit number" - depends on ETRAX_DS1302 - default "0" - help - This is the bit number for the SDA signal line of the DS1302 RTC on - Port PB. This is probably best left at 2. - -config ETRAX_DS1302_TRICKLE_CHARGE - int "DS1302 Trickle charger value" - depends on ETRAX_DS1302 - default "0" - help - This controls the initial value of the trickle charge register. - 0 = disabled (use this if you are unsure or have a non rechargeable battery) - Otherwise the following values can be OR:ed together to control the - charge current: - 1 = 2kohm, 2 = 4kohm, 3 = 4kohm - 4 = 1 diode, 8 = 2 diodes - Allowed values are (increasing current): 0, 11, 10, 9, 7, 6, 5 - endif diff --git a/arch/cris/arch-v10/drivers/Makefile b/arch/cris/arch-v10/drivers/Makefile index 44bf2e88c26..e5c13183b97 100644 --- a/arch/cris/arch-v10/drivers/Makefile +++ b/arch/cris/arch-v10/drivers/Makefile @@ -6,7 +6,5 @@ obj-$(CONFIG_ETRAX_AXISFLASHMAP) += axisflashmap.o obj-$(CONFIG_ETRAX_I2C) += i2c.o obj-$(CONFIG_ETRAX_I2C_EEPROM) += eeprom.o obj-$(CONFIG_ETRAX_GPIO) += gpio.o -obj-$(CONFIG_ETRAX_DS1302) += ds1302.o -obj-$(CONFIG_ETRAX_PCF8563) += pcf8563.o obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o diff --git a/arch/cris/arch-v10/drivers/axisflashmap.c b/arch/cris/arch-v10/drivers/axisflashmap.c index b2079703af7..a4bbdfd37bd 100644 --- a/arch/cris/arch-v10/drivers/axisflashmap.c +++ b/arch/cris/arch-v10/drivers/axisflashmap.c @@ -234,7 +234,6 @@ static struct mtd_info *flash_probe(void) } if (mtd_cse0 && mtd_cse1) { -#ifdef CONFIG_MTD_CONCAT struct mtd_info *mtds[] = { mtd_cse0, mtd_cse1 }; /* Since the concatenation layer adds a small overhead we @@ -246,11 +245,6 @@ static struct mtd_info *flash_probe(void) */ mtd_cse = mtd_concat_create(mtds, ARRAY_SIZE(mtds), "cse0+cse1"); -#else - printk(KERN_ERR "%s and %s: Cannot concatenate due to kernel " - "(mis)configuration!\n", map_cse0.name, map_cse1.name); - mtd_cse = NULL; -#endif if (!mtd_cse) { printk(KERN_ERR "%s and %s: Concatenation failed!\n", map_cse0.name, map_cse1.name); @@ -378,7 +372,7 @@ static int __init init_axis_flash(void) #ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE if (mymtd) { main_partition.size = mymtd->size; - err = add_mtd_partitions(mymtd, &main_partition, 1); + err = mtd_device_register(mymtd, &main_partition, 1); if (err) panic("axisflashmap: Could not initialize " "partition for whole main mtd device!\n"); @@ -388,10 +382,12 @@ static int __init init_axis_flash(void) if (mymtd) { if (use_default_ptable) { printk(KERN_INFO " Using default partition table.\n"); - err = add_mtd_partitions(mymtd, axis_default_partitions, - NUM_DEFAULT_PARTITIONS); + err = mtd_device_register(mymtd, + axis_default_partitions, + NUM_DEFAULT_PARTITIONS); } else { - err = add_mtd_partitions(mymtd, axis_partitions, pidx); + err = mtd_device_register(mymtd, axis_partitions, + pidx); } if (err) diff --git a/arch/cris/arch-v10/drivers/ds1302.c b/arch/cris/arch-v10/drivers/ds1302.c deleted file mode 100644 index 77630df9434..00000000000 --- a/arch/cris/arch-v10/drivers/ds1302.c +++ /dev/null @@ -1,504 +0,0 @@ -/*!*************************************************************************** -*! -*! FILE NAME : ds1302.c -*! -*! DESCRIPTION: Implements an interface for the DS1302 RTC through Etrax I/O -*! -*! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init -*! -*! --------------------------------------------------------------------------- -*! -*! (C) Copyright 1999-2007 Axis Communications AB, LUND, SWEDEN -*! -*!***************************************************************************/ - - -#include <linux/fs.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/miscdevice.h> -#include <linux/delay.h> -#include <linux/bcd.h> -#include <linux/capability.h> - -#include <asm/uaccess.h> -#include <asm/system.h> -#include <arch/svinto.h> -#include <asm/io.h> -#include <asm/rtc.h> -#include <arch/io_interface_mux.h> - -#include "i2c.h" - -#define RTC_MAJOR_NR 121 /* local major, change later */ - -static const char ds1302_name[] = "ds1302"; - -/* The DS1302 might be connected to different bits on different products. - * It has three signals - SDA, SCL and RST. RST and SCL are always outputs, - * but SDA can have a selected direction. - * For now, only PORT_PB is hardcoded. - */ - -/* The RST bit may be on either the Generic Port or Port PB. */ -#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT -#define TK_RST_OUT(x) REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, CONFIG_ETRAX_DS1302_RSTBIT, x) -#define TK_RST_DIR(x) -#else -#define TK_RST_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_RSTBIT, x) -#define TK_RST_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, CONFIG_ETRAX_DS1302_RSTBIT, x) -#endif - - -#define TK_SDA_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_SDABIT, x) -#define TK_SCL_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_SCLBIT, x) - -#define TK_SDA_IN() ((*R_PORT_PB_READ >> CONFIG_ETRAX_DS1302_SDABIT) & 1) -/* 1 is out, 0 is in */ -#define TK_SDA_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, CONFIG_ETRAX_DS1302_SDABIT, x) -#define TK_SCL_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, CONFIG_ETRAX_DS1302_SCLBIT, x) - - -/* - * The reason for tempudelay and not udelay is that loops_per_usec - * (used in udelay) is not set when functions here are called from time.c - */ - -static void tempudelay(int usecs) -{ - volatile int loops; - - for(loops = usecs * 12; loops > 0; loops--) - /* nothing */; -} - - -/* Send 8 bits. */ -static void -out_byte(unsigned char x) -{ - int i; - TK_SDA_DIR(1); - for (i = 8; i--;) { - /* The chip latches incoming bits on the rising edge of SCL. */ - TK_SCL_OUT(0); - TK_SDA_OUT(x & 1); - tempudelay(1); - TK_SCL_OUT(1); - tempudelay(1); - x >>= 1; - } - TK_SDA_DIR(0); -} - -static unsigned char -in_byte(void) -{ - unsigned char x = 0; - int i; - - /* Read byte. Bits come LSB first, on the falling edge of SCL. - * Assume SDA is in input direction already. - */ - TK_SDA_DIR(0); - - for (i = 8; i--;) { - TK_SCL_OUT(0); - tempudelay(1); - x >>= 1; - x |= (TK_SDA_IN() << 7); - TK_SCL_OUT(1); - tempudelay(1); - } - - return x; -} - -/* Prepares for a transaction by de-activating RST (active-low). */ - -static void -start(void) -{ - TK_SCL_OUT(0); - tempudelay(1); - TK_RST_OUT(0); - tempudelay(5); - TK_RST_OUT(1); -} - -/* Ends a transaction by taking RST active again. */ - -static void -stop(void) -{ - tempudelay(2); - TK_RST_OUT(0); -} - -/* Enable writing. */ - -static void -ds1302_wenable(void) -{ - start(); - out_byte(0x8e); /* Write control register */ - out_byte(0x00); /* Disable write protect bit 7 = 0 */ - stop(); -} - -/* Disable writing. */ - -static void -ds1302_wdisable(void) -{ - start(); - out_byte(0x8e); /* Write control register */ - out_byte(0x80); /* Disable write protect bit 7 = 0 */ - stop(); -} - - - -/* Read a byte from the selected register in the DS1302. */ - -unsigned char -ds1302_readreg(int reg) -{ - unsigned char x; - - start(); - out_byte(0x81 | (reg << 1)); /* read register */ - x = in_byte(); - stop(); - - return x; -} - -/* Write a byte to the selected register. */ - -void -ds1302_writereg(int reg, unsigned char val) -{ -#ifndef CONFIG_ETRAX_RTC_READONLY - int do_writereg = 1; -#else - int do_writereg = 0; - - if (reg == RTC_TRICKLECHARGER) - do_writereg = 1; -#endif - - if (do_writereg) { - ds1302_wenable(); - start(); - out_byte(0x80 | (reg << 1)); /* write register */ - out_byte(val); - stop(); - ds1302_wdisable(); - } -} - -void -get_rtc_time(struct rtc_time *rtc_tm) -{ - unsigned long flags; - - local_irq_save(flags); - - rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); - rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); - rtc_tm->tm_hour = CMOS_READ(RTC_HOURS); - rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH); - rtc_tm->tm_mon = CMOS_READ(RTC_MONTH); - rtc_tm->tm_year = CMOS_READ(RTC_YEAR); - - local_irq_restore(flags); - - rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); - rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min); - rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour); - rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday); - rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon); - rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); - - /* - * Account for differences between how the RTC uses the values - * and how they are defined in a struct rtc_time; - */ - - if (rtc_tm->tm_year <= 69) - rtc_tm->tm_year += 100; - - rtc_tm->tm_mon--; -} - -static unsigned char days_in_mo[] = - {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - -/* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date). */ - -static int -rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) -{ - unsigned long flags; - - switch(cmd) { - case RTC_RD_TIME: /* read the time/date from RTC */ - { - struct rtc_time rtc_tm; - - memset(&rtc_tm, 0, sizeof (struct rtc_time)); - get_rtc_time(&rtc_tm); - if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time))) - return -EFAULT; - return 0; - } - - case RTC_SET_TIME: /* set the RTC */ - { - struct rtc_time rtc_tm; - unsigned char mon, day, hrs, min, sec, leap_yr; - unsigned int yrs; - - if (!capable(CAP_SYS_TIME)) - return -EPERM; - - if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time))) - return -EFAULT; - - yrs = rtc_tm.tm_year + 1900; - mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ - day = rtc_tm.tm_mday; - hrs = rtc_tm.tm_hour; - min = rtc_tm.tm_min; - sec = rtc_tm.tm_sec; - - - if ((yrs < 1970) || (yrs > 2069)) - return -EINVAL; - - leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); - - if ((mon > 12) || (day == 0)) - return -EINVAL; - - if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) - return -EINVAL; - - if ((hrs >= 24) || (min >= 60) || (sec >= 60)) - return -EINVAL; - - if (yrs >= 2000) - yrs -= 2000; /* RTC (0, 1, ... 69) */ - else - yrs -= 1900; /* RTC (70, 71, ... 99) */ - - sec = bin2bcd(sec); - min = bin2bcd(min); - hrs = bin2bcd(hrs); - day = bin2bcd(day); - mon = bin2bcd(mon); - yrs = bin2bcd(yrs); - - local_irq_save(flags); - CMOS_WRITE(yrs, RTC_YEAR); - CMOS_WRITE(mon, RTC_MONTH); - CMOS_WRITE(day, RTC_DAY_OF_MONTH); - CMOS_WRITE(hrs, RTC_HOURS); - CMOS_WRITE(min, RTC_MINUTES); - CMOS_WRITE(sec, RTC_SECONDS); - local_irq_restore(flags); - - /* Notice that at this point, the RTC is updated but - * the kernel is still running with the old time. - * You need to set that separately with settimeofday - * or adjtimex. - */ - return 0; - } - - case RTC_SET_CHARGE: /* set the RTC TRICKLE CHARGE register */ - { - int tcs_val; - - if (!capable(CAP_SYS_TIME)) - return -EPERM; - - if(copy_from_user(&tcs_val, (int*)arg, sizeof(int))) - return -EFAULT; - - tcs_val = RTC_TCR_PATTERN | (tcs_val & 0x0F); - ds1302_writereg(RTC_TRICKLECHARGER, tcs_val); - return 0; - } - case RTC_VL_READ: - { - /* TODO: - * Implement voltage low detection support - */ - printk(KERN_WARNING "DS1302: RTC Voltage Low detection" - " is not supported\n"); - return 0; - } - case RTC_VL_CLR: - { - /* TODO: - * Nothing to do since Voltage Low detection is not supported - */ - return 0; - } - default: - return -ENOIOCTLCMD; - } -} - -static void -print_rtc_status(void) -{ - struct rtc_time tm; - - get_rtc_time(&tm); - - /* - * There is no way to tell if the luser has the RTC set for local - * time or for Universal Standard Time (GMT). Probably local though. - */ - - printk(KERN_INFO "rtc_time\t: %02d:%02d:%02d\n", - tm.tm_hour, tm.tm_min, tm.tm_sec); - printk(KERN_INFO "rtc_date\t: %04d-%02d-%02d\n", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); -} - -/* The various file operations we support. */ - -static const struct file_operations rtc_fops = { - .owner = THIS_MODULE, - .ioctl = rtc_ioctl, -}; - -/* Probe for the chip by writing something to its RAM and try reading it back. */ - -#define MAGIC_PATTERN 0x42 - -static int __init -ds1302_probe(void) -{ - int retval, res; - - TK_RST_DIR(1); - TK_SCL_DIR(1); - TK_SDA_DIR(0); - - /* Try to talk to timekeeper. */ - - ds1302_wenable(); - start(); - out_byte(0xc0); /* write RAM byte 0 */ - out_byte(MAGIC_PATTERN); /* write something magic */ - start(); - out_byte(0xc1); /* read RAM byte 0 */ - - if((res = in_byte()) == MAGIC_PATTERN) { - stop(); - ds1302_wdisable(); - printk(KERN_INFO "%s: RTC found.\n", ds1302_name); - printk(KERN_INFO "%s: SDA, SCL, RST on PB%i, PB%i, %s%i\n", - ds1302_name, - CONFIG_ETRAX_DS1302_SDABIT, - CONFIG_ETRAX_DS1302_SCLBIT, -#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT - "GENIO", -#else - "PB", -#endif - CONFIG_ETRAX_DS1302_RSTBIT); - print_rtc_status(); - retval = 1; - } else { - stop(); - retval = 0; - } - - return retval; -} - - -/* Just probe for the RTC and register the device to handle the ioctl needed. */ - -int __init -ds1302_init(void) -{ -#ifdef CONFIG_ETRAX_I2C - i2c_init(); -#endif - - if (!ds1302_probe()) { -#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT -#if CONFIG_ETRAX_DS1302_RSTBIT == 27 - /* - * The only way to set g27 to output is to enable ATA. - * - * Make sure that R_GEN_CONFIG is setup correct. - */ - /* Allocating the ATA interface will grab almost all - * pins in I/O groups a, b, c and d. A consequence of - * allocating the ATA interface is that the fixed - * interfaces shared RAM, parallel port 0, parallel - * port 1, parallel port W, SCSI-8 port 0, SCSI-8 port - * 1, SCSI-W, serial port 2, serial port 3, - * synchronous serial port 3 and USB port 2 and almost - * all GPIO pins on port g cannot be used. - */ - if (cris_request_io_interface(if_ata, "ds1302/ATA")) { - printk(KERN_WARNING "ds1302: Failed to get IO interface\n"); - return -1; - } - -#elif CONFIG_ETRAX_DS1302_RSTBIT == 0 - if (cris_io_interface_allocate_pins(if_gpio_grp_a, - 'g', - CONFIG_ETRAX_DS1302_RSTBIT, - CONFIG_ETRAX_DS1302_RSTBIT)) { - printk(KERN_WARNING "ds1302: Failed to get IO interface\n"); - return -1; - } - - /* Set the direction of this bit to out. */ - genconfig_shadow = ((genconfig_shadow & - ~IO_MASK(R_GEN_CONFIG, g0dir)) | - (IO_STATE(R_GEN_CONFIG, g0dir, out))); - *R_GEN_CONFIG = genconfig_shadow; -#endif - if (!ds1302_probe()) { - printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name); - return -1; - } -#else - printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name); - return -1; -#endif - } - /* Initialise trickle charger */ - ds1302_writereg(RTC_TRICKLECHARGER, - RTC_TCR_PATTERN |(CONFIG_ETRAX_DS1302_TRICKLE_CHARGE & 0x0F)); - /* Start clock by resetting CLOCK_HALT */ - ds1302_writereg(RTC_SECONDS, (ds1302_readreg(RTC_SECONDS) & 0x7F)); - return 0; -} - -static int __init ds1302_register(void) -{ - ds1302_init(); - if (register_chrdev(RTC_MAJOR_NR, ds1302_name, &rtc_fops)) { - printk(KERN_INFO "%s: unable to get major %d for rtc\n", - ds1302_name, RTC_MAJOR_NR); - return -1; - } - return 0; - -} - -module_init(ds1302_register); diff --git a/arch/cris/arch-v10/drivers/eeprom.c b/arch/cris/arch-v10/drivers/eeprom.c index 1f2ae909d3e..5047a33043b 100644 --- a/arch/cris/arch-v10/drivers/eeprom.c +++ b/arch/cris/arch-v10/drivers/eeprom.c @@ -28,7 +28,6 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/interrupt.h> -#include <linux/smp_lock.h> #include <linux/wait.h> #include <asm/uaccess.h> #include "i2c.h" @@ -73,8 +72,7 @@ struct eeprom_type int adapt_state; /* 1 = To high , 0 = Even, -1 = To low */ /* this one is to keep the read/write operations atomic */ - wait_queue_head_t wait_q; - volatile int busy; + struct mutex lock; int retry_cnt_addr; /* Used to keep track of number of retries for adaptive timing adjustments */ int retry_cnt_read; @@ -115,8 +113,7 @@ const struct file_operations eeprom_fops = int __init eeprom_init(void) { - init_waitqueue_head(&eeprom.wait_q); - eeprom.busy = 0; + mutex_init(&eeprom.lock); #ifdef CONFIG_ETRAX_I2C_EEPROM_PROBE #define EETEXT "Found" @@ -378,7 +375,6 @@ int __init eeprom_init(void) /* Opens the device. */ static int eeprom_open(struct inode * inode, struct file * file) { - cycle_kernel_lock(); if(iminor(inode) != EEPROM_MINOR_NR) return -ENXIO; if(imajor(inode) != EEPROM_MAJOR_NR) @@ -439,10 +435,7 @@ static loff_t eeprom_lseek(struct file * file, loff_t offset, int orig) static int eeprom_read_buf(loff_t addr, char * buf, int count) { - struct file f; - - f.f_pos = addr; - return eeprom_read(&f, buf, count, &addr); + return eeprom_read(NULL, buf, count, &addr); } @@ -452,7 +445,7 @@ static int eeprom_read_buf(loff_t addr, char * buf, int count) static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t *off) { int read=0; - unsigned long p = file->f_pos; + unsigned long p = *off; unsigned char page; @@ -461,12 +454,9 @@ static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t return -EFAULT; } - wait_event_interruptible(eeprom.wait_q, !eeprom.busy); - if (signal_pending(current)) + if (mutex_lock_interruptible(&eeprom.lock)) return -EINTR; - eeprom.busy++; - page = (unsigned char) (p >> 8); if(!eeprom_address(p)) @@ -476,8 +466,7 @@ static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t i2c_stop(); /* don't forget to wake them up */ - eeprom.busy--; - wake_up_interruptible(&eeprom.wait_q); + mutex_unlock(&eeprom.lock); return -EFAULT; } @@ -501,11 +490,10 @@ static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t if(read > 0) { - file->f_pos += read; + *off += read; } - eeprom.busy--; - wake_up_interruptible(&eeprom.wait_q); + mutex_unlock(&eeprom.lock); return read; } @@ -513,11 +501,7 @@ static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t static int eeprom_write_buf(loff_t addr, const char * buf, int count) { - struct file f; - - f.f_pos = addr; - - return eeprom_write(&f, buf, count, &addr); + return eeprom_write(NULL, buf, count, &addr); } @@ -534,16 +518,14 @@ static ssize_t eeprom_write(struct file * file, const char * buf, size_t count, return -EFAULT; } - wait_event_interruptible(eeprom.wait_q, !eeprom.busy); /* bail out if we get interrupted */ - if (signal_pending(current)) + if (mutex_lock_interruptible(&eeprom.lock)) return -EINTR; - eeprom.busy++; for(i = 0; (i < EEPROM_RETRIES) && (restart > 0); i++) { restart = 0; written = 0; - p = file->f_pos; + p = *off; while( (written < count) && (p < eeprom.size)) @@ -556,8 +538,7 @@ static ssize_t eeprom_write(struct file * file, const char * buf, size_t count, i2c_stop(); /* don't forget to wake them up */ - eeprom.busy--; - wake_up_interruptible(&eeprom.wait_q); + mutex_unlock(&eeprom.lock); return -EFAULT; } #ifdef EEPROM_ADAPTIVE_TIMING @@ -669,12 +650,11 @@ static ssize_t eeprom_write(struct file * file, const char * buf, size_t count, } /* while */ } /* for */ - eeprom.busy--; - wake_up_interruptible(&eeprom.wait_q); - if (written == 0 && file->f_pos >= eeprom.size){ + mutex_unlock(&eeprom.lock); + if (written == 0 && p >= eeprom.size){ return -ENOSPC; } - file->f_pos += written; + *off = p; return written; } diff --git a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c index 4b0f65fac8e..64285e0d348 100644 --- a/arch/cris/arch-v10/drivers/gpio.c +++ b/arch/cris/arch-v10/drivers/gpio.c @@ -16,7 +16,6 @@ #include <linux/errno.h> #include <linux/kernel.h> #include <linux/fs.h> -#include <linux/smp_lock.h> #include <linux/string.h> #include <linux/poll.h> #include <linux/init.h> @@ -25,7 +24,6 @@ #include <asm/etraxgpio.h> #include <arch/svinto.h> #include <asm/io.h> -#include <asm/system.h> #include <asm/irq.h> #include <arch/io_interface_mux.h> @@ -46,8 +44,7 @@ static char gpio_name[] = "etrax gpio"; static wait_queue_head_t *gpio_wq; #endif -static int gpio_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); +static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static ssize_t gpio_write(struct file *file, const char __user *buf, size_t count, loff_t *off); static int gpio_open(struct inode *inode, struct file *filp); @@ -324,7 +321,6 @@ gpio_open(struct inode *inode, struct file *filp) if (!priv) return -ENOMEM; - lock_kernel(); priv->minor = p; /* initialize the io/alarm struct */ @@ -359,7 +355,6 @@ gpio_open(struct inode *inode, struct file *filp) alarmlist = priv; spin_unlock_irqrestore(&gpio_lock, flags); - unlock_kernel(); return 0; } @@ -504,9 +499,7 @@ unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg) static int gpio_leds_ioctl(unsigned int cmd, unsigned long arg); -static int -gpio_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { unsigned long flags; unsigned long val; @@ -516,54 +509,65 @@ gpio_ioctl(struct inode *inode, struct file *file, if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) return -EINVAL; - spin_lock_irqsave(&gpio_lock, flags); - switch (_IOC_NR(cmd)) { case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */ // read the port + spin_lock_irqsave(&gpio_lock, flags); if (USE_PORTS(priv)) { ret = *priv->port; } else if (priv->minor == GPIO_MINOR_G) { ret = (*R_PORT_G_DATA) & 0x7FFFFFFF; } + spin_unlock_irqrestore(&gpio_lock, flags); + break; case IO_SETBITS: // set changeable bits with a 1 in arg + spin_lock_irqsave(&gpio_lock, flags); + if (USE_PORTS(priv)) { - *priv->port = *priv->shadow |= + *priv->port = *priv->shadow |= ((unsigned char)arg & priv->changeable_bits); } else if (priv->minor == GPIO_MINOR_G) { *R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits); } + spin_unlock_irqrestore(&gpio_lock, flags); + break; case IO_CLRBITS: // clear changeable bits with a 1 in arg + spin_lock_irqsave(&gpio_lock, flags); if (USE_PORTS(priv)) { - *priv->port = *priv->shadow &= + *priv->port = *priv->shadow &= ~((unsigned char)arg & priv->changeable_bits); } else if (priv->minor == GPIO_MINOR_G) { *R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits); } + spin_unlock_irqrestore(&gpio_lock, flags); break; case IO_HIGHALARM: // set alarm when bits with 1 in arg go high + spin_lock_irqsave(&gpio_lock, flags); priv->highalarm |= arg; gpio_some_alarms = 1; + spin_unlock_irqrestore(&gpio_lock, flags); break; case IO_LOWALARM: // set alarm when bits with 1 in arg go low + spin_lock_irqsave(&gpio_lock, flags); priv->lowalarm |= arg; gpio_some_alarms = 1; + spin_unlock_irqrestore(&gpio_lock, flags); break; case IO_CLRALARM: - // clear alarm for bits with 1 in arg + /* clear alarm for bits with 1 in arg */ + spin_lock_irqsave(&gpio_lock, flags); priv->highalarm &= ~arg; priv->lowalarm &= ~arg; { /* Must update gpio_some_alarms */ struct gpio_private *p = alarmlist; int some_alarms; - spin_lock_irq(&gpio_lock); p = alarmlist; some_alarms = 0; while (p) { @@ -574,11 +578,12 @@ gpio_ioctl(struct inode *inode, struct file *file, p = p->next; } gpio_some_alarms = some_alarms; - spin_unlock_irq(&gpio_lock); } + spin_unlock_irqrestore(&gpio_lock, flags); break; case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */ /* Read direction 0=input 1=output */ + spin_lock_irqsave(&gpio_lock, flags); if (USE_PORTS(priv)) { ret = *priv->dir_shadow; } else if (priv->minor == GPIO_MINOR_G) { @@ -587,30 +592,40 @@ gpio_ioctl(struct inode *inode, struct file *file, */ ret = (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF; } + spin_unlock_irqrestore(&gpio_lock, flags); break; case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */ - /* Set direction 0=unchanged 1=input, - * return mask with 1=input + /* Set direction 0=unchanged 1=input, + * return mask with 1=input */ + spin_lock_irqsave(&gpio_lock, flags); ret = setget_input(priv, arg) & 0x7FFFFFFF; + spin_unlock_irqrestore(&gpio_lock, flags); break; case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */ - /* Set direction 0=unchanged 1=output, - * return mask with 1=output + /* Set direction 0=unchanged 1=output, + * return mask with 1=output */ + spin_lock_irqsave(&gpio_lock, flags); ret = setget_output(priv, arg) & 0x7FFFFFFF; + spin_unlock_irqrestore(&gpio_lock, flags); break; case IO_SHUTDOWN: + spin_lock_irqsave(&gpio_lock, flags); SOFT_SHUTDOWN(); + spin_unlock_irqrestore(&gpio_lock, flags); break; case IO_GET_PWR_BT: + spin_lock_irqsave(&gpio_lock, flags); #if defined (CONFIG_ETRAX_SOFT_SHUTDOWN) ret = (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT)); #else ret = 0; #endif + spin_unlock_irqrestore(&gpio_lock, flags); break; case IO_CFG_WRITE_MODE: + spin_lock_irqsave(&gpio_lock, flags); priv->clk_mask = arg & 0xFF; priv->data_mask = (arg >> 8) & 0xFF; priv->write_msb = (arg >> 16) & 0x01; @@ -626,28 +641,33 @@ gpio_ioctl(struct inode *inode, struct file *file, priv->data_mask = 0; ret = -EPERM; } + spin_unlock_irqrestore(&gpio_lock, flags); break; - case IO_READ_INBITS: + case IO_READ_INBITS: /* *arg is result of reading the input pins */ + spin_lock_irqsave(&gpio_lock, flags); if (USE_PORTS(priv)) { val = *priv->port; } else if (priv->minor == GPIO_MINOR_G) { val = *R_PORT_G_DATA; } + spin_unlock_irqrestore(&gpio_lock, flags); if (copy_to_user((void __user *)arg, &val, sizeof(val))) ret = -EFAULT; break; case IO_READ_OUTBITS: /* *arg is result of reading the output shadow */ + spin_lock_irqsave(&gpio_lock, flags); if (USE_PORTS(priv)) { val = *priv->shadow; } else if (priv->minor == GPIO_MINOR_G) { val = port_g_data_shadow; } + spin_unlock_irqrestore(&gpio_lock, flags); if (copy_to_user((void __user *)arg, &val, sizeof(val))) ret = -EFAULT; break; - case IO_SETGET_INPUT: + case IO_SETGET_INPUT: /* bits set in *arg is set to input, * *arg updated with current input pins. */ @@ -656,7 +676,9 @@ gpio_ioctl(struct inode *inode, struct file *file, ret = -EFAULT; break; } + spin_lock_irqsave(&gpio_lock, flags); val = setget_input(priv, val); + spin_unlock_irqrestore(&gpio_lock, flags); if (copy_to_user((void __user *)arg, &val, sizeof(val))) ret = -EFAULT; break; @@ -668,18 +690,21 @@ gpio_ioctl(struct inode *inode, struct file *file, ret = -EFAULT; break; } + spin_lock_irqsave(&gpio_lock, flags); val = setget_output(priv, val); + spin_unlock_irqrestore(&gpio_lock, flags); if (copy_to_user((void __user *)arg, &val, sizeof(val))) ret = -EFAULT; break; default: + spin_lock_irqsave(&gpio_lock, flags); if (priv->minor == GPIO_MINOR_LEDS) ret = gpio_leds_ioctl(cmd, arg); else ret = -EINVAL; + spin_unlock_irqrestore(&gpio_lock, flags); } /* switch */ - spin_unlock_irqrestore(&gpio_lock, flags); return ret; } @@ -713,12 +738,13 @@ gpio_leds_ioctl(unsigned int cmd, unsigned long arg) } static const struct file_operations gpio_fops = { - .owner = THIS_MODULE, - .poll = gpio_poll, - .ioctl = gpio_ioctl, - .write = gpio_write, - .open = gpio_open, - .release = gpio_release, + .owner = THIS_MODULE, + .poll = gpio_poll, + .unlocked_ioctl = gpio_ioctl, + .write = gpio_write, + .open = gpio_open, + .release = gpio_release, + .llseek = noop_llseek, }; static void ioif_watcher(const unsigned int gpio_in_available, @@ -807,18 +833,18 @@ static int __init gpio_init(void) printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001-2008 " "Axis Communications AB\n"); /* We call etrax_gpio_wake_up_check() from timer interrupt and - * from cpu_idle() in kernel/process.c - * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms + * from default_idle() in kernel/process.c + * The check in default_idle() reduces latency from ~15 ms to ~6 ms * in some tests. */ res = request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt, - IRQF_SHARED | IRQF_DISABLED, "gpio poll", gpio_name); + IRQF_SHARED, "gpio poll", gpio_name); if (res) { printk(KERN_CRIT "err: timer0 irq for gpio\n"); return res; } res = request_irq(PA_IRQ_NBR, gpio_interrupt, - IRQF_SHARED | IRQF_DISABLED, "gpio PA", gpio_name); + IRQF_SHARED, "gpio PA", gpio_name); if (res) printk(KERN_CRIT "err: PA irq for gpio\n"); diff --git a/arch/cris/arch-v10/drivers/i2c.c b/arch/cris/arch-v10/drivers/i2c.c index 7f656ae0b21..b3d1f9ed1b9 100644 --- a/arch/cris/arch-v10/drivers/i2c.c +++ b/arch/cris/arch-v10/drivers/i2c.c @@ -14,8 +14,6 @@ #include <linux/module.h> #include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> #include <linux/errno.h> #include <linux/kernel.h> #include <linux/fs.h> @@ -24,7 +22,6 @@ #include <asm/etraxi2c.h> -#include <asm/system.h> #include <arch/svinto.h> #include <asm/io.h> #include <asm/delay.h> @@ -61,8 +58,8 @@ static const char i2c_name[] = "i2c"; #define SDABIT CONFIG_ETRAX_I2C_DATA_PORT #define SCLBIT CONFIG_ETRAX_I2C_CLK_PORT -#define i2c_enable() -#define i2c_disable() +#define i2c_enable() +#define i2c_disable() /* enable or disable output-enable, to select output or input on the i2c bus */ @@ -92,7 +89,7 @@ static const char i2c_name[] = "i2c"; #define i2c_dir_out() \ *R_PORT_PB_I2C = (port_pb_i2c_shadow &= ~IO_MASK(R_PORT_PB_I2C, i2c_oe_)); \ - REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, 0, 1); + REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, 0, 1); #define i2c_dir_in() \ *R_PORT_PB_I2C = (port_pb_i2c_shadow |= IO_MASK(R_PORT_PB_I2C, i2c_oe_)); \ REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, 0, 0); @@ -190,7 +187,7 @@ i2c_outbyte(unsigned char x) } else { i2c_data(I2C_DATA_LOW); } - + i2c_delay(CLOCK_LOW_TIME/2); i2c_clk(I2C_CLOCK_HIGH); i2c_delay(CLOCK_HIGH_TIME); @@ -417,7 +414,7 @@ i2c_sendnack(void) *# *#--------------------------------------------------------------------------*/ int -i2c_writereg(unsigned char theSlave, unsigned char theReg, +i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue) { int error, cntr = 3; @@ -469,7 +466,7 @@ i2c_writereg(unsigned char theSlave, unsigned char theReg, * enable interrupt again */ local_irq_restore(flags); - + } while(error && cntr--); i2c_delay(CLOCK_LOW_TIME); @@ -505,7 +502,7 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg) * generate start condition */ i2c_start(); - + /* * send slave address */ @@ -556,7 +553,7 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg) * enable interrupt again */ local_irq_restore(flags); - + } while(error && cntr--); spin_unlock(&i2c_lock); @@ -567,7 +564,6 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg) static int i2c_open(struct inode *inode, struct file *filp) { - cycle_kernel_lock(); return 0; } @@ -580,9 +576,7 @@ i2c_release(struct inode *inode, struct file *filp) /* Main device API. ioctl's to write or read to/from i2c registers. */ -static int -i2c_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long i2c_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) { return -EINVAL; @@ -591,7 +585,7 @@ i2c_ioctl(struct inode *inode, struct file *file, switch (_IOC_NR(cmd)) { case I2C_WRITEREG: /* write to an i2c slave */ - D(printk("i2cw %d %d %d\n", + D(printk(KERN_DEBUG "i2cw %d %d %d\n", I2C_ARGSLAVE(arg), I2C_ARGREG(arg), I2C_ARGVALUE(arg))); @@ -603,26 +597,26 @@ i2c_ioctl(struct inode *inode, struct file *file, { unsigned char val; /* read from an i2c slave */ - D(printk("i2cr %d %d ", + D(printk(KERN_DEBUG "i2cr %d %d ", I2C_ARGSLAVE(arg), I2C_ARGREG(arg))); val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg)); - D(printk("= %d\n", val)); + D(printk(KERN_DEBUG "= %d\n", val)); return val; - } + } default: return -EINVAL; } - return 0; } static const struct file_operations i2c_fops = { - .owner = THIS_MODULE, - .ioctl = i2c_ioctl, - .open = i2c_open, - .release = i2c_release, + .owner = THIS_MODULE, + .unlocked_ioctl = i2c_ioctl, + .open = i2c_open, + .release = i2c_release, + .llseek = noop_llseek, }; int __init diff --git a/arch/cris/arch-v10/drivers/i2c.h b/arch/cris/arch-v10/drivers/i2c.h index 4ee91426bd4..e36c9627647 100644 --- a/arch/cris/arch-v10/drivers/i2c.h +++ b/arch/cris/arch-v10/drivers/i2c.h @@ -1,5 +1,4 @@ -/* $Id: i2c.h,v 1.3 2004/05/28 09:26:59 starvik Exp $ */ - +/* i2c.h */ int i2c_init(void); /* High level I2C actions */ diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c deleted file mode 100644 index 1e90c1a9c84..00000000000 --- a/arch/cris/arch-v10/drivers/pcf8563.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * PCF8563 RTC - * - * From Phillips' datasheet: - * - * The PCF8563 is a CMOS real-time clock/calendar optimized for low power - * consumption. A programmable clock output, interrupt output and voltage - * low detector are also provided. All address and data are transferred - * serially via two-line bidirectional I2C-bus. Maximum bus speed is - * 400 kbits/s. The built-in word address register is incremented - * automatically after each written or read byte. - * - * Copyright (c) 2002-2007, Axis Communications AB - * All rights reserved. - * - * Author: Tobias Anderberg <tobiasa@axis.com>. - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/sched.h> -#include <linux/init.h> -#include <linux/fs.h> -#include <linux/ioctl.h> -#include <linux/delay.h> -#include <linux/bcd.h> -#include <linux/mutex.h> - -#include <asm/uaccess.h> -#include <asm/system.h> -#include <asm/io.h> -#include <asm/rtc.h> - -#include "i2c.h" - -#define PCF8563_MAJOR 121 /* Local major number. */ -#define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */ -#define PCF8563_NAME "PCF8563" -#define DRIVER_VERSION "$Revision: 1.24 $" - -/* I2C bus slave registers. */ -#define RTC_I2C_READ 0xa3 -#define RTC_I2C_WRITE 0xa2 - -/* Two simple wrapper macros, saves a few keystrokes. */ -#define rtc_read(x) i2c_readreg(RTC_I2C_READ, x) -#define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y) - -static DEFINE_MUTEX(rtc_lock); /* Protect state etc */ - -static const unsigned char days_in_month[] = - { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - -int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long); - -/* Cache VL bit value read at driver init since writing the RTC_SECOND - * register clears the VL status. - */ -static int voltage_low; - -static const struct file_operations pcf8563_fops = { - .owner = THIS_MODULE, - .ioctl = pcf8563_ioctl, -}; - -unsigned char -pcf8563_readreg(int reg) -{ - unsigned char res = rtc_read(reg); - - /* The PCF8563 does not return 0 for unimplemented bits. */ - switch (reg) { - case RTC_SECONDS: - case RTC_MINUTES: - res &= 0x7F; - break; - case RTC_HOURS: - case RTC_DAY_OF_MONTH: - res &= 0x3F; - break; - case RTC_WEEKDAY: - res &= 0x07; - break; - case RTC_MONTH: - res &= 0x1F; - break; - case RTC_CONTROL1: - res &= 0xA8; - break; - case RTC_CONTROL2: - res &= 0x1F; - break; - case RTC_CLOCKOUT_FREQ: - case RTC_TIMER_CONTROL: - res &= 0x83; - break; - } - return res; -} - -void -pcf8563_writereg(int reg, unsigned char val) -{ - rtc_write(reg, val); -} - -void -get_rtc_time(struct rtc_time *tm) -{ - tm->tm_sec = rtc_read(RTC_SECONDS); - tm->tm_min = rtc_read(RTC_MINUTES); - tm->tm_hour = rtc_read(RTC_HOURS); - tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH); - tm->tm_wday = rtc_read(RTC_WEEKDAY); - tm->tm_mon = rtc_read(RTC_MONTH); - tm->tm_year = rtc_read(RTC_YEAR); - - if (tm->tm_sec & 0x80) { - printk(KERN_ERR "%s: RTC Voltage Low - reliable date/time " - "information is no longer guaranteed!\n", PCF8563_NAME); - } - - tm->tm_year = bcd2bin(tm->tm_year) + - ((tm->tm_mon & 0x80) ? 100 : 0); - tm->tm_sec &= 0x7F; - tm->tm_min &= 0x7F; - tm->tm_hour &= 0x3F; - tm->tm_mday &= 0x3F; - tm->tm_wday &= 0x07; /* Not coded in BCD. */ - tm->tm_mon &= 0x1F; - - tm->tm_sec = bcd2bin(tm->tm_sec); - tm->tm_min = bcd2bin(tm->tm_min); - tm->tm_hour = bcd2bin(tm->tm_hour); - tm->tm_mday = bcd2bin(tm->tm_mday); - tm->tm_mon = bcd2bin(tm->tm_mon); - tm->tm_mon--; /* Month is 1..12 in RTC but 0..11 in linux */ -} - -int __init -pcf8563_init(void) -{ - static int res; - static int first = 1; - - if (!first) - return res; - first = 0; - - /* Initiate the i2c protocol. */ - res = i2c_init(); - if (res < 0) { - printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n"); - return res; - } - - /* - * First of all we need to reset the chip. This is done by - * clearing control1, control2 and clk freq and resetting - * all alarms. - */ - if (rtc_write(RTC_CONTROL1, 0x00) < 0) - goto err; - - if (rtc_write(RTC_CONTROL2, 0x00) < 0) - goto err; - - if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0) - goto err; - - if (rtc_write(RTC_TIMER_CONTROL, 0x03) < 0) - goto err; - - /* Reset the alarms. */ - if (rtc_write(RTC_MINUTE_ALARM, 0x80) < 0) - goto err; - - if (rtc_write(RTC_HOUR_ALARM, 0x80) < 0) - goto err; - - if (rtc_write(RTC_DAY_ALARM, 0x80) < 0) - goto err; - - if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0) - goto err; - - /* Check for low voltage, and warn about it. */ - if (rtc_read(RTC_SECONDS) & 0x80) { - voltage_low = 1; - printk(KERN_WARNING "%s: RTC Voltage Low - reliable " - "date/time information is no longer guaranteed!\n", - PCF8563_NAME); - } - - return res; - -err: - printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME); - res = -1; - return res; -} - -void __exit -pcf8563_exit(void) -{ - unregister_chrdev(PCF8563_MAJOR, DEVICE_NAME); -} - -/* - * ioctl calls for this driver. Why return -ENOTTY upon error? Because - * POSIX says so! - */ -int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - /* Some sanity checks. */ - if (_IOC_TYPE(cmd) != RTC_MAGIC) - return -ENOTTY; - - if (_IOC_NR(cmd) > RTC_MAX_IOCTL) - return -ENOTTY; - - switch (cmd) { - case RTC_RD_TIME: - { - struct rtc_time tm; - - mutex_lock(&rtc_lock); - memset(&tm, 0, sizeof tm); - get_rtc_time(&tm); - - if (copy_to_user((struct rtc_time *) arg, &tm, - sizeof tm)) { - mutex_unlock(&rtc_lock); - return -EFAULT; - } - - mutex_unlock(&rtc_lock); - - return 0; - } - case RTC_SET_TIME: - { - int leap; - int year; - int century; - struct rtc_time tm; - - memset(&tm, 0, sizeof tm); - if (!capable(CAP_SYS_TIME)) - return -EPERM; - - if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof tm)) - return -EFAULT; - - /* Convert from struct tm to struct rtc_time. */ - tm.tm_year += 1900; - tm.tm_mon += 1; - - /* - * Check if tm.tm_year is a leap year. A year is a leap - * year if it is divisible by 4 but not 100, except - * that years divisible by 400 _are_ leap years. - */ - year = tm.tm_year; - leap = (tm.tm_mon == 2) && - ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); - - /* Perform some sanity checks. */ - if ((tm.tm_year < 1970) || - (tm.tm_mon > 12) || - (tm.tm_mday == 0) || - (tm.tm_mday > days_in_month[tm.tm_mon] + leap) || - (tm.tm_wday >= 7) || - (tm.tm_hour >= 24) || - (tm.tm_min >= 60) || - (tm.tm_sec >= 60)) - return -EINVAL; - - century = (tm.tm_year >= 2000) ? 0x80 : 0; - tm.tm_year = tm.tm_year % 100; - - tm.tm_year = bin2bcd(tm.tm_year); - tm.tm_mon = bin2bcd(tm.tm_mon); - tm.tm_mday = bin2bcd(tm.tm_mday); - tm.tm_hour = bin2bcd(tm.tm_hour); - tm.tm_min = bin2bcd(tm.tm_min); - tm.tm_sec = bin2bcd(tm.tm_sec); - tm.tm_mon |= century; - - mutex_lock(&rtc_lock); - - rtc_write(RTC_YEAR, tm.tm_year); - rtc_write(RTC_MONTH, tm.tm_mon); - rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */ - rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday); - rtc_write(RTC_HOURS, tm.tm_hour); - rtc_write(RTC_MINUTES, tm.tm_min); - rtc_write(RTC_SECONDS, tm.tm_sec); - - mutex_unlock(&rtc_lock); - - return 0; - } - case RTC_VL_READ: - if (voltage_low) { - printk(KERN_ERR "%s: RTC Voltage Low - " - "reliable date/time information is no " - "longer guaranteed!\n", PCF8563_NAME); - } - - if (copy_to_user((int *) arg, &voltage_low, sizeof(int))) - return -EFAULT; - return 0; - - case RTC_VL_CLR: - { - /* Clear the VL bit in the seconds register in case - * the time has not been set already (which would - * have cleared it). This does not really matter - * because of the cached voltage_low value but do it - * anyway for consistency. */ - - int ret = rtc_read(RTC_SECONDS); - - rtc_write(RTC_SECONDS, (ret & 0x7F)); - - /* Clear the cached value. */ - voltage_low = 0; - - return 0; - } - default: - return -ENOTTY; - } - - return 0; -} - -static int __init pcf8563_register(void) -{ - if (pcf8563_init() < 0) { - printk(KERN_INFO "%s: Unable to initialize Real-Time Clock " - "Driver, %s\n", PCF8563_NAME, DRIVER_VERSION); - return -1; - } - - if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) { - printk(KERN_INFO "%s: Unable to get major number %d for RTC device.\n", - PCF8563_NAME, PCF8563_MAJOR); - return -1; - } - - printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, - DRIVER_VERSION); - - /* Check for low voltage, and warn about it. */ - if (voltage_low) { - printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time " - "information is no longer guaranteed!\n", PCF8563_NAME); - } - - return 0; -} - -module_init(pcf8563_register); -module_exit(pcf8563_exit); diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c index 6cc1a0319a5..29eb02ab3f2 100644 --- a/arch/cris/arch-v10/drivers/sync_serial.c +++ b/arch/cris/arch-v10/drivers/sync_serial.c @@ -17,22 +17,21 @@ #include <linux/errno.h> #include <linux/major.h> #include <linux/sched.h> -#include <linux/slab.h> #include <linux/interrupt.h> #include <linux/poll.h> #include <linux/init.h> -#include <linux/smp_lock.h> +#include <linux/mutex.h> #include <linux/timer.h> +#include <linux/wait.h> #include <asm/irq.h> #include <asm/dma.h> #include <asm/io.h> #include <arch/svinto.h> #include <asm/uaccess.h> -#include <asm/system.h> #include <asm/sync_serial.h> #include <arch/io_interface_mux.h> -/* The receiver is a bit tricky beacuse of the continuous stream of data.*/ +/* The receiver is a bit tricky because of the continuous stream of data.*/ /* */ /* Three DMA descriptors are linked together. Each DMA descriptor is */ /* responsible for port->bufchunk of a common buffer. */ @@ -150,6 +149,7 @@ struct sync_port { }; +static DEFINE_MUTEX(sync_serial_mutex); static int etrax_sync_serial_init(void); static void initialize_port(int portnbr); static inline int sync_data_avail(struct sync_port *port); @@ -158,7 +158,7 @@ static int sync_serial_open(struct inode *inode, struct file *file); static int sync_serial_release(struct inode *inode, struct file *file); static unsigned int sync_serial_poll(struct file *filp, poll_table *wait); -static int sync_serial_ioctl(struct inode *inode, struct file *file, +static long sync_serial_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static ssize_t sync_serial_write(struct file *file, const char *buf, size_t count, loff_t *ppos); @@ -244,14 +244,15 @@ static unsigned sync_serial_prescale_shadow; #define NUMBER_OF_PORTS 2 -static struct file_operations sync_serial_fops = { - .owner = THIS_MODULE, - .write = sync_serial_write, - .read = sync_serial_read, - .poll = sync_serial_poll, - .ioctl = sync_serial_ioctl, - .open = sync_serial_open, - .release = sync_serial_release +static const struct file_operations sync_serial_fops = { + .owner = THIS_MODULE, + .write = sync_serial_write, + .read = sync_serial_read, + .poll = sync_serial_poll, + .unlocked_ioctl = sync_serial_ioctl, + .open = sync_serial_open, + .release = sync_serial_release, + .llseek = noop_llseek, }; static int __init etrax_sync_serial_init(void) @@ -446,7 +447,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) int mode; int err = -EBUSY; - lock_kernel(); + mutex_lock(&sync_serial_mutex); DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev)); if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { @@ -580,7 +581,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) if (port == &ports[0]) { if (request_irq(8, manual_interrupt, - IRQF_SHARED | IRQF_DISABLED, + IRQF_SHARED, "synchronous serial manual irq", &ports[0])) { printk(KERN_CRIT "Can't alloc " @@ -590,7 +591,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) } else if (port == &ports[1]) { if (request_irq(8, manual_interrupt, - IRQF_SHARED | IRQF_DISABLED, + IRQF_SHARED, "synchronous serial manual irq", &ports[1])) { printk(KERN_CRIT "Can't alloc " @@ -624,11 +625,11 @@ static int sync_serial_open(struct inode *inode, struct file *file) *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev)); } - ret = 0; + err = 0; out: - unlock_kernel(); - return ret; + mutex_unlock(&sync_serial_mutex); + return err; } static int sync_serial_release(struct inode *inode, struct file *file) @@ -654,7 +655,7 @@ static int sync_serial_release(struct inode *inode, struct file *file) static unsigned int sync_serial_poll(struct file *file, poll_table *wait) { - int dev = MINOR(file->f_dentry->d_inode->i_rdev); + int dev = MINOR(file_inode(file)->i_rdev); unsigned int mask = 0; struct sync_port *port; DEBUGPOLL(static unsigned int prev_mask = 0); @@ -679,13 +680,13 @@ static unsigned int sync_serial_poll(struct file *file, poll_table *wait) return mask; } -static int sync_serial_ioctl(struct inode *inode, struct file *file, +static int sync_serial_ioctl_unlocked(struct file *file, unsigned int cmd, unsigned long arg) { int return_val = 0; unsigned long flags; - int dev = MINOR(file->f_dentry->d_inode->i_rdev); + int dev = MINOR(file_inode(file)->i_rdev); struct sync_port *port; if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { @@ -957,11 +958,23 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file, return return_val; } +static long sync_serial_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + long ret; + + mutex_lock(&sync_serial_mutex); + ret = sync_serial_ioctl_unlocked(file, cmd, arg); + mutex_unlock(&sync_serial_mutex); + + return ret; +} + static ssize_t sync_serial_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { - int dev = MINOR(file->f_dentry->d_inode->i_rdev); + int dev = MINOR(file_inode(file)->i_rdev); DECLARE_WAITQUEUE(wait, current); struct sync_port *port; unsigned long flags; @@ -1085,7 +1098,7 @@ static ssize_t sync_serial_write(struct file *file, const char *buf, static ssize_t sync_serial_read(struct file *file, char *buf, size_t count, loff_t *ppos) { - int dev = MINOR(file->f_dentry->d_inode->i_rdev); + int dev = MINOR(file_inode(file)->i_rdev); int avail; struct sync_port *port; unsigned char *start; @@ -1124,7 +1137,8 @@ static ssize_t sync_serial_read(struct file *file, char *buf, if (file->f_flags & O_NONBLOCK) return -EAGAIN; - interruptible_sleep_on(&port->in_wait_q); + wait_event_interruptible(port->in_wait_q, + !(start == end && !port->full)); if (signal_pending(current)) return -EINTR; diff --git a/arch/cris/arch-v10/kernel/Makefile b/arch/cris/arch-v10/kernel/Makefile index dcfec41d353..4841e822cdd 100644 --- a/arch/cris/arch-v10/kernel/Makefile +++ b/arch/cris/arch-v10/kernel/Makefile @@ -1,4 +1,3 @@ -# $Id: Makefile,v 1.6 2004/12/13 12:21:51 starvik Exp $ # # Makefile for the linux kernel. # diff --git a/arch/cris/arch-v10/kernel/debugport.c b/arch/cris/arch-v10/kernel/debugport.c index 99851ba8e5f..7d307cce8bd 100644 --- a/arch/cris/arch-v10/kernel/debugport.c +++ b/arch/cris/arch-v10/kernel/debugport.c @@ -18,9 +18,7 @@ #include <linux/major.h> #include <linux/delay.h> #include <linux/tty.h> -#include <asm/system.h> #include <arch/svinto.h> -#include <asm/io.h> /* Get SIMCOUT. */ extern void reset_watchdog(void); @@ -319,12 +317,6 @@ console_write(struct console *co, const char *buf, unsigned int len) if (!port) return; -#ifdef CONFIG_SVINTO_SIM - /* no use to simulate the serial debug output */ - SIMCOUT(buf, len); - return; -#endif - console_write_direct(co, buf, len); } diff --git a/arch/cris/arch-v10/kernel/dma.c b/arch/cris/arch-v10/kernel/dma.c index 929e6866629..5795047359b 100644 --- a/arch/cris/arch-v10/kernel/dma.c +++ b/arch/cris/arch-v10/kernel/dma.c @@ -8,6 +8,7 @@ #include <asm/dma.h> #include <arch/svinto.h> +#include <arch/system.h> /* Macro to access ETRAX 100 registers */ #define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \ @@ -24,7 +25,7 @@ int cris_request_dma(unsigned int dmanr, const char * device_id, unsigned long int gens; int fail = -EINVAL; - if ((dmanr < 0) || (dmanr >= MAX_DMA_CHANNELS)) { + if (dmanr >= MAX_DMA_CHANNELS) { printk(KERN_CRIT "cris_request_dma: invalid DMA channel %u\n", dmanr); return -EINVAL; } @@ -213,7 +214,7 @@ int cris_request_dma(unsigned int dmanr, const char * device_id, void cris_free_dma(unsigned int dmanr, const char * device_id) { unsigned long flags; - if ((dmanr < 0) || (dmanr >= MAX_DMA_CHANNELS)) { + if (dmanr >= MAX_DMA_CHANNELS) { printk(KERN_CRIT "cris_free_dma: invalid DMA channel %u\n", dmanr); return; } diff --git a/arch/cris/arch-v10/kernel/entry.S b/arch/cris/arch-v10/kernel/entry.S index 72f5cd319b9..81570fcd041 100644 --- a/arch/cris/arch-v10/kernel/entry.S +++ b/arch/cris/arch-v10/kernel/entry.S @@ -13,8 +13,8 @@ * after a timer-interrupt and after each system call. * * Stack layout in 'ret_from_system_call': - * ptrace needs to have all regs on the stack. - * if the order here is changed, it needs to be + * ptrace needs to have all regs on the stack. + * if the order here is changed, it needs to be * updated in fork.c:copy_process, signal.c:do_signal, * ptrace.c and ptrace.h * @@ -31,10 +31,11 @@ #include <asm/pgtable.h> ;; functions exported from this file - + .globl system_call .globl ret_from_intr .globl ret_from_fork + .globl ret_from_kernel_thread .globl resume .globl multiple_interrupt .globl hwbreakpoint @@ -45,10 +46,10 @@ .globl do_sigtrap .globl gdb_handle_breakpoint .globl sys_call_table - + ;; below are various parts of system_call which are not in the fast-path - -#ifdef CONFIG_PREEMPT + +#ifdef CONFIG_PREEMPT ; Check if preemptive kernel scheduling should be done _resume_kernel: di @@ -73,7 +74,7 @@ _need_resched: nop #else #define _resume_kernel _Rexit -#endif +#endif ; Called at exit from fork. schedule_tail must be called to drop ; spinlock if CONFIG_PREEMPT @@ -81,18 +82,25 @@ ret_from_fork: jsr schedule_tail ba ret_from_sys_call nop - + +ret_from_kernel_thread: + jsr schedule_tail + move.d $r2, $r10 ; argument is here + jsr $r1 ; call the payload + moveq 0, $r9 ; no syscall restarts, TYVM... + ba ret_from_sys_call + ret_from_intr: - ;; check for resched if preemptive kernel or if we're going back to user-mode + ;; check for resched if preemptive kernel or if we're going back to user-mode ;; this test matches the user_regs(regs) macro ;; we cannot simply test $dccr, because that does not necessarily ;; reflect what mode we'll return into. - + move.d [$sp + PT_dccr], $r0; regs->dccr btstq 8, $r0 ; U-flag bpl _resume_kernel - ; Note that di below is in delay slot - + ; Note that di below is in delay slot + _resume_userspace: di ; so need_resched and sigpending don't change @@ -105,7 +113,7 @@ _resume_userspace: nop ba _Rexit nop - + ;; The system_call is called by a BREAK instruction, which works like ;; an interrupt call but it stores the return PC in BRP instead of IRP. ;; Since we dont really want to have two epilogues (one for system calls @@ -115,7 +123,7 @@ _resume_userspace: ;; ;; Since we can't have system calls inside interrupts, it should not matter ;; that we don't stack IRP. - ;; + ;; ;; In r9 we have the wanted syscall number. Arguments come in r10,r11,r12,r13,mof,srp ;; ;; This function looks on the _surface_ like spaghetti programming, but it's @@ -132,7 +140,7 @@ system_call: movem $r13, [$sp] ; push r0-r13 push $r10 ; push orig_r10 clear.d [$sp=$sp-4] ; frametype == 0, normal stackframe - + movs.w -ENOSYS, $r0 move.d $r0, [$sp+PT_r10] ; put the default return value in r10 in the frame @@ -140,17 +148,17 @@ system_call: movs.w -8192, $r0 ; THREAD_SIZE == 8192 and.d $sp, $r0 - + move.d [$r0+TI_flags], $r0 btstq TIF_SYSCALL_TRACE, $r0 bmi _syscall_trace_entry - nop + nop -_syscall_traced: +_syscall_traced: ;; check for sanity in the requested syscall number - - cmpu.w NR_syscalls, $r9 + + cmpu.w NR_syscalls, $r9 bcc ret_from_sys_call lslq 2, $r9 ; multiply by 4, in the delay slot @@ -158,28 +166,28 @@ _syscall_traced: ;; of the register structure itself. some syscalls need this. push $sp - + ;; the parameter carrying registers r10, r11, r12 and 13 are intact. - ;; the fifth and sixth parameters (if any) was in mof and srp + ;; the fifth and sixth parameters (if any) was in mof and srp ;; respectively, and we need to put them on the stack. push $srp push $mof - + jsr [$r9+sys_call_table] ; actually do the system call addq 3*4, $sp ; pop the mof, srp and regs parameters move.d $r10, [$sp+PT_r10] ; save the return value moveq 1, $r9 ; "parameter" to ret_from_sys_call to show it was a sys call - + ;; fall through into ret_from_sys_call to return - + ret_from_sys_call: ;; r9 is a parameter - if >=1 we came from a syscall, if 0, from an irq - + ;; get the current task-struct pointer (see top for defs) - movs.w -8192, $r0 ; THREAD_SIZE == 8192 + movs.w -8192, $r0 ; THREAD_SIZE == 8192 and.d $sp, $r0 di ; make sure need_resched and sigpending don't change @@ -194,7 +202,7 @@ _Rexit: bne _RBFexit ; was not CRIS_FRAME_NORMAL, handle otherwise addq 4, $sp ; skip orig_r10, in delayslot movem [$sp+], $r13 ; registers r0-r13 - pop $mof ; multiply overflow register + pop $mof ; multiply overflow register pop $dccr ; condition codes pop $srp ; subroutine return pointer ;; now we have a 4-word SBFS frame which we do not want to restore @@ -208,14 +216,14 @@ _Rexit: _RBFexit: movem [$sp+], $r13 ; registers r0-r13, in delay slot - pop $mof ; multiply overflow register + pop $mof ; multiply overflow register pop $dccr ; condition codes pop $srp ; subroutine return pointer rbf [$sp+] ; return by popping the CPU status ;; We get here after doing a syscall if extra work might need to be done ;; perform syscall exit tracing if needed - + _syscall_exit_work: ;; $r0 contains current at this point and irq's are disabled @@ -223,22 +231,22 @@ _syscall_exit_work: btstq TIF_SYSCALL_TRACE, $r1 bpl _work_pending nop - + ei move.d $r9, $r1 ; preserve r9 jsr do_syscall_trace move.d $r1, $r9 - + ba _resume_userspace nop - + _work_pending: move.d [$r0+TI_flags], $r1 btstq TIF_NEED_RESCHED, $r1 bpl _work_notifysig ; was neither trace nor sched, must be signal/notify nop - + _work_resched: move.d $r9, $r1 ; preserve r9 jsr schedule @@ -260,17 +268,17 @@ _work_notifysig: move.d $sp, $r11 ; the regs param move.d $r1, $r12 ; the thread_info_flags parameter jsr do_notify_resume - + ba _Rexit nop ;; We get here as a sidetrack when we've entered a syscall with the ;; trace-bit set. We need to call do_syscall_trace and then continue ;; with the call. - + _syscall_trace_entry: ;; PT_r10 in the frame contains -ENOSYS as required, at this point - + jsr do_syscall_trace ;; now re-enter the syscall code to do the syscall itself @@ -284,10 +292,10 @@ _syscall_trace_entry: move.d [$sp+PT_r13], $r13 move [$sp+PT_mof], $mof move [$sp+PT_srp], $srp - + ba _syscall_traced nop - + ;; resume performs the actual task-switching, by switching stack pointers ;; input arguments: r10 = prev, r11 = next, r12 = thread offset in task struct ;; returns old current in r10 @@ -295,29 +303,29 @@ _syscall_trace_entry: ;; TODO: see the i386 version. The switch_to which calls resume in our version ;; could really be an inline asm of this. -resume: - push $srp ; we keep the old/new PC on the stack +resume: + push $srp ; we keep the old/new PC on the stack add.d $r12, $r10 ; r10 = current tasks tss move $dccr, [$r10+THREAD_dccr]; save irq enable state di move $usp, [$r10+ THREAD_usp] ; save user-mode stackpointer - + ;; See copy_thread for the reason why register R9 is saved. subq 10*4, $sp movem $r9, [$sp] ; save non-scratch registers and R9. - + move.d $sp, [$r10+THREAD_ksp] ; save the kernel stack pointer for the old task move.d $sp, $r10 ; return last running task in r10 and.d -8192, $r10 ; get thread_info from stackpointer - move.d [$r10+TI_task], $r10 ; get task + move.d [$r10+TI_task], $r10 ; get task add.d $r12, $r11 ; find the new tasks tss move.d [$r11+THREAD_ksp], $sp ; switch into the new stackframe by restoring kernel sp movem [$sp+], $r9 ; restore non-scratch registers and R9. move [$r11+THREAD_usp], $usp ; restore user-mode stackpointer - + move [$r11+THREAD_dccr], $dccr ; restore irq enable status jump [$sp+] ; restore PC @@ -358,7 +366,7 @@ mmu_bus_fault: 1: btstq 12, $r1 ; Refill? bpl 2f lsrq 24, $r1 ; Get PGD index (bit 24-31) - move.d [per_cpu__current_pgd], $r0 ; PGD for the current process + move.d [current_pgd], $r0 ; PGD for the current process move.d [$r0+$r1.d], $r0 ; Get PMD beq 2f nop @@ -393,7 +401,7 @@ mmu_bus_fault: push $r10 ; frametype == 1, BUSFAULT frame type move.d $sp, $r10 ; pt_regs argument to handle_mmu_bus_fault - + jsr handle_mmu_bus_fault ; in arch/cris/arch-v10/mm/fault.c ;; now we need to return through the normal path, we cannot just @@ -402,10 +410,10 @@ mmu_bus_fault: ;; whatever. moveq 0, $r9 ; busfault is equivalent to an irq - + ba ret_from_intr nop - + ;; special handlers for breakpoint and NMI hwbreakpoint: push $dccr @@ -421,7 +429,7 @@ hwbreakpoint: pop $dccr retb nop - + IRQ1_interrupt: ;; this prologue MUST match the one in irq.h and the struct in ptregs.h!!! move $brp,[$sp=$sp-16]; instruction pointer and room for a fake SBFS frame @@ -449,7 +457,7 @@ IRQ1_interrupt: ba _Rexit ; Return the standard way nop wdog: -#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM) +#if defined(CONFIG_ETRAX_WATCHDOG) ;; Check if we're waiting for reset to happen, as signalled by ;; hard_reset_now setting cause_of_death to a magic value. If so, just ;; get stuck until reset happens. @@ -492,7 +500,7 @@ Watchdog_bite: move.d $r10, [$r11] #endif - + ;; Note that we don't do "setf m" here (or after two necessary NOPs), ;; since *not* doing that saves us from re-entrancy checks. We don't want ;; to get here again due to possible subsequent NMIs; we want the watchdog @@ -515,16 +523,16 @@ _watchdogmsg: .ascii "Oops: bitten by watchdog\n\0" .previous -#endif /* CONFIG_ETRAX_WATCHDOG and not CONFIG_SVINTO_SIM */ +#endif /* CONFIG_ETRAX_WATCHDOG */ -spurious_interrupt: +spurious_interrupt: di jump hard_reset_now ;; this handles the case when multiple interrupts arrive at the same time ;; we jump to the first set interrupt bit in a priority fashion ;; the hardware will call the unserved interrupts after the handler finishes - + multiple_interrupt: ;; this prologue MUST match the one in irq.h and the struct in ptregs.h!!! move $irp,[$sp=$sp-16]; instruction pointer and room for a fake SBFS frame @@ -536,14 +544,14 @@ multiple_interrupt: movem $r13, [$sp] push $r10 ; push orig_r10 clear.d [$sp=$sp-4] ; frametype == 0, normal frame - + move.d $sp, $r10 jsr do_multiple_IRQ - + jump ret_from_intr do_sigtrap: - ;; + ;; ;; SIGTRAP the process that executed the break instruction. ;; Make a frame that Rexit in entry.S expects. ;; @@ -560,38 +568,31 @@ do_sigtrap: movs.w -8192,$r9 ; THREAD_SIZE == 8192 and.d $sp, $r9 move.d [$r9+TI_task], $r10 - move.d [$r10+TASK_pid], $r10 ; current->pid as arg1. + move.d [$r10+TASK_pid], $r10 ; current->pid as arg1. moveq 5, $r11 ; SIGTRAP as arg2. - jsr sys_kill + jsr sys_kill jump ret_from_intr ; Use the return routine for interrupts. -gdb_handle_breakpoint: +gdb_handle_breakpoint: push $dccr push $r0 #ifdef CONFIG_ETRAX_KGDB - move $dccr, $r0 ; U-flag not affected by previous insns. + move $dccr, $r0 ; U-flag not affected by previous insns. btstq 8, $r0 ; Test the U-flag. - bmi _ugdb_handle_breakpoint ; Go to user mode debugging. - nop ; Empty delay slot (cannot pop r0 here). + bmi _ugdb_handle_breakpoint ; Go to user mode debugging. + nop ; Empty delay slot (cannot pop r0 here). pop $r0 ; Restore r0. - ba kgdb_handle_breakpoint ; Go to kernel debugging. + ba kgdb_handle_breakpoint ; Go to kernel debugging. pop $dccr ; Restore dccr in delay slot. #endif - -_ugdb_handle_breakpoint: + +_ugdb_handle_breakpoint: move $brp, $r0 ; Use r0 temporarily for calculation. subq 2, $r0 ; Set to address of previous instruction. move $r0, $brp - pop $r0 ; Restore r0. - ba do_sigtrap ; SIGTRAP the offending process. + pop $r0 ; Restore r0. + ba do_sigtrap ; SIGTRAP the offending process. pop $dccr ; Restore dccr in delay slot. - - .global kernel_execve -kernel_execve: - move.d __NR_execve, $r9 - break 13 - ret - nop .data @@ -601,7 +602,7 @@ hw_bp_trig_ptr: .dword hw_bp_trigs .section .rodata,"a" -sys_call_table: +sys_call_table: .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ .long sys_exit .long sys_fork @@ -692,7 +693,7 @@ sys_call_table: .long sys_swapon .long sys_reboot .long sys_old_readdir - .long old_mmap /* 90 */ + .long sys_old_mmap /* 90 */ .long sys_munmap .long sys_truncate .long sys_ftruncate @@ -712,7 +713,7 @@ sys_call_table: .long sys_newlstat .long sys_newfstat .long sys_ni_syscall /* old sys_uname holder */ - .long sys_ni_syscall /* sys_iopl in i386 */ + .long sys_ni_syscall /* 110 */ /* sys_iopl in i386 */ .long sys_vhangup .long sys_ni_syscall /* old "idle" system call */ .long sys_ni_syscall /* vm86old in i386 */ @@ -729,7 +730,7 @@ sys_call_table: .long sys_adjtimex .long sys_mprotect /* 125 */ .long sys_sigprocmask - .long sys_ni_syscall /* old "create_module" */ + .long sys_ni_syscall /* old "create_module" */ .long sys_init_module .long sys_delete_module .long sys_ni_syscall /* 130: old "get_kernel_syms" */ @@ -771,7 +772,7 @@ sys_call_table: .long sys_ni_syscall /* sys_vm86 */ .long sys_ni_syscall /* Old sys_query_module */ .long sys_poll - .long sys_nfsservctl + .long sys_ni_syscall /* old nfsservctl */ .long sys_setresgid16 /* 170 */ .long sys_getresgid16 .long sys_prctl @@ -794,7 +795,7 @@ sys_call_table: .long sys_ni_syscall /* streams2 */ .long sys_vfork /* 190 */ .long sys_getrlimit - .long sys_mmap2 + .long sys_mmap2 /* mmap_pgoff */ .long sys_truncate64 .long sys_ftruncate64 .long sys_stat64 /* 195 */ @@ -860,21 +861,21 @@ sys_call_table: .long sys_epoll_ctl /* 255 */ .long sys_epoll_wait .long sys_remap_file_pages - .long sys_set_tid_address - .long sys_timer_create - .long sys_timer_settime /* 260 */ - .long sys_timer_gettime - .long sys_timer_getoverrun - .long sys_timer_delete - .long sys_clock_settime - .long sys_clock_gettime /* 265 */ - .long sys_clock_getres - .long sys_clock_nanosleep + .long sys_set_tid_address + .long sys_timer_create + .long sys_timer_settime /* 260 */ + .long sys_timer_gettime + .long sys_timer_getoverrun + .long sys_timer_delete + .long sys_clock_settime + .long sys_clock_gettime /* 265 */ + .long sys_clock_getres + .long sys_clock_nanosleep .long sys_statfs64 - .long sys_fstatfs64 - .long sys_tgkill /* 270 */ + .long sys_fstatfs64 + .long sys_tgkill /* 270 */ .long sys_utimes - .long sys_fadvise64_64 + .long sys_fadvise64_64 .long sys_ni_syscall /* sys_vserver */ .long sys_ni_syscall /* sys_mbind */ .long sys_ni_syscall /* 275 sys_get_mempolicy */ @@ -885,7 +886,7 @@ sys_call_table: .long sys_mq_timedreceive /* 280 */ .long sys_mq_notify .long sys_mq_getsetattr - .long sys_ni_syscall /* reserved for kexec */ + .long sys_ni_syscall .long sys_waitid .long sys_ni_syscall /* 285 */ /* available */ .long sys_add_key @@ -929,6 +930,31 @@ sys_call_table: .long sys_fallocate .long sys_timerfd_settime /* 325 */ .long sys_timerfd_gettime + .long sys_signalfd4 + .long sys_eventfd2 + .long sys_epoll_create1 + .long sys_dup3 /* 330 */ + .long sys_pipe2 + .long sys_inotify_init1 + .long sys_preadv + .long sys_pwritev + .long sys_setns /* 335 */ + .long sys_name_to_handle_at + .long sys_open_by_handle_at + .long sys_rt_tgsigqueueinfo + .long sys_perf_event_open + .long sys_recvmmsg /* 340 */ + .long sys_accept4 + .long sys_fanotify_init + .long sys_fanotify_mark + .long sys_prlimit64 + .long sys_clock_adjtime /* 345 */ + .long sys_syncfs + .long sys_sendmmsg + .long sys_process_vm_readv + .long sys_process_vm_writev + .long sys_kcmp /* 350 */ + .long sys_finit_module /* * NOTE!! This doesn't have to be exact - we just have @@ -940,4 +966,4 @@ sys_call_table: .rept NR_syscalls-(.-sys_call_table)/4 .long sys_ni_syscall .endr - + diff --git a/arch/cris/arch-v10/kernel/fasttimer.c b/arch/cris/arch-v10/kernel/fasttimer.c index 5ff08a8695e..48a59afbeeb 100644 --- a/arch/cris/arch-v10/kernel/fasttimer.c +++ b/arch/cris/arch-v10/kernel/fasttimer.c @@ -21,12 +21,11 @@ #include <asm/io.h> #include <asm/irq.h> #include <asm/delay.h> -#include <asm/rtc.h> - #include <arch/svinto.h> #include <asm/fasttimer.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #define DEBUG_LOG_INCLUDED @@ -467,11 +466,7 @@ timer1_handler(int irq, void *dev_id) static void wake_up_func(unsigned long data) { -#ifdef DECLARE_WAITQUEUE - wait_queue_head_t *sleep_wait_p = (wait_queue_head_t*)data; -#else - struct wait_queue **sleep_wait_p = (struct wait_queue **)data; -#endif + wait_queue_head_t *sleep_wait_p = (wait_queue_head_t *)data; wake_up(sleep_wait_p); } @@ -495,197 +490,162 @@ void schedule_usleep(unsigned long us) } #ifdef CONFIG_PROC_FS -static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len - ,int *eof, void *data_unused); -static struct proc_dir_entry *fasttimer_proc_entry; -#endif /* CONFIG_PROC_FS */ - -#ifdef CONFIG_PROC_FS - /* This value is very much based on testing */ #define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300) -static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len - ,int *eof, void *data_unused) +static int proc_fasttimer_show(struct seq_file *m, void *v) { - unsigned long flags; - int i = 0; - int num_to_show; + unsigned long flags; + int i = 0; + int num_to_show; struct fasttime_t tv; - struct fast_timer *t, *nextt; - static char *bigbuf = NULL; - static unsigned long used; - - if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE))) - { - used = 0; - if (buf) - buf[0] = '\0'; - return 0; - } - - if (!offset || !used) - { - do_gettimeofday_fast(&tv); - - used = 0; - used += sprintf(bigbuf + used, "Fast timers added: %i\n", - fast_timers_added); - used += sprintf(bigbuf + used, "Fast timers started: %i\n", - fast_timers_started); - used += sprintf(bigbuf + used, "Fast timer interrupts: %i\n", - fast_timer_ints); - used += sprintf(bigbuf + used, "Fast timers expired: %i\n", - fast_timers_expired); - used += sprintf(bigbuf + used, "Fast timers deleted: %i\n", - fast_timers_deleted); - used += sprintf(bigbuf + used, "Fast timer running: %s\n", - fast_timer_running ? "yes" : "no"); - used += sprintf(bigbuf + used, "Current time: %lu.%06lu\n", - (unsigned long)tv.tv_jiff, - (unsigned long)tv.tv_usec); + struct fast_timer *t, *nextt; + + do_gettimeofday_fast(&tv); + + seq_printf(m, "Fast timers added: %i\n", fast_timers_added); + seq_printf(m, "Fast timers started: %i\n", fast_timers_started); + seq_printf(m, "Fast timer interrupts: %i\n", fast_timer_ints); + seq_printf(m, "Fast timers expired: %i\n", fast_timers_expired); + seq_printf(m, "Fast timers deleted: %i\n", fast_timers_deleted); + seq_printf(m, "Fast timer running: %s\n", + fast_timer_running ? "yes" : "no"); + seq_printf(m, "Current time: %lu.%06lu\n", + (unsigned long)tv.tv_jiff, + (unsigned long)tv.tv_usec); #ifdef FAST_TIMER_SANITY_CHECKS - used += sprintf(bigbuf + used, "Sanity failed: %i\n", - sanity_failed); + seq_printf(m, "Sanity failed: %i\n", sanity_failed); #endif - used += sprintf(bigbuf + used, "\n"); + seq_putc(m, '\n'); #ifdef DEBUG_LOG_INCLUDED - { - int end_i = debug_log_cnt; - i = 0; - - if (debug_log_cnt_wrapped) - { - i = debug_log_cnt; - } - - while ((i != end_i || (debug_log_cnt_wrapped && !used)) && - used+100 < BIG_BUF_SIZE) - { - used += sprintf(bigbuf + used, debug_log_string[i], - debug_log_value[i]); - i = (i+1) % DEBUG_LOG_MAX; - } - } - used += sprintf(bigbuf + used, "\n"); + { + int end_i = debug_log_cnt; + i = 0; + + if (debug_log_cnt_wrapped) + i = debug_log_cnt; + + while (i != end_i || debug_log_cnt_wrapped) { + if (seq_printf(m, debug_log_string[i], debug_log_value[i]) < 0) + return 0; + i = (i+1) % DEBUG_LOG_MAX; + } + } + seq_putc(m, '\n'); #endif - num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started: - NUM_TIMER_STATS); - used += sprintf(bigbuf + used, "Timers started: %i\n", fast_timers_started); - for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE) ; i++) - { - int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS; + num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started: + NUM_TIMER_STATS); + seq_printf(m, "Timers started: %i\n", fast_timers_started); + for (i = 0; i < num_to_show; i++) { + int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS; #if 1 //ndef FAST_TIMER_LOG - used += sprintf(bigbuf + used, "div: %i freq: %i delay: %i" - "\n", - timer_div_settings[cur], - timer_freq_settings[cur], - timer_delay_settings[cur] - ); + seq_printf(m, "div: %i freq: %i delay: %i" + "\n", + timer_div_settings[cur], + timer_freq_settings[cur], + timer_delay_settings[cur]); #endif #ifdef FAST_TIMER_LOG - t = &timer_started_log[cur]; - used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " - "d: %6li us data: 0x%08lX" - "\n", - t->name, - (unsigned long)t->tv_set.tv_jiff, - (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, - (unsigned long)t->tv_expires.tv_usec, - t->delay_us, - t->data - ); + t = &timer_started_log[cur]; + if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu " + "d: %6li us data: 0x%08lX" + "\n", + t->name, + (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_usec, + (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_usec, + t->delay_us, + t->data) < 0) + return 0; #endif - } - used += sprintf(bigbuf + used, "\n"); + } + seq_putc(m, '\n'); #ifdef FAST_TIMER_LOG - num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added: - NUM_TIMER_STATS); - used += sprintf(bigbuf + used, "Timers added: %i\n", fast_timers_added); - for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++) - { - t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS]; - used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " - "d: %6li us data: 0x%08lX" - "\n", - t->name, - (unsigned long)t->tv_set.tv_jiff, - (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, - (unsigned long)t->tv_expires.tv_usec, - t->delay_us, - t->data - ); - } - used += sprintf(bigbuf + used, "\n"); - - num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired: - NUM_TIMER_STATS); - used += sprintf(bigbuf + used, "Timers expired: %i\n", fast_timers_expired); - for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++) - { - t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS]; - used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " - "d: %6li us data: 0x%08lX" - "\n", - t->name, - (unsigned long)t->tv_set.tv_jiff, - (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, - (unsigned long)t->tv_expires.tv_usec, - t->delay_us, - t->data - ); - } - used += sprintf(bigbuf + used, "\n"); + num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added: + NUM_TIMER_STATS); + seq_printf(m, "Timers added: %i\n", fast_timers_added); + for (i = 0; i < num_to_show; i++) { + t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS]; + if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu " + "d: %6li us data: 0x%08lX" + "\n", + t->name, + (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_usec, + (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_usec, + t->delay_us, + t->data) < 0) + return 0; + } + seq_putc(m, '\n'); + + num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired: + NUM_TIMER_STATS); + seq_printf(m, "Timers expired: %i\n", fast_timers_expired); + for (i = 0; i < num_to_show; i++) { + t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS]; + if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu " + "d: %6li us data: 0x%08lX" + "\n", + t->name, + (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_usec, + (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_usec, + t->delay_us, + t->data) < 0) + return 0; + } + seq_putc(m, '\n'); #endif - used += sprintf(bigbuf + used, "Active timers:\n"); - local_irq_save(flags); - t = fast_timer_list; - while (t != NULL && (used+100 < BIG_BUF_SIZE)) - { - nextt = t->next; - local_irq_restore(flags); - used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " - "d: %6li us data: 0x%08lX" + seq_puts(m, "Active timers:\n"); + local_irq_save(flags); + t = fast_timer_list; + while (t) { + nextt = t->next; + local_irq_restore(flags); + if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu " + "d: %6li us data: 0x%08lX" /* " func: 0x%08lX" */ - "\n", - t->name, - (unsigned long)t->tv_set.tv_jiff, - (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, - (unsigned long)t->tv_expires.tv_usec, - t->delay_us, - t->data + "\n", + t->name, + (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_usec, + (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_usec, + t->delay_us, + t->data /* , t->function */ - ); - local_irq_save(flags); - if (t->next != nextt) - { - printk(KERN_WARNING "timer removed!\n"); - } - t = nextt; - } - local_irq_restore(flags); - } - - if (used - offset < len) - { - len = used - offset; - } + ) < 0) + return 0; + local_irq_save(flags); + if (t->next != nextt) + printk(KERN_WARNING "timer removed!\n"); + t = nextt; + } + local_irq_restore(flags); - memcpy(buf, bigbuf + offset, len); - *start = buf; - *eof = 1; + return 0; +} - return len; +static int proc_fasttimer_open(struct inode *inode, struct file *file) +{ + return single_open_size(file, proc_fasttimer_show, PDE_DATA(inode), BIG_BUF_SIZE); } + +static const struct file_operations proc_fasttimer_fops = { + .open = proc_fasttimer_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; #endif /* PROC_FS */ #ifdef FAST_TIMER_TEST @@ -863,8 +823,7 @@ int fast_timer_init(void) } #endif #ifdef CONFIG_PROC_FS - if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 ))) - fasttimer_proc_entry->read_proc = proc_fasttimer_read; + proc_create("fasttimer", 0, NULL, &proc_fasttimer_fops); #endif /* PROC_FS */ if(request_irq(TIMER1_IRQ_NBR, timer1_handler, 0, "fast timer int", NULL)) diff --git a/arch/cris/arch-v10/kernel/head.S b/arch/cris/arch-v10/kernel/head.S index fc457710293..4a146e1749c 100644 --- a/arch/cris/arch-v10/kernel/head.S +++ b/arch/cris/arch-v10/kernel/head.S @@ -1,12 +1,10 @@ /* * Head of the kernel - alter with care * - * Copyright (C) 2000, 2001 Axis Communications AB + * Copyright (C) 2000, 2001, 2010 Axis Communications AB * - * Authors: Bjorn Wesen (bjornw@axis.com) - * */ - + #define ASSEMBLER_MACROS_ONLY /* The IO_* macros use the ## token concatenation operator, so -traditional must not be used when assembling this file. */ @@ -18,15 +16,15 @@ #define START_ETHERNET_CLOCK IO_STATE(R_NETWORK_GEN_CONFIG, enable, on) |\ IO_STATE(R_NETWORK_GEN_CONFIG, phy, mii_clk) - + ;; exported symbols - + .globl etrax_irv .globl romfs_start .globl romfs_length .globl romfs_in_flash .globl swapper_pg_dir - + .text ;; This is the entry point of the kernel. We are in supervisor mode. @@ -35,10 +33,10 @@ ;; put a nop (2 bytes) here first so we dont accidentally skip the di ;; ;; NOTICE! The registers r8 and r9 are used as parameters carrying - ;; information from the decompressor (if the kernel was compressed). + ;; information from the decompressor (if the kernel was compressed). ;; They should not be used in the code below until read. - - nop + + nop di ;; First setup the kseg_c mapping from where the kernel is linked @@ -58,19 +56,19 @@ #ifdef CONFIG_CRIS_LOW_MAP ; kseg mappings, temporary map of 0xc0->0x40 - move.d IO_FIELD (R_MMU_KBASE_HI, base_c, 4) \ + move.d IO_FIELD (R_MMU_KBASE_HI, base_c, 4) \ | IO_FIELD (R_MMU_KBASE_HI, base_b, 0xb) \ | IO_FIELD (R_MMU_KBASE_HI, base_9, 9) \ | IO_FIELD (R_MMU_KBASE_HI, base_8, 8), $r0 move.d $r0, [R_MMU_KBASE_HI] - ; temporary map of 0x40->0x40 and 0x60->0x40 - move.d IO_FIELD (R_MMU_KBASE_LO, base_6, 4) \ + ; temporary map of 0x40->0x40 and 0x60->0x40 + move.d IO_FIELD (R_MMU_KBASE_LO, base_6, 4) \ | IO_FIELD (R_MMU_KBASE_LO, base_4, 4), $r0 move.d $r0, [R_MMU_KBASE_LO] ; mmu enable, segs e,c,b,a,6,5,4,0 segment mapped - move.d IO_STATE (R_MMU_CONFIG, mmu_enable, enable) \ + move.d IO_STATE (R_MMU_CONFIG, mmu_enable, enable) \ | IO_STATE (R_MMU_CONFIG, inv_excp, enable) \ | IO_STATE (R_MMU_CONFIG, acc_excp, enable) \ | IO_STATE (R_MMU_CONFIG, we_excp, enable) \ @@ -93,17 +91,17 @@ move.d $r0, [R_MMU_CONFIG] #else ; kseg mappings - move.d IO_FIELD (R_MMU_KBASE_HI, base_e, 8) \ + move.d IO_FIELD (R_MMU_KBASE_HI, base_e, 8) \ | IO_FIELD (R_MMU_KBASE_HI, base_c, 4) \ | IO_FIELD (R_MMU_KBASE_HI, base_b, 0xb), $r0 move.d $r0, [R_MMU_KBASE_HI] - ; temporary map of 0x40->0x40 and 0x00->0x00 + ; temporary map of 0x40->0x40 and 0x00->0x00 move.d IO_FIELD (R_MMU_KBASE_LO, base_4, 4), $r0 move.d $r0, [R_MMU_KBASE_LO] ; mmu enable, segs f,e,c,b,4,0 segment mapped - move.d IO_STATE (R_MMU_CONFIG, mmu_enable, enable) \ + move.d IO_STATE (R_MMU_CONFIG, mmu_enable, enable) \ | IO_STATE (R_MMU_CONFIG, inv_excp, enable) \ | IO_STATE (R_MMU_CONFIG, acc_excp, enable) \ | IO_STATE (R_MMU_CONFIG, we_excp, enable) \ @@ -141,12 +139,12 @@ ;; ;; In both cases, we start in un-cached mode, and need to jump into a ;; cached PC after we're done fiddling around with the segments. - ;; + ;; ;; arch/etrax100/etrax100.ld sets some symbols that define the start ;; and end of each segment. ;; Check if we start from DRAM or FLASH by testing PC - + move.d $pc,$r0 and.d 0x7fffffff,$r0 ; get rid of the non-cache bit cmp.d 0x10000,$r0 ; arbitrary... just something above this code @@ -163,30 +161,28 @@ _inflash0: ;; after init. .section ".init.text", "ax" _inflash: -#ifdef CONFIG_ETRAX_ETHERNET +#ifdef CONFIG_ETRAX_ETHERNET ;; Start MII clock to make sure it is running when tranceiver is reset move.d START_ETHERNET_CLOCK, $r0 move.d $r0, [R_NETWORK_GEN_CONFIG] #endif ;; Set up waitstates etc according to kernel configuration. -#ifndef CONFIG_SVINTO_SIM move.d CONFIG_ETRAX_DEF_R_WAITSTATES, $r0 move.d $r0, [R_WAITSTATES] move.d CONFIG_ETRAX_DEF_R_BUS_CONFIG, $r0 move.d $r0, [R_BUS_CONFIG] -#endif ;; We need to initialze DRAM registers before we start using the DRAM cmp.d RAM_INIT_MAGIC, $r8 ; Already initialized? beq _dram_init_finished nop - + #include "../lib/dram_init.S" -_dram_init_finished: +_dram_init_finished: ;; Copy text+data to DRAM ;; This is fragile - the calculation of r4 as the image size depends ;; on that the labels below actually are the first and last positions @@ -198,7 +194,7 @@ _dram_init_finished: ;; between the physical start of the flash and the flash-image start, ;; and when run with compression, the kernel is actually unpacked to ;; DRAM and we never get here in the first place :)) - + moveq 0, $r0 ; source move.d text_start, $r1 ; destination move.d __vmlinux_end, $r2 ; end destination @@ -229,10 +225,10 @@ _dram_init_finished: add.d 0xf0000000, $r4 ; add flash start in virtual memory (cached) #endif move.d $r4, [romfs_start] -1: +1: moveq 1, $r0 move.d $r0, [romfs_in_flash] - + jump _start_it ; enter code, cached this time _inram: @@ -241,7 +237,7 @@ _inram: moveq 0, $r0 move.d $r0, [romfs_length] ; default if there is no cramfs - + ;; The kernel could have been unpacked to DRAM by the loader, but ;; the cramfs image could still be in the Flash directly after the ;; compressed kernel image. The loader passes the address of the @@ -251,7 +247,7 @@ _inram: ;; (Notice that if this is not booted from the loader, r9 will be ;; garbage but we do sanity checks on it, the chance that it points ;; to a cramfs magic is small.. ) - + cmp.d 0x0ffffff8, $r9 bhs _no_romfs_in_flash ; r9 points outside the flash area nop @@ -274,20 +270,20 @@ _inram: jump _start_it ; enter code, cached this time _no_romfs_in_flash: - + ;; Check if there is a cramfs (magic value). ;; Notice that we check for cramfs magic value - which is ;; the "rom fs" we'll possibly use in 2.4 if not JFFS (which does ;; not need this mechanism anyway) - move.d __vmlinux_end, $r0; the image will be after the vmlinux end address + move.d __init_end, $r0; the image will be after the end of init move.d [$r0], $r1 ; cramfs assumes same endian on host/target cmp.d CRAMFS_MAGIC, $r1; magic value in cramfs superblock bne 2f nop - ;; Ok. What is its size ? - + ;; Ok. What is its size ? + move.d [$r0 + 4], $r2 ; cramfs_super.size (again, no need to swapwb) ;; We want to copy it to the end of the BSS @@ -303,7 +299,7 @@ _no_romfs_in_flash: add.d $r2, $r0 add.d $r2, $r1 - + ;; Go ahead. Make my loop. lsrq 1, $r2 ; size is in bytes, we copy words @@ -314,14 +310,14 @@ _no_romfs_in_flash: bne 1b nop -2: +2: ;; Dont worry that the BSS is tainted. It will be cleared later. moveq 0, $r0 move.d $r0, [romfs_in_flash] jump _start_it ; better skip the additional cramfs check below - + _start_it: ;; Check if kernel command line is supplied @@ -348,7 +344,7 @@ no_command_line: move.d ibr_start,$r0 ; this symbol is set by the linker script move $r0,$ibr move.d $r0,[etrax_irv] ; set the interrupt base register and pointer - + ;; Clear BSS region, from _bss_start to _end move.d __bss_start, $r0 @@ -357,7 +353,7 @@ no_command_line: cmp.d $r1, $r0 blo 1b nop - + #ifdef CONFIG_BLK_DEV_ETRAXIDE ;; disable ATA before enabling it in genconfig below moveq 0,$r0 @@ -380,7 +376,7 @@ no_command_line: #ifdef CONFIG_JULIETTE ;; configure external DMA channel 0 before enabling it in genconfig - + moveq 0,$r0 move.d $r0,[R_EXT_DMA_0_ADDR] ; cnt enable, word size, output, stop, size 0 @@ -395,7 +391,7 @@ no_command_line: move.d $r0,[R_EXT_DMA_0_CMD] ;; reset dma4 and wait for completion - + moveq IO_STATE (R_DMA_CH4_CMD, cmd, reset),$r0 move.b $r0,[R_DMA_CH4_CMD] 1: move.b [R_DMA_CH4_CMD],$r0 @@ -405,7 +401,7 @@ no_command_line: nop ;; reset dma5 and wait for completion - + moveq IO_STATE (R_DMA_CH5_CMD, cmd, reset),$r0 move.b $r0,[R_DMA_CH5_CMD] 1: move.b [R_DMA_CH5_CMD],$r0 @@ -413,8 +409,8 @@ no_command_line: cmp.b IO_STATE (R_DMA_CH5_CMD, cmd, reset),$r0 beq 1b nop -#endif - +#endif + ;; Etrax product HW genconfig setup moveq 0,$r0 @@ -468,7 +464,6 @@ no_command_line: move.d $r0,[genconfig_shadow] ; init a shadow register of R_GEN_CONFIG -#ifndef CONFIG_SVINTO_SIM move.d $r0,[R_GEN_CONFIG] #if 0 @@ -486,7 +481,7 @@ no_command_line: beq 1b nop #endif - + moveq IO_STATE (R_DMA_CH8_CMD, cmd, reset),$r0 move.b $r0,[R_DMA_CH8_CMD] ; reset (ser1 dma out) move.b $r0,[R_DMA_CH9_CMD] ; reset (ser1 dma in) @@ -503,7 +498,7 @@ no_command_line: ;; setup port PA and PB default initial directions and data ;; including their shadow registers - + move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR,$r0 #if defined(CONFIG_BLUETOOTH) && defined(CONFIG_BLUETOOTH_RESET_PA7) or.b IO_STATE (R_PORT_PA_DIR, dir7, output),$r0 @@ -520,7 +515,7 @@ no_command_line: #endif move.b $r0,[port_pa_data_shadow] move.b $r0,[R_PORT_PA_DATA] - + move.b CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG,$r0 move.b $r0,[port_pb_config_shadow] move.b $r0,[R_PORT_PB_CONFIG] @@ -562,13 +557,13 @@ no_command_line: #endif move.d $r0,[port_g_data_shadow] move.d $r0,[R_PORT_G_DATA] - + ;; setup the serial port 0 at 115200 baud for debug purposes - + moveq IO_STATE (R_SERIAL0_XOFF, tx_stop, enable) \ | IO_STATE (R_SERIAL0_XOFF, auto_xoff, disable) \ | IO_FIELD (R_SERIAL0_XOFF, xoff_char, 0),$r0 - move.d $r0,[R_SERIAL0_XOFF] + move.d $r0,[R_SERIAL0_XOFF] ; 115.2kbaud for both transmit and receive move.b IO_STATE (R_SERIAL0_BAUD, tr_baud, c115k2Hz) \ @@ -584,8 +579,8 @@ no_command_line: | IO_STATE (R_SERIAL0_REC_CTRL, rec_par, even) \ | IO_STATE (R_SERIAL0_REC_CTRL, rec_par_en, disable) \ | IO_STATE (R_SERIAL0_REC_CTRL, rec_bitnr, rec_8bit),$r0 - move.b $r0,[R_SERIAL0_REC_CTRL] - + move.b $r0,[R_SERIAL0_REC_CTRL] + ; Set up and enable the serial0 transmitter. move.b IO_FIELD (R_SERIAL0_TR_CTRL, txd, 0) \ | IO_STATE (R_SERIAL0_TR_CTRL, tr_enable, enable) \ @@ -598,11 +593,11 @@ no_command_line: move.b $r0,[R_SERIAL0_TR_CTRL] ;; setup the serial port 1 at 115200 baud for debug purposes - + moveq IO_STATE (R_SERIAL1_XOFF, tx_stop, enable) \ | IO_STATE (R_SERIAL1_XOFF, auto_xoff, disable) \ | IO_FIELD (R_SERIAL1_XOFF, xoff_char, 0),$r0 - move.d $r0,[R_SERIAL1_XOFF] + move.d $r0,[R_SERIAL1_XOFF] ; 115.2kbaud for both transmit and receive move.b IO_STATE (R_SERIAL1_BAUD, tr_baud, c115k2Hz) \ @@ -618,8 +613,8 @@ no_command_line: | IO_STATE (R_SERIAL1_REC_CTRL, rec_par, even) \ | IO_STATE (R_SERIAL1_REC_CTRL, rec_par_en, disable) \ | IO_STATE (R_SERIAL1_REC_CTRL, rec_bitnr, rec_8bit),$r0 - move.b $r0,[R_SERIAL1_REC_CTRL] - + move.b $r0,[R_SERIAL1_REC_CTRL] + ; Set up and enable the serial1 transmitter. move.b IO_FIELD (R_SERIAL1_TR_CTRL, txd, 0) \ | IO_STATE (R_SERIAL1_TR_CTRL, tr_enable, enable) \ @@ -666,14 +661,14 @@ no_command_line: | IO_STATE (R_SERIAL2_TR_CTRL, tr_bitnr, tr_8bit),$r0 move.b $r0,[R_SERIAL2_TR_CTRL] #endif - -#ifdef CONFIG_ETRAX_SERIAL_PORT3 + +#ifdef CONFIG_ETRAX_SERIAL_PORT3 ;; setup the serial port 3 at 115200 baud for debug purposes - + moveq IO_STATE (R_SERIAL3_XOFF, tx_stop, enable) \ | IO_STATE (R_SERIAL3_XOFF, auto_xoff, disable) \ | IO_FIELD (R_SERIAL3_XOFF, xoff_char, 0),$r0 - move.d $r0,[R_SERIAL3_XOFF] + move.d $r0,[R_SERIAL3_XOFF] ; 115.2kbaud for both transmit and receive move.b IO_STATE (R_SERIAL3_BAUD, tr_baud, c115k2Hz) \ @@ -689,8 +684,8 @@ no_command_line: | IO_STATE (R_SERIAL3_REC_CTRL, rec_par, even) \ | IO_STATE (R_SERIAL3_REC_CTRL, rec_par_en, disable) \ | IO_STATE (R_SERIAL3_REC_CTRL, rec_bitnr, rec_8bit),$r0 - move.b $r0,[R_SERIAL3_REC_CTRL] - + move.b $r0,[R_SERIAL3_REC_CTRL] + ; Set up and enable the serial3 transmitter. move.b IO_FIELD (R_SERIAL3_TR_CTRL, txd, 0) \ | IO_STATE (R_SERIAL3_TR_CTRL, tr_enable, enable) \ @@ -702,13 +697,11 @@ no_command_line: | IO_STATE (R_SERIAL3_TR_CTRL, tr_bitnr, tr_8bit),$r0 move.b $r0,[R_SERIAL3_TR_CTRL] #endif - -#endif /* CONFIG_SVINTO_SIM */ jump start_kernel ; jump into the C-function start_kernel in init/main.c - + .data -etrax_irv: +etrax_irv: .dword 0 romfs_start: .dword 0 @@ -716,13 +709,13 @@ romfs_length: .dword 0 romfs_in_flash: .dword 0 - + ;; put some special pages at the beginning of the kernel aligned ;; to page boundaries - the kernel cannot start until after this #ifdef CONFIG_CRIS_LOW_MAP swapper_pg_dir = 0x60002000 -#else +#else swapper_pg_dir = 0xc0002000 #endif diff --git a/arch/cris/arch-v10/kernel/io_interface_mux.c b/arch/cris/arch-v10/kernel/io_interface_mux.c index 29f97e96279..ad64cd1c861 100644 --- a/arch/cris/arch-v10/kernel/io_interface_mux.c +++ b/arch/cris/arch-v10/kernel/io_interface_mux.c @@ -14,6 +14,7 @@ #include <arch/svinto.h> #include <asm/io.h> #include <arch/io_interface_mux.h> +#include <arch/system.h> #define DBG(s) diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c index 65ed803dae6..09cae80a834 100644 --- a/arch/cris/arch-v10/kernel/irq.c +++ b/arch/cris/arch-v10/kernel/irq.c @@ -5,7 +5,7 @@ * * Authors: Bjorn Wesen (bjornw@axis.com) * - * This file contains the interrupt vectors and some + * This file contains the interrupt vectors and some * helper functions * */ @@ -17,8 +17,11 @@ #include <linux/kernel.h> #include <linux/init.h> -#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 crisv10_mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); +#define crisv10_unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); + +extern void kgdb_init(void); +extern void breakpoint(void); /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is * global just so that the kernel gdb can use it. @@ -104,43 +107,21 @@ static void (*interrupt[NR_IRQS])(void) = { IRQ31_interrupt }; -static void enable_crisv10_irq(unsigned int irq); - -static unsigned int startup_crisv10_irq(unsigned int irq) -{ - enable_crisv10_irq(irq); - return 0; -} - -#define shutdown_crisv10_irq disable_crisv10_irq - -static void enable_crisv10_irq(unsigned int irq) -{ - unmask_irq(irq); -} - -static void disable_crisv10_irq(unsigned int irq) -{ - mask_irq(irq); -} - -static void ack_crisv10_irq(unsigned int irq) +static void enable_crisv10_irq(struct irq_data *data) { + crisv10_unmask_irq(data->irq); } -static void end_crisv10_irq(unsigned int irq) +static void disable_crisv10_irq(struct irq_data *data) { + crisv10_mask_irq(data->irq); } -static struct hw_interrupt_type crisv10_irq_type = { - .typename = "CRISv10", - .startup = startup_crisv10_irq, - .shutdown = shutdown_crisv10_irq, - .enable = enable_crisv10_irq, - .disable = disable_crisv10_irq, - .ack = ack_crisv10_irq, - .end = end_crisv10_irq, - .set_affinity = NULL +static struct irq_chip crisv10_irq_type = { + .name = "CRISv10", + .irq_shutdown = disable_crisv10_irq, + .irq_enable = enable_crisv10_irq, + .irq_disable = disable_crisv10_irq, }; void weird_irq(void); @@ -201,19 +182,14 @@ void do_multiple_IRQ(struct pt_regs* regs) setting the irq vector table. */ -void __init -init_IRQ(void) +void __init init_IRQ(void) { int i; /* clear all interrupt masks */ - -#ifndef CONFIG_SVINTO_SIM *R_IRQ_MASK0_CLR = 0xffffffff; *R_IRQ_MASK1_CLR = 0xffffffff; *R_IRQ_MASK2_CLR = 0xffffffff; -#endif - *R_VECT_MASK_CLR = 0xffffffff; for (i = 0; i < 256; i++) @@ -221,7 +197,8 @@ init_IRQ(void) /* Initialize IRQ handler descriptors. */ for(i = 2; i < NR_IRQS; i++) { - irq_desc[i].chip = &crisv10_irq_type; + irq_set_chip_and_handler(i, &crisv10_irq_type, + handle_simple_irq); set_int_vector(i, interrupt[i]); } @@ -229,25 +206,20 @@ init_IRQ(void) executed by the associated break handler, rather than just a jump address. therefore we need to setup a default breakpoint handler for all breakpoints */ - for (i = 0; i < 16; i++) set_break_vector(i, do_sigtrap); - - /* except IRQ 15 which is the multiple-IRQ handler on Etrax100 */ + /* except IRQ 15 which is the multiple-IRQ handler on Etrax100 */ set_int_vector(15, multiple_interrupt); - - /* 0 and 1 which are special breakpoint/NMI traps */ + /* 0 and 1 which are special breakpoint/NMI traps */ set_int_vector(0, hwbreakpoint); set_int_vector(1, IRQ1_interrupt); /* and irq 14 which is the mmu bus fault handler */ - set_int_vector(14, mmu_bus_fault); /* setup the system-call trap, which is reached by BREAK 13 */ - set_break_vector(13, system_call); /* setup a breakpoint handler for debugging used for both user and diff --git a/arch/cris/arch-v10/kernel/kgdb.c b/arch/cris/arch-v10/kernel/kgdb.c index b9f9c8ce216..22d846bfc57 100644 --- a/arch/cris/arch-v10/kernel/kgdb.c +++ b/arch/cris/arch-v10/kernel/kgdb.c @@ -230,46 +230,6 @@ struct register_image unsigned int usp; /* 0x66 User mode stack pointer */ } registers; -/************** Prototypes for local library functions ***********************/ - -/* Copy of strcpy from libc. */ -static char *gdb_cris_strcpy (char *s1, const char *s2); - -/* Copy of strlen from libc. */ -static int gdb_cris_strlen (const char *s); - -/* Copy of memchr from libc. */ -static void *gdb_cris_memchr (const void *s, int c, int n); - -/* Copy of strtol from libc. Does only support base 16. */ -static int gdb_cris_strtol (const char *s, char **endptr, int base); - -/********************** Prototypes for local functions. **********************/ -/* Copy the content of a register image into another. The size n is - the size of the register image. Due to struct assignment generation of - memcpy in libc. */ -static void copy_registers (registers *dptr, registers *sptr, int n); - -/* Copy the stored registers from the stack. Put the register contents - of thread thread_id in the struct reg. */ -static void copy_registers_from_stack (int thread_id, registers *reg); - -/* Copy the registers to the stack. Put the register contents of thread - thread_id from struct reg to the stack. */ -static void copy_registers_to_stack (int thread_id, registers *reg); - -/* Write a value to a specified register regno in the register image - of the current thread. */ -static int write_register (int regno, char *val); - -/* Write a value to a specified register in the stack of a thread other - than the current thread. */ -static write_stack_register (int thread_id, int regno, char *valptr); - -/* Read a value from a specified register in the register image. Returns the - status of the read operation. The register value is returned in valptr. */ -static int read_register (char regno, unsigned int *valptr); - /* Serial port, reads one character. ETRAX 100 specific. from debugport.c */ int getDebugChar (void); @@ -278,42 +238,6 @@ void putDebugChar (int val); void enableDebugIRQ (void); -/* Returns the integer equivalent of a hexadecimal character. */ -static int hex (char ch); - -/* Convert the memory, pointed to by mem into hexadecimal representation. - Put the result in buf, and return a pointer to the last character - in buf (null). */ -static char *mem2hex (char *buf, unsigned char *mem, int count); - -/* Convert the array, in hexadecimal representation, pointed to by buf into - binary representation. Put the result in mem, and return a pointer to - the character after the last byte written. */ -static unsigned char *hex2mem (unsigned char *mem, char *buf, int count); - -/* Put the content of the array, in binary representation, pointed to by buf - into memory pointed to by mem, and return a pointer to - the character after the last byte written. */ -static unsigned char *bin2mem (unsigned char *mem, unsigned char *buf, int count); - -/* Await the sequence $<data>#<checksum> and store <data> in the array buffer - returned. */ -static void getpacket (char *buffer); - -/* Send $<data>#<checksum> from the <data> in the array buffer. */ -static void putpacket (char *buffer); - -/* Build and send a response packet in order to inform the host the - stub is stopped. */ -static void stub_is_stopped (int sigval); - -/* All expected commands are sent from remote.c. Send a response according - to the description in remote.c. */ -static void handle_exception (int sigval); - -/* Performs a complete re-start from scratch. ETRAX specific. */ -static void kill_restart (void); - /******************** Prototypes for global functions. ***********************/ /* The string str is prepended with the GDB printout token and sent. */ @@ -336,10 +260,6 @@ extern unsigned char executing_task; /* The number of characters used for a 64 bit thread identifier. */ #define HEXCHARS_IN_THREAD_ID 16 -/* Avoid warning as the internal_stack is not used in the C-code. */ -#define USEDVAR(name) { if (name) { ; } } -#define USEDFUN(name) { void (*pf)(void) = (void *)name; USEDVAR(pf) } - /********************************** Packet I/O ******************************/ /* BUFMAX defines the maximum number of characters in inbound/outbound buffers */ @@ -405,7 +325,7 @@ static int register_size[] = /* Contains the register image of the executing thread in the assembler part of the code in order to avoid horrible addressing modes. */ -static registers reg; +registers cris_reg; /* FIXME: Should this be used? Delete otherwise. */ /* Contains the assumed consistency state of the register image. Uses the @@ -413,7 +333,7 @@ static registers reg; static int consistency_status = SUCCESS; /********************************** Handle exceptions ************************/ -/* The variable reg contains the register image associated with the +/* The variable cris_reg contains the register image associated with the current_thread_c variable. It is a complete register image created at entry. The reg_g contains a register image of a task where the general registers are taken from the stack and all special registers are taken @@ -421,18 +341,10 @@ static int consistency_status = SUCCESS; in order to provide access mainly for 'g', 'G' and 'P'. */ -/* Need two task id pointers in order to handle Hct and Hgt commands. */ -static int current_thread_c = 0; -static int current_thread_g = 0; - -/* Need two register images in order to handle Hct and Hgt commands. The - variable reg_g is in addition to reg above. */ -static registers reg_g; - /********************************** Breakpoint *******************************/ /* Use an internal stack in the breakpoint and interrupt response routines */ #define INTERNAL_STACK_SIZE 1024 -static char internal_stack[INTERNAL_STACK_SIZE]; +char internal_stack[INTERNAL_STACK_SIZE]; /* Due to the breakpoint return pointer, a state variable is needed to keep track of whether it is a static (compiled) or dynamic (gdb-invoked) @@ -500,164 +412,6 @@ gdb_cris_strtol (const char *s, char **endptr, int base) return x; } -/********************************* Register image ****************************/ -/* Copy the content of a register image into another. The size n is - the size of the register image. Due to struct assignment generation of - memcpy in libc. */ -static void -copy_registers (registers *dptr, registers *sptr, int n) -{ - unsigned char *dreg; - unsigned char *sreg; - - for (dreg = (unsigned char*)dptr, sreg = (unsigned char*)sptr; n > 0; n--) - *dreg++ = *sreg++; -} - -#ifdef PROCESS_SUPPORT -/* Copy the stored registers from the stack. Put the register contents - of thread thread_id in the struct reg. */ -static void -copy_registers_from_stack (int thread_id, registers *regptr) -{ - int j; - stack_registers *s = (stack_registers *)stack_list[thread_id]; - unsigned int *d = (unsigned int *)regptr; - - for (j = 13; j >= 0; j--) - *d++ = s->r[j]; - regptr->sp = (unsigned int)stack_list[thread_id]; - regptr->pc = s->pc; - regptr->dccr = s->dccr; - regptr->srp = s->srp; -} - -/* Copy the registers to the stack. Put the register contents of thread - thread_id from struct reg to the stack. */ -static void -copy_registers_to_stack (int thread_id, registers *regptr) -{ - int i; - stack_registers *d = (stack_registers *)stack_list[thread_id]; - unsigned int *s = (unsigned int *)regptr; - - for (i = 0; i < 14; i++) { - d->r[i] = *s++; - } - d->pc = regptr->pc; - d->dccr = regptr->dccr; - d->srp = regptr->srp; -} -#endif - -/* Write a value to a specified register in the register image of the current - thread. Returns status code SUCCESS, E02 or E05. */ -static int -write_register (int regno, char *val) -{ - int status = SUCCESS; - registers *current_reg = ® - - if (regno >= R0 && regno <= PC) { - /* 32-bit register with simple offset. */ - hex2mem ((unsigned char *)current_reg + regno * sizeof(unsigned int), - val, sizeof(unsigned int)); - } - else if (regno == P0 || regno == VR || regno == P4 || regno == P8) { - /* Do not support read-only registers. */ - status = E02; - } - else if (regno == CCR) { - /* 16 bit register with complex offset. (P4 is read-only, P6 is not implemented, - and P7 (MOF) is 32 bits in ETRAX 100LX. */ - hex2mem ((unsigned char *)&(current_reg->ccr) + (regno-CCR) * sizeof(unsigned short), - val, sizeof(unsigned short)); - } - else if (regno >= MOF && regno <= USP) { - /* 32 bit register with complex offset. (P8 has been taken care of.) */ - hex2mem ((unsigned char *)&(current_reg->ibr) + (regno-IBR) * sizeof(unsigned int), - val, sizeof(unsigned int)); - } - else { - /* Do not support nonexisting or unimplemented registers (P2, P3, and P6). */ - status = E05; - } - return status; -} - -#ifdef PROCESS_SUPPORT -/* Write a value to a specified register in the stack of a thread other - than the current thread. Returns status code SUCCESS or E07. */ -static int -write_stack_register (int thread_id, int regno, char *valptr) -{ - int status = SUCCESS; - stack_registers *d = (stack_registers *)stack_list[thread_id]; - unsigned int val; - - hex2mem ((unsigned char *)&val, valptr, sizeof(unsigned int)); - if (regno >= R0 && regno < SP) { - d->r[regno] = val; - } - else if (regno == SP) { - stack_list[thread_id] = val; - } - else if (regno == PC) { - d->pc = val; - } - else if (regno == SRP) { - d->srp = val; - } - else if (regno == DCCR) { - d->dccr = val; - } - else { - /* Do not support registers in the current thread. */ - status = E07; - } - return status; -} -#endif - -/* Read a value from a specified register in the register image. Returns the - value in the register or -1 for non-implemented registers. - Should check consistency_status after a call which may be E05 after changes - in the implementation. */ -static int -read_register (char regno, unsigned int *valptr) -{ - registers *current_reg = ® - - if (regno >= R0 && regno <= PC) { - /* 32-bit register with simple offset. */ - *valptr = *(unsigned int *)((char *)current_reg + regno * sizeof(unsigned int)); - return SUCCESS; - } - else if (regno == P0 || regno == VR) { - /* 8 bit register with complex offset. */ - *valptr = (unsigned int)(*(unsigned char *) - ((char *)&(current_reg->p0) + (regno-P0) * sizeof(char))); - return SUCCESS; - } - else if (regno == P4 || regno == CCR) { - /* 16 bit register with complex offset. */ - *valptr = (unsigned int)(*(unsigned short *) - ((char *)&(current_reg->p4) + (regno-P4) * sizeof(unsigned short))); - return SUCCESS; - } - else if (regno >= MOF && regno <= USP) { - /* 32 bit register with complex offset. */ - *valptr = *(unsigned int *)((char *)&(current_reg->p8) - + (regno-P8) * sizeof(unsigned int)); - return SUCCESS; - } - else { - /* Do not support nonexisting or unimplemented registers (P2, P3, and P6). */ - consistency_status = E05; - return E05; - } -} - /********************************** Packet I/O ******************************/ /* Returns the integer equivalent of a hexadecimal character. */ static int @@ -676,8 +430,6 @@ hex (char ch) Put the result in buf, and return a pointer to the last character in buf (null). */ -static int do_printk = 0; - static char * mem2hex(char *buf, unsigned char *mem, int count) { @@ -694,7 +446,7 @@ mem2hex(char *buf, unsigned char *mem, int count) /* Valid mem address. */ for (i = 0; i < count; i++) { ch = *mem++; - buf = pack_hex_byte(buf, ch); + buf = hex_byte_pack(buf, ch); } } @@ -761,7 +513,7 @@ getpacket (char *buffer) xmitcsum = -1; count = 0; /* Read until a # or the end of the buffer is reached */ - while (count < BUFMAX) { + while (count < BUFMAX - 1) { ch = getDebugChar (); if (ch == '#') break; @@ -845,6 +597,81 @@ putDebugString (const unsigned char *str, int length) putpacket(remcomOutBuffer); } +/********************************* Register image ****************************/ +/* Write a value to a specified register in the register image of the current + thread. Returns status code SUCCESS, E02 or E05. */ +static int +write_register (int regno, char *val) +{ + int status = SUCCESS; + registers *current_reg = &cris_reg; + + if (regno >= R0 && regno <= PC) { + /* 32-bit register with simple offset. */ + hex2mem ((unsigned char *)current_reg + regno * sizeof(unsigned int), + val, sizeof(unsigned int)); + } + else if (regno == P0 || regno == VR || regno == P4 || regno == P8) { + /* Do not support read-only registers. */ + status = E02; + } + else if (regno == CCR) { + /* 16 bit register with complex offset. (P4 is read-only, P6 is not implemented, + and P7 (MOF) is 32 bits in ETRAX 100LX. */ + hex2mem ((unsigned char *)&(current_reg->ccr) + (regno-CCR) * sizeof(unsigned short), + val, sizeof(unsigned short)); + } + else if (regno >= MOF && regno <= USP) { + /* 32 bit register with complex offset. (P8 has been taken care of.) */ + hex2mem ((unsigned char *)&(current_reg->ibr) + (regno-IBR) * sizeof(unsigned int), + val, sizeof(unsigned int)); + } + else { + /* Do not support nonexisting or unimplemented registers (P2, P3, and P6). */ + status = E05; + } + return status; +} + +/* Read a value from a specified register in the register image. Returns the + value in the register or -1 for non-implemented registers. + Should check consistency_status after a call which may be E05 after changes + in the implementation. */ +static int +read_register (char regno, unsigned int *valptr) +{ + registers *current_reg = &cris_reg; + + if (regno >= R0 && regno <= PC) { + /* 32-bit register with simple offset. */ + *valptr = *(unsigned int *)((char *)current_reg + regno * sizeof(unsigned int)); + return SUCCESS; + } + else if (regno == P0 || regno == VR) { + /* 8 bit register with complex offset. */ + *valptr = (unsigned int)(*(unsigned char *) + ((char *)&(current_reg->p0) + (regno-P0) * sizeof(char))); + return SUCCESS; + } + else if (regno == P4 || regno == CCR) { + /* 16 bit register with complex offset. */ + *valptr = (unsigned int)(*(unsigned short *) + ((char *)&(current_reg->p4) + (regno-P4) * sizeof(unsigned short))); + return SUCCESS; + } + else if (regno >= MOF && regno <= USP) { + /* 32 bit register with complex offset. */ + *valptr = *(unsigned int *)((char *)&(current_reg->p8) + + (regno-P8) * sizeof(unsigned int)); + return SUCCESS; + } + else { + /* Do not support nonexisting or unimplemented registers (P2, P3, and P6). */ + consistency_status = E05; + return E05; + } +} + /********************************** Handle exceptions ************************/ /* Build and send a response packet in order to inform the host the stub is stopped. TAAn...:r...;n...:r...;n...:r...; @@ -868,7 +695,7 @@ stub_is_stopped(int sigval) /* Send trap type (converted to signal) */ *ptr++ = 'T'; - ptr = pack_hex_byte(ptr, sigval); + ptr = hex_byte_pack(ptr, sigval); /* Send register contents. We probably only need to send the * PC, frame pointer and stack pointer here. Other registers will be @@ -881,7 +708,7 @@ stub_is_stopped(int sigval) status = read_register (regno, ®_cont); if (status == SUCCESS) { - ptr = pack_hex_byte(ptr, regno); + ptr = hex_byte_pack(ptr, regno); *ptr++ = ':'; ptr = mem2hex(ptr, (unsigned char *)®_cont, @@ -891,26 +718,6 @@ stub_is_stopped(int sigval) } -#ifdef PROCESS_SUPPORT - /* Store the registers of the executing thread. Assume that both step, - continue, and register content requests are with respect to this - thread. The executing task is from the operating system scheduler. */ - - current_thread_c = executing_task; - current_thread_g = executing_task; - - /* A struct assignment translates into a libc memcpy call. Avoid - all libc functions in order to prevent recursive break points. */ - copy_registers (®_g, ®, sizeof(registers)); - - /* Store thread:r...; with the executing task TID. */ - gdb_cris_strcpy (&remcomOutBuffer[pos], "thread:"); - pos += gdb_cris_strlen ("thread:"); - remcomOutBuffer[pos++] = hex_asc_hi(executing_task); - remcomOutBuffer[pos++] = hex_asc_lo(executing_task); - gdb_cris_strcpy (&remcomOutBuffer[pos], ";"); -#endif - /* null-terminate and send it off */ *ptr = 0; @@ -918,16 +725,18 @@ stub_is_stopped(int sigval) putpacket (remcomOutBuffer); } +/* Performs a complete re-start from scratch. */ +static void +kill_restart (void) +{ + machine_restart(""); +} + /* All expected commands are sent from remote.c. Send a response according to the description in remote.c. */ -static void +void handle_exception (int sigval) { - /* Avoid warning of not used. */ - - USEDFUN(handle_exception); - USEDVAR(internal_stack[0]); - /* Send response. */ stub_is_stopped (sigval); @@ -943,19 +752,7 @@ handle_exception (int sigval) in a register are in the same order the machine uses. Failure: void. */ - { -#ifdef PROCESS_SUPPORT - /* Use the special register content in the executing thread. */ - copy_registers (®_g, ®, sizeof(registers)); - /* Replace the content available on the stack. */ - if (current_thread_g != executing_task) { - copy_registers_from_stack (current_thread_g, ®_g); - } - mem2hex ((unsigned char *)remcomOutBuffer, (unsigned char *)®_g, sizeof(registers)); -#else - mem2hex(remcomOutBuffer, (char *)®, sizeof(registers)); -#endif - } + mem2hex(remcomOutBuffer, (char *)&cris_reg, sizeof(registers)); break; case 'G': @@ -963,17 +760,7 @@ handle_exception (int sigval) Each byte of register data is described by two hex digits. Success: OK Failure: void. */ -#ifdef PROCESS_SUPPORT - hex2mem ((unsigned char *)®_g, &remcomInBuffer[1], sizeof(registers)); - if (current_thread_g == executing_task) { - copy_registers (®, ®_g, sizeof(registers)); - } - else { - copy_registers_to_stack(current_thread_g, ®_g); - } -#else - hex2mem((char *)®, &remcomInBuffer[1], sizeof(registers)); -#endif + hex2mem((char *)&cris_reg, &remcomInBuffer[1], sizeof(registers)); gdb_cris_strcpy (remcomOutBuffer, "OK"); break; @@ -989,12 +776,7 @@ handle_exception (int sigval) char *suffix; int regno = gdb_cris_strtol (&remcomInBuffer[1], &suffix, 16); int status; -#ifdef PROCESS_SUPPORT - if (current_thread_g != executing_task) - status = write_stack_register (current_thread_g, regno, suffix+1); - else -#endif - status = write_register (regno, suffix+1); + status = write_register (regno, suffix+1); switch (status) { case E02: @@ -1073,7 +855,7 @@ handle_exception (int sigval) Success: return to the executing thread. Failure: will never know. */ if (remcomInBuffer[1] != '\0') { - reg.pc = gdb_cris_strtol (&remcomInBuffer[1], 0, 16); + cris_reg.pc = gdb_cris_strtol (&remcomInBuffer[1], 0, 16); } enableDebugIRQ(); return; @@ -1129,119 +911,6 @@ handle_exception (int sigval) Not supported: E04 */ gdb_cris_strcpy (remcomOutBuffer, error_message[E04]); break; -#ifdef PROCESS_SUPPORT - - case 'T': - /* Thread alive. TXX - Is thread XX alive? - Success: OK, thread XX is alive. - Failure: E03, thread XX is dead. */ - { - int thread_id = (int)gdb_cris_strtol (&remcomInBuffer[1], 0, 16); - /* Cannot tell whether it is alive or not. */ - if (thread_id >= 0 && thread_id < number_of_tasks) - gdb_cris_strcpy (remcomOutBuffer, "OK"); - } - break; - - case 'H': - /* Set thread for subsequent operations: Hct - c = 'c' for thread used in step and continue; - t can be -1 for all threads. - c = 'g' for thread used in other operations. - t = 0 means pick any thread. - Success: OK - Failure: E01 */ - { - int thread_id = gdb_cris_strtol (&remcomInBuffer[2], 0, 16); - if (remcomInBuffer[1] == 'c') { - /* c = 'c' for thread used in step and continue */ - /* Do not change current_thread_c here. It would create a mess in - the scheduler. */ - gdb_cris_strcpy (remcomOutBuffer, "OK"); - } - else if (remcomInBuffer[1] == 'g') { - /* c = 'g' for thread used in other operations. - t = 0 means pick any thread. Impossible since the scheduler does - not allow that. */ - if (thread_id >= 0 && thread_id < number_of_tasks) { - current_thread_g = thread_id; - gdb_cris_strcpy (remcomOutBuffer, "OK"); - } - else { - /* Not expected - send an error message. */ - gdb_cris_strcpy (remcomOutBuffer, error_message[E01]); - } - } - else { - /* Not expected - send an error message. */ - gdb_cris_strcpy (remcomOutBuffer, error_message[E01]); - } - } - break; - - case 'q': - case 'Q': - /* Query of general interest. qXXXX - Set general value XXXX. QXXXX=yyyy */ - { - int pos; - int nextpos; - int thread_id; - - switch (remcomInBuffer[1]) { - case 'C': - /* Identify the remote current thread. */ - gdb_cris_strcpy (&remcomOutBuffer[0], "QC"); - remcomOutBuffer[2] = hex_asc_hi(current_thread_c); - remcomOutBuffer[3] = hex_asc_lo(current_thread_c); - remcomOutBuffer[4] = '\0'; - break; - case 'L': - gdb_cris_strcpy (&remcomOutBuffer[0], "QM"); - /* Reply with number of threads. */ - if (os_is_started()) { - remcomOutBuffer[2] = hex_asc_hi(number_of_tasks); - remcomOutBuffer[3] = hex_asc_lo(number_of_tasks); - } - else { - remcomOutBuffer[2] = hex_asc_hi(0); - remcomOutBuffer[3] = hex_asc_lo(1); - } - /* Done with the reply. */ - remcomOutBuffer[4] = hex_asc_lo(1); - pos = 5; - /* Expects the argument thread id. */ - for (; pos < (5 + HEXCHARS_IN_THREAD_ID); pos++) - remcomOutBuffer[pos] = remcomInBuffer[pos]; - /* Reply with the thread identifiers. */ - if (os_is_started()) { - /* Store the thread identifiers of all tasks. */ - for (thread_id = 0; thread_id < number_of_tasks; thread_id++) { - nextpos = pos + HEXCHARS_IN_THREAD_ID - 1; - for (; pos < nextpos; pos ++) - remcomOutBuffer[pos] = hex_asc_lo(0); - remcomOutBuffer[pos++] = hex_asc_lo(thread_id); - } - } - else { - /* Store the thread identifier of the boot task. */ - nextpos = pos + HEXCHARS_IN_THREAD_ID - 1; - for (; pos < nextpos; pos ++) - remcomOutBuffer[pos] = hex_asc_lo(0); - remcomOutBuffer[pos++] = hex_asc_lo(current_thread_c); - } - remcomOutBuffer[pos] = '\0'; - break; - default: - /* Not supported: "" */ - /* Request information about section offsets: qOffsets. */ - remcomOutBuffer[0] = 0; - break; - } - } - break; -#endif /* PROCESS_SUPPORT */ default: /* The stub should ignore other request and send an empty @@ -1254,13 +923,6 @@ handle_exception (int sigval) } } -/* Performs a complete re-start from scratch. */ -static void -kill_restart () -{ - machine_restart(""); -} - /********************************** Breakpoint *******************************/ /* The hook for both a static (compiled) and a dynamic breakpoint set by GDB. An internal stack is used by the stub. The register image of the caller is @@ -1270,93 +932,93 @@ kill_restart () void kgdb_handle_breakpoint(void); -asm (" - .global kgdb_handle_breakpoint -kgdb_handle_breakpoint: -;; -;; Response to the break-instruction -;; -;; Create a register image of the caller -;; - move $dccr,[reg+0x5E] ; Save the flags in DCCR before disable interrupts - di ; Disable interrupts - move.d $r0,[reg] ; Save R0 - move.d $r1,[reg+0x04] ; Save R1 - move.d $r2,[reg+0x08] ; Save R2 - move.d $r3,[reg+0x0C] ; Save R3 - move.d $r4,[reg+0x10] ; Save R4 - move.d $r5,[reg+0x14] ; Save R5 - move.d $r6,[reg+0x18] ; Save R6 - move.d $r7,[reg+0x1C] ; Save R7 - move.d $r8,[reg+0x20] ; Save R8 - move.d $r9,[reg+0x24] ; Save R9 - move.d $r10,[reg+0x28] ; Save R10 - move.d $r11,[reg+0x2C] ; Save R11 - move.d $r12,[reg+0x30] ; Save R12 - move.d $r13,[reg+0x34] ; Save R13 - move.d $sp,[reg+0x38] ; Save SP (R14) -;; Due to the old assembler-versions BRP might not be recognized - .word 0xE670 ; move brp,$r0 - subq 2,$r0 ; Set to address of previous instruction. - move.d $r0,[reg+0x3c] ; Save the address in PC (R15) - clear.b [reg+0x40] ; Clear P0 - move $vr,[reg+0x41] ; Save special register P1 - clear.w [reg+0x42] ; Clear P4 - move $ccr,[reg+0x44] ; Save special register CCR - move $mof,[reg+0x46] ; P7 - clear.d [reg+0x4A] ; Clear P8 - move $ibr,[reg+0x4E] ; P9, - move $irp,[reg+0x52] ; P10, - move $srp,[reg+0x56] ; P11, - move $dtp0,[reg+0x5A] ; P12, register BAR, assembler might not know BAR - ; P13, register DCCR already saved -;; Due to the old assembler-versions BRP might not be recognized - .word 0xE670 ; move brp,r0 -;; Static (compiled) breakpoints must return to the next instruction in order -;; to avoid infinite loops. Dynamic (gdb-invoked) must restore the instruction -;; in order to execute it when execution is continued. - test.b [is_dyn_brkp] ; Is this a dynamic breakpoint? - beq is_static ; No, a static breakpoint - nop - subq 2,$r0 ; rerun the instruction the break replaced -is_static: - moveq 1,$r1 - move.b $r1,[is_dyn_brkp] ; Set the state variable to dynamic breakpoint - move.d $r0,[reg+0x62] ; Save the return address in BRP - move $usp,[reg+0x66] ; USP -;; -;; Handle the communication -;; - move.d internal_stack+1020,$sp ; Use the internal stack which grows upward - moveq 5,$r10 ; SIGTRAP - jsr handle_exception ; Interactive routine -;; -;; Return to the caller -;; - move.d [reg],$r0 ; Restore R0 - move.d [reg+0x04],$r1 ; Restore R1 - move.d [reg+0x08],$r2 ; Restore R2 - move.d [reg+0x0C],$r3 ; Restore R3 - move.d [reg+0x10],$r4 ; Restore R4 - move.d [reg+0x14],$r5 ; Restore R5 - move.d [reg+0x18],$r6 ; Restore R6 - move.d [reg+0x1C],$r7 ; Restore R7 - move.d [reg+0x20],$r8 ; Restore R8 - move.d [reg+0x24],$r9 ; Restore R9 - move.d [reg+0x28],$r10 ; Restore R10 - move.d [reg+0x2C],$r11 ; Restore R11 - move.d [reg+0x30],$r12 ; Restore R12 - move.d [reg+0x34],$r13 ; Restore R13 -;; -;; FIXME: Which registers should be restored? -;; - move.d [reg+0x38],$sp ; Restore SP (R14) - move [reg+0x56],$srp ; Restore the subroutine return pointer. - move [reg+0x5E],$dccr ; Restore DCCR - move [reg+0x66],$usp ; Restore USP - jump [reg+0x62] ; A jump to the content in register BRP works. - nop ; -"); +asm ("\n" +" .global kgdb_handle_breakpoint\n" +"kgdb_handle_breakpoint:\n" +";;\n" +";; Response to the break-instruction\n" +";;\n" +";; Create a register image of the caller\n" +";;\n" +" move $dccr,[cris_reg+0x5E] ; Save the flags in DCCR before disable interrupts\n" +" di ; Disable interrupts\n" +" move.d $r0,[cris_reg] ; Save R0\n" +" move.d $r1,[cris_reg+0x04] ; Save R1\n" +" move.d $r2,[cris_reg+0x08] ; Save R2\n" +" move.d $r3,[cris_reg+0x0C] ; Save R3\n" +" move.d $r4,[cris_reg+0x10] ; Save R4\n" +" move.d $r5,[cris_reg+0x14] ; Save R5\n" +" move.d $r6,[cris_reg+0x18] ; Save R6\n" +" move.d $r7,[cris_reg+0x1C] ; Save R7\n" +" move.d $r8,[cris_reg+0x20] ; Save R8\n" +" move.d $r9,[cris_reg+0x24] ; Save R9\n" +" move.d $r10,[cris_reg+0x28] ; Save R10\n" +" move.d $r11,[cris_reg+0x2C] ; Save R11\n" +" move.d $r12,[cris_reg+0x30] ; Save R12\n" +" move.d $r13,[cris_reg+0x34] ; Save R13\n" +" move.d $sp,[cris_reg+0x38] ; Save SP (R14)\n" +";; Due to the old assembler-versions BRP might not be recognized\n" +" .word 0xE670 ; move brp,$r0\n" +" subq 2,$r0 ; Set to address of previous instruction.\n" +" move.d $r0,[cris_reg+0x3c] ; Save the address in PC (R15)\n" +" clear.b [cris_reg+0x40] ; Clear P0\n" +" move $vr,[cris_reg+0x41] ; Save special register P1\n" +" clear.w [cris_reg+0x42] ; Clear P4\n" +" move $ccr,[cris_reg+0x44] ; Save special register CCR\n" +" move $mof,[cris_reg+0x46] ; P7\n" +" clear.d [cris_reg+0x4A] ; Clear P8\n" +" move $ibr,[cris_reg+0x4E] ; P9,\n" +" move $irp,[cris_reg+0x52] ; P10,\n" +" move $srp,[cris_reg+0x56] ; P11,\n" +" move $dtp0,[cris_reg+0x5A] ; P12, register BAR, assembler might not know BAR\n" +" ; P13, register DCCR already saved\n" +";; Due to the old assembler-versions BRP might not be recognized\n" +" .word 0xE670 ; move brp,r0\n" +";; Static (compiled) breakpoints must return to the next instruction in order\n" +";; to avoid infinite loops. Dynamic (gdb-invoked) must restore the instruction\n" +";; in order to execute it when execution is continued.\n" +" test.b [is_dyn_brkp] ; Is this a dynamic breakpoint?\n" +" beq is_static ; No, a static breakpoint\n" +" nop\n" +" subq 2,$r0 ; rerun the instruction the break replaced\n" +"is_static:\n" +" moveq 1,$r1\n" +" move.b $r1,[is_dyn_brkp] ; Set the state variable to dynamic breakpoint\n" +" move.d $r0,[cris_reg+0x62] ; Save the return address in BRP\n" +" move $usp,[cris_reg+0x66] ; USP\n" +";;\n" +";; Handle the communication\n" +";;\n" +" move.d internal_stack+1020,$sp ; Use the internal stack which grows upward\n" +" moveq 5,$r10 ; SIGTRAP\n" +" jsr handle_exception ; Interactive routine\n" +";;\n" +";; Return to the caller\n" +";;\n" +" move.d [cris_reg],$r0 ; Restore R0\n" +" move.d [cris_reg+0x04],$r1 ; Restore R1\n" +" move.d [cris_reg+0x08],$r2 ; Restore R2\n" +" move.d [cris_reg+0x0C],$r3 ; Restore R3\n" +" move.d [cris_reg+0x10],$r4 ; Restore R4\n" +" move.d [cris_reg+0x14],$r5 ; Restore R5\n" +" move.d [cris_reg+0x18],$r6 ; Restore R6\n" +" move.d [cris_reg+0x1C],$r7 ; Restore R7\n" +" move.d [cris_reg+0x20],$r8 ; Restore R8\n" +" move.d [cris_reg+0x24],$r9 ; Restore R9\n" +" move.d [cris_reg+0x28],$r10 ; Restore R10\n" +" move.d [cris_reg+0x2C],$r11 ; Restore R11\n" +" move.d [cris_reg+0x30],$r12 ; Restore R12\n" +" move.d [cris_reg+0x34],$r13 ; Restore R13\n" +";;\n" +";; FIXME: Which registers should be restored?\n" +";;\n" +" move.d [cris_reg+0x38],$sp ; Restore SP (R14)\n" +" move [cris_reg+0x56],$srp ; Restore the subroutine return pointer.\n" +" move [cris_reg+0x5E],$dccr ; Restore DCCR\n" +" move [cris_reg+0x66],$usp ; Restore USP\n" +" jump [cris_reg+0x62] ; A jump to the content in register BRP works.\n" +" nop ;\n" +"\n"); /* The hook for an interrupt generated by GDB. An internal stack is used by the stub. The register image of the caller is stored in the structure @@ -1367,94 +1029,94 @@ is_static: void kgdb_handle_serial(void); -asm (" - .global kgdb_handle_serial -kgdb_handle_serial: -;; -;; Response to a serial interrupt -;; - - move $dccr,[reg+0x5E] ; Save the flags in DCCR - di ; Disable interrupts - move.d $r0,[reg] ; Save R0 - move.d $r1,[reg+0x04] ; Save R1 - move.d $r2,[reg+0x08] ; Save R2 - move.d $r3,[reg+0x0C] ; Save R3 - move.d $r4,[reg+0x10] ; Save R4 - move.d $r5,[reg+0x14] ; Save R5 - move.d $r6,[reg+0x18] ; Save R6 - move.d $r7,[reg+0x1C] ; Save R7 - move.d $r8,[reg+0x20] ; Save R8 - move.d $r9,[reg+0x24] ; Save R9 - move.d $r10,[reg+0x28] ; Save R10 - move.d $r11,[reg+0x2C] ; Save R11 - move.d $r12,[reg+0x30] ; Save R12 - move.d $r13,[reg+0x34] ; Save R13 - move.d $sp,[reg+0x38] ; Save SP (R14) - move $irp,[reg+0x3c] ; Save the address in PC (R15) - clear.b [reg+0x40] ; Clear P0 - move $vr,[reg+0x41] ; Save special register P1, - clear.w [reg+0x42] ; Clear P4 - move $ccr,[reg+0x44] ; Save special register CCR - move $mof,[reg+0x46] ; P7 - clear.d [reg+0x4A] ; Clear P8 - move $ibr,[reg+0x4E] ; P9, - move $irp,[reg+0x52] ; P10, - move $srp,[reg+0x56] ; P11, - move $dtp0,[reg+0x5A] ; P12, register BAR, assembler might not know BAR - ; P13, register DCCR already saved -;; Due to the old assembler-versions BRP might not be recognized - .word 0xE670 ; move brp,r0 - move.d $r0,[reg+0x62] ; Save the return address in BRP - move $usp,[reg+0x66] ; USP - -;; get the serial character (from debugport.c) and check if it is a ctrl-c - - jsr getDebugChar - cmp.b 3, $r10 - bne goback - nop - - move.d [reg+0x5E], $r10 ; Get DCCR - btstq 8, $r10 ; Test the U-flag. - bmi goback - nop - -;; -;; Handle the communication -;; - move.d internal_stack+1020,$sp ; Use the internal stack - moveq 2,$r10 ; SIGINT - jsr handle_exception ; Interactive routine - -goback: -;; -;; Return to the caller -;; - move.d [reg],$r0 ; Restore R0 - move.d [reg+0x04],$r1 ; Restore R1 - move.d [reg+0x08],$r2 ; Restore R2 - move.d [reg+0x0C],$r3 ; Restore R3 - move.d [reg+0x10],$r4 ; Restore R4 - move.d [reg+0x14],$r5 ; Restore R5 - move.d [reg+0x18],$r6 ; Restore R6 - move.d [reg+0x1C],$r7 ; Restore R7 - move.d [reg+0x20],$r8 ; Restore R8 - move.d [reg+0x24],$r9 ; Restore R9 - move.d [reg+0x28],$r10 ; Restore R10 - move.d [reg+0x2C],$r11 ; Restore R11 - move.d [reg+0x30],$r12 ; Restore R12 - move.d [reg+0x34],$r13 ; Restore R13 -;; -;; FIXME: Which registers should be restored? -;; - move.d [reg+0x38],$sp ; Restore SP (R14) - move [reg+0x56],$srp ; Restore the subroutine return pointer. - move [reg+0x5E],$dccr ; Restore DCCR - move [reg+0x66],$usp ; Restore USP - reti ; Return from the interrupt routine - nop -"); +asm ("\n" +" .global kgdb_handle_serial\n" +"kgdb_handle_serial:\n" +";;\n" +";; Response to a serial interrupt\n" +";;\n" +"\n" +" move $dccr,[cris_reg+0x5E] ; Save the flags in DCCR\n" +" di ; Disable interrupts\n" +" move.d $r0,[cris_reg] ; Save R0\n" +" move.d $r1,[cris_reg+0x04] ; Save R1\n" +" move.d $r2,[cris_reg+0x08] ; Save R2\n" +" move.d $r3,[cris_reg+0x0C] ; Save R3\n" +" move.d $r4,[cris_reg+0x10] ; Save R4\n" +" move.d $r5,[cris_reg+0x14] ; Save R5\n" +" move.d $r6,[cris_reg+0x18] ; Save R6\n" +" move.d $r7,[cris_reg+0x1C] ; Save R7\n" +" move.d $r8,[cris_reg+0x20] ; Save R8\n" +" move.d $r9,[cris_reg+0x24] ; Save R9\n" +" move.d $r10,[cris_reg+0x28] ; Save R10\n" +" move.d $r11,[cris_reg+0x2C] ; Save R11\n" +" move.d $r12,[cris_reg+0x30] ; Save R12\n" +" move.d $r13,[cris_reg+0x34] ; Save R13\n" +" move.d $sp,[cris_reg+0x38] ; Save SP (R14)\n" +" move $irp,[cris_reg+0x3c] ; Save the address in PC (R15)\n" +" clear.b [cris_reg+0x40] ; Clear P0\n" +" move $vr,[cris_reg+0x41] ; Save special register P1,\n" +" clear.w [cris_reg+0x42] ; Clear P4\n" +" move $ccr,[cris_reg+0x44] ; Save special register CCR\n" +" move $mof,[cris_reg+0x46] ; P7\n" +" clear.d [cris_reg+0x4A] ; Clear P8\n" +" move $ibr,[cris_reg+0x4E] ; P9,\n" +" move $irp,[cris_reg+0x52] ; P10,\n" +" move $srp,[cris_reg+0x56] ; P11,\n" +" move $dtp0,[cris_reg+0x5A] ; P12, register BAR, assembler might not know BAR\n" +" ; P13, register DCCR already saved\n" +";; Due to the old assembler-versions BRP might not be recognized\n" +" .word 0xE670 ; move brp,r0\n" +" move.d $r0,[cris_reg+0x62] ; Save the return address in BRP\n" +" move $usp,[cris_reg+0x66] ; USP\n" +"\n" +";; get the serial character (from debugport.c) and check if it is a ctrl-c\n" +"\n" +" jsr getDebugChar\n" +" cmp.b 3, $r10\n" +" bne goback\n" +" nop\n" +"\n" +" move.d [cris_reg+0x5E], $r10 ; Get DCCR\n" +" btstq 8, $r10 ; Test the U-flag.\n" +" bmi goback\n" +" nop\n" +"\n" +";;\n" +";; Handle the communication\n" +";;\n" +" move.d internal_stack+1020,$sp ; Use the internal stack\n" +" moveq 2,$r10 ; SIGINT\n" +" jsr handle_exception ; Interactive routine\n" +"\n" +"goback:\n" +";;\n" +";; Return to the caller\n" +";;\n" +" move.d [cris_reg],$r0 ; Restore R0\n" +" move.d [cris_reg+0x04],$r1 ; Restore R1\n" +" move.d [cris_reg+0x08],$r2 ; Restore R2\n" +" move.d [cris_reg+0x0C],$r3 ; Restore R3\n" +" move.d [cris_reg+0x10],$r4 ; Restore R4\n" +" move.d [cris_reg+0x14],$r5 ; Restore R5\n" +" move.d [cris_reg+0x18],$r6 ; Restore R6\n" +" move.d [cris_reg+0x1C],$r7 ; Restore R7\n" +" move.d [cris_reg+0x20],$r8 ; Restore R8\n" +" move.d [cris_reg+0x24],$r9 ; Restore R9\n" +" move.d [cris_reg+0x28],$r10 ; Restore R10\n" +" move.d [cris_reg+0x2C],$r11 ; Restore R11\n" +" move.d [cris_reg+0x30],$r12 ; Restore R12\n" +" move.d [cris_reg+0x34],$r13 ; Restore R13\n" +";;\n" +";; FIXME: Which registers should be restored?\n" +";;\n" +" move.d [cris_reg+0x38],$sp ; Restore SP (R14)\n" +" move [cris_reg+0x56],$srp ; Restore the subroutine return pointer.\n" +" move [cris_reg+0x5E],$dccr ; Restore DCCR\n" +" move [cris_reg+0x66],$usp ; Restore USP\n" +" reti ; Return from the interrupt routine\n" +" nop\n" +"\n"); /* Use this static breakpoint in the start-up only. */ diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c index bd9b3ff63f6..02b783457be 100644 --- a/arch/cris/arch-v10/kernel/process.c +++ b/arch/cris/arch-v10/kernel/process.c @@ -11,11 +11,13 @@ */ #include <linux/sched.h> +#include <linux/slab.h> #include <linux/err.h> #include <linux/fs.h> -#include <linux/slab.h> #include <arch/svinto.h> #include <linux/init.h> +#include <arch/system.h> +#include <linux/ptrace.h> #ifdef CONFIG_ETRAX_GPIO void etrax_gpio_wake_up_check(void); /* drivers/gpio.c */ @@ -28,8 +30,9 @@ void etrax_gpio_wake_up_check(void); /* drivers/gpio.c */ void default_idle(void) { #ifdef CONFIG_ETRAX_GPIO - etrax_gpio_wake_up_check(); + etrax_gpio_wake_up_check(); #endif + local_irq_enable(); } /* @@ -53,14 +56,14 @@ void hard_reset_now (void) * code to know about it than the watchdog handler in entry.S and * this code, implementing hard reset through the watchdog. */ -#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM) +#if defined(CONFIG_ETRAX_WATCHDOG) extern int cause_of_death; #endif printk("*** HARD RESET ***\n"); local_irq_disable(); -#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM) +#if defined(CONFIG_ETRAX_WATCHDOG) cause_of_death = 0xbedead; #else /* Since we dont plan to keep on resetting the watchdog, @@ -80,31 +83,6 @@ unsigned long thread_saved_pc(struct task_struct *t) return task_pt_regs(t)->irp; } -static void kernel_thread_helper(void* dummy, int (*fn)(void *), void * arg) -{ - fn(arg); - do_exit(-1); /* Should never be called, return bad exit value */ -} - -/* - * Create a kernel thread - */ -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) -{ - struct pt_regs regs; - - memset(®s, 0, sizeof(regs)); - - /* Don't use r10 since that is set to 0 in copy_thread */ - regs.r11 = (unsigned long)fn; - regs.r12 = (unsigned long)arg; - regs.irp = (unsigned long)kernel_thread_helper; - regs.dccr = 1 << I_DCCR_BITNR; - - /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); -} - /* setup the child's kernel stack with a pt_regs and switch_stack on it. * it will be un-nested during _resume and _ret_from_sys_call when the * new thread is scheduled. @@ -114,29 +92,34 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) * */ asmlinkage void ret_from_fork(void); +asmlinkage void ret_from_kernel_thread(void); -int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, - unsigned long unused, - struct task_struct *p, struct pt_regs *regs) +int copy_thread(unsigned long clone_flags, unsigned long usp, + unsigned long arg, struct task_struct *p) { - struct pt_regs * childregs; - struct switch_stack *swstack; + struct pt_regs *childregs = task_pt_regs(p); + struct switch_stack *swstack = ((struct switch_stack *)childregs) - 1; /* put the pt_regs structure at the end of the new kernel stack page and fix it up * remember that the task_struct doubles as the kernel stack for the task */ - childregs = task_pt_regs(p); - - *childregs = *regs; /* struct copy of pt_regs */ - - p->set_child_tid = p->clear_child_tid = NULL; + if (unlikely(p->flags & PF_KTHREAD)) { + memset(swstack, 0, + sizeof(struct switch_stack) + sizeof(struct pt_regs)); + swstack->r1 = usp; + swstack->r2 = arg; + childregs->dccr = 1 << I_DCCR_BITNR; + swstack->return_ip = (unsigned long) ret_from_kernel_thread; + p->thread.ksp = (unsigned long) swstack; + p->thread.usp = 0; + return 0; + } + *childregs = *current_pt_regs(); /* struct copy of pt_regs */ childregs->r10 = 0; /* child returns 0 after a fork/clone */ - - /* put the switch stack right below the pt_regs */ - swstack = ((struct switch_stack *)childregs) - 1; + /* put the switch stack right below the pt_regs */ swstack->r9 = 0; /* parameter to ret_from_sys_call, 0 == dont restart the syscall */ @@ -146,7 +129,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, /* fix the user-mode stackpointer */ - p->thread.usp = usp; + p->thread.usp = usp ?: rdusp(); /* and the kernel-mode one */ @@ -160,68 +143,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, return 0; } -/* - * Be aware of the "magic" 7th argument in the four system-calls below. - * They need the latest stackframe, which is put as the 7th argument by - * entry.S. The previous arguments are dummies or actually used, but need - * to be defined to reach the 7th argument. - * - * N.B.: Another method to get the stackframe is to use current_regs(). But - * it returns the latest stack-frame stacked when going from _user mode_ and - * some of these (at least sys_clone) are called from kernel-mode sometimes - * (for example during kernel_thread, above) and thus cannot use it. Thus, - * to be sure not to get any surprises, we use the method for the other calls - * as well. - */ - -asmlinkage int sys_fork(long r10, long r11, long r12, long r13, long mof, long srp, - struct pt_regs *regs) -{ - return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL); -} - -/* if newusp is 0, we just grab the old usp */ -/* FIXME: Is parent_tid/child_tid really third/fourth argument? Update lib? */ -asmlinkage int sys_clone(unsigned long newusp, unsigned long flags, - int* parent_tid, int* child_tid, long mof, long srp, - struct pt_regs *regs) -{ - if (!newusp) - newusp = rdusp(); - return do_fork(flags, newusp, regs, 0, parent_tid, child_tid); -} - -/* vfork is a system call in i386 because of register-pressure - maybe - * we can remove it and handle it in libc but we put it here until then. - */ - -asmlinkage int sys_vfork(long r10, long r11, long r12, long r13, long mof, long srp, - struct pt_regs *regs) -{ - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL); -} - -/* - * sys_execve() executes a new program. - */ -asmlinkage int sys_execve(const char *fname, char **argv, char **envp, - long r13, long mof, long srp, - struct pt_regs *regs) -{ - int error; - char *filename; - - filename = getname(fname); - error = PTR_ERR(filename); - - if (IS_ERR(filename)) - goto out; - error = do_execve(filename, argv, envp, regs); - putname(filename); - out: - return error; -} - unsigned long get_wchan(struct task_struct *p) { #if 0 @@ -255,6 +176,9 @@ unsigned long get_wchan(struct task_struct *p) void show_regs(struct pt_regs * regs) { unsigned long usp = rdusp(); + + show_regs_print_info(KERN_DEFAULT); + printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n", regs->irp, regs->srp, regs->dccr, usp, regs->mof ); printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n", diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c index ee505b2eb4d..bfddfb99401 100644 --- a/arch/cris/arch-v10/kernel/ptrace.c +++ b/arch/cris/arch-v10/kernel/ptrace.c @@ -15,7 +15,6 @@ #include <asm/uaccess.h> #include <asm/page.h> #include <asm/pgtable.h> -#include <asm/system.h> #include <asm/processor.h> /* @@ -76,9 +75,11 @@ ptrace_disable(struct task_struct *child) * (in user space) where the result of the ptrace call is written (instead of * being returned). */ -long arch_ptrace(struct task_struct *child, long request, long addr, long data) +long arch_ptrace(struct task_struct *child, long request, + unsigned long addr, unsigned long data) { int ret; + unsigned int regno = addr >> 2; unsigned long __user *datap = (unsigned long __user *)data; switch (request) { @@ -93,10 +94,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) unsigned long tmp; ret = -EIO; - if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) + if ((addr & 3) || regno > PT_MAX) break; - tmp = get_reg(child, addr >> 2); + tmp = get_reg(child, regno); ret = put_user(tmp, datap); break; } @@ -110,71 +111,18 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) /* Write the word at location address in the USER area. */ case PTRACE_POKEUSR: ret = -EIO; - if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) + if ((addr & 3) || regno > PT_MAX) break; - addr >>= 2; - - if (addr == PT_DCCR) { + if (regno == PT_DCCR) { /* don't allow the tracing process to change stuff like * interrupt enable, kernel/user bit, dma enables etc. */ data &= DCCR_MASK; data |= get_reg(child, PT_DCCR) & ~DCCR_MASK; } - if (put_reg(child, addr, data)) - break; - ret = 0; - break; - - case PTRACE_SYSCALL: - case PTRACE_CONT: - ret = -EIO; - - if (!valid_signal(data)) - break; - - if (request == PTRACE_SYSCALL) { - set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - } - else { - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - } - - child->exit_code = data; - - /* TODO: make sure any pending breakpoint is killed */ - wake_up_process(child); - ret = 0; - - break; - - /* Make the child exit by sending it a sigkill. */ - case PTRACE_KILL: - ret = 0; - - if (child->exit_state == EXIT_ZOMBIE) - break; - - child->exit_code = SIGKILL; - - /* TODO: make sure any pending breakpoint is killed */ - wake_up_process(child); - break; - - /* Set the trap flag. */ - case PTRACE_SINGLESTEP: - ret = -EIO; - - if (!valid_signal(data)) + if (put_reg(child, regno, data)) break; - - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - - /* TODO: set some clever breakpoint mechanism... */ - - child->exit_code = data; - wake_up_process(child); ret = 0; break; @@ -192,7 +140,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; } - data += sizeof(long); + datap++; } break; @@ -216,7 +164,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) } put_reg(child, i, tmp); - data += sizeof(long); + datap++; } break; diff --git a/arch/cris/arch-v10/kernel/setup.c b/arch/cris/arch-v10/kernel/setup.c index de27b50b72a..4f96d71b515 100644 --- a/arch/cris/arch-v10/kernel/setup.c +++ b/arch/cris/arch-v10/kernel/setup.c @@ -14,6 +14,7 @@ #include <linux/proc_fs.h> #include <linux/delay.h> #include <linux/param.h> +#include <arch/system.h> #ifdef CONFIG_PROC_FS #define HAS_FPU 0x0001 diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c index b6be705c2a3..61ce6273a89 100644 --- a/arch/cris/arch-v10/kernel/signal.c +++ b/arch/cris/arch-v10/kernel/signal.c @@ -27,11 +27,10 @@ #include <asm/processor.h> #include <asm/ucontext.h> #include <asm/uaccess.h> +#include <arch/system.h> #define DEBUG_SIG 0 -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - /* a syscall in Linux/CRIS is a break 13 instruction which is 2 bytes */ /* manipulate regs so that upon return, it will be re-executed */ @@ -43,63 +42,6 @@ void do_signal(int canrestart, struct pt_regs *regs); /* - * Atomically swap in the new signal mask, and wait for a signal. Define - * dummy arguments to be able to reach the regs argument. (Note that this - * arrangement relies on old_sigset_t occupying one register.) - */ -int sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, - long srp, struct pt_regs *regs) -{ - mask &= _BLOCKABLE; - spin_lock_irq(¤t->sighand->siglock); - current->saved_sigmask = current->blocked; - siginitset(¤t->blocked, mask); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - current->state = TASK_INTERRUPTIBLE; - schedule(); - set_thread_flag(TIF_RESTORE_SIGMASK); - return -ERESTARTNOHAND; -} - -int sys_sigaction(int sig, const struct old_sigaction __user *act, - struct old_sigaction *oact) -{ - struct k_sigaction new_ka, old_ka; - int ret; - - if (act) { - old_sigset_t mask; - if (!access_ok(VERIFY_READ, act, sizeof(*act)) || - __get_user(new_ka.sa.sa_handler, &act->sa_handler) || - __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) - return -EFAULT; - __get_user(new_ka.sa.sa_flags, &act->sa_flags); - __get_user(mask, &act->sa_mask); - siginitset(&new_ka.sa.sa_mask, mask); - } - - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); - - if (!ret && oact) { - if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || - __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || - __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) - return -EFAULT; - __put_user(old_ka.sa.sa_flags, &oact->sa_flags); - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); - } - - return ret; -} - -int sys_sigaltstack(const stack_t *uss, stack_t __user *uoss) -{ - return do_sigaltstack(uss, uoss, rdusp()); -} - - -/* * Do a signal return; undo the signal stack. */ @@ -159,11 +101,9 @@ badframe: return 1; } -/* Define dummy arguments to be able to reach the regs argument. */ - -asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof, - long srp, struct pt_regs *regs) +asmlinkage int sys_sigreturn(void) { + struct pt_regs *regs = current_pt_regs(); struct sigframe __user *frame = (struct sigframe *)rdusp(); sigset_t set; @@ -183,11 +123,7 @@ asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof, sizeof(frame->extramask)))) goto badframe; - sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); if (restore_sigcontext(regs, &frame->sc)) goto badframe; @@ -201,11 +137,9 @@ badframe: return 0; } -/* Define dummy arguments to be able to reach the regs argument. */ - -asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13, - long mof, long srp, struct pt_regs *regs) +asmlinkage int sys_rt_sigreturn(void) { + struct pt_regs *regs = current_pt_regs(); struct rt_sigframe __user *frame = (struct rt_sigframe *)rdusp(); sigset_t set; @@ -222,16 +156,12 @@ asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13, if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) goto badframe; - sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) goto badframe; - if (do_sigaltstack(&frame->uc.uc_stack, NULL, rdusp()) == -EFAULT) + if (restore_altstack(&frame->uc.uc_stack)) goto badframe; return regs->r10; @@ -379,6 +309,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + err |= __save_altstack(&frame->uc.uc_stack, rdusp()); + if (err) goto give_sigsegv; @@ -428,10 +360,11 @@ give_sigsegv: * OK, we're invoking a handler */ -static inline int handle_signal(int canrestart, unsigned long sig, +static inline void handle_signal(int canrestart, unsigned long sig, siginfo_t *info, struct k_sigaction *ka, - sigset_t *oldset, struct pt_regs *regs) + struct pt_regs *regs) { + sigset_t *oldset = sigmask_to_save(); int ret; /* Are we from a system call? */ @@ -468,16 +401,8 @@ static inline int handle_signal(int canrestart, unsigned long sig, else ret = setup_frame(sig, ka, oldset, regs); - if (ret == 0) { - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked, ¤t->blocked, - &ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked, sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - } - return ret; + if (ret == 0) + signal_delivered(sig, info, ka, regs, 0); } /* @@ -497,7 +422,6 @@ void do_signal(int canrestart, struct pt_regs *regs) siginfo_t info; int signr; struct k_sigaction ka; - sigset_t *oldset; /* * We want the common case to go fast, which @@ -508,23 +432,10 @@ void do_signal(int canrestart, struct pt_regs *regs) if (!user_mode(regs)) return; - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else - oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ - if (handle_signal(canrestart, signr, &info, &ka, - oldset, regs)) { - /* a signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); - } + handle_signal(canrestart, signr, &info, &ka, regs); return; } @@ -537,15 +448,12 @@ void do_signal(int canrestart, struct pt_regs *regs) RESTART_CRIS_SYS(regs); } if (regs->r10 == -ERESTART_RESTARTBLOCK) { - regs->r10 = __NR_restart_syscall; + regs->r9 = __NR_restart_syscall; regs->irp -= 2; } } /* if there's no signal to deliver, we just put the saved sigmask * back */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } + restore_saved_sigmask(); } diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c index c685ba4c338..b5eb5cd2f60 100644 --- a/arch/cris/arch-v10/kernel/time.c +++ b/arch/cris/arch-v10/kernel/time.c @@ -14,23 +14,16 @@ #include <linux/sched.h> #include <linux/init.h> #include <linux/mm.h> -#include <arch/svinto.h> #include <asm/types.h> #include <asm/signal.h> #include <asm/io.h> #include <asm/delay.h> -#include <asm/rtc.h> #include <asm/irq_regs.h> /* define this if you need to use print_timestamp */ /* it will make jiffies at 96 hz instead of 100 hz though */ #undef USE_CASCADE_TIMERS -extern void update_xtime_from_cmos(void); -extern int set_rtc_mmss(unsigned long nowtime); -extern int setup_irq(int, struct irqaction *); -extern int have_rtc; - unsigned long get_ns_in_jiffie(void) { unsigned char timer_count, t1; @@ -40,7 +33,7 @@ unsigned long get_ns_in_jiffie(void) local_irq_save(flags); timer_count = *R_TIMER0_DATA; - presc_count = *R_TIM_PRESC_STATUS; + presc_count = *R_TIM_PRESC_STATUS; /* presc_count might be wrapped */ t1 = *R_TIMER0_DATA; @@ -56,73 +49,23 @@ unsigned long get_ns_in_jiffie(void) presc_count = PRESCALE_VALUE - presc_count - PRESCALE_VALUE/2; } - ns = ( (TIMER0_DIV - timer_count) * ((1000000000/HZ)/TIMER0_DIV )) + + ns = ( (TIMER0_DIV - timer_count) * ((1000000000/HZ)/TIMER0_DIV )) + ( (presc_count) * (1000000000/PRESCALE_FREQ)); return ns; } -unsigned long do_slow_gettimeoffset(void) +static u32 cris_v10_gettimeoffset(void) { - unsigned long count, t1; - unsigned long usec_count = 0; - unsigned short presc_count; - - static unsigned long count_p = TIMER0_DIV;/* for the first call after boot */ - static unsigned long jiffies_p = 0; - - /* - * cache volatile jiffies temporarily; we have IRQs turned off. - */ - unsigned long jiffies_t; + u32 count; /* The timer interrupt comes from Etrax timer 0. In order to get * better precision, we check the current value. It might have * underflowed already though. */ - -#ifndef CONFIG_SVINTO_SIM - /* Not available in the xsim simulator. */ count = *R_TIMER0_DATA; - presc_count = *R_TIM_PRESC_STATUS; - /* presc_count might be wrapped */ - t1 = *R_TIMER0_DATA; - if (count != t1){ - /* it wrapped, read prescaler again... */ - presc_count = *R_TIM_PRESC_STATUS; - count = t1; - } -#else - count = 0; - presc_count = 0; -#endif - jiffies_t = jiffies; - - /* - * avoiding timer inconsistencies (they are rare, but they happen)... - * there are one problem that must be avoided here: - * 1. the timer counter underflows - */ - if( jiffies_t == jiffies_p ) { - if( count > count_p ) { - /* Timer wrapped, use new count and prescale - * increase the time corresponding to one jiffie - */ - usec_count = 1000000/HZ; - } - } else - jiffies_p = jiffies_t; - count_p = count; - if (presc_count >= PRESCALE_VALUE/2 ){ - presc_count = PRESCALE_VALUE - presc_count + PRESCALE_VALUE/2; - } else { - presc_count = PRESCALE_VALUE - presc_count - PRESCALE_VALUE/2; - } - /* Convert timer value to usec */ - usec_count += ( (TIMER0_DIV - count) * (1000000/HZ)/TIMER0_DIV ) + - (( (presc_count) * (1000000000/PRESCALE_FREQ))/1000); - - return usec_count; + /* Convert timer value to nsec */ + return (TIMER0_DIV - count) * (NSEC_PER_SEC/HZ)/TIMER0_DIV; } /* Excerpt from the Etrax100 HSDD about the built-in watchdog: @@ -136,7 +79,7 @@ unsigned long do_slow_gettimeoffset(void) * by the R_WATCHDOG register. The R_WATCHDOG register contains an enable bit * and a 3-bit key value. The effect of writing to the R_WATCHDOG register is * described in the table below: - * + * * Watchdog Value written: * state: To enable: To key: Operation: * -------- ---------- ------- ---------- @@ -145,15 +88,15 @@ unsigned long do_slow_gettimeoffset(void) * started 0 ~key Stop watchdog * started 1 ~key Restart watchdog with key = ~key. * started X new_key_val Change key to new_key_val. - * + * * Note: '~' is the bitwise NOT operator. - * + * */ /* right now, starting the watchdog is the same as resetting it */ #define start_watchdog reset_watchdog -#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM) +#ifdef CONFIG_ETRAX_WATCHDOG static int watchdog_key = 0; /* arbitrary number */ #endif @@ -163,10 +106,9 @@ static int watchdog_key = 0; /* arbitrary number */ #define WATCHDOG_MIN_FREE_PAGES 8 -void -reset_watchdog(void) +void reset_watchdog(void) { -#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM) +#if defined(CONFIG_ETRAX_WATCHDOG) /* only keep watchdog happy as long as we have memory left! */ if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) { /* reset the watchdog with the inverse of the old key */ @@ -179,30 +121,23 @@ reset_watchdog(void) /* stop the watchdog - we still need the correct key */ -void -stop_watchdog(void) +void stop_watchdog(void) { -#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM) +#ifdef CONFIG_ETRAX_WATCHDOG watchdog_key ^= 0x7; /* invert key, which is 3 bits */ *R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, watchdog_key) | IO_STATE(R_WATCHDOG, enable, stop); -#endif +#endif } -/* last time the cmos clock got updated */ -static long last_rtc_update = 0; + +extern void cris_do_profile(struct pt_regs *regs); /* * timer_interrupt() needs to keep up the real-time clock, - * as well as call the "do_timer()" routine every clocktick + * as well as call the "xtime_update()" routine every clocktick */ - -//static unsigned short myjiff; /* used by our debug routine print_timestamp */ - -extern void cris_do_profile(struct pt_regs *regs); - -static inline irqreturn_t -timer_interrupt(int irq, void *dev_id) +static inline irqreturn_t timer_interrupt(int irq, void *dev_id) { struct pt_regs *regs = get_irq_regs(); /* acknowledge the timer irq */ @@ -218,80 +153,41 @@ timer_interrupt(int irq, void *dev_id) IO_STATE( R_TIMER_CTRL, tm0, run) | IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz); #else - *R_TIMER_CTRL = r_timer_ctrl_shadow | - IO_STATE(R_TIMER_CTRL, i0, clr); + *R_TIMER_CTRL = r_timer_ctrl_shadow | IO_STATE(R_TIMER_CTRL, i0, clr); #endif /* reset watchdog otherwise it resets us! */ reset_watchdog(); - + /* Update statistics. */ update_process_times(user_mode(regs)); /* call the real timer interrupt handler */ + xtime_update(1); - do_timer(1); - cris_do_profile(regs); /* Save profiling information */ - - /* - * If we have an externally synchronized Linux clock, then update - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - * - * The division here is not time critical since it will run once in - * 11 minutes - */ - if (ntp_synced() && - xtime.tv_sec > last_rtc_update + 660 && - (xtime.tv_nsec / 1000) >= 500000 - (tick_nsec / 1000) / 2 && - (xtime.tv_nsec / 1000) <= 500000 + (tick_nsec / 1000) / 2) { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ - } return IRQ_HANDLED; } -/* timer is IRQF_SHARED so drivers can add stuff to the timer irq chain - * it needs to be IRQF_DISABLED to make the jiffies update work properly - */ +/* timer is IRQF_SHARED so drivers can add stuff to the timer irq chain */ static struct irqaction irq2 = { .handler = timer_interrupt, - .flags = IRQF_SHARED | IRQF_DISABLED, - .mask = CPU_MASK_NONE, + .flags = IRQF_SHARED, .name = "timer", }; -void __init -time_init(void) -{ - /* probe for the RTC and read it if it exists - * Before the RTC can be probed the loops_per_usec variable needs - * to be initialized to make usleep work. A better value for - * loops_per_usec is calculated by the kernel later once the - * clock has started. - */ - loops_per_usec = 50; - - if(RTC_INIT() < 0) { - /* no RTC, start at 1980 */ - xtime.tv_sec = 0; - xtime.tv_nsec = 0; - have_rtc = 0; - } else { - /* get the current time */ - have_rtc = 1; - update_xtime_from_cmos(); - } +void __init time_init(void) +{ + arch_gettimeoffset = cris_v10_gettimeoffset; - /* - * Initialize wall_to_monotonic such that adding it to xtime will yield zero, the - * tv_nsec field must be normalized (i.e., 0 <= nsec < NSEC_PER_SEC). + /* probe for the RTC and read it if it exists + * Before the RTC can be probed the loops_per_usec variable needs + * to be initialized to make usleep work. A better value for + * loops_per_usec is calculated by the kernel later once the + * clock has started. */ - set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); + loops_per_usec = 50; /* Setup the etrax timers * Base frequency is 25000 hz, divider 250 -> 100 HZ @@ -300,7 +196,7 @@ time_init(void) * Remember that linux/timex.h contains #defines that rely on the * timer settings below (hz and divide factor) !!! */ - + #ifdef USE_CASCADE_TIMERS *R_TIMER_CTRL = IO_FIELD( R_TIMER_CTRL, timerdiv1, 0) | @@ -311,8 +207,8 @@ time_init(void) IO_STATE( R_TIMER_CTRL, i0, nop) | IO_STATE( R_TIMER_CTRL, tm0, stop_ld) | IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz); - - *R_TIMER_CTRL = r_timer_ctrl_shadow = + + *R_TIMER_CTRL = r_timer_ctrl_shadow = IO_FIELD( R_TIMER_CTRL, timerdiv1, 0) | IO_FIELD( R_TIMER_CTRL, timerdiv0, 0) | IO_STATE( R_TIMER_CTRL, i1, nop) | @@ -322,18 +218,18 @@ time_init(void) IO_STATE( R_TIMER_CTRL, tm0, run) | IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz); #else - *R_TIMER_CTRL = - IO_FIELD(R_TIMER_CTRL, timerdiv1, 192) | + *R_TIMER_CTRL = + IO_FIELD(R_TIMER_CTRL, timerdiv1, 192) | IO_FIELD(R_TIMER_CTRL, timerdiv0, TIMER0_DIV) | - IO_STATE(R_TIMER_CTRL, i1, nop) | + IO_STATE(R_TIMER_CTRL, i1, nop) | IO_STATE(R_TIMER_CTRL, tm1, stop_ld) | IO_STATE(R_TIMER_CTRL, clksel1, c19k2Hz) | IO_STATE(R_TIMER_CTRL, i0, nop) | IO_STATE(R_TIMER_CTRL, tm0, stop_ld) | IO_STATE(R_TIMER_CTRL, clksel0, flexible); - + *R_TIMER_CTRL = r_timer_ctrl_shadow = - IO_FIELD(R_TIMER_CTRL, timerdiv1, 192) | + IO_FIELD(R_TIMER_CTRL, timerdiv1, 192) | IO_FIELD(R_TIMER_CTRL, timerdiv0, TIMER0_DIV) | IO_STATE(R_TIMER_CTRL, i1, nop) | IO_STATE(R_TIMER_CTRL, tm1, run) | @@ -345,16 +241,14 @@ time_init(void) *R_TIMER_PRESCALE = PRESCALE_VALUE; #endif - *R_IRQ_MASK0_SET = - IO_STATE(R_IRQ_MASK0_SET, timer0, set); /* unmask the timer irq */ - - /* now actually register the timer irq handler that calls timer_interrupt() */ - + /* unmask the timer irq */ + *R_IRQ_MASK0_SET = IO_STATE(R_IRQ_MASK0_SET, timer0, set); + + /* now actually register the irq handler that calls timer_interrupt() */ setup_irq(2, &irq2); /* irq 2 is the timer0 irq in etrax */ /* enable watchdog if we should use one */ - -#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM) +#if defined(CONFIG_ETRAX_WATCHDOG) printk("Enabling watchdog...\n"); start_watchdog(); @@ -367,9 +261,7 @@ time_init(void) driver or infrastructure support yet. */ asm ("setf m"); - *R_IRQ_MASK0_SET = - IO_STATE(R_IRQ_MASK0_SET, watchdog_nmi, set); - *R_VECT_MASK_SET = - IO_STATE(R_VECT_MASK_SET, nmi, set); + *R_IRQ_MASK0_SET = IO_STATE(R_IRQ_MASK0_SET, watchdog_nmi, set); + *R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, nmi, set); #endif } diff --git a/arch/cris/arch-v10/kernel/traps.c b/arch/cris/arch-v10/kernel/traps.c index 8bebb96bbca..7001beda716 100644 --- a/arch/cris/arch-v10/kernel/traps.c +++ b/arch/cris/arch-v10/kernel/traps.c @@ -11,6 +11,7 @@ #include <linux/ptrace.h> #include <asm/uaccess.h> #include <arch/sv_addr_ag.h> +#include <arch/system.h> void show_registers(struct pt_regs *regs) diff --git a/arch/cris/arch-v10/lib/Makefile b/arch/cris/arch-v10/lib/Makefile index 36e9a9c5239..725153edb76 100644 --- a/arch/cris/arch-v10/lib/Makefile +++ b/arch/cris/arch-v10/lib/Makefile @@ -2,8 +2,5 @@ # Makefile for Etrax-specific library files.. # - -EXTRA_AFLAGS := -traditional - lib-y = checksum.o checksumcopy.o string.o usercopy.o memset.o csumcpfruser.o diff --git a/arch/cris/arch-v10/lib/dmacopy.c b/arch/cris/arch-v10/lib/dmacopy.c index e5fb44f505c..49f5b8ca5b4 100644 --- a/arch/cris/arch-v10/lib/dmacopy.c +++ b/arch/cris/arch-v10/lib/dmacopy.c @@ -1,5 +1,4 @@ -/* $Id: dmacopy.c,v 1.1 2001/12/17 13:59:27 bjornw Exp $ - * +/* * memcpy for large blocks, using memory-memory DMA channels 6 and 7 in Etrax */ @@ -13,11 +12,11 @@ void *dma_memcpy(void *pdst, unsigned int pn) { static etrax_dma_descr indma, outdma; - - D(printk("dma_memcpy %d bytes... ", pn)); + + D(printk(KERN_DEBUG "dma_memcpy %d bytes... ", pn)); #if 0 - *R_GEN_CONFIG = genconfig_shadow = + *R_GEN_CONFIG = genconfig_shadow = (genconfig_shadow & ~0x3c0000) | IO_STATE(R_GEN_CONFIG, dma6, intdma7) | IO_STATE(R_GEN_CONFIG, dma7, intdma6); @@ -32,11 +31,11 @@ void *dma_memcpy(void *pdst, *R_DMA_CH7_FIRST = &outdma; *R_DMA_CH6_CMD = IO_STATE(R_DMA_CH6_CMD, cmd, start); *R_DMA_CH7_CMD = IO_STATE(R_DMA_CH7_CMD, cmd, start); - - while(*R_DMA_CH7_CMD == 1) /* wait for completion */ ; - D(printk("done\n")); + while (*R_DMA_CH7_CMD == 1) + /* wait for completion */; + D(printk(KERN_DEBUG "done\n")); } diff --git a/arch/cris/arch-v10/lib/dram_init.S b/arch/cris/arch-v10/lib/dram_init.S index b9190ff7d0a..e541d3d8f92 100644 --- a/arch/cris/arch-v10/lib/dram_init.S +++ b/arch/cris/arch-v10/lib/dram_init.S @@ -5,9 +5,7 @@ * Note: This file may not modify r9 because r9 is used to carry * information from the decompresser to the kernel * - * Copyright (C) 2000, 2001 Axis Communications AB - * - * Authors: Mikael Starvik (starvik@axis.com) + * Copyright (C) 2000-2012 Axis Communications AB * */ @@ -18,16 +16,15 @@ ;; WARNING! The registers r8 and r9 are used as parameters carrying - ;; information from the decompressor (if the kernel was compressed). + ;; information from the decompressor (if the kernel was compressed). ;; They should not be used in the code below. -#ifndef CONFIG_SVINTO_SIM move.d CONFIG_ETRAX_DEF_R_WAITSTATES, $r0 move.d $r0, [R_WAITSTATES] move.d CONFIG_ETRAX_DEF_R_BUS_CONFIG, $r0 move.d $r0, [R_BUS_CONFIG] - + #ifndef CONFIG_ETRAX_SDRAM move.d CONFIG_ETRAX_DEF_R_DRAM_CONFIG, $r0 move.d $r0, [R_DRAM_CONFIG] @@ -38,14 +35,14 @@ ;; Samsung SDRAMs seem to require to be initialized twice to work properly. moveq 2, $r6 _sdram_init: - + ; Refer to ETRAX 100LX Designers Reference for a description of SDRAM initialization - + ; Bank configuration move.d CONFIG_ETRAX_DEF_R_SDRAM_CONFIG, $r0 move.d $r0, [R_SDRAM_CONFIG] - ; Calculate value of mrs_data + ; Calculate value of mrs_data ; CAS latency = 2 && bus_width = 32 => 0x40 ; CAS latency = 3 && bus_width = 32 => 0x60 ; CAS latency = 2 && bus_width = 16 => 0x20 @@ -56,22 +53,22 @@ _sdram_init: and.d 0x00ff0000, $r2 bne _set_timing lsrq 16, $r2 - + move.d 0x40, $r2 ; Assume 32 bits and CAS latency = 2 move.d CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r1 move.d $r1, $r3 - and.d 0x03, $r1 ; Get CAS latency + and.d 0x03, $r1 ; Get CAS latency and.d 0x1000, $r3 ; 50 or 100 MHz? beq _speed_50 nop -_speed_100: +_speed_100: cmp.d 0x00, $r1 ; CAS latency = 2? beq _bw_check nop - or.d 0x20, $r2 ; CAS latency = 3 + or.d 0x20, $r2 ; CAS latency = 3 ba _bw_check nop -_speed_50: +_speed_50: cmp.d 0x01, $r1 ; CAS latency = 2? beq _bw_check nop @@ -86,19 +83,19 @@ _bw_check: ; Set timing parameters. Starts master clock _set_timing: move.d CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r1 - and.d 0x8000f9ff, $r1 ; Make sure mrs data and command is 0 + and.d 0x8000f9ff, $r1 ; Make sure mrs data and command is 0 or.d 0x80000000, $r1 ; Make sure sdram enable bit is set move.d $r1, $r5 or.d 0x0000c000, $r1 ; ref = disable lslq 16, $r2 ; mrs data starts at bit 16 - or.d $r2, $r1 - move.d $r1, [R_SDRAM_TIMING] - + or.d $r2, $r1 + move.d $r1, [R_SDRAM_TIMING] + ; Wait 200us move.d 10000, $r2 1: bne 1b subq 1, $r2 - + ; Issue initialization command sequence move.d _sdram_commands_start, $r2 and.d 0x000fffff, $r2 ; Make sure commands are read from flash @@ -144,7 +141,6 @@ _sdram_commands_start: .byte 2 ; refresh .byte 0 ; nop .byte 1 ; mrs - .byte 0 ; nop -_sdram_commands_end: -#endif + .byte 0 ; nop +_sdram_commands_end: #endif diff --git a/arch/cris/arch-v10/lib/hw_settings.S b/arch/cris/arch-v10/lib/hw_settings.S index 56905aaa7b6..c09f19f478a 100644 --- a/arch/cris/arch-v10/lib/hw_settings.S +++ b/arch/cris/arch-v10/lib/hw_settings.S @@ -1,13 +1,11 @@ /* - * $Id: hw_settings.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $ - * * This table is used by some tools to extract hardware parameters. * The table should be included in the kernel and the decompressor. * Don't forget to update the tools if you change this table. * * Copyright (C) 2001 Axis Communications AB * - * Authors: Mikael Starvik (starvik@axis.com) + * Authors: Mikael Starvik (starvik@axis.com) */ #define PA_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PA_DIR << 8) | \ @@ -15,13 +13,13 @@ #define PB_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG << 16) | \ (CONFIG_ETRAX_DEF_R_PORT_PB_DIR << 8) | \ (CONFIG_ETRAX_DEF_R_PORT_PB_DATA)) - + .ascii "HW_PARAM_MAGIC" ; Magic number .dword 0xc0004000 ; Kernel start address ; Debug port #ifdef CONFIG_ETRAX_DEBUG_PORT0 - .dword 0 + .dword 0 #elif defined(CONFIG_ETRAX_DEBUG_PORT1) .dword 1 #elif defined(CONFIG_ETRAX_DEBUG_PORT2) @@ -30,7 +28,7 @@ .dword 3 #else .dword 4 ; No debug -#endif +#endif ; SDRAM or EDO DRAM? #ifdef CONFIG_ETRAX_SDRAM @@ -39,7 +37,7 @@ .dword 0 #endif - ; Register values + ; Register values .dword R_WAITSTATES .dword CONFIG_ETRAX_DEF_R_WAITSTATES .dword R_BUS_CONFIG @@ -56,7 +54,7 @@ .dword CONFIG_ETRAX_DEF_R_DRAM_TIMING #endif .dword R_PORT_PA_SET - .dword PA_SET_VALUE + .dword PA_SET_VALUE .dword R_PORT_PB_SET .dword PB_SET_VALUE .dword 0 ; No more register values diff --git a/arch/cris/arch-v10/lib/old_checksum.c b/arch/cris/arch-v10/lib/old_checksum.c index 1734b467efa..8f79163f139 100644 --- a/arch/cris/arch-v10/lib/old_checksum.c +++ b/arch/cris/arch-v10/lib/old_checksum.c @@ -77,7 +77,7 @@ __wsum csum_partial(const void *p, int len, __wsum __sum) sum += *buff++; if (endMarker > buff) - sum += *(const u8 *)buff; /* add extra byte seperately */ + sum += *(const u8 *)buff; /* add extra byte separately */ BITOFF; return (__force __wsum)sum; diff --git a/arch/cris/arch-v10/mm/fault.c b/arch/cris/arch-v10/mm/fault.c index 087a2096f22..ed60588f846 100644 --- a/arch/cris/arch-v10/mm/fault.c +++ b/arch/cris/arch-v10/mm/fault.c @@ -80,8 +80,7 @@ handle_mmu_bus_fault(struct pt_regs *regs) * do_page_fault may have flushed the TLB so we have to restore * the MMU registers. */ - local_save_flags(flags); - local_irq_disable(); + local_irq_save(flags); pmd = (pmd_t *)(pgd + pgd_index(address)); if (pmd_none(*pmd)) goto exit; diff --git a/arch/cris/arch-v10/mm/init.c b/arch/cris/arch-v10/mm/init.c index baa746ce4e7..e7f8066105a 100644 --- a/arch/cris/arch-v10/mm/init.c +++ b/arch/cris/arch-v10/mm/init.c @@ -241,7 +241,7 @@ flush_etrax_cacherange(void *startadr, int length) } /* Due to a bug in Etrax100(LX) all versions, receiving DMA buffers - * will occationally corrupt certain CPU writes if the DMA buffers + * will occasionally corrupt certain CPU writes if the DMA buffers * happen to be hot in the cache. * * As a workaround, we have to flush the relevant parts of the cache diff --git a/arch/cris/arch-v10/mm/tlb.c b/arch/cris/arch-v10/mm/tlb.c index 4a496e4ffac..21d78c599ba 100644 --- a/arch/cris/arch-v10/mm/tlb.c +++ b/arch/cris/arch-v10/mm/tlb.c @@ -134,28 +134,6 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) local_irq_restore(flags); } -/* dump the entire TLB for debug purposes */ - -#if 0 -void -dump_tlb_all(void) -{ - int i; - unsigned long flags; - - printk("TLB dump. LO is: pfn | reserved | global | valid | kernel | we |\n"); - - local_save_flags(flags); - local_irq_disable(); - for(i = 0; i < NUM_TLB_ENTRIES; i++) { - *R_TLB_SELECT = ( IO_FIELD(R_TLB_SELECT, index, i) ); - printk("Entry %d: HI 0x%08lx, LO 0x%08lx\n", - i, *R_TLB_HI, *R_TLB_LO); - } - local_irq_restore(flags); -} -#endif - /* * Initialize the context related info for a new mm_struct * instance. |
