diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-01-07 02:33:00 +0000 |
---|---|---|
committer | <ralf@linux-mips.org> | 1997-01-07 02:33:00 +0000 |
commit | beb116954b9b7f3bb56412b2494b562f02b864b1 (patch) | |
tree | 120e997879884e1b9d93b265221b939d2ef1ade1 /include/asm-alpha | |
parent | 908d4681a1dc3792ecafbe64265783a86c4cccb6 (diff) |
Import of Linux/MIPS 2.1.14
Diffstat (limited to 'include/asm-alpha')
55 files changed, 4481 insertions, 927 deletions
diff --git a/include/asm-alpha/,fcntl.h, b/include/asm-alpha/,fcntl.h, deleted file mode 100644 index e69de29bb..000000000 --- a/include/asm-alpha/,fcntl.h, +++ /dev/null diff --git a/include/asm-alpha/a.out.h b/include/asm-alpha/a.out.h new file mode 100644 index 000000000..f1965d5ca --- /dev/null +++ b/include/asm-alpha/a.out.h @@ -0,0 +1,97 @@ +#ifndef __ALPHA_A_OUT_H__ +#define __ALPHA_A_OUT_H__ + +#include <linux/types.h> + +/* + * OSF/1 ECOFF header structs. ECOFF files consist of: + * - a file header (struct filehdr), + * - an a.out header (struct aouthdr), + * - one or more section headers (struct scnhdr). + * The filhdr's "f_nscns" field contains the + * number of section headers. + */ + +struct filehdr +{ + /* OSF/1 "file" header */ + __u16 f_magic, f_nscns; + __u32 f_timdat; + __u64 f_symptr; + __u32 f_nsyms; + __u16 f_opthdr, f_flags; +}; + +struct aouthdr +{ + __u64 info; /* after that it looks quite normal.. */ + __u64 tsize; + __u64 dsize; + __u64 bsize; + __u64 entry; + __u64 text_start; /* with a few additions that actually make sense */ + __u64 data_start; + __u64 bss_start; + __u32 gprmask, fprmask; /* bitmask of general & floating point regs used in binary */ + __u64 gpvalue; +}; + +struct scnhdr +{ + char s_name[8]; + __u64 s_paddr; + __u64 s_vaddr; + __u64 s_size; + __u64 s_scnptr; + __u64 s_relptr; + __u64 s_lnnoptr; + __u16 s_nreloc; + __u16 s_nlnno; + __u32 s_flags; +}; + +struct exec +{ + /* OSF/1 "file" header */ + struct filehdr fh; + struct aouthdr ah; +}; + +/* + * Define's so that the kernel exec code can access the a.out header + * fields... + */ +#define a_info ah.info +#define a_text ah.tsize +#define a_data ah.dsize +#define a_bss ah.bsize +#define a_entry ah.entry +#define a_textstart ah.text_start +#define a_datastart ah.data_start +#define a_bssstart ah.bss_start +#define a_gprmask ah.gprmask +#define a_fprmask ah.fprmask +#define a_gpvalue ah.gpvalue + +#define N_TXTADDR(x) ((x).a_textstart) +#define N_DATADDR(x) ((x).a_datastart) +#define N_BSSADDR(x) ((x).a_bssstart) +#define N_DRSIZE(x) 0 +#define N_TRSIZE(x) 0 +#define N_SYMSIZE(x) 0 + +#define AOUTHSZ sizeof(struct aouthdr) +#define SCNHSZ sizeof(struct scnhdr) +#define SCNROUND 16 + +#define N_TXTOFF(x) \ + ((long) N_MAGIC(x) == ZMAGIC ? 0 : \ + (sizeof(struct exec) + (x).fh.f_nscns*SCNHSZ + SCNROUND - 1) & ~(SCNROUND - 1)) + +#ifdef __KERNEL__ + +#define STACK_TOP (0x00120000000UL) + +#endif + +#endif /* __A_OUT_GNU_H__ */ diff --git a/include/asm-alpha/apecs.h b/include/asm-alpha/apecs.h new file mode 100644 index 000000000..0f38c8aac --- /dev/null +++ b/include/asm-alpha/apecs.h @@ -0,0 +1,561 @@ +#ifndef __ALPHA_APECS__H__ +#define __ALPHA_APECS__H__ + +#include <linux/types.h> + +/* + * APECS is the internal name for the 2107x chipset which provides + * memory controller and PCI access for the 21064 chip based systems. + * + * This file is based on: + * + * DECchip 21071-AA and DECchip 21072-AA Core Logic Chipsets + * Data Sheet + * + * EC-N0648-72 + * + * + * david.rusling@reo.mts.dec.com Initial Version. + * + */ +#include <linux/config.h> + +#ifdef CONFIG_ALPHA_XL +/* + An AVANTI *might* be an XL, and an XL has only 27 bits of ISA address + that get passed through the PCI<->ISA bridge chip. So we've gotta use + both windows to max out the physical memory we can DMA to. Sigh... + + If we try a window at 0 for 1GB as a work-around, we run into conflicts + with ISA/PCI bus memory which can't be relocated, like VGA aperture and + BIOS ROMs. So we must put the windows high enough to avoid these areas. + + We put window 1 at BUS 64Mb for 64Mb, mapping physical 0 to 64Mb-1, + and window 2 at BUS 512Mb for 512Mb, mapping physical 0 to 512Mb-1. + Yes, this does map 0 to 64Mb-1 twice, but only window 1 will actually + be used for that range (via virt_to_bus()). + + Note that we actually fudge the window 1 maximum as 48Mb instead of 64Mb, + to keep virt_to_bus() from returning an address in the first window, for + a data area that goes beyond the 64Mb first DMA window. Sigh... + The fudge factor MUST match with <asm/dma.h> MAX_DMA_ADDRESS, but + we can't just use that here, because of header file looping... :-( + + Window 1 will be used for all DMA from the ISA bus; yes, that does + limit what memory an ISA floppy or soundcard or Ethernet can touch, but + it's also a known limitation on other platforms as well. We use the + same technique that is used on INTEL platforms with similar limitation: + set MAX_DMA_ADDRESS and clear some pages' DMAable flags during mem_init(). + We trust that any ISA bus device drivers will *always* ask for DMAable + memory explicitly via kmalloc()/get_free_pages() flags arguments. + + Note that most PCI bus devices' drivers do *not* explicitly ask for + DMAable memory; they count on being able to DMA to any memory they + get from kmalloc()/get_free_pages(). They will also use window 1 for + any physical memory accesses below 64Mb; the rest will be handled by + window 2, maxing out at 512Mb of memory. I trust this is enough... :-) + + Finally, the reason we make window 2 start at 512Mb for 512Mb, is so that + we can allocate PCI bus devices' memory starting at 1Gb and up, to ensure + that no conflicts occur and bookkeeping is simplified (ie we don't + try to fill the gap between the two windows, we just go above the top). + + Note that the XL is treated differently from the AVANTI, even though + for most other things they are identical. It didn't seem reasonable to + make the AVANTI support pay for the limitations of the XL. It is true, + however, that an XL kernel will run on an AVANTI without problems. + +*/ +#define APECS_XL_DMA_WIN1_BASE (64*1024*1024) +#define APECS_XL_DMA_WIN1_SIZE (64*1024*1024) +#define APECS_XL_DMA_WIN1_SIZE_PARANOID (48*1024*1024) +#define APECS_XL_DMA_WIN2_BASE (512*1024*1024) +#define APECS_XL_DMA_WIN2_SIZE (512*1024*1024) + +#else /* CONFIG_ALPHA_XL */ + +/* these are for normal APECS family machines, AVANTI/MUSTANG/EB64/PC64 */ +#define APECS_DMA_WIN_BASE (1024*1024*1024) +#define APECS_DMA_WIN_SIZE (1024*1024*1024) + +#endif /* CONFIG_ALPHA_XL */ + +/* + * 21071-DA Control and Status registers. + * These are used for PCI memory access. + */ +#define APECS_IOC_DCSR (IDENT_ADDR + 0x1A0000000UL) +#define APECS_IOC_PEAR (IDENT_ADDR + 0x1A0000020UL) +#define APECS_IOC_SEAR (IDENT_ADDR + 0x1A0000040UL) +#define APECS_IOC_DR1 (IDENT_ADDR + 0x1A0000060UL) +#define APECS_IOC_DR2 (IDENT_ADDR + 0x1A0000080UL) +#define APECS_IOC_DR3 (IDENT_ADDR + 0x1A00000A0UL) + +#define APECS_IOC_TB1R (IDENT_ADDR + 0x1A00000C0UL) +#define APECS_IOC_TB2R (IDENT_ADDR + 0x1A00000E0UL) + +#define APECS_IOC_PB1R (IDENT_ADDR + 0x1A0000100UL) +#define APECS_IOC_PB2R (IDENT_ADDR + 0x1A0000120UL) + +#define APECS_IOC_PM1R (IDENT_ADDR + 0x1A0000140UL) +#define APECS_IOC_PM2R (IDENT_ADDR + 0x1A0000160UL) + +#define APECS_IOC_HAXR0 (IDENT_ADDR + 0x1A0000180UL) +#define APECS_IOC_HAXR1 (IDENT_ADDR + 0x1A00001A0UL) +#define APECS_IOC_HAXR2 (IDENT_ADDR + 0x1A00001C0UL) + +#define APECS_IOC_PMLT (IDENT_ADDR + 0x1A00001E0UL) + +#define APECS_IOC_TLBTAG0 (IDENT_ADDR + 0x1A0000200UL) +#define APECS_IOC_TLBTAG1 (IDENT_ADDR + 0x1A0000220UL) +#define APECS_IOC_TLBTAG2 (IDENT_ADDR + 0x1A0000240UL) +#define APECS_IOC_TLBTAG3 (IDENT_ADDR + 0x1A0000260UL) +#define APECS_IOC_TLBTAG4 (IDENT_ADDR + 0x1A0000280UL) +#define APECS_IOC_TLBTAG5 (IDENT_ADDR + 0x1A00002A0UL) +#define APECS_IOC_TLBTAG6 (IDENT_ADDR + 0x1A00002C0UL) +#define APECS_IOC_TLBTAG7 (IDENT_ADDR + 0x1A00002E0UL) + +#define APECS_IOC_TLBDATA0 (IDENT_ADDR + 0x1A0000300UL) +#define APECS_IOC_TLBDATA1 (IDENT_ADDR + 0x1A0000320UL) +#define APECS_IOC_TLBDATA2 (IDENT_ADDR + 0x1A0000340UL) +#define APECS_IOC_TLBDATA3 (IDENT_ADDR + 0x1A0000360UL) +#define APECS_IOC_TLBDATA4 (IDENT_ADDR + 0x1A0000380UL) +#define APECS_IOC_TLBDATA5 (IDENT_ADDR + 0x1A00003A0UL) +#define APECS_IOC_TLBDATA6 (IDENT_ADDR + 0x1A00003C0UL) +#define APECS_IOC_TLBDATA7 (IDENT_ADDR + 0x1A00003E0UL) + +#define APECS_IOC_TBIA (IDENT_ADDR + 0x1A0000400UL) + + +/* + * 21071-CA Control and Status registers. + * These are used to program memory timing, + * configure memory and initialise the B-Cache. + */ +#define APECS_MEM_GCR (IDENT_ADDR + 0x180000000UL) +#define APECS_MEM_EDSR (IDENT_ADDR + 0x180000040UL) +#define APECS_MEM_TAR (IDENT_ADDR + 0x180000060UL) +#define APECS_MEM_ELAR (IDENT_ADDR + 0x180000080UL) +#define APECS_MEM_EHAR (IDENT_ADDR + 0x1800000a0UL) +#define APECS_MEM_SFT_RST (IDENT_ADDR + 0x1800000c0UL) +#define APECS_MEM_LDxLAR (IDENT_ADDR + 0x1800000e0UL) +#define APECS_MEM_LDxHAR (IDENT_ADDR + 0x180000100UL) +#define APECS_MEM_GTR (IDENT_ADDR + 0x180000200UL) +#define APECS_MEM_RTR (IDENT_ADDR + 0x180000220UL) +#define APECS_MEM_VFPR (IDENT_ADDR + 0x180000240UL) +#define APECS_MEM_PDLDR (IDENT_ADDR + 0x180000260UL) +#define APECS_MEM_PDhDR (IDENT_ADDR + 0x180000280UL) + +/* Bank x Base Address Register */ +#define APECS_MEM_B0BAR (IDENT_ADDR + 0x180000800UL) +#define APECS_MEM_B1BAR (IDENT_ADDR + 0x180000820UL) +#define APECS_MEM_B2BAR (IDENT_ADDR + 0x180000840UL) +#define APECS_MEM_B3BAR (IDENT_ADDR + 0x180000860UL) +#define APECS_MEM_B4BAR (IDENT_ADDR + 0x180000880UL) +#define APECS_MEM_B5BAR (IDENT_ADDR + 0x1800008A0UL) +#define APECS_MEM_B6BAR (IDENT_ADDR + 0x1800008C0UL) +#define APECS_MEM_B7BAR (IDENT_ADDR + 0x1800008E0UL) +#define APECS_MEM_B8BAR (IDENT_ADDR + 0x180000900UL) + +/* Bank x Configuration Register */ +#define APECS_MEM_B0BCR (IDENT_ADDR + 0x180000A00UL) +#define APECS_MEM_B1BCR (IDENT_ADDR + 0x180000A20UL) +#define APECS_MEM_B2BCR (IDENT_ADDR + 0x180000A40UL) +#define APECS_MEM_B3BCR (IDENT_ADDR + 0x180000A60UL) +#define APECS_MEM_B4BCR (IDENT_ADDR + 0x180000A80UL) +#define APECS_MEM_B5BCR (IDENT_ADDR + 0x180000AA0UL) +#define APECS_MEM_B6BCR (IDENT_ADDR + 0x180000AC0UL) +#define APECS_MEM_B7BCR (IDENT_ADDR + 0x180000AE0UL) +#define APECS_MEM_B8BCR (IDENT_ADDR + 0x180000B00UL) + +/* Bank x Timing Register A */ +#define APECS_MEM_B0TRA (IDENT_ADDR + 0x180000C00UL) +#define APECS_MEM_B1TRA (IDENT_ADDR + 0x180000C20UL) +#define APECS_MEM_B2TRA (IDENT_ADDR + 0x180000C40UL) +#define APECS_MEM_B3TRA (IDENT_ADDR + 0x180000C60UL) +#define APECS_MEM_B4TRA (IDENT_ADDR + 0x180000C80UL) +#define APECS_MEM_B5TRA (IDENT_ADDR + 0x180000CA0UL) +#define APECS_MEM_B6TRA (IDENT_ADDR + 0x180000CC0UL) +#define APECS_MEM_B7TRA (IDENT_ADDR + 0x180000CE0UL) +#define APECS_MEM_B8TRA (IDENT_ADDR + 0x180000D00UL) + +/* Bank x Timing Register B */ +#define APECS_MEM_B0TRB (IDENT_ADDR + 0x180000E00UL) +#define APECS_MEM_B1TRB (IDENT_ADDR + 0x180000E20UL) +#define APECS_MEM_B2TRB (IDENT_ADDR + 0x180000E40UL) +#define APECS_MEM_B3TRB (IDENT_ADDR + 0x180000E60UL) +#define APECS_MEM_B4TRB (IDENT_ADDR + 0x180000E80UL) +#define APECS_MEM_B5TRB (IDENT_ADDR + 0x180000EA0UL) +#define APECS_MEM_B6TRB (IDENT_ADDR + 0x180000EC0UL) +#define APECS_MEM_B7TRB (IDENT_ADDR + 0x180000EE0UL) +#define APECS_MEM_B8TRB (IDENT_ADDR + 0x180000F00UL) + + +/* + * Memory spaces: + */ +#define APECS_IACK_SC (IDENT_ADDR + 0x1b0000000UL) +#define APECS_CONF (IDENT_ADDR + 0x1e0000000UL) +#define APECS_IO (IDENT_ADDR + 0x1c0000000UL) +#define APECS_SPARSE_MEM (IDENT_ADDR + 0x200000000UL) +#define APECS_DENSE_MEM (IDENT_ADDR + 0x300000000UL) + +/* + * Bit definitions for I/O Controller status register 0: + */ +#define APECS_IOC_STAT0_CMD 0xf +#define APECS_IOC_STAT0_ERR (1<<4) +#define APECS_IOC_STAT0_LOST (1<<5) +#define APECS_IOC_STAT0_THIT (1<<6) +#define APECS_IOC_STAT0_TREF (1<<7) +#define APECS_IOC_STAT0_CODE_SHIFT 8 +#define APECS_IOC_STAT0_CODE_MASK 0x7 +#define APECS_IOC_STAT0_P_NBR_SHIFT 13 +#define APECS_IOC_STAT0_P_NBR_MASK 0x7ffff + +#define HAE_ADDRESS APECS_IOC_HAXR1 + +#ifdef __KERNEL__ + +/* + * Translate physical memory address as seen on (PCI) bus into + * a kernel virtual address and vv. + */ +/* NOTE: we fudge the window 1 maximum as 48Mb instead of 64Mb, to prevent + virt_to_bus() from returning an address in the first window, for a + data area that goes beyond the 64Mb first DMA window. Sigh... + This MUST match with <asm/dma.h> MAX_DMA_ADDRESS for consistency, but + we can't just use that here, because of header file looping... :-( +*/ +extern inline unsigned long virt_to_bus(void * address) +{ + unsigned long paddr = virt_to_phys(address); +#ifdef CONFIG_ALPHA_XL + if (paddr < APECS_XL_DMA_WIN1_SIZE_PARANOID) + return paddr + APECS_XL_DMA_WIN1_BASE; + else + return paddr + APECS_XL_DMA_WIN2_BASE; /* win 2 xlates to 0 also */ +#else /* CONFIG_ALPHA_XL */ + return paddr + APECS_DMA_WIN_BASE; +#endif /* CONFIG_ALPHA_XL */ +} + +extern inline void * bus_to_virt(unsigned long address) +{ + /* + * This check is a sanity check but also ensures that bus + * address 0 maps to virtual address 0 which is useful to + * detect null "pointers" (the NCR driver is much simpler if + * NULL pointers are preserved). + */ +#ifdef CONFIG_ALPHA_XL + if (address < APECS_XL_DMA_WIN1_BASE) + return 0; + else if (address < (APECS_XL_DMA_WIN1_BASE + APECS_XL_DMA_WIN1_SIZE)) + return phys_to_virt(address - APECS_XL_DMA_WIN1_BASE); + else /* should be more checking here, maybe? */ + return phys_to_virt(address - APECS_XL_DMA_WIN2_BASE); +#else /* CONFIG_ALPHA_XL */ + if (address < APECS_DMA_WIN_BASE) + return 0; + return phys_to_virt(address - APECS_DMA_WIN_BASE); +#endif /* CONFIG_ALPHA_XL */ +} + +/* + * I/O functions: + * + * Unlike Jensen, the APECS machines have no concept of local + * I/O---everything goes over the PCI bus. + * + * There is plenty room for optimization here. In particular, + * the Alpha's insb/insw/extb/extw should be useful in moving + * data to/from the right byte-lanes. + */ + +#define vuip volatile unsigned int * + +extern inline unsigned int __inb(unsigned long addr) +{ + long result = *(vuip) ((addr << 5) + APECS_IO + 0x00); + result >>= (addr & 3) * 8; + return 0xffUL & result; +} + +extern inline void __outb(unsigned char b, unsigned long addr) +{ + unsigned int w; + + asm ("insbl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b)); + *(vuip) ((addr << 5) + APECS_IO + 0x00) = w; + mb(); +} + +extern inline unsigned int __inw(unsigned long addr) +{ + long result = *(vuip) ((addr << 5) + APECS_IO + 0x08); + result >>= (addr & 3) * 8; + return 0xffffUL & result; +} + +extern inline void __outw(unsigned short b, unsigned long addr) +{ + unsigned int w; + + asm ("inswl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b)); + *(vuip) ((addr << 5) + APECS_IO + 0x08) = w; + mb(); +} + +extern inline unsigned int __inl(unsigned long addr) +{ + return *(vuip) ((addr << 5) + APECS_IO + 0x18); +} + +extern inline void __outl(unsigned int b, unsigned long addr) +{ + *(vuip) ((addr << 5) + APECS_IO + 0x18) = b; + mb(); +} + + +/* + * Memory functions. 64-bit and 32-bit accesses are done through + * dense memory space, everything else through sparse space. + */ +extern inline unsigned long __readb(unsigned long addr) +{ + unsigned long result, shift, msb; + + shift = (addr & 0x3) * 8; + if (addr >= (1UL << 24)) { + msb = addr & 0xf8000000; + addr -= msb; + if (msb != hae.cache) { + set_hae(msb); + } + } + result = *(vuip) ((addr << 5) + APECS_SPARSE_MEM + 0x00); + result >>= shift; + return 0xffUL & result; +} + +extern inline unsigned long __readw(unsigned long addr) +{ + unsigned long result, shift, msb; + + shift = (addr & 0x3) * 8; + if (addr >= (1UL << 24)) { + msb = addr & 0xf8000000; + addr -= msb; + if (msb != hae.cache) { + set_hae(msb); + } + } + result = *(vuip) ((addr << 5) + APECS_SPARSE_MEM + 0x08); + result >>= shift; + return 0xffffUL & result; +} + +extern inline unsigned long __readl(unsigned long addr) +{ + return *(vuip) (addr + APECS_DENSE_MEM); +} + +extern inline void __writeb(unsigned char b, unsigned long addr) +{ + unsigned long msb; + + if (addr >= (1UL << 24)) { + msb = addr & 0xf8000000; + addr -= msb; + if (msb != hae.cache) { + set_hae(msb); + } + } + *(vuip) ((addr << 5) + APECS_SPARSE_MEM + 0x00) = b * 0x01010101; +} + +extern inline void __writew(unsigned short b, unsigned long addr) +{ + unsigned long msb; + + if (addr >= (1UL << 24)) { + msb = addr & 0xf8000000; + addr -= msb; + if (msb != hae.cache) { + set_hae(msb); + } + } + *(vuip) ((addr << 5) + APECS_SPARSE_MEM + 0x08) = b * 0x00010001; +} + +extern inline void __writel(unsigned int b, unsigned long addr) +{ + *(vuip) (addr + APECS_DENSE_MEM) = b; +} + +#define inb(port) \ +(__builtin_constant_p((port))?__inb(port):_inb(port)) + +#define outb(x, port) \ +(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port))) + +#define readl(a) __readl((unsigned long)(a)) +#define writel(v,a) __writel((v),(unsigned long)(a)) + +#undef vuip + +extern unsigned long apecs_init (unsigned long mem_start, + unsigned long mem_end); + +#endif /* __KERNEL__ */ + +/* + * Data structure for handling APECS machine checks: + */ +#ifdef CONFIG_ALPHA_MIKASA +struct el_apecs_sysdata_mcheck { + unsigned long coma_gcr; + unsigned long coma_edsr; + unsigned long coma_ter; + unsigned long coma_elar; + unsigned long coma_ehar; + unsigned long coma_ldlr; + unsigned long coma_ldhr; + unsigned long coma_base0; + unsigned long coma_base1; + unsigned long coma_base2; + unsigned long coma_base3; + unsigned long coma_cnfg0; + unsigned long coma_cnfg1; + unsigned long coma_cnfg2; + unsigned long coma_cnfg3; + unsigned long epic_dcsr; + unsigned long epic_pear; + unsigned long epic_sear; + unsigned long epic_tbr1; + unsigned long epic_tbr2; + unsigned long epic_pbr1; + unsigned long epic_pbr2; + unsigned long epic_pmr1; + unsigned long epic_pmr2; + unsigned long epic_harx1; + unsigned long epic_harx2; + unsigned long epic_pmlt; + unsigned long epic_tag0; + unsigned long epic_tag1; + unsigned long epic_tag2; + unsigned long epic_tag3; + unsigned long epic_tag4; + unsigned long epic_tag5; + unsigned long epic_tag6; + unsigned long epic_tag7; + unsigned long epic_data0; + unsigned long epic_data1; + unsigned long epic_data2; + unsigned long epic_data3; + unsigned long epic_data4; + unsigned long epic_data5; + unsigned long epic_data6; + unsigned long epic_data7; + + unsigned long pceb_vid; + unsigned long pceb_did; + unsigned long pceb_revision; + unsigned long pceb_command; + unsigned long pceb_status; + unsigned long pceb_latency; + unsigned long pceb_control; + unsigned long pceb_arbcon; + unsigned long pceb_arbpri; + + unsigned long esc_id; + unsigned long esc_revision; + unsigned long esc_int0; + unsigned long esc_int1; + unsigned long esc_elcr0; + unsigned long esc_elcr1; + unsigned long esc_last_eisa; + unsigned long esc_nmi_stat; + + unsigned long pci_ir; + unsigned long pci_imr; + unsigned long svr_mgr; +}; +#else /* CONFIG_ALPHA_MIKASA */ +/* this for the normal APECS machines */ +struct el_apecs_sysdata_mcheck { + unsigned long coma_gcr; + unsigned long coma_edsr; + unsigned long coma_ter; + unsigned long coma_elar; + unsigned long coma_ehar; + unsigned long coma_ldlr; + unsigned long coma_ldhr; + unsigned long coma_base0; + unsigned long coma_base1; + unsigned long coma_base2; + unsigned long coma_cnfg0; + unsigned long coma_cnfg1; + unsigned long coma_cnfg2; + unsigned long epic_dcsr; + unsigned long epic_pear; + unsigned long epic_sear; + unsigned long epic_tbr1; + unsigned long epic_tbr2; + unsigned long epic_pbr1; + unsigned long epic_pbr2; + unsigned long epic_pmr1; + unsigned long epic_pmr2; + unsigned long epic_harx1; + unsigned long epic_harx2; + unsigned long epic_pmlt; + unsigned long epic_tag0; + unsigned long epic_tag1; + unsigned long epic_tag2; + unsigned long epic_tag3; + unsigned long epic_tag4; + unsigned long epic_tag5; + unsigned long epic_tag6; + unsigned long epic_tag7; + unsigned long epic_data0; + unsigned long epic_data1; + unsigned long epic_data2; + unsigned long epic_data3; + unsigned long epic_data4; + unsigned long epic_data5; + unsigned long epic_data6; + unsigned long epic_data7; +}; +#endif /* CONFIG_ALPHA_MIKASA */ + +struct el_procdata { + unsigned long paltemp[32]; /* PAL TEMP REGS. */ + /* EV4-specific fields */ + unsigned long exc_addr; /* Address of excepting instruction. */ + unsigned long exc_sum; /* Summary of arithmetic traps. */ + unsigned long exc_mask; /* Exception mask (from exc_sum). */ + unsigned long iccsr; /* IBox hardware enables. */ + unsigned long pal_base; /* Base address for PALcode. */ + unsigned long hier; /* Hardware Interrupt Enable. */ + unsigned long hirr; /* Hardware Interrupt Request. */ + unsigned long csr; /* D-stream fault info. */ + unsigned long dc_stat; /* D-cache status (ECC/Parity Err). */ + unsigned long dc_addr; /* EV3 Phys Addr for ECC/DPERR. */ + unsigned long abox_ctl; /* ABox Control Register. */ + unsigned long biu_stat; /* BIU Status. */ + unsigned long biu_addr; /* BUI Address. */ + unsigned long biu_ctl; /* BIU Control. */ + unsigned long fill_syndrome;/* For correcting ECC errors. */ + unsigned long fill_addr; /* Cache block which was being read */ + unsigned long va; /* Effective VA of fault or miss. */ + unsigned long bc_tag; /* Backup Cache Tag Probe Results.*/ +}; + + +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ADDR(x) (0x80 | (x)) +#define RTC_ALWAYS_BCD 0 + +#endif /* __ALPHA_APECS__H__ */ diff --git a/include/asm-alpha/atomic.h b/include/asm-alpha/atomic.h new file mode 100644 index 000000000..621c3a932 --- /dev/null +++ b/include/asm-alpha/atomic.h @@ -0,0 +1,103 @@ +#ifndef __ARCH_ALPHA_ATOMIC__ +#define __ARCH_ALPHA_ATOMIC__ + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc... + * + * But use these as seldom as possible since they are much more slower + * than regular operations. + */ + +/* + * Make sure gcc doesn't try to be clever and move things around + * on us. We need to use _exactly_ the address the user gave us, + * not some alias that contains the same information. + */ +#define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x) + +typedef int atomic_t; + +extern __inline__ void atomic_add(atomic_t i, atomic_t * v) +{ + unsigned long temp; + __asm__ __volatile__( + "\n1:\t" + "ldl_l %0,%1\n\t" + "addl %0,%2,%0\n\t" + "stl_c %0,%1\n\t" + "beq %0,1b\n" + "2:" + :"=&r" (temp), + "=m" (__atomic_fool_gcc(v)) + :"Ir" (i), + "m" (__atomic_fool_gcc(v))); +} + +extern __inline__ void atomic_sub(atomic_t i, atomic_t * v) +{ + unsigned long temp; + __asm__ __volatile__( + "\n1:\t" + "ldl_l %0,%1\n\t" + "subl %0,%2,%0\n\t" + "stl_c %0,%1\n\t" + "beq %0,1b\n" + "2:" + :"=&r" (temp), + "=m" (__atomic_fool_gcc(v)) + :"Ir" (i), + "m" (__atomic_fool_gcc(v))); +} + +/* + * Same as above, but return the result value + */ +extern __inline__ long atomic_add_return(atomic_t i, atomic_t * v) +{ + long temp, result; + __asm__ __volatile__( + "\n1:\t" + "ldl_l %0,%1\n\t" + "addl %0,%3,%0\n\t" + "bis %0,%0,%2\n\t" + "stl_c %0,%1\n\t" + "beq %0,1b\n" + "2:" + :"=&r" (temp), + "=m" (__atomic_fool_gcc(v)), + "=&r" (result) + :"Ir" (i), + "m" (__atomic_fool_gcc(v))); + return result; +} + +extern __inline__ long atomic_sub_return(atomic_t i, atomic_t * v) +{ + long temp, result; + __asm__ __volatile__( + "\n1:\t" + "ldl_l %0,%1\n\t" + "subl %0,%3,%0\n\t" + "bis %0,%0,%2\n\t" + "stl_c %0,%1\n\t" + "beq %0,1b\n" + "2:" + :"=&r" (temp), + "=m" (__atomic_fool_gcc(v)), + "=&r" (result) + :"Ir" (i), + "m" (__atomic_fool_gcc(v))); + return result; +} + +#define atomic_dec_return(v) atomic_sub_return(1,(v)) +#define atomic_inc_return(v) atomic_add_return(1,(v)) + +#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) +#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) + +#define atomic_inc(v) atomic_add(1,(v)) +#define atomic_dec(v) atomic_sub(1,(v)) + +#endif diff --git a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h index 420ffa02c..200a905c1 100644 --- a/include/asm-alpha/bitops.h +++ b/include/asm-alpha/bitops.h @@ -17,21 +17,22 @@ extern __inline__ unsigned long set_bit(unsigned long nr, void * addr) { unsigned long oldbit; unsigned long temp; + unsigned int * m = ((unsigned int *) addr) + (nr >> 5); __asm__ __volatile__( "\n1:\t" - "ldq_l %0,%1\n\t" + "ldl_l %0,%1\n\t" "and %0,%3,%2\n\t" "bne %2,2f\n\t" "xor %0,%3,%0\n\t" - "stq_c %0,%1\n\t" + "stl_c %0,%1\n\t" "beq %0,1b\n" "2:" :"=&r" (temp), - "=m" (((unsigned long *) addr)[nr >> 6]), + "=m" (*m), "=&r" (oldbit) - :"r" (1UL << (nr & 63)), - "m" (((unsigned long *) addr)[nr >> 6])); + :"Ir" (1UL << (nr & 31)), + "m" (*m)); return oldbit != 0; } @@ -39,21 +40,22 @@ extern __inline__ unsigned long clear_bit(unsigned long nr, void * addr) { unsigned long oldbit; unsigned long temp; + unsigned int * m = ((unsigned int *) addr) + (nr >> 5); __asm__ __volatile__( "\n1:\t" - "ldq_l %0,%1\n\t" + "ldl_l %0,%1\n\t" "and %0,%3,%2\n\t" "beq %2,2f\n\t" "xor %0,%3,%0\n\t" - "stq_c %0,%1\n\t" + "stl_c %0,%1\n\t" "beq %0,1b\n" "2:" :"=&r" (temp), - "=m" (((unsigned long *) addr)[nr >> 6]), + "=m" (*m), "=&r" (oldbit) - :"r" (1UL << (nr & 63)), - "m" (((unsigned long *) addr)[nr >> 6])); + :"Ir" (1UL << (nr & 31)), + "m" (*m)); return oldbit != 0; } @@ -61,54 +63,57 @@ extern __inline__ unsigned long change_bit(unsigned long nr, void * addr) { unsigned long oldbit; unsigned long temp; + unsigned int * m = ((unsigned int *) addr) + (nr >> 5); __asm__ __volatile__( "\n1:\t" - "ldq_l %0,%1\n\t" + "ldl_l %0,%1\n\t" "and %0,%3,%2\n\t" "xor %0,%3,%0\n\t" - "stq_c %0,%1\n\t" + "stl_c %0,%1\n\t" "beq %0,1b\n" :"=&r" (temp), - "=m" (((unsigned long *) addr)[nr >> 6]), + "=m" (*m), "=&r" (oldbit) - :"r" (1UL << (nr & 63)), - "m" (((unsigned long *) addr)[nr >> 6])); + :"Ir" (1UL << (nr & 31)), + "m" (*m)); return oldbit != 0; } -extern __inline__ unsigned long test_bit(int nr, void * addr) +extern __inline__ unsigned long test_bit(int nr, const void * addr) { - return 1UL & (((unsigned long *) addr)[nr >> 6] >> (nr & 63)); + return 1UL & (((const int *) addr)[nr >> 5] >> (nr & 31)); } /* * ffz = Find First Zero in word. Undefined if no zero exists, * so code should check against ~0UL first.. * - * This uses the cmpbge insn to check which byte contains the zero. - * I don't know if that's actually a good idea, but it's fun and the - * resulting LBS tests should be natural on the alpha.. Besides, I'm - * just teaching myself the asm of the alpha anyway. + * Do a binary search on the bits. Due to the nature of large + * constants on the alpha, it is worthwhile to split the search. */ +extern inline unsigned long ffz_b(unsigned long x) +{ + unsigned long sum = 0; + + x = ~x & -~x; /* set first 0 bit, clear others */ + if (x & 0xF0) sum += 4; + if (x & 0xCC) sum += 2; + if (x & 0xAA) sum += 1; + + return sum; +} + extern inline unsigned long ffz(unsigned long word) { - unsigned long result = 0; - unsigned long tmp; + unsigned long bits, qofs, bofs; - __asm__("cmpbge %1,%0,%0" - :"=r" (tmp) - :"r" (word), "0" (~0UL)); - while (tmp & 1) { - word >>= 8; - tmp >>= 1; - result += 8; - } - while (word & 1) { - result++; - word >>= 1; - } - return result; + __asm__("cmpbge %1,%2,%0" : "=r"(bits) : "r"(word), "r"(~0UL)); + qofs = ffz_b(bits); + __asm__("extbl %1,%2,%0" : "=r"(bits) : "r"(word), "r"(qofs)); + bofs = ffz_b(bits); + + return qofs*8 + bofs; } /* @@ -155,4 +160,14 @@ found_middle: #define find_first_zero_bit(addr, size) \ find_next_zero_bit((addr), (size), 0) +#ifdef __KERNEL__ + +#define ext2_set_bit set_bit +#define ext2_clear_bit 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 + +#endif /* __KERNEL__ */ + #endif /* _ALPHA_BITOPS_H */ diff --git a/include/asm-alpha/byteorder.h b/include/asm-alpha/byteorder.h index 02902df90..438ecb89c 100644 --- a/include/asm-alpha/byteorder.h +++ b/include/asm-alpha/byteorder.h @@ -6,14 +6,32 @@ #undef htonl #undef htons -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 1234 #endif -#ifndef LITTLE_ENDIAN_BITFIELD -#define LITTLE_ENDIAN_BITFIELD +#ifndef __LITTLE_ENDIAN_BITFIELD +#define __LITTLE_ENDIAN_BITFIELD #endif +#ifdef __KERNEL__ + +/* + * In-kernel byte order macros to handle stuff like + * byte-order-dependent filesystems etc. + */ +#define cpu_to_le32(x) (x) +#define le32_to_cpu(x) (x) +#define cpu_to_le16(x) (x) +#define le16_to_cpu(x) (x) + +#define cpu_to_be32(x) htonl((x)) +#define be32_to_cpu(x) ntohl((x)) +#define cpu_to_be16(x) htons((x)) +#define be16_to_cpu(x) ntohs((x)) + +#endif /* __KERNEL__ */ + extern unsigned long int ntohl(unsigned long int); extern unsigned short int ntohs(unsigned short int); extern unsigned long int htonl(unsigned long int); @@ -21,6 +39,9 @@ extern unsigned short int htons(unsigned short int); extern unsigned long int __ntohl(unsigned long int); extern unsigned short int __ntohs(unsigned short int); + +#ifdef __GNUC__ + extern unsigned long int __constant_ntohl(unsigned long int); extern unsigned short int __constant_ntohs(unsigned short int); @@ -34,23 +55,44 @@ extern unsigned short int __constant_ntohs(unsigned short int); extern __inline__ unsigned long int __ntohl(unsigned long int x) { - return (((x & 0x000000ffU) << 24) | - ((x & 0x0000ff00U) << 8) | - ((x & 0x00ff0000U) >> 8) | - ((x & 0xff000000U) >> 24)); + unsigned long int res, t1, t2; + + __asm__( + "# bswap input: %0 (aabbccdd)\n\t" + "# output: %0, used %1 %2\n\t" + "extlh %0,5,%1 # %1 = dd000000\n\t" + "zap %0,0xfd,%2 # %2 = 0000cc00\n\t" + "sll %2,5,%2 # %2 = 00198000\n\t" + "s8addq %2,%1,%1 # %1 = ddcc0000\n\t" + "zap %0,0xfb,%2 # %2 = 00bb0000\n\t" + "srl %2,8,%2 # %2 = 0000bb00\n\t" + "extbl %0,3,%0 # %0 = 000000aa\n\t" + "or %1,%0,%0 # %0 = ddcc00aa\n\t" + "or %2,%0,%0 # %0 = ddccbbaa\n" + : "r="(res), "r="(t1), "r="(t2) + : "0" (x & 0xffffffffUL)); + return res; } #define __constant_ntohl(x) \ -((unsigned int)((((unsigned int)(x) & 0x000000ffU) << 24) | \ - (((unsigned int)(x) & 0x0000ff00U) << 8) | \ - (((unsigned int)(x) & 0x00ff0000U) >> 8) | \ - (((unsigned int)(x) & 0xff000000U) >> 24))) + ((unsigned long int)((((x) & 0x000000ffUL) << 24) | \ + (((x) & 0x0000ff00UL) << 8) | \ + (((x) & 0x00ff0000UL) >> 8) | \ + (((x) & 0xff000000UL) >> 24))) extern __inline__ unsigned short int __ntohs(unsigned short int x) { - return (((x & 0x00ff) << 8) | - ((x & 0xff00) >> 8)); + unsigned long int res, t1; + + __asm__( + "# v0 is result; swap in-place.\n\t" + "bis %2,%2,%0 # v0 = aabb\n\t" + "extwh %0,7,%1 # t1 = bb00\n\t" + "extbl %0,1,%0 # v0 = 00aa\n\t" + "bis %0,%1,%0 # v0 = bbaa\n" + : "r="(res), "r="(t1) : "r"(x)); + return res; } #define __constant_ntohs(x) \ @@ -79,6 +121,8 @@ __ntohs(unsigned short int x) (__builtin_constant_p((short)(x)) ? \ __constant_htons((x)) : \ __htons((x))) -#endif +#endif /* __OPTIMIZE__ */ -#endif +#endif /* __GNUC__ */ + +#endif /* _ALPHA_BYTEORDER_H */ diff --git a/include/asm-alpha/checksum.h b/include/asm-alpha/checksum.h new file mode 100644 index 000000000..26c672521 --- /dev/null +++ b/include/asm-alpha/checksum.h @@ -0,0 +1,76 @@ +#ifndef _ALPHA_CHECKSUM_H +#define _ALPHA_CHECKSUM_H + + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + */ +extern unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl); + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +extern unsigned short int csum_tcpudp_magic(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, + unsigned int sum); + +/* + * 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 + */ +extern unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ +unsigned int csum_partial_copy(const char *src, char *dst, int len, unsigned int sum); + +/* + * the same as csum_partial, but copies from user space (but on the alpha + * we have just one address space, so this is identical to the above) + */ +#define csum_partial_copy_fromuser csum_partial_copy + + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ + +extern unsigned short ip_compute_csum(unsigned char * buff, int len); + +/* + * Fold a partial checksum without adding pseudo headers + */ + +static inline unsigned short csum_fold(unsigned int sum) +{ + sum = (sum & 0xffff) + (sum >> 16); + sum = (sum & 0xffff) + (sum >> 16); + return ~sum; +} + +#define _HAVE_ARCH_IPV6_CSUM +extern unsigned short int csum_ipv6_magic(struct in6_addr *saddr, + struct in6_addr *daddr, + __u16 len, + unsigned short proto, + unsigned int sum); + +#endif diff --git a/include/asm-alpha/cia.h b/include/asm-alpha/cia.h new file mode 100644 index 000000000..963cfa8c1 --- /dev/null +++ b/include/asm-alpha/cia.h @@ -0,0 +1,455 @@ +#ifndef __ALPHA_CIA__H__ +#define __ALPHA_CIA__H__ + +#include <linux/config.h> +#include <linux/types.h> + +/* + * CIA is the internal name for the 2117x chipset which provides + * memory controller and PCI access for the 21164 chip based systems. + * + * This file is based on: + * + * DECchip 21171 Core Logic Chipset + * Technical Reference Manual + * + * EC-QE18B-TE + * + * david.rusling@reo.mts.dec.com Initial Version. + * + */ + +/*------------------------------------------------------------------------** +** ** +** EB164 I/O procedures ** +** ** +** inport[b|w|t|l], outport[b|w|t|l] 8:16:24:32 IO xfers ** +** inportbxt: 8 bits only ** +** inport: alias of inportw ** +** outport: alias of outportw ** +** ** +** inmem[b|w|t|l], outmem[b|w|t|l] 8:16:24:32 ISA memory xfers ** +** inmembxt: 8 bits only ** +** inmem: alias of inmemw ** +** outmem: alias of outmemw ** +** ** +**------------------------------------------------------------------------*/ + + +/* CIA ADDRESS BIT DEFINITIONS + * + * 3 3 3 3|3 3 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 + * 9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |1| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |0|0|0| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | \_/ \_/ + * | | | + * +-- IO space, not cached. Byte Enable --+ | + * Transfer Length --+ + * + * + * + * Byte Transfer + * Enable Length Transfer Byte Address + * adr<6:5> adr<4:3> Length Enable Adder + * --------------------------------------------- + * 00 00 Byte 1110 0x000 + * 01 00 Byte 1101 0x020 + * 10 00 Byte 1011 0x040 + * 11 00 Byte 0111 0x060 + * + * 00 01 Word 1100 0x008 + * 01 01 Word 1001 0x028 <= Not supported in this code. + * 10 01 Word 0011 0x048 + * + * 00 10 Tribyte 1000 0x010 + * 01 10 Tribyte 0001 0x030 + * + * 10 11 Longword 0000 0x058 + * + * Note that byte enables are asserted low. + * + */ + +#define BYTE_ENABLE_SHIFT 5 +#define TRANSFER_LENGTH_SHIFT 3 +#define MEM_SP1_MASK 0x1fffffff /* Mem sparse space 1 mask is 29 bits */ + + +#define CIA_DMA_WIN_BASE (1024UL*1024UL*1024UL) +#define CIA_DMA_WIN_SIZE (1024*1024*1024) + +/* + * 21171-CA Control and Status Registers (p4-1) + */ +#define CIA_IOC_CIA_REV (IDENT_ADDR + 0x8740000080UL) +#define CIA_IOC_PCI_LAT (IDENT_ADDR + 0x87400000C0UL) +#define CIA_IOC_CIA_CTRL (IDENT_ADDR + 0x8740000100UL) +#define CIA_IOC_HAE_MEM (IDENT_ADDR + 0x8740000400UL) +#define CIA_IOC_HAE_IO (IDENT_ADDR + 0x8740000440UL) +#define CIA_IOC_CFG (IDENT_ADDR + 0x8740000480UL) +#define CIA_IOC_CACK_EN (IDENT_ADDR + 0x8740000600UL) + +/* + * 21171-CA Diagnostic Registers (p4-2) + */ +#define CIA_IOC_CIA_DIAG (IDENT_ADDR + 0x8740002000UL) +#define CIA_IOC_DIAG_CHECK (IDENT_ADDR + 0x8740003000UL) + +/* + * 21171-CA Performance Monitor registers (p4-3) + */ +#define CIA_IOC_PERF_MONITOR (IDENT_ADDR + 0x8740004000UL) +#define CIA_IOC_PERF_CONTROL (IDENT_ADDR + 0x8740004040UL) + +/* + * 21171-CA Error registers (p4-3) + */ +#define CIA_IOC_CPU_ERR0 (IDENT_ADDR + 0x8740008000UL) +#define CIA_IOC_CPU_ERR1 (IDENT_ADDR + 0x8740008040UL) +#define CIA_IOC_CIA_ERR (IDENT_ADDR + 0x8740008200UL) +#define CIA_IOC_CIA_STAT (IDENT_ADDR + 0x8740008240UL) +#define CIA_IOC_ERR_MASK (IDENT_ADDR + 0x8740008280UL) +#define CIA_IOC_CIA_SYN (IDENT_ADDR + 0x8740008300UL) +#define CIA_IOC_MEM_ERR0 (IDENT_ADDR + 0x8740008400UL) +#define CIA_IOC_MEM_ERR1 (IDENT_ADDR + 0x8740008440UL) +#define CIA_IOC_PCI_ERR0 (IDENT_ADDR + 0x8740008800UL) +#define CIA_IOC_PCI_ERR1 (IDENT_ADDR + 0x8740008840UL) +#define CIA_IOC_PCI_ERR3 (IDENT_ADDR + 0x8740008880UL) + +/* + * 2117A-CA PCI Address Translation Registers. I've only defined + * the first window fully as that's the only one that we're currently using. + * The other window bases are needed to disable the windows. + */ +#define CIA_IOC_PCI_TBIA (IDENT_ADDR + 0x8760000100UL) +#define CIA_IOC_PCI_W0_BASE (IDENT_ADDR + 0x8760000400UL) +#define CIA_IOC_PCI_W0_MASK (IDENT_ADDR + 0x8760000440UL) +#define CIA_IOC_PCI_T0_BASE (IDENT_ADDR + 0x8760000480UL) + +#define CIA_IOC_PCI_W1_BASE (IDENT_ADDR + 0x8760000500UL) +#define CIA_IOC_PCI_W2_BASE (IDENT_ADDR + 0x8760000600UL) +#define CIA_IOC_PCI_W3_BASE (IDENT_ADDR + 0x8760000700UL) + +/* + * 21171-CA System configuration registers (p4-3) + */ +#define CIA_IOC_MCR (IDENT_ADDR + 0x8750000000UL) +#define CIA_IOC_MBA0 (IDENT_ADDR + 0x8750000600UL) +#define CIA_IOC_MBA2 (IDENT_ADDR + 0x8750000680UL) +#define CIA_IOC_MBA4 (IDENT_ADDR + 0x8750000700UL) +#define CIA_IOC_MBA6 (IDENT_ADDR + 0x8750000780UL) +#define CIA_IOC_MBA8 (IDENT_ADDR + 0x8750000800UL) +#define CIA_IOC_MBAA (IDENT_ADDR + 0x8750000880UL) +#define CIA_IOC_MBAC (IDENT_ADDR + 0x8750000900UL) +#define CIA_IOC_MBAE (IDENT_ADDR + 0x8750000980UL) +#define CIA_IOC_TMG0 (IDENT_ADDR + 0x8750000B00UL) +#define CIA_IOC_TMG1 (IDENT_ADDR + 0x8750000B40UL) +#define CIA_IOC_TMG2 (IDENT_ADDR + 0x8750000B80UL) + +/* + * Memory spaces: + */ +#define CIA_IACK_SC (IDENT_ADDR + 0x8720000000UL) +#define CIA_CONF (IDENT_ADDR + 0x8700000000UL) +#define CIA_IO (IDENT_ADDR + 0x8580000000UL) +#define CIA_SPARSE_MEM (IDENT_ADDR + 0x8000000000UL) +#define CIA_DENSE_MEM (IDENT_ADDR + 0x8600000000UL) + +/* + * ALCOR's GRU ASIC registers + */ +#define GRU_INT_REQ (IDENT_ADDR + 0x8780000000UL) +#define GRU_INT_MASK (IDENT_ADDR + 0x8780000040UL) +#define GRU_INT_EDGE (IDENT_ADDR + 0x8780000080UL) +#define GRU_INT_HILO (IDENT_ADDR + 0x87800000C0UL) +#define GRU_INT_CLEAR (IDENT_ADDR + 0x8780000100UL) + +#define GRU_CACHE_CNFG (IDENT_ADDR + 0x8780000200UL) +#define GRU_SCR (IDENT_ADDR + 0x8780000300UL) +#define GRU_LED (IDENT_ADDR + 0x8780000800UL) +#define GRU_RESET (IDENT_ADDR + 0x8780000900UL) + +#if defined(CONFIG_ALPHA_ALCOR) +#define GRU_INT_REQ_BITS 0x800fffffUL +#elif defined(CONFIG_ALPHA_XLT) +#define GRU_INT_REQ_BITS 0x80003fffUL +#else +#define GRU_INT_REQ_BITS 0xffffffffUL +#endif + +/* + * Bit definitions for I/O Controller status register 0: + */ +#define CIA_IOC_STAT0_CMD 0xf +#define CIA_IOC_STAT0_ERR (1<<4) +#define CIA_IOC_STAT0_LOST (1<<5) +#define CIA_IOC_STAT0_THIT (1<<6) +#define CIA_IOC_STAT0_TREF (1<<7) +#define CIA_IOC_STAT0_CODE_SHIFT 8 +#define CIA_IOC_STAT0_CODE_MASK 0x7 +#define CIA_IOC_STAT0_P_NBR_SHIFT 13 +#define CIA_IOC_STAT0_P_NBR_MASK 0x7ffff + +#define HAE_ADDRESS CIA_IOC_HAE_MEM + +#ifdef __KERNEL__ + +/* + * Translate physical memory address as seen on (PCI) bus into + * a kernel virtual address and vv. + */ +extern inline unsigned long virt_to_bus(void * address) +{ + return virt_to_phys(address) + CIA_DMA_WIN_BASE; +} + +extern inline void * bus_to_virt(unsigned long address) +{ + return phys_to_virt(address - CIA_DMA_WIN_BASE); +} + +/* + * I/O functions: + * + * CIA (the 2117x PCI/memory support chipset for the EV5 (21164) + * series of processors uses a sparse address mapping scheme to + * get at PCI memory and I/O. + */ + +#define vuip volatile unsigned int * + +extern inline unsigned int __inb(unsigned long addr) +{ + long result = *(vuip) ((addr << 5) + CIA_IO + 0x00); + result >>= (addr & 3) * 8; + return 0xffUL & result; +} + +extern inline void __outb(unsigned char b, unsigned long addr) +{ + unsigned int w; + + asm ("insbl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b)); + *(vuip) ((addr << 5) + CIA_IO + 0x00) = w; + mb(); +} + +extern inline unsigned int __inw(unsigned long addr) +{ + long result = *(vuip) ((addr << 5) + CIA_IO + 0x08); + result >>= (addr & 3) * 8; + return 0xffffUL & result; +} + +extern inline void __outw(unsigned short b, unsigned long addr) +{ + unsigned int w; + + asm ("inswl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b)); + *(vuip) ((addr << 5) + CIA_IO + 0x08) = w; + mb(); +} + +extern inline unsigned int __inl(unsigned long addr) +{ + return *(vuip) ((addr << 5) + CIA_IO + 0x18); +} + +extern inline void __outl(unsigned int b, unsigned long addr) +{ + *(vuip) ((addr << 5) + CIA_IO + 0x18) = b; + mb(); +} + + +/* + * Memory functions. 64-bit and 32-bit accesses are done through + * dense memory space, everything else through sparse space. + * + * For reading and writing 8 and 16 bit quantities we need to + * go through one of the three sparse address mapping regions + * and use the HAE_MEM CSR to provide some bits of the address. + * The following few routines use only sparse address region 1 + * which gives 1Gbyte of accessible space which relates exactly + * to the amount of PCI memory mapping *into* system address space. + * See p 6-17 of the specification but it looks something like this: + * + * 21164 Address: + * + * 3 2 1 + * 9876543210987654321098765432109876543210 + * 1ZZZZ0.PCI.QW.Address............BBLL + * + * ZZ = SBZ + * BB = Byte offset + * LL = Transfer length + * + * PCI Address: + * + * 3 2 1 + * 10987654321098765432109876543210 + * HHH....PCI.QW.Address........ 00 + * + * HHH = 31:29 HAE_MEM CSR + * + */ + +extern inline unsigned long __readb(unsigned long addr) +{ + unsigned long result, shift, msb; + + shift = (addr & 0x3) * 8 ; + msb = addr & 0xE0000000 ; + addr &= MEM_SP1_MASK ; + if (msb != hae.cache) { + set_hae(msb); + } + result = *(vuip) ((addr << 5) + CIA_SPARSE_MEM + 0x00) ; + result >>= shift; + return 0xffUL & result; +} + +extern inline unsigned long __readw(unsigned long addr) +{ + unsigned long result, shift, msb; + + shift = (addr & 0x3) * 8; + msb = addr & 0xE0000000 ; + addr &= MEM_SP1_MASK ; + if (msb != hae.cache) { + set_hae(msb); + } + result = *(vuip) ((addr << 5) + CIA_SPARSE_MEM + 0x08); + result >>= shift; + return 0xffffUL & result; +} + +extern inline unsigned long __readl(unsigned long addr) +{ + return *(vuip) (addr + CIA_DENSE_MEM); +} + +extern inline void __writeb(unsigned char b, unsigned long addr) +{ + unsigned long msb ; + + msb = addr & 0xE0000000 ; + addr &= MEM_SP1_MASK ; + if (msb != hae.cache) { + set_hae(msb); + } + *(vuip) ((addr << 5) + CIA_SPARSE_MEM + 0x00) = b * 0x01010101; +} + +extern inline void __writew(unsigned short b, unsigned long addr) +{ + unsigned long msb ; + + msb = addr & 0xE0000000 ; + addr &= MEM_SP1_MASK ; + if (msb != hae.cache) { + set_hae(msb); + } + *(vuip) ((addr << 5) + CIA_SPARSE_MEM + 0x08) = b * 0x00010001; +} + +extern inline void __writel(unsigned int b, unsigned long addr) +{ + *(vuip) (addr + CIA_DENSE_MEM) = b; +} + +#define inb(port) \ +(__builtin_constant_p((port))?__inb(port):_inb(port)) + +#define outb(x, port) \ +(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port))) + +#define readl(a) __readl((unsigned long)(a)) +#define writel(v,a) __writel((v),(unsigned long)(a)) + +#undef vuip + +extern unsigned long cia_init (unsigned long mem_start, + unsigned long mem_end); + +#endif /* __KERNEL__ */ + +/* + * Data structure for handling CIA machine checks: + */ +/* ev5-specific info: */ +struct el_procdata { + unsigned long shadow[8]; /* PALmode shadow registers */ + unsigned long paltemp[24]; /* PAL temporary registers */ + /* EV5-specific fields */ + unsigned long exc_addr; /* Address of excepting instruction. */ + unsigned long exc_sum; /* Summary of arithmetic traps. */ + unsigned long exc_mask; /* Exception mask (from exc_sum). */ + unsigned long exc_base; /* PALbase at time of exception. */ + unsigned long isr; /* Interrupt summary register. */ + unsigned long icsr; /* Ibox control register. */ + unsigned long ic_perr_stat; + unsigned long dc_perr_stat; + unsigned long va; /* Effective VA of fault or miss. */ + unsigned long mm_stat; + unsigned long sc_addr; + unsigned long sc_stat; + unsigned long bc_tag_addr; + unsigned long ei_addr; + unsigned long fill_syn; + unsigned long ei_stat; + unsigned long ld_lock; +}; + +/* system-specific info: */ +struct el_CIA_sysdata_mcheck { + unsigned long coma_gcr; + unsigned long coma_edsr; + unsigned long coma_ter; + unsigned long coma_elar; + unsigned long coma_ehar; + unsigned long coma_ldlr; + unsigned long coma_ldhr; + unsigned long coma_base0; + unsigned long coma_base1; + unsigned long coma_base2; + unsigned long coma_cnfg0; + unsigned long coma_cnfg1; + unsigned long coma_cnfg2; + unsigned long epic_dcsr; + unsigned long epic_pear; + unsigned long epic_sear; + unsigned long epic_tbr1; + unsigned long epic_tbr2; + unsigned long epic_pbr1; + unsigned long epic_pbr2; + unsigned long epic_pmr1; + unsigned long epic_pmr2; + unsigned long epic_harx1; + unsigned long epic_harx2; + unsigned long epic_pmlt; + unsigned long epic_tag0; + unsigned long epic_tag1; + unsigned long epic_tag2; + unsigned long epic_tag3; + unsigned long epic_tag4; + unsigned long epic_tag5; + unsigned long epic_tag6; + unsigned long epic_tag7; + unsigned long epic_data0; + unsigned long epic_data1; + unsigned long epic_data2; + unsigned long epic_data3; + unsigned long epic_data4; + unsigned long epic_data5; + unsigned long epic_data6; + unsigned long epic_data7; +}; + +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ADDR(x) (0x80 | (x)) +#define RTC_ALWAYS_BCD 0 + +#endif /* __ALPHA_CIA__H__ */ diff --git a/include/asm-alpha/dirent.h b/include/asm-alpha/dirent.h deleted file mode 100644 index 07fe9e9e0..000000000 --- a/include/asm-alpha/dirent.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _ALPHA_DIRENT_H -#define _ALPHA_DIRENT_H - -struct dirent { - ino_t d_ino; - unsigned short d_reclen; - unsigned short d_namlen; - char d_name[256]; -}; - -#endif diff --git a/include/asm-alpha/dma.h b/include/asm-alpha/dma.h index 4b327266d..b5c3c1c7c 100644 --- a/include/asm-alpha/dma.h +++ b/include/asm-alpha/dma.h @@ -18,6 +18,8 @@ #ifndef _ASM_DMA_H #define _ASM_DMA_H +#include <linux/config.h> + #include <asm/io.h> /* need byte IO */ #define dma_outb outb @@ -73,8 +75,23 @@ #define MAX_DMA_CHANNELS 8 -/* The maximum address that we can perform a DMA transfer to on this platform */ -#define MAX_DMA_ADDRESS 0x1000000 +#ifdef CONFIG_ALPHA_XL +/* The maximum address that we can perform a DMA transfer to on Alpha XL, + due to a hardware SIO (PCI<->ISA bus bridge) chip limitation, is 64MB. + See <asm/apecs.h> for more info. +*/ +/* NOTE: we must define the maximum as something less than 64Mb, to prevent + virt_to_bus() from returning an address in the first window, for a + data area that goes beyond the 64Mb first DMA window. Sigh... + We MUST coordinate the maximum with <asm/apecs.h> for consistency. + For now, this limit is set to 48Mb... +*/ +#define MAX_DMA_ADDRESS (0xfffffc0003000000UL) +#else /* CONFIG_ALPHA_XL */ +/* The maximum address that we can perform a DMA transfer to on normal + Alpha platforms */ +#define MAX_DMA_ADDRESS (~0UL) +#endif /* CONFIG_ALPHA_XL */ /* 8237 DMA controllers */ #define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ @@ -294,8 +311,7 @@ static __inline__ int get_dma_residue(unsigned int dmanr) /* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr, char * device_id); /* reserve a DMA channel */ +extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ extern void free_dma(unsigned int dmanr); /* release it again */ - #endif /* _ASM_DMA_H */ diff --git a/include/asm-alpha/elf.h b/include/asm-alpha/elf.h new file mode 100644 index 000000000..0cf5ecbec --- /dev/null +++ b/include/asm-alpha/elf.h @@ -0,0 +1,94 @@ +#ifndef __ASMaxp_ELF_H +#define __ASMaxp_ELF_H + +/* + * ELF register definitions.. + */ + +/* + * The OSF/1 version of <sys/procfs.h> makes gregset_t 46 entries long. + * I have no idea why that is so. For now, we just leave it at 33 + * (32 general regs + processor status word). + */ +#define ELF_NGREG 33 +#define ELF_NFPREG 32 + +typedef unsigned long elf_greg_t; +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef double elf_fpreg_t; +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ((x) == EM_ALPHA) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS64 +#define ELF_DATA ELFDATA2LSB; +#define ELF_ARCH EM_ALPHA + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 8192 + +/* $0 is set by ld.so to a pointer to a function which might be + registered using atexit. This provides a mean for the dynamic + linker to call DT_FINI functions for shared libraries that have + been loaded before the code runs. + + So that we can use the same startup file with static executables, + we start programs with a value of 0 to indicate that there is no + such function. */ + +#define ELF_PLAT_INIT(_r) _r->r0 = 0 + +/* Use the same format as the OSF/1 procfs interface. The register + layout is sane. However, since dump_thread() creates the funky + layout that ECOFF coredumps want, we need to undo that layout here. + Eventually, it would be nice if the ECOFF core-dump had to do the + translation, then ELF_CORE_COPY_REGS() would become trivial and + faster. */ +#define ELF_CORE_COPY_REGS(_dest,_regs) \ +{ \ + struct user _dump; \ + \ + dump_thread(_regs, &_dump); \ + _dest[ 0] = _dump.regs[EF_V0]; \ + _dest[ 1] = _dump.regs[EF_T0]; \ + _dest[ 2] = _dump.regs[EF_T1]; \ + _dest[ 3] = _dump.regs[EF_T2]; \ + _dest[ 4] = _dump.regs[EF_T3]; \ + _dest[ 5] = _dump.regs[EF_T4]; \ + _dest[ 6] = _dump.regs[EF_T5]; \ + _dest[ 7] = _dump.regs[EF_T6]; \ + _dest[ 8] = _dump.regs[EF_T7]; \ + _dest[ 9] = _dump.regs[EF_S0]; \ + _dest[10] = _dump.regs[EF_S1]; \ + _dest[11] = _dump.regs[EF_S2]; \ + _dest[12] = _dump.regs[EF_S3]; \ + _dest[13] = _dump.regs[EF_S4]; \ + _dest[14] = _dump.regs[EF_S5]; \ + _dest[15] = _dump.regs[EF_S6]; \ + _dest[16] = _dump.regs[EF_A0]; \ + _dest[17] = _dump.regs[EF_A1]; \ + _dest[18] = _dump.regs[EF_A2]; \ + _dest[19] = _dump.regs[EF_A3]; \ + _dest[20] = _dump.regs[EF_A4]; \ + _dest[21] = _dump.regs[EF_A5]; \ + _dest[22] = _dump.regs[EF_T8]; \ + _dest[23] = _dump.regs[EF_T9]; \ + _dest[24] = _dump.regs[EF_T10]; \ + _dest[25] = _dump.regs[EF_T11]; \ + _dest[26] = _dump.regs[EF_RA]; \ + _dest[27] = _dump.regs[EF_T12]; \ + _dest[28] = _dump.regs[EF_AT]; \ + _dest[29] = _dump.regs[EF_GP]; \ + _dest[30] = _dump.regs[EF_SP]; \ + _dest[31] = _dump.regs[EF_PC]; /* store PC here */ \ + _dest[32] = _dump.regs[EF_PS]; \ +} + +#endif diff --git a/include/asm-alpha/errno.h b/include/asm-alpha/errno.h index 45c1ea0d5..3641c3460 100644 --- a/include/asm-alpha/errno.h +++ b/include/asm-alpha/errno.h @@ -91,44 +91,49 @@ #define EILSEQ 116 /* Illegal byte sequence */ /* The following are just random noise.. */ -#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 58 /* File locking deadlock error */ -#define EBFONT 59 /* Bad font file format */ -#define ENONET 64 /* Machine is not on the network */ -#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 EMULTIHOP 72 /* Multihop attempted */ -#define EDOTDOT 73 /* RFS specific error */ -#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 ERESTART 85 /* Interrupted system call should be restarted */ -#define ESTRPIPE 86 /* Streams pipe error */ +#define ECHRNG 88 /* Channel number out of range */ +#define EL2NSYNC 89 /* Level 2 not synchronized */ +#define EL3HLT 90 /* Level 3 halted */ +#define EL3RST 91 /* Level 3 reset */ + +#define ELNRNG 93 /* Link number out of range */ +#define EUNATCH 94 /* Protocol driver not attached */ +#define ENOCSI 95 /* No CSI structure available */ +#define EL2HLT 96 /* Level 2 halted */ +#define EBADE 97 /* Invalid exchange */ +#define EBADR 98 /* Invalid request descriptor */ +#define EXFULL 99 /* Exchange full */ +#define ENOANO 100 /* No anode */ +#define EBADRQC 101 /* Invalid request code */ +#define EBADSLT 102 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 104 /* Bad font file format */ +#define ENONET 105 /* Machine is not on the network */ +#define ENOLINK 106 /* Link has been severed */ +#define EADV 107 /* Advertise error */ +#define ESRMNT 108 /* Srmount error */ +#define ECOMM 109 /* Communication error on send */ +#define EMULTIHOP 110 /* Multihop attempted */ +#define EDOTDOT 111 /* RFS specific error */ +#define EOVERFLOW 112 /* Value too large for defined data type */ +#define ENOTUNIQ 113 /* Name not unique on network */ +#define EBADFD 114 /* File descriptor in bad state */ +#define EREMCHG 115 /* Remote address changed */ + #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 ELIBACC 122 /* Can not access a needed shared library */ +#define ELIBBAD 123 /* Accessing a corrupted shared library */ +#define ELIBSCN 124 /* .lib section in a.out corrupted */ +#define ELIBMAX 125 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 126 /* Cannot exec a shared library directly */ +#define ERESTART 127 /* Interrupted system call should be restarted */ +#define ESTRPIPE 128 /* Streams pipe error */ + #endif diff --git a/include/asm-alpha/fcntl.h b/include/asm-alpha/fcntl.h index e4cd88361..3df5edf2b 100644 --- a/include/asm-alpha/fcntl.h +++ b/include/asm-alpha/fcntl.h @@ -33,20 +33,28 @@ /* for F_[GET|SET]FL */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ +/* for posix fcntl() and lockf() */ #define F_RDLCK 1 #define F_WRLCK 2 #define F_UNLCK 8 -/* For bsd flock () */ +/* for old implementation of bsd flock () */ #define F_EXLCK 16 /* or 3 */ #define F_SHLCK 32 /* 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; + __kernel_off_t l_start; + __kernel_off_t l_len; + __kernel_pid_t l_pid; }; #endif diff --git a/include/asm-alpha/floppy.h b/include/asm-alpha/floppy.h new file mode 100644 index 000000000..f5eae6ee2 --- /dev/null +++ b/include/asm-alpha/floppy.h @@ -0,0 +1,61 @@ +/* + * Architecture specific parts of the Floppy driver + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995 + */ +#ifndef __ASM_ALPHA_FLOPPY_H +#define __ASM_ALPHA_FLOPPY_H + +#include <linux/config.h> + +#define fd_inb(port) inb_p(port) +#define fd_outb(value,port) outb_p(value,port) + +#define fd_enable_dma() enable_dma(FLOPPY_DMA) +#define fd_disable_dma() disable_dma(FLOPPY_DMA) +#define fd_request_dma() request_dma(FLOPPY_DMA,"floppy") +#define fd_free_dma() free_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(count) set_dma_count(FLOPPY_DMA,count) +#define fd_enable_irq() enable_irq(FLOPPY_IRQ) +#define fd_disable_irq() disable_irq(FLOPPY_IRQ) +#define fd_cacheflush(addr,size) /* nothing */ +#define fd_request_irq() request_irq(FLOPPY_IRQ, floppy_interrupt, \ + SA_INTERRUPT|SA_SAMPLE_RANDOM, \ + "floppy", NULL) +#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL); + +__inline__ void virtual_dma_init(void) +{ + /* Nothing to do on an Alpha */ +} + +static int FDC1 = 0x3f0; +static int FDC2 = -1; + +/* + * Again, the CMOS information doesn't work on the alpha.. + */ +#define FLOPPY0_TYPE 6 +#define FLOPPY1_TYPE 0 + +#define N_FDC 2 +#define N_DRIVE 8 + +/* + * Most Alphas have no problems with floppy DMA crossing 64k borders. Sigh... + */ +#ifdef CONFIG_ALPHA_XL +#define CROSS_64KB(a,s) \ + ((unsigned long)(a)/0x10000 != ((unsigned long)(a) + (s) - 1) / 0x10000) +#else /* CONFIG_ALPHA_XL */ +#define CROSS_64KB(a,s) (0) +#endif /* CONFIG_ALPHA_XL */ + +#endif /* __ASM_ALPHA_FLOPPY_H */ diff --git a/include/asm-alpha/fpu.h b/include/asm-alpha/fpu.h new file mode 100644 index 000000000..f32b95f27 --- /dev/null +++ b/include/asm-alpha/fpu.h @@ -0,0 +1,64 @@ +#ifndef __ASM_ALPHA_FPU_H +#define __ASM_ALPHA_FPU_H + +/* + * Alpha floating-point control register defines: + */ +#define FPCR_INVD (1UL<<49) /* invalid op disable (opt.) */ +#define FPCR_DZED (1UL<<50) /* division by zero disable (opt.) */ +#define FPCR_OVFD (1UL<<51) /* overflow disable (optional) */ +#define FPCR_INV (1UL<<52) /* invalid operation */ +#define FPCR_DZE (1UL<<53) /* division by zero */ +#define FPCR_OVF (1UL<<54) /* overflow */ +#define FPCR_UNF (1UL<<55) /* underflow */ +#define FPCR_INE (1UL<<56) /* inexact */ +#define FPCR_IOV (1UL<<57) /* integer overflow */ +#define FPCR_UNDZ (1UL<<60) /* underflow to zero (opt.) */ +#define FPCR_UNFD (1UL<<61) /* underflow disable (opt.) */ +#define FPCR_INED (1UL<<62) /* inexact disable (opt.) */ +#define FPCR_SUM (1UL<<63) /* summary bit */ + +#define FPCR_DYN_SHIFT 58 /* first dynamic rounding mode bit */ +#define FPCR_DYN_CHOPPED (0x0UL << FPCR_DYN_SHIFT) /* towards 0 */ +#define FPCR_DYN_MINUS (0x1UL << FPCR_DYN_SHIFT) /* towards -INF */ +#define FPCR_DYN_NORMAL (0x2UL << FPCR_DYN_SHIFT) /* towards nearest */ +#define FPCR_DYN_PLUS (0x3UL << FPCR_DYN_SHIFT) /* towards +INF */ +#define FPCR_DYN_MASK (0x3UL << FPCR_DYN_SHIFT) + +#define FPCR_MASK 0xfffe000000000000 + +/* + * IEEE trap enables are implemented in software. These per-thread + * bits are stored in the "flags" field of "struct thread_struct". + * Thus, the bits are defined so as not to conflict with the + * floating-point enable bit (which is architected). On top of that, + * we want to make these bits compatible with OSF/1 so + * ieee_set_fp_control() etc. can be implemented easily and + * compatibly. The corresponding definitions are in + * /usr/include/machine/fpu.h under OSF/1. + */ +#define IEEE_TRAP_ENABLE_INV (1<<1) /* invalid op */ +#define IEEE_TRAP_ENABLE_DZE (1<<2) /* division by zero */ +#define IEEE_TRAP_ENABLE_OVF (1<<3) /* overflow */ +#define IEEE_TRAP_ENABLE_UNF (1<<4) /* underflow */ +#define IEEE_TRAP_ENABLE_INE (1<<5) /* inexact */ +#define IEEE_TRAP_ENABLE_MASK (IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE |\ + IEEE_TRAP_ENABLE_OVF | IEEE_TRAP_ENABLE_UNF |\ + IEEE_TRAP_ENABLE_INE) + +/* status bits coming from fpcr: */ +#define IEEE_STATUS_INV (1<<17) +#define IEEE_STATUS_DZE (1<<18) +#define IEEE_STATUS_OVF (1<<19) +#define IEEE_STATUS_UNF (1<<20) +#define IEEE_STATUS_INE (1<<21) + +#define IEEE_STATUS_MASK (IEEE_STATUS_INV | IEEE_STATUS_DZE | \ + IEEE_STATUS_OVF | IEEE_STATUS_UNF | \ + IEEE_STATUS_INE) + +#define IEEE_STATUS_TO_EXCSUM_SHIFT 16 + +#define IEEE_INHERIT (1UL<<63) /* inherit on thread create? */ + +#endif /* __ASM_ALPHA_FPU_H */ diff --git a/include/asm-alpha/gentrap.h b/include/asm-alpha/gentrap.h new file mode 100644 index 000000000..ae50cc319 --- /dev/null +++ b/include/asm-alpha/gentrap.h @@ -0,0 +1,37 @@ +#ifndef _ASMAXP_GENTRAP_H +#define _ASMAXP_GENTRAP_H + +/* + * Definitions for gentrap causes. They are generated by user-level + * programs and therefore should be compatible with the corresponding + * OSF/1 definitions. + */ +#define GEN_INTOVF -1 /* integer overflow */ +#define GEN_INTDIV -2 /* integer division by zero */ +#define GEN_FLTOVF -3 /* fp overflow */ +#define GEN_FLTDIV -4 /* fp division by zero */ +#define GEN_FLTUND -5 /* fp underflow */ +#define GEN_FLTINV -6 /* invalid fp operand */ +#define GEN_FLTINE -7 /* inexact fp operand */ +#define GEN_DECOVF -8 /* decimal overflow (for COBOL??) */ +#define GEN_DECDIV -9 /* decimal division by zero */ +#define GEN_DECINV -10 /* invalid decimal operand */ +#define GEN_ROPRAND -11 /* reserved operand */ +#define GEN_ASSERTERR -12 /* assertion error */ +#define GEN_NULPTRERR -13 /* null pointer error */ +#define GEN_STKOVF -14 /* stack overflow */ +#define GEN_STRLENERR -15 /* string length error */ +#define GEN_SUBSTRERR -16 /* substring error */ +#define GEN_RANGERR -17 /* range error */ +#define GEN_SUBRNG -18 +#define GEN_SUBRNG1 -19 +#define GEN_SUBRNG2 -20 +#define GEN_SUBRNG3 -21 /* these report range errors for */ +#define GEN_SUBRNG4 -22 /* subscripting (indexing) at levels 0..7 */ +#define GEN_SUBRNG5 -23 +#define GEN_SUBRNG6 -24 +#define GEN_SUBRNG7 -25 + +/* the remaining codes (-26..-1023) are reserved. */ + +#endif /* _ASMAXP_GENTRAP_H */ diff --git a/include/asm-alpha/hwrpb.h b/include/asm-alpha/hwrpb.h index 35204d7c2..662aa35f6 100644 --- a/include/asm-alpha/hwrpb.h +++ b/include/asm-alpha/hwrpb.h @@ -13,28 +13,33 @@ #define LCA4_CPU 4 /* LCA4 (21066/21068) */ #define EV5_CPU 5 /* EV5 (21164) */ #define EV45_CPU 6 /* EV4.5 (21064/xxx) */ +#define EV56_CPU 7 /* EV5.6 (21164) */ +#define EV6_CPU 8 /* EV6 (21164) */ /* * DEC system types for Alpha systems. Found in HWRPB. * These values are architected. */ -#define ST_ADU 1 /* Alpha ADU systype */ -#define ST_DEC_4000 2 /* Cobra systype */ -#define ST_DEC_7000 3 /* Ruby systype */ -#define ST_DEC_3000_500 4 /* Flamingo systype */ -#define ST_DEC_2000_300 6 /* Jensen systype */ -#define ST_DEC_3000_300 7 /* Pelican systype */ -#define ST_DEC_2100_A500 9 /* Sable systype */ -#define ST_DEC_AXPVME_64 10 /* AXPvme system type */ -#define ST_DEC_AXPPCI_33 11 /* NoName system type */ -#define ST_DEC_TLASER 12 /* Turbolaser systype */ -#define ST_DEC_2100_A50 13 /* Avanti systype */ -#define ST_DEC_MUSTANG 14 /* Mustang systype */ -#define ST_DEC_ALCOR 15 /* Alcor systype */ -#define ST_DEC_1000 17 /* Mikasa systype */ -#define ST_DEC_EB66 19 /* EB66 systype */ -#define ST_DEC_EB64P 20 /* EB64+ systype */ +#define ST_ADU 1 /* Alpha ADU systype */ +#define ST_DEC_4000 2 /* Cobra systype */ +#define ST_DEC_7000 3 /* Ruby systype */ +#define ST_DEC_3000_500 4 /* Flamingo systype */ +#define ST_DEC_2000_300 6 /* Jensen systype */ +#define ST_DEC_3000_300 7 /* Pelican systype */ +#define ST_DEC_2100_A500 9 /* Sable systype */ +#define ST_DEC_AXPVME_64 10 /* AXPvme system type */ +#define ST_DEC_AXPPCI_33 11 /* NoName system type */ +#define ST_DEC_TLASER 12 /* Turbolaser systype */ +#define ST_DEC_2100_A50 13 /* Avanti systype */ +#define ST_DEC_MUSTANG 14 /* Mustang systype */ +#define ST_DEC_ALCOR 15 /* Alcor (EV5) systype */ +#define ST_DEC_1000 17 /* Mikasa systype */ +#define ST_DEC_EB66 19 /* EB66 systype */ +#define ST_DEC_EB64P 20 /* EB64+ systype */ +#define ST_DEC_EB66P -19 /* EB66 systype */ +#define ST_DEC_EBPC64 -20 /* Cabriolet (AlphaPC64) systype */ +#define ST_DEC_EB164 26 /* EB164 systype */ struct pcb_struct { unsigned long ksp; diff --git a/include/asm-alpha/ide.h b/include/asm-alpha/ide.h new file mode 100644 index 000000000..6ad91b1d7 --- /dev/null +++ b/include/asm-alpha/ide.h @@ -0,0 +1,119 @@ +/* + * linux/include/asm-alpha/ide.h + * + * Copyright (C) 1994-1996 Linus Torvalds & authors + */ + +/* + * This file contains the alpha architecture specific IDE code. + */ + +#ifndef __ASMalpha_IDE_H +#define __ASMalpha_IDE_H + +#ifdef __KERNEL__ + +typedef unsigned short ide_ioreg_t; + +#ifndef MAX_HWIFS +#define MAX_HWIFS 4 +#endif + +#define ide_sti() sti() + +static __inline__ int ide_default_irq(ide_ioreg_t base) +{ + switch (base) { + case 0x1f0: return 14; + case 0x170: return 15; + case 0x1e8: return 11; + case 0x168: return 10; + default: + return 0; + } +} + +static __inline__ ide_ioreg_t ide_default_io_base(int index) +{ + switch (index) { + case 0: return 0x1f0; + case 1: return 0x170; + case 2: return 0x1e8; + case 3: return 0x168; + default: + return 0; + } +} + +static __inline__ void ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq) +{ + ide_ioreg_t port = base; + int i = 8; + + while (i--) + *p++ = port++; + *p++ = base + 0x206; + if (irq != NULL) + *irq = 0; +} + +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 base_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 /* __ASMalpha_IDE_H */ diff --git a/include/asm-alpha/io.h b/include/asm-alpha/io.h index e567c750b..ed6cffc1f 100644 --- a/include/asm-alpha/io.h +++ b/include/asm-alpha/io.h @@ -5,6 +5,10 @@ #include <asm/system.h> +/* We don't use IO slowdowns on the alpha, but.. */ +#define __SLOW_DOWN_IO do { } while (0) +#define SLOW_DOWN_IO do { } while (0) + /* * The hae (hardware address extension) register is used to * access high IO addresses. To avoid doing an external cycle @@ -19,6 +23,13 @@ extern struct hae { } hae; /* + * Virtual -> physical identity mapping starts at this offset + */ +#define IDENT_ADDR (0xfffffc0000000000UL) + +#ifdef __KERNEL__ + +/* * We try to avoid hae updates (thus the cache), but when we * do need to update the hae, we need to do it atomically, so * that any interrupts wouldn't get confused with the hae @@ -35,14 +46,9 @@ extern inline void set_hae(unsigned long new_hae) } /* - * Virtual -> physical identity mapping starts at this offset - */ -#define IDENT_ADDR (0xfffffc0000000000UL) - -/* * Change virtual addresses to physical addresses and vv. */ -extern inline unsigned long virt_to_phys(void * address) +extern inline unsigned long virt_to_phys(volatile void * address) { return 0xffffffffUL & (unsigned long) address; } @@ -52,15 +58,179 @@ extern inline void * phys_to_virt(unsigned long address) return (void *) (address + IDENT_ADDR); } +#else /* !__KERNEL__ */ + +/* + * Define actual functions in private name-space so it's easier to + * accommodate things like XFree or svgalib that like to define their + * own versions of inb etc. + */ +extern void __sethae (unsigned long addr); /* syscall */ +extern void _sethae (unsigned long addr); /* cached version */ + +#endif /* !__KERNEL__ */ + /* - * There are different version of the alpha motherboards: the - * "interesting" (read: slightly braindead) Jensen type hardware - * and the PCI version + * There are different chipsets to interface the Alpha CPUs to the world. */ -#ifdef CONFIG_PCI -#include <asm/lca.h> /* get chip-specific definitions */ +#if defined(CONFIG_ALPHA_LCA) +# include <asm/lca.h> /* get chip-specific definitions */ +#elif defined(CONFIG_ALPHA_APECS) +# include <asm/apecs.h> /* get chip-specific definitions */ +#elif defined(CONFIG_ALPHA_CIA) +# include <asm/cia.h> /* get chip-specific definitions */ #else -#include <asm/jensen.h> +# include <asm/jensen.h> #endif +/* + * The convention used for inb/outb etc. is that names starting with + * two underscores are the inline versions, names starting with a + * single underscore are proper functions, and names starting with a + * letter are macros that map in some way to inline or proper function + * versions. Not all that pretty, but before you change it, be sure + * to convince yourself that it won't break anything (in particular + * module support). + */ +extern unsigned int _inb (unsigned long port); +extern unsigned int _inw (unsigned long port); +extern unsigned int _inl (unsigned long port); +extern void _outb (unsigned char b,unsigned long port); +extern void _outw (unsigned short w,unsigned long port); +extern void _outl (unsigned int l,unsigned long port); +extern unsigned long _readb(unsigned long addr); +extern unsigned long _readw(unsigned long addr); +extern unsigned long _readl(unsigned long addr); +extern void _writeb(unsigned char b, unsigned long addr); +extern void _writew(unsigned short b, unsigned long addr); +extern void _writel(unsigned int b, unsigned long addr); + +/* + * The platform header files may define some of these macros to use + * the inlined versions where appropriate. These macros may also be + * redefined by userlevel programs. + */ +#ifndef inb +# define inb(p) _inb((p)) +#endif +#ifndef inw +# define inw(p) _inw((p)) +#endif +#ifndef inl +# define inl(p) _inl((p)) +#endif +#ifndef outb +# define outb(b,p) _outb((b),(p)) +#endif +#ifndef outw +# define outw(w,p) _outw((w),(p)) +#endif +#ifndef outl +# define outl(l,p) _outl((l),(p)) +#endif + +#ifndef inb_p +# define inb_p inb +#endif +#ifndef inw_p +# define inw_p inw +#endif +#ifndef inl_p +# define inl_p inl +#endif + +#ifndef outb_p +# define outb_p outb +#endif +#ifndef outw_p +# define outw_p outw +#endif +#ifndef outl_p +# define outl_p outl +#endif + +/* + * The "address" in IO memory space is not clearly either an integer or a + * pointer. We will accept both, thus the casts. + * + * On the alpha, we have the whole physical address space mapped at all + * times, so "ioremap()" and "iounmap()" do not need to do anything. + */ +extern inline void * ioremap(unsigned long offset, unsigned long size) +{ + return (void *) offset; +} + +extern inline void iounmap(void *addr) +{ +} + +#ifndef readb +# define readb(a) _readb((unsigned long)(a)) +#endif +#ifndef readw +# define readw(a) _readw((unsigned long)(a)) +#endif +#ifndef readl +# define readl(a) _readl((unsigned long)(a)) +#endif +#ifndef writeb +# define writeb(v,a) _writeb((v),(unsigned long)(a)) +#endif +#ifndef writew +# define writew(v,a) _writew((v),(unsigned long)(a)) +#endif +#ifndef writel +# define writel(v,a) _writel((v),(unsigned long)(a)) +#endif + +#ifdef __KERNEL__ + +/* + * String version of IO memory access ops: + */ +extern void _memcpy_fromio(void *, unsigned long, unsigned long); +extern void _memcpy_toio(unsigned long, void *, unsigned long); +extern void _memset_io(unsigned long, int, unsigned long); + +#define memcpy_fromio(to,from,len) _memcpy_fromio((to),(unsigned long)(from),(len)) +#define memcpy_toio(to,from,len) _memcpy_toio((unsigned long)(to),(from),(len)) +#define memset_io(addr,c,len) _memset_io((unsigned long)(addr),(c),(len)) + +/* + * String versions of in/out ops: + */ +extern void insb (unsigned long port, void *dst, unsigned long count); +extern void insw (unsigned long port, void *dst, unsigned long count); +extern void insl (unsigned long port, void *dst, unsigned long count); +extern void outsb (unsigned long port, const void *src, unsigned long count); +extern void outsw (unsigned long port, const void *src, unsigned long count); +extern void outsl (unsigned long port, const void *src, unsigned long count); + +/* + * XXX - We don't have csum_partial_copy_fromio() yet, so we cheat here and + * just copy it. The net code will then do the checksum later. Presently + * only used by some shared memory 8390 ethernet cards anyway. + */ + +#define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len)) + +static inline int check_signature(unsigned long io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + +#endif /* __KERNEL__ */ + #endif diff --git a/include/asm-alpha/ioctl.h b/include/asm-alpha/ioctl.h index a981caadf..fc63727f4 100644 --- a/include/asm-alpha/ioctl.h +++ b/include/asm-alpha/ioctl.h @@ -36,11 +36,12 @@ #define _IOC_READ 2U #define _IOC_WRITE 4U -#define _IOC(dir,type,nr,size) \ - (((dir) << _IOC_DIRSHIFT) | \ - ((type) << _IOC_TYPESHIFT) | \ - ((nr) << _IOC_NRSHIFT) | \ - ((size) << _IOC_SIZESHIFT)) +#define _IOC(dir,type,nr,size) \ + ((unsigned int) \ + (((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) @@ -54,4 +55,12 @@ #define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) #define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) -#endif +/* ...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 /* _ALPHA_IOCTL_H */ diff --git a/include/asm-alpha/ioctls.h b/include/asm-alpha/ioctls.h new file mode 100644 index 000000000..bb4f71de8 --- /dev/null +++ b/include/asm-alpha/ioctls.h @@ -0,0 +1,102 @@ +#ifndef _ASM_ALPHA_IOCTLS_H +#define _ASM_ALPHA_IOCTLS_H + +#include <asm/ioctl.h> + +#define FIOCLEX _IO('f', 1) +#define FIONCLEX _IO('f', 2) +#define FIOASYNC _IOW('f', 125, int) +#define FIONBIO _IOW('f', 126, int) +#define FIONREAD _IOR('f', 127, int) +#define TIOCINQ FIONREAD + +#define TIOCGETP _IOR('t', 8, struct sgttyb) +#define TIOCSETP _IOW('t', 9, struct sgttyb) +#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ + +#define TIOCSETC _IOW('t', 17, struct tchars) +#define TIOCGETC _IOR('t', 18, struct tchars) +#define TCGETS _IOR('t', 19, struct termios) +#define TCSETS _IOW('t', 20, struct termios) +#define TCSETSW _IOW('t', 21, struct termios) +#define TCSETSF _IOW('t', 22, struct termios) + +#define TCGETA _IOR('t', 23, struct termio) +#define TCSETA _IOW('t', 24, struct termio) +#define TCSETAW _IOW('t', 25, struct termio) +#define TCSETAF _IOW('t', 28, struct termio) + +#define TCSBRK _IO('t', 29) +#define TCXONC _IO('t', 30) +#define TCFLSH _IO('t', 31) + +#define TIOCSWINSZ _IOW('t', 103, struct winsize) +#define TIOCGWINSZ _IOR('t', 104, struct winsize) +#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ +#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ +#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ + +#define TIOCGLTC _IOR('t', 116, struct ltchars) +#define TIOCSLTC _IOW('t', 117, struct ltchars) +#define TIOCSPGRP _IOW('t', 118, int) +#define TIOCGPGRP _IOR('t', 119, int) + +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E + +#define TIOCSTI 0x5412 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +# define TIOCM_LE 0x001 +# define TIOCM_DTR 0x002 +# define TIOCM_RTS 0x004 +# define TIOCM_ST 0x008 +# define TIOCM_SR 0x010 +# define TIOCM_CTS 0x020 +# define TIOCM_CAR 0x040 +# define TIOCM_RNG 0x080 +# define TIOCM_DSR 0x100 +# define TIOCM_CD TIOCM_CAR +# define TIOCM_RI TIOCM_RNG + +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +# 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 TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ + +#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 */ + /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ +# define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ +#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 */ + +#endif /* _ASM_ALPHA_IOCTLS_H */ diff --git a/include/asm-alpha/irq.h b/include/asm-alpha/irq.h index 2a7421aef..bf2a380e9 100644 --- a/include/asm-alpha/irq.h +++ b/include/asm-alpha/irq.h @@ -8,6 +8,18 @@ */ #include <linux/linkage.h> +#include <linux/config.h> + +#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P) || defined(CONFIG_ALPHA_EB164) || defined(CONFIG_ALPHA_PC164) +# define NR_IRQS 33 +#elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P) || defined(CONFIG_ALPHA_MIKASA) +# define NR_IRQS 32 +#elif defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT) +# define NR_IRQS 48 +#else +# define NR_IRQS 16 +#endif + extern void disable_irq(unsigned int); extern void enable_irq(unsigned int); diff --git a/include/asm-alpha/jensen.h b/include/asm-alpha/jensen.h index 952d56375..7a3b07851 100644 --- a/include/asm-alpha/jensen.h +++ b/include/asm-alpha/jensen.h @@ -95,6 +95,8 @@ extern inline void __set_hae(unsigned long addr) set_hae(addr); } +#ifdef __KERNEL__ + /* * IO functions * @@ -118,8 +120,9 @@ extern inline void __local_outb(unsigned char b, unsigned long addr) mb(); } -extern unsigned int __bus_inb(unsigned long addr); -extern inline unsigned int ___bus_inb(unsigned long addr) +extern unsigned int _bus_inb(unsigned long addr); + +extern inline unsigned int __bus_inb(unsigned long addr) { long result; @@ -129,8 +132,9 @@ extern inline unsigned int ___bus_inb(unsigned long addr) return 0xffUL & result; } -extern void __bus_outb(unsigned char b, unsigned long addr); -extern inline void ___bus_outb(unsigned char b, unsigned long addr) +extern void _bus_outb(unsigned char b, unsigned long addr); + +extern inline void __bus_outb(unsigned char b, unsigned long addr) { __set_hae(0); *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x00) = b * 0x01010101; @@ -153,7 +157,7 @@ extern inline unsigned int __inb(unsigned long addr) { if (__is_local(addr)) return __local_inb(addr); - return __bus_inb(addr); + return _bus_inb(addr); } extern inline void __outb(unsigned char b, unsigned long addr) @@ -161,7 +165,7 @@ extern inline void __outb(unsigned char b, unsigned long addr) if (__is_local(addr)) __local_outb(b, addr); else - __bus_outb(b, addr); + _bus_outb(b, addr); } extern inline unsigned int __inw(unsigned long addr) @@ -251,30 +255,13 @@ extern inline void __writel(unsigned int b, unsigned long addr) * The above have so much overhead that it probably doesn't make * sense to have them inlined (better icache behaviour). */ -extern unsigned int inb(unsigned long addr); -extern unsigned int inw(unsigned long addr); -extern unsigned int inl(unsigned long addr); - -extern void outb(unsigned char b, unsigned long addr); -extern void outw(unsigned short b, unsigned long addr); -extern void outl(unsigned int b, unsigned long addr); - -extern unsigned long readb(unsigned long addr); -extern unsigned long readw(unsigned long addr); -extern unsigned long readl(unsigned long addr); - -extern void writeb(unsigned short b, unsigned long addr); -extern void writew(unsigned short b, unsigned long addr); -extern void writel(unsigned int b, unsigned long addr); - #define inb(port) \ -(__builtin_constant_p((port))?__inb(port):(inb)(port)) +(__builtin_constant_p((port))?__inb(port):_inb(port)) #define outb(x, port) \ -(__builtin_constant_p((port))?__outb((x),(port)):(outb)((x),(port))) +(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port))) -#define inb_p inb -#define outb_p outb +#endif /* __KERNEL__ */ /* * The Alpha Jensen hardware for some rather strange reason puts diff --git a/include/asm-alpha/keyboard.h b/include/asm-alpha/keyboard.h new file mode 100644 index 000000000..6aca53255 --- /dev/null +++ b/include/asm-alpha/keyboard.h @@ -0,0 +1,176 @@ +/* + * CPU specific parts of the keyboard driver + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#ifndef __ASM_ALPHA_KEYBOARD_H +#define __ASM_ALPHA_KEYBOARD_H + +#include <asm/io.h> + +#define KEYBOARD_IRQ 1 + +static int initialize_kbd(void); + +#define kbd_inb_p(port) inb_p(port) +#define kbd_inb(port) inb(port) +#define kbd_outb_p(data,port) outb_p(data,port) +#define kbd_outb(data,port) outb(data,port) + +static int +kbd_wait_for_input(void) +{ + int n; + int status, data; + + n = TIMEOUT_CONST; + do { + status = kbd_inb(KBD_STATUS_REG); + /* + * Wait for input data to become available. This bit will + * then be cleared by the following read of the DATA + * register. + */ + + if (!(status & KBD_OBF)) + continue; + + data = kbd_inb(KBD_DATA_REG); + + /* + * Check to see if a timeout error has occurred. This means + * that transmission was started but did not complete in the + * normal time cycle. PERR is set when a parity error occurred + * in the last transmission. + */ + if (status & (KBD_GTO | KBD_PERR)) { + continue; + } + return (data & 0xff); + } while (--n); + return (-1); /* timed-out if fell through to here... */ +} + +static void +kbd_write(int address, int data) +{ + int status; + + do { + status = kbd_inb(KBD_STATUS_REG); /* spin until input buffer empty*/ + } while (status & KBD_IBF); + kbd_outb(data, address); /* write out the data*/ +} + +static int +initialize_kbd(void) +{ + unsigned long flags; + + save_flags(flags); cli(); + + /* Flush any pending input. */ + while (kbd_wait_for_input() != -1) + continue; + + /* + * Test the keyboard interface. + * This seems to be the only way to get it going. + * If the test is successful a x55 is placed in the input buffer. + */ + kbd_write(KBD_CNTL_REG, KBD_SELF_TEST); + if (kbd_wait_for_input() != 0x55) { + printk(KERN_WARNING "initialize_kbd: " + "keyboard failed self test.\n"); + restore_flags(flags); + return(-1); + } + + /* + * Perform a keyboard interface test. This causes the controller + * to test the keyboard clock and data lines. The results of the + * test are placed in the input buffer. + */ + kbd_write(KBD_CNTL_REG, KBD_SELF_TEST2); + if (kbd_wait_for_input() != 0x00) { + printk(KERN_WARNING "initialize_kbd: " + "keyboard failed self test 2.\n"); + restore_flags(flags); + return(-1); + } + + /* Enable the keyboard by allowing the keyboard clock to run. */ + kbd_write(KBD_CNTL_REG, KBD_CNTL_ENABLE); + + /* + * Reset keyboard. If the read times out + * then the assumption is that no keyboard is + * plugged into the machine. + * This defaults the keyboard to scan-code set 2. + */ + kbd_write(KBD_DATA_REG, KBD_RESET); + if (kbd_wait_for_input() != KBD_ACK) { + printk(KERN_WARNING "initialize_kbd: " + "reset kbd failed, no ACK.\n"); + restore_flags(flags); + return(-1); + } + + /* + * Give the keyboard some time to breathe ... + * ... or it fucks up the floppy controller, too. Wiered. + */ + udelay(20); + + if (kbd_wait_for_input() != KBD_POR) { + printk(KERN_WARNING "initialize_kbd: " + "reset kbd failed, not POR.\n"); + restore_flags(flags); + return(-1); + } + + /* + * now do a DEFAULTS_DISABLE always + */ + kbd_write(KBD_DATA_REG, KBD_DISABLE); + if (kbd_wait_for_input() != KBD_ACK) { + printk(KERN_WARNING "initialize_kbd: " + "disable kbd failed, no ACK.\n"); + restore_flags(flags); + return(-1); + } + + /* + * Enable keyboard interrupt, operate in "sys" mode, + * enable keyboard (by clearing the disable keyboard bit), + * disable mouse, do conversion of keycodes. + */ + kbd_write(KBD_CNTL_REG, KBD_WRITE_MODE); + kbd_write(KBD_DATA_REG, KBD_EKI|KBD_SYS|KBD_DMS|KBD_KCC); + + /* + * now ENABLE the keyboard to set it scanning... + */ + kbd_write(KBD_DATA_REG, KBD_ENABLE); + if (kbd_wait_for_input() != KBD_ACK) { + printk(KERN_WARNING "initialize_kbd: " + "keyboard enable failed.\n"); + restore_flags(flags); + return(-1); + } + + restore_flags(flags); + + return (1); +} + +extern __inline__ void +keyboard_setup() +{ + request_region(0x60,16,"keyboard"); + initialize_kbd(); +} + +#endif /* __ASM_ALPHA_KEYBOARD_H */ diff --git a/include/asm-alpha/lca.h b/include/asm-alpha/lca.h index c3f58650f..43c6e9eca 100644 --- a/include/asm-alpha/lca.h +++ b/include/asm-alpha/lca.h @@ -1,5 +1,5 @@ -#ifndef __ALPHA_LCA__H -#define __ALPHA_LCA__H +#ifndef __ALPHA_LCA__H__ +#define __ALPHA_LCA__H__ /* * Low Cost Alpha (LCA) definitions (these apply to 21066 and 21068, @@ -52,24 +52,12 @@ * ugh). */ +#include <asm/system.h> + #define LCA_DMA_WIN_BASE (1024*1024*1024) #define LCA_DMA_WIN_SIZE (1024*1024*1024) /* - * Translate physical memory address as seen on (PCI) bus into - * a kernel virtual address and vv. - */ -extern inline unsigned long virt_to_bus(void * address) -{ - return virt_to_phys(address) + LCA_DMA_WIN_BASE; -} - -extern inline void * bus_to_virt(unsigned long address) -{ - return phys_to_virt(address - LCA_DMA_WIN_BASE); -} - -/* * Memory Controller registers: */ #define LCA_MEM_BCR0 (IDENT_ADDR + 0x120000000UL) @@ -142,6 +130,30 @@ extern inline void * bus_to_virt(unsigned long address) #define HAE_ADDRESS LCA_IOC_HAE +#ifdef __KERNEL__ + +/* + * Translate physical memory address as seen on (PCI) bus into + * a kernel virtual address and vv. + */ +extern inline unsigned long virt_to_bus(void * address) +{ + return virt_to_phys(address) + LCA_DMA_WIN_BASE; +} + +extern inline void * bus_to_virt(unsigned long address) +{ + /* + * This check is a sanity check but also ensures that bus + * address 0 maps to virtual address 0 which is useful to + * detect null "pointers" (the NCR driver is much simpler if + * NULL pointers are preserved). + */ + if (address < LCA_DMA_WIN_BASE) + return 0; + return phys_to_virt(address - LCA_DMA_WIN_BASE); +} + /* * I/O functions: * @@ -245,6 +257,7 @@ extern inline unsigned long __readl(unsigned long addr) extern inline void __writeb(unsigned char b, unsigned long addr) { unsigned long msb; + unsigned int w; if (addr >= (1UL << 24)) { msb = addr & 0xf8000000; @@ -253,12 +266,14 @@ extern inline void __writeb(unsigned char b, unsigned long addr) set_hae(msb); } } - *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x00) = b * 0x01010101; + asm ("insbl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b)); + *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x00) = w; } extern inline void __writew(unsigned short b, unsigned long addr) { unsigned long msb; + unsigned int w; if (addr >= (1UL << 24)) { msb = addr & 0xf8000000; @@ -267,7 +282,8 @@ extern inline void __writew(unsigned short b, unsigned long addr) set_hae(msb); } } - *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x08) = b * 0x00010001; + asm ("inswl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b)); + *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x08) = w; } extern inline void __writel(unsigned int b, unsigned long addr) @@ -279,34 +295,63 @@ extern inline void __writel(unsigned int b, unsigned long addr) * Most of the above have so much overhead that it probably doesn't * make sense to have them inlined (better icache behavior). */ -extern unsigned int inb(unsigned long addr); -extern unsigned int inw(unsigned long addr); -extern unsigned int inl(unsigned long addr); - -extern void outb(unsigned char b, unsigned long addr); -extern void outw(unsigned short b, unsigned long addr); -extern void outl(unsigned int b, unsigned long addr); - -extern unsigned long readb(unsigned long addr); -extern unsigned long readw(unsigned long addr); - -extern void writeb(unsigned short b, unsigned long addr); -extern void writew(unsigned short b, unsigned long addr); #define inb(port) \ -(__builtin_constant_p((port))?__inb(port):(inb)(port)) +(__builtin_constant_p((port))?__inb(port):_inb(port)) #define outb(x, port) \ -(__builtin_constant_p((port))?__outb((x),(port)):(outb)((x),(port))) - -#define inb_p inb -#define outb_p outb +(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port))) -#define readl(addr) __readl(addr) -#define writel(b,addr) __writel(b,addr) +#define readl(a) __readl((unsigned long)(a)) +#define writel(v,a) __writel((v),(unsigned long)(a)) #undef vuip extern unsigned long lca_init (unsigned long mem_start, unsigned long mem_end); -#endif +#endif /* __KERNEL__ */ + +/* + * Data structure for handling LCA machine checks. Correctable errors + * result in a short logout frame, uncorrectable ones in a long one. + */ +struct el_lca_mcheck_short { + struct el_common h; /* common logout header */ + unsigned long esr; /* error-status register */ + unsigned long ear; /* error-address register */ + unsigned long dc_stat; /* dcache status register */ + unsigned long ioc_stat0; /* I/O controller status register 0 */ + unsigned long ioc_stat1; /* I/O controller status register 1 */ +}; + +struct el_lca_mcheck_long { + struct el_common h; /* common logout header */ + unsigned long pt[31]; /* PAL temps */ + unsigned long exc_addr; /* exception address */ + unsigned long pad1[3]; + unsigned long pal_base; /* PALcode base address */ + unsigned long hier; /* hw interrupt enable */ + unsigned long hirr; /* hw interrupt request */ + unsigned long mm_csr; /* MMU control & status */ + unsigned long dc_stat; /* data cache status */ + unsigned long dc_addr; /* data cache addr register */ + unsigned long abox_ctl; /* address box control register */ + unsigned long esr; /* error status register */ + unsigned long ear; /* error address register */ + unsigned long car; /* cache control register */ + unsigned long ioc_stat0; /* I/O controller status register 0 */ + unsigned long ioc_stat1; /* I/O controller status register 1 */ + unsigned long va; /* virtual address register */ +}; + +union el_lca { + struct el_common * c; + struct el_lca_mcheck_long * l; + struct el_lca_mcheck_short * s; +}; + +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ADDR(x) (0x80 | (x)) +#define RTC_ALWAYS_BCD 0 + +#endif /* __ALPHA_LCA__H__ */ diff --git a/include/asm-alpha/mc146818rtc.h b/include/asm-alpha/mc146818rtc.h new file mode 100644 index 000000000..40ce6163f --- /dev/null +++ b/include/asm-alpha/mc146818rtc.h @@ -0,0 +1,23 @@ +/* + * Machine dependend access functions for RTC registers. + */ +#ifndef __ASM_ALPHA_MC146818RTC_H +#define __ASM_ALPHA_MC146818RTC_H + +#include <asm/io.h> + +#ifndef RTC_PORT +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ALWAYS_BCD 1 +#endif + +#define CMOS_READ(addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +inb_p(RTC_PORT(1)); \ +}) +#define CMOS_WRITE(val, addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +outb_p((val),RTC_PORT(1)); \ +}) + +#endif /* __ASM_ALPHA_MC146818RTC_H */ diff --git a/include/asm-alpha/mman.h b/include/asm-alpha/mman.h new file mode 100644 index 000000000..a08ec81df --- /dev/null +++ b/include/asm-alpha/mman.h @@ -0,0 +1,38 @@ +#ifndef __ALPHA_MMAN_H__ +#define __ALPHA_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 (OSF/1 is _wrong_) */ +#define MAP_FIXED 0x100 /* Interpret addr exactly */ +#define MAP_ANONYMOUS 0x10 /* don't use a file */ + +/* not used by linux, but here to make sure we don't clash with OSF/1 defines */ +#define MAP_HASSEMAPHORE 0x0200 +#define MAP_INHERIT 0x0400 +#define MAP_UNALIGNED 0x0800 + +/* These are linux-specific */ +#define MAP_GROWSDOWN 0x1000 /* stack-like segment */ +#define MAP_DENYWRITE 0x2000 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x4000 /* mark it as an executable */ +#define MAP_LOCKED 0x8000 /* lock the mapping */ +#define MAP_NORESERVE 0x10000 /* don't check for reservations */ + +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_SYNC 2 /* synchronous memory sync */ +#define MS_INVALIDATE 4 /* invalidate the caches */ + +#define MCL_CURRENT 8192 /* lock all currently mapped pages */ +#define MCL_FUTURE 16384 /* lock all additions to address space */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif /* __ALPHA_MMAN_H__ */ diff --git a/include/asm-alpha/mmu_context.h b/include/asm-alpha/mmu_context.h new file mode 100644 index 000000000..a94d1b7ea --- /dev/null +++ b/include/asm-alpha/mmu_context.h @@ -0,0 +1,90 @@ +#ifndef __ALPHA_MMU_CONTEXT_H +#define __ALPHA_MMU_CONTEXT_H + +/* + * get a new mmu context.. + * + * Copyright (C) 1996, Linus Torvalds + */ + +#include <linux/config.h> +#include <asm/system.h> + +/* + * The maximum ASN's the processor supports. On the EV4 this is 63 + * but the PAL-code doesn't actually use this information. On the + * EV5 this is 127. + * + * On the EV4, the ASNs are more-or-less useless anyway, as they are + * only used as an icache tag, not for TB entries. On the EV5 ASN's + * also validate the TB entries, and thus make a lot more sense. + * + * The EV4 ASN's don't even match the architecture manual, ugh. And + * I quote: "If a processor implements address space numbers (ASNs), + * and the old PTE has the Address Space Match (ASM) bit clear (ASNs + * in use) and the Valid bit set, then entries can also effectively be + * made coherent by assigning a new, unused ASN to the currently + * running process and not reusing the previous ASN before calling the + * appropriate PALcode routine to invalidate the translation buffer + * (TB)". + * + * In short, the EV4 has a "kind of" ASN capability, but it doesn't actually + * work correctly and can thus not be used (explaining the lack of PAL-code + * support). + */ +#ifdef CONFIG_ALPHA_EV5 +#define MAX_ASN 127 +#else +#define MAX_ASN 63 +#define BROKEN_ASN 1 +#endif + +extern unsigned long asn_cache; + +#define ASN_VERSION_SHIFT 16 +#define ASN_VERSION_MASK ((~0UL) << ASN_VERSION_SHIFT) +#define ASN_FIRST_VERSION (1UL << ASN_VERSION_SHIFT) + +extern inline void get_new_mmu_context(struct task_struct *p, + struct mm_struct *mm, + unsigned long asn) +{ + /* check if it's legal.. */ + if ((asn & ~ASN_VERSION_MASK) > MAX_ASN) { + /* start a new version, invalidate all old asn's */ + tbiap(); imb(); + asn = (asn & ASN_VERSION_MASK) + ASN_FIRST_VERSION; + if (!asn) + asn = ASN_FIRST_VERSION; + } + asn_cache = asn + 1; + mm->context = asn; /* full version + asn */ + p->tss.asn = asn & ~ASN_VERSION_MASK; /* just asn */ +} + +/* + * NOTE! The way this is set up, the high bits of the "asn_cache" (and + * the "mm->context") are the ASN _version_ code. A version of 0 is + * always considered invalid, so to invalidate another process you only + * need to do "p->mm->context = 0". + * + * If we need more ASN's than the processor has, we invalidate the old + * user TLB's (tbiap()) and start a new ASN version. That will automatically + * force a new asn for any other processes the next time they want to + * run. + */ +extern inline void get_mmu_context(struct task_struct *p) +{ +#ifndef BROKEN_ASN + struct mm_struct * mm = p->mm; + + if (mm) { + unsigned long asn = asn_cache; + /* Check if our ASN is of an older version and thus invalid */ + if ((mm->context ^ asn) & ASN_VERSION_MASK) + get_new_mmu_context(p, mm, asn); + } +#endif +} + +#endif diff --git a/include/asm-alpha/page.h b/include/asm-alpha/page.h index 316bc9dd1..9e4f2d595 100644 --- a/include/asm-alpha/page.h +++ b/include/asm-alpha/page.h @@ -8,9 +8,68 @@ #ifdef __KERNEL__ -#define CONFIG_STRICT_MM_TYPECHECKS +#define STRICT_MM_TYPECHECKS -#ifdef CONFIG_STRICT_MM_TYPECHECKS +/* + * A _lot_ of the kernel time is spent clearing pages, so + * do this as fast as we possibly can. Also, doing this + * as a separate inline function (rather than memset()) + * results in clearer kernel profiles as we see _who_ is + * doing page clearing or copying. + */ +static inline void clear_page(unsigned long page) +{ + unsigned long count; + __asm__ __volatile__( + ".align 4\n" + "1:\n\t" + "stq $31,0(%1)\n\t" + "stq $31,8(%1)\n\t" + "stq $31,16(%1)\n\t" + "stq $31,24(%1)\n\t" + "subq %0,1,%0\n\t" + "stq $31,32(%1)\n\t" + "stq $31,40(%1)\n\t" + "stq $31,48(%1)\n\t" + "stq $31,56(%1)\n\t" + "addq $1,64,$1\n\t" + "bne %0,1b" + :"=r" (count),"=r" (page) + :"0" (PAGE_SIZE/64), "1" (page)); +} + +static inline void copy_page(unsigned long to, unsigned long from) +{ + unsigned long count; + __asm__ __volatile__( + ".align 4\n" + "1:\n\t" + "ldq $0,0(%1)\n\t" + "ldq $1,8(%1)\n\t" + "ldq $2,16(%1)\n\t" + "ldq $3,24(%1)\n\t" + "ldq $4,32(%1)\n\t" + "ldq $5,40(%1)\n\t" + "ldq $6,48(%1)\n\t" + "ldq $7,56(%1)\n\t" + "subq %0,1,%0\n\t" + "addq %1,64,%1\n\t" + "stq $0,0(%2)\n\t" + "stq $1,8(%2)\n\t" + "stq $2,16(%2)\n\t" + "stq $3,24(%2)\n\t" + "stq $4,32(%2)\n\t" + "stq $5,40(%2)\n\t" + "stq $6,48(%2)\n\t" + "stq $7,56(%2)\n\t" + "addq %2,64,%2\n\t" + "bne %0,1b" + :"=r" (count), "=r" (from), "=r" (to) + :"0" (PAGE_SIZE/64), "1" (from), "2" (to) + :"$0","$1","$2","$3","$4","$5","$6","$7"); +} + +#ifdef STRICT_MM_TYPECHECKS /* * These are used to make use of C type-checking.. */ @@ -48,28 +107,15 @@ typedef unsigned long pgprot_t; #endif -#define invalidate_all() \ -__asm__ __volatile__( \ - "lda $16,-2($31)\n\t" \ - ".long 51" \ - : : :"$1", "$16", "$17", "$22","$23","$24","$25") - -#define invalidate() \ -__asm__ __volatile__( \ - "lda $16,-1($31)\n\t" \ - ".long 51" \ - : : :"$1", "$16", "$17", "$22","$23","$24","$25") - #define copy_page(from,to) memcpy((void *) to, (void *) from, PAGE_SIZE) /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) -#define PAGE_OFFSET 0xFFFFFC0000000000 -#define MAP_NR(addr) ((((unsigned long) (addr)) - PAGE_OFFSET) >> PAGE_SHIFT) -#define MAP_PAGE_RESERVED (1<<31) - -typedef unsigned int mem_map_t; +#define PAGE_OFFSET 0xFFFFFC0000000000UL +#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) +#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) +#define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT) #endif /* __KERNEL__ */ diff --git a/include/asm-alpha/pal.h b/include/asm-alpha/pal.h new file mode 100644 index 000000000..a4ef2e38a --- /dev/null +++ b/include/asm-alpha/pal.h @@ -0,0 +1,50 @@ +#ifndef __ALPHA_PAL_H +#define __ALPHA_PAL_H + +/* + * Common PAL-code + */ +#define PAL_halt 0 +#define PAL_cflush 1 +#define PAL_draina 2 +#define PAL_cobratt 9 +#define PAL_bpt 128 +#define PAL_bugchk 129 +#define PAL_chmk 131 +#define PAL_callsys 131 +#define PAL_imb 134 +#define PAL_rduniq 158 +#define PAL_wruniq 159 +#define PAL_gentrap 170 +#define PAL_nphalt 190 + +/* + * VMS specific PAL-code + */ +#define PAL_swppal 10 +#define PAL_mfpr_vptb 41 + +/* + * OSF specific PAL-code + */ +#define PAL_rdmces 16 +#define PAL_wrmces 17 +#define PAL_wrfen 43 +#define PAL_wrvptptr 45 +#define PAL_jtopal 46 +#define PAL_swpctx 48 +#define PAL_wrval 49 +#define PAL_rdval 50 +#define PAL_tbi 51 +#define PAL_wrent 52 +#define PAL_swpipl 53 +#define PAL_rdps 54 +#define PAL_wrkgp 55 +#define PAL_wrusp 56 +#define PAL_wrperfmon 57 +#define PAL_rdusp 58 +#define PAL_whami 60 +#define PAL_rtsys 61 +#define PAL_rti 63 + +#endif /* __ALPHA_PAL_H */ diff --git a/include/asm-alpha/param.h b/include/asm-alpha/param.h index 03f57ecff..07382f5f1 100644 --- a/include/asm-alpha/param.h +++ b/include/asm-alpha/param.h @@ -1,8 +1,8 @@ -#ifndef _ASMAXP_PARAM_H -#define _ASMAXP_PARAM_H +#ifndef _ASM_ALPHA_PARAM_H +#define _ASM_ALPHA_PARAM_H #ifndef HZ -#define HZ 1024 +# define HZ 1024 #endif #define EXEC_PAGESIZE 8192 @@ -17,4 +17,4 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ -#endif +#endif /* _ASM_ALPHA_PARAM_H */ diff --git a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h index 51425af46..937700caf 100644 --- a/include/asm-alpha/pgtable.h +++ b/include/asm-alpha/pgtable.h @@ -9,6 +9,131 @@ * in <asm/page.h> (currently 8192). */ +#include <asm/system.h> +#include <asm/mmu_context.h> + +/* Caches aren't brain-dead on the alpha. */ +#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) + +/* + * Force a context reload. This is needed when we + * change the page table pointer or when we update + * the ASN of the current process. + */ +static inline void reload_context(struct task_struct *task) +{ + __asm__ __volatile__( + "bis %0,%0,$16\n\t" + "call_pal %1" + : /* no outputs */ + : "r" (&task->tss), "i" (PAL_swpctx) + : "$0", "$1", "$16", "$22", "$23", "$24", "$25"); +} + +/* + * Use a few helper functions to hide the ugly broken ASN + * numbers on early alpha's (ev4 and ev45) + */ +#ifdef BROKEN_ASN + +#define flush_tlb_current(x) tbiap() +#define flush_tlb_other(x) do { } while (0) + +#else + +extern void get_new_asn_and_reload(struct task_struct *, struct mm_struct *); + +#define flush_tlb_current(mm) get_new_asn_and_reload(current, mm) +#define flush_tlb_other(mm) do { (mm)->context = 0; } while (0) + +#endif + +/* + * Flush just one page in the current TLB set. + * We need to be very careful about the icache here, there + * is no way to invalidate a specific icache page.. + */ +static inline void flush_tlb_current_page(struct mm_struct * mm, + struct vm_area_struct *vma, + unsigned long addr) +{ +#ifdef BROKEN_ASN + tbi(2 + ((vma->vm_flags & VM_EXEC) != 0), addr); +#else + if (vma->vm_flags & VM_EXEC) + flush_tlb_current(mm); + else + tbi(2, addr); +#endif +} + +/* + * Flush current user mapping. + */ +static inline void flush_tlb(void) +{ + flush_tlb_current(current->mm); +} + +/* + * Flush everything (kernel mapping may also have + * changed due to vmalloc/vfree) + */ +static inline void flush_tlb_all(void) +{ + tbia(); +} + +/* + * Flush a specified user mapping + */ +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + if (mm != current->mm) + flush_tlb_other(mm); + else + flush_tlb_current(mm); +} + +/* + * Page-granular tlb flush. + * + * do a tbisd (type = 2) normally, and a tbis (type = 3) + * if it is an executable mapping. We want to avoid the + * itlb flush, because that potentially also does a + * icache flush. + */ +static inline void flush_tlb_page(struct vm_area_struct *vma, + unsigned long addr) +{ + struct mm_struct * mm = vma->vm_mm; + + if (mm != current->mm) + flush_tlb_other(mm); + else + flush_tlb_current_page(mm, vma, addr); +} + +/* + * Flush a specified range of user mapping: on the + * alpha we flush the whole user tlb + */ +static inline void flush_tlb_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + flush_tlb_mm(mm); +} + +/* Certain architectures need to do special things when pte's + * within a page table are directly modified. Thus, the following + * hook is made available. + */ +#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 + (PAGE_SHIFT-3)) #define PMD_SIZE (1UL << PMD_SHIFT) @@ -49,7 +174,6 @@ #define _PAGE_UWE 0x2000 /* used to do the dirty bit in software */ /* .. and these are ours ... */ -#define _PAGE_COW 0x10000 #define _PAGE_DIRTY 0x20000 #define _PAGE_ACCESSED 0x40000 @@ -78,13 +202,13 @@ */ #define PAGE_NONE __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOR | _PAGE_FOW | _PAGE_FOE) #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS) -#define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_COW) +#define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW) #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW) #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE) #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x)) -#define _PAGE_P(x) _PAGE_NORMAL((x) | (((x) & _PAGE_FOW)?0:(_PAGE_FOW | _PAGE_COW))) +#define _PAGE_P(x) _PAGE_NORMAL((x) | (((x) & _PAGE_FOW)?0:_PAGE_FOW)) #define _PAGE_S(x) _PAGE_NORMAL(x) /* @@ -125,9 +249,9 @@ extern pmd_t * __bad_pagetable(void); extern unsigned long __zero_page(void); -#define BAD_PAGETABLE __bad_pagetable() -#define BAD_PAGE __bad_page() -#define ZERO_PAGE __zero_page() +#define BAD_PAGETABLE __bad_pagetable() +#define BAD_PAGE __bad_page() +#define ZERO_PAGE 0xfffffc000030A000 /* number of bits that fit into a memory pointer */ #define BITS_PER_PTR (8*sizeof(unsigned long)) @@ -142,8 +266,6 @@ extern unsigned long __zero_page(void); #define PAGE_PTR(address) \ ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) -extern unsigned long high_memory; - /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. @@ -151,6 +273,9 @@ extern unsigned long high_memory; extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot) { pte_t pte; pte_val(pte) = ((page-PAGE_OFFSET) << (32-PAGE_SHIFT)) | pgprot_val(pgprot); return pte; } +extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) +{ pte_t pte; pte_val(pte) = (physpage << (32-PAGE_SHIFT)) | 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; } @@ -171,35 +296,17 @@ extern inline unsigned long pgd_page(pgd_t pgd) 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_VALID; } -extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)] != 1; } extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; } -extern inline void pte_reuse(pte_t * ptep) -{ - if (!(mem_map[MAP_NR(ptep)] & MAP_PAGE_RESERVED)) - mem_map[MAP_NR(ptep)]++; -} extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); } -extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~_PFN_MASK) != _PAGE_TABLE || pmd_page(pmd) > high_memory; } +extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~_PFN_MASK) != _PAGE_TABLE; } extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_VALID; } -extern inline int pmd_inuse(pmd_t *pmdp) { return mem_map[MAP_NR(pmdp)] != 1; } extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = 0; } -extern inline void pmd_reuse(pmd_t * pmdp) -{ - if (!(mem_map[MAP_NR(pmdp)] & MAP_PAGE_RESERVED)) - mem_map[MAP_NR(pmdp)]++; -} extern inline int pgd_none(pgd_t pgd) { return !pgd_val(pgd); } -extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & ~_PFN_MASK) != _PAGE_TABLE || pgd_page(pgd) > high_memory; } +extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & ~_PFN_MASK) != _PAGE_TABLE; } extern inline int pgd_present(pgd_t pgd) { return pgd_val(pgd) & _PAGE_VALID; } -extern inline int pgd_inuse(pgd_t *pgdp) { return mem_map[MAP_NR(pgdp)] != 1; } extern inline void pgd_clear(pgd_t * pgdp) { pgd_val(*pgdp) = 0; } -extern inline void pgd_reuse(pgd_t * pgdp) -{ - if (!(mem_map[MAP_NR(pgdp)] & MAP_PAGE_RESERVED)) - mem_map[MAP_NR(pgdp)]++; -} /* * The following only work if pte_present() is true. @@ -210,20 +317,17 @@ extern inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_FOW); } extern inline int pte_exec(pte_t pte) { return !(pte_val(pte) & _PAGE_FOE); } 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; } -extern inline int pte_cow(pte_t pte) { return pte_val(pte) & _PAGE_COW; } extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_FOW; return pte; } extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) |= _PAGE_FOR; return pte; } extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) |= _PAGE_FOE; return pte; } extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~(__DIRTY_BITS); return pte; } extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~(__ACCESS_BITS); return pte; } -extern inline pte_t pte_uncow(pte_t pte) { pte_val(pte) &= ~_PAGE_COW; return pte; } extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_FOW; return pte; } extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) &= ~_PAGE_FOR; return pte; } extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) &= ~_PAGE_FOE; return pte; } extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= __DIRTY_BITS; return pte; } extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= __ACCESS_BITS; return pte; } -extern inline pte_t pte_mkcow(pte_t pte) { pte_val(pte) |= _PAGE_COW; return pte; } /* * To set the page-dir. Note the self-mapping in the last entry @@ -238,21 +342,15 @@ extern inline void SET_PAGE_DIR(struct task_struct * tsk, pgd_t * pgdir) pgd_val(pgdir[PTRS_PER_PGD]) = pte_val(mk_pte((unsigned long) pgdir, PAGE_KERNEL)); tsk->tss.ptbr = ((unsigned long) pgdir - PAGE_OFFSET) >> PAGE_SHIFT; if (tsk == current) - __asm__ __volatile__( - "bis %0,%0,$16\n\t" - "call_pal %1" - : /* no outputs */ - : "r" (&tsk->tss), "i" (PAL_swpctx) - : "$0", "$1", "$16", "$22", "$23", "$24", "$25"); + reload_context(tsk); } #define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) /* to find an entry in a page-table-directory. */ -extern inline pgd_t * pgd_offset(struct task_struct * tsk, unsigned long address) +extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) { - return (pgd_t *) ((tsk->tss.ptbr << PAGE_SHIFT) + PAGE_OFFSET) + - ((address >> PGDIR_SHIFT) & (PTRS_PER_PAGE - 1)); + return mm->pgd + ((address >> PGDIR_SHIFT) & (PTRS_PER_PAGE - 1)); } /* Find an entry in the second-level page table.. */ @@ -270,11 +368,10 @@ extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address) /* * Allocate and free page tables. The xxx_kernel() versions are * used to allocate a kernel page table - this turns on ASN bits - * if any, and marks the page tables reserved. + * if any. */ extern inline void pte_free_kernel(pte_t * pte) { - mem_map[MAP_NR(pte)] = 1; free_page((unsigned long) pte); } @@ -286,7 +383,6 @@ extern inline pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address) if (pmd_none(*pmd)) { if (page) { pmd_set(pmd, page); - mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED; return page + address; } pmd_set(pmd, (pte_t *) BAD_PAGETABLE); @@ -304,7 +400,6 @@ extern inline pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address) extern inline void pmd_free_kernel(pmd_t * pmd) { - mem_map[MAP_NR(pmd)] = 1; free_page((unsigned long) pmd); } @@ -316,7 +411,6 @@ extern inline pmd_t * pmd_alloc_kernel(pgd_t *pgd, unsigned long address) if (pgd_none(*pgd)) { if (page) { pgd_set(pgd, page); - mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED; return page + address; } pgd_set(pgd, BAD_PAGETABLE); diff --git a/include/asm-alpha/posix_types.h b/include/asm-alpha/posix_types.h new file mode 100644 index 000000000..92855e8bc --- /dev/null +++ b/include/asm-alpha/posix_types.h @@ -0,0 +1,111 @@ +#ifndef _ALPHA_POSIX_TYPES_H +#define _ALPHA_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 int __kernel_dev_t; +typedef unsigned int __kernel_ino_t; +typedef unsigned int __kernel_mode_t; +typedef unsigned int __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef int __kernel_ipc_pid_t; +typedef unsigned int __kernel_uid_t; +typedef unsigned int __kernel_gid_t; +typedef unsigned long __kernel_size_t; +typedef long __kernel_ssize_t; +typedef long __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned long __kernel_sigset_t; /* at least 32 bits */ + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { + int val[2]; +} __kernel_fsid_t; + +#ifndef __GNUC__ + +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) +#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) +#define __FD_ZERO(set) \ + ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set))) + +#else /* __GNUC__ */ + +/* With GNU C, use inline functions instead so args are evaluated only once: */ + +#undef __FD_SET +static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + fdsetp->fds_bits[_tmp] |= (1UL<<_rem); +} + +#undef __FD_CLR +static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem); +} + +#undef __FD_ISSET +static __inline__ int __FD_ISSET(unsigned long fd, const __kernel_fd_set *p) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0; +} + +/* + * This will unroll the loop for the normal constant case (8 ints, + * for a 256-bit fd_set) + */ +#undef __FD_ZERO +static __inline__ void __FD_ZERO(__kernel_fd_set *p) +{ + unsigned long *tmp = p->fds_bits; + int i; + + if (__builtin_constant_p(__FDSET_LONGS)) { + switch (__FDSET_LONGS) { + case 16: + tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; + tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0; + tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0; + tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0; + return; + + case 8: + tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; + tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0; + return; + + case 4: + tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; + return; + } + } + i = __FDSET_LONGS; + while (i) { + i--; + *tmp = 0; + tmp++; + } +} + +#endif /* __GNUC__ */ + +#endif /* _ALPHA_POSIX_TYPES_H */ diff --git a/include/asm-alpha/processor.h b/include/asm-alpha/processor.h index 2e953e3cd..4ffb38a37 100644 --- a/include/asm-alpha/processor.h +++ b/include/asm-alpha/processor.h @@ -8,7 +8,7 @@ #define __ASM_ALPHA_PROCESSOR_H /* - * We have a 41-bit user address space: 2TB user VM... + * We have a 42-bit user address space: 4TB user VM... */ #define TASK_SIZE (0x40000000000UL) @@ -20,39 +20,51 @@ #define MCA_bus 0 #define MCA_bus__is_a_macro /* for versions in ksyms.c */ -/* - * The alpha has no problems with write protection - */ -#define wp_works_ok 1 -#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ - struct thread_struct { + /* the fields below are used by PALcode and must match struct pcb: */ unsigned long ksp; unsigned long usp; unsigned long ptbr; unsigned int pcc; unsigned int asn; unsigned long unique; - unsigned long flags; + /* + * bit 0: floating point enable + * bit 62: performance monitor enable + */ + unsigned long pal_flags; unsigned long res1, res2; + + /* the fields below are Linux-specific: */ + /* bit 1..5: IEEE_TRAP_ENABLE bits (see fpu.h) */ + unsigned long flags; + /* perform syscall argument validation (get/set_fs) */ + unsigned long fs; }; -#define INIT_MMAP { &init_task, 0xfffffc0000000000, 0xfffffc0010000000, \ +#define INIT_MMAP { &init_mm, 0xfffffc0000000000, 0xfffffc0010000000, \ PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC } #define INIT_TSS { \ 0, 0, 0, \ 0, 0, 0, \ 0, 0, 0, \ + 0, \ + 0 \ } +#define alloc_kernel_stack() __get_free_page(GFP_KERNEL) +#define free_kernel_stack(page) free_page((page)) + #include <asm/ptrace.h> /* - * Return saved PC of a blocked thread. This assumes the frame pointer - * is the 6th saved long on the kernel stack and that the saved return - * address is the first long in the frame. This all holds provided the - * thread blocked through a call to schedule(). + * Return saved PC of a blocked thread. This assumes the frame + * pointer is the 6th saved long on the kernel stack and that the + * saved return address is the first long in the frame. This all + * holds provided the thread blocked through a call to schedule() ($15 + * is the frame pointer in schedule() and $15 is saved at offset 48 by + * entry.S:do_switch_stack). */ extern inline unsigned long thread_saved_pc(struct thread_struct *t) { @@ -65,11 +77,16 @@ extern inline unsigned long thread_saved_pc(struct thread_struct *t) /* * Do necessary setup to start up a newly executed thread. */ -static inline void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) -{ - regs->pc = pc; - regs->ps = 8; - wrusp(sp); -} +extern void start_thread(struct pt_regs *, unsigned long, unsigned long); + +/* + * Return_address is a replacement for __builtin_return_address(count) + * which on certain architectures cannot reasonably be implemented in GCC + * (MIPS, Alpha) or is unuseable with -fomit-frame-pointer (i386). + * Note that __builtin_return_address(x>=1) is forbidden because the GCC + * aborts compilation on some CPUs. It's simply not possible to unwind + * some CPU's stackframes. + */ +#define return_address() __builtin_return_address(0) #endif /* __ASM_ALPHA_PROCESSOR_H */ diff --git a/include/asm-alpha/ptrace.h b/include/asm-alpha/ptrace.h index 7bda114cd..8f7d643fc 100644 --- a/include/asm-alpha/ptrace.h +++ b/include/asm-alpha/ptrace.h @@ -59,11 +59,12 @@ struct switch_stack { unsigned long r14; unsigned long r15; unsigned long r26; - unsigned long fp[32]; + unsigned long fp[32]; /* fp[31] is fpcr */ }; #ifdef __KERNEL__ #define user_mode(regs) ((regs)->ps & 8) +#define instruction_pointer(regs) ((regs)->pc) extern void show_regs(struct pt_regs *); #endif diff --git a/include/asm-alpha/reg.h b/include/asm-alpha/reg.h new file mode 100644 index 000000000..86ff916fb --- /dev/null +++ b/include/asm-alpha/reg.h @@ -0,0 +1,52 @@ +#ifndef __reg_h__ +#define __reg_h__ + +/* + * Exception frame offsets. + */ +#define EF_V0 0 +#define EF_T0 1 +#define EF_T1 2 +#define EF_T2 3 +#define EF_T3 4 +#define EF_T4 5 +#define EF_T5 6 +#define EF_T6 7 +#define EF_T7 8 +#define EF_S0 9 +#define EF_S1 10 +#define EF_S2 11 +#define EF_S3 12 +#define EF_S4 13 +#define EF_S5 14 +#define EF_S6 15 +#define EF_A3 16 +#define EF_A4 17 +#define EF_A5 18 +#define EF_T8 19 +#define EF_T9 20 +#define EF_T10 21 +#define EF_T11 22 +#define EF_RA 23 +#define EF_T12 24 +#define EF_AT 25 +#define EF_SP 26 +#define EF_PS 27 +#define EF_PC 28 +#define EF_GP 29 +#define EF_A0 30 +#define EF_A1 31 +#define EF_A2 32 + +#define EF_SIZE (33*8) +#define HWEF_SIZE (6*8) /* size of PAL frame (PS-A2) */ + +#define EF_SSIZE (EF_SIZE - HWEF_SIZE) + +/* + * Map register number into core file offset. + */ +#define CORE_REG(reg, ubase) \ + (((unsigned long *)((unsigned long)(ubase)))[reg]) + +#endif /* __reg_h__ */ diff --git a/include/asm-alpha/resource.h b/include/asm-alpha/resource.h index daf5c4037..96b338fc4 100644 --- a/include/asm-alpha/resource.h +++ b/include/asm-alpha/resource.h @@ -14,11 +14,26 @@ #define RLIMIT_NOFILE 6 /* max number of open files */ #define RLIMIT_AS 7 /* address space limit(?) */ #define RLIMIT_NPROC 8 /* max number of processes */ +#define RLIMIT_MEMLOCK 9 /* max locked-in-memory address space */ -#ifdef notdef -#define RLIMIT_MEMLOCK 9 /* max locked-in-memory address space*/ -#endif +#define RLIM_NLIMITS 10 -#define RLIM_NLIMITS 9 +#ifdef __KERNEL__ -#endif +#define INIT_RLIMITS \ +{ \ + {LONG_MAX, LONG_MAX}, /* RLIMIT_CPU */ \ + {LONG_MAX, LONG_MAX}, /* RLIMIT_FSIZE */ \ + {LONG_MAX, LONG_MAX}, /* RLIMIT_DATA */ \ + {_STK_LIM, _STK_LIM}, /* RLIMIT_STACK */ \ + { 0, LONG_MAX}, /* RLIMIT_CORE */ \ + {LONG_MAX, LONG_MAX}, /* RLIMIT_RSS */ \ + { NR_OPEN, NR_OPEN}, /* RLIMIT_NOFILE */ \ + {LONG_MAX, LONG_MAX}, /* RLIMIT_AS */ \ + {MAX_TASKS_PER_USER, MAX_TASKS_PER_USER}, /* RLIMIT_NPROC */ \ + {LONG_MAX, LONG_MAX}, /* RLIMIT_MEMLOCK */ \ +} + +#endif /* __KERNEL__ */ + +#endif /* _ALPHA_RESOURCE_H */ diff --git a/include/asm-alpha/segment.h b/include/asm-alpha/segment.h index ed3770607..0453d97da 100644 --- a/include/asm-alpha/segment.h +++ b/include/asm-alpha/segment.h @@ -1,143 +1,6 @@ -#ifndef _ASM_SEGMENT_H -#define _ASM_SEGMENT_H +#ifndef __ALPHA_SEGMENT_H +#define __ALPHA_SEGMENT_H -#include <linux/string.h> +/* Only here because we have some old header files that expect it.. */ -/* - * Uh, these should become the main single-value transfer routines.. - * They automatically use the right size if we just have the right - * pointer type.. - */ -#define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))) -#define get_user(ptr) __get_user((ptr),sizeof(*(ptr))) - -/* - * This is a silly but good way to make sure that - * the __put_user function is indeed always optimized, - * and that we use the correct sizes.. - */ -extern int bad_user_access_length(void); - -/* I should make this use unaligned transfers etc.. */ -static inline void __put_user(unsigned long x, void * y, int size) -{ - switch (size) { - case 1: - *(char *) y = x; - break; - case 2: - *(short *) y = x; - break; - case 4: - *(int *) y = x; - break; - case 8: - *(long *) y = x; - break; - default: - bad_user_access_length(); - } -} - -/* I should make this use unaligned transfers etc.. */ -static inline unsigned long __get_user(void * y, int size) -{ - switch (size) { - case 1: - return *(unsigned char *) y; - case 2: - return *(unsigned short *) y; - case 4: - return *(unsigned int *) y; - case 8: - return *(unsigned long *) y; - default: - return bad_user_access_length(); - } -} - -static inline unsigned char get_user_byte(const char * addr) -{ - return *addr; -} - -#define get_fs_byte(addr) get_user_byte((char *)(addr)) - -static inline unsigned short get_user_word(const short *addr) -{ - return *addr; -} - -#define get_fs_word(addr) get_user_word((short *)(addr)) - -static inline unsigned long get_user_long(const int *addr) -{ - return *addr; -} - -#define get_fs_long(addr) get_user_long((int *)(addr)) - -static inline unsigned long get_user_quad(const long *addr) -{ - return *addr; -} - -#define get_fs_quad(addr) get_user_quad((long *)(addr)) - -static inline void put_user_byte(char val,char *addr) -{ - *addr = val; -} - -#define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr)) - -static inline void put_user_word(short val,short * addr) -{ - *addr = val; -} - -#define put_fs_word(x,addr) put_user_word((x),(short *)(addr)) - -static inline void put_user_long(unsigned long val,int * addr) -{ - *addr = val; -} - -#define put_fs_long(x,addr) put_user_long((x),(int *)(addr)) - -static inline void put_user_quad(unsigned long val,long * addr) -{ - *addr = val; -} - -#define put_fs_quad(x,addr) put_user_quad((x),(long *)(addr)) - -#define memcpy_fromfs(to, from, n) memcpy((to),(from),(n)) - -#define memcpy_tofs(to, from, n) memcpy((to),(from),(n)) - -/* - * For segmented architectures, these are used to specify which segment - * to use for the above functions. - * - * The alpha is not segmented, so these are just dummies. - */ - -#define KERNEL_DS 0 -#define USER_DS 1 - -static inline unsigned long get_fs(void) -{ - return 1; -} - -static inline unsigned long get_ds(void) -{ - return 0; -} - -static inline void set_fs(unsigned long val) -{ -} - -#endif /* _ASM_SEGMENT_H */ +#endif diff --git a/include/asm-alpha/semaphore.h b/include/asm-alpha/semaphore.h new file mode 100644 index 000000000..210c2a5b3 --- /dev/null +++ b/include/asm-alpha/semaphore.h @@ -0,0 +1,43 @@ +#ifndef _ALPHA_SEMAPHORE_H +#define _ALPHA_SEMAPHORE_H + +/* + * SMP- and interrupt-safe semaphores.. + * + * (C) Copyright 1996 Linus Torvalds + */ + +#include <asm/atomic.h> + +struct semaphore { + atomic_t count; + atomic_t waiting; + struct wait_queue * wait; +}; + +#define MUTEX ((struct semaphore) { 1, 0, NULL }) +#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL }) + +extern void __down(struct semaphore * sem); +extern void __up(struct semaphore * sem); + +/* + * This isn't quite as clever as the x86 side, but the gp register + * makes things a bit more complicated on the alpha.. + */ +extern inline void down(struct semaphore * sem) +{ + for (;;) { + if (atomic_dec_return(&sem->count) >= 0) + break; + __down(sem); + } +} + +extern inline void up(struct semaphore * sem) +{ + if (atomic_inc_return(&sem->count) <= 0) + __up(sem); +} + +#endif diff --git a/include/asm-alpha/shmparam.h b/include/asm-alpha/shmparam.h new file mode 100644 index 000000000..a9ce7164b --- /dev/null +++ b/include/asm-alpha/shmparam.h @@ -0,0 +1,47 @@ +#ifndef _ASMAXP_SHMPARAM_H +#define _ASMAXP_SHMPARAM_H + +/* + * Address range for shared memory attaches if no address passed to shmat(). + */ +#define SHM_RANGE_START 0x14000000000 +#define SHM_RANGE_END 0x15000000000 + + +/* + * 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 Alpha and + * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). + */ + +#define SHMMAX 0x3fa000 /* max shared seg size (bytes) */ +#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 /* _ASMAXP_SHMPARAM_H */ diff --git a/include/asm-alpha/sigcontext.h b/include/asm-alpha/sigcontext.h new file mode 100644 index 000000000..916955f4b --- /dev/null +++ b/include/asm-alpha/sigcontext.h @@ -0,0 +1,34 @@ +#ifndef _ASMAXP_SIGCONTEXT_H +#define _ASMAXP_SIGCONTEXT_H + +struct sigcontext { + /* + * what should we have here? I'd probably better use the same + * stack layout as OSF/1, just in case we ever want to try + * running their binaries.. + * + * This is the basic layout, but I don't know if we'll ever + * actually fill in all the values.. + */ + long sc_onstack; + long sc_mask; + long sc_pc; + long sc_ps; + long sc_regs[32]; + long sc_ownedfp; + long sc_fpregs[32]; + unsigned long sc_fpcr; + unsigned long sc_fp_control; + unsigned long sc_reserved1, sc_reserved2; + unsigned long sc_ssize; + char * sc_sbase; + unsigned long sc_traparg_a0; + unsigned long sc_traparg_a1; + unsigned long sc_traparg_a2; + unsigned long sc_fp_trap_pc; + unsigned long sc_fp_trigger_sum; + unsigned long sc_fp_trigger_inst; + unsigned long sc_retcode[2]; +}; + +#endif diff --git a/include/asm-alpha/signal.h b/include/asm-alpha/signal.h index 83f3d80ee..ecccdd3e8 100644 --- a/include/asm-alpha/signal.h +++ b/include/asm-alpha/signal.h @@ -43,6 +43,8 @@ typedef unsigned long sigset_t; /* at least 32 bits */ #define SIGUSR2 31 #define SIGPOLL SIGIO +#define SIGPWR SIGINFO +#define SIGIOT SIGABRT /* * sa_flags values: SA_STACK is not currently supported, but will allow the @@ -51,6 +53,7 @@ typedef unsigned long sigset_t; /* at least 32 bits */ * the changes in signal handling. LBT 010493. * 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_SHIRQ flag is for shared interrupt support on PCI and EISA. */ #define SA_NOCLDSTOP 0x00000004 @@ -59,6 +62,19 @@ typedef unsigned long sigset_t; /* at least 32 bits */ #define SA_INTERRUPT 0x20000000 #define SA_NOMASK 0x00000008 #define SA_ONESHOT 0x00000010 +#define SA_SHIRQ 0x00000020 + +#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. + */ +#define SA_PROBE SA_ONESHOT +#define SA_SAMPLE_RANDOM SA_RESTART +#endif + #define SIG_BLOCK 1 /* for blocking signals */ #define SIG_UNBLOCK 2 /* for unblocking signals */ @@ -78,37 +94,7 @@ struct sigaction { }; #ifdef __KERNEL__ - -struct sigcontext_struct { - /* - * what should we have here? I'd probably better use the same - * stack layout as OSF/1, just in case we ever want to try - * running their binaries.. - * - * This is the basic layout, but I don't know if we'll ever - * actually fill in all the values.. - */ - long sc_onstack; - long sc_mask; - long sc_pc; - long sc_ps; - long sc_regs[32]; - long sc_ownedfp; - long sc_fpregs[32]; - unsigned long sc_fpcr; - unsigned long sc_fp_control; - unsigned long sc_reserved1, sc_reserved2; - unsigned long sc_ssize; - char * sc_sbase; - unsigned long sc_traparg_a0; - unsigned long sc_traparg_a1; - unsigned long sc_traparg_a2; - unsigned long sc_fp_trap_pc; - unsigned long sc_fp_trigger_sum; - unsigned long sc_fp_trigger_inst; - unsigned long sc_retcode[2]; -}; - +#include <asm/sigcontext.h> #endif #endif diff --git a/include/asm-alpha/socket.h b/include/asm-alpha/socket.h new file mode 100644 index 000000000..031636871 --- /dev/null +++ b/include/asm-alpha/socket.h @@ -0,0 +1,52 @@ +#ifndef _ASM_SOCKET_H +#define _ASM_SOCKET_H + +#include <linux/types.h> +#include <asm/ioctl.h> +#include <asm/sockios.h> + +/* For setsockoptions(2) */ +/* + * Note: we only bother about making the SOL_SOCKET options + * same as OSF/1, as that's all that "normal" programs are + * likely to set. We don't necessarily want to be binary + * compatible with _everything_. + */ +#define SOL_SOCKET 0xffff + +#define SO_DEBUG 0x0001 +#define SO_REUSEADDR 0x0004 +#define SO_KEEPALIVE 0x0008 +#define SO_DONTROUTE 0x0010 +#define SO_BROADCAST 0x0020 +#define SO_LINGER 0x0080 +#define SO_OOBINLINE 0x0100 +/* To add :#define SO_REUSEPORT 0x0200 */ + +#define SO_TYPE 0x1008 +#define SO_ERROR 0x1007 +#define SO_SNDBUF 0x1001 +#define SO_RCVBUF 0x1002 +#define SO_RCVLOWAT 0x1010 +#define SO_SNDLOWAT 0x1011 +#define SO_RCVTIMEO 0x1012 +#define SO_SNDTIMEO 0x1013 + +/* linux-specific, might as well be the same as on i386 */ +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_BSDCOMPAT 14 + +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ + +#endif /* _ASM_SOCKET_H */ diff --git a/include/asm-alpha/sockios.h b/include/asm-alpha/sockios.h new file mode 100644 index 000000000..e4961a740 --- /dev/null +++ b/include/asm-alpha/sockios.h @@ -0,0 +1,15 @@ +#ifndef _ASM_ALPHA_SOCKIOS_H +#define _ASM_ALPHA_SOCKIOS_H + +/* Socket-level I/O control calls. */ + +#define FIOGETOWN _IOR('f', 123, int) +#define FIOSETOWN _IOW('f', 124, int) + +#define SIOCATMARK _IOR('s', 7, int) +#define SIOCSPGRP _IOW('s', 8, pid_t) +#define SIOCGPGRP _IOR('s', 9, pid_t) + +#define SIOCGSTAMP 0x8906 /* Get stamp - linux-specific */ + +#endif /* _ASM_ALPHA_SOCKIOS_H */ diff --git a/include/asm-alpha/stat.h b/include/asm-alpha/stat.h index 275383002..66ea898d1 100644 --- a/include/asm-alpha/stat.h +++ b/include/asm-alpha/stat.h @@ -1,7 +1,7 @@ #ifndef _ALPHA_STAT_H #define _ALPHA_STAT_H -struct old_stat { +struct __old_kernel_stat { unsigned int st_dev; unsigned int st_ino; unsigned int st_mode; @@ -10,16 +10,16 @@ struct old_stat { unsigned int st_gid; unsigned int st_rdev; long st_size; - unsigned int st_atime, st_res1; - unsigned int st_mtime, st_res2; - unsigned int st_ctime, st_res3; - unsigned int st_blkize; + unsigned long st_atime; + unsigned long st_mtime; + unsigned long st_ctime; + unsigned int st_blksize; int st_blocks; unsigned int st_flags; unsigned int st_gen; }; -struct new_stat { +struct stat { unsigned int st_dev; unsigned int st_ino; unsigned int st_mode; @@ -28,9 +28,9 @@ struct new_stat { unsigned int st_gid; unsigned int st_rdev; long st_size; - unsigned int st_atime, st_res1; - unsigned int st_mtime, st_res2; - unsigned int st_ctime, st_res3; + unsigned long st_atime; + unsigned long st_mtime; + unsigned long st_ctime; unsigned int st_blksize; int st_blocks; unsigned int st_flags; diff --git a/include/asm-alpha/statfs.h b/include/asm-alpha/statfs.h index b2cd89057..cc4ba1de0 100644 --- a/include/asm-alpha/statfs.h +++ b/include/asm-alpha/statfs.h @@ -1,27 +1,25 @@ #ifndef _ALPHA_STATFS_H #define _ALPHA_STATFS_H -typedef struct { - int val[2]; -} fsid_t; +#ifndef __KERNEL_STRICT_NAMES + +#include <linux/types.h> + +typedef __kernel_fsid_t fsid_t; + +#endif -/* - * The OSF/1 statfs structure is much larger, but this should - * match the beginning, at least. - */ struct statfs { - short f_type; - short f_flags; - int f_fsize; - int f_bsize; - int f_blocks; - int f_bfree; - int f_bavail; - int f_files; - int f_ffree; - fsid_t f_fsid; - /* linux-specific entries start here.. */ - int f_namelen; + int f_type; + int f_bsize; + int f_blocks; + int f_bfree; + int f_bavail; + int f_files; + int f_ffree; + __kernel_fsid_t f_fsid; + int f_namelen; + int f_spare[6]; }; #endif diff --git a/include/asm-alpha/string.h b/include/asm-alpha/string.h index 1c6fe64ec..6ef1f4120 100644 --- a/include/asm-alpha/string.h +++ b/include/asm-alpha/string.h @@ -1,15 +1,40 @@ -#ifndef __ALPHA_STRING_H -#define __ALPHA_STRING_H +#ifndef __ALPHA_STRING_H__ +#define __ALPHA_STRING_H__ + +#ifdef __KERNEL__ extern void * __constant_c_memset(void *, unsigned long, long); extern void * __memset(void *, char, size_t); + +/* + * Ugh. Gcc uses "bcopy()" internally for structure assignments. + */ +#define __HAVE_ARCH_BCOPY + +/* + * Define "memcpy()" to something else, otherwise gcc will + * corrupt that too into a "bcopy". Also, some day we might + * want to do a separate inlined constant-size memcpy (for 8 + * and 16 byte user<->kernel structure copying). + */ +#define __HAVE_ARCH_MEMCPY extern void * __memcpy(void *, const void *, size_t); +#define memcpy __memcpy +#define __HAVE_ARCH_MEMSET #define memset(s, c, count) \ (__builtin_constant_p(c) ? \ - __constant_c_memset((s),(0x01010101UL*(unsigned char)c),(count)) : \ + __constant_c_memset((s),(0x0101010101010101UL*(unsigned char)c),(count)) : \ __memset((s),(c),(count))) -#define memcpy(d,s,count) __memcpy((d),(s),(count)) +#define __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRNCPY +#define __HAVE_ARCH_STRCAT +#define __HAVE_ARCH_STRNCAT +#define __HAVE_ARCH_STRCHR +#define __HAVE_ARCH_STRRCHR +#define __HAVE_ARCH_STRLEN + +#endif /* __KERNEL__ */ -#endif +#endif /* __ALPHA_STRING_H__ */ diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h index cbed1ded7..9854413fd 100644 --- a/include/asm-alpha/system.h +++ b/include/asm-alpha/system.h @@ -1,6 +1,8 @@ #ifndef __ALPHA_SYSTEM_H #define __ALPHA_SYSTEM_H +#include <asm/pal.h> /* for backwards compatibility... */ + /* * System defines.. Note that this is included both from .c and .S * files, so it does only defines, not any C code. @@ -15,6 +17,7 @@ */ #define BOOT_PCB 0x20000000 #define BOOT_ADDR 0x20000000 +/* Remove when official MILO sources have ELF support: */ #define BOOT_SIZE (16*1024) #define KERNEL_START 0xfffffc0000300000 @@ -25,69 +28,41 @@ #define ZERO_PGE 0xfffffc000030A000 #define START_ADDR 0xfffffc0000310000 +/* Remove when official MILO sources have ELF support: */ #define START_SIZE (2*1024*1024) -/* - * Common PAL-code - */ -#define PAL_halt 0 -#define PAL_cflush 1 -#define PAL_draina 2 -#define PAL_cobratt 9 -#define PAL_bpt 128 -#define PAL_bugchk 129 -#define PAL_chmk 131 -#define PAL_callsys 131 -#define PAL_imb 134 -#define PAL_rduniq 158 -#define PAL_wruniq 159 -#define PAL_gentrap 170 -#define PAL_nphalt 190 - -/* - * VMS specific PAL-code - */ -#define PAL_swppal 10 -#define PAL_mfpr_vptb 41 +#ifndef __ASSEMBLY__ /* - * OSF specific PAL-code + * This is the logout header that should be common to all platforms + * (assuming they are running OSF/1 PALcode, I guess). */ -#define PAL_rdmces 16 -#define PAL_wrmces 17 -#define PAL_wrfen 43 -#define PAL_wrvptptr 45 -#define PAL_jtopal 46 -#define PAL_swpctx 48 -#define PAL_wrval 49 -#define PAL_rdval 50 -#define PAL_tbi 51 -#define PAL_wrent 52 -#define PAL_swpipl 53 -#define PAL_rdps 54 -#define PAL_wrkgp 55 -#define PAL_wrusp 56 -#define PAL_wrperfmon 57 -#define PAL_rdusp 58 -#define PAL_whami 60 -#define PAL_rtsys 61 -#define PAL_rti 63 - -#ifndef __ASSEMBLY__ +struct el_common { + unsigned int size; /* size in bytes of logout area */ + int sbz1 : 31; /* should be zero */ + char retry : 1; /* retry flag */ + unsigned int proc_offset; /* processor-specific offset */ + unsigned int sys_offset; /* system-specific offset */ + unsigned long code; /* machine check code */ +}; extern void wrent(void *, unsigned long); extern void wrkgp(unsigned long); extern void wrusp(unsigned long); extern unsigned long rdusp(void); +extern unsigned long rdmces (void); +extern void wrmces (unsigned long); -#define halt() __asm__ __volatile__(".long 0"); +#define halt() __asm__ __volatile__ ("call_pal %0" : : "i" (PAL_halt) : "memory") + +#define switch_to(prev,next) do { \ + current_set[0] = next; \ + alpha_switch_to((unsigned long) &(next)->tss - 0xfffffc0000000000); \ +} while (0) extern void alpha_switch_to(unsigned long pctxp); -#define switch_to(p) do { \ - current = p; \ - alpha_switch_to((unsigned long) &(p)->tss - 0xfffffc0000000000); \ -} while (0) +extern void imb(void); #define mb() \ __asm__ __volatile__("mb": : :"memory") @@ -109,7 +84,7 @@ __asm__ __volatile__( \ "bis %0,%0,$16\n\t" \ "call_pal 53" \ : : "r" (__new_ipl) \ - : "$0", "$1", "$16", "$22", "$23", "$24", "$25") + : "$0", "$1", "$16", "$22", "$23", "$24", "$25", "memory") #define swpipl(__new_ipl) \ ({ unsigned long __old_ipl; \ @@ -119,7 +94,7 @@ __asm__ __volatile__( \ "bis $0,$0,%0" \ : "=r" (__old_ipl) \ : "r" (__new_ipl) \ - : "$0", "$1", "$16", "$22", "$23", "$24", "$25"); \ + : "$0", "$1", "$16", "$22", "$23", "$24", "$25", "memory"); \ __old_ipl; }) #define cli() setipl(7) @@ -127,41 +102,81 @@ __old_ipl; }) #define save_flags(flags) do { flags = getipl(); } while (0) #define restore_flags(flags) setipl(flags) -extern inline unsigned long xchg_u32(int * m, unsigned long val) -{ - unsigned long dummy, dummy2; +/* + * TB routines.. + */ +extern void tbi(long type, ...); + +#define tbisi(x) tbi(1,(x)) +#define tbisd(x) tbi(2,(x)) +#define tbis(x) tbi(3,(x)) +#define tbiap() tbi(-1) +#define tbia() tbi(-2) +/* + * Give prototypes to shut up gcc. + */ +extern __inline__ unsigned long xchg_u32 (volatile int * m, unsigned long val); +extern __inline__ unsigned long xchg_u64 (volatile long * m, unsigned long val); + +extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val) +{ + unsigned long dummy; __asm__ __volatile__( "\n1:\t" - "ldl_l %0,%1\n\t" - "bis %2,%2,%3\n\t" - "stl_c %3,%1\n\t" - "beq %3,1b\n" - : "=r" (val), "=m" (*m), "=r" (dummy), "=r" (dummy2) - : "1" (*m), "2" (val)); + "ldl_l %0,%2\n\t" + "bis %3,%3,%1\n\t" + "stl_c %1,%2\n\t" + "beq %1,1b\n" + : "=&r" (val), "=&r" (dummy), "=m" (*m) + : "r" (val), "m" (*m)); return val; } -extern inline unsigned long xchg_u64(long * m, unsigned long val) +extern __inline__ unsigned long xchg_u64(volatile long * m, unsigned long val) { - unsigned long dummy, dummy2; - + unsigned long dummy; __asm__ __volatile__( "\n1:\t" - "ldq_l %0,%1\n\t" - "bis %2,%2,%3\n\t" - "stq_c %3,%1\n\t" - "beq %3,1b\n" - : "=r" (val), "=m" (*m), "=r" (dummy), "=r" (dummy2) - : "1" (*m), "2" (val)); + "ldq_l %0,%2\n\t" + "bis %3,%3,%1\n\t" + "stq_c %1,%2\n\t" + "beq %1,1b\n" + : "=&r" (val), "=&r" (dummy), "=m" (*m) + : "r" (val), "m" (*m)); return val; } -extern inline void * xchg_ptr(void *m, void *val) +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define tas(ptr) (xchg((ptr),1)) + +/* + * This function doesn't exist, so you'll get a linker error + * if something tries to do an invalid xchg(). + * + * This only works if the compiler isn't horribly bad at optimizing. + * gcc-2.5.8 reportedly can't handle this, but as that doesn't work + * too well on the alpha anyway.. + */ +extern void __xchg_called_with_bad_pointer(void); + +static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, int size) { - return (void *) xchg_u64((long *) m, (unsigned long) val); + switch (size) { + case 4: + return xchg_u32(ptr, x); + case 8: + return xchg_u64(ptr, x); + } + __xchg_called_with_bad_pointer(); + return x; } +/* + * Reset the machine. + */ +extern void hard_reset_now(void); + #endif /* __ASSEMBLY__ */ #endif diff --git a/include/asm-alpha/termbits.h b/include/asm-alpha/termbits.h new file mode 100644 index 000000000..0d0a33251 --- /dev/null +++ b/include/asm-alpha/termbits.h @@ -0,0 +1,177 @@ +#ifndef _ALPHA_TERMBITS_H +#define _ALPHA_TERMBITS_H + +#include <linux/posix_types.h> + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +/* + * termios type and macro definitions. Be careful about adding stuff + * to this file since it's used in GNU libc and there are strict rules + * concerning namespace pollution. + */ + +#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_cc[NCCS]; /* control characters */ + cc_t c_line; /* line discipline (== c_cc[19]) */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +/* c_cc characters */ +#define VEOF 0 +#define VEOL 1 +#define VEOL2 2 +#define VERASE 3 +#define VWERASE 4 +#define VKILL 5 +#define VREPRINT 6 +#define VSWTC 7 +#define VINTR 8 +#define VQUIT 9 +#define VSUSP 10 +#define VSTART 12 +#define VSTOP 13 +#define VLNEXT 14 +#define VDISCARD 15 +#define VMIN 16 +#define VTIME 17 + +/* 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 IXON 0001000 +#define IXOFF 0002000 +#if !defined(KERNEL) || defined(__USE_BSD) + /* POSIX.1 doesn't want these... */ +# define IXANY 0004000 +# define IUCLC 0010000 +# define IMAXBEL 0020000 +#endif + +/* c_oflag bits */ +#define OPOST 0000001 +#define ONLCR 0000002 +#define OLCUC 0000004 + +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 + +#define OFILL 00000100 +#define OFDEL 00000200 +#define NLDLY 00001400 +#define NL0 00000000 +#define NL1 00000400 +#define NL2 00001000 +#define NL3 00001400 +#define TABDLY 00006000 +#define TAB0 00000000 +#define TAB1 00002000 +#define TAB2 00004000 +#define TAB3 00006000 +#define CRDLY 00030000 +#define CR0 00000000 +#define CR1 00010000 +#define CR2 00020000 +#define CR3 00030000 +#define FFDLY 00040000 +#define FF0 00000000 +#define FF1 00040000 +#define BSDLY 00100000 +#define BS0 00000000 +#define BS1 00100000 +#define VTDLY 00200000 +#define VT0 00000000 +#define VT1 00200000 +#define XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */ + +/* c_cflag bit meaning */ +#define CBAUD 0000037 +#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 CBAUDEX 0000000 +#define B57600 00020 +#define B115200 00021 +#define B230400 00022 +#define B460800 00023 + +#define CSIZE 00001400 +#define CS5 00000000 +#define CS6 00000400 +#define CS7 00001000 +#define CS8 00001400 + +#define CSTOPB 00002000 +#define CREAD 00004000 +#define PARENB 00010000 +#define PARODD 00020000 +#define HUPCL 00040000 + +#define CLOCAL 00100000 +#define CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0x00000080 +#define ICANON 0x00000100 +#define XCASE 0x00004000 +#define ECHO 0x00000008 +#define ECHOE 0x00000002 +#define ECHOK 0x00000004 +#define ECHONL 0x00000010 +#define NOFLSH 0x80000000 +#define TOSTOP 0x00400000 +#define ECHOCTL 0x00000040 +#define ECHOPRT 0x00000020 +#define ECHOKE 0x00000001 +#define FLUSHO 0x00800000 +#define PENDIN 0x20000000 +#define IEXTEN 0x00000400 + +/* Values for the ACTION argument to `tcflow'. */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* Values for the QUEUE_SELECTOR argument to `tcflush'. */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'. */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif /* _ALPHA_TERMBITS_H */ diff --git a/include/asm-alpha/termios.h b/include/asm-alpha/termios.h index 4eb45be99..efa0fcb2d 100644 --- a/include/asm-alpha/termios.h +++ b/include/asm-alpha/termios.h @@ -1,9 +1,8 @@ #ifndef _ALPHA_TERMIOS_H #define _ALPHA_TERMIOS_H -#include <linux/types.h> - -#include <asm/ioctl.h> +#include <asm/ioctls.h> +#include <asm/termbits.h> struct sgttyb { char sg_ispeed; @@ -31,84 +30,6 @@ struct ltchars { char t_lnextc; }; -#define FIOCLEX _IO('f', 1) -#define FIONCLEX _IO('f', 2) -#define FIOASYNC _IOW('f', 125, int) -#define FIONBIO _IOW('f', 126, int) -#define FIONREAD _IOR('f', 127, int) -#define TIOCINQ FIONREAD - -#define TIOCGETP _IOR('t', 8, struct sgttyb) -#define TIOCSETP _IOW('t', 9, struct sgttyb) -#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ - -#define TIOCSETC _IOW('t', 17, struct tchars) -#define TIOCGETC _IOR('t', 18, struct tchars) -#define TCGETS _IOR('t', 19, struct termios) -#define TCSETS _IOW('t', 20, struct termios) -#define TCSETSW _IOW('t', 21, struct termios) -#define TCSETSF _IOW('t', 22, struct termios) - -#define TCGETA _IOR('t', 23, struct termio) -#define TCSETA _IOW('t', 24, struct termio) -#define TCSETAW _IOW('t', 25, struct termio) -#define TCSETAF _IOW('t', 28, struct termio) - -#define TCSBRK _IO('t', 29) -#define TCXONC _IO('t', 30) -#define TCFLSH _IO('t', 31) - -#define TIOCSWINSZ _IOW('t', 103, struct winsize) -#define TIOCGWINSZ _IOR('t', 104, struct winsize) - -#define TIOCGLTC _IOR('t', 116, struct ltchars) -#define TIOCSLTC _IOW('t', 117, struct ltchars) -#define TIOCSPGRP _IOW('t', 118, int) -#define TIOCGPGRP _IOR('t', 119, int) - -#define TIOCEXCL 0x540C -#define TIOCNXCL 0x540D -#define TIOCSCTTY 0x540E - -#define TIOCOUTQ 0x5411 -#define TIOCSTI 0x5412 -#define TIOCMGET 0x5415 -#define TIOCMBIS 0x5416 -#define TIOCMBIC 0x5417 -#define TIOCMSET 0x5418 -#define TIOCGSOFTCAR 0x5419 -#define TIOCSSOFTCAR 0x541A -#define TIOCLINUX 0x541C -#define TIOCCONS 0x541D -#define TIOCGSERIAL 0x541E -#define TIOCSSERIAL 0x541F -#define TIOCPKT 0x5420 - -#define TIOCNOTTY 0x5422 -#define TIOCSETD 0x5423 -#define TIOCGETD 0x5424 -#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ -#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ - -#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 */ - -/* 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 - struct winsize { unsigned short ws_row; unsigned short ws_col; @@ -126,40 +47,13 @@ struct termio { unsigned char c_cc[NCC]; /* control characters */ }; -#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_cc[NCCS]; /* control characters */ - cc_t c_line; /* line discipline (== c_cc[19]) */ - int c_ispeed; /* input speed */ - int c_ospeed; /* output speed */ -}; - -/* c_cc characters */ -#define VEOF 0 -#define VEOL 1 -#define VEOL2 2 -#define VERASE 3 -#define VWERASE 4 -#define VKILL 5 -#define VREPRINT 6 -#define VSWTC 7 -#define VINTR 8 -#define VQUIT 9 -#define VSUSP 10 -#define VSTART 12 -#define VSTOP 13 -#define VLNEXT 14 -#define VDISCARD 15 -#define VTIME 17 -#define VMIN 16 - /* - * ..and the same for c_cc in the termio structure.. - * Oh, how I love being backwardly compatible. + * c_cc characters in the termio structure. Oh, how I love being + * backwardly compatible. Notice that character 4 and 5 are + * interpreted differently depending on whether ICANON is set in + * c_lflag. If it's set, they are used as _VEOF and _VEOL, otherwise + * as _VMIN and V_TIME. This is for compatibility with OSF/1 (which + * is compatible with sysV)... */ #define _VINTR 0 #define _VQUIT 1 @@ -172,163 +66,73 @@ struct termios { #define _VEOL2 6 #define _VSWTC 7 -#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 "\004\000\000\177\027\025\022\000\003\034\032\000\021\023\026\025\000\001" -#endif - -/* 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 IXON 0001000 -#define IXOFF 0002000 -#define IXANY 0004000 -#define IUCLC 0010000 -#define IMAXBEL 0020000 - -/* c_oflag bits */ -#define OPOST 0000001 -#define ONLCR 0000002 -#define OLCUC 0000004 - -#define OCRNL 0000010 -#define ONOCR 0000020 -#define ONLRET 0000040 - -#define OFILL 00000100 -#define OFDEL 00000200 -#define NLDLY 00001400 -#define NL0 00000000 -#define NL1 00000400 -#define NL2 00001000 -#define NL3 00001400 -#define TABDLY 00006000 -#define TAB0 00000000 -#define TAB1 00002000 -#define TAB2 00004000 -#define TAB3 00006000 -#define CRDLY 00030000 -#define CR0 00000000 -#define CR1 00010000 -#define CR2 00020000 -#define CR3 00030000 -#define FFDLY 00040000 -#define FF0 00000000 -#define FF1 00040000 -#define BSDLY 00100000 -#define BS0 00000000 -#define BS1 00100000 -#define VTDLY 00200000 -#define VT0 00000000 -#define VT1 00200000 -#define XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */ - -/* c_cflag bit meaning */ -#define CBAUD 0000377 -#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 CBAUDEX 0000020 -#define B57600 00020 -#define B115200 00021 -#define B230400 00022 - -#define CSIZE 00001400 -#define CS5 00000000 -#define CS6 00000400 -#define CS7 00001000 -#define CS8 00001400 - -#define CSTOPB 00002000 -#define CREAD 00004000 -#define PARENB 00010000 -#define PARODD 00020000 -#define HUPCL 00040000 - -#define CLOCAL 00100000 -#define CRTSCTS 020000000000 /* flow control */ - -/* c_lflag bits */ -#define ISIG 0x00000080 -#define ICANON 0x00000100 -#define XCASE 0x00004000 -#define ECHO 0x00000008 -#define ECHOE 0x00000002 -#define ECHOK 0x00000004 -#define ECHONL 0x00000010 -#define NOFLSH 0x80000000 -#define TOSTOP 0x00400000 -#define ECHOCTL 0x00000040 -#define ECHOPRT 0x00000020 -#define ECHOKE 0x00000001 -#define FLUSHO 0x00800000 -#define PENDIN 0x20000000 -#define IEXTEN 0x00000400 - -/* 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 */ -#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ - - -/* 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 - /* line disciplines */ #define N_TTY 0 #define N_SLIP 1 #define N_MOUSE 2 #define N_PPP 3 +#define N_AX25 5 + +#ifdef __KERNEL__ +/* eof=^D eol=\0 eol2=\0 erase=del + werase=^W kill=^U reprint=^R sxtc=\0 + intr=^C quit=^\ susp=^Z <OSF/1 VDSUSP> + start=^Q stop=^S lnext=^V discard=^U + vmin=\1 vtime=\0 +*/ +#define INIT_C_CC "\004\000\000\177\027\025\022\000\003\034\032\000\021\023\026\025\001\000" -#endif +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +extern inline void trans_from_termio(struct termio * termio, + struct termios * termios) +{ +#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y)) + SET_LOW_BITS(termios->c_iflag, termio->c_iflag); + SET_LOW_BITS(termios->c_oflag, termio->c_oflag); + SET_LOW_BITS(termios->c_cflag, termio->c_cflag); + SET_LOW_BITS(termios->c_lflag, termio->c_lflag); +#undef SET_LOW_BITS + termios->c_cc[VINTR] = termio->c_cc[_VINTR]; + termios->c_cc[VQUIT] = termio->c_cc[_VQUIT]; + termios->c_cc[VERASE]= termio->c_cc[_VERASE]; + termios->c_cc[VKILL] = termio->c_cc[_VKILL]; + termios->c_cc[VEOF] = termio->c_cc[_VEOF]; + termios->c_cc[VMIN] = termio->c_cc[_VMIN]; + termios->c_cc[VEOL] = termio->c_cc[_VEOL]; + termios->c_cc[VTIME] = termio->c_cc[_VTIME]; + termios->c_cc[VEOL2] = termio->c_cc[_VEOL2]; + termios->c_cc[VSWTC] = termio->c_cc[_VSWTC]; +} + +/* + * Translate a "termios" structure into a "termio". Ugh. + * + * Note the "fun" _VMIN overloading. + */ +extern inline void trans_to_termio(struct termios * termios, + struct termio * termio) +{ + termio->c_iflag = termios->c_iflag; + termio->c_oflag = termios->c_oflag; + termio->c_cflag = termios->c_cflag; + termio->c_lflag = termios->c_lflag; + termio->c_line = termios->c_line; + termio->c_cc[_VINTR] = termios->c_cc[VINTR]; + termio->c_cc[_VQUIT] = termios->c_cc[VQUIT]; + termio->c_cc[_VERASE]= termios->c_cc[VERASE]; + termio->c_cc[_VKILL] = termios->c_cc[VKILL]; + termio->c_cc[_VEOF] = termios->c_cc[VEOF]; + termio->c_cc[_VEOL] = termios->c_cc[VEOL]; + termio->c_cc[_VEOL2] = termios->c_cc[VEOL2]; + termio->c_cc[_VSWTC] = termios->c_cc[VSWTC]; + if (!(termios->c_lflag & ICANON)) { + termio->c_cc[_VMIN] = termios->c_cc[VMIN]; + termio->c_cc[_VTIME] = termios->c_cc[VTIME]; + } +} + +#endif /* __KERNEL__ */ + +#endif /* _ALPHA_TERMIOS_H */ diff --git a/include/asm-alpha/types.h b/include/asm-alpha/types.h index 2654e4b42..28e5d487d 100644 --- a/include/asm-alpha/types.h +++ b/include/asm-alpha/types.h @@ -1,41 +1,15 @@ #ifndef _ALPHA_TYPES_H #define _ALPHA_TYPES_H -#ifndef _SIZE_T -#define _SIZE_T -typedef unsigned long size_t; -#endif - -#ifndef _SSIZE_T -#define _SSIZE_T -typedef long ssize_t; -#endif - -#ifndef _PTRDIFF_T -#define _PTRDIFF_T -typedef long ptrdiff_t; -#endif - -#ifndef _TIME_T -#define _TIME_T -typedef long time_t; -#endif - -#ifndef _CLOCK_T -#define _CLOCK_T -typedef long clock_t; -#endif +/* + * This file is never included by application software unless + * explicitly requested (e.g., via linux/types.h) in which case the + * application is Linux specific so (user-) name space pollution is + * not a major issue. However, for interoperability, libraries still + * need to be careful to avoid a name clashes. + */ -typedef int pid_t; -typedef unsigned int uid_t; -typedef unsigned int gid_t; -typedef unsigned int dev_t; -typedef unsigned int ino_t; -typedef unsigned int mode_t; typedef unsigned int umode_t; -typedef unsigned short nlink_t; -typedef int daddr_t; -typedef long off_t; /* * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the @@ -98,5 +72,4 @@ typedef unsigned long u64; #endif #endif /* __KERNEL__ */ - -#endif +#endif /* _ALPHA_TYPES_H */ diff --git a/include/asm-alpha/uaccess.h b/include/asm-alpha/uaccess.h new file mode 100644 index 000000000..526767e41 --- /dev/null +++ b/include/asm-alpha/uaccess.h @@ -0,0 +1,447 @@ +#ifndef __ALPHA_UACCESS_H +#define __ALPHA_UACCESS_H + +#include <linux/errno.h> +#include <linux/sched.h> + + +/* + * The fs value determines whether argument validity checking should be + * performed or not. If get_fs() == USER_DS, checking is performed, with + * get_fs() == KERNEL_DS, checking is bypassed. + * + * For historical reasons, these macros are grossly misnamed. + */ + +#define KERNEL_DS (0UL) +#define USER_DS (-0x40000000000UL) + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +#define get_fs() (current->tss.fs) +#define set_fs(x) (current->tss.fs = (x)) +#define get_ds() (KERNEL_DS) + +/* + * Is a address valid? This does a straighforward calculation rather + * than tests. + * + * Address valid if: + * - "addr" doesn't have any high-bits set + * - AND "size" doesn't have any high-bits set + * - AND "addr+size" doesn't have any high-bits set + * - OR we are in kernel mode. + */ +#define __access_ok(addr,size,mask) \ + (((mask) & (addr | size | (addr+size))) == 0) +#define __access_mask get_fs() + +#define access_ok(type,addr,size) \ + __access_ok(((unsigned long)(addr)),(size),__access_mask) + +extern inline int verify_area(int type, const void * addr, unsigned long size) +{ + return access_ok(type,addr,size) ? 0 : -EFAULT; +} + +/* + * These are the main single-value transfer routines. They automatically + * use the right size if we just have the right pointer type. + * + * As the alpha uses the same address space for kernel and user + * data, we can just do these as direct assignments. (Of course, the + * exception handling means that it's no longer "just"...) + * + * Careful to not + * (a) re-use the arguments for side effects (sizeof/typeof is ok) + * (b) require any knowledge of processes at this stage + */ +#define put_user(x,ptr) \ + __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)),__access_mask) +#define get_user(x,ptr) \ + __get_user_check((x),(ptr),sizeof(*(ptr)),__access_mask) + +/* + * The "__xxx" versions do not do address space checking, useful when + * doing multiple accesses to the same area (the programmer has to do the + * checks by hand with "access_ok()") + */ +#define __put_user(x,ptr) \ + __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) +#define __get_user(x,ptr) \ + __get_user_nocheck((x),(ptr),sizeof(*(ptr))) + +/* + * The "lda %1, 2b-1b(%0)" bits are magic to get the assembler to + * encode the bits we need for resolving the exception. See the + * more extensive comments with fixup_inline_exception below for + * more information. + */ + +extern void __get_user_unknown(void); + +#define __get_user_nocheck(x,ptr,size) \ +({ \ + long __gu_err = 0, __gu_val; \ + switch (size) { \ + case 1: __get_user_8(ptr); break; \ + case 2: __get_user_16(ptr); break; \ + case 4: __get_user_32(ptr); break; \ + case 8: __get_user_64(ptr); break; \ + default: __get_user_unknown(); break; \ + } \ + (x) = (__typeof__(*(ptr))) __gu_val; \ + __gu_err; \ +}) + +#define __get_user_check(x,ptr,size,mask) \ +({ \ + long __gu_err = -EFAULT, __gu_val = 0; \ + const __typeof__(*(ptr)) *__gu_addr = (ptr); \ + if (__access_ok((long)__gu_addr,size,mask)) { \ + __gu_err = 0; \ + switch (size) { \ + case 1: __get_user_8(__gu_addr); break; \ + case 2: __get_user_16(__gu_addr); break; \ + case 4: __get_user_32(__gu_addr); break; \ + case 8: __get_user_64(__gu_addr); break; \ + default: __get_user_unknown(); break; \ + } \ + } \ + (x) = (__typeof__(*(ptr))) __gu_val; \ + __gu_err; \ +}) + +struct __large_struct { unsigned long buf[100]; }; +#define __m(x) (*(struct __large_struct *)(x)) + +#define __get_user_64(addr) \ + __asm__("1: ldq %0,%2\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda %0, 2b-1b(%1)\n" \ + ".text" \ + : "=r"(__gu_val), "=r"(__gu_err) \ + : "m"(__m(addr)), "1"(__gu_err)) + +#define __get_user_32(addr) \ + __asm__("1: ldl %0,%2\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda %0, 2b-1b(%1)\n" \ + ".text" \ + : "=r"(__gu_val), "=r"(__gu_err) \ + : "m"(__m(addr)), "1"(__gu_err)) + +#ifdef __HAVE_CPU_BWX +/* Those lucky bastards with ev56 and later cpus can do byte/word moves. */ + +#define __get_user_16(addr) \ + __asm__("1: ldwu %0,%2\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda %0, 2b-1b(%1)\n" \ + ".text" \ + : "=r"(__gu_val), "=r"(__gu_err) \ + : "m"(__m(addr)), "1"(__gu_err)) + +#define __get_user_8(addr) \ + __asm__("1: ldbu %0,%2\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda %0, 2b-1b(%1)\n" \ + ".text" \ + : "=r"(__gu_val), "=r"(__gu_err) \ + : "m"(__m(addr)), "1"(__gu_err)) +#else +/* Unfortunately, we can't get an unaligned access trap for the sub-word + load, so we have to do a general unaligned operation. */ + +#define __get_user_16(addr) \ +{ \ + long __gu_tmp; \ + __asm__("1: ldq_u %0,0(%3)\n" \ + "2: ldq_u %1,1(%3)\n" \ + " extwl %0,%3,%0\n" \ + " extwh %1,%3,%1\n" \ + " or %0,%1,%0\n" \ + "3:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda %0, 3b-1b(%2)\n" \ + " .gprel32 2b\n" \ + " lda %0, 2b-1b(%2)\n" \ + ".text" \ + : "=&r"(__gu_val), "=&r"(__gu_tmp), "=r"(__gu_err) \ + : "r"(addr), "2"(__gu_err)); \ +} + +#define __get_user_8(addr) \ + __asm__("1: ldq_u %0,0(%2)\n" \ + " extbl %0,%2,%0\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda %0, 2b-1b(%1)\n" \ + ".text" \ + : "=&r"(__gu_val), "=r"(__gu_err) \ + : "r"(addr), "1"(__gu_err)) +#endif + +extern void __put_user_unknown(void); + +#define __put_user_nocheck(x,ptr,size) \ +({ \ + long __pu_err = 0; \ + switch (size) { \ + case 1: __put_user_8(x,ptr); break; \ + case 2: __put_user_16(x,ptr); break; \ + case 4: __put_user_32(x,ptr); break; \ + case 8: __put_user_64(x,ptr); break; \ + default: __put_user_unknown(); break; \ + } \ + __pu_err; \ +}) + +#define __put_user_check(x,ptr,size,mask) \ +({ \ + long __pu_err = -EFAULT; \ + __typeof__(*(ptr)) *__pu_addr = (ptr); \ + if (__access_ok((long)__pu_addr,size,mask)) { \ + __pu_err = 0; \ + switch (size) { \ + case 1: __put_user_8(x,__pu_addr); break; \ + case 2: __put_user_16(x,__pu_addr); break; \ + case 4: __put_user_32(x,__pu_addr); break; \ + case 8: __put_user_64(x,__pu_addr); break; \ + default: __put_user_unknown(); break; \ + } \ + } \ + __pu_err; \ +}) + +/* + * The "__put_user_xx()" macros tell gcc they read from memory + * instead of writing: this is because they do not write to + * any memory gcc knows about, so there are no aliasing issues + */ +#define __put_user_64(x,addr) \ +__asm__ __volatile__("1: stq %r2,%1\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda $31,2b-1b(%0)\n" \ + ".text" \ + : "=r"(__pu_err) \ + : "m" (__m(addr)), "rJ" (x), "0"(__pu_err)) + +#define __put_user_32(x,addr) \ +__asm__ __volatile__("1: stl %r2,%1\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda $31,2b-1b(%0)\n" \ + ".text" \ + : "=r"(__pu_err) \ + : "m"(__m(addr)), "rJ"(x), "0"(__pu_err)) + +#ifdef __HAVE_CPU_BWX +/* Those lucky bastards with ev56 and later cpus can do byte/word moves. */ + +#define __put_user_16(x,addr) \ +__asm__ __volatile__("1: stw %r2,%1\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda $31,2b-1b(%0)\n" \ + ".text" \ + : "=r"(__pu_err) \ + : "m"(__m(addr)), "rJ"(x), "0"(__pu_err)) + +#define __put_user_8(x,addr) \ +__asm__ __volatile__("1: stb %r2,%1\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda $31,2b-1b(%0)\n" \ + ".text" \ + : "=r"(__pu_err) \ + : "m"(__m(addr)), "rJ"(x), "0"(__pu_err)) +#else +/* Unfortunately, we can't get an unaligned access trap for the sub-word + write, so we have to do a general unaligned operation. */ + +#define __put_user_16(x,addr) \ +{ \ + long __pu_tmp1, __pu_tmp2, __pu_tmp3, __pu_tmp4; \ + __asm__ __volatile__( \ + "1: ldq_u %2,1(%5)\n" \ + "2: ldq_u %1,0(%5)\n" \ + " inswh %6,%5,%4\n" \ + " inswl %6,%5,%3\n" \ + " mskwh %2,%5,%2\n" \ + " mskwl %1,%5,%1\n" \ + " or %2,%4,%2\n" \ + " or %1,%3,%1\n" \ + "3: stq_u %2,1(%5)\n" \ + "4: stq_u %1,0(%5)\n" \ + "5:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda $31, 5b-1b(%0)\n" \ + " .gprel32 2b\n" \ + " lda $31, 5b-2b(%0)\n" \ + " .gprel32 3b\n" \ + " lda $31, 5b-3b(%0)\n" \ + " .gprel32 4b\n" \ + " lda $31, 5b-4b(%0)\n" \ + ".text" \ + : "=r"(__pu_err), "=&r"(__pu_tmp1), \ + "=&r"(__pu_tmp2), "=&r"(__pu_tmp3), \ + "=&r"(__pu_tmp4) \ + : "r"(addr), "r"((unsigned long)(x)), "0"(__pu_err)); \ +} + +#define __put_user_8(x,addr) \ +{ \ + long __pu_tmp1, __pu_tmp2; \ + __asm__ __volatile__( \ + "1: ldq_u %1,0(%4)\n" \ + " insbl %3,%4,%2\n" \ + " mskbl %1,%4,%1\n" \ + " or %1,%2,%1\n" \ + "2: stq_u %1,0(%4)\n" \ + "3:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda $31, 3b-1b(%0)\n" \ + " .gprel32 2b\n" \ + " lda $31, 3b-2b(%0)\n" \ + ".text" \ + : "=r"(__pu_err), \ + "=&r"(__pu_tmp1), "=&r"(__pu_tmp2) \ + : "r"((unsigned long)(x)), "r"(addr), "0"(__pu_err)); \ +} +#endif + + +/* + * Complex access routines + */ + +#define copy_to_user(to,from,n) __copy_tofrom_user((to),(from),(n),__cu_to) +#define copy_from_user(to,from,n) __copy_tofrom_user((to),(from),(n),__cu_from) + +extern void __copy_user(void); + +#define __copy_tofrom_user(to,from,n,v) \ +({ \ + register void * __cu_to __asm__("$6") = (to); \ + register const void * __cu_from __asm__("$7") = (from); \ + register long __cu_len __asm__("$0") = (n); \ + if (__access_ok(((long)(v)),__cu_len,__access_mask)) { \ + __asm__ __volatile__( \ + "jsr $28,(%3),__copy_user" \ + : "=r" (__cu_len), "=r" (__cu_from), "=r" (__cu_to) \ + : "r" (__copy_user), "0" (__cu_len), \ + "1" (__cu_from), "2" (__cu_to) \ + : "$1","$2","$3","$4","$5","$28","memory"); \ + } \ + __cu_len; \ +}) + +extern void __clear_user(void); + +#define clear_user(to,n) \ +({ \ + register void * __cl_to __asm__("$6") = (to); \ + register long __cl_len __asm__("$0") = (n); \ + if (__access_ok(((long)__cl_to),__cl_len,__access_mask)) { \ + __asm__ __volatile__( \ + "jsr $28,(%2),__clear_user" \ + : "=r"(__cl_len), "=r"(__cl_to) \ + : "r"(__clear_user), "0"(__cl_len), "1"(__cl_to)\ + : "$1","$2","$3","$4","$5","$28","memory"); \ + } \ + __cl_len; \ +}) + + +/* Returns: -EFAULT if exception before terminator, N if the entire + buffer filled, else strlen. */ + +extern long __strncpy_from_user(char *__to, const char *__from, long __to_len); + +#define strncpy_from_user(to,from,n) \ +({ \ + char * __sfu_to = (to); \ + const char * __sfu_from = (from); \ + long __sfu_ret = -EFAULT; \ + if (__access_ok(((long)__sfu_from),0,__access_mask)) \ + __sfu_ret = __strncpy_from_user(__sfu_to,__sfu_from,(n)); \ + __sfu_ret; \ +}) + +/* Returns: 0 if bad, string length+1 (memory size) of string if ok */ +extern long __strlen_user(const char *); + +extern inline long strlen_user(const char *str) +{ + return access_ok(VERIFY_READ,str,0) ? __strlen_user(str) : 0; +} + +/* + * About the exception table: + * + * - insn is a 32-bit offset off of the kernel's or module's gp. + * - nextinsn is a 16-bit offset off of the faulting instruction + * (not off of the *next* instruction as branches are). + * - errreg is the register in which to place -EFAULT. + * - valreg is the final target register for the load sequence + * and will be zeroed. + * + * Either errreg or valreg may be $31, in which case nothing happens. + * + * The exception fixup information "just so happens" to be arranged + * as in a MEM format instruction. This lets us emit our three + * values like so: + * + * lda valreg, nextinsn(errreg) + * + */ + +struct exception_table_entry +{ + signed int insn; + union exception_fixup { + unsigned unit; + struct { + signed int nextinsn : 16; + unsigned int errreg : 5; + unsigned int valreg : 5; + } bits; + } fixup; +}; + +/* Returns 0 if exception not found and fixup.unit otherwise. */ +extern unsigned search_exception_table(unsigned long); + +/* Returns the new pc */ +#define fixup_exception(map_reg, fixup_unit, pc) \ +({ \ + union exception_fixup __fie_fixup; \ + __fie_fixup.unit = fixup_unit; \ + if (__fie_fixup.bits.valreg != 31) \ + map_reg(__fie_fixup.bits.valreg) = 0; \ + if (__fie_fixup.bits.errreg != 31) \ + map_reg(__fie_fixup.bits.errreg) = -EFAULT; \ + (pc) + __fie_fixup.bits.nextinsn; \ +}) + + +#endif /* __ALPHA_UACCESS_H */ diff --git a/include/asm-alpha/unaligned.h b/include/asm-alpha/unaligned.h index 071477496..35da3d5ae 100644 --- a/include/asm-alpha/unaligned.h +++ b/include/asm-alpha/unaligned.h @@ -1,55 +1,72 @@ #ifndef __ALPHA_UNALIGNED_H #define __ALPHA_UNALIGNED_H +/* + * The main single-value unaligned transfer routines. + */ +#define get_unaligned(ptr) \ + ((__typeof__(*(ptr)))__get_unaligned((ptr), sizeof(*(ptr)))) +#define put_unaligned(x,ptr) \ + __put_unaligned((unsigned long)(x), (ptr), sizeof(*(ptr))) + +/* + * This is a silly but good way to make sure that + * the get/put functions are indeed always optimized, + * and that we use the correct sizes. + */ +extern void bad_unaligned_access_length(void); + /* - * inline functions to do unaligned accesses.. See entUna in traps.c + * Elemental unaligned loads */ -extern inline unsigned long ldq_u(unsigned long * r11) + +extern inline unsigned long __uldq(const unsigned long * r11) { unsigned long r1,r2; __asm__("ldq_u %0,%3\n\t" "ldq_u %1,%4\n\t" "extql %0,%2,%0\n\t" - "extqh %1,%2,%1\n\t" - "bis %1,%0,%0" + "extqh %1,%2,%1" :"=&r" (r1), "=&r" (r2) :"r" (r11), "m" (*r11), - "m" (*(unsigned long *)(7+(char *) r11))); - return r1; + "m" (*(const unsigned long *)(7+(char *) r11))); + return r1 | r2; } -extern inline unsigned long ldl_u(unsigned int * r11) +extern inline unsigned long __uldl(const unsigned int * r11) { unsigned long r1,r2; __asm__("ldq_u %0,%3\n\t" "ldq_u %1,%4\n\t" "extll %0,%2,%0\n\t" - "extlh %1,%2,%1\n\t" - "bis %1,%0,%0" + "extlh %1,%2,%1" :"=&r" (r1), "=&r" (r2) :"r" (r11), "m" (*r11), - "m" (*(unsigned long *)(3+(char *) r11))); - return r1; + "m" (*(const unsigned long *)(3+(char *) r11))); + return r1 | r2; } -extern inline unsigned long ldw_u(unsigned short * r11) +extern inline unsigned long __uldw(const unsigned short * r11) { unsigned long r1,r2; __asm__("ldq_u %0,%3\n\t" "ldq_u %1,%4\n\t" "extwl %0,%2,%0\n\t" - "extwh %1,%2,%1\n\t" - "bis %1,%0,%0" + "extwh %1,%2,%1" :"=&r" (r1), "=&r" (r2) :"r" (r11), "m" (*r11), - "m" (*(unsigned long *)(1+(char *) r11))); - return r1; + "m" (*(const unsigned long *)(1+(char *) r11))); + return r1 | r2; } -extern inline void stq_u(unsigned long r5, unsigned long * r11) +/* + * Elemental unaligned stores + */ + +extern inline void __ustq(unsigned long r5, unsigned long * r11) { unsigned long r1,r2,r3,r4; @@ -69,7 +86,7 @@ extern inline void stq_u(unsigned long r5, unsigned long * r11) :"r" (r5), "r" (r11)); } -extern inline void stl_u(unsigned long r5, unsigned int * r11) +extern inline void __ustl(unsigned long r5, unsigned int * r11) { unsigned long r1,r2,r3,r4; @@ -89,7 +106,7 @@ extern inline void stl_u(unsigned long r5, unsigned int * r11) :"r" (r5), "r" (r11)); } -extern inline void stw_u(unsigned long r5, unsigned short * r11) +extern inline void __ustw(unsigned long r5, unsigned short * r11) { unsigned long r1,r2,r3,r4; @@ -109,4 +126,46 @@ extern inline void stw_u(unsigned long r5, unsigned short * r11) :"r" (r5), "r" (r11)); } +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 = __uldw((const unsigned short *)ptr); + break; + case 4: + val = __uldl((const unsigned int *)ptr); + break; + case 8: + val = __uldq((const unsigned long *)ptr); + 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: + __ustw(val, (unsigned short *)ptr); + break; + case 4: + __ustl(val, (unsigned int *)ptr); + break; + case 8: + __ustq(val, (unsigned long *)ptr); + break; + default: + bad_unaligned_access_length(); + } +} + #endif diff --git a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h index 11a940a57..03f745481 100644 --- a/include/asm-alpha/unistd.h +++ b/include/asm-alpha/unistd.h @@ -1,57 +1,234 @@ #ifndef _ALPHA_UNISTD_H #define _ALPHA_UNISTD_H +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_close 6 +#define __NR_wait4 7 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_chdir 12 +#define __NR_fchdir 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_brk 17 +#define __NR_lseek 19 +#define __NR_getxpid 20 +#define __NR_setuid 23 +#define __NR_getxuid 24 +#define __NR_ptrace 26 +#define __NR_access 33 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_setpgid 39 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_open 45 +#define __NR_getxgid 47 +#define __NR_acct 51 +#define __NR_sigpending 52 +#define __NR_ioctl 54 +#define __NR_symlink 57 +#define __NR_readlink 58 +#define __NR_execve 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_getpgrp 63 +#define __NR_getpagesize 64 +#define __NR_stat 67 +#define __NR_lstat 68 +#define __NR_mmap 71 /* OSF/1 mmap is superset of Linux */ +#define __NR_munmap 73 +#define __NR_mprotect 74 +#define __NR_madvise 75 +#define __NR_vhangup 76 +#define __NR_getgroups 79 +#define __NR_setgroups 80 +#define __NR_setpgrp 82 /* BSD alias for setpgid */ +#define __NR_setitimer 83 +#define __NR_getitimer 86 +#define __NR_gethostname 87 +#define __NR_sethostname 88 +#define __NR_getdtablesize 89 +#define __NR_dup2 90 +#define __NR_fstat 91 +#define __NR_fcntl 92 +#define __NR_select 93 +#define __NR_fsync 95 +#define __NR_setpriority 96 +#define __NR_socket 97 +#define __NR_connect 98 +#define __NR_accept 99 +#define __NR_getpriority 100 +#define __NR_send 101 +#define __NR_recv 102 +#define __NR_sigreturn 103 +#define __NR_bind 104 +#define __NR_setsockopt 105 +#define __NR_listen 106 +#define __NR_sigsuspend 111 +#define __NR_recvmsg 113 +#define __NR_sendmsg 114 +#define __NR_gettimeofday 116 +#define __NR_getrusage 117 +#define __NR_getsockopt 118 +#define __NR_readv 120 +#define __NR_writev 121 +#define __NR_settimeofday 122 +#define __NR_fchown 123 +#define __NR_fchmod 124 +#define __NR_recvfrom 125 +#define __NR_setreuid 126 +#define __NR_setregid 127 +#define __NR_rename 128 +#define __NR_truncate 129 +#define __NR_ftruncate 130 +#define __NR_flock 131 +#define __NR_setgid 132 +#define __NR_sendto 133 +#define __NR_shutdown 134 +#define __NR_socketpair 135 +#define __NR_mkdir 136 +#define __NR_rmdir 137 +#define __NR_utimes 138 +#define __NR_getpeername 141 +#define __NR_getrlimit 144 +#define __NR_setrlimit 145 +#define __NR_setsid 147 +#define __NR_quotactl 148 +#define __NR_getsockname 150 +#define __NR_sigaction 156 +#define __NR_setdomainname 166 +#define __NR_msgctl 200 +#define __NR_msgget 201 +#define __NR_msgrcv 202 +#define __NR_msgsnd 203 +#define __NR_semctl 204 +#define __NR_semget 205 +#define __NR_semop 206 +#define __NR_shmctl 210 +#define __NR_shmdt 211 +#define __NR_shmget 212 + +#define __NR_msync 217 + +#define __NR_getpgid 233 +#define __NR_getsid 234 + +#define __NR_sysfs 254 + /* - * ".long 131" is "PAL_callsys".. - * - * Duh, the alpha gcc compiler doesn't allow us to specify regs - * yet. I'll have to see about this later.. + * Linux-specific system calls begin at 300 */ +#define __NR_bdflush 300 +#define __NR_sethae 301 +#define __NR_mount 302 +#define __NR_adjtimex 303 +#define __NR_swapoff 304 +#define __NR_getdents 305 +#define __NR_create_module 306 +#define __NR_init_module 307 +#define __NR_delete_module 308 +#define __NR_get_kernel_syms 309 +#define __NR_syslog 310 +#define __NR_reboot 311 +#define __NR_clone 312 +#define __NR_uselib 313 +#define __NR_mlock 314 +#define __NR_munlock 315 +#define __NR_mlockall 316 +#define __NR_munlockall 317 +#define __NR_sysinfo 318 +#define __NR__sysctl 319 +#define __NR_idle 320 +#define __NR_umount 321 +#define __NR_swapon 322 +#define __NR_times 323 +#define __NR_personality 324 +#define __NR_setfsuid 325 +#define __NR_setfsgid 326 +#define __NR_ustat 327 +#define __NR_statfs 328 +#define __NR_fstatfs 329 +#define __NR_sched_setparam 330 +#define __NR_sched_getparam 331 +#define __NR_sched_setscheduler 332 +#define __NR_sched_getscheduler 333 +#define __NR_sched_yield 334 +#define __NR_sched_get_priority_max 335 +#define __NR_sched_get_priority_min 336 +#define __NR_sched_rr_get_interval 337 +#define __NR_afs_syscall 338 +#define __NR_uname 339 +#define __NR_nanosleep 340 +#define __NR_mremap 341 +#define __NR_nfsctl 342 +#define __NR_setresuid 343 +#define __NR_getresuid 344 +#define __NR_pciconfig_read 345 +#define __NR_pciconfig_write 346 + +#if defined(__LIBRARY__) && defined(__GNUC__) /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ -#define _syscall0(type,name) \ -type name(void) \ -{ \ - return (type) -1; \ +#define _syscall0(type, name) \ +type name(void) \ +{ \ + extern long syscall (int, ...); \ + return syscall(__NR_##name)); \ } -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ - return (type) -1; \ +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ + extern long syscall (int, ...); \ + return syscall(__NR_##name, arg1); \ } -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) \ -{ \ - return (type) -1; \ +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ + extern long syscall (int, ...); \ + return syscall(__NR_##name, arg1, arg2); \ } -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) \ -{ \ - return (type) -1; \ +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ + extern long syscall (int, ...); \ + return syscall(__NR_##name, arg1, arg2, arg3); \ } #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ - return (type) -1; \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ + extern long syscall (int, ...); \ + return syscall(__NR_##name, arg1, arg2, arg3, arg4); \ } #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) \ -{ \ - return (type) -1; \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ + extern long syscall (int, ...); \ + return syscall(__NR_##name, arg1, arg2, arg3, arg4); \ } +#endif /* __LIBRARY__ && __GNUC__ */ + #ifdef __KERNEL_SYSCALLS__ -extern unsigned long kernel_fork(void); -static inline unsigned long fork(void) +#include <linux/string.h> +#include <linux/signal.h> + +extern long __kernel_thread(unsigned long, int (*)(void *), void *); + +static inline long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) { - return kernel_fork(); + return __kernel_thread(flags | CLONE_VM, fn, arg); } extern void sys_idle(void); @@ -133,10 +310,10 @@ static inline int sync(void) return sys_sync(); } -extern int sys_waitpid(int, int *, int); +extern int sys_wait4(int, int *, int, struct rusage *); static inline pid_t waitpid(int pid, int * wait_stat, int flags) { - return sys_waitpid(pid,wait_stat,flags); + return sys_wait4(pid, wait_stat, flags, NULL); } static inline pid_t wait(int * wait_stat) diff --git a/include/asm-alpha/user.h b/include/asm-alpha/user.h new file mode 100644 index 000000000..c5519bf16 --- /dev/null +++ b/include/asm-alpha/user.h @@ -0,0 +1,52 @@ +#ifndef _ALPHA_USER_H +#define _ALPHA_USER_H + +#include <linux/ptrace.h> + +#include <asm/page.h> +#include <asm/reg.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, NOT the osf-core). The 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 handy at some point. All of the registers + * are stored as part of the upage. The upage should always be + * only one page long. + * data: The data segment follows next. We use current->end_text to + * current->brk to pick up all of the user variables, plus any memory + * that may have been sbrk'ed. 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 usp to + * current->start_stack, so we round each of these in order to be able + * to write an integer number of pages. + */ +struct user { + unsigned long regs[EF_SIZE/8+32]; /* integer and fp regs */ + size_t u_tsize; /* text size (pages) */ + size_t u_dsize; /* data size (pages) */ + size_t u_ssize; /* stack size (pages) */ + unsigned long start_code; /* text starting address */ + unsigned long start_data; /* data starting address */ + unsigned long start_stack; /* stack starting address */ + long int signal; /* signal causing core dump */ + struct regs * u_ar0; /* help gdb find registers */ + unsigned long magic; /* identifies a core file */ + char u_comm[32]; /* user command name */ +}; + +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_DATA_START_ADDR (u.start_data) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#endif /* _ALPHA_USER_H */ |