diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-03-17 22:05:47 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-03-17 22:05:47 +0000 |
commit | 27cfca1ec98e91261b1a5355d10a8996464b63af (patch) | |
tree | 8e895a53e372fa682b4c0a585b9377d67ed70d0e /include/asm-arm | |
parent | 6a76fb7214c477ccf6582bd79c5b4ccc4f9c41b1 (diff) |
Look Ma' what I found on my harddisk ...
o New faster syscalls for 2.1.x, too
o Upgrade to 2.1.89.
Don't try to run this. It's flaky as hell. But feel free to debug ...
Diffstat (limited to 'include/asm-arm')
177 files changed, 11716 insertions, 0 deletions
diff --git a/include/asm-arm/a.out.h b/include/asm-arm/a.out.h new file mode 100644 index 000000000..45e4a9cd6 --- /dev/null +++ b/include/asm-arm/a.out.h @@ -0,0 +1,28 @@ +#ifndef __ARM_A_OUT_H__ +#define __ARM_A_OUT_H__ + +struct exec +{ + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + +/* + * This is always the same + */ +#define N_TXTADDR(a) (0x00008000) + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +#define M_ARM 103 + +#include <asm/arch/a.out.h> +#endif /* __A_OUT_GNU_H__ */ diff --git a/include/asm-arm/arcaudio.h b/include/asm-arm/arcaudio.h new file mode 100644 index 000000000..43a31bc79 --- /dev/null +++ b/include/asm-arm/arcaudio.h @@ -0,0 +1,51 @@ +/* + * arcaudio.h + * + */ + +#ifndef _LINUX_ARCAUDIO_H +#define _LINUX_ARCAUDIO_H + +#define ARCAUDIO_MAXCHANNELS 8 + +enum ch_type +{ + ARCAUDIO_NONE, /* No sound (muted) */ + ARCAUDIO_8BITSIGNED, /* signed 8 bits per samples */ + ARCAUDIO_8BITUNSIGNED, /* unsigned 8 bits per samples */ + ARCAUDIO_16BITSIGNED, /* signed 16 bits per samples (little endian) */ + ARCAUDIO_16BITUNSIGNED, /* unsigned 16 bits per samples (little endian) */ + ARCAUDIO_LOG /* Vidc Log */ +}; + +/* + * Global information + */ +struct arcaudio +{ + int sample_rate; /* sample rate (Hz) */ + int num_channels; /* number of channels */ + int volume; /* overall system volume */ +}; + +/* + * Per channel information + */ +struct arcaudio_channel +{ + int stereo_position; /* Channel position */ + int channel_volume; /* Channel volume */ + enum ch_type channel_type; /* Type of channel */ + int buffer_size; /* Size of channel buffer */ +}; + +/* IOCTLS */ +#define ARCAUDIO_GETINFO 0x6101 +#define ARCAUDIO_SETINFO 0x6102 +#define ARCAUDIO_GETCHANNELINFO 0x6111 +#define ARCAUDIO_SETCHANNELINFO 0x6112 +#define ARCAUDIO_GETOPTS 0x61f0 +#define ARCAUDIO_SETOPTS 0x61f1 +#define ARCAUDIO_OPTSPKR 1<<0 + +#endif diff --git a/include/asm-arm/arch-a5k/a.out.h b/include/asm-arm/arch-a5k/a.out.h new file mode 100644 index 000000000..065340745 --- /dev/null +++ b/include/asm-arm/arch-a5k/a.out.h @@ -0,0 +1,16 @@ +/* + * linux/include/asm-arm/arch-a5k/a.out.h + * + * Copyright (C) 1996 Russell King + */ + +#ifndef __ASM_ARCH_A_OUT_H +#define __ASM_ARCH_A_OUT_H + +#ifdef __KERNEL__ +#define STACK_TOP (0x01a00000) +#define LIBRARY_START_TEXT (0x00c00000) +#endif + +#endif + diff --git a/include/asm-arm/arch-a5k/dma.h b/include/asm-arm/arch-a5k/dma.h new file mode 100644 index 000000000..9acb5c122 --- /dev/null +++ b/include/asm-arm/arch-a5k/dma.h @@ -0,0 +1,101 @@ +#ifndef __ASM_ARCH_DMA_H +#define __ASM_ARCH_DMA_H + +#define MAX_DMA_ADDRESS 0x03000000 + +#ifdef KERNEL_ARCH_DMA + +static inline void arch_disable_dma (int dmanr) +{ + printk (dma_str, "arch_disable_dma", dmanr); +} + +static inline void arch_enable_dma (int dmanr) +{ + printk (dma_str, "arch_enable_dma", dmanr); +} + +static inline void arch_set_dma_addr (int dmanr, unsigned int addr) +{ + printk (dma_str, "arch_set_dma_addr", dmanr); +} + +static inline void arch_set_dma_count (int dmanr, unsigned int count) +{ + printk (dma_str, "arch_set_dma_count", dmanr); +} + +static inline void arch_set_dma_mode (int dmanr, char mode) +{ + printk (dma_str, "arch_set_dma_mode", dmanr); +} + +static inline int arch_dma_count (int dmanr) +{ + printk (dma_str, "arch_dma_count", dmanr); + return 0; +} + +#endif + +/* enable/disable a specific DMA channel */ +extern void enable_dma(unsigned int dmanr); + +static __inline__ void disable_dma(unsigned int dmanr) +{ + switch(dmanr) { + case 2: disable_irq(64); break; + default: printk (dma_str, "disable_dma", dmanr); break; + } +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while interrupts are disabled! --- + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ + switch(dmanr) { + case 2: break; + default: printk (dma_str, "clear_dma_ff", dmanr); break; + } +} + +/* set mode (above) for a specific DMA channel */ +extern void set_dma_mode(unsigned int dmanr, char mode); + +/* Set only the page register bits of the transfer address. + * This is used for successive transfers when we know the contents of + * the lower 16 bits of the DMA current address register, but a 64k boundary + * may have been crossed. + */ +static __inline__ void set_dma_page(unsigned int dmanr, char pagenr) +{ + printk (dma_str, "set_dma_page", dmanr); +} + + +/* Set transfer address & page bits for specific DMA channel. + * Assumes dma flipflop is clear. + */ +extern void set_dma_addr(unsigned int dmanr, unsigned int addr); + +/* Set transfer size for a specific DMA channel. + */ +extern void set_dma_count(unsigned int dmanr, unsigned int count); + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + * + * Assumes DMA flip-flop is clear. + */ +extern int get_dma_residue(unsigned int dmanr); + +#endif /* _ASM_ARCH_DMA_H */ + diff --git a/include/asm-arm/arch-a5k/hardware.h b/include/asm-arm/arch-a5k/hardware.h new file mode 100644 index 000000000..317b4c64f --- /dev/null +++ b/include/asm-arm/arch-a5k/hardware.h @@ -0,0 +1,81 @@ +/* + * linux/include/asm-arm/arch-a5k/hardware.h + * + * Copyright (C) 1996 Russell King. + * + * This file contains the hardware definitions of the A5000 series machines. + */ + +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +/* + * What hardware must be present + */ +#define HAS_IOC +#define HAS_PCIO +#define HAS_MEMC +#define HAS_MEMC1A +#define HAS_VIDC + +/* + * Optional hardware + */ +#define HAS_EXPMASK + +#ifndef __ASSEMBLER__ + +/* + * for use with inb/outb + */ +#define VIDC_BASE 0x80100000 +#define IOCEC4IO_BASE 0x8009c000 +#define IOCECIO_BASE 0x80090000 +#define IOC_BASE 0x80080000 +#define MEMCECIO_BASE 0x80000000 + +/* + * IO definitions + */ +#define EXPMASK_BASE ((volatile unsigned char *)0x03360000) +#define IOEB_BASE ((volatile unsigned char *)0x03350050) +#define PCIO_FLOPPYDMABASE ((volatile unsigned char *)0x0302a000) +#define PCIO_BASE 0x03010000 + +/* + * Mapping areas + */ +#define IO_END 0x03ffffff +#define IO_BASE 0x03000000 +#define IO_SIZE (IO_END - IO_BASE) +#define IO_START 0x03000000 + +/* + * Screen mapping information + */ +#define SCREEN2_END 0x02078000 +#define SCREEN2_BASE 0x02000000 +#define SCREEN1_END SCREEN2_BASE +#define SCREEN1_BASE 0x01f88000 +#define SCREEN_START 0x02000000 + +/* + * RAM definitions + */ +#define MAPTOPHYS(a) (((unsigned long)a & 0x007fffff) + PAGE_OFFSET) +#define KERNTOPHYS(a) ((((unsigned long)(&a)) & 0x007fffff) + PAGE_OFFSET) +#define GET_MEMORY_END(p) (PAGE_OFFSET + (p->u1.s.page_size) * (p->u1.s.nr_pages)) +#define PARAMS_BASE (PAGE_OFFSET + 0x7c000) +#define KERNEL_BASE (PAGE_OFFSET + 0x80000) + +#else + +#define IOEB_BASE 0x03350050 +#define IOC_BASE 0x03200000 +#define PCIO_FLOPPYDMABASE 0x0302a000 +#define PCIO_BASE 0x03010000 +#define IO_BASE 0x03000000 + +#endif +#endif + diff --git a/include/asm-arm/arch-a5k/ide.h b/include/asm-arm/arch-a5k/ide.h new file mode 100644 index 000000000..3beb3c3aa --- /dev/null +++ b/include/asm-arm/arch-a5k/ide.h @@ -0,0 +1,44 @@ +/* + * linux/include/asm-arm/arch-a5k/ide.h + * + * Copyright (c) 1997 Russell King + */ + +static __inline__ int +ide_default_irq(ide_ioreg_t base) +{ + if (base == 0x1f0) + return 11; + return 0; +} + +static __inline__ ide_ioreg_t +ide_default_io_base(int index) +{ + if (index == 0) + return 0x1f0; + return 0; +} + +static __inline__ int +ide_default_stepping(int index) +{ + return 0; +} + +static __inline__ void +ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int stepping, int *irq) +{ + ide_ioreg_t port = base; + ide_ioreg_t ctrl = base + 0x206; + int i; + + i = 8; + while (i--) { + *p++ = port; + port += 1 << stepping; + } + *p++ = ctrl; + if (irq != NULL) + irq = 0; +} diff --git a/include/asm-arm/arch-a5k/io.h b/include/asm-arm/arch-a5k/io.h new file mode 100644 index 000000000..b305c7dba --- /dev/null +++ b/include/asm-arm/arch-a5k/io.h @@ -0,0 +1,215 @@ +/* + * linux/include/asm-arm/arch-a5k/io.h + * + * Copyright (C) 1997 Russell King + * + * Modifications: + * 06-Dec-1997 RMK Created. + */ +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +/* + * Virtual view <-> DMA view memory address translations + * virt_to_bus: Used to translate the virtual address to an + * address suitable to be passed to set_dma_addr + * bus_to_virt: Used to convert an address for DMA operations + * to an address that the kernel can use. + */ +#define virt_to_bus(x) ((unsigned long)(x)) +#define bus_to_virt(x) ((void *)(x)) + +/* + * This architecture does not require any delayed IO, and + * has the constant-optimised IO + */ +#undef ARCH_IO_DELAY + +/* + * We use two different types of addressing - PC style addresses, and ARM + * addresses. PC style accesses the PC hardware with the normal PC IO + * addresses, eg 0x3f8 for serial#1. ARM addresses are 0x80000000+ + * and are translated to the start of IO. Note that all addresses are + * shifted left! + */ +#define __PORT_PCIO(x) (!((x) & 0x80000000)) + +/* + * Dynamic IO functions - let the compiler + * optimize the expressions + */ +extern __inline__ void __outb (unsigned int value, unsigned int port) +{ + unsigned long temp; + __asm__ __volatile__( + "tst %2, #0x80000000\n\t" + "mov %0, %4\n\t" + "addeq %0, %0, %3\n\t" + "strb %1, [%0, %2, lsl #2]" + : "=&r" (temp) + : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) + : "cc"); +} + +extern __inline__ void __outw (unsigned int value, unsigned int port) +{ + unsigned long temp; + __asm__ __volatile__( + "tst %2, #0x80000000\n\t" + "mov %0, %4\n\t" + "addeq %0, %0, %3\n\t" + "str %1, [%0, %2, lsl #2]" + : "=&r" (temp) + : "r" (value|value<<16), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) + : "cc"); +} + +extern __inline__ void __outl (unsigned int value, unsigned int port) +{ + unsigned long temp; + __asm__ __volatile__( + "tst %2, #0x80000000\n\t" + "mov %0, %4\n\t" + "addeq %0, %0, %3\n\t" + "str %1, [%0, %2, lsl #2]" + : "=&r" (temp) + : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) + : "cc"); +} + +#define DECLARE_DYN_IN(sz,fnsuffix,instr) \ +extern __inline__ unsigned sz __in##fnsuffix (unsigned int port) \ +{ \ + unsigned long temp, value; \ + __asm__ __volatile__( \ + "tst %2, #0x80000000\n\t" \ + "mov %0, %4\n\t" \ + "addeq %0, %0, %3\n\t" \ + "ldr" ##instr## " %1, [%0, %2, lsl #2]" \ + : "=&r" (temp), "=r" (value) \ + : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \ + : "cc"); \ + return (unsigned sz)value; \ +} + +extern __inline__ unsigned int __ioaddr (unsigned int port) \ +{ \ + if (__PORT_PCIO(port)) \ + return (unsigned int)(PCIO_BASE + (port << 2)); \ + else \ + return (unsigned int)(IO_BASE + (port << 2)); \ +} + +#define DECLARE_IO(sz,fnsuffix,instr) \ + DECLARE_DYN_IN(sz,fnsuffix,instr) + +DECLARE_IO(char,b,"b") +DECLARE_IO(short,w,"") +DECLARE_IO(long,l,"") + +#undef DECLARE_IO +#undef DECLARE_DYN_IN + +/* + * Constant address IO functions + * + * These have to be macros for the 'J' constraint to work - + * +/-4096 immediate operand. + */ +#define __outbc(value,port) \ +({ \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "strb %0, [%1, %2]" \ + : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "strb %0, [%1, %2]" \ + : : "r" (value), "r" (IO_BASE), "r" ((port) << 2)); \ +}) + +#define __inbc(port) \ +({ \ + unsigned char result; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "ldrb %0, [%1, %2]" \ + : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "ldrb %0, [%1, %2]" \ + : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ + result; \ +}) + +#define __outwc(value,port) \ +({ \ + unsigned long v = value; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "str %0, [%1, %2]" \ + : : "r" (v|v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "str %0, [%1, %2]" \ + : : "r" (v|v<<16), "r" (IO_BASE), "r" ((port) << 2)); \ +}) + +#define __inwc(port) \ +({ \ + unsigned short result; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2]" \ + : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2]" \ + : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ + result & 0xffff; \ +}) + +#define __outlc(v,p) __outwc((v),(p)) + +#define __inlc(port) \ +({ \ + unsigned long result; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2]" \ + : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2]" \ + : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ + result; \ +}) + +#define __ioaddrc(port) \ +({ \ + unsigned long addr; \ + if (__PORT_PCIO((port))) \ + addr = PCIO_BASE + ((port) << 2); \ + else \ + addr = IO_BASE + ((port) << 2); \ + addr; \ +}) + +/* + * Translated address IO functions + * + * IO address has already been translated to a virtual address + */ +#define outb_t(v,p) \ + (*(volatile unsigned char *)(p) = (v)) + +#define inb_t(p) \ + (*(volatile unsigned char *)(p)) + +#define outl_t(v,p) \ + (*(volatile unsigned long *)(p) = (v)) + +#define inl_t(p) \ + (*(volatile unsigned long *)(p)) + +#endif diff --git a/include/asm-arm/arch-a5k/irq.h b/include/asm-arm/arch-a5k/irq.h new file mode 100644 index 000000000..6c868d83a --- /dev/null +++ b/include/asm-arm/arch-a5k/irq.h @@ -0,0 +1,130 @@ +/* + * include/asm-arm/arch-a5k/irq.h + * + * Copyright (C) 1996 Russell King + * + * Changelog: + * 24-09-1996 RMK Created + * 10-10-1996 RMK Brought up to date with arch-sa110eval + * 22-10-1996 RMK Changed interrupt numbers & uses new inb/outb macros + * 11-01-1998 RMK Added mask_and_ack_irq + */ + +#define BUILD_IRQ(s,n,m) \ + void IRQ##n##_interrupt(void); \ + void fast_IRQ##n##_interrupt(void); \ + void bad_IRQ##n##_interrupt(void); \ + void probe_IRQ##n##_interrupt(void); + +/* + * The timer is a special interrupt + */ +#define IRQ5_interrupt timer_IRQ_interrupt + +#define IRQ_INTERRUPT(n) IRQ##n##_interrupt +#define FAST_INTERRUPT(n) fast_IRQ##n##_interrupt +#define BAD_INTERRUPT(n) bad_IRQ##n##_interrupt +#define PROBE_INTERRUPT(n) probe_IRQ##n##_interrupt + +#define X(x) (x)|0x01, (x)|0x02, (x)|0x04, (x)|0x08, (x)|0x10, (x)|0x20, (x)|0x40, (x)|0x80 +#define Z(x) (x), (x), (x), (x), (x), (x), (x), (x) + +static __inline__ void mask_and_ack_irq(unsigned int irq) +{ + static const int addrmasks[] = { + X((IOC_IRQMASKA - IOC_BASE)<<18 | (1 << 15)), + X((IOC_IRQMASKB - IOC_BASE)<<18), + Z(0), + Z(0), + Z(0), + Z(0), + Z(0), + Z(0), + X((IOC_FIQMASK - IOC_BASE)<<18), + Z(0), + Z(0), + Z(0), + Z(0), + Z(0), + Z(0), + Z(0) + }; + unsigned int temp1, temp2; + + __asm__ __volatile__( +" ldr %1, [%5, %3, lsl #2]\n" +" teq %1, #0\n" +" beq 2f\n" +" ldrb %0, [%2, %1, lsr #16]\n" +" bic %0, %0, %1\n" +" strb %0, [%2, %1, lsr #16]\n" +" tst %1, #0x8000\n" /* do we need an IRQ clear? */ +" strneb %1, [%2, %4]\n" +"2:" + : "=&r" (temp1), "=&r" (temp2) + : "r" (ioaddr(IOC_BASE)), "r" (irq), + "I" ((IOC_IRQCLRA - IOC_BASE) << 2), "r" (addrmasks)); +} + +#undef X +#undef Z + +static __inline__ void mask_irq(unsigned int irq) +{ + extern void ecard_disableirq (unsigned int); + extern void ecard_disablefiq (unsigned int); + unsigned char mask = 1 << (irq & 7); + + switch (irq >> 3) { + case 0: + outb(inb(IOC_IRQMASKA) & ~mask, IOC_IRQMASKA); + break; + case 1: + outb(inb(IOC_IRQMASKB) & ~mask, IOC_IRQMASKB); + break; + case 4: + ecard_disableirq (irq & 7); + break; + case 8: + outb(inb(IOC_FIQMASK) & ~mask, IOC_FIQMASK); + break; + case 12: + ecard_disablefiq (irq & 7); + } +} + +static __inline__ void unmask_irq(unsigned int irq) +{ + extern void ecard_enableirq (unsigned int); + extern void ecard_enablefiq (unsigned int); + unsigned char mask = 1 << (irq & 7); + + switch (irq >> 3) { + case 0: + outb(inb(IOC_IRQMASKA) | mask, IOC_IRQMASKA); + break; + case 1: + outb(inb(IOC_IRQMASKB) | mask, IOC_IRQMASKB); + break; + case 4: + ecard_enableirq (irq & 7); + break; + case 8: + outb(inb(IOC_FIQMASK) | mask, IOC_FIQMASK); + break; + case 12: + ecard_enablefiq (irq & 7); + } +} + +static __inline__ unsigned long get_enabled_irqs(void) +{ + return inb(IOC_IRQMASKA) | inb(IOC_IRQMASKB) << 8; +} + +static __inline__ void irq_init_irq(void) +{ + outb(0, IOC_IRQMASKA); + outb(0, IOC_IRQMASKB); + outb(0, IOC_FIQMASK); +} diff --git a/include/asm-arm/arch-a5k/irqs.h b/include/asm-arm/arch-a5k/irqs.h new file mode 100644 index 000000000..b7188fb8e --- /dev/null +++ b/include/asm-arm/arch-a5k/irqs.h @@ -0,0 +1,28 @@ +/* + * linux/include/asm-arm/arch-a5k/irqs.h + * + * Copyright (C) 1996 Russell King + */ + +#define IRQ_PRINTER 0 +#define IRQ_BATLOW 1 +#define IRQ_FLOPPYINDEX 2 +#define IRQ_VSYNCPULSE 3 +#define IRQ_POWERON 4 +#define IRQ_TIMER0 5 +#define IRQ_TIMER1 6 +#define IRQ_IMMEDIATE 7 +#define IRQ_EXPCARDFIQ 8 +#define IRQ_SOUNDCHANGE 9 +#define IRQ_SERIALPORT 10 +#define IRQ_HARDDISK 11 +#define IRQ_FLOPPYDISK 12 +#define IRQ_EXPANSIONCARD 13 +#define IRQ_KEYBOARDTX 14 +#define IRQ_KEYBOARDRX 15 + +#define FIQ_FLOPPYDATA 0 +#define FIQ_ECONET 2 +#define FIQ_SERIALPORT 4 +#define FIQ_EXPANSIONCARD 6 +#define FIQ_FORCE 7 diff --git a/include/asm-arm/arch-a5k/mmu.h b/include/asm-arm/arch-a5k/mmu.h new file mode 100644 index 000000000..3c2fb95a1 --- /dev/null +++ b/include/asm-arm/arch-a5k/mmu.h @@ -0,0 +1,15 @@ +/* + * linux/include/asm-arm/arch-a5k/mmu.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 22-11-1996 RMK Created + */ +#ifndef __ASM_ARCH_MMU_H +#define __ASM_ARCH_MMU_H + +#define __virt_to_phys(vpage) vpage +#define __phys_to_virt(ppage) ppage + +#endif diff --git a/include/asm-arm/arch-a5k/oldlatches.h b/include/asm-arm/arch-a5k/oldlatches.h new file mode 100644 index 000000000..fa759a23e --- /dev/null +++ b/include/asm-arm/arch-a5k/oldlatches.h @@ -0,0 +1,9 @@ +/* + * Dummy oldlatches.h + * + * Copyright (C) 1996 Russell King + */ + +#ifdef __need_oldlatches +#error "Old latches not present in this (a5k) machine" +#endif diff --git a/include/asm-arm/arch-a5k/processor.h b/include/asm-arm/arch-a5k/processor.h new file mode 100644 index 000000000..a8bf6e540 --- /dev/null +++ b/include/asm-arm/arch-a5k/processor.h @@ -0,0 +1,34 @@ +/* + * linux/include/asm-arm/arch-a5k/processor.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 10-09-1996 RMK Created + */ + +#ifndef __ASM_ARCH_PROCESSOR_H +#define __ASM_ARCH_PROCESSOR_H + +/* + * Bus types + */ +#define EISA_bus 0 +#define EISA_bus__is_a_macro /* for versions in ksyms.c */ +#define MCA_bus 0 +#define MCA_bus__is_a_macro /* for versions in ksyms.c */ + +/* + * User space: 26MB + */ +#define TASK_SIZE (0x01a00000UL) + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) + +#define INIT_MMAP \ +{ &init_mm, 0, 0x02000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } + +#endif diff --git a/include/asm-arm/arch-a5k/serial.h b/include/asm-arm/arch-a5k/serial.h new file mode 100644 index 000000000..c8397084e --- /dev/null +++ b/include/asm-arm/arch-a5k/serial.h @@ -0,0 +1,40 @@ +/* + * linux/include/asm-arm/arch-a5k/serial.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 15-10-1996 RMK Created + */ +#ifndef __ASM_ARCH_SERIAL_H +#define __ASM_ARCH_SERIAL_H + +/* + * This assumes you have a 1.8432 MHz clock for your UART. + * + * It'd be nice if someone built a serial card with a 24.576 MHz + * clock, since the 16550A is capable of handling a top speed of 1.5 + * megabits/second; but this requires the faster clock. + */ +#define BASE_BAUD (1843200 / 16) + +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) + + /* UART CLK PORT IRQ FLAGS */ +#define RS_UARTS \ + { 0, BASE_BAUD, 0x3F8, 10, STD_COM_FLAGS }, /* ttyS0 */ \ + { 0, BASE_BAUD, 0x2F8, 10, STD_COM_FLAGS }, /* ttyS1 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS2 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS3 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS4 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS5 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS6 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS7 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS8 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS9 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS10 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS11 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS12 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS13 */ + +#endif diff --git a/include/asm-arm/arch-a5k/shmparam.h b/include/asm-arm/arch-a5k/shmparam.h new file mode 100644 index 000000000..073c7c276 --- /dev/null +++ b/include/asm-arm/arch-a5k/shmparam.h @@ -0,0 +1,5 @@ +/* + * linux/include/asm-arm/arch-a5k/shmparam.h + * + * Copyright (c) 1996 Russell King. + */ diff --git a/include/asm-arm/arch-a5k/system.h b/include/asm-arm/arch-a5k/system.h new file mode 100644 index 000000000..a1d845c2a --- /dev/null +++ b/include/asm-arm/arch-a5k/system.h @@ -0,0 +1,30 @@ +/* + * linux/include/asm-arm/arch-a5k/system.h + * + * Copyright (c) 1996 Russell King + */ +#ifndef __ASM_ARCH_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H + +extern __inline__ void arch_hard_reset (void) +{ + extern void ecard_reset (int card); + + /* + * Reset all expansion cards. + */ + ecard_reset (-1); + + /* + * copy branch instruction to reset location and call it + */ + *(unsigned long *)0 = *(unsigned long *)0x03800000; + ((void(*)(void))0)(); + + /* + * If that didn't work, loop endlessly + */ + while (1); +} + +#endif diff --git a/include/asm-arm/arch-a5k/time.h b/include/asm-arm/arch-a5k/time.h new file mode 100644 index 000000000..0d12303cb --- /dev/null +++ b/include/asm-arm/arch-a5k/time.h @@ -0,0 +1,96 @@ +/* + * linux/include/asm-arm/arch-a5k/time.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 24-Sep-1996 RMK Created + * 10-Oct-1996 RMK Brought up to date with arch-sa110eval + * 04-Dec-1997 RMK Updated for new arch/arm/time.c + */ + +extern __inline__ unsigned long gettimeoffset (void) +{ + unsigned int count1, count2, status1, status2; + unsigned long offset = 0; + + status1 = IOC_IRQREQA; + barrier (); + outb (0, IOC_T0LATCH); + barrier (); + count1 = inb(IOC_T0CNTL) | (inb(IOC_T0CNTH) << 8); + barrier (); + status2 = inb(IOC_IRQREQA); + barrier (); + outb (0, IOC_T0LATCH); + barrier (); + count2 = inb(IOC_T0CNTL) | (inb(IOC_T0CNTH) << 8); + + if (count2 < count1) { + /* + * This means that we haven't just had an interrupt + * while reading into status2. + */ + if (status2 & (1 << 5)) + offset = tick; + count1 = count2; + } else if (count2 > count1) { + /* + * We have just had another interrupt while reading + * status2. + */ + offset += tick; + count1 = count2; + } + + count1 = LATCH - count1; + /* + * count1 = number of clock ticks since last interrupt + */ + offset += count1 * tick / LATCH; + return offset; +} + +/* + * No need to reset the timer at every irq + */ +#define reset_timer() 1 + +/* + * Updating of the RTC. We don't currently write the time to the + * CMOS clock. + */ +#define update_rtc() + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +extern __inline__ unsigned long setup_timer (void) +{ + extern int iic_control (unsigned char, int, char *, int); + unsigned int year, mon, day, hour, min, sec; + char buf[8]; + + outb(LATCH & 255, IOC_T0LTCHL); + outb(LATCH >> 8, IOC_T0LTCHH); + outb(0, IOC_T0GO); + + iic_control (0xa0, 0xc0, buf, 1); + year = buf[0]; + if ((year += 1900) < 1970) + year += 100; + + iic_control (0xa0, 2, buf, 5); + mon = buf[4] & 0x1f; + day = buf[3] & 0x3f; + hour = buf[2]; + min = buf[1]; + sec = buf[0]; + BCD_TO_BIN(mon); + BCD_TO_BIN(day); + BCD_TO_BIN(hour); + BCD_TO_BIN(min); + BCD_TO_BIN(sec); + + return mktime(year, mon, day, hour, min, sec); +} diff --git a/include/asm-arm/arch-a5k/timex.h b/include/asm-arm/arch-a5k/timex.h new file mode 100644 index 000000000..84baf1fc4 --- /dev/null +++ b/include/asm-arm/arch-a5k/timex.h @@ -0,0 +1,13 @@ +/* + * linux/include/asm-arm/arch-a5k/timex.h + * + * A5000 architecture timex specifications + * + * Copyright (C) 1997, 1998 Russell King + */ + +/* + * On the RiscPC, the clock ticks at 2MHz. + */ +#define CLOCK_TICK_RATE 2000000 + diff --git a/include/asm-arm/arch-a5k/uncompress.h b/include/asm-arm/arch-a5k/uncompress.h new file mode 100644 index 000000000..e6af264b5 --- /dev/null +++ b/include/asm-arm/arch-a5k/uncompress.h @@ -0,0 +1,104 @@ +/* + * linux/include/asm-arm/arch-a5k/uncompress.h + * + * Copyright (C) 1996 Russell King + */ +#define VIDMEM ((char *)0x02000000) + +#include "../arch/arm/drivers/char/font.h" + +int video_num_columns, video_num_lines, video_size_row; +int white, bytes_per_char_h; +extern unsigned long con_charconvtable[256]; + +struct param_struct { + unsigned long page_size; + unsigned long nr_pages; + unsigned long ramdisk_size; + unsigned long mountrootrdonly; + unsigned long rootdev; + unsigned long video_num_cols; + unsigned long video_num_rows; + unsigned long video_x; + unsigned long video_y; + unsigned long memc_control_reg; + unsigned char sounddefault; + unsigned char adfsdrives; + unsigned char bytes_per_char_h; + unsigned char bytes_per_char_v; + unsigned long unused[256/4-11]; +}; + +static struct param_struct *params = (struct param_struct *)0x0207c000; + +/* + * This does not append a newline + */ +static void puts(const char *s) +{ + extern void ll_write_char(char *, unsigned long); + int x,y; + unsigned char c; + char *ptr; + + x = params->video_x; + y = params->video_y; + + while ( ( c = *(unsigned char *)s++ ) != '\0' ) { + if ( c == '\n' ) { + x = 0; + if ( ++y >= video_num_lines ) { + y--; + } + } else { + ptr = VIDMEM + ((y*video_num_columns*params->bytes_per_char_v+x)*bytes_per_char_h); + ll_write_char(ptr, c|(white<<8)); + if ( ++x >= video_num_columns ) { + x = 0; + if ( ++y >= video_num_lines ) { + y--; + } + } + } + } + + params->video_x = x; + params->video_y = y; +} + +static void error(char *x); + +/* + * Setup for decompression + */ +static void arch_decomp_setup(void) +{ + int i; + + video_num_lines = params->video_num_rows; + video_num_columns = params->video_num_cols; + bytes_per_char_h = params->bytes_per_char_h; + video_size_row = video_num_columns * bytes_per_char_h; + if (bytes_per_char_h == 4) + for (i = 0; i < 256; i++) + con_charconvtable[i] = + (i & 128 ? 1 << 0 : 0) | + (i & 64 ? 1 << 4 : 0) | + (i & 32 ? 1 << 8 : 0) | + (i & 16 ? 1 << 12 : 0) | + (i & 8 ? 1 << 16 : 0) | + (i & 4 ? 1 << 20 : 0) | + (i & 2 ? 1 << 24 : 0) | + (i & 1 ? 1 << 28 : 0); + else + for (i = 0; i < 16; i++) + con_charconvtable[i] = + (i & 8 ? 1 << 0 : 0) | + (i & 4 ? 1 << 8 : 0) | + (i & 2 ? 1 << 16 : 0) | + (i & 1 ? 1 << 24 : 0); + + white = bytes_per_char_h == 8 ? 0xfc : 7; + + if (params->nr_pages * params->page_size < 4096*1024) error("<4M of mem\n"); +} diff --git a/include/asm-arm/arch-arc/a.out.h b/include/asm-arm/arch-arc/a.out.h new file mode 100644 index 000000000..985c27e90 --- /dev/null +++ b/include/asm-arm/arch-arc/a.out.h @@ -0,0 +1,16 @@ +/* + * linux/include/asm-arm/arch-arc/a.out.h + * + * Copyright (C) 1996 Russell King + */ + +#ifndef __ASM_ARCH_A_OUT_H +#define __ASM_ARCH_A_OUT_H + +#ifdef __KERNEL__ +#define STACK_TOP (0x01a00000) +#define LIBRARY_START_TEXT (0x00c00000) +#endif + +#endif + diff --git a/include/asm-arm/arch-arc/dma.h b/include/asm-arm/arch-arc/dma.h new file mode 100644 index 000000000..8e82fe58d --- /dev/null +++ b/include/asm-arm/arch-arc/dma.h @@ -0,0 +1,95 @@ +#ifndef __ASM_ARCH_DMA_H +#define __ASM_ARCH_DMA_H + +#define MAX_DMA_ADDRESS 0x03000000 + +#ifdef KERNEL_ARCH_DMA + +static inline void arch_disable_dma (int dmanr) +{ + printk (dma_str, "arch_disable_dma", dmanr); +} + +static inline void arch_enable_dma (int dmanr) +{ + printk (dma_str, "arch_enable_dma", dmanr); +} + +static inline void arch_set_dma_addr (int dmanr, unsigned int addr) +{ + printk (dma_str, "arch_set_dma_addr", dmanr); +} + +static inline void arch_set_dma_count (int dmanr, unsigned int count) +{ + printk (dma_str, "arch_set_dma_count", dmanr); +} + +static inline void arch_set_dma_mode (int dmanr, char mode) +{ + printk (dma_str, "arch_set_dma_mode", dmanr); +} + +static inline int arch_dma_count (int dmanr) +{ + printk (dma_str, "arch_dma_count", dmanr); + return 0; +} + +#endif + +/* enable/disable a specific DMA channel */ +extern void enable_dma(unsigned int dmanr); + +static __inline__ void disable_dma(unsigned int dmanr) +{ + switch(dmanr) { + case 0: disable_irq(64); break; + case 1: break; + default: printk (dma_str, "disable_dma", dmanr); break; + } +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while interrupts are disabled! --- + */ +#define clear_dma_ff(dmanr) + +/* set mode (above) for a specific DMA channel */ +extern void set_dma_mode(unsigned int dmanr, char mode); + +/* Set only the page register bits of the transfer address. + * This is used for successive transfers when we know the contents of + * the lower 16 bits of the DMA current address register, but a 64k boundary + * may have been crossed. + */ +static __inline__ void set_dma_page(unsigned int dmanr, char pagenr) +{ + printk (dma_str, "set_dma_page", dmanr); +} + + +/* Set transfer address & page bits for specific DMA channel. + * Assumes dma flipflop is clear. + */ +extern void set_dma_addr(unsigned int dmanr, unsigned int addr); + +/* Set transfer size for a specific DMA channel. + */ +extern void set_dma_count(unsigned int dmanr, unsigned int count); + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + * + * Assumes DMA flip-flop is clear. + */ +extern int get_dma_residue(unsigned int dmanr); + +#endif /* _ASM_ARCH_DMA_H */ diff --git a/include/asm-arm/arch-arc/hardware.h b/include/asm-arm/arch-arc/hardware.h new file mode 100644 index 000000000..21d933d86 --- /dev/null +++ b/include/asm-arm/arch-arc/hardware.h @@ -0,0 +1,82 @@ +/* + * linux/include/asm-arm/arch-arc/hardware.h + * + * Copyright (C) 1996 Russell King. + * + * This file contains the hardware definitions of the A3/4/5xx series machines. + */ + +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +/* + * What hardware must be present + */ +#define HAS_IOC +#define HAS_MEMC +#define HAS_MEMC1A +#define HAS_VIDC + +/* + * Optional hardware + */ +#define HAS_EXPMASK + +#ifndef __ASSEMBLER__ + +/* + * for use with inb/outb + */ +#define VIDC_BASE 0x80100000 +#define IOCEC4IO_BASE 0x8009c000 +#define LATCHAADDR 0x80094010 +#define LATCHBADDR 0x80094006 +#define IOCECIO_BASE 0x80090000 +#define IOC_BASE 0x80080000 +#define MEMCECIO_BASE 0x80000000 + +/* + * IO definitions + */ +#define EXPMASK_BASE ((volatile unsigned char *)0x03360000) +#define IOEB_BASE ((volatile unsigned char *)0x03350050) +#define PCIO_FLOPPYDMABASE ((volatile unsigned char *)0x0302a000) +#define PCIO_BASE 0x03010000 + +/* + * Mapping areas + */ +#define IO_END 0x03ffffff +#define IO_BASE 0x03000000 +#define IO_SIZE (IO_END - IO_BASE) +#define IO_START 0x03000000 + +/* + * Screen mapping information + */ +#define SCREEN2_END 0x02078000 +#define SCREEN2_BASE 0x02000000 +#define SCREEN1_END SCREEN2_BASE +#define SCREEN1_BASE 0x01f88000 +#define SCREEN_START 0x02000000 + +/* + * RAM definitions + */ +#define MAPTOPHYS(a) (((unsigned long)a & 0x007fffff) + PAGE_OFFSET) +#define KERNTOPHYS(a) ((((unsigned long)(&a)) & 0x007fffff) + PAGE_OFFSET) +#define GET_MEMORY_END(p) (PAGE_OFFSET + (p->u1.s.page_size) * (p->u1.s.nr_pages)) +#define PARAMS_BASE (PAGE_OFFSET + 0x7c000) +#define KERNEL_BASE (PAGE_OFFSET + 0x80000) + +#else + +#define IOEB_BASE 0x03350050 +#define IOC_BASE 0x03200000 +#define PCIO_FLOPPYDMABASE 0x0302a000 +#define PCIO_BASE 0x03010000 +#define IO_BASE 0x03000000 + +#endif +#endif + diff --git a/include/asm-arm/arch-arc/ide.h b/include/asm-arm/arch-arc/ide.h new file mode 100644 index 000000000..9da7a9c56 --- /dev/null +++ b/include/asm-arm/arch-arc/ide.h @@ -0,0 +1,40 @@ +/* + * linux/include/asm-arm/arch-arc/ide.h + * + * Copyright (c) 1997,1998 Russell King + */ + +static __inline__ int +ide_default_irq(ide_ioreg_t base) +{ + return 0; +} + +static __inline__ ide_ioreg_t +ide_default_io_base(int index) +{ + return 0; +} + +static __inline__ int +ide_default_stepping(int index) +{ + return 0; +} + +static __inline__ void +ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int stepping, int *irq) +{ + ide_ioreg_t port = base; + ide_ioreg_t ctrl = base + 0x206; + int i; + + i = 8; + while (i--) { + *p++ = port; + port += 1 << stepping; + } + *p++ = ctrl; + if (irq != NULL) + irq = 0; +} diff --git a/include/asm-arm/arch-arc/io.h b/include/asm-arm/arch-arc/io.h new file mode 100644 index 000000000..40775ec8f --- /dev/null +++ b/include/asm-arm/arch-arc/io.h @@ -0,0 +1,215 @@ +/* + * linux/include/asm-arm/arch-arc/io.h + * + * Copyright (C) 1997 Russell King + * + * Modifications: + * 06-Dec-1997 RMK Created. + */ +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +/* + * Virtual view <-> DMA view memory address translations + * virt_to_bus: Used to translate the virtual address to an + * address suitable to be passed to set_dma_addr + * bus_to_virt: Used to convert an address for DMA operations + * to an address that the kernel can use. + */ +#define virt_to_bus(x) ((unsigned long)(x)) +#define bus_to_virt(x) ((void *)(x)) + +/* + * This architecture does not require any delayed IO, and + * has the constant-optimised IO + */ +#undef ARCH_IO_DELAY + +/* + * We use two different types of addressing - PC style addresses, and ARM + * addresses. PC style accesses the PC hardware with the normal PC IO + * addresses, eg 0x3f8 for serial#1. ARM addresses are 0x80000000+ + * and are translated to the start of IO. Note that all addresses are + * shifted left! + */ +#define __PORT_PCIO(x) (!((x) & 0x80000000)) + +/* + * Dynamic IO functions - let the compiler + * optimize the expressions + */ +extern __inline__ void __outb (unsigned int value, unsigned int port) +{ + unsigned long temp; + __asm__ __volatile__( + "tst %2, #0x80000000\n\t" + "mov %0, %4\n\t" + "addeq %0, %0, %3\n\t" + "strb %1, [%0, %2, lsl #2]" + : "=&r" (temp) + : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) + : "cc"); +} + +extern __inline__ void __outw (unsigned int value, unsigned int port) +{ + unsigned long temp; + __asm__ __volatile__( + "tst %2, #0x80000000\n\t" + "mov %0, %4\n\t" + "addeq %0, %0, %3\n\t" + "strb %1, [%0, %2, lsl #2]" + : "=&r" (temp) + : "r" (value|value<<16), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) + : "cc"); +} + +extern __inline__ void __outl (unsigned int value, unsigned int port) +{ + unsigned long temp; + __asm__ __volatile__( + "tst %2, #0x80000000\n\t" + "mov %0, %4\n\t" + "addeq %0, %0, %3\n\t" + "strb %1, [%0, %2, lsl #2]" + : "=&r" (temp) + : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) + : "cc"); +} + +#define DECLARE_DYN_IN(sz,fnsuffix,instr) \ +extern __inline__ unsigned sz __in##fnsuffix (unsigned int port) \ +{ \ + unsigned long temp, value; \ + __asm__ __volatile__( \ + "tst %2, #0x80000000\n\t" \ + "mov %0, %4\n\t" \ + "addeq %0, %0, %3\n\t" \ + "ldr" ##instr## " %1, [%0, %2, lsl #2]" \ + : "=&r" (temp), "=r" (value) \ + : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \ + : "cc"); \ + return (unsigned sz)value; \ +} + +extern __inline__ unsigned int __ioaddr (unsigned int port) \ +{ \ + if (__PORT_PCIO(port)) \ + return (unsigned int)(PCIO_BASE + (port << 2)); \ + else \ + return (unsigned int)(IO_BASE + (port << 2)); \ +} + +#define DECLARE_IO(sz,fnsuffix,instr) \ + DECLARE_DYN_IN(sz,fnsuffix,instr) + +DECLARE_IO(char,b,"b") +DECLARE_IO(short,w,"") +DECLARE_IO(long,l,"") + +#undef DECLARE_IO +#undef DECLARE_DYN_IN + +/* + * Constant address IO functions + * + * These have to be macros for the 'J' constraint to work - + * +/-4096 immediate operand. + */ +#define __outbc(value,port) \ +({ \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "strb %0, [%1, %2]" \ + : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "strb %0, [%1, %2]" \ + : : "r" (value), "r" (IO_BASE), "r" ((port) << 2)); \ +}) + +#define __inbc(port) \ +({ \ + unsigned char result; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "ldrb %0, [%1, %2]" \ + : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "ldrb %0, [%1, %2]" \ + : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ + result; \ +}) + +#define __outwc(value,port) \ +({ \ + unsigned long v = value; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "str %0, [%1, %2]" \ + : : "r" (v|v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "str %0, [%1, %2]" \ + : : "r" (v|v<<16), "r" (IO_BASE), "r" ((port) << 2)); \ +}) + +#define __inwc(port) \ +({ \ + unsigned short result; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2]" \ + : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2]" \ + : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ + result & 0xffff; \ +}) + +#define __outlc(v,p) __outwc((v),(p)) + +#define __inlc(port) \ +({ \ + unsigned long result; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2]" \ + : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2]" \ + : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ + result; \ +}) + +#define __ioaddrc(port) \ +({ \ + unsigned long addr; \ + if (__PORT_PCIO((port))) \ + addr = PCIO_BASE + ((port) << 2); \ + else \ + addr = IO_BASE + ((port) << 2); \ + addr; \ +}) + +/* + * Translated address IO functions + * + * IO address has already been translated to a virtual address + */ +#define outb_t(v,p) \ + (*(volatile unsigned char *)(p) = (v)) + +#define inb_t(p) \ + (*(volatile unsigned char *)(p)) + +#define outl_t(v,p) \ + (*(volatile unsigned long *)(p) = (v)) + +#define inl_t(p) \ + (*(volatile unsigned long *)(p)) + +#endif diff --git a/include/asm-arm/arch-arc/irq.h b/include/asm-arm/arch-arc/irq.h new file mode 100644 index 000000000..62ea30478 --- /dev/null +++ b/include/asm-arm/arch-arc/irq.h @@ -0,0 +1,130 @@ +/* + * include/asm-arm/arch-arc/irq.h + * + * Copyright (C) 1996 Russell King + * + * Changelog: + * 24-09-1996 RMK Created + * 10-10-1996 RMK Brought up to date with arch-sa110eval + * 05-11-1996 RMK Changed interrupt numbers & uses new inb/outb macros + * 11-01-1998 RMK Added mask_and_ack_irq + */ + +#define BUILD_IRQ(s,n,m) \ + void IRQ##n##_interrupt(void); \ + void fast_IRQ##n##_interrupt(void); \ + void bad_IRQ##n##_interrupt(void); \ + void probe_IRQ##n##_interrupt(void); + +/* + * The timer is a special interrupt + */ +#define IRQ5_interrupt timer_IRQ_interrupt + +#define IRQ_INTERRUPT(n) IRQ##n##_interrupt +#define FAST_INTERRUPT(n) fast_IRQ##n##_interrupt +#define BAD_INTERRUPT(n) bad_IRQ##n##_interrupt +#define PROBE_INTERRUPT(n) probe_IRQ##n##_interrupt + +#define X(x) (x)|0x01, (x)|0x02, (x)|0x04, (x)|0x08, (x)|0x10, (x)|0x20, (x)|0x40, (x)|0x80 +#define Z(x) (x), (x), (x), (x), (x), (x), (x), (x) + +static __inline__ void mask_and_ack_irq(unsigned int irq) +{ + static const int addrmasks[] = { + X((IOC_IRQMASKA - IOC_BASE)<<18 | (1 << 15)), + X((IOC_IRQMASKB - IOC_BASE)<<18), + Z(0), + Z(0), + Z(0), + Z(0), + Z(0), + Z(0), + X((IOC_FIQMASK - IOC_BASE)<<18), + Z(0), + Z(0), + Z(0), + Z(0), + Z(0), + Z(0), + Z(0) + }; + unsigned int temp1, temp2; + + __asm__ __volatile__( +" ldr %1, [%5, %3, lsl #2]\n" +" teq %1, #0\n" +" beq 2f\n" +" ldrb %0, [%2, %1, lsr #16]\n" +" bic %0, %0, %1\n" +" strb %0, [%2, %1, lsr #16]\n" +" tst %1, #0x8000\n" /* do we need an IRQ clear? */ +" strneb %1, [%2, %4]\n" +"2:" + : "=&r" (temp1), "=&r" (temp2) + : "r" (ioaddr(IOC_BASE)), "r" (irq), + "I" ((IOC_IRQCLRA - IOC_BASE) << 2), "r" (addrmasks)); +} + +#undef X +#undef Z + +static __inline__ void mask_irq(unsigned int irq) +{ + extern void ecard_disableirq (unsigned int); + extern void ecard_disablefiq (unsigned int); + unsigned char mask = 1 << (irq & 7); + + switch (irq >> 3) { + case 0: + outb(inb(IOC_IRQMASKA) & ~mask, IOC_IRQMASKA); + break; + case 1: + outb(inb(IOC_IRQMASKB) & ~mask, IOC_IRQMASKB); + break; + case 4: + ecard_disableirq (irq & 7); + break; + case 8: + outb(inb(IOC_FIQMASK) & ~mask, IOC_FIQMASK); + break; + case 12: + ecard_disablefiq (irq & 7); + } +} + +static __inline__ void unmask_irq(unsigned int irq) +{ + extern void ecard_enableirq (unsigned int); + extern void ecard_enablefiq (unsigned int); + unsigned char mask = 1 << (irq & 7); + + switch (irq >> 3) { + case 0: + outb(inb(IOC_IRQMASKA) | mask, IOC_IRQMASKA); + break; + case 1: + outb(inb(IOC_IRQMASKB) | mask, IOC_IRQMASKB); + break; + case 4: + ecard_enableirq (irq & 7); + break; + case 8: + outb(inb(IOC_FIQMASK) | mask, IOC_FIQMASK); + break; + case 12: + ecard_enablefiq (irq & 7); + } +} + +static __inline__ unsigned long get_enabled_irqs(void) +{ + return inb(IOC_IRQMASKA) | inb(IOC_IRQMASKB) << 8; +} + +static __inline__ void irq_init_irq(void) +{ + outb(0, IOC_IRQMASKA); + outb(0, IOC_IRQMASKB); + outb(0, IOC_FIQMASK); +} diff --git a/include/asm-arm/arch-arc/irqs.h b/include/asm-arm/arch-arc/irqs.h new file mode 100644 index 000000000..e4043aaef --- /dev/null +++ b/include/asm-arm/arch-arc/irqs.h @@ -0,0 +1,30 @@ +/* + * linux/include/asm-arm/arch-arc/irqs.h + * + * Copyright (C) 1996 Russell King, Dave Gilbert (gilbertd@cs.man.ac.uk) + */ + +#define IRQ_PRINTERBUSY 0 +#define IRQ_SERIALRING 1 +#define IRQ_PRINTERACK 2 +#define IRQ_VSYNCPULSE 3 +#define IRQ_POWERON 4 +#define IRQ_TIMER0 5 +#define IRQ_TIMER1 6 +#define IRQ_IMMEDIATE 7 +#define IRQ_EXPCARDFIQ 8 +#define IRQ_SOUNDCHANGE 9 +#define IRQ_SERIALPORT 10 +#define IRQ_HARDDISK 11 +#define IRQ_FLOPPYCHANGED 12 +#define IRQ_EXPANSIONCARD 13 +#define IRQ_KEYBOARDTX 14 +#define IRQ_KEYBOARDRX 15 + +#define FIQ_FLOPPYDATA 0 +#define FIQ_FLOPPYIRQ 1 +#define FIQ_ECONET 2 +#define FIQ_EXPANSIONCARD 6 +#define FIQ_FORCE 7 + +#define FIQ_FD1772 FIQ_FLOPPYIRQ diff --git a/include/asm-arm/arch-arc/mmu.h b/include/asm-arm/arch-arc/mmu.h new file mode 100644 index 000000000..747f61ada --- /dev/null +++ b/include/asm-arm/arch-arc/mmu.h @@ -0,0 +1,15 @@ +/* + * linux/include/asm-arm/arch-arc/mmu.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 22-11-1996 RMK Created + */ +#ifndef __ASM_ARCH_MMU_H +#define __ASM_ARCH_MMU_H + +#define __virt_to_phys(vpage) vpage +#define __phys_to_virt(ppage) ppage + +#endif diff --git a/include/asm-arm/arch-arc/oldlatches.h b/include/asm-arm/arch-arc/oldlatches.h new file mode 100644 index 000000000..747a5e86d --- /dev/null +++ b/include/asm-arm/arch-arc/oldlatches.h @@ -0,0 +1,24 @@ +#ifndef _ASM_ARM_ARCHARC_OLDLATCH_H +#define _ASM_ARM_ARCHARC_OLDLATCH_H + +#define LATCHA_FDSEL0 (1<<0) +#define LATCHA_FDSEL1 (1<<1) +#define LATCHA_FDSEL2 (1<<2) +#define LATCHA_FDSEL3 (1<<3) +#define LATCHA_FDSELALL (0xf) +#define LATCHA_SIDESEL (1<<4) +#define LATCHA_MOTOR (1<<5) +#define LATCHA_INUSE (1<<6) +#define LATCHA_CHANGERST (1<<7) + +#define LATCHB_FDCDENSITY (1<<1) +#define LATCHB_FDCRESET (1<<3) +#define LATCHB_PRINTSTROBE (1<<4) + +/* newval=(oldval & mask)|newdata */ +void oldlatch_bupdate(unsigned char mask,unsigned char newdata); + +/* newval=(oldval & mask)|newdata */ +void oldlatch_aupdate(unsigned char mask,unsigned char newdata); + +#endif diff --git a/include/asm-arm/arch-arc/processor.h b/include/asm-arm/arch-arc/processor.h new file mode 100644 index 000000000..0d3aee84a --- /dev/null +++ b/include/asm-arm/arch-arc/processor.h @@ -0,0 +1,34 @@ +/* + * linux/include/asm-arm/arch-arc/processor.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 10-09-1996 RMK Created + */ + +#ifndef __ASM_ARCH_PROCESSOR_H +#define __ASM_ARCH_PROCESSOR_H + +/* + * Bus types + */ +#define EISA_bus 0 +#define EISA_bus__is_a_macro /* for versions in ksyms.c */ +#define MCA_bus 0 +#define MCA_bus__is_a_macro /* for versions in ksyms.c */ + +/* + * User space: 26MB + */ +#define TASK_SIZE (0x01a00000UL) + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) + +#define INIT_MMAP \ +{ &init_mm, 0, 0x02000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } + +#endif diff --git a/include/asm-arm/arch-arc/serial.h b/include/asm-arm/arch-arc/serial.h new file mode 100644 index 000000000..d9a6bde58 --- /dev/null +++ b/include/asm-arm/arch-arc/serial.h @@ -0,0 +1,40 @@ +/* + * linux/include/asm-arm/arch-arc/serial.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 15-10-1996 RMK Created + */ +#ifndef __ASM_ARCH_SERIAL_H +#define __ASM_ARCH_SERIAL_H + +/* + * This assumes you have a 1.8432 MHz clock for your UART. + * + * It'd be nice if someone built a serial card with a 24.576 MHz + * clock, since the 16550A is capable of handling a top speed of 1.5 + * megabits/second; but this requires the faster clock. + */ +#define BASE_BAUD (1843200 / 16) + +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) + + /* UART CLK PORT IRQ FLAGS */ +#define RS_UARTS \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS0 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS1 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS2 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS3 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS4 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS5 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS6 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS7 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS8 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS9 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS10 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS11 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS12 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS13 */ + +#endif diff --git a/include/asm-arm/arch-arc/shmparam.h b/include/asm-arm/arch-arc/shmparam.h new file mode 100644 index 000000000..e4e47e254 --- /dev/null +++ b/include/asm-arm/arch-arc/shmparam.h @@ -0,0 +1,5 @@ +/* + * linux/include/asm-arm/arch-arc/shmparam.h + * + * Copyright (c) 1996 Russell King. + */ diff --git a/include/asm-arm/arch-arc/system.h b/include/asm-arm/arch-arc/system.h new file mode 100644 index 000000000..6807cc66c --- /dev/null +++ b/include/asm-arm/arch-arc/system.h @@ -0,0 +1,41 @@ +/* + * linux/include/asm-arm/arch-arc/system.h + * + * Copyright (c) 1996 Russell King and Dave Gilbert + */ +#ifndef __ASM_ARCH_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H + +#define cliIF() \ + do { \ + unsigned long temp; \ + __asm__ __volatile__( \ +" mov %0, pc\n" \ +" orr %0, %0, #0x0c000000\n" \ +" teqp %0, #0\n" \ + : "=r" (temp) \ + : ); \ + } while(0) + +extern __inline__ void arch_hard_reset (void) +{ + extern void ecard_reset (int card); + + /* + * Reset all expansion cards. + */ + ecard_reset (-1); + + /* + * copy branch instruction to reset location and call it + */ + *(unsigned long *)0 = *(unsigned long *)0x03800000; + ((void(*)(void))0)(); + + /* + * If that didn't work, loop endlessly + */ + while (1); +} + +#endif diff --git a/include/asm-arm/arch-arc/time.h b/include/asm-arm/arch-arc/time.h new file mode 100644 index 000000000..6df347484 --- /dev/null +++ b/include/asm-arm/arch-arc/time.h @@ -0,0 +1,96 @@ +/* + * linux/include/asm-arm/arch-arc/time.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 24-Sep-1996 RMK Created + * 10-Oct-1996 RMK Brought up to date with arch-sa110eval + * 04-Dec-1997 RMK Updated for new arch/arm/time.c + */ + +extern __inline__ unsigned long gettimeoffset (void) +{ + unsigned int count1, count2, status1, status2; + unsigned long offset = 0; + + status1 = inb(IOC_IRQREQA); + barrier (); + outb (0, IOC_T0LATCH); + barrier (); + count1 = inb(IOC_T0CNTL) | (inb(IOC_T0CNTH) << 8); + barrier (); + status2 = inb(IOC_IRQREQA); + barrier (); + outb (0, IOC_T0LATCH); + barrier (); + count2 = inb(IOC_T0CNTL) | (inb(IOC_T0CNTH) << 8); + + if (count2 < count1) { + /* + * This means that we haven't just had an interrupt + * while reading into status2. + */ + if (status2 & (1 << 5)) + offset = tick; + count1 = count2; + } else if (count2 > count1) { + /* + * We have just had another interrupt while reading + * status2. + */ + offset += tick; + count1 = count2; + } + + count1 = LATCH - count1; + /* + * count1 = number of clock ticks since last interrupt + */ + offset += count1 * tick / LATCH; + return offset; +} + +/* + * No need to reset the timer at every irq + */ +#define reset_timer() 1 + +/* + * Updating of the RTC. We don't currently write the time to the + * CMOS clock. + */ +#define update_rtc() + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +extern __inline__ unsigned long setup_timer (void) +{ + extern int iic_control (unsigned char, int, char *, int); + unsigned int year, mon, day, hour, min, sec; + char buf[8]; + + outb(LATCH & 255, IOC_T0LTCHL); + outb(LATCH >> 8, IOC_T0LTCHH); + outb(0, IOC_T0GO); + + iic_control (0xa0, 0xc0, buf, 1); + year = buf[0]; + if ((year += 1900) < 1970) + year += 100; + + iic_control (0xa0, 2, buf, 5); + mon = buf[4] & 0x1f; + day = buf[3] & 0x3f; + hour = buf[2]; + min = buf[1]; + sec = buf[0]; + BCD_TO_BIN(mon); + BCD_TO_BIN(day); + BCD_TO_BIN(hour); + BCD_TO_BIN(min); + BCD_TO_BIN(sec); + + return mktime(year, mon, day, hour, min, sec); +} diff --git a/include/asm-arm/arch-arc/timex.h b/include/asm-arm/arch-arc/timex.h new file mode 100644 index 000000000..5161a9a62 --- /dev/null +++ b/include/asm-arm/arch-arc/timex.h @@ -0,0 +1,13 @@ +/* + * linux/include/asm-arm/arch-arc/timex.h + * + * Archimedes architecture timex specifications + * + * Copyright (C) 1997, 1998 Russell King + */ + +/* + * On the RiscPC, the clock ticks at 2MHz. + */ +#define CLOCK_TICK_RATE 2000000 + diff --git a/include/asm-arm/arch-arc/uncompress.h b/include/asm-arm/arch-arc/uncompress.h new file mode 100644 index 000000000..e6af264b5 --- /dev/null +++ b/include/asm-arm/arch-arc/uncompress.h @@ -0,0 +1,104 @@ +/* + * linux/include/asm-arm/arch-a5k/uncompress.h + * + * Copyright (C) 1996 Russell King + */ +#define VIDMEM ((char *)0x02000000) + +#include "../arch/arm/drivers/char/font.h" + +int video_num_columns, video_num_lines, video_size_row; +int white, bytes_per_char_h; +extern unsigned long con_charconvtable[256]; + +struct param_struct { + unsigned long page_size; + unsigned long nr_pages; + unsigned long ramdisk_size; + unsigned long mountrootrdonly; + unsigned long rootdev; + unsigned long video_num_cols; + unsigned long video_num_rows; + unsigned long video_x; + unsigned long video_y; + unsigned long memc_control_reg; + unsigned char sounddefault; + unsigned char adfsdrives; + unsigned char bytes_per_char_h; + unsigned char bytes_per_char_v; + unsigned long unused[256/4-11]; +}; + +static struct param_struct *params = (struct param_struct *)0x0207c000; + +/* + * This does not append a newline + */ +static void puts(const char *s) +{ + extern void ll_write_char(char *, unsigned long); + int x,y; + unsigned char c; + char *ptr; + + x = params->video_x; + y = params->video_y; + + while ( ( c = *(unsigned char *)s++ ) != '\0' ) { + if ( c == '\n' ) { + x = 0; + if ( ++y >= video_num_lines ) { + y--; + } + } else { + ptr = VIDMEM + ((y*video_num_columns*params->bytes_per_char_v+x)*bytes_per_char_h); + ll_write_char(ptr, c|(white<<8)); + if ( ++x >= video_num_columns ) { + x = 0; + if ( ++y >= video_num_lines ) { + y--; + } + } + } + } + + params->video_x = x; + params->video_y = y; +} + +static void error(char *x); + +/* + * Setup for decompression + */ +static void arch_decomp_setup(void) +{ + int i; + + video_num_lines = params->video_num_rows; + video_num_columns = params->video_num_cols; + bytes_per_char_h = params->bytes_per_char_h; + video_size_row = video_num_columns * bytes_per_char_h; + if (bytes_per_char_h == 4) + for (i = 0; i < 256; i++) + con_charconvtable[i] = + (i & 128 ? 1 << 0 : 0) | + (i & 64 ? 1 << 4 : 0) | + (i & 32 ? 1 << 8 : 0) | + (i & 16 ? 1 << 12 : 0) | + (i & 8 ? 1 << 16 : 0) | + (i & 4 ? 1 << 20 : 0) | + (i & 2 ? 1 << 24 : 0) | + (i & 1 ? 1 << 28 : 0); + else + for (i = 0; i < 16; i++) + con_charconvtable[i] = + (i & 8 ? 1 << 0 : 0) | + (i & 4 ? 1 << 8 : 0) | + (i & 2 ? 1 << 16 : 0) | + (i & 1 ? 1 << 24 : 0); + + white = bytes_per_char_h == 8 ? 0xfc : 7; + + if (params->nr_pages * params->page_size < 4096*1024) error("<4M of mem\n"); +} diff --git a/include/asm-arm/arch-ebsa110/a.out.h b/include/asm-arm/arch-ebsa110/a.out.h new file mode 100644 index 000000000..a34c23ef2 --- /dev/null +++ b/include/asm-arm/arch-ebsa110/a.out.h @@ -0,0 +1,16 @@ +/* + * linux/include/asm-arm/arch-ebsa110/a.out.h + * + * Copyright (C) 1996 Russell King + */ + +#ifndef __ASM_ARCH_A_OUT_H +#define __ASM_ARCH_A_OUT_H + +#ifdef __KERNEL__ +#define STACK_TOP (0xc0000000) +#define LIBRARY_START_TEXT (0x00c00000) +#endif + +#endif + diff --git a/include/asm-arm/arch-ebsa110/dma.h b/include/asm-arm/arch-ebsa110/dma.h new file mode 100644 index 000000000..73340527a --- /dev/null +++ b/include/asm-arm/arch-ebsa110/dma.h @@ -0,0 +1,100 @@ +/* + * linux/include/asm-arm/arch-ebsa110/dma.h + * + * Architecture DMA routes + * + * Copyright (C) 1997.1998 Russell King + */ +#ifndef __ASM_ARCH_DMA_H +#define __ASM_ARCH_DMA_H + +#ifdef KERNEL_ARCH_DMA + +static inline void arch_disable_dma (int dmanr) +{ + printk (dma_str, "arch_disable_dma", dmanr); +} + +static inline void arch_enable_dma (int dmanr) +{ + printk (dma_str, "arch_enable_dma", dmanr); +} + +static inline void arch_set_dma_addr (int dmanr, unsigned int addr) +{ + printk (dma_str, "arch_set_dma_addr", dmanr); +} + +static inline void arch_set_dma_count (int dmanr, unsigned int count) +{ + printk (dma_str, "arch_set_dma_count", dmanr); +} + +static inline void arch_set_dma_mode (int dmanr, char mode) +{ + printk (dma_str, "arch_set_dma_mode", dmanr); +} + +static inline int arch_dma_count (int dmanr) +{ + printk (dma_str, "arch_dma_count", dmanr); + return 0; +} + +#endif + +/* enable/disable a specific DMA channel */ +extern void enable_dma(unsigned int dmanr); + +static __inline__ void disable_dma(unsigned int dmanr) +{ + printk (dma_str, "disable_dma", dmanr); +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while interrupts are disabled! --- + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ + printk (dma_str, "clear_dma_ff", dmanr); +} + +/* set mode (above) for a specific DMA channel */ +extern void set_dma_mode(unsigned int dmanr, char mode); + +/* Set only the page register bits of the transfer address. + * This is used for successive transfers when we know the contents of + * the lower 16 bits of the DMA current address register, but a 64k boundary + * may have been crossed. + */ +static __inline__ void set_dma_page(unsigned int dmanr, char pagenr) +{ + printk (dma_str, "set_dma_page", dmanr); +} + + +/* Set transfer address & page bits for specific DMA channel. + * Assumes dma flipflop is clear. + */ +extern void set_dma_addr(unsigned int dmanr, unsigned int addr); + +/* Set transfer size for a specific DMA channel. + */ +extern void set_dma_count(unsigned int dmanr, unsigned int count); + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + * + * Assumes DMA flip-flop is clear. + */ +extern int get_dma_residue(unsigned int dmanr); + +#endif /* _ASM_ARCH_DMA_H */ + diff --git a/include/asm-arm/arch-ebsa110/hardware.h b/include/asm-arm/arch-ebsa110/hardware.h new file mode 100644 index 000000000..14655b47b --- /dev/null +++ b/include/asm-arm/arch-ebsa110/hardware.h @@ -0,0 +1,50 @@ +/* + * linux/include/asm-arm/arch-ebsa110/hardware.h + * + * Copyright (C) 1996,1997,1998 Russell King. + * + * This file contains the hardware definitions of the EBSA-110. + */ + +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +/* + * What hardware must be present + */ +#define HAS_PCIO + +#ifndef __ASSEMBLER__ + +/* + * IO definitions + */ +#define PIT_CTRL ((volatile unsigned char *)0xf200000d) +#define PIT_T2 ((volatile unsigned char *)0xf2000009) +#define PIT_T1 ((volatile unsigned char *)0xf2000005) +#define PIT_T0 ((volatile unsigned char *)0xf2000001) +#define PCIO_BASE 0xf0000000 + +/* + * Mapping areas + */ +#define IO_END 0xffffffff +#define IO_BASE 0xe0000000 +#define IO_SIZE (IO_END - IO_BASE) +#define IO_START 0xe0000000 + +/* + * RAM definitions + */ +#define MAPTOPHYS(a) ((unsigned long)(a) - PAGE_OFFSET) +#define KERNTOPHYS(a) ((unsigned long)(&a)) +#define KERNEL_BASE (0xc0008000) + +#else + +#define PCIO_BASE 0xf0000000 +#define IO_BASE 0 + +#endif +#endif + diff --git a/include/asm-arm/arch-ebsa110/ide.h b/include/asm-arm/arch-ebsa110/ide.h new file mode 100644 index 000000000..35eff5c28 --- /dev/null +++ b/include/asm-arm/arch-ebsa110/ide.h @@ -0,0 +1 @@ +/* no ide */ diff --git a/include/asm-arm/arch-ebsa110/io.h b/include/asm-arm/arch-ebsa110/io.h new file mode 100644 index 000000000..30621db0a --- /dev/null +++ b/include/asm-arm/arch-ebsa110/io.h @@ -0,0 +1,192 @@ +/* + * linux/include/asm-arm/arch-ebsa110/io.h + * + * Copyright (C) 1997,1998 Russell King + * + * Modifications: + * 06-Dec-1997 RMK Created. + */ +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +/* + * Virtual view <-> DMA view memory address translations + * virt_to_bus: Used to translate the virtual address to an + * address suitable to be passed to set_dma_addr + * bus_to_virt: Used to convert an address for DMA operations + * to an address that the kernel can use. + */ +#define virt_to_bus(x) ((unsigned long)(x)) +#define bus_to_virt(x) ((void *)(x)) + +/* + * This architecture does not require any delayed IO, and + * has the constant-optimised IO + */ +#undef ARCH_IO_DELAY + +/* + * We use two different types of addressing - PC style addresses, and ARM + * addresses. PC style accesses the PC hardware with the normal PC IO + * addresses, eg 0x3f8 for serial#1. ARM addresses are 0x80000000+ + * and are translated to the start of IO. Note that all addresses are + * shifted left! + */ +#define __PORT_PCIO(x) (!((x) & 0x80000000)) + +/* + * Dynamic IO functions - let the compiler + * optimize the expressions + */ +#define DECLARE_DYN_OUT(fnsuffix,instr) \ +extern __inline__ void __out##fnsuffix (unsigned int value, unsigned int port) \ +{ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "tst %2, #0x80000000\n\t" \ + "mov %0, %4\n\t" \ + "addeq %0, %0, %3\n\t" \ + "str" ##instr## " %1, [%0, %2, lsl #2]" \ + : "=&r" (temp) \ + : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \ + : "cc"); \ +} + +#define DECLARE_DYN_IN(sz,fnsuffix,instr) \ +extern __inline__ unsigned sz __in##fnsuffix (unsigned int port) \ +{ \ + unsigned long temp, value; \ + __asm__ __volatile__( \ + "tst %2, #0x80000000\n\t" \ + "mov %0, %4\n\t" \ + "addeq %0, %0, %3\n\t" \ + "ldr" ##instr## " %1, [%0, %2, lsl #2]" \ + : "=&r" (temp), "=r" (value) \ + : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \ + : "cc"); \ + return (unsigned sz)value; \ +} + +extern __inline__ unsigned int __ioaddr (unsigned int port) \ +{ \ + if (__PORT_PCIO(port)) \ + return (unsigned int)(PCIO_BASE + (port << 2)); \ + else \ + return (unsigned int)(IO_BASE + (port << 2)); \ +} + +#define DECLARE_IO(sz,fnsuffix,instr) \ + DECLARE_DYN_OUT(fnsuffix,instr) \ + DECLARE_DYN_IN(sz,fnsuffix,instr) + +DECLARE_IO(char,b,"b") +DECLARE_IO(short,w,"") +DECLARE_IO(long,l,"") + +#undef DECLARE_IO +#undef DECLARE_DYN_OUT +#undef DECLARE_DYN_IN + +/* + * Constant address IO functions + * + * These have to be macros for the 'J' constraint to work - + * +/-4096 immediate operand. + */ +#define __outbc(value,port) \ +({ \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "strb %0, [%1, %2]" \ + : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "strb %0, [%1, %2]" \ + : : "r" (value), "r" (IO_BASE), "r" ((port) << 2)); \ +}) + +#define __inbc(port) \ +({ \ + unsigned char result; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "ldrb %0, [%1, %2]" \ + : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "ldrb %0, [%1, %2]" \ + : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ + result; \ +}) + +#define __outwc(value,port) \ +({ \ + unsigned long v = value; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "str %0, [%1, %2]" \ + : : "r" (v|v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "str %0, [%1, %2]" \ + : : "r" (v|v<<16), "r" (IO_BASE), "r" ((port) << 2)); \ +}) + +#define __inwc(port) \ +({ \ + unsigned short result; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2]" \ + : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2]" \ + : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ + result & 0xffff; \ +}) + +#define __outlc(v,p) __outwc((v),(p)) + +#define __inlc(port) \ +({ \ + unsigned long result; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2]" \ + : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2]" \ + : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ + result; \ +}) + +#define __ioaddrc(port) \ +({ \ + unsigned long addr; \ + if (__PORT_PCIO((port))) \ + addr = PCIO_BASE + ((port) << 2); \ + else \ + addr = IO_BASE + ((port) << 2); \ + addr; \ +}) + +/* + * Translated address IO functions + * + * IO address has already been translated to a virtual address + */ +#define outb_t(v,p) \ + (*(volatile unsigned char *)(p) = (v)) + +#define inb_t(p) \ + (*(volatile unsigned char *)(p)) + +#define outl_t(v,p) \ + (*(volatile unsigned long *)(p) = (v)) + +#define inl_t(p) \ + (*(volatile unsigned long *)(p)) + +#endif diff --git a/include/asm-arm/arch-ebsa110/irq.h b/include/asm-arm/arch-ebsa110/irq.h new file mode 100644 index 000000000..18ddf053b --- /dev/null +++ b/include/asm-arm/arch-ebsa110/irq.h @@ -0,0 +1,46 @@ +/* + * include/asm-arm/arch-ebsa110/irq.h + * + * Copyright (C) 1996,1997,1998 Russell King + */ + +#define IRQ_MCLR ((volatile unsigned char *)0xf3000000) +#define IRQ_MSET ((volatile unsigned char *)0xf2c00000) +#define IRQ_MASK ((volatile unsigned char *)0xf2c00000) + +static __inline__ void mask_and_ack_irq(unsigned int irq) +{ + if (irq < 8) + *IRQ_MCLR = 1 << irq; +} + +static __inline__ void mask_irq(unsigned int irq) +{ + if (irq < 8) + *IRQ_MCLR = 1 << irq; +} + +static __inline__ void unmask_irq(unsigned int irq) +{ + if (irq < 8) + *IRQ_MSET = 1 << irq; +} + +static __inline__ unsigned long get_enabled_irqs(void) +{ + return 0; +} + +static __inline__ void irq_init_irq(void) +{ + unsigned long flags; + + save_flags_cli (flags); + *IRQ_MCLR = 0xff; + *IRQ_MSET = 0x55; + *IRQ_MSET = 0x00; + if (*IRQ_MASK != 0x55) + while (1); + *IRQ_MCLR = 0xff; /* clear all interrupt enables */ + restore_flags (flags); +} diff --git a/include/asm-arm/arch-ebsa110/irqs.h b/include/asm-arm/arch-ebsa110/irqs.h new file mode 100644 index 000000000..b83b5967c --- /dev/null +++ b/include/asm-arm/arch-ebsa110/irqs.h @@ -0,0 +1,14 @@ +/* + * linux/include/asm-arm/arch-sa100eval/irqs.h + * + * Copyright (C) 1996 Russell King + */ + +#define IRQ_PRINTER 0 +#define IRQ_COM1 1 +#define IRQ_COM2 2 +#define IRQ_ETHERNET 3 +#define IRQ_TIMER0 4 +#define IRQ_TIMER1 5 +#define IRQ_PCMCIA 6 +#define IRQ_IMMEDIATE 7 diff --git a/include/asm-arm/arch-ebsa110/mm-init.h b/include/asm-arm/arch-ebsa110/mm-init.h new file mode 100644 index 000000000..9c70f7505 --- /dev/null +++ b/include/asm-arm/arch-ebsa110/mm-init.h @@ -0,0 +1,11 @@ +/* + * linux/include/asm-arm/arch-ebsa110/mm-init.h + * + * Copyright (C) 1997,1998 Russell King + * + * Description of the initial memory map for EBSA-110 + */ + +static init_mem_map_t init_mem_map[] = { + INIT_MEM_MAP_SENTINEL +}; diff --git a/include/asm-arm/arch-ebsa110/mmap.h b/include/asm-arm/arch-ebsa110/mmap.h new file mode 100644 index 000000000..2ba0c2a27 --- /dev/null +++ b/include/asm-arm/arch-ebsa110/mmap.h @@ -0,0 +1,10 @@ +/* + * linux/include/asm-arm/arch-ebsa110/mmap.h + * + * Copyright (C) 1996,1997,1998 Russell King + */ + +/* + * Use SRAM for cache flushing + */ +#define SAFE_ADDR 0x40000000 diff --git a/include/asm-arm/arch-ebsa110/mmu.h b/include/asm-arm/arch-ebsa110/mmu.h new file mode 100644 index 000000000..fb684dd74 --- /dev/null +++ b/include/asm-arm/arch-ebsa110/mmu.h @@ -0,0 +1,19 @@ +/* + * linux/include/asm-arm/arch-ebsa110/mmu.h + * + * Copyright (c) 1996,1997,1998 Russell King. + * + * Changelog: + * 20-10-1996 RMK Created + * 31-12-1997 RMK Fixed definitions to reduce warnings + */ +#ifndef __ASM_ARCH_MMU_H +#define __ASM_ARCH_MMU_H + +/* + * On ebsa, the dram is contiguous + */ +#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET) +#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET) + +#endif diff --git a/include/asm-arm/arch-ebsa110/oldlatches.h b/include/asm-arm/arch-ebsa110/oldlatches.h new file mode 100644 index 000000000..8ff6ebd67 --- /dev/null +++ b/include/asm-arm/arch-ebsa110/oldlatches.h @@ -0,0 +1,9 @@ +/* + * Dummy oldlatches.h + * + * Copyright (C) 1996 Russell King + */ + +#ifdef __need_oldlatches +#error "Old latches not present in this (rpc) machine" +#endif diff --git a/include/asm-arm/arch-ebsa110/processor.h b/include/asm-arm/arch-ebsa110/processor.h new file mode 100644 index 000000000..b54085946 --- /dev/null +++ b/include/asm-arm/arch-ebsa110/processor.h @@ -0,0 +1,31 @@ +/* + * linux/include/asm-arm/arch-ebsa110/processor.h + * + * Copyright (C) 1996,1997,1998 Russell King + */ + +#ifndef __ASM_ARCH_PROCESSOR_H +#define __ASM_ARCH_PROCESSOR_H + +/* + * Bus types + */ +#define EISA_bus 0 +#define EISA_bus__is_a_macro /* for versions in ksyms.c */ +#define MCA_bus 0 +#define MCA_bus__is_a_macro /* for versions in ksyms.c */ + +/* + * User space: 3GB + */ +#define TASK_SIZE (0xc0000000UL) + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) + +#define INIT_MMAP \ +{ &init_mm, 0xc0000000, 0xc2000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } + +#endif diff --git a/include/asm-arm/arch-ebsa110/serial.h b/include/asm-arm/arch-ebsa110/serial.h new file mode 100644 index 000000000..1d41a7c1d --- /dev/null +++ b/include/asm-arm/arch-ebsa110/serial.h @@ -0,0 +1,41 @@ +/* + * linux/include/asm-arm/arch-ebsa110/serial.h + * + * Copyright (c) 1996,1997,1998 Russell King. + * + * Changelog: + * 15-10-1996 RMK Created + */ +#ifndef __ASM_ARCH_SERIAL_H +#define __ASM_ARCH_SERIAL_H + +/* + * This assumes you have a 1.8432 MHz clock for your UART. + * + * It'd be nice if someone built a serial card with a 24.576 MHz + * clock, since the 16550A is capable of handling a top speed of 1.5 + * megabits/second; but this requires the faster clock. + */ +#define BASE_BAUD (1843200 / 16) + +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) + + /* UART CLK PORT IRQ FLAGS */ +#define RS_UARTS \ + { 0, BASE_BAUD, 0x3F8, 1, STD_COM_FLAGS }, /* ttyS0 */ \ + { 0, BASE_BAUD, 0x2F8, 2, STD_COM_FLAGS }, /* ttyS1 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS2 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS3 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS4 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS5 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS6 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS7 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS8 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS9 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS10 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS11 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS12 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS13 */ + +#endif + diff --git a/include/asm-arm/arch-ebsa110/shmparam.h b/include/asm-arm/arch-ebsa110/shmparam.h new file mode 100644 index 000000000..9c36489cb --- /dev/null +++ b/include/asm-arm/arch-ebsa110/shmparam.h @@ -0,0 +1,5 @@ +/* + * linux/include/asm-arm/arch-ebsa110/shmparam.h + * + * Copyright (c) 1996 Russell King. + */ diff --git a/include/asm-arm/arch-ebsa110/system.h b/include/asm-arm/arch-ebsa110/system.h new file mode 100644 index 000000000..7a2957cae --- /dev/null +++ b/include/asm-arm/arch-ebsa110/system.h @@ -0,0 +1,18 @@ +/* + * linux/include/asm-arm/arch-ebsa110/system.h + * + * Copyright (c) 1996,1997,1998 Russell King. + */ +#ifndef __ASM_ARCH_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H + +extern __inline__ void arch_hard_reset (void) +{ + /* + * loop endlessly + */ + cli(); + while (1); +} + +#endif diff --git a/include/asm-arm/arch-ebsa110/time.h b/include/asm-arm/arch-ebsa110/time.h new file mode 100644 index 000000000..84d04d90f --- /dev/null +++ b/include/asm-arm/arch-ebsa110/time.h @@ -0,0 +1,89 @@ +/* + * linux/include/asm-arm/arch-ebsa110/time.h + * + * Copyright (c) 1996,1997,1998 Russell King. + * + * No real time clock on the evalulation board! + * + * Changelog: + * 10-Oct-1996 RMK Created + * 04-Dec-1997 RMK Updated for new arch/arm/time.c + */ + +#define MCLK_47_8 + +#if defined(MCLK_42_3) +#define PIT1_COUNT 0xecbe +#elif defined(MCLK_47_8) +/* + * This should be 0x10AE1, but that doesn't exactly fit. + * We run the timer interrupt at 5ms, and then divide it by + * two in software... This is so that the user processes + * see exactly the same model whichever ARM processor they're + * running on. + */ +#define PIT1_COUNT 0x8570 +#define DIVISOR 2 +#endif + +extern __inline__ unsigned long gettimeoffset (void) +{ + return 0; +} + +#ifndef DIVISOR +extern __inline__ int reset_timer (void) +{ + *PIT_T1 = (PIT1_COUNT) & 0xff; + *PIT_T1 = (PIT1_COUNT) >> 8; + return 1; +} +#else +extern __inline__ int reset_timer (void) +{ + static unsigned int divisor; + static int count = 50; + + *PIT_T1 = (PIT1_COUNT) & 0xff; + *PIT_T1 = (PIT1_COUNT) >> 8; + + if (--count == 0) { + count = 50; + *(volatile unsigned char *)0xf2400000 ^= 128; + } + + if (divisor == 0) { + divisor = DIVISOR - 1; + return 1; + } + divisor -= 1; + return 0; +} +#endif + +/* + * We don't have a RTC to update! + */ +#define update_rtc() + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +extern __inline__ unsigned long setup_timer (void) +{ + /* + * Timer 1, mode 0, 16-bit, autoreload + */ + *PIT_CTRL = 0x70; + /* + * Refresh counter clocked at 47.8MHz/7 = 146.4ns + * We want centi-second interrupts + */ + reset_timer (); + /* + * Default the date to 1 Jan 1970 0:0:0 + * You will have to run a time daemon to set the + * clock correctly at bootup + */ + return mktime(1970, 1, 1, 0, 0, 0); +} diff --git a/include/asm-arm/arch-ebsa110/timex.h b/include/asm-arm/arch-ebsa110/timex.h new file mode 100644 index 000000000..86bb588e7 --- /dev/null +++ b/include/asm-arm/arch-ebsa110/timex.h @@ -0,0 +1,15 @@ +/* + * linux/include/asm-arm/arch-ebsa110/timex.h + * + * RiscPC architecture timex specifications + * + * Copyright (C) 1997, 1998 Russell King + */ + +/* + * On the EBSA, the clock ticks at weird rates. + * This is therefore not used to calculate the + * divisor. + */ +//#define CLOCK_TICK_RATE 2000000 + diff --git a/include/asm-arm/arch-ebsa110/uncompress.h b/include/asm-arm/arch-ebsa110/uncompress.h new file mode 100644 index 000000000..d5260b027 --- /dev/null +++ b/include/asm-arm/arch-ebsa110/uncompress.h @@ -0,0 +1,33 @@ +/* + * linux/include/asm-arm/arch-ebsa110/uncompress.h + * + * Copyright (C) 1996,1997,1998 Russell King + */ + +/* + * This does not append a newline + */ +static void puts(const char *s) +{ + __asm__ __volatile__(" + ldrb %0, [%2], #1 + teq %0, #0 + beq 3f +1: strb %0, [%3] +2: ldrb %1, [%3, #0x14] + and %1, %1, #0x60 + teq %1, #0x60 + bne 2b + teq %0, #'\n' + moveq %0, #'\r' + beq 1b + ldrb %0, [%2], #1 + teq %0, #0 + bne 1b +3: " : : "r" (0), "r" (0), "r" (s), "r" (0xf0000be0) : "cc"); +} + +/* + * nothing to do + */ +#define arch_decomp_setup() diff --git a/include/asm-arm/arch-nexuspci/a.out.h b/include/asm-arm/arch-nexuspci/a.out.h new file mode 100644 index 000000000..b8e278074 --- /dev/null +++ b/include/asm-arm/arch-nexuspci/a.out.h @@ -0,0 +1,16 @@ +/* + * linux/include/asm-arm/arch-ebsa/a.out.h + * + * Copyright (C) 1996 Russell King + */ + +#ifndef __ASM_ARCH_A_OUT_H +#define __ASM_ARCH_A_OUT_H + +#ifdef __KERNEL__ +#define STACK_TOP (0xc0000000) +#define LIBRARY_START_TEXT (0x00c00000) +#endif + +#endif + diff --git a/include/asm-arm/arch-nexuspci/dma.h b/include/asm-arm/arch-nexuspci/dma.h new file mode 100644 index 000000000..73340527a --- /dev/null +++ b/include/asm-arm/arch-nexuspci/dma.h @@ -0,0 +1,100 @@ +/* + * linux/include/asm-arm/arch-ebsa110/dma.h + * + * Architecture DMA routes + * + * Copyright (C) 1997.1998 Russell King + */ +#ifndef __ASM_ARCH_DMA_H +#define __ASM_ARCH_DMA_H + +#ifdef KERNEL_ARCH_DMA + +static inline void arch_disable_dma (int dmanr) +{ + printk (dma_str, "arch_disable_dma", dmanr); +} + +static inline void arch_enable_dma (int dmanr) +{ + printk (dma_str, "arch_enable_dma", dmanr); +} + +static inline void arch_set_dma_addr (int dmanr, unsigned int addr) +{ + printk (dma_str, "arch_set_dma_addr", dmanr); +} + +static inline void arch_set_dma_count (int dmanr, unsigned int count) +{ + printk (dma_str, "arch_set_dma_count", dmanr); +} + +static inline void arch_set_dma_mode (int dmanr, char mode) +{ + printk (dma_str, "arch_set_dma_mode", dmanr); +} + +static inline int arch_dma_count (int dmanr) +{ + printk (dma_str, "arch_dma_count", dmanr); + return 0; +} + +#endif + +/* enable/disable a specific DMA channel */ +extern void enable_dma(unsigned int dmanr); + +static __inline__ void disable_dma(unsigned int dmanr) +{ + printk (dma_str, "disable_dma", dmanr); +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while interrupts are disabled! --- + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ + printk (dma_str, "clear_dma_ff", dmanr); +} + +/* set mode (above) for a specific DMA channel */ +extern void set_dma_mode(unsigned int dmanr, char mode); + +/* Set only the page register bits of the transfer address. + * This is used for successive transfers when we know the contents of + * the lower 16 bits of the DMA current address register, but a 64k boundary + * may have been crossed. + */ +static __inline__ void set_dma_page(unsigned int dmanr, char pagenr) +{ + printk (dma_str, "set_dma_page", dmanr); +} + + +/* Set transfer address & page bits for specific DMA channel. + * Assumes dma flipflop is clear. + */ +extern void set_dma_addr(unsigned int dmanr, unsigned int addr); + +/* Set transfer size for a specific DMA channel. + */ +extern void set_dma_count(unsigned int dmanr, unsigned int count); + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + * + * Assumes DMA flip-flop is clear. + */ +extern int get_dma_residue(unsigned int dmanr); + +#endif /* _ASM_ARCH_DMA_H */ + diff --git a/include/asm-arm/arch-nexuspci/hardware.h b/include/asm-arm/arch-nexuspci/hardware.h new file mode 100644 index 000000000..154bce9df --- /dev/null +++ b/include/asm-arm/arch-nexuspci/hardware.h @@ -0,0 +1,40 @@ +/* + * linux/include/asm-arm/arch-nexuspci/hardware.h + * + * Copyright (C) 1997 Philip Blundell + * + * This file contains the hardware definitions of the Nexus PCI card. + */ + +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +/* + * What hardware must be present + */ + +#ifndef __ASSEMBLER__ + +/* + * Mapping areas + */ +#define IO_END 0xffffffff +#define IO_BASE 0xd0000000 +#define IO_SIZE (IO_END - IO_BASE) +#define IO_START 0xd0000000 + +/* + * RAM definitions + */ +#define RAM_BASE 0x40000000 +#define MAPTOPHYS(a) ((unsigned long)(a) - PAGE_OFFSET + RAM_BASE) +#define KERNTOPHYS(a) ((unsigned long)(&a)) +#define KERNEL_BASE (0xc0008000) + +#else + +#define IO_BASE 0 + +#endif +#endif + diff --git a/include/asm-arm/arch-nexuspci/irq.h b/include/asm-arm/arch-nexuspci/irq.h new file mode 100644 index 000000000..18ddf053b --- /dev/null +++ b/include/asm-arm/arch-nexuspci/irq.h @@ -0,0 +1,46 @@ +/* + * include/asm-arm/arch-ebsa110/irq.h + * + * Copyright (C) 1996,1997,1998 Russell King + */ + +#define IRQ_MCLR ((volatile unsigned char *)0xf3000000) +#define IRQ_MSET ((volatile unsigned char *)0xf2c00000) +#define IRQ_MASK ((volatile unsigned char *)0xf2c00000) + +static __inline__ void mask_and_ack_irq(unsigned int irq) +{ + if (irq < 8) + *IRQ_MCLR = 1 << irq; +} + +static __inline__ void mask_irq(unsigned int irq) +{ + if (irq < 8) + *IRQ_MCLR = 1 << irq; +} + +static __inline__ void unmask_irq(unsigned int irq) +{ + if (irq < 8) + *IRQ_MSET = 1 << irq; +} + +static __inline__ unsigned long get_enabled_irqs(void) +{ + return 0; +} + +static __inline__ void irq_init_irq(void) +{ + unsigned long flags; + + save_flags_cli (flags); + *IRQ_MCLR = 0xff; + *IRQ_MSET = 0x55; + *IRQ_MSET = 0x00; + if (*IRQ_MASK != 0x55) + while (1); + *IRQ_MCLR = 0xff; /* clear all interrupt enables */ + restore_flags (flags); +} diff --git a/include/asm-arm/arch-nexuspci/irqs.h b/include/asm-arm/arch-nexuspci/irqs.h new file mode 100644 index 000000000..661af14a1 --- /dev/null +++ b/include/asm-arm/arch-nexuspci/irqs.h @@ -0,0 +1,14 @@ +/* + * linux/include/asm-arm/arch-nexuspci/irqs.h + * + * Copyright (C) 1997 Philip Blundell + */ + +#define IRQ_DUART 0 +#define IRQ_TIMER0 0 /* timer is part of the DUART */ +#define IRQ_PLX 1 +#define IRQ_PCI_D 2 +#define IRQ_PCI_C 3 +#define IRQ_PCI_B 4 +#define IRQ_PCI_A 5 +#define IRQ_SYSERR 6 /* must ask JB about this one */ diff --git a/include/asm-arm/arch-nexuspci/mmap.h b/include/asm-arm/arch-nexuspci/mmap.h new file mode 100644 index 000000000..2ba0c2a27 --- /dev/null +++ b/include/asm-arm/arch-nexuspci/mmap.h @@ -0,0 +1,10 @@ +/* + * linux/include/asm-arm/arch-ebsa110/mmap.h + * + * Copyright (C) 1996,1997,1998 Russell King + */ + +/* + * Use SRAM for cache flushing + */ +#define SAFE_ADDR 0x40000000 diff --git a/include/asm-arm/arch-nexuspci/mmu.h b/include/asm-arm/arch-nexuspci/mmu.h new file mode 100644 index 000000000..6e21320d3 --- /dev/null +++ b/include/asm-arm/arch-nexuspci/mmu.h @@ -0,0 +1,16 @@ +/* + * linux/include/asm-arm/arch-nexuspci/mmu.h + * + * Copyright (c) 1997 Philip Blundell. + * + */ +#ifndef __ASM_ARCH_MMU_H +#define __ASM_ARCH_MMU_H + +/* + * On NexusPCI, the dram is contiguous + */ +#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET + 0x40000000) +#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET - 0x40000000) + +#endif diff --git a/include/asm-arm/arch-nexuspci/processor.h b/include/asm-arm/arch-nexuspci/processor.h new file mode 100644 index 000000000..b54085946 --- /dev/null +++ b/include/asm-arm/arch-nexuspci/processor.h @@ -0,0 +1,31 @@ +/* + * linux/include/asm-arm/arch-ebsa110/processor.h + * + * Copyright (C) 1996,1997,1998 Russell King + */ + +#ifndef __ASM_ARCH_PROCESSOR_H +#define __ASM_ARCH_PROCESSOR_H + +/* + * Bus types + */ +#define EISA_bus 0 +#define EISA_bus__is_a_macro /* for versions in ksyms.c */ +#define MCA_bus 0 +#define MCA_bus__is_a_macro /* for versions in ksyms.c */ + +/* + * User space: 3GB + */ +#define TASK_SIZE (0xc0000000UL) + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) + +#define INIT_MMAP \ +{ &init_mm, 0xc0000000, 0xc2000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } + +#endif diff --git a/include/asm-arm/arch-nexuspci/serial.h b/include/asm-arm/arch-nexuspci/serial.h new file mode 100644 index 000000000..1d41a7c1d --- /dev/null +++ b/include/asm-arm/arch-nexuspci/serial.h @@ -0,0 +1,41 @@ +/* + * linux/include/asm-arm/arch-ebsa110/serial.h + * + * Copyright (c) 1996,1997,1998 Russell King. + * + * Changelog: + * 15-10-1996 RMK Created + */ +#ifndef __ASM_ARCH_SERIAL_H +#define __ASM_ARCH_SERIAL_H + +/* + * This assumes you have a 1.8432 MHz clock for your UART. + * + * It'd be nice if someone built a serial card with a 24.576 MHz + * clock, since the 16550A is capable of handling a top speed of 1.5 + * megabits/second; but this requires the faster clock. + */ +#define BASE_BAUD (1843200 / 16) + +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) + + /* UART CLK PORT IRQ FLAGS */ +#define RS_UARTS \ + { 0, BASE_BAUD, 0x3F8, 1, STD_COM_FLAGS }, /* ttyS0 */ \ + { 0, BASE_BAUD, 0x2F8, 2, STD_COM_FLAGS }, /* ttyS1 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS2 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS3 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS4 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS5 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS6 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS7 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS8 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS9 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS10 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS11 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS12 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS13 */ + +#endif + diff --git a/include/asm-arm/arch-nexuspci/shmparam.h b/include/asm-arm/arch-nexuspci/shmparam.h new file mode 100644 index 000000000..9c36489cb --- /dev/null +++ b/include/asm-arm/arch-nexuspci/shmparam.h @@ -0,0 +1,5 @@ +/* + * linux/include/asm-arm/arch-ebsa110/shmparam.h + * + * Copyright (c) 1996 Russell King. + */ diff --git a/include/asm-arm/arch-nexuspci/system.h b/include/asm-arm/arch-nexuspci/system.h new file mode 100644 index 000000000..7a2957cae --- /dev/null +++ b/include/asm-arm/arch-nexuspci/system.h @@ -0,0 +1,18 @@ +/* + * linux/include/asm-arm/arch-ebsa110/system.h + * + * Copyright (c) 1996,1997,1998 Russell King. + */ +#ifndef __ASM_ARCH_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H + +extern __inline__ void arch_hard_reset (void) +{ + /* + * loop endlessly + */ + cli(); + while (1); +} + +#endif diff --git a/include/asm-arm/arch-nexuspci/time.h b/include/asm-arm/arch-nexuspci/time.h new file mode 100644 index 000000000..ddbee82db --- /dev/null +++ b/include/asm-arm/arch-nexuspci/time.h @@ -0,0 +1,29 @@ +/* + * linux/include/asm-arm/arch-nexuspci/time.h + * + * Copyright (c) 1997 Phil Blundell. + * + * Nexus PCI card has no real-time clock. + * + */ + +extern __inline__ unsigned long gettimeoffset (void) +{ + return 0; +} + +extern __inline__ int reset_timer (void) +{ + return 0; +} + +extern __inline__ unsigned long setup_timer (void) +{ + reset_timer (); + /* + * Default the date to 1 Jan 1970 0:0:0 + * You will have to run a time daemon to set the + * clock correctly at bootup + */ + return mktime(1970, 1, 1, 0, 0, 0); +} diff --git a/include/asm-arm/arch-nexuspci/uncompress.h b/include/asm-arm/arch-nexuspci/uncompress.h new file mode 100644 index 000000000..16daee5b9 --- /dev/null +++ b/include/asm-arm/arch-nexuspci/uncompress.h @@ -0,0 +1,17 @@ +/* + * linux/include/asm-arm/arch-ebsa110/uncompress.h + * + * Copyright (C) 1996,1997,1998 Russell King + */ + +/* + * This does not append a newline + */ +static void puts(const char *s) +{ +} + +/* + * nothing to do + */ +#define arch_decomp_setup() diff --git a/include/asm-arm/arch-rpc/a.out.h b/include/asm-arm/arch-rpc/a.out.h new file mode 100644 index 000000000..c9a1d0413 --- /dev/null +++ b/include/asm-arm/arch-rpc/a.out.h @@ -0,0 +1,16 @@ +/* + * linux/include/asm-arm/arch-rpc/a.out.h + * + * Copyright (C) 1996 Russell King + */ + +#ifndef __ASM_ARCH_A_OUT_H +#define __ASM_ARCH_A_OUT_H + +#ifdef __KERNEL__ +#define STACK_TOP (0xc0000000) +#define LIBRARY_START_TEXT (0x00c00000) +#endif + +#endif + diff --git a/include/asm-arm/arch-rpc/dma.h b/include/asm-arm/arch-rpc/dma.h new file mode 100644 index 000000000..540ac46f1 --- /dev/null +++ b/include/asm-arm/arch-rpc/dma.h @@ -0,0 +1,128 @@ +#ifndef __ASM_ARCH_DMA_H +#define __ASM_ARCH_DMA_H + +#define MAX_DMA_ADDRESS 0xd0000000 + +#ifdef KERNEL_ARCH_DMA + +static unsigned char arch_dma_setup; +unsigned char arch_dma_ctrl[8]; +unsigned long arch_dma_addr[8]; +unsigned long arch_dma_cnt[8]; + +static inline void arch_enable_dma(int dmanr) +{ + if (!(arch_dma_setup & (1 << dmanr))) { + arch_dma_setup |= 1 << dmanr; +/* dma_interrupt (16 + dmanr);*/ + } + arch_dma_ctrl[dmanr] |= DMA_CR_E; + switch (dmanr) { + case 0: outb (arch_dma_ctrl[0], IOMD_IO0CR); break; + case 1: outb (arch_dma_ctrl[1], IOMD_IO1CR); break; + case 2: outb (arch_dma_ctrl[2], IOMD_IO2CR); break; + case 3: outb (arch_dma_ctrl[3], IOMD_IO3CR); break; + case 4: outb (arch_dma_ctrl[4], IOMD_SD0CR); break; + case 5: outb (arch_dma_ctrl[5], IOMD_SD1CR); break; + } +} + +static inline void arch_disable_dma(int dmanr) +{ + arch_dma_ctrl[dmanr] &= ~DMA_CR_E; + switch (dmanr) { + case 0: outb (arch_dma_ctrl[0], IOMD_IO0CR); break; + case 1: outb (arch_dma_ctrl[1], IOMD_IO1CR); break; + case 2: outb (arch_dma_ctrl[2], IOMD_IO2CR); break; + case 3: outb (arch_dma_ctrl[3], IOMD_IO3CR); break; + case 4: outb (arch_dma_ctrl[4], IOMD_SD0CR); break; + case 5: outb (arch_dma_ctrl[5], IOMD_SD1CR); break; + } +} + +static inline void arch_set_dma_addr(int dmanr, unsigned int addr) +{ + arch_dma_setup &= ~dmanr; + arch_dma_addr[dmanr] = addr; +} + +static inline void arch_set_dma_count(int dmanr, unsigned int count) +{ + arch_dma_setup &= ~dmanr; + arch_dma_cnt[dmanr] = count; +} + +static inline void arch_set_dma_mode(int dmanr, char mode) +{ + switch (mode) { + case DMA_MODE_READ: + arch_dma_ctrl[dmanr] |= DMA_CR_D; + break; + case DMA_MODE_WRITE: + arch_dma_ctrl[dmanr] &= ~DMA_CR_D; + break; + } +} + +static inline int arch_dma_count (int dmanr) +{ + return arch_dma_cnt[dmanr]; +} +#endif + +/* enable/disable a specific DMA channel */ +extern void enable_dma(unsigned int dmanr); + +static __inline__ void disable_dma(unsigned int dmanr) +{ + switch(dmanr) { + case 1: break; + case 2: disable_irq(64); break; + default: printk(dma_str, "disable_dma", dmanr); break; + } +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while interrupts are disabled! --- + */ +#define clear_dma_ff(dmanr) + +/* set mode (above) for a specific DMA channel */ +extern void set_dma_mode(unsigned int dmanr, char mode); + +/* Set only the page register bits of the transfer address. + * This is used for successive transfers when we know the contents of + * the lower 16 bits of the DMA current address register, but a 64k boundary + * may have been crossed. + */ +static __inline__ void set_dma_page(unsigned int dmanr, char pagenr) +{ + printk (dma_str, "set_dma_page", dmanr); +} + + +/* Set transfer address & page bits for specific DMA channel. + * Assumes dma flipflop is clear. + */ +extern void set_dma_addr(unsigned int dmanr, unsigned int addr); + +/* Set transfer size for a specific DMA channel. + */ +extern void set_dma_count(unsigned int dmanr, unsigned int count); + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + * + * Assumes DMA flip-flop is clear. + */ +extern int get_dma_residue(unsigned int dmanr); + +#endif /* _ASM_ARCH_DMA_H */ + diff --git a/include/asm-arm/arch-rpc/hardware.h b/include/asm-arm/arch-rpc/hardware.h new file mode 100644 index 000000000..2bdd96c6f --- /dev/null +++ b/include/asm-arm/arch-rpc/hardware.h @@ -0,0 +1,101 @@ +/* + * linux/include/asm-arm/arch-rpc/hardware.h + * + * Copyright (C) 1996 Russell King. + * + * This file contains the hardware definitions of the RiscPC series machines. + */ + +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +/* + * What hardware must be present + */ +#define HAS_IOMD +#define HAS_PCIO +#define HAS_VIDC20 + +/* + * Optional hardware + */ +#define HAS_EXPMASK + +/* + * Physical definitions + */ +#define RAM_START 0x10000000 +#define IO_START 0x03000000 +#define SCREEN_START 0x02000000 /* VRAM */ + +#ifndef __ASSEMBLER__ + +/* + * for use with inb/outb + */ +#define VIDC_AUDIO_BASE 0x80140000 +#define VIDC_BASE 0x80100000 +#define IOCEC4IO_BASE 0x8009c000 +#define IOCECIO_BASE 0x80090000 +#define IOMD_BASE 0x80080000 +#define MEMCEC8IO_BASE 0x8000ac00 +#define MEMCECIO_BASE 0x80000000 + +/* + * IO definitions + */ +#define EXPMASK_BASE ((volatile unsigned char *)0xe0360000) +#define IOEB_BASE ((volatile unsigned char *)0xe0350050) +#define IOC_BASE ((volatile unsigned char *)0xe0200000) +#define PCIO_FLOPPYDMABASE ((volatile unsigned char *)0xe002a000) +#define PCIO_BASE 0xe0010000 + +/* + * Mapping areas + */ +#define IO_END 0xe0ffffff +#define IO_BASE 0xe0000000 +#define IO_SIZE (IO_END - IO_BASE) + +/* + * Screen mapping information + */ +#define SCREEN2_END 0xe0000000 +#define SCREEN2_BASE 0xd8000000 +#define SCREEN1_END SCREEN2_BASE +#define SCREEN1_BASE 0xd0000000 + +/* + * Offsets from RAM base + */ +#define PARAMS_OFFSET 0x0100 +#define KERNEL_OFFSET 0x8000 + +/* + * RAM definitions + */ +#define MAPTOPHYS(x) (x) +#define KERNTOPHYS(x) ((unsigned long)(&x)) +#define GET_MEMORY_END(p) (PAGE_OFFSET + p->u1.s.page_size * \ + (p->u1.s.pages_in_bank[0] + \ + p->u1.s.pages_in_bank[1] + \ + p->u1.s.pages_in_bank[2] + \ + p->u1.s.pages_in_bank[3])) + +#define KERNEL_BASE (PAGE_OFFSET + KERNEL_OFFSET) +#define PARAMS_BASE (PAGE_OFFSET + PARAMS_OFFSET) +#define Z_PARAMS_BASE (RAM_START + PARAMS_OFFSET) + +#else + +#define VIDC_SND_BASE 0xe0500000 +#define VIDC_BASE 0xe0400000 +#define IOMD_BASE 0xe0200000 +#define IOC_BASE 0xe0200000 +#define PCIO_FLOPPYDMABASE 0xe002a000 +#define PCIO_BASE 0xe0010000 +#define IO_BASE 0xe0000000 + +#endif +#endif + diff --git a/include/asm-arm/arch-rpc/ide.h b/include/asm-arm/arch-rpc/ide.h new file mode 100644 index 000000000..49463bae0 --- /dev/null +++ b/include/asm-arm/arch-rpc/ide.h @@ -0,0 +1,44 @@ +/* + * linux/include/asm-arm/arch-rpc/ide.h + * + * Copyright (c) 1997 Russell King + */ + +static __inline__ int +ide_default_irq(ide_ioreg_t base) +{ + if (base == 0x1f0) + return 9; + return 0; +} + +static __inline__ ide_ioreg_t +ide_default_io_base(int index) +{ + if (index == 0) + return 0x1f0; + return 0; +} + +static __inline__ int +ide_default_stepping(int index) +{ + return 0; +} + +static __inline__ void +ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int stepping, int *irq) +{ + ide_ioreg_t port = base; + ide_ioreg_t ctrl = base + 0x206; + int i; + + i = 8; + while (i--) { + *p++ = port; + port += 1 << stepping; + } + *p++ = ctrl; + if (irq != NULL) + irq = 0; +} diff --git a/include/asm-arm/arch-rpc/io.h b/include/asm-arm/arch-rpc/io.h new file mode 100644 index 000000000..b78483cc8 --- /dev/null +++ b/include/asm-arm/arch-rpc/io.h @@ -0,0 +1,203 @@ +/* + * linux/include/asm-arm/arch-rpc/io.h + * + * Copyright (C) 1997 Russell King + * + * Modifications: + * 06-Dec-1997 RMK Created. + */ +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +/* + * Virtual view <-> DMA view memory address translations + * virt_to_bus: Used to translate the virtual address to an + * address suitable to be passed to set_dma_addr + * bus_to_virt: Used to convert an address for DMA operations + * to an address that the kernel can use. + */ +#define virt_to_bus(x) ((unsigned long)(x)) +#define bus_to_virt(x) ((void *)(x)) + +/* + * This architecture does not require any delayed IO, and + * has the constant-optimised IO + */ +#undef ARCH_IO_DELAY + +/* + * We use two different types of addressing - PC style addresses, and ARM + * addresses. PC style accesses the PC hardware with the normal PC IO + * addresses, eg 0x3f8 for serial#1. ARM addresses are 0x80000000+ + * and are translated to the start of IO. Note that all addresses are + * shifted left! + */ +#define __PORT_PCIO(x) (!((x) & 0x80000000)) + +/* + * Dynamic IO functions - let the compiler + * optimize the expressions + */ +#define DECLARE_DYN_OUT(fnsuffix,instr) \ +extern __inline__ void __out##fnsuffix (unsigned int value, unsigned int port) \ +{ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "tst %2, #0x80000000\n\t" \ + "mov %0, %4\n\t" \ + "addeq %0, %0, %3\n\t" \ + "str" ##instr## " %1, [%0, %2, lsl #2]" \ + : "=&r" (temp) \ + : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \ + : "cc"); \ +} + +#define DECLARE_DYN_IN(sz,fnsuffix,instr) \ +extern __inline__ unsigned sz __in##fnsuffix (unsigned int port) \ +{ \ + unsigned long temp, value; \ + __asm__ __volatile__( \ + "tst %2, #0x80000000\n\t" \ + "mov %0, %4\n\t" \ + "addeq %0, %0, %3\n\t" \ + "ldr" ##instr## " %1, [%0, %2, lsl #2]" \ + : "=&r" (temp), "=r" (value) \ + : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \ + : "cc"); \ + return (unsigned sz)value; \ +} + +extern __inline__ unsigned int __ioaddr (unsigned int port) \ +{ \ + if (__PORT_PCIO(port)) \ + return (unsigned int)(PCIO_BASE + (port << 2)); \ + else \ + return (unsigned int)(IO_BASE + (port << 2)); \ +} + +#define DECLARE_IO(sz,fnsuffix,instr) \ + DECLARE_DYN_OUT(fnsuffix,instr) \ + DECLARE_DYN_IN(sz,fnsuffix,instr) + +DECLARE_IO(char,b,"b") +DECLARE_IO(short,w,"") +DECLARE_IO(long,l,"") + +#undef DECLARE_IO +#undef DECLARE_DYN_OUT +#undef DECLARE_DYN_IN + +/* + * Constant address IO functions + * + * These have to be macros for the 'J' constraint to work - + * +/-4096 immediate operand. + */ +#define __outbc(value,port) \ +({ \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "strb %0, [%1, %2]" \ + : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "strb %0, [%1, %2]" \ + : : "r" (value), "r" (IO_BASE), "r" ((port) << 2)); \ +}) + +#define __inbc(port) \ +({ \ + unsigned char result; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "ldrb %0, [%1, %2]" \ + : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "ldrb %0, [%1, %2]" \ + : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ + result; \ +}) + +#define __outwc(value,port) \ +({ \ + unsigned long v = value; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "str %0, [%1, %2]" \ + : : "r" (v|v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "str %0, [%1, %2]" \ + : : "r" (v|v<<16), "r" (IO_BASE), "r" ((port) << 2)); \ +}) + +#define __inwc(port) \ +({ \ + unsigned short result; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2]" \ + : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2]" \ + : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ + result & 0xffff; \ +}) + +#define __outlc(value,port) \ +({ \ + unsigned long v = value; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "str %0, [%1, %2]" \ + : : "r" (v), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "str %0, [%1, %2]" \ + : : "r" (v), "r" (IO_BASE), "r" ((port) << 2)); \ +}) + +#define __inlc(port) \ +({ \ + unsigned long result; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2]" \ + : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ + else \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2]" \ + : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ + result; \ +}) + +#define __ioaddrc(port) \ +({ \ + unsigned long addr; \ + if (__PORT_PCIO((port))) \ + addr = PCIO_BASE + ((port) << 2); \ + else \ + addr = IO_BASE + ((port) << 2); \ + addr; \ +}) + +/* + * Translated address IO functions + * + * IO address has already been translated to a virtual address + */ +#define outb_t(v,p) \ + (*(volatile unsigned char *)(p) = (v)) + +#define inb_t(p) \ + (*(volatile unsigned char *)(p)) + +#define outl_t(v,p) \ + (*(volatile unsigned long *)(p) = (v)) + +#define inl_t(p) \ + (*(volatile unsigned long *)(p)) + +#endif diff --git a/include/asm-arm/arch-rpc/irq.h b/include/asm-arm/arch-rpc/irq.h new file mode 100644 index 000000000..750f5c905 --- /dev/null +++ b/include/asm-arm/arch-rpc/irq.h @@ -0,0 +1,138 @@ +/* + * include/asm-arm/arch-rpc/irq.h + * + * Copyright (C) 1996 Russell King + * + * Changelog: + * 10-10-1996 RMK Brought up to date with arch-sa110eval + */ + +#define BUILD_IRQ(s,n,m) \ + void IRQ##n##_interrupt(void); \ + void fast_IRQ##n##_interrupt(void); \ + void bad_IRQ##n##_interrupt(void); \ + void probe_IRQ##n##_interrupt(void); + +/* + * The timer is a special interrupt + */ +#define IRQ5_interrupt timer_IRQ_interrupt + +#define IRQ_INTERRUPT(n) IRQ##n##_interrupt +#define FAST_INTERRUPT(n) fast_IRQ##n##_interrupt +#define BAD_INTERRUPT(n) bad_IRQ##n##_interrupt +#define PROBE_INTERRUPT(n) probe_IRQ##n##_interrupt + +#define X(x) (x)|0x01, (x)|0x02, (x)|0x04, (x)|0x08, (x)|0x10, (x)|0x20, (x)|0x40, (x)|0x80 +#define Z(x) (x), (x), (x), (x), (x), (x), (x), (x) + +static __inline__ void mask_and_ack_irq(unsigned int irq) +{ + static const int addrmasks[] = { + X((IOMD_IRQMASKA - IOMD_BASE)<<18 | (1 << 15)), + X((IOMD_IRQMASKB - IOMD_BASE)<<18), + X((IOMD_DMAMASK - IOMD_BASE)<<18), + Z(0), + Z(0), + Z(0), + Z(0), + Z(0), + X((IOMD_FIQMASK - IOMD_BASE)<<18), + Z(0), + Z(0), + Z(0), + Z(0), + Z(0), + Z(0), + Z(0) + }; + unsigned int temp1, temp2; + + __asm__ __volatile__( +" ldr %1, [%5, %3, lsl #2]\n" +" teq %1, #0\n" +" beq 2f\n" +" ldrb %0, [%2, %1, lsr #16]\n" +" bic %0, %0, %1\n" +" strb %0, [%2, %1, lsr #16]\n" +" tst %1, #0x8000\n" /* do we need an IRQ clear? */ +" strneb %1, [%2, %4]\n" +"2:" + : "=&r" (temp1), "=&r" (temp2) + : "r" (ioaddr(IOMD_BASE)), "r" (irq), + "I" ((IOMD_IRQCLRA - IOMD_BASE) << 2), "r" (addrmasks)); +} + +#undef X +#undef Z + +static __inline__ void mask_irq(unsigned int irq) +{ + extern void ecard_disableirq (unsigned int); + extern void ecard_disablefiq (unsigned int); + unsigned char mask = 1 << (irq & 7); + + switch (irq >> 3) { + case 0: + outb(inb(IOMD_IRQMASKA) & ~mask, IOMD_IRQMASKA); + break; + case 1: + outb(inb(IOMD_IRQMASKB) & ~mask, IOMD_IRQMASKB); + break; + case 2: + outb(inb(IOMD_DMAMASK) & ~mask, IOMD_DMAMASK); + break; + case 4: + ecard_disableirq (irq & 7); + break; + case 8: + outb(inb(IOMD_FIQMASK) & ~mask, IOMD_FIQMASK); + break; + case 12: + ecard_disablefiq (irq & 7); + } +} + +static __inline__ void unmask_irq(unsigned int irq) +{ + extern void ecard_enableirq (unsigned int); + extern void ecard_enablefiq (unsigned int); + unsigned char mask = 1 << (irq & 7); + + switch (irq >> 3) { + case 0: + outb(inb(IOMD_IRQMASKA) | mask, IOMD_IRQMASKA); + break; + case 1: + outb(inb(IOMD_IRQMASKB) | mask, IOMD_IRQMASKB); + break; + case 2: + outb(inb(IOMD_DMAMASK) | mask, IOMD_DMAMASK); + break; + case 4: + ecard_enableirq (irq & 7); + break; + case 8: + outb(inb(IOMD_FIQMASK) | mask, IOMD_FIQMASK); + break; + case 12: + ecard_enablefiq (irq & 7); + } +} + +static __inline__ unsigned long get_enabled_irqs(void) +{ + return inb(IOMD_IRQMASKA) | inb(IOMD_IRQMASKB) << 8 | inb(IOMD_DMAMASK) << 16; +} + +static __inline__ void irq_init_irq(void) +{ + outb(0, IOMD_IRQMASKA); + outb(0, IOMD_IRQMASKB); + outb(0, IOMD_FIQMASK); + outb(0, IOMD_DMAMASK); + outb(0, IOMD_IO0CR); + outb(0, IOMD_IO1CR); + outb(0, IOMD_IO2CR); + outb(0, IOMD_IO3CR); +} diff --git a/include/asm-arm/arch-rpc/irqs.h b/include/asm-arm/arch-rpc/irqs.h new file mode 100644 index 000000000..b7188fb8e --- /dev/null +++ b/include/asm-arm/arch-rpc/irqs.h @@ -0,0 +1,28 @@ +/* + * linux/include/asm-arm/arch-a5k/irqs.h + * + * Copyright (C) 1996 Russell King + */ + +#define IRQ_PRINTER 0 +#define IRQ_BATLOW 1 +#define IRQ_FLOPPYINDEX 2 +#define IRQ_VSYNCPULSE 3 +#define IRQ_POWERON 4 +#define IRQ_TIMER0 5 +#define IRQ_TIMER1 6 +#define IRQ_IMMEDIATE 7 +#define IRQ_EXPCARDFIQ 8 +#define IRQ_SOUNDCHANGE 9 +#define IRQ_SERIALPORT 10 +#define IRQ_HARDDISK 11 +#define IRQ_FLOPPYDISK 12 +#define IRQ_EXPANSIONCARD 13 +#define IRQ_KEYBOARDTX 14 +#define IRQ_KEYBOARDRX 15 + +#define FIQ_FLOPPYDATA 0 +#define FIQ_ECONET 2 +#define FIQ_SERIALPORT 4 +#define FIQ_EXPANSIONCARD 6 +#define FIQ_FORCE 7 diff --git a/include/asm-arm/arch-rpc/mmap.h b/include/asm-arm/arch-rpc/mmap.h new file mode 100644 index 000000000..4a1cdeab9 --- /dev/null +++ b/include/asm-arm/arch-rpc/mmap.h @@ -0,0 +1,48 @@ +/* + * linux/include/asm-arm/arch-rpc/mmap.h + * + * Copyright (C) 1996 Russell King + */ + +#define HAVE_MAP_VID_MEM +#define SAFE_ADDR 0x00000000 /* ROM */ + +unsigned long map_screen_mem(unsigned long log_start, unsigned long kmem, int update) +{ + static int updated = 0; + unsigned long address; + pgd_t *pgd; + + if (updated) + return 0; + updated = update; + + address = SCREEN_START | PMD_TYPE_SECT | PMD_DOMAIN(DOMAIN_KERNEL) | PMD_SECT_AP_WRITE; + pgd = swapper_pg_dir + (SCREEN2_BASE >> PGDIR_SHIFT); + pgd_val(pgd[0]) = address; + pgd_val(pgd[1]) = address + (1 << PGDIR_SHIFT); + + if (update) { + unsigned long pgtable = PAGE_ALIGN(kmem), *p; + int i; + + memzero ((void *)pgtable, 4096); + + pgd_val(pgd[-2]) = virt_to_phys(pgtable) | PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_KERNEL); + pgd_val(pgd[-1]) = virt_to_phys(pgtable + PTRS_PER_PTE*4) | PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_KERNEL); + p = (unsigned long *)pgtable; + + i = PTRS_PER_PTE * 2 - ((SCREEN1_END - log_start) >> PAGE_SHIFT); + address = SCREEN_START | PTE_TYPE_SMALL | PTE_AP_WRITE; + + while (i < PTRS_PER_PTE * 2) { + p[i++] = address; + address += PAGE_SIZE; + } + + flush_page_to_ram(pgtable); + + kmem = pgtable + PAGE_SIZE; + } + return kmem; +} diff --git a/include/asm-arm/arch-rpc/mmu.h b/include/asm-arm/arch-rpc/mmu.h new file mode 100644 index 000000000..fbd403d36 --- /dev/null +++ b/include/asm-arm/arch-rpc/mmu.h @@ -0,0 +1,17 @@ +/* + * linux/include/asm-arm/arch-rpc/mmu.h + * + * Copyright (c) 1996,1997,1998 Russell King. + * + * Changelog: + * 20-10-1996 RMK Created + * 31-12-1997 RMK Fixed definitions to reduce warnings + * 11-01-1998 RMK Uninlined to reduce hits on cache + */ +#ifndef __ASM_ARCH_MMU_H +#define __ASM_ARCH_MMU_H + +extern unsigned long __virt_to_phys(unsigned long vpage); +extern unsigned long __phys_to_virt(unsigned long ppage); + +#endif diff --git a/include/asm-arm/arch-rpc/oldlatches.h b/include/asm-arm/arch-rpc/oldlatches.h new file mode 100644 index 000000000..8ff6ebd67 --- /dev/null +++ b/include/asm-arm/arch-rpc/oldlatches.h @@ -0,0 +1,9 @@ +/* + * Dummy oldlatches.h + * + * Copyright (C) 1996 Russell King + */ + +#ifdef __need_oldlatches +#error "Old latches not present in this (rpc) machine" +#endif diff --git a/include/asm-arm/arch-rpc/processor.h b/include/asm-arm/arch-rpc/processor.h new file mode 100644 index 000000000..d5c478737 --- /dev/null +++ b/include/asm-arm/arch-rpc/processor.h @@ -0,0 +1,34 @@ +/* + * linux/include/asm-arm/arch-rpc/processor.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 10-09-1996 RMK Created + */ + +#ifndef __ASM_ARCH_PROCESSOR_H +#define __ASM_ARCH_PROCESSOR_H + +/* + * Bus types + */ +#define EISA_bus 0 +#define EISA_bus__is_a_macro /* for versions in ksyms.c */ +#define MCA_bus 0 +#define MCA_bus__is_a_macro /* for versions in ksyms.c */ + +/* + * User space: 3GB + */ +#define TASK_SIZE (0xc0000000UL) + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) + +#define INIT_MMAP \ +{ &init_mm, 0xc0000000, 0xc2000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } + +#endif diff --git a/include/asm-arm/arch-rpc/serial.h b/include/asm-arm/arch-rpc/serial.h new file mode 100644 index 000000000..2718276cb --- /dev/null +++ b/include/asm-arm/arch-rpc/serial.h @@ -0,0 +1,40 @@ +/* + * linux/include/asm-arm/arch-rpc/serial.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 15-10-1996 RMK Created + */ +#ifndef __ASM_ARCH_SERIAL_H +#define __ASM_ARCH_SERIAL_H + +/* + * This assumes you have a 1.8432 MHz clock for your UART. + * + * It'd be nice if someone built a serial card with a 24.576 MHz + * clock, since the 16550A is capable of handling a top speed of 1.5 + * megabits/second; but this requires the faster clock. + */ +#define BASE_BAUD (1843200 / 16) + +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) + + /* UART CLK PORT IRQ FLAGS */ +#define RS_UARTS \ + { 0, BASE_BAUD, 0x3F8, 10, STD_COM_FLAGS }, /* ttyS0 */ \ + { 0, BASE_BAUD, 0x2F8, 10, STD_COM_FLAGS }, /* ttyS1 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS2 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS3 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS4 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS5 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS6 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS7 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS8 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS9 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS10 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS11 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS12 */ \ + { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS13 */ + +#endif diff --git a/include/asm-arm/arch-rpc/shmparam.h b/include/asm-arm/arch-rpc/shmparam.h new file mode 100644 index 000000000..2f7dec9c3 --- /dev/null +++ b/include/asm-arm/arch-rpc/shmparam.h @@ -0,0 +1,5 @@ +/* + * linux/include/asm-arm/arch-rpc/shmparam.h + * + * Copyright (c) 1996 Russell King. + */ diff --git a/include/asm-arm/arch-rpc/system.h b/include/asm-arm/arch-rpc/system.h new file mode 100644 index 000000000..aa6e645c6 --- /dev/null +++ b/include/asm-arm/arch-rpc/system.h @@ -0,0 +1,23 @@ +/* + * linux/include/asm-arm/arch-rpc/system.h + * + * Copyright (c) 1996 Russell King + */ +#ifndef __ASM_ARCH_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H + +#include <asm/proc-fns.h> + +#define arch_hard_reset() { \ + extern void ecard_reset (int card); \ + outb (0, IOMD_ROMCR0); \ + ecard_reset (-1); \ + cli(); \ + __asm__ __volatile__("msr spsr, r1;" \ + "mcr p15, 0, %0, c1, c0, 0;" \ + "movs pc, #0" \ + : \ + : "r" (processor.u.armv3v4.reset())); \ + } + +#endif diff --git a/include/asm-arm/arch-rpc/time.h b/include/asm-arm/arch-rpc/time.h new file mode 100644 index 000000000..3d0f742da --- /dev/null +++ b/include/asm-arm/arch-rpc/time.h @@ -0,0 +1,96 @@ +/* + * linux/include/asm-arm/arch-rpc/time.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 24-Sep-1996 RMK Created + * 10-Oct-1996 RMK Brought up to date with arch-sa110eval + * 04-Dec-1997 RMK Updated for new arch/arm/time.c + */ + +extern __inline__ unsigned long gettimeoffset (void) +{ + unsigned long offset = 0; + unsigned int count1, count2, status1, status2; + + status1 = IOMD_IRQREQA; + barrier (); + outb(0, IOMD_T0LATCH); + barrier (); + count1 = inb(IOMD_T0CNTL) | (inb(IOMD_T0CNTH) << 8); + barrier (); + status2 = inb(IOMD_IRQREQA); + barrier (); + outb(0, IOMD_T0LATCH); + barrier (); + count2 = inb(IOMD_T0CNTL) | (inb(IOMD_T0CNTH) << 8); + + if (count2 < count1) { + /* + * This means that we haven't just had an interrupt + * while reading into status2. + */ + if (status2 & (1 << 5)) + offset = tick; + count1 = count2; + } else if (count2 > count1) { + /* + * We have just had another interrupt while reading + * status2. + */ + offset += tick; + count1 = count2; + } + + count1 = LATCH - count1; + /* + * count1 = number of clock ticks since last interrupt + */ + offset += count1 * tick / LATCH; + return offset; +} + +/* + * No need to reset the timer at every irq + */ +#define reset_timer() 1 + +/* + * Updating of the RTC. We don't currently write the time to the + * CMOS clock. + */ +#define update_rtc() + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +extern __inline__ unsigned long setup_timer (void) +{ + extern int iic_control (unsigned char, int, char *, int); + unsigned int year, mon, day, hour, min, sec; + char buf[8]; + + outb(LATCH & 255, IOMD_T0LTCHL); + outb(LATCH >> 8, IOMD_T0LTCHH); + outb(0, IOMD_T0GO); + + iic_control (0xa0, 0xc0, buf, 1); + year = buf[0]; + if ((year += 1900) < 1970) + year += 100; + + iic_control (0xa0, 2, buf, 5); + mon = buf[4] & 0x1f; + day = buf[3] & 0x3f; + hour = buf[2]; + min = buf[1]; + sec = buf[0]; + BCD_TO_BIN(mon); + BCD_TO_BIN(day); + BCD_TO_BIN(hour); + BCD_TO_BIN(min); + BCD_TO_BIN(sec); + + return mktime(year, mon, day, hour, min, sec); +} diff --git a/include/asm-arm/arch-rpc/timex.h b/include/asm-arm/arch-rpc/timex.h new file mode 100644 index 000000000..cb3c72abe --- /dev/null +++ b/include/asm-arm/arch-rpc/timex.h @@ -0,0 +1,13 @@ +/* + * linux/include/asm-arm/arch-rpc/timex.h + * + * RiscPC architecture timex specifications + * + * Copyright (C) 1997, 1998 Russell King + */ + +/* + * On the RiscPC, the clock ticks at 2MHz. + */ +#define CLOCK_TICK_RATE 2000000 + diff --git a/include/asm-arm/arch-rpc/uncompress.h b/include/asm-arm/arch-rpc/uncompress.h new file mode 100644 index 000000000..de645f76d --- /dev/null +++ b/include/asm-arm/arch-rpc/uncompress.h @@ -0,0 +1,143 @@ +/* + * linux/include/asm-arm/arch-a5k/uncompress.h + * + * Copyright (C) 1996 Russell King + */ +#define VIDMEM ((char *)SCREEN_START) + +#include "../arch/arm/drivers/char/font.h" +#include <asm/hardware.h> +#include <asm/io.h> + +int video_num_columns, video_num_lines, video_size_row; +int white, bytes_per_char_h; +extern unsigned long con_charconvtable[256]; + +struct param_struct { + unsigned long page_size; + unsigned long nr_pages; + unsigned long ramdisk_size; + unsigned long mountrootrdonly; + unsigned long rootdev; + unsigned long video_num_cols; + unsigned long video_num_rows; + unsigned long video_x; + unsigned long video_y; + unsigned long memc_control_reg; + unsigned char sounddefault; + unsigned char adfsdrives; + unsigned char bytes_per_char_h; + unsigned char bytes_per_char_v; + unsigned long unused[256/4-11]; +}; + +static const unsigned long palette_4[16] = { + 0x00000000, + 0x000000cc, + 0x0000cc00, /* Green */ + 0x0000cccc, /* Yellow */ + 0x00cc0000, /* Blue */ + 0x00cc00cc, /* Magenta */ + 0x00cccc00, /* Cyan */ + 0x00cccccc, /* White */ + 0x00000000, + 0x000000ff, + 0x0000ff00, + 0x0000ffff, + 0x00ff0000, + 0x00ff00ff, + 0x00ffff00, + 0x00ffffff +}; + +#define palette_setpixel(p) *(unsigned long *)(IO_START+0x00400000) = 0x10000000|((p) & 255) +#define palette_write(v) *(unsigned long *)(IO_START+0x00400000) = 0x00000000|((v) & 0x00ffffff) + +static struct param_struct * const params = (struct param_struct *)Z_PARAMS_BASE; + +#ifndef STANDALONE_DEBUG +/* + * This does not append a newline + */ +static void puts(const char *s) +{ + extern void ll_write_char(char *, unsigned long); + int x,y; + unsigned char c; + char *ptr; + + x = params->video_x; + y = params->video_y; + + while ( ( c = *(unsigned char *)s++ ) != '\0' ) { + if ( c == '\n' ) { + x = 0; + if ( ++y >= video_num_lines ) { + y--; + } + } else { + ptr = VIDMEM + ((y*video_num_columns*params->bytes_per_char_v+x)*bytes_per_char_h); + ll_write_char(ptr, c|(white<<8)); + if ( ++x >= video_num_columns ) { + x = 0; + if ( ++y >= video_num_lines ) { + y--; + } + } + } + } + + params->video_x = x; + params->video_y = y; +} + +static void error(char *x); + +/* + * Setup for decompression + */ +static void arch_decomp_setup(void) +{ + int i; + + video_num_lines = params->video_num_rows; + video_num_columns = params->video_num_cols; + bytes_per_char_h = params->bytes_per_char_h; + video_size_row = video_num_columns * bytes_per_char_h; + if (bytes_per_char_h == 4) + for (i = 0; i < 256; i++) + con_charconvtable[i] = + (i & 128 ? 1 << 0 : 0) | + (i & 64 ? 1 << 4 : 0) | + (i & 32 ? 1 << 8 : 0) | + (i & 16 ? 1 << 12 : 0) | + (i & 8 ? 1 << 16 : 0) | + (i & 4 ? 1 << 20 : 0) | + (i & 2 ? 1 << 24 : 0) | + (i & 1 ? 1 << 28 : 0); + else + for (i = 0; i < 16; i++) + con_charconvtable[i] = + (i & 8 ? 1 << 0 : 0) | + (i & 4 ? 1 << 8 : 0) | + (i & 2 ? 1 << 16 : 0) | + (i & 1 ? 1 << 24 : 0); + + + palette_setpixel(0); + if (bytes_per_char_h == 1) { + palette_write (0); + palette_write (0x00ffffff); + for (i = 2; i < 256; i++) + palette_write (0); + white = 1; + } else { + for (i = 0; i < 256; i++) + palette_write (i < 16 ? palette_4[i] : 0); + white = 7; + } + + if (params->nr_pages * params->page_size < 4096*1024) error("<4M of mem\n"); +} +#endif + diff --git a/include/asm-arm/assembler.h b/include/asm-arm/assembler.h new file mode 100644 index 000000000..e2dae1533 --- /dev/null +++ b/include/asm-arm/assembler.h @@ -0,0 +1,34 @@ +/* + * linux/asm/assembler.h + * + * This file contains arm architecture specific defines + * for the different processors. + * + * Do not include any C declarations in this file - it is included by + * assembler source. + */ + +/* + * LOADREGS: multiple register load (ldm) with pc in register list + * (takes account of ARM6 not using ^) + * + * RETINSTR: return instruction: adds the 's' in at the end of the + * instruction if this is not an ARM6 + * + * SAVEIRQS: save IRQ state (not required on ARM2/ARM3 - done + * implicitly + * + * RESTOREIRQS: restore IRQ state (not required on ARM2/ARM3 - done + * implicitly with ldm ... ^ or movs. + * + * These next two need thinking about - can't easily use stack... (see system.S) + * DISABLEIRQS: disable IRQS in SVC mode + * + * ENABLEIRQS: enable IRQS in SVC mode + * + * USERMODE: switch to USER mode + * + * SVCMODE: switch to SVC mode + */ + +#include <asm/proc/assembler.h> diff --git a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h new file mode 100644 index 000000000..df9e941db --- /dev/null +++ b/include/asm-arm/atomic.h @@ -0,0 +1,85 @@ +/* + * linux/include/asm-arm/atomic.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 27-06-1996 RMK Created + * 13-04-1997 RMK Made functions atomic! + * 07-12-1997 RMK Upgraded for v2.1. + */ +#ifndef __ASM_ARM_ATOMIC_H +#define __ASM_ARM_ATOMIC_H + +#include <asm/system.h> + +#ifdef __SMP__ +#error SMP not supported +#endif + +typedef struct { int counter; } atomic_t; + +#define ATOMIC_INIT(i) { (i) } + +#define atomic_read(v) ((v)->counter) +#define atomic_set(v,i) (((v)->counter) = (i)) + +static __inline__ void atomic_add(int i, volatile atomic_t *v) +{ + unsigned long flags; + + save_flags_cli (flags); + v->counter += i; + restore_flags (flags); +} + +static __inline__ void atomic_sub(int i, volatile atomic_t *v) +{ + unsigned long flags; + + save_flags_cli (flags); + v->counter -= i; + restore_flags (flags); +} + +static __inline__ void atomic_inc(volatile atomic_t *v) +{ + unsigned long flags; + + save_flags_cli (flags); + v->counter += 1; + restore_flags (flags); +} + +static __inline__ void atomic_dec(volatile atomic_t *v) +{ + unsigned long flags; + + save_flags_cli (flags); + v->counter -= 1; + restore_flags (flags); +} + +static __inline__ int atomic_dec_and_test(volatile atomic_t *v) +{ + unsigned long flags; + int result; + + save_flags_cli (flags); + v->counter -= 1; + result = (v->counter == 0); + restore_flags (flags); + + return result; +} + +static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *addr) +{ + unsigned long flags; + + save_flags_cli (flags); + *addr &= ~mask; + restore_flags (flags); +} + +#endif diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h new file mode 100644 index 000000000..e6d942f71 --- /dev/null +++ b/include/asm-arm/bitops.h @@ -0,0 +1,72 @@ +#ifndef __ASM_ARM_BITOPS_H +#define __ASM_ARM_BITOPS_H + +/* + * Copyright 1995, Russell King. + * Various bits and pieces copyrights include: + * Linus Torvalds (test_bit). + */ + +/* + * These should be done with inline assembly. + * All bit operations return 0 if the bit + * was cleared before the operation and != 0 if it was not. + * + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + */ + +/* + * Function prototypes to keep gcc -Wall happy + */ +extern void set_bit(int nr, volatile void * addr); +extern void clear_bit(int nr, volatile void * addr); +extern void change_bit(int nr, volatile void * addr); +extern int test_and_set_bit(int nr, volatile void * addr); +extern int test_and_clear_bit(int nr, volatile void * addr); +extern int test_and_change_bit(int nr, volatile void * addr); +extern int find_first_zero_bit(void * addr, unsigned size); +extern int find_next_zero_bit(void * addr, int size, int offset); + +/* + * This routine doesn't need to be atomic. + */ +extern __inline__ int test_bit(int nr, const void * addr) +{ + return ((unsigned char *) addr)[nr >> 3] & (1U << (nr & 7)); +} + +/* + * ffz = Find First Zero in word. Undefined if no zero exists, + * so code should check against ~0UL first.. + */ +extern __inline__ unsigned long ffz(unsigned long word) +{ + int k; + + word = ~word; + k = 31; + if (word & 0x0000ffff) { k -= 16; word <<= 16; } + if (word & 0x00ff0000) { k -= 8; word <<= 8; } + if (word & 0x0f000000) { k -= 4; word <<= 4; } + if (word & 0x30000000) { k -= 2; word <<= 2; } + if (word & 0x40000000) { k -= 1; } + return k; +} + +#ifdef __KERNEL__ + +#define ext2_set_bit test_and_set_bit +#define ext2_clear_bit test_and_clear_bit +#define ext2_test_bit test_bit +#define ext2_find_first_zero_bit find_first_zero_bit +#define ext2_find_next_zero_bit find_next_zero_bit + +/* Bitmap functions for the minix filesystem. */ +#define minix_set_bit(nr,addr) test_and_set_bit(nr,addr) +#define minix_clear_bit(nr,addr) test_and_clear_bit(nr,addr) +#define minix_test_bit(nr,addr) test_bit(nr,addr) +#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) + +#endif /* __KERNEL__ */ + +#endif /* _ARM_BITOPS_H */ diff --git a/include/asm-arm/bugs.h b/include/asm-arm/bugs.h new file mode 100644 index 000000000..b9fc82775 --- /dev/null +++ b/include/asm-arm/bugs.h @@ -0,0 +1,13 @@ +/* + * include/asm-arm/bugs.h + * + * Copyright (C) 1995 Russell King + */ +#ifndef __ASM_BUGS_H +#define __ASM_BUGS_H + +#include <asm/proc-fns.h> + +#define check_bugs() processor._check_bugs() + +#endif diff --git a/include/asm-arm/byteorder.h b/include/asm-arm/byteorder.h new file mode 100644 index 000000000..7b232d906 --- /dev/null +++ b/include/asm-arm/byteorder.h @@ -0,0 +1,39 @@ +#ifndef __ASM_ARM_BYTEORDER_H +#define __ASM_ARM_BYTEORDER_H + +#include <asm/types.h> + +#ifdef __GNUC__ + +static __inline__ __const__ __u32 ___arch__swab32(__u32 x) +{ + unsigned long xx; + __asm__("eor\t%1, %0, %0, ror #16\n\t" + "bic\t%1, %1, #0xff0000\n\t" + "mov\t%0, %0, ror #8\n\t" + "eor\t%0, %0, %1, lsr #8\n\t" + : "=r" (x), "=&r" (xx) + : "0" (x)); + return x; +} + +static __inline__ __const__ __u16 ___arch__swab16(__u16 x) +{ + __asm__("eor\t%0, %0, %0, lsr #8\n\t" + "eor\t%0, %0, %0, lsl #8\n\t" + "bic\t%0, %0, #0xff0000\n\t" + "eor\t%0, %0, %0, lsr #8\n\t" + : "=r" (x) + : "0" (x)); + return x; +} + +#define __arch__swab32(x) ___arch__swab32(x) +#define __arch__swab16(x) ___arch__swab16(x) + +#endif /* __GNUC__ */ + +#include <linux/byteorder/little_endian.h> + +#endif + diff --git a/include/asm-arm/cache.h b/include/asm-arm/cache.h new file mode 100644 index 000000000..c5b3c6659 --- /dev/null +++ b/include/asm-arm/cache.h @@ -0,0 +1,10 @@ +/* + * include/asm-i386/cache.h + */ +#ifndef __ASMARM_CACHE_H +#define __ASMARM_CACHE_H + +#define L1_CACHE_BYTES 32 +#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)) + +#endif diff --git a/include/asm-arm/checksum.h b/include/asm-arm/checksum.h new file mode 100644 index 000000000..ccfadd761 --- /dev/null +++ b/include/asm-arm/checksum.h @@ -0,0 +1,154 @@ +/* + * linux/include/asm-arm/checksum.h + * + * IP checksum routines + * + * Copyright (C) Original authors of ../asm-i386/checksum.h + * Copyright (C) 1996,1997,1998 Russell King + */ +#ifndef __ASM_ARM_CHECKSUM_H +#define __ASM_ARM_CHECKSUM_H + +#ifndef __ASM_ARM_SEGMENT_H +#include <asm/segment.h> +#endif + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums, and handles user-space pointer exceptions correctly, when needed. + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +extern +unsigned int csum_partial_copy_from_user (const char *src, char *dst, int len, int sum, int *err_ptr); + +/* + * This combination is currently not used, but possible: + */ +extern +unsigned int csum_partial_copy_to_user (const char *src, char *dst, int len, int sum, int *err_ptr); + +/* + * These are the old (and unsafe) way of doing checksums, a warning message will be + * printed if they are used and an exception occurs. + * + * these functions should go away after some time. + */ +#define csum_partial_copy_fromuser csum_partial_copy +unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum); + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + * + * Converted and optimised for ARM by R. M. King. + * + * Note: the order that the LDM registers are loaded with respect to + * the adc's doesn't matter. + */ +static inline unsigned short ip_fast_csum(unsigned char * iph, + unsigned int ihl) { + unsigned int sum, tmp1; + + __asm__ __volatile__(" + sub %2, %2, #5 + ldr %0, [%1], #4 + ldr %3, [%1], #4 + adds %0, %0, %3 + ldr %3, [%1], #4 + adcs %0, %0, %3 + ldr %3, [%1], #4 + adcs %0, %0, %3 +1: ldr %3, [%1], #4 + adcs %0, %0, %3 + tst %2, #15 + subne %2, %2, #1 + bne 1b + adc %0, %0, #0 + adds %0, %0, %0, lsl #16 + addcs %0, %0, #0x10000 + mvn %0, %0 + mov %0, %0, lsr #16 + " + : "=&r" (sum), "=&r" (iph), "=&r" (ihl), "=&r" (tmp1) + : "1" (iph), "2" (ihl)); + return(sum); +} + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, + unsigned int sum) { + __asm__ __volatile__(" + adds %0, %0, %1 + adcs %0, %0, %4 + adcs %0, %0, %5 + adc %0, %0, #0 + adds %0, %0, %0, lsl #16 + addcs %0, %0, #0x10000 + mvn %0, %0 + mov %0, %0, lsr #16 + " + : "=&r" (sum), "=&r" (saddr) + : "0" (daddr), "1"(saddr), "r"((ntohs(len)<<16)+proto*256), "r"(sum)); + return((unsigned short)sum); +} + +/* + * Fold a partial checksum without adding pseudo headers + */ +static inline unsigned int csum_fold(unsigned int sum) +{ + __asm__ __volatile__(" + adds %0, %0, %0, lsl #16 + addcs %0, %0, #0x10000 + mvn %0, %0 + mov %0, %0, lsr #16 + " + : "=r" (sum) + : "0" (sum)); + return sum; +} + + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ + +static inline unsigned short ip_compute_csum(unsigned char * buff, int len) { + unsigned int sum; + + __asm__ __volatile__(" + adds %0, %0, %0, lsl #16 + addcs %0, %0, #0x10000 + mvn %0, %0 + mov %0, %0, lsr #16 + " + : "=r"(sum) + : "0" (csum_partial(buff, len, 0))); + return(sum); +} + +#endif diff --git a/include/asm-arm/current.h b/include/asm-arm/current.h new file mode 100644 index 000000000..9f08dae30 --- /dev/null +++ b/include/asm-arm/current.h @@ -0,0 +1,23 @@ +#ifndef _ASMARM_CURRENT_H +#define _ASMARM_CURRENT_H + +static inline unsigned long get_sp(void) +{ + unsigned long sp; + __asm__ ("mov %0,sp" : "=r" (sp)); + return sp; +} + +static inline struct task_struct *get_current(void) +{ + struct task_struct *ts; + __asm__ __volatile__(" + bic %0, sp, #0x1f00 + bic %0, %0, #0x00ff + " : "=r" (ts)); + return ts; +} + +#define current (get_current()) + +#endif /* _ASMARM_CURRENT_H */ diff --git a/include/asm-arm/delay.h b/include/asm-arm/delay.h new file mode 100644 index 000000000..3f56cbd70 --- /dev/null +++ b/include/asm-arm/delay.h @@ -0,0 +1,32 @@ +#ifndef __ASM_ARM_DELAY_H +#define __ASM_ARM_DELAY_H + +/* + * Copyright (C) 1995 Russell King + * + * Delay routines, using a pre-computed "loops_per_second" value. + */ + +extern void __delay(int loops); + +/* + * division by multiplication: you don't have to worry about + * loss of precision. + * + * Use only for very small delays ( < 1 msec). Should probably use a + * lookup table, really, as the multiplications take much too long with + * short delays. This is a "reasonable" implementation, though (and the + * first constant multiplications gets optimized away if the delay is + * a constant) + */ +extern void udelay(unsigned long usecs); + +extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c) +{ + return a * b / c; +} + + + +#endif /* defined(_ARM_DELAY_H) */ + diff --git a/include/asm-arm/dma.h b/include/asm-arm/dma.h new file mode 100644 index 000000000..718fbb2b8 --- /dev/null +++ b/include/asm-arm/dma.h @@ -0,0 +1,28 @@ +#ifndef __ASM_ARM_DMA_H +#define __ASM_ARM_DMA_H + +#include <asm/irq.h> + +#define MAX_DMA_CHANNELS 14 +#define DMA_0 8 +#define DMA_1 9 +#define DMA_2 10 +#define DMA_3 11 +#define DMA_S0 12 +#define DMA_S1 13 + +#define DMA_MODE_READ 0x44 +#define DMA_MODE_WRITE 0x48 + +extern const char dma_str[]; + +#include <asm/arch/dma.h> + +/* These are in kernel/dma.c: */ +/* reserve a DMA channel */ +extern int request_dma(unsigned int dmanr, const char * device_id); +/* release it again */ +extern void free_dma(unsigned int dmanr); + +#endif /* _ARM_DMA_H */ + diff --git a/include/asm-arm/ecard.h b/include/asm-arm/ecard.h new file mode 100644 index 000000000..3ca8cf1fb --- /dev/null +++ b/include/asm-arm/ecard.h @@ -0,0 +1,227 @@ +/* + * linux/include/asm-arm/ecard.h + * + * definitions for expansion cards + * + * This is a new system as from Linux 1.2.3 + * + * Changelog: + * 11-12-1996 RMK Further minor improvements + * 12-09-1997 RMK Added interrupt enable/disable for card level + * + * Reference: Acorns Risc OS 3 Programmers Reference Manuals. + */ + +#ifndef __ASM_ECARD_H +#define __ASM_ECARD_H + +/* + * Currently understood cards + * Manufacturer Product ID + */ +#define MANU_ACORN 0x0000 +#define PROD_ACORN_SCSI 0x0002 +#define PROD_ACORN_ETHER1 0x0003 +#define PROD_ACORN_MFM 0x000b + +#define MANU_ANT2 0x0011 +#define PROD_ANT_ETHER3 0x00a4 + +#define MANU_ATOMWIDE 0x0017 +#define PROD_ATOMWIDE_3PSERIAL 0x0090 + +#define MANU_OAK 0x0021 +#define PROD_OAK_SCSI 0x0058 + +#define MANU_MORLEY 0x002b +#define PROD_MORLEY_SCSI_UNCACHED 0x0067 + +#define MANU_CUMANA 0x003a +#define PROD_CUMANA_SCSI_1 0x00a0 +#define PROD_CUMANA_SCSI_2 0x003a + +#define MANU_ICS 0x003c +#define PROD_ICS_IDE 0x00ae + +#define MANU_SERPORT 0x003f +#define PROD_SERPORT_DSPORT 0x00b9 + +#define MANU_I3 0x0046 +#define PROD_I3_ETHERLAN500 0x00d4 +#define PROD_I3_ETHERLAN600 0x00ec +#define PROD_I3_ETHERLAN600A 0x011e + +#define MANU_ANT 0x0053 +#define PROD_ANT_ETHERB 0x00e4 + +#define MANU_ALSYSTEMS 0x005b +#define PROD_ALSYS_SCSIATAPI 0x0107 + +#define MANU_MCS 0x0063 +#define PROD_MCS_CONNECT32 0x0125 + + + +#ifdef ECARD_C +#define CONST +#else +#define CONST const +#endif + +#define MAX_ECARDS 8 + +/* Type of card's address space */ +typedef enum { + ECARD_IOC = 0, + ECARD_MEMC = 1 +} card_type_t; + +/* Speed of card for ECARD_IOC address space */ +typedef enum { + ECARD_SLOW = 0, + ECARD_MEDIUM = 1, + ECARD_FAST = 2, + ECARD_SYNC = 3 +} card_speed_t; + +/* Card ID structure */ +typedef struct { + unsigned short manufacturer; + unsigned short product; +} card_ids; + +/* External view of card ID information */ +struct in_ecld { + unsigned short product; + unsigned short manufacturer; + unsigned char ecld; + unsigned char country; + unsigned char fiqmask; + unsigned char irqmask; + unsigned long fiqaddr; + unsigned long irqaddr; +}; + +typedef struct expansion_card ecard_t; + +/* Card handler routines */ +typedef struct { + void (*irqenable)(ecard_t *ec, int irqnr); + void (*irqdisable)(ecard_t *ec, int irqnr); + void (*fiqenable)(ecard_t *ec, int fiqnr); + void (*fiqdisable)(ecard_t *ec, int fiqnr); +} expansioncard_ops_t; + +typedef unsigned long *loader_t; + +/* + * This contains all the info needed on an expansion card + */ +struct expansion_card { + /* Public data */ + volatile unsigned char *irqaddr; /* address of IRQ register */ + volatile unsigned char *fiqaddr; /* address of FIQ register */ + unsigned char irqmask; /* IRQ mask */ + unsigned char fiqmask; /* FIQ mask */ + unsigned char claimed; /* Card claimed? */ + CONST unsigned char slot_no; /* Slot number */ + CONST unsigned char irq; /* IRQ number (for request_irq) */ + CONST unsigned char fiq; /* FIQ number (for request_irq) */ + CONST unsigned short unused; + CONST struct in_ecld cld; /* Card Identification */ + void *irq_data; /* Data for use for IRQ by card */ + void *fiq_data; /* Data for use for FIQ by card */ + expansioncard_ops_t *ops; /* Enable/Disable Ops for card */ + + /* Private internal data */ + CONST unsigned int podaddr; /* Base Linux address for card */ + CONST loader_t loader; /* loader program */ +}; + +struct in_chunk_dir { + unsigned int start_offset; + union { + unsigned char string[256]; + unsigned char data[1]; + } d; +}; + +/* + * ecard_claim: claim an expansion card entry + */ +#define ecard_claim(ec) ((ec)->claimed = 1) + +/* + * ecard_release: release an expansion card entry + */ +#define ecard_release(ec) ((ec)->claimed = 0) + +/* + * Start finding cards from the top of the list + */ +extern void ecard_startfind (void); + +/* + * Find an expansion card with the correct cld, product and manufacturer code + */ +extern struct expansion_card *ecard_find (int cld, const card_ids *ids); + +/* + * Read a chunk from an expansion card + * cd : where to put read data + * ec : expansion card info struct + * id : id number to find + * num: (n+1)'th id to find. + */ +extern int ecard_readchunk (struct in_chunk_dir *cd, struct expansion_card *ec, int id, int num); + +/* + * Obtain the address of a card + */ +extern unsigned int ecard_address (struct expansion_card *ec, card_type_t card_type, card_speed_t speed); + +#ifdef ECARD_C +/* Definitions internal to ecard.c - for it's use only!! + * + * External expansion card header as read from the card + */ +struct ex_ecld { + unsigned char r_ecld; + unsigned char r_reserved[2]; + unsigned char r_product[2]; + unsigned char r_manufacturer[2]; + unsigned char r_country; + long r_fiqs; + long r_irqs; +#define e_ecld(x) ((x)->r_ecld) +#define e_cd(x) ((x)->r_reserved[0] & 1) +#define e_is(x) ((x)->r_reserved[0] & 2) +#define e_w(x) (((x)->r_reserved[0] & 12)>>2) +#define e_prod(x) ((x)->r_product[0]|((x)->r_product[1]<<8)) +#define e_manu(x) ((x)->r_manufacturer[0]|((x)->r_manufacturer[1]<<8)) +#define e_country(x) ((x)->r_country) +#define e_fiqmask(x) ((x)->r_fiqs & 0xff) +#define e_fiqaddr(x) ((x)->r_fiqs >> 8) +#define e_irqmask(x) ((x)->r_irqs & 0xff) +#define e_irqaddr(x) ((x)->r_irqs >> 8) +}; + +/* + * Chunk directory entry as read from the card + */ +struct ex_chunk_dir { + unsigned char r_id; + unsigned char r_len[3]; + unsigned long r_start; + union { + char string[256]; + char data[1]; + } d; +#define c_id(x) ((x)->r_id) +#define c_len(x) ((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16)) +#define c_start(x) ((x)->r_start) +}; + +#endif + +#endif diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h new file mode 100644 index 000000000..cf49fbfa1 --- /dev/null +++ b/include/asm-arm/elf.h @@ -0,0 +1,54 @@ +#ifndef __ASMARM_ELF_H +#define __ASMARM_ELF_H + +/* + * ELF register definitions.. + */ + +#include <asm/ptrace.h> + +typedef unsigned long elf_greg_t; + +#define EM_ARM 40 + +#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef struct { void *null; } elf_fpregset_t; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ( ((x) == EM_ARM) ) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2LSB; +#define ELF_ARCH EM_ARM + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 32768 + +/* This is the location that an ET_DYN program is loaded if exec'ed. Typical + use of this is to invoke "./ld.so someprog" to test out a new version of + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) + +#define R_ARM_NONE (0) +#define R_ARM_32 (1) /* => ld 32 */ +#define R_ARM_PC26 (2) /* => ld b/bl branches */ +#define R_ARM_PC32 (3) +#define R_ARM_GOT32 (4) /* -> object relocation into GOT */ +#define R_ARM_PLT32 (5) +#define R_ARM_COPY (6) /* => dlink copy object */ +#define R_ARM_GLOB_DAT (7) /* => dlink 32bit absolute address for .got */ +#define R_ARM_JUMP_SLOT (8) /* => dlink 32bit absolute address for .got.plt */ +#define R_ARM_RELATIVE (9) /* => ld resolved 32bit absolute address requiring load address adjustment */ +#define R_ARM_GOTOFF (10) /* => ld calculates offset of data from base of GOT */ +#define R_ARM_GOTPC (11) /* => ld 32-bit relative offset */ + +#endif diff --git a/include/asm-arm/errno.h b/include/asm-arm/errno.h new file mode 100644 index 000000000..48fcd2bca --- /dev/null +++ b/include/asm-arm/errno.h @@ -0,0 +1,132 @@ +#ifndef _ARM_ERRNO_H +#define _ARM_ERRNO_H + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ + +#endif diff --git a/include/asm-arm/fcntl.h b/include/asm-arm/fcntl.h new file mode 100644 index 000000000..af29f7f46 --- /dev/null +++ b/include/asm-arm/fcntl.h @@ -0,0 +1,59 @@ +#ifndef _ARM_FCNTL_H +#define _ARM_FCNTL_H + +/* open/fcntl - O_SYNC is only implemented on blocks devices and on files + located on an ext2 file system */ +#define O_ACCMODE 0003 +#define O_RDONLY 00 +#define O_WRONLY 01 +#define O_RDWR 02 +#define O_CREAT 0100 /* not fcntl */ +#define O_EXCL 0200 /* not fcntl */ +#define O_NOCTTY 0400 /* not fcntl */ +#define O_TRUNC 01000 /* not fcntl */ +#define O_APPEND 02000 +#define O_NONBLOCK 04000 +#define O_NDELAY O_NONBLOCK +#define O_SYNC 010000 +#define FASYNC 020000 /* fcntl, for BSD compatibility */ + +#define F_DUPFD 0 /* dup */ +#define F_GETFD 1 /* get f_flags */ +#define F_SETFD 2 /* set f_flags */ +#define F_GETFL 3 /* more flags (cloexec) */ +#define F_SETFL 4 +#define F_GETLK 5 +#define F_SETLK 6 +#define F_SETLKW 7 + +#define F_SETOWN 8 /* for sockets. */ +#define F_GETOWN 9 /* for sockets. */ + +/* for F_[GET|SET]FL */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* for posix fcntl() and lockf() */ +#define F_RDLCK 0 +#define F_WRLCK 1 +#define F_UNLCK 2 + +/* for old implementation of bsd flock () */ +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ + +/* operations for bsd flock(), also used by the kernel implementation */ +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +#define LOCK_UN 8 /* remove lock */ + +struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; +}; + +#endif diff --git a/include/asm-arm/floppy.h b/include/asm-arm/floppy.h new file mode 100644 index 000000000..0f3857962 --- /dev/null +++ b/include/asm-arm/floppy.h @@ -0,0 +1,113 @@ +/* + * linux/include/asm-arm/floppy.h + * + * (C) 1996 Russell King + */ +#ifndef __ASM_ARM_FLOPPY_H +#define __ASM_ARM_FLOPPY_H +#if 0 +#include <asm/arch/floppy.h> +#endif + +#define fd_outb(val,port) outb((val),(port)) +#define fd_inb(port) inb((port)) +#define fd_request_irq() request_irq(IRQ_FLOPPYDISK,floppy_interrupt,\ + SA_INTERRUPT|SA_SAMPLE_RANDOM,"floppy",NULL) +#define fd_free_irq() free_irq(IRQ_FLOPPYDISK,NULL) +#define fd_disable_irq() disable_irq(IRQ_FLOPPYDISK) +#define fd_enable_irq() enable_irq(IRQ_FLOPPYDISK) + +#define fd_request_dma() request_dma(FLOPPY_DMA,"floppy") +#define fd_free_dma() free_dma(FLOPPY_DMA) +#define fd_disable_dma() disable_dma(FLOPPY_DMA) +#define fd_enable_dma() enable_dma(FLOPPY_DMA) +#define fd_clear_dma_ff() clear_dma_ff(FLOPPY_DMA) +#define fd_set_dma_mode(mode) set_dma_mode(FLOPPY_DMA, (mode)) +#define fd_set_dma_addr(addr) set_dma_addr(FLOPPY_DMA, virt_to_bus((addr))) +#define fd_set_dma_count(len) set_dma_count(FLOPPY_DMA, (len)) +#define fd_cacheflush(addr,sz) + +/* Floppy_selects is the list of DOR's to select drive fd + * + * On initialisation, the floppy list is scanned, and the drives allocated + * in the order that they are found. This is done by seeking the drive + * to a non-zero track, and then restoring it to track 0. If an error occurs, + * then there is no floppy drive present. [to be put back in again] + */ +static unsigned char floppy_selects[2][4] = +{ + { 0x10, 0x21, 0x23, 0x33 }, + { 0x10, 0x21, 0x23, 0x33 } +}; + +#define fd_setdor(dor) \ +do { \ + int new_dor = (dor); \ + if (new_dor & 0xf0) \ + fd_outb((new_dor & 0x0c) | floppy_selects[fdc][new_dor & 3], FD_DOR); \ + else \ + fd_outb((new_dor & 0x0c), FD_DOR); \ +} while (0) + +/* + * Someday, we'll automatically detect which drives are present... + */ +extern __inline__ void fd_scandrives (void) +{ +#if 0 + int floppy, drive_count; + + fd_disable_irq(); + raw_cmd = &default_raw_cmd; + raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_SEEK; + raw_cmd->track = 0; + raw_cmd->rate = ?; + drive_count = 0; + for (floppy = 0; floppy < 4; floppy ++) { + current_drive = drive_count; + /* + * Turn on floppy motor + */ + if (start_motor(redo_fd_request)) + continue; + /* + * Set up FDC + */ + fdc_specify(); + /* + * Tell FDC to recalibrate + */ + output_byte(FD_RECALIBRATE); + LAST_OUT(UNIT(floppy)); + /* wait for command to complete */ + if (!successful) { + int i; + for (i = drive_count; i < 3; i--) + floppy_selects[fdc][i] = floppy_selects[fdc][i + 1]; + floppy_selects[fdc][3] = 0; + floppy -= 1; + } else + drive_count++; + } +#else + floppy_selects[0][0] = 0x10; + floppy_selects[0][1] = 0x21; + floppy_selects[0][2] = 0x23; + floppy_selects[0][3] = 0x33; +#endif +} + +#define FDC1 (0x3f0) +static int FDC2 = -1; + +#define FLOPPY0_TYPE 4 +#define FLOPPY1_TYPE 4 + +#define N_FDC 1 +#define N_DRIVE 8 + +#define FLOPPY_MOTOR_MASK 0xf0 + +#define CROSS_64KB(a,s) (0) + +#endif diff --git a/include/asm-arm/hardirq.h b/include/asm-arm/hardirq.h new file mode 100644 index 000000000..0e38fc890 --- /dev/null +++ b/include/asm-arm/hardirq.h @@ -0,0 +1,23 @@ +#ifndef __ASM_HARDIRQ_H +#define __ASM_HARDIRQ_H + +#include <linux/tasks.h> + +extern unsigned int local_irq_count[NR_CPUS]; +#define in_interrupt() (local_irq_count[smp_processor_id()] != 0) + +#ifndef __SMP__ + +#define hardirq_trylock(cpu) (local_irq_count[cpu] == 0) +#define hardirq_endlock(cpu) do { } while (0) + +#define hardirq_enter(cpu) (local_irq_count[cpu]++) +#define hardirq_exit(cpu) (local_irq_count[cpu]--) + +#define synchronize_irq() do { } while (0) + +#else +#error SMP not supported +#endif /* __SMP__ */ + +#endif /* __ASM_HARDIRQ_H */ diff --git a/include/asm-arm/hardware.h b/include/asm-arm/hardware.h new file mode 100644 index 000000000..6b3cbfaba --- /dev/null +++ b/include/asm-arm/hardware.h @@ -0,0 +1,271 @@ +/* + * linux/include/asm-arm/hardware.h + * + * Copyright (C) 1996 Russell King + * + * Common hardware definitions + */ + +#ifndef __ASM_HARDWARE_H +#define __ASM_HARDWARE_H + +#include <asm/arch/hardware.h> + +/* + * Use these macros to read/write the IOC. All it does is perform the actual + * read/write. + */ +#ifdef HAS_IOC +#ifndef __ASSEMBLER__ +#define __IOC(offset) (IOC_BASE + (offset >> 2)) +#else +#define __IOC(offset) offset +#endif + +#define IOC_CONTROL __IOC(0x00) +#define IOC_KARTTX __IOC(0x04) +#define IOC_KARTRX __IOC(0x04) + +#define IOC_IRQSTATA __IOC(0x10) +#define IOC_IRQREQA __IOC(0x14) +#define IOC_IRQCLRA __IOC(0x14) +#define IOC_IRQMASKA __IOC(0x18) + +#define IOC_IRQSTATB __IOC(0x20) +#define IOC_IRQREQB __IOC(0x24) +#define IOC_IRQMASKB __IOC(0x28) + +#define IOC_FIQSTAT __IOC(0x30) +#define IOC_FIQREQ __IOC(0x34) +#define IOC_FIQMASK __IOC(0x38) + +#define IOC_T0CNTL __IOC(0x40) +#define IOC_T0LTCHL __IOC(0x40) +#define IOC_T0CNTH __IOC(0x44) +#define IOC_T0LTCHH __IOC(0x44) +#define IOC_T0GO __IOC(0x48) +#define IOC_T0LATCH __IOC(0x4c) + +#define IOC_T1CNTL __IOC(0x50) +#define IOC_T1LTCHL __IOC(0x50) +#define IOC_T1CNTH __IOC(0x54) +#define IOC_T1LTCHH __IOC(0x54) +#define IOC_T1GO __IOC(0x58) +#define IOC_T1LATCH __IOC(0x5c) + +#define IOC_T2CNTL __IOC(0x60) +#define IOC_T2LTCHL __IOC(0x60) +#define IOC_T2CNTH __IOC(0x64) +#define IOC_T2LTCHH __IOC(0x64) +#define IOC_T2GO __IOC(0x68) +#define IOC_T2LATCH __IOC(0x6c) + +#define IOC_T3CNTL __IOC(0x70) +#define IOC_T3LTCHL __IOC(0x70) +#define IOC_T3CNTH __IOC(0x74) +#define IOC_T3LTCHH __IOC(0x74) +#define IOC_T3GO __IOC(0x78) +#define IOC_T3LATCH __IOC(0x7c) +#endif + +#ifdef HAS_MEMC +#define VDMA_ALIGNMENT PAGE_SIZE +#define VDMA_XFERSIZE 16 +#define VDMA_INIT 0 +#define VDMA_START 1 +#define VDMA_END 2 + +#define video_set_dma(start,end,offset) \ +do { \ + memc_write (VDMA_START, (start >> 2)); \ + memc_write (VDMA_END, (end - VDMA_XFERSIZE) >> 2); \ + memc_write (VDMA_INIT, (offset >> 2)); \ +} while (0) +#endif + +#ifdef HAS_IOMD +#ifndef __ASSEMBLER__ +#define __IOMD(offset) (IOMD_BASE + (offset >> 2)) +#else +#define __IOMD(offset) offset +#endif + +#define IOMD_CONTROL __IOMD(0x000) +#define IOMD_KARTTX __IOMD(0x004) +#define IOMD_KARTRX __IOMD(0x004) +#define IOMD_KCTRL __IOMD(0x008) + +#define IOMD_IRQSTATA __IOMD(0x010) +#define IOMD_IRQREQA __IOMD(0x014) +#define IOMD_IRQCLRA __IOMD(0x014) +#define IOMD_IRQMASKA __IOMD(0x018) + +#define IOMD_IRQSTATB __IOMD(0x020) +#define IOMD_IRQREQB __IOMD(0x024) +#define IOMD_IRQMASKB __IOMD(0x028) + +#define IOMD_FIQSTAT __IOMD(0x030) +#define IOMD_FIQREQ __IOMD(0x034) +#define IOMD_FIQMASK __IOMD(0x038) + +#define IOMD_T0CNTL __IOMD(0x040) +#define IOMD_T0LTCHL __IOMD(0x040) +#define IOMD_T0CNTH __IOMD(0x044) +#define IOMD_T0LTCHH __IOMD(0x044) +#define IOMD_T0GO __IOMD(0x048) +#define IOMD_T0LATCH __IOMD(0x04c) + +#define IOMD_T1CNTL __IOMD(0x050) +#define IOMD_T1LTCHL __IOMD(0x050) +#define IOMD_T1CNTH __IOMD(0x054) +#define IOMD_T1LTCHH __IOMD(0x054) +#define IOMD_T1GO __IOMD(0x058) +#define IOMD_T1LATCH __IOMD(0x05c) + +#define IOMD_ROMCR0 __IOMD(0x080) +#define IOMD_ROMCR1 __IOMD(0x084) +#define IOMD_DRAMCR __IOMD(0x088) +#define IOMD_VREFCR __IOMD(0x08C) + +#define IOMD_FSIZE __IOMD(0x090) +#define IOMD_ID0 __IOMD(0x094) +#define IOMD_ID1 __IOMD(0x098) +#define IOMD_VERSION __IOMD(0x09C) + +#define IOMD_MOUSEX __IOMD(0x0A0) +#define IOMD_MOUSEY __IOMD(0x0A4) + +#define IOMD_DMATCR __IOMD(0x0C0) +#define IOMD_IOTCR __IOMD(0x0C4) +#define IOMD_ECTCR __IOMD(0x0C8) +#define IOMD_DMAEXT __IOMD(0x0CC) + +#define IOMD_IO0CURA __IOMD(0x100) +#define IOMD_IO0ENDA __IOMD(0x104) +#define IOMD_IO0CURB __IOMD(0x108) +#define IOMD_IO0ENDB __IOMD(0x10C) +#define IOMD_IO0CR __IOMD(0x110) +#define IOMD_IO0ST __IOMD(0x114) + +#define IOMD_IO1CURA __IOMD(0x120) +#define IOMD_IO1ENDA __IOMD(0x124) +#define IOMD_IO1CURB __IOMD(0x128) +#define IOMD_IO1ENDB __IOMD(0x12C) +#define IOMD_IO1CR __IOMD(0x130) +#define IOMD_IO1ST __IOMD(0x134) + +#define IOMD_IO2CURA __IOMD(0x140) +#define IOMD_IO2ENDA __IOMD(0x144) +#define IOMD_IO2CURB __IOMD(0x148) +#define IOMD_IO2ENDB __IOMD(0x14C) +#define IOMD_IO2CR __IOMD(0x150) +#define IOMD_IO2ST __IOMD(0x154) + +#define IOMD_IO3CURA __IOMD(0x160) +#define IOMD_IO3ENDA __IOMD(0x164) +#define IOMD_IO3CURB __IOMD(0x168) +#define IOMD_IO3ENDB __IOMD(0x16C) +#define IOMD_IO3CR __IOMD(0x170) +#define IOMD_IO3ST __IOMD(0x174) + +#define IOMD_SD0CURA __IOMD(0x180) +#define IOMD_SD0ENDA __IOMD(0x184) +#define IOMD_SD0CURB __IOMD(0x188) +#define IOMD_SD0ENDB __IOMD(0x18C) +#define IOMD_SD0CR __IOMD(0x190) +#define IOMD_SD0ST __IOMD(0x194) + +#define IOMD_SD1CURA __IOMD(0x1A0) +#define IOMD_SD1ENDA __IOMD(0x1A4) +#define IOMD_SD1CURB __IOMD(0x1A8) +#define IOMD_SD1ENDB __IOMD(0x1AC) +#define IOMD_SD1CR __IOMD(0x1B0) +#define IOMD_SD1ST __IOMD(0x1B4) + +#define IOMD_CURSCUR __IOMD(0x1C0) +#define IOMD_CURSINIT __IOMD(0x1C4) + +#define IOMD_VIDCUR __IOMD(0x1D0) +#define IOMD_VIDEND __IOMD(0x1D4) +#define IOMD_VIDSTART __IOMD(0x1D8) +#define IOMD_VIDINIT __IOMD(0x1DC) +#define IOMD_VIDCR __IOMD(0x1E0) + +#define IOMD_DMASTAT __IOMD(0x1F0) +#define IOMD_DMAREQ __IOMD(0x1F4) +#define IOMD_DMAMASK __IOMD(0x1F8) + +#define DMA_CR_C 0x80 +#define DMA_CR_D 0x40 +#define DMA_CR_E 0x20 + +#define DMA_ST_OFL 4 +#define DMA_ST_INT 2 +#define DMA_ST_AB 1 +/* + * IOC compatability + */ +#define IOC_CONTROL IOMD_CONTROL +#define IOC_IRQSTATA IOMD_IRQSTATA +#define IOC_IRQREQA IOMD_IRQREQA +#define IOC_IRQCLRA IOMD_IRQCLRA +#define IOC_IRQMASKA IOMD_IRQMASKA + +#define IOC_IRQSTATB IOMD_IRQSTATB +#define IOC_IRQREQB IOMD_IRQREQB +#define IOC_IRQMASKB IOMD_IRQMASKB + +#define IOC_FIQSTAT IOMD_FIQSTAT +#define IOC_FIQREQ IOMD_FIQREQ +#define IOC_FIQMASK IOMD_FIQMASK + +#define IOC_T0CNTL IOMD_T0CNTL +#define IOC_T0LTCHL IOMD_T0LTCHL +#define IOC_T0CNTH IOMD_T0CNTH +#define IOC_T0LTCHH IOMD_T0LTCHH +#define IOC_T0GO IOMD_T0GO +#define IOC_T0LATCH IOMD_T0LATCH + +#define IOC_T1CNTL IOMD_T1CNTL +#define IOC_T1LTCHL IOMD_T1LTCHL +#define IOC_T1CNTH IOMD_T1CNTH +#define IOC_T1LTCHH IOMD_T1LTCHH +#define IOC_T1GO IOMD_T1GO +#define IOC_T1LATCH IOMD_T1LATCH + +/* + * DMA (MEMC) compatability + */ +#define HALF_SAM vram_half_sam +#define VDMA_ALIGNMENT (HALF_SAM * 2) +#define VDMA_XFERSIZE (HALF_SAM) +#define VDMA_INIT IOMD_VIDINIT +#define VDMA_START IOMD_VIDSTART +#define VDMA_END IOMD_VIDEND + +#ifndef __ASSEMBLER__ +extern unsigned int vram_half_sam; +#define video_set_dma(start,end,offset) \ +do { \ + outl (SCREEN_START + start, VDMA_START); \ + outl (SCREEN_START + end - VDMA_XFERSIZE, VDMA_END); \ + if (offset >= end - VDMA_XFERSIZE) \ + offset |= 0x40000000; \ + outl (SCREEN_START + offset, VDMA_INIT); \ +} while (0) +#endif +#endif + +#ifdef HAS_EXPMASK +#ifndef __ASSEMBLER__ +#define __EXPMASK(offset) (((volatile unsigned char *)EXPMASK_BASE)[offset]) +#else +#define __EXPMASK(offset) offset +#endif + +#define EXPMASK_STATUS __EXPMASK(0x00) +#define EXPMASK_ENABLE __EXPMASK(0x04) + +#endif + +#endif diff --git a/include/asm-arm/ide.h b/include/asm-arm/ide.h new file mode 100644 index 000000000..3710c2911 --- /dev/null +++ b/include/asm-arm/ide.h @@ -0,0 +1,85 @@ +/* + * linux/include/asm-arm/ide.h + * + * Copyright (C) 1994-1996 Linus Torvalds & authors + */ + +/* + * This file contains the i386 architecture specific IDE code. + */ + +#ifndef __ASMARM_IDE_H +#define __ASMARM_IDE_H + +#ifdef __KERNEL__ + +typedef unsigned long ide_ioreg_t; + +#ifndef MAX_HWIFS +#define MAX_HWIFS 4 +#endif + +#define ide_sti() sti() + +#include <asm/arch/ide.h> + +typedef union { + unsigned all : 8; /* all of the bits together */ + struct { + unsigned head : 4; /* always zeros here */ + unsigned unit : 1; /* drive select number, 0 or 1 */ + unsigned bit5 : 1; /* always 1 */ + unsigned lba : 1; /* using LBA instead of CHS */ + unsigned bit7 : 1; /* always 1 */ + } b; + } select_t; + +static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *device, void *dev_id) +{ + return request_irq(irq, handler, flags, device, dev_id); +} + +static __inline__ void ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static __inline__ void ide_request_region (ide_ioreg_t from, unsigned int extent, const char *name) +{ + request_region(from, extent, name); +} + +static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + +/* + * The following are not needed for the non-m68k ports + */ +static __inline__ int ide_ack_intr (ide_ioreg_t status_port, ide_ioreg_t irq_port) +{ + return(1); +} + +static __inline__ void ide_fix_driveid(struct hd_driveid *id) +{ +} + +static __inline__ void ide_release_lock (int *ide_lock) +{ +} + +static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data) +{ +} + +#endif /* __KERNEL__ */ + +#endif /* __ASMi386_IDE_H */ diff --git a/include/asm-arm/init.h b/include/asm-arm/init.h new file mode 100644 index 000000000..7c1e47360 --- /dev/null +++ b/include/asm-arm/init.h @@ -0,0 +1,24 @@ +#ifndef _ASMARM_INIT_H +#define _ASMARM_INIT_H + +#if 0 +#define __init __attribute__ ((__section__ (".text.init"))) +#define __initdata __attribute__ ((__section__ (".data.init"))) +#define __initfunc(__arginit) \ + __arginit __init; \ + __arginit +/* For assembly routines */ +#define __INIT .section ".text.init",@alloc,@execinstr +#define __FINIT .previous +#define __INITDATA .section ".data.init",@alloc,@write +#else +#define __init +#define __initdata +#define __initfunc(__arginit) __arginit +/* For assembly routines */ +#define __INIT +#define __FINIT +#define __INITDATA +#endif + +#endif diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h new file mode 100644 index 000000000..8703c920a --- /dev/null +++ b/include/asm-arm/io.h @@ -0,0 +1,203 @@ +/* + * linux/include/asm-arm/io.h + * + * Copyright (C) 1996 Russell King + * + * Modifications: + * 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both + * constant addresses and variable addresses. + * 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture + * specific IO header files. + */ +#ifndef __ASM_ARM_IO_H +#define __ASM_ARM_IO_H + +#include <asm/hardware.h> +#include <asm/arch/mmu.h> +#include <asm/arch/io.h> + +/* unsigned long virt_to_phys(void *x) */ +#define virt_to_phys(x) __virt_to_phys((unsigned long)(x)) + +/* void *phys_to_virt(unsigned long x) */ +#define phys_to_virt(x) ((void *)(__phys_to_virt((unsigned long)(x)))) + +/* + * These macros actually build the multi-value IO function prototypes + */ +#define __OUTS(s,i,x) extern void outs##s(unsigned int port, const void *from, int len); +#define __INS(s,i,x) extern void ins##s(unsigned int port, void *to, int len); + +#define __IO(s,i,x) \ + __OUTS(s,i,x) \ + __INS(s,i,x) + +__IO(b,"b",char) +__IO(w,"h",short) +__IO(l,"",long) + +/* + * Note that due to the way __builtin_constant_t() works, you + * - can't use it inside an inline function (it will never be true) + * - you don't have to worry about side effects withing the __builtin.. + */ +#ifdef __outbc +#define outb(val,port) \ + (__builtin_constant_p((port)) ? __outbc((val),(port)) : __outb((val),(port))) +#else +#define outb(val,port) __outb((val),(port)) +#endif + +#ifdef __outwc +#define outw(val,port) \ + (__builtin_constant_p((port)) ? __outwc((val),(port)) : __outw((val),(port))) +#else +#define outw(val,port) __outw((val),(port)) +#endif + +#ifdef __outlc +#define outl(val,port) \ + (__builtin_constant_p((port)) ? __outlc((val),(port)) : __outl((val),(port))) +#else +#define outl(val,port) __outl((val),(port)) +#endif + +#ifdef __inbc +#define inb(port) \ + (__builtin_constant_p((port)) ? __inbc((port)) : __inb((port))) +#else +#define inb(port) __inb((port)) +#endif + +#ifdef __inwc +#define inw(port) \ + (__builtin_constant_p((port)) ? __inwc((port)) : __inw((port))) +#else +#define inw(port) __inw((port)) +#endif + +#ifdef __inlc +#define inl(port) \ + (__builtin_constant_p((port)) ? __inlc((port)) : __inl((port))) +#else +#define inl(port) __inl((port)) +#endif + +/* + * This macro will give you the translated IO address for this particular + * architecture, which can be used with the out_t... functions. + */ +#define ioaddr(port) \ + (__builtin_constant_p((port)) ? __ioaddrc((port)) : __ioaddr((port))) + +#ifndef ARCH_IO_DELAY +/* + * This architecture does not require any delayed IO. + * It is handled in the hardware. + */ +#define outb_p(val,port) outb((val),(port)) +#define outw_p(val,port) outw((val),(port)) +#define outl_p(val,port) outl((val),(port)) +#define inb_p(port) inb((port)) +#define inw_p(port) inw((port)) +#define inl_p(port) inl((port)) +#define outsb_p(port,from,len) outsb(port,from,len) +#define outsw_p(port,from,len) outsw(port,from,len) +#define outsl_p(port,from,len) outsl(port,from,len) +#define insb_p(port,to,len) insb(port,to,len) +#define insw_p(port,to,len) insw(port,to,len) +#define insl_p(port,to,len) insl(port,to,len) + +#else + +/* + * We have to delay the IO... + */ +#ifdef __outbc_p +#define outb_p(val,port) \ + (__builtin_constant_p((port)) ? __outbc_p((val),(port)) : __outb_p((val),(port))) +#else +#define outb_p(val,port) __outb_p((val),(port)) +#endif + +#ifdef __outwc_p +#define outw_p(val,port) \ + (__builtin_constant_p((port)) ? __outwc_p((val),(port)) : __outw_p((val),(port))) +#else +#define outw_p(val,port) __outw_p((val),(port)) +#endif + +#ifdef __outlc_p +#define outl_p(val,port) \ + (__builtin_constant_p((port)) ? __outlc_p((val),(port)) : __outl_p((val),(port))) +#else +#define outl_p(val,port) __outl_p((val),(port)) +#endif + +#ifdef __inbc_p +#define inb_p(port) \ + (__builtin_constant_p((port)) ? __inbc_p((port)) : __inb_p((port))) +#else +#define inb_p(port) __inb_p((port)) +#endif + +#ifdef __inwc_p +#define inw_p(port) \ + (__builtin_constant_p((port)) ? __inwc_p((port)) : __inw_p((port))) +#else +#define inw_p(port) __inw_p((port)) +#endif + +#ifdef __inlc_p +#define inl_p(port) \ + (__builtin_constant_p((port)) ? __inlc_p((port)) : __inl_p((port))) +#else +#define inl_p(port) __inl_p((port)) +#endif + +#endif + +#undef ARCH_IO_DELAY +#undef ARCH_IO_CONSTANT + +/* + * Leftovers... + */ +#if 0 +#define __outwc(value,port) \ +({ \ + if (port < 256) \ + __asm__ __volatile__( \ + "strh %0, [%1, %2]" \ + : : "r" (value), "r" (PCIO_BASE), "J" (port << 2)); \ + else if (__PORT_PCIO(port)) \ + __asm__ __volatile__( \ + "strh %0, [%1, %2]" \ + : : "r" (value), "r" (PCIO_BASE), "r" (port << 2)); \ + else \ + __asm__ __volatile__( \ + "strh %0, [%1, %2]" \ + : : "r" (value), "r" (IO_BASE), "r" (port << 2)); \ +}) + +#define __inwc(port) \ +({ \ + unsigned short result; \ + if (port < 256) \ + __asm__ __volatile__( \ + "ldrh %0, [%1, %2]" \ + : "=r" (result) : "r" (PCIO_BASE), "J" (port << 2)); \ + else \ + if (__PORT_PCIO(port)) \ + __asm__ __volatile__( \ + "ldrh %0, [%1, %2]" \ + : "=r" (result) : "r" (PCIO_BASE), "r" (port << 2)); \ + else \ + __asm__ __volatile__( \ + "ldrh %0, [%1, %2]" \ + : "=r" (result) : "r" (IO_BASE), "r" (port << 2)); \ + result; \ +}) +#endif +#endif + diff --git a/include/asm-arm/ioctl.h b/include/asm-arm/ioctl.h new file mode 100644 index 000000000..a45e2fadc --- /dev/null +++ b/include/asm-arm/ioctl.h @@ -0,0 +1,75 @@ +/* $Id: ioctl.h,v 1.5 1993/07/19 21:53:50 root Exp root $ + * + * linux/ioctl.h for Linux by H.H. Bergman. + */ + +#ifndef _ASMARM_IOCTL_H +#define _ASMARM_IOCTL_H + +/* ioctl command encoding: 32 bits total, command in lower 16 bits, + * size of the parameter structure in the lower 14 bits of the + * upper 16 bits. + * Encoding the size of the parameter structure in the ioctl request + * is useful for catching programs compiled with old versions + * and to avoid overwriting user space outside the user buffer area. + * The highest 2 bits are reserved for indicating the ``access mode''. + * NOTE: This limits the max parameter size to 16kB -1 ! + */ + +/* + * The following is for compatibility across the various Linux + * platforms. The i386 ioctl numbering scheme doesn't really enforce + * a type field. De facto, however, the top 8 bits of the lower 16 + * bits are indeed used as a type field, so we might just as well make + * this explicit here. Please be sure to use the decoding macros + * below from now on. + */ +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 +#define _IOC_SIZEBITS 14 +#define _IOC_DIRBITS 2 + +#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) + +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) + +/* + * Direction bits. + */ +#define _IOC_NONE 0U +#define _IOC_WRITE 1U +#define _IOC_READ 2U + +#define _IOC(dir,type,nr,size) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT)) + +/* used to create numbers */ +#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) + +/* used to decode ioctl numbers.. */ +#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) +#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) + +/* ...and for the drivers/sound files... */ + +#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) +#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) +#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) +#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) + +#endif /* _ASMARM_IOCTL_H */ diff --git a/include/asm-arm/ioctls.h b/include/asm-arm/ioctls.h new file mode 100644 index 000000000..87f998fae --- /dev/null +++ b/include/asm-arm/ioctls.h @@ -0,0 +1,80 @@ +#ifndef __ASM_ARM_IOCTLS_H +#define __ASM_ARM_IOCTLS_H + +#include <asm/ioctl.h> + +/* 0x54 is just a magic number to make these relatively unique ('T') */ + +#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ +#define TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ +#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ + +#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ +#define FIOCLEX 0x5451 +#define FIOASYNC 0x5452 +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +#endif diff --git a/include/asm-arm/ipc.h b/include/asm-arm/ipc.h new file mode 100644 index 000000000..c330504ba --- /dev/null +++ b/include/asm-arm/ipc.h @@ -0,0 +1,28 @@ +#ifndef __ASMARM_IPC_H +#define __ASMARM_IPC_H + +/* + * These are used to wrap system calls on ARM. + * + * See arch/arm/kernel/sys-arm.c for ugly details.. + */ +struct ipc_kludge { + struct msgbuf *msgp; + long msgtyp; +}; + +#define SEMOP 1 +#define SEMGET 2 +#define SEMCTL 3 +#define MSGSND 11 +#define MSGRCV 12 +#define MSGGET 13 +#define MSGCTL 14 +#define SHMAT 21 +#define SHMDT 22 +#define SHMGET 23 +#define SHMCTL 24 + +#define IPCCALL(version,op) ((version)<<16 | (op)) + +#endif diff --git a/include/asm-arm/irq-no.h b/include/asm-arm/irq-no.h new file mode 100644 index 000000000..7d599cb80 --- /dev/null +++ b/include/asm-arm/irq-no.h @@ -0,0 +1,11 @@ +/* + * linux/include/asm-arm/irq-no.h + * + * Machine independent interrupt numbers + */ + +#include <asm/arch/irqs.h> + +#ifndef NR_IRQS +#define NR_IRQS 128 +#endif diff --git a/include/asm-arm/irq.h b/include/asm-arm/irq.h new file mode 100644 index 000000000..f7a7a8934 --- /dev/null +++ b/include/asm-arm/irq.h @@ -0,0 +1,13 @@ +#ifndef __ASM_ARM_IRQ_H +#define __ASM_ARM_IRQ_H + +#include <asm/irq-no.h> + +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); + +#define __STR(x) #x +#define STR(x) __STR(x) + +#endif + diff --git a/include/asm-arm/limits.h b/include/asm-arm/limits.h new file mode 100644 index 000000000..08d8c6600 --- /dev/null +++ b/include/asm-arm/limits.h @@ -0,0 +1,11 @@ +#ifndef __ASM_PIPE_H +#define __ASM_PIPE_H + +#ifndef PAGE_SIZE +#include <asm/page.h> +#endif + +#define PIPE_BUF PAGE_SIZE + +#endif + diff --git a/include/asm-arm/mm-init.h b/include/asm-arm/mm-init.h new file mode 100644 index 000000000..863e66259 --- /dev/null +++ b/include/asm-arm/mm-init.h @@ -0,0 +1,46 @@ +/* + * linux/include/asm-arm/mm-init.h + * + * Copyright (C) 1997,1998 Russell King + * + * Contained within are structures to describe how to set up the + * initial memory map. It includes both a processor-specific header + * for parsing these structures, and an architecture-specific header + * to fill out the structures. + */ +#ifndef __ASM_MM_INIT_H +#define __ASM_MM_INIT_H + +typedef enum { + // physical address is absolute + init_mem_map_absolute, + /* physical address is relative to start_mem + * as passed in paging_init + */ + init_mem_map_relative_start_mem +} init_memmap_type_t; + +typedef struct { + init_memmap_type_t type; + unsigned long physical_address; + unsigned long virtual_address; + unsigned long size; +} init_memmap_t; + +#define INIT_MEM_MAP_SENTINEL { init_mem_map_absolute, 0, 0, 0 } +#define INIT_MEM_MAP_ABSOLUTE(p,l,s) { init_mem_map_absolute,p,l,s } +#define INIT_MEM_MAP_RELATIVE(o,l,s) { init_mem_map_relative_start_mem,o,l,s } + +/* + * Within this file, initialise an array of init_mem_map_t's + * to describe your initial memory mapping structure. + */ +#include <asm/arch/mm-init.h> + +/* + * Contained within this file is code to read the array + * of init_mem_map_t's created above. + */ +#include <asm/proc/mm-init.h> + +#endif diff --git a/include/asm-arm/mman.h b/include/asm-arm/mman.h new file mode 100644 index 000000000..9fa76d215 --- /dev/null +++ b/include/asm-arm/mman.h @@ -0,0 +1,32 @@ +#ifndef __ARM_MMAN_H__ +#define __ARM_MMAN_H__ + +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_NONE 0x0 /* page can not be accessed */ + +#define MAP_SHARED 0x01 /* Share changes */ +#define MAP_PRIVATE 0x02 /* Changes are private */ +#define MAP_TYPE 0x0f /* Mask for type of mapping */ +#define MAP_FIXED 0x10 /* Interpret addr exactly */ +#define MAP_ANONYMOUS 0x20 /* don't use a file */ + +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ +#define MAP_LOCKED 0x2000 /* pages are locked */ +#define MAP_NORESERVE 0x4000 /* don't check for reservations */ + +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_INVALIDATE 2 /* invalidate the caches */ +#define MS_SYNC 4 /* synchronous memory sync */ + +#define MCL_CURRENT 1 /* lock all current mappings */ +#define MCL_FUTURE 2 /* lock all future mappings */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif /* __ARM_MMAN_H__ */ diff --git a/include/asm-arm/mmu_context.h b/include/asm-arm/mmu_context.h new file mode 100644 index 000000000..7325fbaa4 --- /dev/null +++ b/include/asm-arm/mmu_context.h @@ -0,0 +1,17 @@ +/* + * linux/include/asm-arm/mmu_context.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 27-06-1996 RMK Created + */ +#ifndef __ASM_ARM_MMU_CONTEXT_H +#define __ASM_ARM_MMU_CONTEXT_H + +#define get_mmu_context(x) do { } while (0) + +#define init_new_context(mm) do { } while(0) +#define destroy_context(mm) do { } while(0) + +#endif diff --git a/include/asm-arm/namei.h b/include/asm-arm/namei.h new file mode 100644 index 000000000..5270c3bdc --- /dev/null +++ b/include/asm-arm/namei.h @@ -0,0 +1,18 @@ +/* $Id: namei.h,v 1.1 1996/12/13 14:48:21 jj Exp $ + * linux/include/asm-i386/namei.h + * + * Included from linux/fs/namei.c + */ + +#ifndef __ASMARM_NAMEI_H +#define __ASMARM_NAMEI_H + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __prefix_namei(retrieve_mode, name, base, buf, res_dir, res_inode, \ + last_name, last_entry, last_error) 1 + +#endif /* __ASMARM_NAMEI_H */ diff --git a/include/asm-arm/page.h b/include/asm-arm/page.h new file mode 100644 index 000000000..9a4429eb9 --- /dev/null +++ b/include/asm-arm/page.h @@ -0,0 +1,20 @@ +#ifndef _ASMARM_PAGE_H +#define _ASMARM_PAGE_H + +#include <asm/arch/mmu.h> +#include <asm/proc/page.h> + +#ifdef __KERNEL__ + +#define clear_page(page) memzero((void *)(page), PAGE_SIZE) +#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) + +#endif + +/* unsigned long __pa(void *x) */ +#define __pa(x) __virt_to_phys((unsigned long)(x)) + +/* void *__va(unsigned long x) */ +#define __va(x) ((void *)(__phys_to_virt((unsigned long)(x)))) + +#endif diff --git a/include/asm-arm/param.h b/include/asm-arm/param.h new file mode 100644 index 000000000..0d7de8684 --- /dev/null +++ b/include/asm-arm/param.h @@ -0,0 +1 @@ +#include <asm/proc/param.h> diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h new file mode 100644 index 000000000..4f9e5ba4a --- /dev/null +++ b/include/asm-arm/pgtable.h @@ -0,0 +1,10 @@ +#ifndef _ASMARM_PGTABLE_H +#define _ASMARM_PGTABLE_H + +#include <asm/proc-fns.h> +#include <asm/proc/pgtable.h> + +#define module_map vmalloc +#define module_unmap vfree + +#endif /* _ASMARM_PGTABLE_H */ diff --git a/include/asm-arm/poll.h b/include/asm-arm/poll.h new file mode 100644 index 000000000..fdfdab064 --- /dev/null +++ b/include/asm-arm/poll.h @@ -0,0 +1,25 @@ +#ifndef __ASMARM_POLL_H +#define __ASMARM_POLL_H + +/* These are specified by iBCS2 */ +#define POLLIN 0x0001 +#define POLLPRI 0x0002 +#define POLLOUT 0x0004 +#define POLLERR 0x0008 +#define POLLHUP 0x0010 +#define POLLNVAL 0x0020 + +/* The rest seem to be more-or-less nonstandard. Check them! */ +#define POLLRDNORM 0x0040 +#define POLLRDBAND 0x0080 +#define POLLWRNORM 0x0100 +#define POLLWRBAND 0x0200 +#define POLLMSG 0x0400 + +struct pollfd { + int fd; + short events; + short revents; +}; + +#endif diff --git a/include/asm-arm/posix_types.h b/include/asm-arm/posix_types.h new file mode 100644 index 000000000..e32c78139 --- /dev/null +++ b/include/asm-arm/posix_types.h @@ -0,0 +1,60 @@ +/* + * linux/include/asm-arm/posix_types.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 27-06-1996 RMK Created + */ +#ifndef __ARCH_ARM_POSIX_TYPES_H +#define __ARCH_ARM_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { + int val[2]; +} __kernel_fsid_t; + +#undef __FD_SET +#define __FD_SET(fd, fdsetp) \ + (((fd_set *)fdsetp)->fds_bits[fd >> 5] |= (1<<(fd & 31))) + +#undef __FD_CLR +#define __FD_CLR(fd, fdsetp) \ + (((fd_set *)fdsetp)->fds_bits[fd >> 5] &= ~(1<<(fd & 31))) + +#undef __FD_ISSET +#define __FD_ISSET(fd, fdsetp) \ + ((((fd_set *)fdsetp)->fds_bits[fd >> 5] & (1<<(fd & 31))) != 0) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) \ + (memset (fdsetp, 0, sizeof (*(fd_set *)fdsetp))) + +#endif diff --git a/include/asm-arm/proc-armo/assembler.h b/include/asm-arm/proc-armo/assembler.h new file mode 100644 index 000000000..5b9e7c058 --- /dev/null +++ b/include/asm-arm/proc-armo/assembler.h @@ -0,0 +1,88 @@ +/* + * linux/asm-arm/proc-armo/assembler.h + * + * Copyright (C) 1996 Russell King + * + * This file contains arm architecture specific defines + * for the different processors + */ + +/* + * LOADREGS: multiple register load (ldm) with pc in register list + * (takes account of ARM6 not using ^) + * + * RETINSTR: return instruction: adds the 's' in at the end of the + * instruction if this is not an ARM6 + * + * SAVEIRQS: save IRQ state (not required on ARM2/ARM3 - done + * implicitly + * + * RESTOREIRQS: restore IRQ state (not required on ARM2/ARM3 - done + * implicitly with ldm ... ^ or movs. + * + * These next two need thinking about - can't easily use stack... (see system.S) + * DISABLEIRQS: disable IRQS in SVC mode + * + * ENABLEIRQS: enable IRQS in SVC mode + * + * USERMODE: switch to USER mode + * + * SVCMODE: switch to SVC mode + */ + +#define N_BIT (1 << 31) +#define Z_BIT (1 << 30) +#define C_BIT (1 << 29) +#define V_BIT (1 << 28) + +#define PCMASK 0xfc000003 + +#ifdef __ASSEMBLER__ + +#define I_BIT (1 << 27) +#define F_BIT (1 << 26) + +#define MODE_USR 0 +#define MODE_FIQ 1 +#define MODE_IRQ 2 +#define MODE_SVC 3 + +#define DEFAULT_FIQ MODE_FIQ + +#define LOADREGS(cond, base, reglist...)\ + ldm##cond base,reglist^ + +#define RETINSTR(instr, regs...)\ + instr##s regs + +#define MODENOP\ + mov r0, r0 + +#define MODE(savereg,tmpreg,mode) \ + mov savereg, pc; \ + bic tmpreg, savereg, $0x0c000003; \ + orr tmpreg, tmpreg, $mode; \ + teqp tmpreg, $0 + +#define RESTOREMODE(savereg) \ + teqp savereg, $0 + +#define SAVEIRQS(tmpreg) + +#define RESTOREIRQS(tmpreg) + +#define DISABLEIRQS(tmpreg)\ + teqp pc, $0x08000003 + +#define ENABLEIRQS(tmpreg)\ + teqp pc, $0x00000003 + +#define USERMODE(tmpreg)\ + teqp pc, $0x00000000;\ + mov r0, r0 + +#define SVCMODE(tmpreg)\ + teqp pc, $0x00000003;\ + mov r0, r0 + +#endif diff --git a/include/asm-arm/proc-armo/mm-init-flat.h b/include/asm-arm/proc-armo/mm-init-flat.h new file mode 100644 index 000000000..919ef59a4 --- /dev/null +++ b/include/asm-arm/proc-armo/mm-init-flat.h @@ -0,0 +1,82 @@ +/* + * linux/include/asm-arm/proc-armo/mmap.h + * + * Copyright (C) 1996 Russell King + * + * This contains the code to setup the memory map on an ARM2/ARM250/ARM3 + * machine. This is both processor & architecture specific, and requires + * some more work to get it to fit into our separate processor and + * architecture structure. + */ + +static unsigned long phys_screen_end; +int page_nr; + +#define setup_processor_functions() + +/* + * This routine needs more work to make it dynamically release/allocate mem! + */ +unsigned long map_screen_mem(unsigned long log_start, unsigned long kmem, int update) +{ + static int updated = 0; + unsigned long address = SCREEN_START, i; + pgd_t *pg_dir; + pmd_t *pm_dir; + pte_t *pt_entry; + + if (updated) + return 0; + updated = update; + + pg_dir = swapper_pg_dir + (SCREEN1_BASE >> PGDIR_SHIFT); + pm_dir = pmd_offset(pg_dir, SCREEN1_BASE); + pt_entry = pte_offset(pm_dir, SCREEN1_BASE); + + for (i = SCREEN1_BASE; i < SCREEN1_END; i += PAGE_SIZE) { + if (i >= log_start) { + *pt_entry = mk_pte(address, __pgprot(_PAGE_PRESENT)); + address += PAGE_SIZE; + } else + *pt_entry = mk_pte(0, __pgprot(0)); + pt_entry++; + } + phys_screen_end = address; + if (update) + flush_tlb_all (); + return kmem; +} + +static inline unsigned long setup_pagetables(unsigned long start_mem, unsigned long end_mem) +{ + unsigned long address; + unsigned int spi; + + page_nr = MAP_NR(end_mem); + + /* Allocate zero page */ + address = PAGE_OFFSET + 480*1024; + for (spi = 0; spi < 32768 >> PAGE_SHIFT; spi++) { + pgd_val(swapper_pg_dir[spi]) = pte_val(mk_pte(address, PAGE_READONLY)); + address += PAGE_SIZE; + } + + while (spi < (PAGE_OFFSET >> PGDIR_SHIFT)) + pgd_val(swapper_pg_dir[spi++]) = 0; + + map_screen_mem (SCREEN1_END - 480*1024, 0, 0); + return start_mem; +} + +static inline void mark_usable_memory_areas(unsigned long *start_mem, unsigned long end_mem) +{ + unsigned long smem = PAGE_ALIGN(*start_mem); + + while (smem < end_mem) { + clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags); + smem += PAGE_SIZE; + } + + for (smem = phys_screen_end; smem < SCREEN2_END; smem += PAGE_SIZE) + clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags); +} diff --git a/include/asm-arm/proc-armo/mm-init.h b/include/asm-arm/proc-armo/mm-init.h new file mode 100644 index 000000000..2cf40e9da --- /dev/null +++ b/include/asm-arm/proc-armo/mm-init.h @@ -0,0 +1,130 @@ +/* + * linux/include/asm-arm/proc-armo/mm-init.h + * + * Copyright (C) 1996 Russell King + * + * This contains the code to setup the memory map on an ARM2/ARM250/ARM3 + * machine. This is both processor & architecture specific, and requires + * some more work to get it to fit into our separate processor and + * architecture structure. + */ + +static unsigned long phys_screen_end; +int page_nr; + +#define setup_processor_functions() +#define PTE_SIZE (PTRS_PER_PTE * BYTES_PER_PTR) + +static inline void setup_swapper_dir (int index, pte_t *ptep) +{ + set_pmd (pmd_offset (swapper_pg_dir + index, 0), mk_pmd (ptep)); +} + +/* + * This routine needs more work to make it dynamically release/allocate mem! + */ +unsigned long map_screen_mem(unsigned long log_start, unsigned long kmem, int update) +{ + static int updated = 0; + + if (updated) + return 0; + + updated = update; + + if (update) { + unsigned long address = log_start, offset; + pgd_t *pgdp; + + kmem = (kmem + 3) & ~3; + + pgdp = pgd_offset (&init_mm, address); /* +31 */ + offset = SCREEN_START; + while (address < SCREEN1_END) { + unsigned long addr_pmd, end_pmd; + pmd_t *pmdp; + + /* if (pgd_none (*pgdp)) alloc pmd */ + pmdp = pmd_offset (pgdp, address); /* +0 */ + addr_pmd = address & ~PGDIR_MASK; /* 088000 */ + end_pmd = addr_pmd + SCREEN1_END - address; /* 100000 */ + if (end_pmd > PGDIR_SIZE) + end_pmd = PGDIR_SIZE; + + do { + unsigned long addr_pte, end_pte; + pte_t *ptep; + + if (pmd_none (*pmdp)) { + pte_t *new_pte = (pte_t *)kmem; + kmem += PTRS_PER_PTE * BYTES_PER_PTR; + memzero (new_pte, PTRS_PER_PTE * BYTES_PER_PTR); + set_pmd (pmdp, mk_pmd(new_pte)); + } + + ptep = pte_offset (pmdp, addr_pmd); /* +11 */ + addr_pte = addr_pmd & ~PMD_MASK; /* 088000 */ + end_pte = addr_pte + end_pmd - addr_pmd; /* 100000 */ + if (end_pte > PMD_SIZE) + end_pte = PMD_SIZE; + + do { + set_pte (ptep, mk_pte(offset, PAGE_KERNEL)); + addr_pte += PAGE_SIZE; + offset += PAGE_SIZE; + ptep++; + } while (addr_pte < end_pte); + + pmdp++; + addr_pmd = (addr_pmd + PMD_SIZE) & PMD_MASK; + } while (addr_pmd < end_pmd); + + address = (address + PGDIR_SIZE) & PGDIR_MASK; + pgdp ++; + } + + phys_screen_end = offset; + flush_tlb_all (); + update_mm_cache_all (); + } + return kmem; +} + +static inline unsigned long setup_pagetables(unsigned long start_mem, unsigned long end_mem) +{ + unsigned int i; + union {unsigned long l; pte_t *pte; } u; + + page_nr = MAP_NR(end_mem); + + /* map in pages for (0x0000 - 0x8000) */ + u.l = ((start_mem + (PTE_SIZE-1)) & ~(PTE_SIZE-1)); + start_mem = u.l + PTE_SIZE; + memzero (u.pte, PTE_SIZE); + u.pte[0] = mk_pte(PAGE_OFFSET + 491520, PAGE_READONLY); + setup_swapper_dir (0, u.pte); + + for (i = 1; i < PTRS_PER_PGD; i++) + pgd_val(swapper_pg_dir[i]) = 0; + + /* now map screen mem in */ + phys_screen_end = SCREEN2_END; + map_screen_mem (SCREEN1_END - 480*1024, 0, 0); + + return start_mem; +} + +static inline void mark_usable_memory_areas(unsigned long *start_mem, unsigned long end_mem) +{ + unsigned long smem; + + *start_mem = smem = PAGE_ALIGN(*start_mem); + + while (smem < end_mem) { + clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags); + smem += PAGE_SIZE; + } + + for (smem = phys_screen_end; smem < SCREEN2_END; smem += PAGE_SIZE) + clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags); +} diff --git a/include/asm-arm/proc-armo/page.h b/include/asm-arm/proc-armo/page.h new file mode 100644 index 000000000..058d7e9bd --- /dev/null +++ b/include/asm-arm/proc-armo/page.h @@ -0,0 +1,69 @@ +/* + * linux/include/asm-arm/proc-armo/page.h + * + * Copyright (C) 1995, 1996 Russell King + */ + +#ifndef __ASM_PROC_PAGE_H +#define __ASM_PROC_PAGE_H + +/* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT 15 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#ifdef __KERNEL__ + +#define STRICT_MM_TYPECHECKS + +#ifdef STRICT_MM_TYPECHECKS +/* + * These are used to make use of C type-checking.. + */ +typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long pmd; } pmd_t; +typedef struct { unsigned long pgd; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; + +#define pte_val(x) ((x).pte) +#define pmd_val(x) ((x).pmd) +#define pgd_val(x) ((x).pgd) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgd(x) ((pgd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +#else +/* + * .. while these make it easier on the compiler + */ +typedef unsigned long pte_t; +typedef unsigned long pmd_t; +typedef unsigned long pgd_t; +typedef unsigned long pgprot_t; + +#define pte_val(x) (x) +#define pmd_val(x) (x) +#define pgd_val(x) (x) +#define pgprot_val(x) (x) + +#define __pte(x) (x) +#define __pmd(x) (x) +#define __pgd(x) (x) +#define __pgprot(x) (x) + +#endif + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +/* This handles the memory map.. */ +#define PAGE_OFFSET 0x02000000 +#define MAP_NR(addr) (((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT) + +#endif /* __KERNEL__ */ + +#endif /* __ASM_PROC_PAGE_H */ + diff --git a/include/asm-arm/proc-armo/param.h b/include/asm-arm/proc-armo/param.h new file mode 100644 index 000000000..230511003 --- /dev/null +++ b/include/asm-arm/proc-armo/param.h @@ -0,0 +1,27 @@ +/* + * linux/include/asm-arm/proc-armo/param.h + * + * Copyright (C) 1995, 1996 Russell King + */ + +#ifndef __ASM_PROC_PARAM_H +#define __ASM_PROC_PARAM_H + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 32768 + +#ifndef NGROUPS +#define NGROUPS 32 +#endif + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif + diff --git a/include/asm-arm/proc-armo/pgtable-flat.h b/include/asm-arm/proc-armo/pgtable-flat.h new file mode 100644 index 000000000..994fa9f21 --- /dev/null +++ b/include/asm-arm/proc-armo/pgtable-flat.h @@ -0,0 +1,307 @@ +/* + * linux/include/asm-arm/proc-armo/pgtable.h + * + * Copyright (C) 1995, 1996 Russell King + */ +#ifndef __ASM_PROC_PGTABLE_H +#define __ASM_PROC_PGTABLE_H + +#include <asm/arch/mmu.h> + +#define LIBRARY_TEXT_START 0x0c000000 + +/* + * Cache flushing... + */ +#define flush_cache_all() do { } while (0) +#define flush_cache_mm(mm) do { } while (0) +#define flush_cache_range(mm,start,end) do { } while (0) +#define flush_cache_page(vma,vmaddr) do { } while (0) +#define flush_page_to_ram(page) do { } while (0) + +/* + * TLB flushing: + * + * - flush_tlb() flushes the current mm struct TLBs + * - flush_tlb_all() flushes all processes TLBs + * - flush_tlb_mm(mm) flushes the specified mm context TLB's + * - flush_tlb_page(vma, vmaddr) flushes one page + * - flush_tlb_range(mm, start, end) flushes a range of pages + */ + +#define flush_tlb() flush_tlb_mm(current->mm) + +extern __inline__ void flush_tlb_all(void) +{ + struct task_struct *p; + + p = &init_task; + do { + processor.u.armv2._update_map(p); + p = p->next_task; + } while (p != &init_task); + + processor.u.armv2._remap_memc (current); +} + +extern __inline__ void flush_tlb_mm(struct mm_struct *mm) +{ + struct task_struct *p; + + p = &init_task; + do { + if (p->mm == mm) + processor.u.armv2._update_map(p); + p = p->next_task; + } while (p != &init_task); + + if (current->mm == mm) + processor.u.armv2._remap_memc (current); +} + +#define flush_tlb_range(mm, start, end) flush_tlb_mm(mm) +#define flush_tlb_page(vma, vmaddr) flush_tlb_mm(vma->vm_mm) + +#define __flush_entry_to_ram(entry) + +/* Certain architectures need to do special things when pte's + * within a page table are directly modified. Thus, the following + * hook is made available. + */ +#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval)) + +/* PMD_SHIFT determines the size of the area a second-level page table can map */ +#define PMD_SHIFT PAGE_SHIFT +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) + +/* PGDIR_SHIFT determines what a third-level page table entry can map */ +#define PGDIR_SHIFT PAGE_SHIFT +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) + +/* + * entries per page directory level: the arm3 is one-level, so + * we don't really have any PMD or PTE directory physically. + */ +#define PTRS_PER_PTE 1 +#define PTRS_PER_PMD 1 +#define PTRS_PER_PGD 1024 + +/* Just any arbitrary offset to the start of the vmalloc VM area: the + * current 8MB value just means that there will be a 8MB "hole" after the + * physical memory until the kernel virtual memory starts. That means that + * any out-of-bounds memory accesses will hopefully be caught. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) + */ +#define VMALLOC_START 0x01a00000 +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) + +#define _PAGE_PRESENT 0x001 +#define _PAGE_RW 0x002 +#define _PAGE_USER 0x004 +#define _PAGE_PCD 0x010 +#define _PAGE_ACCESSED 0x020 +#define _PAGE_DIRTY 0x040 + +#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) + +#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) + +/* + * The arm can't do page protection for execute, and considers that the same are read. + * Also, write permissions imply read permissions. This is the closest we can get.. + */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY +#define __P101 PAGE_READONLY +#define __P110 PAGE_COPY +#define __P111 PAGE_COPY + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY +#define __S101 PAGE_READONLY +#define __S110 PAGE_SHARED +#define __S111 PAGE_SHARED + +#undef TEST_VERIFY_AREA + +/* + * BAD_PAGE is used for a bogus page. + * + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +extern pte_t __bad_page(void); +extern unsigned long *empty_zero_page; + +#define BAD_PAGE __bad_page() +#define ZERO_PAGE ((unsigned long) empty_zero_page) + +/* number of bits that fit into a memory pointer */ +#define BYTES_PER_PTR (sizeof(unsigned long)) +#define BITS_PER_PTR (8*BYTES_PER_PTR) + +/* to align the pointer to a pointer address */ +#define PTR_MASK (~(sizeof(void*)-1)) + +/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */ +#define SIZEOF_PTR_LOG2 2 + +/* to find an entry in a page-table */ +#define PAGE_PTR(address) \ +((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) + +/* to set the page-dir */ +#define SET_PAGE_DIR(tsk,pgdir) \ +do { \ + tsk->tss.memmap = (unsigned long)pgdir; \ + processor.u.armv2._update_map(tsk); \ + if ((tsk) == current) \ + processor.u.armv2._remap_memc (current); \ +} while (0) + +extern unsigned long physical_start; +extern unsigned long physical_end; + +extern inline int pte_none(pte_t pte) { return !pte_val(pte); } +extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; } +extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; } + +extern inline int pmd_none(pmd_t pmd) { return 0; } +extern inline int pmd_bad(pmd_t pmd) { return 0; } +extern inline int pmd_present(pmd_t pmd) { return 1; } +extern inline void pmd_clear(pmd_t * pmdp) { } + +/* + * The "pgd_xxx()" functions here are trivial for a folded two-level + * setup: the pgd is never bad, and a pmd always exists (as it's folded + * into the pgd entry) + */ +extern inline int pgd_none(pgd_t pgd) { return 0; } +extern inline int pgd_bad(pgd_t pgd) { return 0; } +extern inline int pgd_present(pgd_t pgd) { return 1; } +extern inline void pgd_clear(pgd_t * pgdp) { } + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; } +extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } +extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; } +extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } +extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +#define pte_cacheable(pte) 1 + +extern inline pte_t pte_nocache(pte_t pte) { return pte; } +extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_RW; return pte; } +extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; } +extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; } +extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } +extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } +extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_RW; return pte; } +extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; } +extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; } +extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } +extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ +extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot) +{ pte_t pte; pte_val(pte) = virt_to_phys(page) | pgprot_val(pgprot); return pte; } + +extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } + +extern inline unsigned long pte_page(pte_t pte) +{ return phys_to_virt(pte_val(pte) & PAGE_MASK); } + +extern inline unsigned long pmd_page(pmd_t pmd) +{ return phys_to_virt(pmd_val(pmd) & PAGE_MASK); } + +/* to find an entry in a page-table-directory */ +extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) +{ + return mm->pgd + (address >> PGDIR_SHIFT); +} + +/* Find an entry in the second-level page table.. */ +#define pmd_offset(dir, address) ((pmd_t *)(dir)) + +/* Find an entry in the third-level page table.. */ +#define pte_offset(dir, address) ((pte_t *)(dir)) + +/* + * Allocate and free page tables. The xxx_kernel() versions are + * used to allocate a kernel page table - this turns on ASN bits + * if any. + */ +extern inline void pte_free_kernel(pte_t * pte) +{ + pte_val(*pte) = 0; +} + +extern inline pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address) +{ + return (pte_t *) pmd; +} + +/* + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. + */ +#define pmd_free_kernel(pmdp) +#define pmd_alloc_kernel(pgd,address) ((pmd_t *)(pgd)) + +#define pte_free(ptep) +#define pte_alloc(pmd,address) ((pte_t *)(pmd)) + +/* + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. + */ +#define pmd_free(pmd) +#define pmd_alloc(pgd,address) ((pmd_t *)(pgd)) + +extern inline void pgd_free(pgd_t * pgd) +{ + extern void kfree(void *); + kfree((void *)pgd); +} + +extern inline pgd_t * pgd_alloc(void) +{ + pgd_t *pgd; + extern void *kmalloc(unsigned int, int); + + pgd = (pgd_t *) kmalloc(PTRS_PER_PGD * BYTES_PER_PTR, GFP_KERNEL); + if (pgd) + memset(pgd, 0, PTRS_PER_PGD * BYTES_PER_PTR); + return pgd; +} + +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; + +#define update_mmu_cache(vma,address,pte) processor.u.armv2._update_mmu_cache(vma,address,pte) + +#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f) +#define SWP_OFFSET(entry) ((entry) >> 8) +#define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8)) + +#endif /* __ASM_PROC_PAGE_H */ + diff --git a/include/asm-arm/proc-armo/pgtable.h b/include/asm-arm/proc-armo/pgtable.h new file mode 100644 index 000000000..3fdb824e7 --- /dev/null +++ b/include/asm-arm/proc-armo/pgtable.h @@ -0,0 +1,403 @@ +/* + * linux/include/asm-arm/proc-armo/pgtable.h + * + * Copyright (C) 1995, 1996 Russell King + * Modified 18/19-Oct-1997 for two-level page table + */ +#ifndef __ASM_PROC_PGTABLE_H +#define __ASM_PROC_PGTABLE_H + +#include <asm/arch/mmu.h> +#include <linux/slab.h> + +#define LIBRARY_TEXT_START 0x0c000000 + +/* + * Cache flushing... + */ +#define flush_cache_all() do { } while (0) +#define flush_cache_mm(mm) do { } while (0) +#define flush_cache_range(mm,start,end) do { } while (0) +#define flush_cache_page(vma,vmaddr) do { } while (0) +#define flush_page_to_ram(page) do { } while (0) +#define flush_icache_range(start,end) do { } while (0) + +/* + * TLB flushing: + * + * - flush_tlb() flushes the current mm struct TLBs + * - flush_tlb_all() flushes all processes TLBs + * - flush_tlb_mm(mm) flushes the specified mm context TLB's + * - flush_tlb_page(vma, vmaddr) flushes one page + * - flush_tlb_range(mm, start, end) flushes a range of pages + */ +#define flush_tlb() do { } while (0) +#define flush_tlb_all() do { } while (0) +#define flush_tlb_mm(mm) do { } while (0) +#define flush_tlb_range(mm, start, end) do { } while (0) +#define flush_tlb_page(vma, vmaddr) do { } while (0) + +/* + * We have a mem map cache... + */ +extern __inline__ void update_mm_cache_all(void) +{ + struct task_struct *p; + + p = &init_task; + do { + processor.u.armv2._update_map(p); + p = p->next_task; + } while (p != &init_task); + + processor.u.armv2._remap_memc (current); +} + +extern __inline__ void update_mm_cache_task(struct task_struct *tsk) +{ + processor.u.armv2._update_map(tsk); + + if (tsk == current) + processor.u.armv2._remap_memc (tsk); +} + +extern __inline__ void update_mm_cache_mm(struct mm_struct *mm) +{ + struct task_struct *p; + + p = &init_task; + do { + if (p->mm == mm) + processor.u.armv2._update_map(p); + p = p->next_task; + } while (p != &init_task); + + if (current->mm == mm) + processor.u.armv2._remap_memc (current); +} + +extern __inline__ void update_mm_cache_mm_addr(struct mm_struct *mm, unsigned long addr, pte_t pte) +{ + struct task_struct *p; + + p = &init_task; + do { + if (p->mm == mm) + processor.u.armv2._update_mmu_cache(p, addr, pte); + p = p->next_task; + } while (p != &init_task); + + if (current->mm == mm) + processor.u.armv2._remap_memc (current); +} + +#define __flush_entry_to_ram(entry) + +/* Certain architectures need to do special things when pte's + * within a page table are directly modified. Thus, the following + * hook is made available. + */ +/* PMD_SHIFT determines the size of the area a second-level page table can map */ +#define PMD_SHIFT 20 +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) + +/* PGDIR_SHIFT determines what a third-level page table entry can map */ +#define PGDIR_SHIFT 20 +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) + +/* + * entries per page directory level: the arm3 is one-level, so + * we don't really have any PMD or PTE directory physically. + * + * 18-Oct-1997 RMK Now two-level (32x32) + */ +#define PTRS_PER_PTE 32 +#define PTRS_PER_PMD 1 +#define PTRS_PER_PGD 32 + +/* Just any arbitrary offset to the start of the vmalloc VM area: the + * current 8MB value just means that there will be a 8MB "hole" after the + * physical memory until the kernel virtual memory starts. That means that + * any out-of-bounds memory accesses will hopefully be caught. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) + */ +#define VMALLOC_START 0x01a00000 +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) + +#define _PAGE_PRESENT 0x01 +#define _PAGE_READONLY 0x02 +#define _PAGE_NOT_USER 0x04 +#define _PAGE_OLD 0x08 +#define _PAGE_CLEAN 0x10 + +#define _PAGE_TABLE (_PAGE_PRESENT) +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_OLD | _PAGE_CLEAN) + +/* -- present -- -- !dirty -- --- !write --- ---- !user --- */ +#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_CLEAN | _PAGE_READONLY | _PAGE_NOT_USER) +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_CLEAN ) +#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_CLEAN | _PAGE_READONLY ) +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_CLEAN | _PAGE_READONLY ) +#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_NOT_USER) + +/* + * The arm can't do page protection for execute, and considers that the same are read. + * Also, write permissions imply read permissions. This is the closest we can get.. + */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY +#define __P101 PAGE_READONLY +#define __P110 PAGE_COPY +#define __P111 PAGE_COPY + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY +#define __S101 PAGE_READONLY +#define __S110 PAGE_SHARED +#define __S111 PAGE_SHARED + +#undef TEST_VERIFY_AREA + +extern unsigned long *empty_zero_page; + +/* + * BAD_PAGETABLE is used when we need a bogus page-table, while + * BAD_PAGE is used for a bogus page. + * + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +extern pte_t __bad_page(void); +extern pte_t *__bad_pagetable(void); + +#define BAD_PAGETABLE __bad_pagetable() +#define BAD_PAGE __bad_page() +#define ZERO_PAGE ((unsigned long) empty_zero_page) + +/* number of bits that fit into a memory pointer */ +#define BYTES_PER_PTR (sizeof(unsigned long)) +#define BITS_PER_PTR (8*BYTES_PER_PTR) + +/* to align the pointer to a pointer address */ +#define PTR_MASK (~(sizeof(void*)-1)) + +/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */ +#define SIZEOF_PTR_LOG2 2 + +/* to find an entry in a page-table */ +#define PAGE_PTR(address) \ +((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) + +/* to set the page-dir */ +#define SET_PAGE_DIR(tsk,pgdir) \ +do { \ + tsk->tss.memmap = (unsigned long)pgdir; \ + processor.u.armv2._update_map(tsk); \ + if ((tsk) == current) \ + processor.u.armv2._remap_memc (current); \ +} while (0) + +extern unsigned long physical_start; +extern unsigned long physical_end; + +#define pte_none(pte) (!pte_val(pte)) +#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT) +#define pte_clear(ptep) set_pte((ptep), __pte(0)) + +#define pmd_none(pmd) (!pmd_val(pmd)) +#define pmd_bad(pmd) ((pmd_val(pmd) & 0xfc000002)) +#define pmd_present(pmd) (pmd_val(pmd) & _PAGE_PRESENT) +#define pmd_clear(pmdp) set_pmd(pmdp, __pmd(0)) + +/* + * The "pgd_xxx()" functions here are trivial for a folded two-level + * setup: the pgd is never bad, and a pmd always exists (as it's folded + * into the pgd entry) + */ +#define pgd_none(pgd) (0) +#define pgd_bad(pgd) (0) +#define pgd_present(pgd) (1) +#define pgd_clear(pgdp) + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +extern inline int pte_read(pte_t pte) { return !(pte_val(pte) & _PAGE_NOT_USER); } +extern inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_READONLY); } +extern inline int pte_exec(pte_t pte) { return !(pte_val(pte) & _PAGE_NOT_USER); } +extern inline int pte_dirty(pte_t pte) { return !(pte_val(pte) & _PAGE_CLEAN); } +extern inline int pte_young(pte_t pte) { return !(pte_val(pte) & _PAGE_OLD); } +#define pte_cacheable(pte) 1 + +extern inline pte_t pte_nocache(pte_t pte) { return pte; } +extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_READONLY; return pte; } +extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) |= _PAGE_NOT_USER; return pte; } +extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) |= _PAGE_NOT_USER; return pte; } +extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) |= _PAGE_CLEAN; return pte; } +extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) |= _PAGE_OLD; return pte; } + +extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_READONLY; return pte; } +extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) &= ~_PAGE_NOT_USER; return pte; } +extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) &= ~_PAGE_NOT_USER; return pte; } +extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) &= ~_PAGE_CLEAN; return pte; } +extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) &= ~_PAGE_OLD; return pte; } + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ +extern __inline__ pte_t mk_pte(unsigned long page, pgprot_t pgprot) +{ + pte_t pte; + pte_val(pte) = __virt_to_phys(page) | pgprot_val(pgprot); + return pte; +} + +/* This takes a physical page address that is used by the remapping functions */ +extern __inline__ pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) +{ + pte_t pte; + pte_val(pte) = physpage + pgprot_val(pgprot); + return pte; +} + +extern __inline__ pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); + return pte; +} + +#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval)) + +extern __inline__ unsigned long pte_page(pte_t pte) +{ + return __phys_to_virt(pte_val(pte) & PAGE_MASK); +} + +extern __inline__ pmd_t mk_pmd (pte_t *ptep) +{ + pmd_t pmd; + pmd_val(pmd) = __virt_to_phys((unsigned long)ptep) | _PAGE_TABLE; + return pmd; +} + +#define set_pmd(pmdp,pmd) ((*(pmdp)) = (pmd)) + +extern __inline__ unsigned long pmd_page(pmd_t pmd) +{ + return __phys_to_virt(pmd_val(pmd) & ~_PAGE_TABLE); +} + +/* to find an entry in a kernel page-table-directory */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) + +/* to find an entry in a page-table-directory */ +extern __inline__ pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) +{ + return mm->pgd + (address >> PGDIR_SHIFT); +} + +/* Find an entry in the second-level page table.. */ +#define pmd_offset(dir, address) ((pmd_t *)(dir)) + +/* Find an entry in the third-level page table.. */ +extern __inline__ pte_t * pte_offset(pmd_t *dir, unsigned long address) +{ + return (pte_t *)pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); +} + +/* + * Allocate and free page tables. The xxx_kernel() versions are + * used to allocate a kernel page table - this turns on ASN bits + * if any. + */ +#define pte_free_kernel(pte) pte_free((pte)) +#define pte_alloc_kernel(pmd,address) pte_alloc((pmd),(address)) + +/* + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. + */ +#define pmd_free_kernel(pmdp) +#define pmd_alloc_kernel(pgd,address) ((pmd_t *)(pgd)) + +extern __inline__ void pte_free(pte_t * pte) +{ + kfree (pte); +} + +extern const char bad_pmd_string[]; + +extern __inline__ pte_t *pte_alloc(pmd_t * pmd, unsigned long address) +{ + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); + + if (pmd_none (*pmd)) { + pte_t *page = (pte_t *) kmalloc (PTRS_PER_PTE * BYTES_PER_PTR, GFP_KERNEL); + if (pmd_none (*pmd)) { + if (page) { + memzero (page, PTRS_PER_PTE * BYTES_PER_PTR); + set_pmd(pmd, mk_pmd(page)); + return page + address; + } + set_pmd (pmd, mk_pmd (BAD_PAGETABLE)); + return NULL; + } + kfree (page); + } + if (pmd_bad (*pmd)) { + printk(bad_pmd_string, pmd_val(*pmd)); + set_pmd (pmd, mk_pmd (BAD_PAGETABLE)); + return NULL; + } + return (pte_t *) pmd_page(*pmd) + address; +} + +/* + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. + */ +#define pmd_free(pmd) +#define pmd_alloc(pgd,address) ((pmd_t *)(pgd)) + +/* + * Free a page directory. Takes the virtual address. + */ +extern __inline__ void pgd_free(pgd_t * pgd) +{ + kfree ((void *)pgd); +} + +/* + * Allocate a new page directory. Return the virtual address of it. + */ +extern __inline__ pgd_t * pgd_alloc(void) +{ + pgd_t *pgd; + + pgd = (pgd_t *) kmalloc(PTRS_PER_PGD * BYTES_PER_PTR, GFP_KERNEL); + if (pgd) + memzero (pgd, PTRS_PER_PGD * BYTES_PER_PTR); + return pgd; +} + +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; + +#define update_mmu_cache(vma,address,pte) + +#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f) +#define SWP_OFFSET(entry) ((entry) >> 8) +#define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8)) + +#endif /* __ASM_PROC_PAGE_H */ + diff --git a/include/asm-arm/proc-armo/processor.h b/include/asm-arm/proc-armo/processor.h new file mode 100644 index 000000000..0da437ff7 --- /dev/null +++ b/include/asm-arm/proc-armo/processor.h @@ -0,0 +1,118 @@ +/* + * linux/include/asm-arm/proc-armo/processor.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 27-06-1996 RMK Created + * 10-10-1996 RMK Brought up to date with SA110 + * 26-09-1996 RMK Added 'EXTRA_THREAD_STRUCT*' + * 28-09-1996 RMK Moved start_thread into the processor dependencies + * 11-01-1998 RMK Added new uaccess_t + */ +#ifndef __ASM_PROC_PROCESSOR_H +#define __ASM_PROC_PROCESSOR_H + +#ifdef __KERNEL__ + +#include <asm/assembler.h> +#include <linux/string.h> + +#define KERNEL_STACK_SIZE 4096 + +/* + * on arm2,3 wp does not work + */ +#define wp_works_ok 0 +#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ + +struct context_save_struct { + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long fp; + unsigned long pc; +}; + +typedef struct { + void (*put_byte)(void); /* Special calling convention */ + void (*get_byte)(void); /* Special calling convention */ + void (*put_half)(void); /* Special calling convention */ + void (*get_half)(void); /* Special calling convention */ + void (*put_word)(void); /* Special calling convention */ + void (*get_word)(void); /* Special calling convention */ + unsigned long (*copy_from_user)(void *to, const void *from, unsigned long sz); + unsigned long (*copy_to_user)(void *to, const void *from, unsigned long sz); + unsigned long (*clear_user)(void *addr, unsigned long sz); + unsigned long (*strncpy_from_user)(char *to, const char *from, unsigned long sz); + unsigned long (*strlen_user)(const char *s); +} uaccess_t; + +extern uaccess_t uaccess_user, uaccess_kernel; + +#define EXTRA_THREAD_STRUCT \ + uaccess_t *uaccess; /* User access functions*/ \ + struct context_save_struct *save; \ + unsigned long memmap; \ + unsigned long memcmap[256]; + +#define EXTRA_THREAD_STRUCT_INIT \ + &uaccess_kernel, \ + 0, \ + (unsigned long) swapper_pg_dir, \ + { 0, } + +DECLARE_THREAD_STRUCT; + +/* + * Return saved PC of a blocked thread. + */ +extern __inline__ unsigned long thread_saved_pc (struct thread_struct *t) +{ + if (t->save) + return t->save->pc & ~PCMASK; + else + return 0; +} + +extern __inline__ unsigned long get_css_fp (struct thread_struct *t) +{ + if (t->save) + return t->save->fp; + else + return 0; +} + +asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call"); + +extern __inline__ void copy_thread_css (struct context_save_struct *save) +{ + save->r4 = + save->r5 = + save->r6 = + save->r7 = + save->r8 = + save->r9 = + save->fp = 0; + save->pc = ((unsigned long)ret_from_sys_call) | SVC26_MODE; +} + +#define start_thread(regs,pc,sp) \ +({ \ + unsigned long *stack = (unsigned long *)sp; \ + set_fs(USER_DS); \ + memzero(regs->uregs, sizeof (regs->uregs)); \ + regs->ARM_pc = pc; /* pc */ \ + regs->ARM_sp = sp; /* sp */ \ + regs->ARM_r2 = stack[2]; /* r2 (envp) */ \ + regs->ARM_r1 = stack[1]; /* r1 (argv) */ \ + regs->ARM_r0 = stack[0]; /* r0 (argc) */ \ + flush_tlb_mm(current->mm); \ +}) + +#endif + +#endif diff --git a/include/asm-arm/proc-armo/ptrace.h b/include/asm-arm/proc-armo/ptrace.h new file mode 100644 index 000000000..6468fb549 --- /dev/null +++ b/include/asm-arm/proc-armo/ptrace.h @@ -0,0 +1,65 @@ +/* + * linux/include/asm-arm/proc-armo/ptrace.h + * + * Copyright (C) 1996 Russell King + */ + +#ifndef __ASM_PROC_PTRACE_H +#define __ASM_PROC_PTRACE_H + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long uregs[17]; +}; + +#define ARM_pc uregs[15] +#define ARM_lr uregs[14] +#define ARM_sp uregs[13] +#define ARM_ip uregs[12] +#define ARM_fp uregs[11] +#define ARM_r10 uregs[10] +#define ARM_r9 uregs[9] +#define ARM_r8 uregs[8] +#define ARM_r7 uregs[7] +#define ARM_r6 uregs[6] +#define ARM_r5 uregs[5] +#define ARM_r4 uregs[4] +#define ARM_r3 uregs[3] +#define ARM_r2 uregs[2] +#define ARM_r1 uregs[1] +#define ARM_r0 uregs[0] +#define ARM_ORIG_r0 uregs[16] /* -1 */ + +#define USR26_MODE 0x00 +#define FIQ26_MODE 0x01 +#define IRQ26_MODE 0x02 +#define SVC26_MODE 0x03 +#define MODE_MASK 0x03 +#define F_BIT (1 << 26) +#define I_BIT (1 << 27) +#define CC_V_BIT (1 << 28) +#define CC_C_BIT (1 << 29) +#define CC_Z_BIT (1 << 30) +#define CC_N_BIT (1 << 31) + +#define user_mode(regs) \ + (((regs)->ARM_pc & MODE_MASK) == USR26_MODE) + +#define processor_mode(regs) \ + ((regs)->ARM_pc & MODE_MASK) + +#define interrupts_enabled(regs) \ + (!((regs)->ARM_pc & I_BIT)) + +#define fast_interrupts_enabled(regs) \ + (!((regs)->ARM_pc & F_BIT)) + +#define condition_codes(regs) \ + ((regs)->ARM_pc & (CC_V_BIT|CC_C_BIT|CC_Z_BIT|CC_N_BIT)) + +#define instruction_pointer(regs) ((regs)->ARM_pc & 0x03fffffc) +#define pc_pointer(v) ((v) & 0x03fffffc) +#endif + diff --git a/include/asm-arm/proc-armo/semaphore.h b/include/asm-arm/proc-armo/semaphore.h new file mode 100644 index 000000000..483803217 --- /dev/null +++ b/include/asm-arm/proc-armo/semaphore.h @@ -0,0 +1,83 @@ +/* + * linux/include/asm-arm/proc-armo/semaphore.h + */ +#ifndef __ASM_PROC_SEMAPHORE_H +#define __ASM_PROC_SEMAPHORE_H + +/* + * This is ugly, but we want the default case to fall through. + * "__down" is the actual routine that waits... + */ +extern inline void down(struct semaphore * sem) +{ + __asm__ __volatile__ (" + @ atomic down operation + mov r0, pc + orr r1, r0, #0x08000000 + and r0, r0, #0x0c000003 + teqp r1, #0 + ldr r1, [%0] + subs r1, r1, #1 + str r1, [%0] + mov r1, pc, lsr #28 + teqp r0, r1, lsl #28 + movmi r0, %0 + blmi " SYMBOL_NAME_STR(__down) + : : "r" (sem) : "r0", "r1", "r2", "r3", "ip", "lr", "cc"); +} + +/* + * This is ugly, but we want the default case to fall through. + * "__down_interruptible" is the actual routine that waits... + */ +extern inline int down_interruptible (struct semaphore * sem) +{ + int result; + __asm__ __volatile__ (" + @ atomic down operation + mov r0, pc + orr r1, r0, #0x08000000 + and r0, r0, #0x0c000003 + teqp r1, #0 + ldr r1, [%1] + subs r1, r1, #1 + str r1, [%1] + mov r1, pc, lsr #28 + orrmi r0, r0, #0x80000000 @ set N + teqp r0, r1, lsl #28 + movmi r0, %1 + movpl r0, #0 + blmi " SYMBOL_NAME_STR(__down_interruptible) " + mov %0, r0" + : "=r" (result) + : "r" (sem) + : "r0", "r1", "r2", "r3", "ip", "lr", "cc"); + return result; +} + +/* + * Note! This is subtle. We jump to wake people up only if + * the semaphore was negative (== somebody was waiting on it). + * The default case (no contention) will result in NO + * jumps for both down() and up(). + */ +extern inline void up(struct semaphore * sem) +{ + __asm__ __volatile__ (" + @ atomic up operation + mov r0, pc + orr r1, r0, #0x08000000 + and r0, r0, #0x0c000003 + teqp r1, #0 + ldr r1, [%0] + adds r1, r1, #1 + str r1, [%0] + mov r1, pc, lsr #28 + orrls r0, r0, #0x80000000 @ set N + teqp r0, r1, lsl #28 + movmi r0, %0 + blmi " SYMBOL_NAME_STR(__up) + : : "r" (sem) : "r0", "r1", "r2", "r3", "ip", "lr", "cc"); +} + +#endif diff --git a/include/asm-arm/proc-armo/shmparam.h b/include/asm-arm/proc-armo/shmparam.h new file mode 100644 index 000000000..e61096091 --- /dev/null +++ b/include/asm-arm/proc-armo/shmparam.h @@ -0,0 +1,18 @@ +/* + * linux/include/asm-arm/proc-armo/shmparam.h + * + * Copyright (C) 1996 Russell King + * + * definitions for the shared process memory on the ARM3 + */ + +#ifndef __ASM_PROC_SHMPARAM_H +#define __ASM_PROC_SHMPARAM_H + +#ifndef SHM_RANGE_START +#define SHM_RANGE_START 0x00a00000 +#define SHM_RANGE_END 0x00c00000 +#define SHMMAX 0x003fa000 +#endif + +#endif diff --git a/include/asm-arm/proc-armo/system.h b/include/asm-arm/proc-armo/system.h new file mode 100644 index 000000000..a1c2d01cb --- /dev/null +++ b/include/asm-arm/proc-armo/system.h @@ -0,0 +1,124 @@ +/* + * linux/include/asm-arm/proc-armo/system.h + * + * Copyright (C) 1995, 1996 Russell King + */ + +#ifndef __ASM_PROC_SYSTEM_H +#define __ASM_PROC_SYSTEM_H + +extern const char xchg_str[]; + +#include <asm/proc-fns.h> + +extern __inline__ unsigned long __xchg(unsigned long x, volatile void *ptr, int size) +{ + switch (size) { + case 1: return processor.u.armv2._xchg_1(x, ptr); + case 2: return processor.u.armv2._xchg_2(x, ptr); + case 4: return processor.u.armv2._xchg_4(x, ptr); + default: arm_invalidptr(xchg_str, size); + } +} + +/* + * We need to turn the caches off before calling the reset vector - RiscOS + * messes up if we don't + */ +#define proc_hard_reset() processor._proc_fin() + +/* + * This processor does not idle + */ +#define proc_idle() + +/* + * A couple of speedups for the ARM + */ + +/* + * Save the current interrupt enable state & disable IRQs + */ +#define __save_flags_cli(x) \ + do { \ + unsigned long temp; \ + __asm__ __volatile__( \ +" mov %0, pc\n" \ +" orr %1, %0, #0x08000000\n" \ +" and %0, %0, #0x0c000000\n" \ +" teqp %1, #0\n" \ + : "=r" (x), "=r" (temp) \ + : \ + : "memory"); \ + } while (0) + +/* + * Enable IRQs + */ +#define __sti() \ + do { \ + unsigned long temp; \ + __asm__ __volatile__( \ +" mov %0, pc\n" \ +" bic %0, %0, #0x08000000\n" \ +" teqp %0, #0\n" \ + : "=r" (temp) \ + : \ + : "memory"); \ + } while(0) + +/* + * Disable IRQs + */ +#define __cli() \ + do { \ + unsigned long temp; \ + __asm__ __volatile__( \ +" mov %0, pc\n" \ +" orr %0, %0, #0x08000000\n" \ +" teqp %0, #0\n" \ + : "=r" (temp) \ + : \ + : "memory"); \ + } while(0) + +/* + * save current IRQ & FIQ state + */ +#define __save_flags(x) \ + do { \ + __asm__ __volatile__( \ +" mov %0, pc\n" \ +" and %0, %0, #0x0c000000\n" \ + : "=r" (x)); \ + } while (0) + +/* + * restore saved IRQ & FIQ state + */ +#define __restore_flags(x) \ + do { \ + unsigned long temp; \ + __asm__ __volatile__( \ +" mov %0, pc\n" \ +" bic %0, %0, #0x0c000000\n" \ +" orr %0, %0, %1\n" \ +" teqp %0, #0\n" \ + : "=r" (temp) \ + : "r" (x) \ + : "memory"); \ + } while (0) + +#ifdef __SMP__ +#error SMP not supported +#else + +#define cli() __cli() +#define sti() __sti() +#define save_flags(x) __save_flags(x) +#define restore_flags(x) __restore_flags(x) +#define save_flags_cli(x) __save_flags_cli(x) + +#endif + +#endif diff --git a/include/asm-arm/proc-armo/uaccess.h b/include/asm-arm/proc-armo/uaccess.h new file mode 100644 index 000000000..8d5745aed --- /dev/null +++ b/include/asm-arm/proc-armo/uaccess.h @@ -0,0 +1,140 @@ +/* + * linux/include/asm-arm/proc-armo/segment.h + * + * Copyright (C) 1996 Russell King + */ + +/* + * The fs functions are implemented on the ARM2 and ARM3 architectures + * manually. + * Use *_user functions to access user memory with faulting behaving + * as though the user is accessing the memory. + * Use set_fs(get_ds()) and then the *_user functions to allow them to + * access kernel memory. + */ + +/* + * These are the values used to represent the user `fs' and the kernel `ds' + */ +#define KERNEL_DS 0x03000000 +#define USER_DS 0x02000000 + +#define get_ds() (KERNEL_DS) +#define get_fs() (current->addr_limit) +#define segment_eq(a,b) ((a) == (b)) + +extern uaccess_t uaccess_user, uaccess_kernel; + +extern __inline__ void set_fs (mm_segment_t fs) +{ + current->addr_limit = fs; + current->tss.uaccess = fs == USER_DS ? &uaccess_user : &uaccess_kernel; +} + +#define __range_ok(addr,size) ({ \ + unsigned long flag, sum; \ + __asm__ __volatile__("adds %1, %2, %3; cmpls %1, %0; movls %0, #0" \ + : "=&r" (flag), "=&r" (sum) \ + : "r" (addr), "Ir" (size), "0" (current->addr_limit) \ + : "cc"); \ + flag; }) + +#define __addr_ok(addr) ({ \ + unsigned long flag; \ + __asm__ __volatile__("cmp %2, %0; movlo %0, #0" \ + : "=&r" (flag) \ + : "0" (current->addr_limit), "r" (addr) \ + : "cc"); \ + (flag == 0); }) + +#define access_ok(type,addr,size) (__range_ok(addr,size) == 0) + +#define __put_user_asm_byte(x,addr,err) \ + __asm__ __volatile__( \ + " mov r0, %1\n" \ + " mov r1, %2\n" \ + " mov r2, %0\n" \ + " mov lr, pc\n" \ + " mov pc, %3\n" \ + " mov %0, r2\n" \ + : "=r" (err) \ + : "r" (x), "r" (addr), "r" (current->tss.uaccess->put_byte), \ + "0" (err) \ + : "r0", "r1", "r2", "lr") + +#define __put_user_asm_half(x,addr,err) \ + __asm__ __volatile__( \ + " mov r0, %1\n" \ + " mov r1, %2\n" \ + " mov r2, %0\n" \ + " mov lr, pc\n" \ + " mov pc, %3\n" \ + " mov %0, r2\n" \ + : "=r" (err) \ + : "r" (x), "r" (addr), "r" (current->tss.uaccess->put_half), \ + "0" (err) \ + : "r0", "r1", "r2", "lr") + +#define __put_user_asm_word(x,addr,err) \ + __asm__ __volatile__( \ + " mov r0, %1\n" \ + " mov r1, %2\n" \ + " mov r2, %0\n" \ + " mov lr, pc\n" \ + " mov pc, %3\n" \ + " mov %0, r2\n" \ + : "=r" (err) \ + : "r" (x), "r" (addr), "r" (current->tss.uaccess->put_word), \ + "0" (err) \ + : "r0", "r1", "r2", "lr") + +#define __get_user_asm_byte(x,addr,err) \ + __asm__ __volatile__( \ + " mov r0, %2\n" \ + " mov r1, %0\n" \ + " mov lr, pc\n" \ + " mov pc, %3\n" \ + " mov %0, r1\n" \ + " mov %1, r0\n" \ + : "=r" (err), "=r" (x) \ + : "r" (addr), "r" (current->tss.uaccess->get_byte), "0" (err) \ + : "r0", "r1", "r2", "lr") + +#define __get_user_asm_half(x,addr,err) \ + __asm__ __volatile__( \ + " mov r0, %2\n" \ + " mov r1, %0\n" \ + " mov lr, pc\n" \ + " mov pc, %3\n" \ + " mov %0, r1\n" \ + " mov %1, r0\n" \ + : "=r" (err), "=r" (x) \ + : "r" (addr), "r" (current->tss.uaccess->get_half), "0" (err) \ + : "r0", "r1", "r2", "lr") + +#define __get_user_asm_word(x,addr,err) \ + __asm__ __volatile__( \ + " mov r0, %2\n" \ + " mov r1, %0\n" \ + " mov lr, pc\n" \ + " mov pc, %3\n" \ + " mov %0, r1\n" \ + " mov %1, r0\n" \ + : "=r" (err), "=r" (x) \ + : "r" (addr), "r" (current->tss.uaccess->get_word), "0" (err) \ + : "r0", "r1", "r2", "lr") + +#define __do_copy_from_user(to,from,n) \ + (n) = current->tss.uaccess->copy_from_user((to),(from),(n)) + +#define __do_copy_to_user(to,from,n) \ + (n) = current->tss.uaccess->copy_to_user((to),(from),(n)) + +#define __do_clear_user(addr,sz) \ + (sz) = current->tss.uaccess->clear_user((addr),(sz)) + +#define __do_strncpy_from_user(dst,src,count,res) \ + (res) = current->tss.uaccess->strncpy_from_user(dst,src,count) + +#define __do_strlen_user(s,res) \ + (res) = current->tss.uaccess->strlen_user(s) diff --git a/include/asm-arm/proc-armo/uncompress.h b/include/asm-arm/proc-armo/uncompress.h new file mode 100644 index 000000000..b4edb06f7 --- /dev/null +++ b/include/asm-arm/proc-armo/uncompress.h @@ -0,0 +1,7 @@ +/* + * linux/include/asm-arm/proc-armo/uncompress.h + * + * (c) 1997 Russell King + */ + +#define proc_decomp_setup() diff --git a/include/asm-arm/proc-armv/assembler.h b/include/asm-arm/proc-armv/assembler.h new file mode 100644 index 000000000..2294981c3 --- /dev/null +++ b/include/asm-arm/proc-armv/assembler.h @@ -0,0 +1,84 @@ +/* + * linux/asm-arm/proc-armv/assembler.h + * + * Copyright (C) 1996 Russell King + * + * This file contains arm architecture specific defines + * for the different processors + */ + +/* + * LOADREGS: multiple register load (ldm) with pc in register list + * (takes account of ARM6 not using ^) + * + * RETINSTR: return instruction: adds the 's' in at the end of the + * instruction if this is not an ARM6 + * + * SAVEIRQS: save IRQ state (not required on ARM2/ARM3 - done + * implicitly + * + * RESTOREIRQS: restore IRQ state (not required on ARM2/ARM3 - done + * implicitly with ldm ... ^ or movs. + * + * These next two need thinking about - can't easily use stack... (see system.S) + * DISABLEIRQS: disable IRQS in SVC mode + * + * ENABLEIRQS: enable IRQS in SVC mode + * + * USERMODE: switch to USER mode + * + * SVCMODE: switch to SVC mode + */ + +#define N_BIT (1 << 31) +#define Z_BIT (1 << 30) +#define C_BIT (1 << 29) +#define V_BIT (1 << 28) + +#define PCMASK 0 + +#ifdef __ASSEMBLER__ + +#define I_BIT (1 << 7) +#define F_BIT (1 << 6) + +#define MODE_FIQ26 0x01 +#define MODE_FIQ32 0x11 + +#define DEFAULT_FIQ MODE_FIQ32 + +#define LOADREGS(cond, base, reglist...)\ + ldm##cond base,reglist + +#define RETINSTR(instr, regs...)\ + instr regs + +#define MODENOP + +#define MODE(savereg,tmpreg,mode) \ + mrs savereg, cpsr; \ + bic tmpreg, savereg, $0x1f; \ + orr tmpreg, tmpreg, $mode; \ + msr cpsr, tmpreg + +#define RESTOREMODE(savereg) \ + msr cpsr, savereg + +#define SAVEIRQS(tmpreg)\ + mrs tmpreg, cpsr; \ + str tmpreg, [sp, $-4]! + +#define RESTOREIRQS(tmpreg)\ + ldr tmpreg, [sp], $4; \ + msr cpsr, tmpreg + +#define DISABLEIRQS(tmpreg)\ + mrs tmpreg , cpsr; \ + orr tmpreg , tmpreg , $I_BIT; \ + msr cpsr, tmpreg + +#define ENABLEIRQS(tmpreg)\ + mrs tmpreg , cpsr; \ + bic tmpreg , tmpreg , $I_BIT; \ + msr cpsr, tmpreg +#endif diff --git a/include/asm-arm/proc-armv/mm-init.h b/include/asm-arm/proc-armv/mm-init.h new file mode 100644 index 000000000..0ffb05a16 --- /dev/null +++ b/include/asm-arm/proc-armv/mm-init.h @@ -0,0 +1,118 @@ +/* + * linux/include/asm-arm/proc-armv/mm-init.h + * + * Copyright (C) 1996 Russell King + * + * This contains the code to setup the memory map on an ARM v3 or v4 machine. + * This is both processor & architecture specific, and requires some + * more work to get it to fit into our separate processor and architecture + * structure. + */ + +/* + * On ebsa, we want the memory map set up so: + * + * PHYS VIRT + * 00000000 00000000 Zero page + * 000003ff 000003ff Zero page end + * 00000000 c0000000 Kernel and all physical memory + * 01ffffff c1ffffff End of physical (32MB) + * e0000000 e0000000 IO start + * ffffffff ffffffff IO end + * + * On rpc, we want: + * + * PHYS VIRT + * 10000000 00000000 Zero page + * 100003ff 000003ff Zero page end + * 10000000 c0000000 Kernel and all physical memory + * 1fffffff cfffffff End of physical (32MB) + * 02000000 d?000000 Screen memory (first image) + * 02000000 d8000000 Screen memory (second image) + * 00000000 df000000 StrongARM cache invalidation area + * 03000000 e0000000 IO start + * 03ffffff e0ffffff IO end + * + * We set it up using the section page table entries. + */ + +#include <asm/arch/mmap.h> +#include <asm/pgtable.h> + +#define V2P(x) virt_to_phys(x) +#define PTE_SIZE (PTRS_PER_PTE * 4) + +#define PMD_SECT (PMD_TYPE_SECT | PMD_DOMAIN(DOMAIN_KERNEL) | PMD_SECT_CACHEABLE) + +static inline void setup_swapper_dir (int index, unsigned long entry) +{ + pmd_t pmd; + + pmd_val(pmd) = entry; + set_pmd (pmd_offset (swapper_pg_dir + index, 0), pmd); +} + +static inline unsigned long setup_pagetables(unsigned long start_mem, unsigned long end_mem) +{ + unsigned long address; + unsigned int spi; + union { unsigned long l; unsigned long *p; } u; + + /* map in zero page */ + u.l = ((start_mem + (PTE_SIZE-1)) & ~(PTE_SIZE-1)); + start_mem = u.l + PTE_SIZE; + memzero (u.p, PTE_SIZE); + *u.p = V2P(PAGE_OFFSET) | PTE_CACHEABLE | PTE_TYPE_SMALL; + setup_swapper_dir (0, V2P(u.l) | PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_USER)); + + for (spi = 1; spi < (PAGE_OFFSET >> PGDIR_SHIFT); spi++) + pgd_val(swapper_pg_dir[spi]) = 0; + + /* map in physical ram & kernel */ + address = PAGE_OFFSET; + while (spi < end_mem >> PGDIR_SHIFT) { + setup_swapper_dir (spi++, + V2P(address) | PMD_SECT | + PMD_SECT_BUFFERABLE | PMD_SECT_AP_WRITE); + address += PGDIR_SIZE; + } + while (spi < PTRS_PER_PGD) + pgd_val(swapper_pg_dir[spi++]) = 0; + + /* + * An area to invalidate the cache + */ + setup_swapper_dir (0xdf0, SAFE_ADDR | PMD_SECT | PMD_SECT_AP_READ); + + /* map in IO */ + address = IO_START; + spi = IO_BASE >> PGDIR_SHIFT; + pgd_val(swapper_pg_dir[spi-1]) = 0xc0000000 | PMD_TYPE_SECT | + PMD_DOMAIN(DOMAIN_KERNEL) | PMD_SECT_AP_WRITE; + while (address < IO_START + IO_SIZE && address) { + pgd_val(swapper_pg_dir[spi++]) = address | + PMD_TYPE_SECT | PMD_DOMAIN(DOMAIN_IO) | + PMD_SECT_AP_WRITE; + address += PGDIR_SIZE; + } + +#ifdef HAVE_MAP_VID_MEM + map_screen_mem(0, 0, 0); +#endif + + flush_cache_all(); + return start_mem; +} + +static inline void mark_usable_memory_areas(unsigned long *start_mem, unsigned long end_mem) +{ + unsigned long smem; + + *start_mem = smem = PAGE_ALIGN(*start_mem); + + while (smem < end_mem) { + clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags); + smem += PAGE_SIZE; + } +} + diff --git a/include/asm-arm/proc-armv/page.h b/include/asm-arm/proc-armv/page.h new file mode 100644 index 000000000..fd8768939 --- /dev/null +++ b/include/asm-arm/proc-armv/page.h @@ -0,0 +1,68 @@ +/* + * linux/include/asm-arm/proc-armv/page.h + * + * Copyright (C) 1995, 1996 Russell King + */ + +#ifndef __ASM_PROC_PAGE_H +#define __ASM_PROC_PAGE_H + +/* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#ifdef __KERNEL__ + +#define STRICT_MM_TYPECHECKS + +#ifdef STRICT_MM_TYPECHECKS +/* + * These are used to make use of C type-checking.. + */ +typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long pmd; } pmd_t; +typedef struct { unsigned long pgd; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; + +#define pte_val(x) ((x).pte) +#define pmd_val(x) ((x).pmd) +#define pgd_val(x) ((x).pgd) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgd(x) ((pgd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +#else +/* + * .. while these make it easier on the compiler + */ +typedef unsigned long pte_t; +typedef unsigned long pmd_t; +typedef unsigned long pgd_t; +typedef unsigned long pgprot_t; + +#define pte_val(x) (x) +#define pmd_val(x) (x) +#define pgd_val(x) (x) +#define pgprot_val(x) (x) + +#define __pte(x) (x) +#define __pmd(x) (x) +#define __pgd(x) (x) +#define __pgprot(x) (x) + +#endif + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +/* This handles the memory map.. */ +#define PAGE_OFFSET 0xc0000000 +#define MAP_NR(addr) (((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT) + +#endif /* __KERNEL__ */ + +#endif /* __ASM_PROC_PAGE_H */ diff --git a/include/asm-arm/proc-armv/param.h b/include/asm-arm/proc-armv/param.h new file mode 100644 index 000000000..fa22ce2d3 --- /dev/null +++ b/include/asm-arm/proc-armv/param.h @@ -0,0 +1,27 @@ +/* + * linux/include/asm-arm/proc-armv/param.h + * + * Copyright (C) 1996 Russell King + */ + +#ifndef __ASM_PROC_PARAM_H +#define __ASM_PROC_PARAM_H + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 4096 + +#ifndef NGROUPS +#define NGROUPS 32 +#endif + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif + diff --git a/include/asm-arm/proc-armv/pgtable.h b/include/asm-arm/proc-armv/pgtable.h new file mode 100644 index 000000000..5816b2698 --- /dev/null +++ b/include/asm-arm/proc-armv/pgtable.h @@ -0,0 +1,617 @@ +/* + * linux/include/asm-arm/proc-armv/pgtable.h + * + * Copyright (C) 1995, 1996, 1997 Russell King + * + * 12-01-1997 RMK Altered flushing routines to use function pointers + * now possible to combine ARM6, ARM7 and StrongARM versions. + */ +#ifndef __ASM_PROC_PGTABLE_H +#define __ASM_PROC_PGTABLE_H + +#include <asm/arch/mmu.h> + +#define LIBRARY_TEXT_START 0x0c000000 + +/* + * Cache flushing... + */ +#define flush_cache_all() \ + processor.u.armv3v4._flush_cache_all() + +#define flush_cache_mm(_mm) \ + do { \ + if ((_mm) == current->mm) \ + processor.u.armv3v4._flush_cache_all(); \ + } while (0) + +#define flush_cache_range(_mm,_start,_end) \ + do { \ + if ((_mm) == current->mm) \ + processor.u.armv3v4._flush_cache_area \ + ((_start), (_end), 1); \ + } while (0) + +#define flush_cache_page(_vma,_vmaddr) \ + do { \ + if ((_vma)->vm_mm == current->mm) \ + processor.u.armv3v4._flush_cache_area \ + ((_vmaddr), (_vmaddr) + PAGE_SIZE, \ + ((_vma)->vm_flags & VM_EXEC) ? 1 : 0); \ + } while (0) + +#define flush_icache_range(_start,_end) \ + processor.u.armv3v4._flush_icache_area((_start), (_end)) + +/* + * We don't have a mem map cache... + */ +#define update_mm_cache_all() do { } while (0) +#define update_mm_cache_task(tsk) do { } while (0) +#define update_mm_cache_mm(mm) do { } while (0) +#define update_mm_cache_mm_addr(mm,addr,pte) do { } while (0) + +/* + * This flushes back any buffered write data. We have to clean and flush the entries + * in the cache for this page. Is it necessary to invalidate the I-cache? + */ +#define flush_page_to_ram(_page) \ + processor.u.armv3v4._flush_ram_page ((_page) & PAGE_MASK); + +/* + * Make the page uncacheable (must flush page beforehand). + */ +#define uncache_page(_page) \ + processor.u.armv3v4._flush_ram_page ((_page) & PAGE_MASK); + +/* + * TLB flushing: + * + * - flush_tlb() flushes the current mm struct TLBs + * - flush_tlb_all() flushes all processes TLBs + * - flush_tlb_mm(mm) flushes the specified mm context TLB's + * - flush_tlb_page(vma, vmaddr) flushes one page + * - flush_tlb_range(mm, start, end) flushes a range of pages + * + * GCC uses conditional instructions, and expects the assembler code to do so as well. + * + * We drain the write buffer in here to ensure that the page tables in ram + * are really up to date. It is more efficient to do this here... + */ +#define flush_tlb() flush_tlb_all() + +#define flush_tlb_all() \ + processor.u.armv3v4._flush_tlb_all() + +#define flush_tlb_mm(_mm) \ + do { \ + if ((_mm) == current->mm) \ + processor.u.armv3v4._flush_tlb_all(); \ + } while (0) + +#define flush_tlb_range(_mm,_start,_end) \ + do { \ + if ((_mm) == current->mm) \ + processor.u.armv3v4._flush_tlb_area \ + ((_start), (_end), 1); \ + } while (0) + +#define flush_tlb_page(_vma,_vmaddr) \ + do { \ + if ((_vma)->vm_mm == current->mm) \ + processor.u.armv3v4._flush_tlb_area \ + ((_vmaddr), (_vmaddr) + PAGE_SIZE, \ + ((_vma)->vm_flags & VM_EXEC) ? 1 : 0); \ + } while (0) + +/* + * Since the page tables are in cached memory, we need to flush the dirty + * data cached entries back before we flush the tlb... This is also useful + * to flush out the SWI instruction for signal handlers... + */ +#define __flush_entry_to_ram(entry) \ + processor.u.armv3v4._flush_cache_entry((unsigned long)(entry)) + +#define __flush_pte_to_ram(entry) \ + processor.u.armv3v4._flush_cache_pte((unsigned long)(entry)) + +/* PMD_SHIFT determines the size of the area a second-level page table can map */ +#define PMD_SHIFT 20 +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) + +/* PGDIR_SHIFT determines what a third-level page table entry can map */ +#define PGDIR_SHIFT 20 +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) + +/* + * entries per page directory level: the sa110 is two-level, so + * we don't really have any PMD directory physically. + */ +#define PTRS_PER_PTE 256 +#define PTRS_PER_PMD 1 +#define PTRS_PER_PGD 4096 + +/* Just any arbitrary offset to the start of the vmalloc VM area: the + * current 8MB value just means that there will be a 8MB "hole" after the + * physical memory until the kernel virtual memory starts. That means that + * any out-of-bounds memory accesses will hopefully be caught. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) + */ +#define VMALLOC_OFFSET (8*1024*1024) +#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) + +/* PMD types (actually level 1 descriptor) */ +#define PMD_TYPE_MASK 0x0003 +#define PMD_TYPE_FAULT 0x0000 +#define PMD_TYPE_TABLE 0x0001 +#define PMD_TYPE_SECT 0x0002 +#define PMD_UPDATABLE 0x0010 +#define PMD_SECT_CACHEABLE 0x0008 +#define PMD_SECT_BUFFERABLE 0x0004 +#define PMD_SECT_AP_WRITE 0x0400 +#define PMD_SECT_AP_READ 0x0800 +#define PMD_DOMAIN(x) ((x) << 5) + +/* PTE types (actially level 2 descriptor) */ +#define PTE_TYPE_MASK 0x0003 +#define PTE_TYPE_FAULT 0x0000 +#define PTE_TYPE_LARGE 0x0001 +#define PTE_TYPE_SMALL 0x0002 +#define PTE_AP_READ 0x0aa0 +#define PTE_AP_WRITE 0x0550 +#define PTE_CACHEABLE 0x0008 +#define PTE_BUFFERABLE 0x0004 + +/* Domains */ +#define DOMAIN_USER 0 +#define DOMAIN_KERNEL 1 +#define DOMAIN_TABLE 1 +#define DOMAIN_IO 2 + +#define _PAGE_CHG_MASK (0xfffff00c | PTE_TYPE_MASK) + +/* + * We define the bits in the page tables as follows: + * PTE_BUFFERABLE page is dirty + * PTE_AP_WRITE page is writable + * PTE_AP_READ page is a young (unsetting this causes faults for any access) + * + * Any page that is mapped in is assumed to be readable... + */ +#define PAGE_NONE __pgprot(PTE_TYPE_SMALL) +#define PAGE_SHARED __pgprot(PTE_TYPE_SMALL | PTE_CACHEABLE | PTE_AP_READ | PTE_AP_WRITE) +#define PAGE_COPY __pgprot(PTE_TYPE_SMALL | PTE_CACHEABLE | PTE_AP_READ) +#define PAGE_READONLY __pgprot(PTE_TYPE_SMALL | PTE_CACHEABLE | PTE_AP_READ) +#define PAGE_KERNEL __pgprot(PTE_TYPE_SMALL | PTE_CACHEABLE | PTE_BUFFERABLE | PTE_AP_WRITE) + +#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_USER)) +#define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_KERNEL)) + +/* + * The arm can't do page protection for execute, and considers that the same are read. + * Also, write permissions imply read permissions. This is the closest we can get.. + */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY +#define __P101 PAGE_READONLY +#define __P110 PAGE_COPY +#define __P111 PAGE_COPY + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY +#define __S101 PAGE_READONLY +#define __S110 PAGE_SHARED +#define __S111 PAGE_SHARED + +#undef TEST_VERIFY_AREA + +/* + * BAD_PAGETABLE is used when we need a bogus page-table, while + * BAD_PAGE is used for a bogus page. + * + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +extern pte_t __bad_page(void); +extern pte_t * __bad_pagetable(void); +extern unsigned long *empty_zero_page; + +#define BAD_PAGETABLE __bad_pagetable() +#define BAD_PAGE __bad_page() +#define ZERO_PAGE ((unsigned long) empty_zero_page) + +/* number of bits that fit into a memory pointer */ +#define BYTES_PER_PTR (sizeof(unsigned long)) +#define BITS_PER_PTR (8*BYTES_PER_PTR) + +/* to align the pointer to a pointer address */ +#define PTR_MASK (~(sizeof(void*)-1)) + +/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */ +#define SIZEOF_PTR_LOG2 2 + +/* to find an entry in a page-table */ +#define PAGE_PTR(address) \ +((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) + +/* to set the page-dir */ +#define SET_PAGE_DIR(tsk,pgdir) \ +do { \ + tsk->tss.memmap = __virt_to_phys(pgdir); \ + if ((tsk) == current) \ + __asm__ __volatile__( \ + "mcr%? p15, 0, %0, c2, c0, 0\n" \ + : : "r" (tsk->tss.memmap)); \ +} while (0) + +extern __inline__ int pte_none(pte_t pte) +{ + return !pte_val(pte); +} + +#define pte_clear(ptep) set_pte(ptep, __pte(0)) + +extern __inline__ int pte_present(pte_t pte) +{ + switch (pte_val(pte) & PTE_TYPE_MASK) { + case PTE_TYPE_LARGE: + case PTE_TYPE_SMALL: + return 1; + default: + return 0; + } +} + +extern __inline__ int pmd_none(pmd_t pmd) +{ + return !pmd_val(pmd); +} + +#define pmd_clear(pmdp) set_pmd(pmdp, __pmd(0)) + +extern __inline__ int pmd_bad(pmd_t pmd) +{ + switch (pmd_val(pmd) & PMD_TYPE_MASK) { + case PMD_TYPE_FAULT: + case PMD_TYPE_TABLE: + return 0; + default: + return 1; + } +} + +extern __inline__ int pmd_present(pmd_t pmd) +{ + switch (pmd_val(pmd) & PMD_TYPE_MASK) { + case PMD_TYPE_TABLE: + return 1; + default: + return 0; + } +} + +/* + * The "pgd_xxx()" functions here are trivial for a folded two-level + * setup: the pgd is never bad, and a pmd always exists (as it's folded + * into the pgd entry) + */ +#define pgd_none(pgd) (0) +#define pgd_bad(pgd) (0) +#define pgd_present(pgd) (1) +#define pgd_clear(pgdp) + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +#define pte_read(pte) (1) +#define pte_exec(pte) (1) + +extern __inline__ int pte_write(pte_t pte) +{ + return pte_val(pte) & PTE_AP_WRITE; +} + +extern __inline__ int pte_cacheable(pte_t pte) +{ + return pte_val(pte) & PTE_CACHEABLE; +} + +extern __inline__ int pte_dirty(pte_t pte) +{ + return pte_val(pte) & PTE_BUFFERABLE; +} + +extern __inline__ int pte_young(pte_t pte) +{ + return pte_val(pte) & PTE_AP_READ; +} + +extern __inline__ pte_t pte_wrprotect(pte_t pte) +{ + pte_val(pte) &= ~PTE_AP_WRITE; + return pte; +} + +extern __inline__ pte_t pte_nocache(pte_t pte) +{ + pte_val(pte) &= ~PTE_CACHEABLE; + return pte; +} + +extern __inline__ pte_t pte_mkclean(pte_t pte) +{ + pte_val(pte) &= ~PTE_BUFFERABLE; + return pte; +} + +extern __inline__ pte_t pte_mkold(pte_t pte) +{ + pte_val(pte) &= ~PTE_AP_READ; + return pte; +} + +extern __inline__ pte_t pte_mkwrite(pte_t pte) +{ + pte_val(pte) |= PTE_AP_WRITE; + return pte; +} + +extern __inline__ pte_t pte_mkdirty(pte_t pte) +{ + pte_val(pte) |= PTE_BUFFERABLE; + return pte; +} + +extern __inline__ pte_t pte_mkyoung(pte_t pte) +{ + pte_val(pte) |= PTE_AP_READ; + return pte; +} + +/* + * The following are unable to be implemented on this MMU + */ +#if 0 +extern __inline__ pte_t pte_rdprotect(pte_t pte) +{ + pte_val(pte) &= ~(PTE_CACHEABLE|PTE_AP_READ); + return pte; +} + +extern __inline__ pte_t pte_exprotect(pte_t pte) +{ + pte_val(pte) &= ~(PTE_CACHEABLE|PTE_AP_READ); + return pte; +} + +extern __inline__ pte_t pte_mkread(pte_t pte) +{ + pte_val(pte) |= PTE_CACHEABLE; + return pte; +} + +extern __inline__ pte_t pte_mkexec(pte_t pte) +{ + pte_val(pte) |= PTE_CACHEABLE; + return pte; +} +#endif + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ +extern __inline__ pte_t mk_pte(unsigned long page, pgprot_t pgprot) +{ + pte_t pte; + pte_val(pte) = __virt_to_phys(page) | pgprot_val(pgprot); + return pte; +} + +/* This takes a physical page address that is used by the remapping functions */ +extern __inline__ pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) +{ + pte_t pte; + pte_val(pte) = physpage + pgprot_val(pgprot); + return pte; +} + +extern __inline__ pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); + return pte; +} + +extern __inline__ void set_pte(pte_t *pteptr, pte_t pteval) +{ + *pteptr = pteval; + __flush_pte_to_ram(pteptr); +} + +extern __inline__ unsigned long pte_page(pte_t pte) +{ + return (unsigned long)phys_to_virt(pte_val(pte) & PAGE_MASK); +} + +extern __inline__ pmd_t mk_user_pmd(pte_t *ptep) +{ + pmd_t pmd; + pmd_val(pmd) = __virt_to_phys((unsigned long)ptep) | _PAGE_USER_TABLE; + return pmd; +} + +extern __inline__ pmd_t mk_kernel_pmd(pte_t *ptep) +{ + pmd_t pmd; + pmd_val(pmd) = __virt_to_phys((unsigned long)ptep) | _PAGE_KERNEL_TABLE; + return pmd; +} + +#if 1 +#define set_pmd(pmdp,pmd) processor.u.armv3v4._set_pmd(pmdp,pmd) +#else +extern __inline__ void set_pmd(pmd_t *pmdp, pmd_t pmd) +{ + *pmdp = pmd; + __flush_pte_to_ram(pmdp); +} +#endif + +extern __inline__ unsigned long pmd_page(pmd_t pmd) +{ + return (unsigned long)phys_to_virt(pmd_val(pmd) & 0xfffffc00); +} + +/* to find an entry in a kernel page-table-directory */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) + +/* to find an entry in a page-table-directory */ +extern __inline__ pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) +{ + return mm->pgd + (address >> PGDIR_SHIFT); +} + +/* Find an entry in the second-level page table.. */ +#define pmd_offset(dir, address) ((pmd_t *)(dir)) + +/* Find an entry in the third-level page table.. */ +extern __inline__ pte_t * pte_offset(pmd_t * dir, unsigned long address) +{ + return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); +} + +extern unsigned long get_small_page(int priority); +extern void free_small_page(unsigned long page); + +/* + * Allocate and free page tables. The xxx_kernel() versions are + * used to allocate a kernel page table - this turns on ASN bits + * if any. + */ +extern __inline__ void pte_free_kernel(pte_t * pte) +{ + free_small_page((unsigned long) pte); +} + +extern const char bad_pmd_string[]; + +extern __inline__ pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address) +{ + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); + if (pmd_none(*pmd)) { + pte_t *page = (pte_t *) get_small_page(GFP_KERNEL); + if (pmd_none(*pmd)) { + if (page) { + memzero (page, PTRS_PER_PTE * BYTES_PER_PTR); + set_pmd(pmd, mk_kernel_pmd(page)); + return page + address; + } + set_pmd(pmd, mk_kernel_pmd(BAD_PAGETABLE)); + return NULL; + } + free_small_page((unsigned long) page); + } + if (pmd_bad(*pmd)) { + printk(bad_pmd_string, pmd_val(*pmd)); + set_pmd(pmd, mk_kernel_pmd(BAD_PAGETABLE)); + return NULL; + } + return (pte_t *) pmd_page(*pmd) + address; +} + +/* + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. + */ +#define pmd_free_kernel(pmdp) pmd_val(*(pmdp)) = 0; +#define pmd_alloc_kernel(pgdp, address) ((pmd_t *)(pgdp)) + +extern __inline__ void pte_free(pte_t * pte) +{ + free_small_page((unsigned long) pte); +} + +extern __inline__ pte_t * pte_alloc(pmd_t * pmd, unsigned long address) +{ + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); + + if (pmd_none(*pmd)) { + pte_t *page = (pte_t *) get_small_page(GFP_KERNEL); + if (pmd_none(*pmd)) { + if (page) { + memzero (page, PTRS_PER_PTE * BYTES_PER_PTR); + set_pmd(pmd, mk_user_pmd(page)); + return page + address; + } + set_pmd(pmd, mk_user_pmd(BAD_PAGETABLE)); + return NULL; + } + free_small_page ((unsigned long) page); + } + if (pmd_bad(*pmd)) { + printk(bad_pmd_string, pmd_val(*pmd)); + set_pmd(pmd, mk_user_pmd(BAD_PAGETABLE)); + return NULL; + } + return (pte_t *) pmd_page(*pmd) + address; +} + +/* + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. + */ +#define pmd_free(pmdp) pmd_val(*(pmdp)) = 0; +#define pmd_alloc(pgdp, address) ((pmd_t *)(pgdp)) + +/* + * Free a page directory. Takes the virtual address. + */ +extern __inline__ void pgd_free(pgd_t * pgd) +{ + free_pages((unsigned long) pgd, 2); +} + +/* + * Allocate a new page directory. Return the virtual address of it. + */ +extern __inline__ pgd_t * pgd_alloc(void) +{ + unsigned long pgd; + + /* + * need to get a 16k page for level 1 + */ + pgd = __get_free_pages(GFP_KERNEL,2,0); + if (pgd) + memzero ((void *)pgd, PTRS_PER_PGD * BYTES_PER_PTR); + return (pgd_t *)pgd; +} + +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; + +/* + * The sa110 doesn't have any external MMU info: the kernel page + * tables contain all the necessary information. + */ +extern __inline__ void update_mmu_cache(struct vm_area_struct * vma, + unsigned long address, pte_t pte) +{ +} + +#define SWP_TYPE(entry) (((entry) >> 2) & 0x7f) +#define SWP_OFFSET(entry) ((entry) >> 9) +#define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << 9)) + +#endif /* __ASM_PROC_PAGE_H */ + diff --git a/include/asm-arm/proc-armv/processor.h b/include/asm-arm/proc-armv/processor.h new file mode 100644 index 000000000..cc2be2ceb --- /dev/null +++ b/include/asm-arm/proc-armv/processor.h @@ -0,0 +1,103 @@ +/* + * linux/include/asm-arm/proc-armv/processor.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 20-09-1996 RMK Created + * 26-09-1996 RMK Added 'EXTRA_THREAD_STRUCT*' + * 28-09-1996 RMK Moved start_thread into the processor dependencies + */ +#ifndef __ASM_PROC_PROCESSOR_H +#define __ASM_PROC_PROCESSOR_H + +#ifdef __KERNEL__ + +#define KERNEL_STACK_SIZE PAGE_SIZE + +/* + * on arm2,3 wp does not work + */ +#define wp_works_ok 0 +#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ + +struct context_save_struct { + unsigned long cpsr; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long fp; + unsigned long pc; +}; + +#define EXTRA_THREAD_STRUCT \ + struct context_save_struct *save; \ + unsigned long memmap; + +#define EXTRA_THREAD_STRUCT_INIT \ + 0, \ + ((unsigned long) swapper_pg_dir) - PAGE_OFFSET + +DECLARE_THREAD_STRUCT; + +/* + * Return saved PC of a blocked thread. + */ +extern __inline__ unsigned long thread_saved_pc (struct thread_struct *t) +{ + if (t->save) + return t->save->pc; + else + return 0; +} + +extern __inline__ unsigned long get_css_fp (struct thread_struct *t) +{ + if (t->save) + return t->save->fp; + else + return 0; +} + +asmlinkage void ret_from_sys_call(void) __asm__ ("ret_from_sys_call"); + +extern __inline__ void copy_thread_css (struct context_save_struct *save) +{ + save->cpsr = SVC_MODE; + save->r4 = + save->r5 = + save->r6 = + save->r7 = + save->r8 = + save->r9 = + save->fp = 0; + save->pc = (unsigned long) ret_from_sys_call; +} + +#define start_thread(regs,pc,sp) \ +({ \ + unsigned long *stack = (unsigned long *)sp; \ + set_fs(USER_DS); \ + memzero(regs->uregs, sizeof(regs->uregs)); \ + regs->ARM_cpsr = sp <= 0x04000000 ? USR26_MODE : USR_MODE; \ + regs->ARM_pc = pc; /* pc */ \ + regs->ARM_sp = sp; /* sp */ \ + regs->ARM_r2 = stack[2]; /* r2 (envp) */ \ + regs->ARM_r1 = stack[1]; /* r1 (argv) */ \ + regs->ARM_r0 = stack[0]; /* r0 (argc) */ \ +}) + +/* Allocation and freeing of basic task resources. */ +/* + * NOTE! The task struct and the stack go together + */ +#define alloc_task_struct() \ + ((struct task_struct *) __get_free_pages(GFP_KERNEL,1,0)) +#define free_task_struct(p) free_pages((unsigned long)(p),1) + +#endif + +#endif diff --git a/include/asm-arm/proc-armv/ptrace.h b/include/asm-arm/proc-armv/ptrace.h new file mode 100644 index 000000000..42a56433f --- /dev/null +++ b/include/asm-arm/proc-armv/ptrace.h @@ -0,0 +1,75 @@ +/* + * linux/include/asm-arm/proc-armv/ptrace.h + * + * Copyright (C) 1996 Russell King + */ + +#ifndef __ASM_PROC_PTRACE_H +#define __ASM_PROC_PTRACE_H + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long uregs[18]; +}; + +#define ARM_cpsr uregs[16] +#define ARM_pc uregs[15] +#define ARM_lr uregs[14] +#define ARM_sp uregs[13] +#define ARM_ip uregs[12] +#define ARM_fp uregs[11] +#define ARM_r10 uregs[10] +#define ARM_r9 uregs[9] +#define ARM_r8 uregs[8] +#define ARM_r7 uregs[7] +#define ARM_r6 uregs[6] +#define ARM_r5 uregs[5] +#define ARM_r4 uregs[4] +#define ARM_r3 uregs[3] +#define ARM_r2 uregs[2] +#define ARM_r1 uregs[1] +#define ARM_r0 uregs[0] +#define ARM_ORIG_r0 uregs[17] /* -1 */ + +#define USR26_MODE 0x00 +#define FIQ26_MODE 0x01 +#define IRQ26_MODE 0x02 +#define SVC26_MODE 0x03 +#define USR_MODE 0x10 +#define FIQ_MODE 0x11 +#define IRQ_MODE 0x12 +#define SVC_MODE 0x13 +#define ABT_MODE 0x17 +#define UND_MODE 0x1b +#define SYSTEM_MODE 0x1f +#define MODE_MASK 0x1f +#define F_BIT 0x40 +#define I_BIT 0x80 +#define CC_V_BIT (1 << 28) +#define CC_C_BIT (1 << 29) +#define CC_Z_BIT (1 << 30) +#define CC_N_BIT (1 << 31) + +#define user_mode(regs) \ + ((((regs)->ARM_cpsr & MODE_MASK) == USR_MODE) || \ + (((regs)->ARM_cpsr & MODE_MASK) == USR26_MODE)) + +#define processor_mode(regs) \ + ((regs)->ARM_cpsr & MODE_MASK) + +#define interrupts_enabled(regs) \ + (!((regs)->ARM_cpsr & I_BIT)) + +#define fast_interrupts_enabled(regs) \ + (!((regs)->ARM_cpsr & F_BIT)) + +#define condition_codes(regs) \ + ((regs)->ARM_cpsr & (CC_V_BIT|CC_C_BIT|CC_Z_BIT|CC_N_BIT)) + +#define instruction_pointer(regs) ((regs)->ARM_pc) +#define pc_pointer(v) (v) + +#endif + diff --git a/include/asm-arm/proc-armv/semaphore.h b/include/asm-arm/proc-armv/semaphore.h new file mode 100644 index 000000000..fb1ad746f --- /dev/null +++ b/include/asm-arm/proc-armv/semaphore.h @@ -0,0 +1,81 @@ +/* + * linux/include/asm-arm/semaphore.h + */ +#ifndef __ASM_PROC_SEMAPHORE_H +#define __ASM_PROC_SEMAPHORE_H + +/* + * This is ugly, but we want the default case to fall through. + * "__down" is the actual routine that waits... + */ +extern inline void down(struct semaphore * sem) +{ + __asm__ __volatile__ (" + @ atomic down operation + mrs r0, cpsr + orr r1, r0, #128 @ disable IRQs + bic r0, r0, #0x80000000 @ clear N + msr cpsr, r1 + ldr r1, [%0] + subs r1, r1, #1 + str r1, [%0] + orrmi r0, r0, #0x80000000 @ set N + msr cpsr, r0 + movmi r0, %0 + blmi " SYMBOL_NAME_STR(__down) + : : "r" (sem) : "r0", "r1", "r2", "r3", "ip", "lr", "cc"); +} + +/* + * This is ugly, but we want the default case to fall through. + * "__down_interruptible" is the actual routine that waits... + */ +extern inline int down_interruptible (struct semaphore * sem) +{ + int result; + __asm__ __volatile__ (" + @ atomic down operation + mrs r0, cpsr + orr r1, r0, #128 @ disable IRQs + bic r0, r0, #0x80000000 @ clear N + msr cpsr, r1 + ldr r1, [%1] + subs r1, r1, #1 + str r1, [%1] + orrmi r0, r0, #0x80000000 @ set N + msr cpsr, r0 + movmi r0, %1 + movpl r0, #0 + blmi " SYMBOL_NAME_STR(__down_interruptible) " + mov %0, r0" + : "=r" (result) + : "r" (sem) + : "r0", "r1", "r2", "r3", "ip", "lr", "cc"); + return result; +} + +/* + * Note! This is subtle. We jump to wake people up only if + * the semaphore was negative (== somebody was waiting on it). + * The default case (no contention) will result in NO + * jumps for both down() and up(). + */ +extern inline void up(struct semaphore * sem) +{ + __asm__ __volatile__ (" + @ atomic up operation + mrs r0, cpsr + orr r1, r0, #128 @ disable IRQs + bic r0, r0, #0x80000000 @ clear N + msr cpsr, r1 + ldr r1, [%0] + adds r1, r1, #1 + str r1, [%0] + orrls r0, r0, #0x80000000 @ set N + msr cpsr, r0 + movmi r0, %0 + blmi " SYMBOL_NAME_STR(__up) + : : "r" (sem) : "r0", "r1", "r2", "r3", "ip", "lr", "cc"); +} + +#endif diff --git a/include/asm-arm/proc-armv/shmparam.h b/include/asm-arm/proc-armv/shmparam.h new file mode 100644 index 000000000..10e280b6d --- /dev/null +++ b/include/asm-arm/proc-armv/shmparam.h @@ -0,0 +1,19 @@ +/* + * linux/include/asm-arm/proc-armv/shmparam.h + * + * Copyright (C) 1996 Russell King + * + * definitions for the shared process memory on ARM v3 or v4 + * processors + */ + +#ifndef __ASM_PROC_SHMPARAM_H +#define __ASM_PROC_SHMPARAM_H + +#ifndef SHM_RANGE_START +#define SHM_RANGE_START 0x50000000 +#define SHM_RANGE_END 0x60000000 +#define SHMMAX 0x01000000 +#endif + +#endif diff --git a/include/asm-arm/proc-armv/system.h b/include/asm-arm/proc-armv/system.h new file mode 100644 index 000000000..6a1f38de0 --- /dev/null +++ b/include/asm-arm/proc-armv/system.h @@ -0,0 +1,137 @@ +/* + * linux/include/asm-arm/proc-armv/system.h + * + * Copyright (C) 1996 Russell King + */ + +#ifndef __ASM_PROC_SYSTEM_H +#define __ASM_PROC_SYSTEM_H + +extern const char xchg_str[]; + +extern __inline__ unsigned long __xchg(unsigned long x, volatile void *ptr, int size) +{ + switch (size) { + case 1: __asm__ __volatile__ ("swpb %0, %1, [%2]" : "=r" (x) : "r" (x), "r" (ptr) : "memory"); + break; + case 2: abort (); + case 4: __asm__ __volatile__ ("swp %0, %1, [%2]" : "=r" (x) : "r" (x), "r" (ptr) : "memory"); + break; + default: arm_invalidptr(xchg_str, size); + } + return x; +} + +/* + * This processor does not need anything special before reset, + * but RPC may do... + */ +extern __inline__ void proc_hard_reset(void) +{ +} + +/* + * We can wait for an interrupt... + */ +#if 0 +#define proc_idle() \ + do { \ + __asm__ __volatile__( \ +" mcr p15, 0, %0, c15, c8, 2" \ + : : "r" (0)); \ + } while (0) +#else +#define proc_idle() +#endif +/* + * A couple of speedups for the ARM + */ + +/* + * Save the current interrupt enable state & disable IRQs + */ +#define __save_flags_cli(x) \ + do { \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %1, cpsr\n" \ +" and %0, %1, #192\n" \ +" orr %1, %1, #128\n" \ +" msr cpsr, %1" \ + : "=r" (x), "=r" (temp) \ + : \ + : "memory"); \ + } while (0) + +/* + * Enable IRQs + */ +#define __sti() \ + do { \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr\n" \ +" bic %0, %0, #128\n" \ +" msr cpsr, %0" \ + : "=r" (temp) \ + : \ + : "memory"); \ + } while(0) + +/* + * Disable IRQs + */ +#define __cli() \ + do { \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr\n" \ +" orr %0, %0, #128\n" \ +" msr cpsr, %0" \ + : "=r" (temp) \ + : \ + : "memory"); \ + } while(0) + +/* + * save current IRQ & FIQ state + */ +#define __save_flags(x) \ + do { \ + __asm__ __volatile__( \ + "mrs %0, cpsr\n" \ +" and %0, %0, #192" \ + : "=r" (x) \ + : \ + : "memory"); \ + } while (0) + +/* + * restore saved IRQ & FIQ state + */ +#define __restore_flags(x) \ + do { \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr\n" \ +" bic %0, %0, #192\n" \ +" orr %0, %0, %1\n" \ +" msr cpsr, %0" \ + : "=r" (temp) \ + : "r" (x) \ + : "memory"); \ + } while (0) + +#ifdef __SMP__ +#error SMP not supported +#else + +#define cli() __cli() +#define sti() __sti() +#define save_flags(x) __save_flags(x) +#define restore_flags(x) __restore_flags(x) +#define save_flags_cli(x) __save_flags_cli(x) + +#endif + +#endif diff --git a/include/asm-arm/proc-armv/uaccess.h b/include/asm-arm/proc-armv/uaccess.h new file mode 100644 index 000000000..acadb35a3 --- /dev/null +++ b/include/asm-arm/proc-armv/uaccess.h @@ -0,0 +1,204 @@ +/* + * linux/include/asm-arm/proc-armv/uaccess.h + */ + +/* + * The fs functions are implemented on the ARMV3 and V4 architectures + * using the domain register. + * + * DOMAIN_IO - domain 2 includes all IO only + * DOMAIN_KERNEL - domain 1 includes all kernel memory only + * DOMAIN_USER - domain 0 includes all user memory only + */ + +#define DOMAIN_CLIENT 1 +#define DOMAIN_MANAGER 3 + +#define DOMAIN_USER_CLIENT ((DOMAIN_CLIENT) << 0) +#define DOMAIN_USER_MANAGER ((DOMAIN_MANAGER) << 0) + +#define DOMAIN_KERNEL_CLIENT ((DOMAIN_CLIENT) << 2) +#define DOMAIN_KERNEL_MANAGER ((DOMAIN_MANAGER) << 2) + +#define DOMAIN_IO_CLIENT ((DOMAIN_CLIENT) << 4) +#define DOMAIN_IO_MANAGER ((DOMAIN_MANAGER) << 4) + +/* + * When we want to access kernel memory in the *_user functions, + * we change the domain register to KERNEL_DS, thus allowing + * unrestricted access + */ +#define KERNEL_DOMAIN (DOMAIN_USER_CLIENT | DOMAIN_KERNEL_MANAGER | DOMAIN_IO_CLIENT) +#define USER_DOMAIN (DOMAIN_USER_CLIENT | DOMAIN_KERNEL_CLIENT | DOMAIN_IO_CLIENT) + +/* + * Note that this is actually 0x1,0000,0000 + */ +#define KERNEL_DS 0x00000000 +#define USER_DS 0xc0000000 + +#define get_ds() (KERNEL_DS) +#define get_fs() (current->addr_limit) + +#define segment_eq(a,b) ((a) == (b)) + +extern __inline__ void set_fs (mm_segment_t fs) +{ + current->addr_limit = fs; + + __asm__ __volatile__("mcr p15, 0, %0, c3, c0" : + : "r" (fs ? USER_DOMAIN : KERNEL_DOMAIN)); +} + +/* + * a + s <= 2^32 -> C = 0 || Z = 0 (LS) + * (a + s) <= l -> C = 0 || Z = 0 (LS) + */ +#define __range_ok(addr,size) ({ \ + unsigned long flag, sum; \ + __asm__ __volatile__("adds %1, %2, %3; cmpls %1, %0; movls %0, #0" \ + : "=&r" (flag), "=&r" (sum) \ + : "r" (addr), "Ir" (size), "0" (current->addr_limit) \ + : "cc"); \ + flag; }) + +#define __addr_ok(addr) ({ \ + unsigned long flag; \ + __asm__ __volatile__("cmp %2, %0; movlo %0, #0" \ + : "=&r" (flag) \ + : "0" (current->addr_limit), "r" (addr) \ + : "cc"); \ + (flag == 0); }) + +#define access_ok(type,addr,size) (__range_ok(addr,size) == 0) + +#define __put_user_asm_byte(x,addr,err) \ + __asm__ __volatile__( \ + "1: strbt %1,[%2],#0\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mvn %0, %3\n" \ + " b 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .previous" \ + : "=r" (err) \ + : "r" (x), "r" (addr), "i" (EFAULT), "0" (err)) + +#define __put_user_asm_half(x,addr,err) \ +({ \ + unsigned long __temp = (unsigned long)(x); \ + __asm__ __volatile__( \ + "1: strbt %1,[%3],#0\n" \ + "2: strbt %2,[%4],#0\n" \ + "3:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "4: mvn %0, %5\n" \ + " b 3b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 4b\n" \ + " .long 2b, 4b\n" \ + " .previous" \ + : "=r" (err) \ + : "r" (__temp), "r" (__temp >> 8), \ + "r" (addr), "r" ((int)(addr) + 1), \ + "i" (EFAULT), "0" (err)); \ +}) + +#define __put_user_asm_word(x,addr,err) \ + __asm__ __volatile__( \ + "1: strt %1,[%2],#0\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mvn %0, %3\n" \ + " b 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .previous" \ + : "=r" (err) \ + : "r" (x), "r" (addr), "i" (EFAULT), "0" (err)) + +#define __get_user_asm_byte(x,addr,err) \ + __asm__ __volatile__( \ + "1: ldrbt %1,[%2],#0\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mvn %0, %3\n" \ + " b 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .previous" \ + : "=r" (err), "=r" (x) \ + : "r" (addr), "i" (EFAULT), "0" (err)) + +#define __get_user_asm_half(x,addr,err) \ +({ \ + unsigned long __temp; \ + __asm__ __volatile__( \ + "1: ldrbt %1,[%3],#0\n" \ + "2: ldrbt %2,[%4],#0\n" \ + " orr %1, %1, %2, lsl #8\n" \ + "3:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "4: mvn %0, %5\n" \ + " b 3b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 4b\n" \ + " .long 2b, 4b\n" \ + " .previous" \ + : "=r" (err), "=r" (x), "=&r" (__temp) \ + : "r" (addr), "r" ((int)(addr) + 1), \ + "i" (EFAULT), "0" (err)); \ +}) + + +#define __get_user_asm_word(x,addr,err) \ + __asm__ __volatile__( \ + "1: ldrt %1,[%2],#0\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mvn %0, %3\n" \ + " b 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .previous" \ + : "=r" (err), "=r" (x) \ + : "r" (addr), "i" (EFAULT), "0" (err)) + +extern unsigned long __arch_copy_from_user(void *to, const void *from, unsigned long n); +#define __do_copy_from_user(to,from,n) \ + (n) = __arch_copy_from_user(to,from,n) + +extern unsigned long __arch_copy_to_user(void *to, const void *from, unsigned long n); +#define __do_copy_to_user(to,from,n) \ + (n) = __arch_copy_to_user(to,from,n) + +extern unsigned long __arch_clear_user(void *addr, unsigned long n); +#define __do_clear_user(addr,sz) \ + (sz) = __arch_clear_user(addr,sz) + +extern unsigned long __arch_strncpy_from_user(char *to, const char *from, unsigned long count); +#define __do_strncpy_from_user(dst,src,count,res) \ + (res) = __arch_strncpy_from_user(dst,src,count) + +extern unsigned long __arch_strlen_user(const char *s); +#define __do_strlen_user(s,res) \ + (res) = __arch_strlen_user(s) diff --git a/include/asm-arm/proc-armv/uncompress.h b/include/asm-arm/proc-armv/uncompress.h new file mode 100644 index 000000000..acce2de35 --- /dev/null +++ b/include/asm-arm/proc-armv/uncompress.h @@ -0,0 +1,22 @@ +/* + * linux/include/asm-arm/proc-armv/uncompress.h + * + * (c) 1997 Russell King + */ + +static inline void proc_decomp_setup (void) +{ + __asm__ __volatile__(" + mrc p15, 0, r0, c0, c0 + eor r0, r0, #0x44 << 24 + eor r0, r0, #0x01 << 16 + eor r0, r0, #0xA1 << 8 + movs r0, r0, lsr #4 + mcreq p15, 0, r0, c7, c5, 0 @ flush I cache + mrceq p15, 0, r0, c1, c0 + orreq r0, r0, #1 << 12 + mcreq p15, 0, r0, c1, c0 @ enable I cache + mov r0, #0 + mcreq p15, 0, r0, c15, c1, 2 @ enable clock switching + " : : : "r0", "cc", "memory"); +} diff --git a/include/asm-arm/proc-fns.h b/include/asm-arm/proc-fns.h new file mode 100644 index 000000000..4f8a48d06 --- /dev/null +++ b/include/asm-arm/proc-fns.h @@ -0,0 +1,111 @@ +/* + * linux/include/asm-arm/proc-fns.h + * + * Copyright (C) 1997 Russell King + */ +#ifndef __ASM_PROCFNS_H +#define __ASM_PROCFNS_H + +#include <asm/page.h> + +#ifdef __KERNEL__ +/* + * Don't change this structure + */ +extern struct processor { + const char *name; + /* MISC + * + * flush caches for task switch + */ + void (*_switch_to)(void *prev, void *next); + /* + * get data abort address/flags + */ + void (*_data_abort)(unsigned long pc); + /* + * check for any bugs + */ + void (*_check_bugs)(void); + /* + * Set up any processor specifics + */ + void (*_proc_init)(void); + /* + * Disable any processor specifics + */ + void (*_proc_fin)(void); + /* + * Processor architecture specific + */ + union { + struct { + /* CACHE + * + * flush all caches + */ + void (*_flush_cache_all)(void); + /* + * flush a specific page or pages + */ + void (*_flush_cache_area)(unsigned long address, unsigned long end, int flags); + /* + * flush cache entry for an address + */ + void (*_flush_cache_entry)(unsigned long address); + /* + * flush a virtual address used for a page table + * note D-cache only! + */ + void (*_flush_cache_pte)(unsigned long address); + /* + * flush a page to RAM + */ + void (*_flush_ram_page)(unsigned long page); + /* TLB + * + * flush all TLBs + */ + void (*_flush_tlb_all)(void); + /* + * flush a specific TLB + */ + void (*_flush_tlb_area)(unsigned long address, unsigned long end, int flags); + /* + * Set a PMD (handling IMP bit 4) + */ + void (*_set_pmd)(pmd_t *pmdp, pmd_t pmd); + /* + * Special stuff for a reset + */ + unsigned long (*reset)(void); + /* + * flush an icached page + */ + void (*_flush_icache_area)(unsigned long start, unsigned long end); + } armv3v4; + struct { + /* MEMC + * + * remap memc tables + */ + void (*_remap_memc)(void *tsk); + /* + * update task's idea of mmap + */ + void (*_update_map)(void *tsk); + /* + * update task's idea after abort + */ + void (*_update_mmu_cache)(void *vma, unsigned long addr, pte_t pte); + /* XCHG + */ + unsigned long (*_xchg_1)(unsigned long x, volatile void *ptr); + unsigned long (*_xchg_2)(unsigned long x, volatile void *ptr); + unsigned long (*_xchg_4)(unsigned long x, volatile void *ptr); + } armv2; + } u; +} processor; +#endif +#endif + diff --git a/include/asm-arm/processor.h b/include/asm-arm/processor.h new file mode 100644 index 000000000..a75d4a960 --- /dev/null +++ b/include/asm-arm/processor.h @@ -0,0 +1,51 @@ +/* + * include/asm-arm/processor.h + * + * Copyright (C) 1995 Russell King + */ + +#ifndef __ASM_ARM_PROCESSOR_H +#define __ASM_ARM_PROCESSOR_H + +struct fp_hard_struct { + unsigned int save[140/4]; /* as yet undefined */ +}; + +struct fp_soft_struct { + unsigned int save[140/4]; /* undefined information */ +}; + +union fp_state { + struct fp_hard_struct hard; + struct fp_soft_struct soft; +}; + +typedef unsigned long mm_segment_t; /* domain register */ + +#define DECLARE_THREAD_STRUCT \ +struct thread_struct { \ + unsigned long address; /* Address of fault */ \ + unsigned long trap_no; /* Trap number */ \ + unsigned long error_code; /* Error code of trap */ \ + union fp_state fpstate; /* FPE save state */ \ + EXTRA_THREAD_STRUCT \ +} + +#include <asm/arch/processor.h> +#include <asm/proc/processor.h> + +#define INIT_TSS { \ + 0, \ + 0, \ + 0, \ + { { { 0, }, }, }, \ + EXTRA_THREAD_STRUCT_INIT \ +} + +/* Free all resources held by a thread. */ +extern void release_thread(struct task_struct *); + +#define init_task (init_task_union.task) +#define init_stack (init_task_union.stack) + +#endif /* __ASM_ARM_PROCESSOR_H */ diff --git a/include/asm-arm/procinfo.h b/include/asm-arm/procinfo.h new file mode 100644 index 000000000..0d8811624 --- /dev/null +++ b/include/asm-arm/procinfo.h @@ -0,0 +1,32 @@ +/* + * linux/include/asm-arm/procinfo.h + * + * Copyright (C) 1996 Russell King + */ + +#ifndef __ASM_PROCINFO_H +#define __ASM_PROCINFO_H + +#include <asm/proc-fns.h> + +#define F_MEMC (1<<0) +#define F_MMU (1<<1) +#define F_32BIT (1<<2) +#define F_CACHE (1<<3) +#define F_IOEB (1<<31) + +#ifndef __ASSEMBLER__ + +struct armversions { + unsigned long id; + unsigned long mask; + unsigned long features; + const char *manu; + const char *name; + const struct processor *proc; +}; + +#endif + +#endif + diff --git a/include/asm-arm/ptrace.h b/include/asm-arm/ptrace.h new file mode 100644 index 000000000..5cd91dc31 --- /dev/null +++ b/include/asm-arm/ptrace.h @@ -0,0 +1,11 @@ +#ifndef __ASM_ARM_PTRACE_H +#define __ASM_ARM_PTRACE_H + +#include <asm/proc/ptrace.h> + +#ifdef __KERNEL__ +extern void show_regs(struct pt_regs *); +#endif + +#endif + diff --git a/include/asm-arm/resource.h b/include/asm-arm/resource.h new file mode 100644 index 000000000..85d281157 --- /dev/null +++ b/include/asm-arm/resource.h @@ -0,0 +1,39 @@ +#ifndef _ARM_RESOURCE_H +#define _ARM_RESOURCE_H + +/* + * Resource limits + */ + +#define RLIMIT_CPU 0 /* CPU time in ms */ +#define RLIMIT_FSIZE 1 /* Maximum filesize */ +#define RLIMIT_DATA 2 /* max data size */ +#define RLIMIT_STACK 3 /* max stack size */ +#define RLIMIT_CORE 4 /* max core file size */ +#define RLIMIT_RSS 5 /* max resident set size */ +#define RLIMIT_NPROC 6 /* max number of processes */ +#define RLIMIT_NOFILE 7 /* max number of open files */ +#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ +#define RLIMIT_AS 9 /* address space limit */ + +#define RLIM_NLIMITS 10 + +#ifdef __KERNEL__ + +#define INIT_RLIMITS \ +{ \ + { LONG_MAX, LONG_MAX }, \ + { LONG_MAX, LONG_MAX }, \ + { LONG_MAX, LONG_MAX }, \ + { _STK_LIM, _STK_LIM }, \ + { 0, LONG_MAX }, \ + { LONG_MAX, LONG_MAX }, \ + { MAX_TASKS_PER_USER, MAX_TASKS_PER_USER }, \ + { NR_OPEN, NR_OPEN }, \ + { LONG_MAX, LONG_MAX }, \ + { LONG_MAX, LONG_MAX }, \ +} + +#endif /* __KERNEL__ */ + +#endif diff --git a/include/asm-arm/scatterlist.h b/include/asm-arm/scatterlist.h new file mode 100644 index 000000000..7d0175507 --- /dev/null +++ b/include/asm-arm/scatterlist.h @@ -0,0 +1,13 @@ +#ifndef _ASMARM_SCATTERLIST_H +#define _ASMARM_SCATTERLIST_H + +struct scatterlist { + char * address; /* Location data is to be transferred to */ + char * alt_address; /* Location of actual if address is a + * dma indirect buffer. NULL otherwise */ + unsigned int length; +}; + +#define ISA_DMA_THRESHOLD (0xffffffff) + +#endif /* _ASMARM_SCATTERLIST_H */ diff --git a/include/asm-arm/segment.h b/include/asm-arm/segment.h new file mode 100644 index 000000000..9e24c21f6 --- /dev/null +++ b/include/asm-arm/segment.h @@ -0,0 +1,11 @@ +#ifndef __ASM_ARM_SEGMENT_H +#define __ASM_ARM_SEGMENT_H + +#define __KERNEL_CS 0x0 +#define __KERNEL_DS 0x0 + +#define __USER_CS 0x1 +#define __USER_DS 0x1 + +#endif /* __ASM_ARM_SEGMENT_H */ + diff --git a/include/asm-arm/semaphore.h b/include/asm-arm/semaphore.h new file mode 100644 index 000000000..3186aac19 --- /dev/null +++ b/include/asm-arm/semaphore.h @@ -0,0 +1,67 @@ +/* + * linux/include/asm-arm/semaphore.h + */ +#ifndef __ASM_ARM_SEMAPHORE_H +#define __ASM_ARM_SEMAPHORE_H + +#include <linux/linkage.h> +#include <asm/system.h> +#include <asm/atomic.h> + +struct semaphore { + atomic_t count; + int waking; + struct wait_queue * wait; +}; + +#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), 0, NULL }) +#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), 0, NULL }) + +asmlinkage void __down_failed (void /* special register calling convention */); +asmlinkage int __down_failed_interruptible (void /* special register calling convention */); +asmlinkage void __up_wakeup (void /* special register calling convention */); + +extern void __down(struct semaphore * sem); +extern void __up(struct semaphore * sem); + +#define sema_init(sem, val) atomic_set(&((sem)->count), (val)) + +/* + * These two _must_ execute atomically wrt each other. + * + * This is trivially done with load_locked/store_cond, + * but on the x86 we need an external synchronizer. + * Currently this is just the global interrupt lock, + * bah. Go for a smaller spinlock some day. + * + * (On the other hand this shouldn't be in any critical + * path, so..) + */ +static inline void wake_one_more(struct semaphore * sem) +{ + unsigned long flags; + + save_flags(flags); + cli(); + sem->waking++; + restore_flags(flags); +} + +static inline int waking_non_zero(struct semaphore *sem) +{ + unsigned long flags; + int ret = 0; + + save_flags(flags); + cli(); + if (sem->waking > 0) { + sem->waking--; + ret = 1; + } + restore_flags(flags); + return ret; +} + +#include <asm/proc/semaphore.h> + +#endif diff --git a/include/asm-arm/serial.h b/include/asm-arm/serial.h new file mode 100644 index 000000000..3e1513a45 --- /dev/null +++ b/include/asm-arm/serial.h @@ -0,0 +1,15 @@ +/* + * linux/include/asm-arm/serial.h + * + * Copyright (c) 1996 Russell King. + * + * Changelog: + * 15-10-1996 RMK Created + */ + +#ifndef __ASM_SERIAL_H +#define __ASM_SERIAL_H + +#include <asm/arch/serial.h> + +#endif diff --git a/include/asm-arm/setup.h b/include/asm-arm/setup.h new file mode 100644 index 000000000..07aefda05 --- /dev/null +++ b/include/asm-arm/setup.h @@ -0,0 +1,49 @@ +/* + * include/asm/setup.h + * + * Structure passed to kernel to tell it about the hardware it's running on + * + * Copyright (C) 1997,1998 Russell King + */ +#ifndef __ASMARM_SETUP_H +#define __ASMARM_SETUP_H + +struct param_struct { + union { + struct { + unsigned long page_size; /* 0 */ + unsigned long nr_pages; /* 4 */ + unsigned long ramdisk_size; /* 8 */ + unsigned long flags; /* 12 */ +#define FLAG_READONLY 1 +#define FLAG_RDLOAD 4 +#define FLAG_RDPROMPT 8 + unsigned long rootdev; /* 16 */ + unsigned long video_num_cols; /* 20 */ + unsigned long video_num_rows; /* 24 */ + unsigned long video_x; /* 28 */ + unsigned long video_y; /* 32 */ + unsigned long memc_control_reg; /* 36 */ + unsigned char sounddefault; /* 40 */ + unsigned char adfsdrives; /* 41 */ + unsigned char bytes_per_char_h; /* 42 */ + unsigned char bytes_per_char_v; /* 43 */ + unsigned long pages_in_bank[4]; /* 44 */ + unsigned long pages_in_vram; /* 60 */ + unsigned long initrd_start; /* 64 */ + unsigned long initrd_size; /* 68 */ + unsigned long rd_start; /* 72 */ + } s; + char unused[256]; + } u1; + union { + char paths[8][128]; + struct { + unsigned long magic; + char n[1024 - sizeof(unsigned long)]; + } s; + } u2; + char commandline[256]; +}; + +#endif diff --git a/include/asm-arm/shmparam.h b/include/asm-arm/shmparam.h new file mode 100644 index 000000000..74d2a6122 --- /dev/null +++ b/include/asm-arm/shmparam.h @@ -0,0 +1,47 @@ +#ifndef _ASMARM_SHMPARAM_H +#define _ASMARM_SHMPARAM_H + +/* + * Include the machine specific shm parameters before the processor + * dependent parameters so that the machine parameters can override + * the processor parameters + */ +#include <asm/arch/shmparam.h> +#include <asm/proc/shmparam.h> + +/* + * Format of a swap-entry for shared memory pages currently out in + * swap space (see also mm/swap.c). + * + * SWP_TYPE = SHM_SWP_TYPE + * SWP_OFFSET is used as follows: + * + * bits 0..6 : id of shared memory segment page belongs to (SHM_ID) + * bits 7..21: index of page within shared memory segment (SHM_IDX) + * (actually fewer bits get used since SHMMAX is so low) + */ + +/* + * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and + * there is a static array of size SHMMNI. + */ +#define _SHM_ID_BITS 7 +#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) + +#define SHM_IDX_SHIFT (_SHM_ID_BITS) +#define _SHM_IDX_BITS 15 +#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) + +/* + * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and + * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). + */ + +#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */ +#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */ +#define SHMALL /* max shm system wide (pages) */ \ + (1<<(_SHM_IDX_BITS+_SHM_ID_BITS)) +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ +#define SHMSEG SHMMNI /* max shared segs per process */ + +#endif /* _ASMARM_SHMPARAM_H */ diff --git a/include/asm-arm/sigcontext.h b/include/asm-arm/sigcontext.h new file mode 100644 index 000000000..6ce49457f --- /dev/null +++ b/include/asm-arm/sigcontext.h @@ -0,0 +1,33 @@ +#ifndef _ASMARM_SIGCONTEXT_H +#define _ASMARM_SIGCONTEXT_H + +/* + * Signal context structure - contains all info to do with the state + * before the signal handler was invoked. Note: only add new entries + * to the end of the structure. + */ +struct sigcontext { + unsigned long trap_no; + unsigned long error_code; + unsigned long oldmask; + unsigned long arm_r0; + unsigned long arm_r1; + unsigned long arm_r2; + unsigned long arm_r3; + unsigned long arm_r4; + unsigned long arm_r5; + unsigned long arm_r6; + unsigned long arm_r7; + unsigned long arm_r8; + unsigned long arm_r9; + unsigned long arm_r10; + unsigned long arm_fp; + unsigned long arm_ip; + unsigned long arm_sp; + unsigned long arm_lr; + unsigned long arm_pc; + unsigned long arm_cpsr; +}; + + +#endif diff --git a/include/asm-arm/siginfo.h b/include/asm-arm/siginfo.h new file mode 100644 index 000000000..b987a12eb --- /dev/null +++ b/include/asm-arm/siginfo.h @@ -0,0 +1,195 @@ +#ifndef _ASMARM_SIGINFO_H +#define _ASMARM_SIGINFO_H + +#include <linux/types.h> + +/* XXX: This structure was copied from the Alpha; is there an iBCS version? */ + +typedef union sigval { + int sival_int; + void *sival_ptr; +} sigval_t; + +#define SI_MAX_SIZE 128 +#define SI_PAD_SIZE ((SI_MAX_SIZE/sizeof(int)) - 3) + +typedef struct siginfo { + int si_signo; + int si_errno; + int si_code; + + union { + int _pad[SI_PAD_SIZE]; + + /* kill() */ + struct { + pid_t _pid; /* sender's pid */ + uid_t _uid; /* sender's uid */ + } _kill; + + /* POSIX.1b timers */ + struct { + unsigned int _timer1; + unsigned int _timer2; + } _timer; + + /* POSIX.1b signals */ + struct { + pid_t _pid; /* sender's pid */ + uid_t _uid; /* sender's uid */ + sigval_t _sigval; + } _rt; + + /* SIGCHLD */ + struct { + pid_t _pid; /* which child */ + int _status; /* exit code */ + clock_t _utime; + clock_t _stime; + } _sigchld; + + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ + struct { + void *_addr; /* faulting insn/memory ref. */ + } _sigfault; + + /* SIGPOLL */ + struct { + int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ + int _fd; + } _sigpoll; + } _sifields; +} siginfo_t; + +/* + * How these fields are to be accessed. + */ +#define si_pid _sifields._kill._pid +#define si_uid _sifields._kill._uid +#define si_status _sifields._sigchld._status +#define si_utime _sifields._sigchld._utime +#define si_stime _sifields._sigchld._stime +#define si_value _sifields._rt._sigval +#define si_int _sifields._rt._sigval.sival_int +#define si_ptr _sifields._rt._sigval.sival_ptr +#define si_addr _sifields._sigfault._addr +#define si_band _sifields._sigpoll._band +#define si_fd _sifields._sigpoll._fd + +/* + * si_code values + * Digital reserves positive values for kernel-generated signals. + */ +#define SI_USER 0 /* sent by kill, sigsend, raise */ +#define SI_KERNEL 0x80 /* sent by the kernel from somewhere */ +#define SI_QUEUE -1 /* sent by sigqueue */ +#define SI_TIMER -2 /* sent by timer expiration */ +#define SI_MESGQ -3 /* sent by real time mesq state change */ +#define SI_ASYNCIO -4 /* sent by AIO completion */ + +#define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) +#define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) + +/* + * SIGILL si_codes + */ +#define ILL_ILLOPC 1 /* illegal opcode */ +#define ILL_ILLOPN 2 /* illegal operand */ +#define ILL_ILLADR 3 /* illegal addressing mode */ +#define ILL_ILLTRP 4 /* illegal trap */ +#define ILL_PRVOPC 5 /* privileged opcode */ +#define ILL_PRVREG 6 /* privileged register */ +#define ILL_COPROC 7 /* coprocessor error */ +#define ILL_BADSTK 8 /* internal stack error */ +#define NSIGILL 8 + +/* + * SIGFPE si_codes + */ +#define FPE_INTDIV 1 /* integer divide by zero */ +#define FPE_INTOVF 2 /* integer overflow */ +#define FPE_FLTDIV 3 /* floating point divide by zero */ +#define FPE_FLTOVF 4 /* floating point overflow */ +#define FPE_FLTUND 5 /* floating point underflow */ +#define FPE_FLTRES 6 /* floating point inexact result */ +#define FPE_FLTINV 7 /* floating point invalid operation */ +#define FPE_FLTSUB 8 /* subscript out of range */ +#define NSIGFPE 8 + +/* + * SIGSEGV si_codes + */ +#define SEGV_MAPERR 1 /* address not mapped to object */ +#define SEGV_ACCERR 2 /* invalid permissions for mapped object */ +#define NSIGSEGV 2 + +/* + * SIGBUS si_codes + */ +#define BUS_ADRALN 1 /* invalid address alignment */ +#define BUS_ADRERR 2 /* non-existant physical address */ +#define BUS_OBJERR 3 /* object specific hardware error */ +#define NSIGBUS 3 + +/* + * SIGTRAP si_codes + */ +#define TRAP_BRKPT 1 /* process breakpoint */ +#define TRAP_TRACE 2 /* process trace trap */ +#define NSIGTRAP + +/* + * SIGCHLD si_codes + */ +#define CLD_EXITED 1 /* child has exited */ +#define CLD_KILLED 2 /* child was killed */ +#define CLD_DUMPED 3 /* child terminated abnormally */ +#define CLD_TRAPPED 4 /* traced child has trapped */ +#define CLD_STOPPED 5 /* child has stopped */ +#define CLD_CONTINUED 6 /* stopped child has continued */ +#define NSIGCHLD + +/* + * SIGPOLL si_codes + */ +#define POLL_IN 1 /* data input available */ +#define POLL_OUT 2 /* output buffers available */ +#define POLL_MSG 3 /* input message available */ +#define POLL_ERR 4 /* i/o error */ +#define POLL_PRI 5 /* high priority input available */ +#define POLL_HUP 6 /* device disconnected */ +#define NSIGPOLL 6 + +/* + * sigevent definitions + * + * It seems likely that SIGEV_THREAD will have to be handled from + * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the + * thread manager then catches and does the appropriate nonsense. + * However, everything is written out here so as to not get lost. + */ +#define SIGEV_SIGNAL 0 /* notify via signal */ +#define SIGEV_NONE 1 /* other notification: meaningless */ +#define SIGEV_THREAD 2 /* deliver via thread creation */ + +#define SIGEV_MAX_SIZE 64 +#define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3) + +typedef struct sigevent { + sigval_t sigev_value; + int sigev_signo; + int sigev_notify; + union { + int _pad[SIGEV_PAD_SIZE]; + + struct { + void (*_function)(sigval_t); + void *_attribute; /* really pthread_attr_t */ + } _sigev_thread; + } _sigev_un; +} sigevent_t; + +#define sigev_notify_function _sigev_un._sigev_thread._function +#define sigev_notify_attributes _sigev_un._sigev_thread._attribute + +#endif diff --git a/include/asm-arm/signal.h b/include/asm-arm/signal.h new file mode 100644 index 000000000..6303537f6 --- /dev/null +++ b/include/asm-arm/signal.h @@ -0,0 +1,147 @@ +#ifndef _ASMARM_SIGNAL_H +#define _ASMARM_SIGNAL_H + +#include <linux/types.h> + +/* Avoid too many header ordering problems. */ +struct siginfo; + +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +#define _NSIG 64 +#define _NSIG_BPW 32 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define SIGRTMIN 32 +#define SIGRTMAX (_NSIG-1) + +/* + * SA_FLAGS values: + * + * SA_ONSTACK is not currently supported, but will allow sigaltstack(2). + * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. + * SA_RESETHAND clears the handler when the signal is delivered. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. + * SA_NODEFER prevents the current signal from being masked in the handler. + * + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single + * Unix names RESETHAND and NODEFER respectively. + */ +#define SA_NOCLDSTOP 0x00000001 +#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_SIGINFO 0x00000004 +#define SA_ONSTACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_NODEFER 0x40000000 +#define SA_RESETHAND 0x80000000 + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND +#define SA_INTERRUPT 0x20000000 /* dummy -- ignored */ + +#define SA_RESTORER 0x04000000 + +#ifdef __KERNEL__ + +/* + * These values of sa_flags are used only by the kernel as part of the + * irq handling routines. + * + * SA_INTERRUPT is also used by the irq handling routines. + * SA_SHIRQ is for shared interrupt support on PCI and EISA. + */ +#define SA_PROBE SA_ONESHOT +#define SA_SAMPLE_RANDOM SA_RESTART +#define SA_SHIRQ 0x04000000 +#endif + +#define SIG_BLOCK 0 /* for blocking signals */ +#define SIG_UNBLOCK 1 /* for unblocking signals */ +#define SIG_SETMASK 2 /* for setting the signal mask */ + +/* Type of a signal handler. */ +typedef void (*__sighandler_t)(int); + +#define SIG_DFL ((__sighandler_t)0) /* default signal handling */ +#define SIG_IGN ((__sighandler_t)1) /* ignore signal */ +#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ + +struct old_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + void (*sa_restorer)(void); + sigset_t sa_mask; /* mask last for extensibility */ +}; + +struct k_sigaction { + struct sigaction sa; +}; + +typedef struct sigaltstack { + void *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +#ifdef __KERNEL__ +#include <asm/sigcontext.h> + +#define sigmask(sig) (1UL << ((sig) - 1)) + +#endif + +#endif diff --git a/include/asm-arm/smp.h b/include/asm-arm/smp.h new file mode 100644 index 000000000..888933936 --- /dev/null +++ b/include/asm-arm/smp.h @@ -0,0 +1,7 @@ +#ifndef __ASM_SMP_H +#define __ASM_SMP_H + +#ifdef __SMP__ +#error SMP not supported +#endif +#endif diff --git a/include/asm-arm/smp_lock.h b/include/asm-arm/smp_lock.h new file mode 100644 index 000000000..2d024ed57 --- /dev/null +++ b/include/asm-arm/smp_lock.h @@ -0,0 +1,17 @@ +#ifndef __I386_SMPLOCK_H +#define __I386_SMPLOCK_H + +#define __STR(x) #x + +#ifndef __SMP__ + +#define lock_kernel() do { } while(0) +#define unlock_kernel() do { } while(0) +#define release_kernel_lock(task, cpu, depth) ((depth) = 1) +#define reacquire_kernel_lock(task, cpu, depth) do { } while(0) + +#else +#error SMP not supported +#endif /* __SMP__ */ + +#endif /* __I386_SMPLOCK_H */ diff --git a/include/asm-arm/socket.h b/include/asm-arm/socket.h new file mode 100644 index 000000000..312aef936 --- /dev/null +++ b/include/asm-arm/socket.h @@ -0,0 +1,33 @@ +#ifndef _ASMARM_SOCKET_H +#define _ASMARM_SOCKET_H + +#include <asm/sockios.h> + +/* For setsockoptions(2) */ +#define SOL_SOCKET 1 + +#define SO_DEBUG 1 +#define SO_REUSEADDR 2 +#define SO_TYPE 3 +#define SO_ERROR 4 +#define SO_DONTROUTE 5 +#define SO_BROADCAST 6 +#define SO_SNDBUF 7 +#define SO_RCVBUF 8 +#define SO_KEEPALIVE 9 +#define SO_OOBINLINE 10 +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_LINGER 13 +#define SO_BSDCOMPAT 14 +/* To add :#define SO_REUSEPORT 15 */ +#define SO_PASSCRED 16 +#define SO_PEERCRED 17 +#define SO_RCVLOWAT 18 +#define SO_SNDLOWAT 19 +#define SO_RCVTIMEO 20 +#define SO_SNDTIMEO 21 + +#define SO_BINDTODEVICE 25 + +#endif /* _ASM_SOCKET_H */ diff --git a/include/asm-arm/sockios.h b/include/asm-arm/sockios.h new file mode 100644 index 000000000..77c34087d --- /dev/null +++ b/include/asm-arm/sockios.h @@ -0,0 +1,12 @@ +#ifndef __ARCH_ARM_SOCKIOS_H +#define __ARCH_ARM_SOCKIOS_H + +/* Socket-level I/O control calls. */ +#define FIOSETOWN 0x8901 +#define SIOCSPGRP 0x8902 +#define FIOGETOWN 0x8903 +#define SIOCGPGRP 0x8904 +#define SIOCATMARK 0x8905 +#define SIOCGSTAMP 0x8906 /* Get stamp */ + +#endif diff --git a/include/asm-arm/softirq.h b/include/asm-arm/softirq.h new file mode 100644 index 000000000..a9208b421 --- /dev/null +++ b/include/asm-arm/softirq.h @@ -0,0 +1,68 @@ +#ifndef __ASM_SOFTIRQ_H +#define __ASM_SOFTIRQ_H + +#include <asm/atomic.h> +#include <asm/hardirq.h> + +#define get_active_bhs() (bh_mask & bh_active) +#define clear_active_bhs(x) atomic_clear_mask((int)(x),&bh_active) + +extern inline void init_bh(int nr, void (*routine)(void)) +{ + bh_base[nr] = routine; + bh_mask_count[nr] = 0; + bh_mask |= 1 << nr; +} + +extern inline void remove_bh(int nr) +{ + bh_base[nr] = NULL; + bh_mask &= ~(1 << nr); +} + +extern inline void mark_bh(int nr) +{ + set_bit(nr, &bh_active); +} + +/* + * These use a mask count to correctly handle + * nested disable/enable calls + */ +extern inline void disable_bh(int nr) +{ + bh_mask &= ~(1 << nr); + bh_mask_count[nr]++; +} + +extern inline void enable_bh(int nr) +{ + if (!--bh_mask_count[nr]) + bh_mask |= 1 << nr; +} + +#ifdef __SMP__ +#error SMP not supported +#else + +extern int __arm_bh_counter; + +extern inline void start_bh_atomic(void) +{ + __arm_bh_counter++; + barrier(); +} + +extern inline void end_bh_atomic(void) +{ + barrier(); + __arm_bh_counter--; +} + +/* These are for the irq's testing the lock */ +#define softirq_trylock() (__arm_bh_counter ? 0 : (__arm_bh_counter=1)) +#define softirq_endlock() (__arm_bh_counter = 0) + +#endif /* SMP */ + +#endif /* __ASM_SOFTIRQ_H */ diff --git a/include/asm-arm/spinlock.h b/include/asm-arm/spinlock.h new file mode 100644 index 000000000..376179b96 --- /dev/null +++ b/include/asm-arm/spinlock.h @@ -0,0 +1,59 @@ +#ifndef __ASM_SPINLOCK_H +#define __ASM_SPINLOCK_H + +#ifndef __SMP__ + +/* + * Your basic spinlocks, allowing only a single CPU anywhere + */ +typedef struct { } spinlock_t; +#define SPIN_LOCK_UNLOCKED { } + +#define spin_lock_init(lock) do { } while(0) +#define spin_lock(lock) do { } while(0) +#define spin_trylock(lock) do { } while(0) +#define spin_unlock_wait(lock) do { } while(0) +#define spin_unlock(lock) do { } while(0) +#define spin_lock_irq(lock) cli() +#define spin_unlock_irq(lock) sti() + +#define spin_lock_irqsave(lock, flags) \ + do { save_flags(flags); cli(); } while (0) +#define spin_unlock_irqrestore(lock, flags) \ + restore_flags(flags) + +/* + * Read-write spinlocks, allowing multiple readers + * but only one writer. + * + * NOTE! it is quite common to have readers in interrupts + * but no interrupt writers. For those circumstances we + * can "mix" irq-safe locks - any writer needs to get a + * irq-safe write-lock, but readers can get non-irqsafe + * read-locks. + */ +typedef struct { } rwlock_t; +#define RW_LOCK_UNLOCKED { } + +#define read_lock(lock) do { } while(0) +#define read_unlock(lock) do { } while(0) +#define write_lock(lock) do { } while(0) +#define write_unlock(lock) do { } while(0) +#define read_lock_irq(lock) cli() +#define read_unlock_irq(lock) sti() +#define write_lock_irq(lock) cli() +#define write_unlock_irq(lock) sti() + +#define read_lock_irqsave(lock, flags) \ + do { save_flags(flags); cli(); } while (0) +#define read_unlock_irqrestore(lock, flags) \ + restore_flags(flags) +#define write_lock_irqsave(lock, flags) \ + do { save_flags(flags); cli(); } while (0) +#define write_unlock_irqrestore(lock, flags) \ + restore_flags(flags) + +#else +#error ARM architecture does not support spin locks +#endif /* SMP */ +#endif /* __ASM_SPINLOCK_H */ diff --git a/include/asm-arm/stat.h b/include/asm-arm/stat.h new file mode 100644 index 000000000..76c20e28f --- /dev/null +++ b/include/asm-arm/stat.h @@ -0,0 +1,41 @@ +#ifndef _ASMARM_STAT_H +#define _ASMARM_STAT_H + +struct __old_kernel_stat { + unsigned short st_dev; + unsigned short st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned long st_size; + unsigned long st_atime; + unsigned long st_mtime; + unsigned long st_ctime; +}; + +struct stat { + unsigned short st_dev; + unsigned short __pad1; + unsigned long st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned short __pad2; + unsigned long st_size; + unsigned long st_blksize; + unsigned long st_blocks; + unsigned long st_atime; + unsigned long __unused1; + unsigned long st_mtime; + unsigned long __unused2; + unsigned long st_ctime; + unsigned long __unused3; + unsigned long __unused4; + unsigned long __unused5; +}; + +#endif diff --git a/include/asm-arm/statfs.h b/include/asm-arm/statfs.h new file mode 100644 index 000000000..a1eba73de --- /dev/null +++ b/include/asm-arm/statfs.h @@ -0,0 +1,25 @@ +#ifndef _ASMARM_STATFS_H +#define _ASMARM_STATFS_H + +#ifndef __KERNEL_STRICT_NAMES + +#include <linux/types.h> + +typedef __kernel_fsid_t fsid_t; + +#endif + +struct statfs { + long f_type; + long f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; + __kernel_fsid_t f_fsid; + long f_namelen; + long f_spare[6]; +}; + +#endif diff --git a/include/asm-arm/string.h b/include/asm-arm/string.h new file mode 100644 index 000000000..d185c87bb --- /dev/null +++ b/include/asm-arm/string.h @@ -0,0 +1,24 @@ +#ifndef __ASM_ARM_STRING_H +#define __ASM_ARM_STRING_H + +/* + * inline versions, hmm... + */ + +#define __HAVE_ARCH_STRRCHR +extern char * strrchr(const char * s, int c); + +#define __HAVE_ARCH_STRCHR +extern char * strchr(const char * s, int c); + +#define __HAVE_ARCH_MEMCPY +#define __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMSET + +#define __HAVE_ARCH_MEMZERO +extern void memzero(void *ptr, int n); + +extern void memsetl (unsigned long *, unsigned long, int n); + +#endif + diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h new file mode 100644 index 000000000..2ad6a16cd --- /dev/null +++ b/include/asm-arm/system.h @@ -0,0 +1,33 @@ +#ifndef __ASM_ARM_SYSTEM_H +#define __ASM_ARM_SYSTEM_H + +#include <linux/kernel.h> +#include <asm/proc-fns.h> + +extern void arm_malalignedptr(const char *, void *, volatile void *); +extern void arm_invalidptr(const char *, int); + +#define xchg(ptr,x) \ + ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) + +#define tas(ptr) (xchg((ptr),1)) + +/* + * switch_to(prev, next) should switch from task `prev' to `next' + * `prev' will never be the same as `next'. + * + * `next' and `prev' should be struct task_struct, but it isn't always defined + */ +#define switch_to(prev,next) processor._switch_to(prev,next) + +/* + * Include processor dependent parts + */ +#include <asm/proc/system.h> +#include <asm/arch/system.h> + +#define mb() __asm__ __volatile__ ("" : : : "memory") +#define nop() __asm__ __volatile__("mov r0,r0\n\t"); + +#endif + diff --git a/include/asm-arm/termbits.h b/include/asm-arm/termbits.h new file mode 100644 index 000000000..435833937 --- /dev/null +++ b/include/asm-arm/termbits.h @@ -0,0 +1,161 @@ +#ifndef __ASM_ARM_TERMBITS_H +#define __ASM_ARM_TERMBITS_H + +#include <linux/posix_types.h> + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0100000 +#define FF0 0000000 +#define FF1 0100000 + +/* c_cflag bit meaning */ +#define CBAUD 0010017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define CBAUDEX 0010000 +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define B460800 0010004 +#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CMSPAR 010000000000 /* mark or space (stick) parity */ +#define CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif /* __ASM_ARM_TERMBITS_H */ diff --git a/include/asm-arm/termios.h b/include/asm-arm/termios.h new file mode 100644 index 000000000..9ad62d154 --- /dev/null +++ b/include/asm-arm/termios.h @@ -0,0 +1,98 @@ +#ifndef __ASM_ARM_TERMIOS_H +#define __ASM_ARM_TERMIOS_H + +#include <asm/termbits.h> +#include <asm/ioctls.h> + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +#ifdef __KERNEL__ +/* intr=^C quit=^| erase=del kill=^U + eof=^D vtime=\0 vmin=\1 sxtc=\0 + start=^Q stop=^S susp=^Z eol=\0 + reprint=^R discard=^U werase=^W lnext=^V + eol2=\0 +*/ +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" +#endif + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ + +/* line disciplines */ +#define N_TTY 0 +#define N_SLIP 1 +#define N_MOUSE 2 +#define N_PPP 3 +#define N_STRIP 4 +#define N_AX25 5 +#define N_X25 6 /* X.25 async */ + +#ifdef __KERNEL__ + +#include <linux/string.h> + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ + unsigned short __tmp; \ + get_user(__tmp,&(termio)->x); \ + *(unsigned short *) &(termios)->x = __tmp; \ +} + +#define user_termio_to_kernel_termios(termios, termio) \ +({ \ + SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ + copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ +}) + +/* + * Translate a "termios" structure into a "termio". Ugh. + */ +#define kernel_termios_to_user_termio(termio, termios) \ +({ \ + put_user((termios)->c_iflag, &(termio)->c_iflag); \ + put_user((termios)->c_oflag, &(termio)->c_oflag); \ + put_user((termios)->c_cflag, &(termio)->c_cflag); \ + put_user((termios)->c_lflag, &(termio)->c_lflag); \ + put_user((termios)->c_line, &(termio)->c_line); \ + copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ +}) + +#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) +#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) + +#endif /* __KERNEL__ */ + +#endif /* __ASM_ARM_TERMIOS_H */ diff --git a/include/asm-arm/timex.h b/include/asm-arm/timex.h new file mode 100644 index 000000000..29ae27df2 --- /dev/null +++ b/include/asm-arm/timex.h @@ -0,0 +1,13 @@ +/* + * linux/include/asm-arm/timex.h + * + * Architecture Specific TIME specifications + * + * Copyright (C) 1997,1998 Russell King + */ +#ifndef _ASMARM_TIMEX_H +#define _ASMARM_TIMEX_H + +#include <asm/arch/timex.h> + +#endif diff --git a/include/asm-arm/types.h b/include/asm-arm/types.h new file mode 100644 index 000000000..38ea29855 --- /dev/null +++ b/include/asm-arm/types.h @@ -0,0 +1,45 @@ +#ifndef __ASM_ARM_TYPES_H +#define __ASM_ARM_TYPES_H + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#endif /* __KERNEL__ */ + +#endif + diff --git a/include/asm-arm/uaccess.h b/include/asm-arm/uaccess.h new file mode 100644 index 000000000..30b4950fe --- /dev/null +++ b/include/asm-arm/uaccess.h @@ -0,0 +1,194 @@ +#ifndef _ASMARM_UACCESS_H +#define _ASMARM_UACCESS_H + +/* + * User space memory access functions + */ +#include <linux/sched.h> + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry +{ + unsigned long insn, fixup; +}; + +/* Returns 0 if exception not found and fixup otherwise. */ +extern unsigned long search_exception_table(unsigned long); + +#include <asm/proc/uaccess.h> + +extern inline int verify_area(int type, const void * addr, unsigned long size) +{ + return access_ok(type,addr,size) ? 0 : -EFAULT; +} + +/* + * Single-value transfer routines. They automatically use the right + * size if we just have the right pointer type. + * + * The "__xxx" versions of the user access functions do not verify the + * address space - it must have been done previously with a separate + * "access_ok()" call. + * + * The "xxx_ret" versions return constant specified in the third + * argument if something bad happens. + */ +#define get_user(x,p) __get_user_check((x),(p),sizeof(*(p))) +#define __get_user(x,p) __get_user_nocheck((x),(p),sizeof(*(p))) +#define get_user_ret(x,p,r) ({ if (get_user(x,p)) return r; }) +#define __get_user_ret(x,p,r) ({ if (__get_user(x,p)) return r; }) + +#define put_user(x,p) __put_user_check((__typeof(*(p)))(x),(p),sizeof(*(p))) +#define __put_user(x,p) __put_user_nocheck((__typeof(*(p)))(x),(p),sizeof(*(p))) +#define put_user_ret(x,p,r) ({ if (put_user(x,p)) return r; }) +#define __put_user_ret(x,p,r) ({ if (__put_user(x,p)) return r; }) + +static __inline__ unsigned long copy_from_user(void *to, const void *from, unsigned long n) +{ + if (access_ok(VERIFY_READ, from, n)) + __do_copy_from_user(to, from, n); + return n; +} + +static __inline__ unsigned long __copy_from_user(void *to, const void *from, unsigned long n) +{ + __do_copy_from_user(to, from, n); + return n; +} + +#define copy_from_user_ret(t,f,n,r) \ + ({ if (copy_from_user(t,f,n)) return r; }) + +static __inline__ unsigned long copy_to_user(void *to, const void *from, unsigned long n) +{ + if (access_ok(VERIFY_WRITE, to, n)) + __do_copy_to_user(to, from, n); + return n; +} + +static __inline__ unsigned long __copy_to_user(void *to, const void *from, unsigned long n) +{ + __do_copy_to_user(to, from, n); + return n; +} + +#define copy_to_user_ret(t,f,n,r) \ + ({ if (copy_to_user(t,f,n)) return r; }) + +static __inline__ unsigned long clear_user (void *to, unsigned long n) +{ + if (access_ok(VERIFY_WRITE, to, n)) + __do_clear_user(to, n); + return n; +} + +static __inline__ unsigned long __clear_user (void *to, unsigned long n) +{ + __do_clear_user(to, n); + return n; +} + +static __inline__ long strncpy_from_user (char *dst, const char *src, long count) +{ + long res = -EFAULT; + if (access_ok(VERIFY_READ, src, 1)) + __do_strncpy_from_user(dst, src, count, res); + return res; +} + +static __inline__ long __strncpy_from_user (char *dst, const char *src, long count) +{ + long res; + __do_strncpy_from_user(dst, src, count, res); + return res; +} + +extern __inline__ long strlen_user (const char *s) +{ + unsigned long res = 0; + + if (__addr_ok(s)) + __do_strlen_user (s, res); + + return res; +} + +/* + * These are the work horses of the get/put_user functions + */ +#define __get_user_check(x,ptr,size) \ +({ \ + long __gu_err = -EFAULT, __gu_val = 0; \ + const __typeof__(*(ptr)) *__gu_addr = (ptr); \ + if (access_ok(VERIFY_READ,__gu_addr,size)) \ + __get_user_size(__gu_val,__gu_addr,(size),__gu_err); \ + (x) = (__typeof__(*(ptr)))__gu_val; \ + __gu_err; \ +}) + +#define __get_user_nocheck(x,ptr,size) \ +({ \ + long __gu_err = 0, __gu_val = 0; \ + __get_user_size(__gu_val,(ptr),(size),__gu_err); \ + (x) = (__typeof__(*(ptr)))__gu_val; \ + __gu_err; \ +}) + +#define __put_user_check(x,ptr,size) \ +({ \ + long __pu_err = -EFAULT; \ + __typeof__(*(ptr)) *__pu_addr = (ptr); \ + if (access_ok(VERIFY_WRITE,__pu_addr,size)) \ + __put_user_size((x),__pu_addr,(size),__pu_err); \ + __pu_err; \ +}) + +#define __put_user_nocheck(x,ptr,size) \ +({ \ + long __pu_err = 0; \ + __put_user_size((x),(ptr),(size),__pu_err); \ + __pu_err; \ +}) + +extern long __get_user_bad(void); + +#define __get_user_size(x,ptr,size,retval) \ +do { \ + retval = 0; \ + switch (size) { \ + case 1: __get_user_asm_byte(x,ptr,retval); break; \ + case 2: __get_user_asm_half(x,ptr,retval); break; \ + case 4: __get_user_asm_word(x,ptr,retval); break; \ + default: (x) = __get_user_bad(); \ + } \ +} while (0) + +extern long __put_user_bad(void); + +#define __put_user_size(x,ptr,size,retval) \ +do { \ + retval = 0; \ + switch (size) { \ + case 1: __put_user_asm_byte(x,ptr,retval); break; \ + case 2: __put_user_asm_half(x,ptr,retval); break; \ + case 4: __put_user_asm_word(x,ptr,retval); break; \ + default: __put_user_bad(); \ + } \ +} while (0) + +#endif /* _ASMARM_UACCESS_H */ diff --git a/include/asm-arm/ucontext.h b/include/asm-arm/ucontext.h new file mode 100644 index 000000000..f85313013 --- /dev/null +++ b/include/asm-arm/ucontext.h @@ -0,0 +1,12 @@ +#ifndef _ASMARM_UCONTEXT_H +#define _ASMARM_UCONTEXT_H + +struct ucontext { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + struct sigcontext uc_mcontext; + sigset_t uc_sigmask; /* mask last for extensibility */ +}; + +#endif /* !_ASMARM_UCONTEXT_H */ diff --git a/include/asm-arm/unaligned.h b/include/asm-arm/unaligned.h new file mode 100644 index 000000000..9b86bd415 --- /dev/null +++ b/include/asm-arm/unaligned.h @@ -0,0 +1,59 @@ +#ifndef __ARM_UNALIGNED_H +#define __ARM_UNALIGNED_H + +#define get_unaligned(ptr) \ + ((__typeof__(*(ptr)))__get_unaligned((ptr), sizeof(*(ptr)))) + +#define put_unaligned(val, ptr) \ + __put_unaligned((unsigned long)(val), (ptr), sizeof(*(ptr))) + +extern void bad_unaligned_access_length (void); + +extern inline unsigned long __get_unaligned(const void *ptr, size_t size) +{ + unsigned long val; + switch (size) { + case 1: + val = *(const unsigned char *)ptr; + break; + + case 2: + val = ((const unsigned char *)ptr)[0] | (((const unsigned char *)ptr)[1] << 8); + break; + + case 4: + val = ((const unsigned char *)ptr)[0] | (((const unsigned char *)ptr)[1] << 8) | + (((const unsigned char *)ptr)[2]) << 16 | (((const unsigned char *)ptr)[3] << 24); + break; + + default: + bad_unaligned_access_length (); + } + return val; +} + +extern inline void __put_unaligned(unsigned long val, void *ptr, size_t size) +{ + switch (size) { + case 1: + *(unsigned char *)ptr = val; + break; + + case 2: + ((unsigned char *)ptr)[0] = val; + ((unsigned char *)ptr)[1] = val >> 8; + break; + + case 4: + ((unsigned char *)ptr)[0] = val; + ((unsigned char *)ptr)[1] = val >> 8; + ((unsigned char *)ptr)[2] = val >> 16; + ((unsigned char *)ptr)[3] = val >> 24; + break; + + default: + bad_unaligned_access_length (); + } +} + +#endif diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h new file mode 100644 index 000000000..31b407dbb --- /dev/null +++ b/include/asm-arm/unistd.h @@ -0,0 +1,371 @@ +#ifndef __ASM_ARM_UNISTD_H +#define __ASM_ARM_UNISTD_H + +#define __NR_SYSCALL_BASE 0x900000 + +/* + * This file contains the system call numbers. + */ + +#define __NR_setup (__NR_SYSCALL_BASE+ 0) /* used only by init, to get system going */ +#define __NR_exit (__NR_SYSCALL_BASE+ 1) +#define __NR_fork (__NR_SYSCALL_BASE+ 2) +#define __NR_read (__NR_SYSCALL_BASE+ 3) +#define __NR_write (__NR_SYSCALL_BASE+ 4) +#define __NR_open (__NR_SYSCALL_BASE+ 5) +#define __NR_close (__NR_SYSCALL_BASE+ 6) +#define __NR_waitpid (__NR_SYSCALL_BASE+ 7) +#define __NR_creat (__NR_SYSCALL_BASE+ 8) +#define __NR_link (__NR_SYSCALL_BASE+ 9) +#define __NR_unlink (__NR_SYSCALL_BASE+ 10) +#define __NR_execve (__NR_SYSCALL_BASE+ 11) +#define __NR_chdir (__NR_SYSCALL_BASE+ 12) +#define __NR_time (__NR_SYSCALL_BASE+ 13) +#define __NR_mknod (__NR_SYSCALL_BASE+ 14) +#define __NR_chmod (__NR_SYSCALL_BASE+ 15) +#define __NR_chown (__NR_SYSCALL_BASE+ 16) +#define __NR_break (__NR_SYSCALL_BASE+ 17) +#define __NR_oldstat (__NR_SYSCALL_BASE+ 18) +#define __NR_lseek (__NR_SYSCALL_BASE+ 19) +#define __NR_getpid (__NR_SYSCALL_BASE+ 20) +#define __NR_mount (__NR_SYSCALL_BASE+ 21) +#define __NR_umount (__NR_SYSCALL_BASE+ 22) +#define __NR_setuid (__NR_SYSCALL_BASE+ 23) +#define __NR_getuid (__NR_SYSCALL_BASE+ 24) +#define __NR_stime (__NR_SYSCALL_BASE+ 25) +#define __NR_ptrace (__NR_SYSCALL_BASE+ 26) +#define __NR_alarm (__NR_SYSCALL_BASE+ 27) +#define __NR_oldfstat (__NR_SYSCALL_BASE+ 28) +#define __NR_pause (__NR_SYSCALL_BASE+ 29) +#define __NR_utime (__NR_SYSCALL_BASE+ 30) +#define __NR_stty (__NR_SYSCALL_BASE+ 31) +#define __NR_gtty (__NR_SYSCALL_BASE+ 32) +#define __NR_access (__NR_SYSCALL_BASE+ 33) +#define __NR_nice (__NR_SYSCALL_BASE+ 34) +#define __NR_ftime (__NR_SYSCALL_BASE+ 35) +#define __NR_sync (__NR_SYSCALL_BASE+ 36) +#define __NR_kill (__NR_SYSCALL_BASE+ 37) +#define __NR_rename (__NR_SYSCALL_BASE+ 38) +#define __NR_mkdir (__NR_SYSCALL_BASE+ 39) +#define __NR_rmdir (__NR_SYSCALL_BASE+ 40) +#define __NR_dup (__NR_SYSCALL_BASE+ 41) +#define __NR_pipe (__NR_SYSCALL_BASE+ 42) +#define __NR_times (__NR_SYSCALL_BASE+ 43) +#define __NR_prof (__NR_SYSCALL_BASE+ 44) +#define __NR_brk (__NR_SYSCALL_BASE+ 45) +#define __NR_setgid (__NR_SYSCALL_BASE+ 46) +#define __NR_getgid (__NR_SYSCALL_BASE+ 47) +#define __NR_signal (__NR_SYSCALL_BASE+ 48) +#define __NR_geteuid (__NR_SYSCALL_BASE+ 49) +#define __NR_getegid (__NR_SYSCALL_BASE+ 50) +#define __NR_acct (__NR_SYSCALL_BASE+ 51) +#define __NR_phys (__NR_SYSCALL_BASE+ 52) +#define __NR_lock (__NR_SYSCALL_BASE+ 53) +#define __NR_ioctl (__NR_SYSCALL_BASE+ 54) +#define __NR_fcntl (__NR_SYSCALL_BASE+ 55) +#define __NR_mpx (__NR_SYSCALL_BASE+ 56) +#define __NR_setpgid (__NR_SYSCALL_BASE+ 57) +#define __NR_ulimit (__NR_SYSCALL_BASE+ 58) +#define __NR_oldolduname (__NR_SYSCALL_BASE+ 59) +#define __NR_umask (__NR_SYSCALL_BASE+ 60) +#define __NR_chroot (__NR_SYSCALL_BASE+ 61) +#define __NR_ustat (__NR_SYSCALL_BASE+ 62) +#define __NR_dup2 (__NR_SYSCALL_BASE+ 63) +#define __NR_getppid (__NR_SYSCALL_BASE+ 64) +#define __NR_getpgrp (__NR_SYSCALL_BASE+ 65) +#define __NR_setsid (__NR_SYSCALL_BASE+ 66) +#define __NR_sigaction (__NR_SYSCALL_BASE+ 67) +#define __NR_sgetmask (__NR_SYSCALL_BASE+ 68) +#define __NR_ssetmask (__NR_SYSCALL_BASE+ 69) +#define __NR_setreuid (__NR_SYSCALL_BASE+ 70) +#define __NR_setregid (__NR_SYSCALL_BASE+ 71) +#define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72) +#define __NR_sigpending (__NR_SYSCALL_BASE+ 73) +#define __NR_sethostname (__NR_SYSCALL_BASE+ 74) +#define __NR_setrlimit (__NR_SYSCALL_BASE+ 75) +#define __NR_getrlimit (__NR_SYSCALL_BASE+ 76) +#define __NR_getrusage (__NR_SYSCALL_BASE+ 77) +#define __NR_gettimeofday (__NR_SYSCALL_BASE+ 78) +#define __NR_settimeofday (__NR_SYSCALL_BASE+ 79) +#define __NR_getgroups (__NR_SYSCALL_BASE+ 80) +#define __NR_setgroups (__NR_SYSCALL_BASE+ 81) +#define __NR_select (__NR_SYSCALL_BASE+ 82) +#define __NR_symlink (__NR_SYSCALL_BASE+ 83) +#define __NR_oldlstat (__NR_SYSCALL_BASE+ 84) +#define __NR_readlink (__NR_SYSCALL_BASE+ 85) +#define __NR_uselib (__NR_SYSCALL_BASE+ 86) +#define __NR_swapon (__NR_SYSCALL_BASE+ 87) +#define __NR_reboot (__NR_SYSCALL_BASE+ 88) +#define __NR_readdir (__NR_SYSCALL_BASE+ 89) +#define __NR_mmap (__NR_SYSCALL_BASE+ 90) +#define __NR_munmap (__NR_SYSCALL_BASE+ 91) +#define __NR_truncate (__NR_SYSCALL_BASE+ 92) +#define __NR_ftruncate (__NR_SYSCALL_BASE+ 93) +#define __NR_fchmod (__NR_SYSCALL_BASE+ 94) +#define __NR_fchown (__NR_SYSCALL_BASE+ 95) +#define __NR_getpriority (__NR_SYSCALL_BASE+ 96) +#define __NR_setpriority (__NR_SYSCALL_BASE+ 97) +#define __NR_profil (__NR_SYSCALL_BASE+ 98) +#define __NR_statfs (__NR_SYSCALL_BASE+ 99) +#define __NR_fstatfs (__NR_SYSCALL_BASE+100) +#define __NR_ioperm (__NR_SYSCALL_BASE+101) +#define __NR_socketcall (__NR_SYSCALL_BASE+102) +#define __NR_syslog (__NR_SYSCALL_BASE+103) +#define __NR_setitimer (__NR_SYSCALL_BASE+104) +#define __NR_getitimer (__NR_SYSCALL_BASE+105) +#define __NR_stat (__NR_SYSCALL_BASE+106) +#define __NR_lstat (__NR_SYSCALL_BASE+107) +#define __NR_fstat (__NR_SYSCALL_BASE+108) +#define __NR_olduname (__NR_SYSCALL_BASE+109) +#define __NR_iopl (__NR_SYSCALL_BASE+110) +#define __NR_vhangup (__NR_SYSCALL_BASE+111) +#define __NR_idle (__NR_SYSCALL_BASE+112) +#define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */ +#define __NR_wait4 (__NR_SYSCALL_BASE+114) +#define __NR_swapoff (__NR_SYSCALL_BASE+115) +#define __NR_sysinfo (__NR_SYSCALL_BASE+116) +#define __NR_ipc (__NR_SYSCALL_BASE+117) +#define __NR_fsync (__NR_SYSCALL_BASE+118) +#define __NR_sigreturn (__NR_SYSCALL_BASE+119) +#define __NR_clone (__NR_SYSCALL_BASE+120) +#define __NR_setdomainname (__NR_SYSCALL_BASE+121) +#define __NR_uname (__NR_SYSCALL_BASE+122) +#define __NR_modify_ldt (__NR_SYSCALL_BASE+123) +#define __NR_adjtimex (__NR_SYSCALL_BASE+124) +#define __NR_mprotect (__NR_SYSCALL_BASE+125) +#define __NR_sigprocmask (__NR_SYSCALL_BASE+126) +#define __NR_create_module (__NR_SYSCALL_BASE+127) +#define __NR_init_module (__NR_SYSCALL_BASE+128) +#define __NR_delete_module (__NR_SYSCALL_BASE+129) +#define __NR_get_kernel_syms (__NR_SYSCALL_BASE+130) +#define __NR_quotactl (__NR_SYSCALL_BASE+131) +#define __NR_getpgid (__NR_SYSCALL_BASE+132) +#define __NR_fchdir (__NR_SYSCALL_BASE+133) +#define __NR_bdflush (__NR_SYSCALL_BASE+134) +#define __NR_sysfs (__NR_SYSCALL_BASE+135) +#define __NR_personality (__NR_SYSCALL_BASE+136) +#define __NR_afs_syscall (__NR_SYSCALL_BASE+137) /* Syscall for Andrew File System */ +#define __NR_setfsuid (__NR_SYSCALL_BASE+138) +#define __NR_setfsgid (__NR_SYSCALL_BASE+139) +#define __NR__llseek (__NR_SYSCALL_BASE+140) +#define __NR_getdents (__NR_SYSCALL_BASE+141) +#define __NR__newselect (__NR_SYSCALL_BASE+142) +#define __NR_flock (__NR_SYSCALL_BASE+143) +#define __NR_msync (__NR_SYSCALL_BASE+144) +#define __NR_readv (__NR_SYSCALL_BASE+145) +#define __NR_writev (__NR_SYSCALL_BASE+146) +#define __NR_getsid (__NR_SYSCALL_BASE+147) +#define __NR_fdatasync (__NR_SYSCALL_BASE+148) +#define __NR__sysctl (__NR_SYSCALL_BASE+149) +#define __NR_mlock (__NR_SYSCALL_BASE+150) +#define __NR_munlock (__NR_SYSCALL_BASE+151) +#define __NR_mlockall (__NR_SYSCALL_BASE+152) +#define __NR_munlockall (__NR_SYSCALL_BASE+153) +#define __NR_sched_setparam (__NR_SYSCALL_BASE+154) +#define __NR_sched_getparam (__NR_SYSCALL_BASE+155) +#define __NR_sched_setscheduler (__NR_SYSCALL_BASE+156) +#define __NR_sched_getscheduler (__NR_SYSCALL_BASE+157) +#define __NR_sched_yield (__NR_SYSCALL_BASE+158) +#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE+159) +#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE+160) +#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE+161) +#define __NR_nanosleep (__NR_SYSCALL_BASE+162) +#define __NR_mremap (__NR_SYSCALL_BASE+163) +#define __NR_setresuid (__NR_SYSCALL_BASE+164) +#define __NR_getresuid (__NR_SYSCALL_BASE+165) +#define __NR_vm86 (__NR_SYSCALL_BASE+166) +#define __NR_query_module (__NR_SYSCALL_BASE+167) +#define __NR_poll (__NR_SYSCALL_BASE+168) +#define __NR_nfsservctl (__NR_SYSCALL_BASE+169) +#define __NR_setresgid (__NR_SYSCALL_BASE+170) +#define __NR_getresgid (__NR_SYSCALL_BASE+171) +#define __NR_prctl (__NR_SYSCALL_BASE+172) +#define __NR_rt_sigreturn (__NR_SYSCALL_BASE+173) +#define __NR_rt_sigaction (__NR_SYSCALL_BASE+174) +#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE+175) +#define __NR_rt_sigpending (__NR_SYSCALL_BASE+176) +#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE+177) +#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE+178) +#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE+179) +#define __NR_pread (__NR_SYSCALL_BASE+180) +#define __NR_pwrite (__NR_SYSCALL_BASE+181) + +#define __sys2(x) #x +#define __sys1(x) __sys2(x) + +#ifndef __syscall +#define __syscall(name) "swi\t" __sys1(__NR_##name) "\n\t" +#endif + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-125)) { \ + errno = -(res); \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + +#define _syscall0(type,name) \ +type name(void) { \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + "mov %0,r0" \ + :"=r" (__res) : : "r0","lr"); \ + __syscall_return(type,__res); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) { \ + long __res; \ + __asm__ __volatile__ ( \ + "mov\tr0,%1\n\t" \ + __syscall(name) \ + "mov %0,r0" \ + : "=r" (__res) \ + : "r" ((long)(arg1)) \ + : "r0","lr"); \ + __syscall_return(type,__res); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) { \ + long __res; \ + __asm__ __volatile__ ( \ + "mov\tr0,%1\n\t" \ + "mov\tr1,%2\n\t" \ + __syscall(name) \ + "mov\t%0,r0" \ + : "=r" (__res) \ + : "r" ((long)(arg1)),"r" ((long)(arg2)) \ + : "r0","r1","lr"); \ + __syscall_return(type,__res); \ +} + + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) { \ + long __res; \ + __asm__ __volatile__ ( \ + "mov\tr0,%1\n\t" \ + "mov\tr1,%2\n\t" \ + "mov\tr2,%3\n\t" \ + __syscall(name) \ + "mov\t%0,r0" \ + : "=r" (__res) \ + : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)) \ + : "r0","r1","r2","lr"); \ + __syscall_return(type,__res); \ +} + + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ + long __res; \ + __asm__ __volatile__ ( \ + "mov\tr0,%1\n\t" \ + "mov\tr1,%2\n\t" \ + "mov\tr2,%3\n\t" \ + "mov\tr3,%4\n\t" \ + __syscall(name) \ + "mov\t%0,r0" \ + : "=r" (__res) \ + : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)),"r" ((long)(arg4)) \ + : "r0","r1","r2","r3","lr"); \ + __syscall_return(type,__res); \ +} + + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \ + long __res; \ + __asm__ __volatile__ ( \ + "mov\tr0,%1\n\t" \ + "mov\tr1,%2\n\t" \ + "mov\tr2,%3\n\t" \ + "mov\tr3,%4\n\t" \ + "mov\tr4,%5\n\t" \ + __syscall(name) \ + "mov\t%0,r0" \ + : "=r" (__res) \ + : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)),"r" ((long)(arg4)), \ + "r" ((long)(arg5)) \ + : "r0","r1","r2","r3","r4","lr"); \ + __syscall_return(type,__res); \ +} + +#ifdef __KERNEL_SYSCALLS__ + +/* + * we need this inline - forking from kernel space will result + * in NO COPY ON WRITE (!!!), until an execve is executed. This + * is no problem, but for the stack. This is handled by not letting + * main() use the stack at all after fork(). Thus, no function + * calls - which means inline code for fork too, as otherwise we + * would use the stack upon exit from 'fork()'. + * + * Actually only pause and fork are needed inline, so that there + * won't be any messing with the stack from main(), but we define + * some others too. + */ +#define __NR__exit __NR_exit +static inline _syscall0(int,idle); +static inline _syscall0(int,fork); +static inline _syscall2(int,clone,unsigned long,flags,char *,esp); +static inline _syscall0(int,pause); +static inline _syscall1(int,setup,int,magic); +static inline _syscall0(int,sync); +static inline _syscall0(pid_t,setsid); +static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count); +static inline _syscall3(int,read,int,fd,char *,buf,off_t,count) +static inline _syscall1(int,dup,int,fd); +static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp); +static inline _syscall3(int,open,const char *,file,int,flag,int,mode); +static inline _syscall1(int,close,int,fd); +static inline _syscall1(int,_exit,int,exitcode); +static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options); + +static inline pid_t wait(int * wait_stat) +{ + return waitpid(-1,wait_stat,0); +} + + + +/* + * This is the mechanism for creating a new kernel thread. + * + * NOTE! Only a kernel-only process(ie the swapper or direct descendants + * who haven't done an "execve()") should use this: it will work within + * a system call from a "real" process, but the process memory space will + * not be free'd until both the parent and the child have exited. + */ +static inline pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +{ + long retval; + + __asm__ __volatile__(" + mov r0,%1 + mov r1,%2 + "__syscall(clone)" + teq r0, #0 + bne 1f + mov r0,%4 + mov lr, pc + mov pc, %3 + "__syscall(exit)" +1: mov %0,r0" + : "=r" (retval) + : "Ir" (flags | CLONE_VM), "Ir" (NULL), "r" (fn), "Ir" (arg) + : "r0","r1","r2","r3","lr"); + + return retval; +} + +#endif + +#endif /* __ASM_ARM_UNISTD_H */ + + + diff --git a/include/asm-arm/user.h b/include/asm-arm/user.h new file mode 100644 index 000000000..7afe1a2a9 --- /dev/null +++ b/include/asm-arm/user.h @@ -0,0 +1,82 @@ +#ifndef _ARM_USER_H +#define _ARM_USER_H + +#include <asm/page.h> +#include <linux/ptrace.h> +/* Core file format: The core file is written in such a way that gdb + can understand it and provide useful information to the user (under + linux we use the 'trad-core' bfd). There are quite a number of + obstacles to being able to view the contents of the floating point + registers, and until these are solved you will not be able to view the + contents of them. Actually, you can read in the core file and look at + the contents of the user struct to find out what the floating point + registers contain. + The actual file contents are as follows: + UPAGE: 1 page consisting of a user struct that tells gdb what is present + in the file. Directly after this is a copy of the task_struct, which + is currently not used by gdb, but it may come in useful at some point. + All of the registers are stored as part of the upage. The upage should + always be only one page. + DATA: The data area is stored. We use current->end_text to + current->brk to pick up all of the user variables, plus any memory + that may have been malloced. No attempt is made to determine if a page + is demand-zero or if a page is totally unused, we just cover the entire + range. All of the addresses are rounded in such a way that an integral + number of pages is written. + STACK: We need the stack information in order to get a meaningful + backtrace. We need to write the data from (esp) to + current->start_stack, so we round each of these off in order to be able + to write an integer number of pages. + The minimum core file size is 3 pages, or 12288 bytes. +*/ + +struct user_fp { + struct fp_reg { + unsigned int sign1:1; + unsigned int unused:15; + unsigned int sign2:1; + unsigned int exponent:14; + unsigned int j:1; + unsigned int mantissa1:31; + unsigned int mantissa0:32; + } fpregs[8]; + unsigned int fpsr:32; + unsigned int fpcr:32; +}; + +/* When the kernel dumps core, it starts by dumping the user struct - + this will be used by gdb to figure out where the data and stack segments + are within the file, and what virtual addresses to use. */ +struct user{ +/* We start with the registers, to mimic the way that "memory" is returned + from the ptrace(3,...) function. */ + struct pt_regs regs; /* Where the registers are actually stored */ +/* ptrace does not yet supply these. Someday.... */ + int u_fpvalid; /* True if math co-processor being used. */ + /* for this mess. Not yet used. */ +/* The rest of this junk is to help gdb figure out what goes where */ + unsigned long int u_tsize; /* Text segment size (pages). */ + unsigned long int u_dsize; /* Data segment size (pages). */ + unsigned long int u_ssize; /* Stack segment size (pages). */ + unsigned long start_code; /* Starting virtual address of text. */ + unsigned long start_stack; /* Starting virtual address of stack area. + This is actually the bottom of the stack, + the top of the stack is always found in the + esp register. */ + long int signal; /* Signal that caused the core dump. */ + int reserved; /* No longer used */ + struct pt_regs * u_ar0; /* Used by gdb to help find the values for */ + /* the registers. */ + unsigned long magic; /* To uniquely identify a core file */ + char u_comm[32]; /* User command that was responsible */ + int u_debugreg[8]; + struct user_fp u_fp; /* FP state */ + struct user_fp_struct * u_fp0;/* Used by gdb to help find the values for */ + /* the FP registers. */ +}; +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#endif /* _ARM_USER_H */ diff --git a/include/asm-arm/vt.h b/include/asm-arm/vt.h new file mode 100644 index 000000000..6c3573768 --- /dev/null +++ b/include/asm-arm/vt.h @@ -0,0 +1,8 @@ +#ifndef _ASMARM_VT_H +#define _ASMARM_VT_H + +#define VT_GETSCRINFO 0x56FD /* get screen info */ +#define VT_GETPALETTE 0x56FE /* get palette */ +#define VT_SETPALETTE 0x56FF /* set palette */ + +#endif /* _ASMARM_VT_H */ |