diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-17 00:20:36 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-17 00:20:36 +0200 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /include/asm-sparc64 | |
download | linux-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.xz linux-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.zip |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'include/asm-sparc64')
145 files changed, 15769 insertions, 0 deletions
diff --git a/include/asm-sparc64/a.out.h b/include/asm-sparc64/a.out.h new file mode 100644 index 000000000000..02af289e3f46 --- /dev/null +++ b/include/asm-sparc64/a.out.h @@ -0,0 +1,104 @@ +/* $Id: a.out.h,v 1.8 2002/02/09 19:49:31 davem Exp $ */ +#ifndef __SPARC64_A_OUT_H__ +#define __SPARC64_A_OUT_H__ + +#define SPARC_PGSIZE 0x2000 /* Thanks to the sun4 architecture... */ +#define SEGMENT_SIZE SPARC_PGSIZE /* whee... */ + +#ifndef __ASSEMBLY__ + +struct exec { + unsigned char a_dynamic:1; /* A __DYNAMIC is in this image */ + unsigned char a_toolversion:7; + unsigned char a_machtype; + unsigned short a_info; + unsigned int a_text; /* length of text, in bytes */ + unsigned int a_data; /* length of data, in bytes */ + unsigned int a_bss; /* length of bss, in bytes */ + unsigned int a_syms; /* length of symbol table, in bytes */ + unsigned int a_entry; /* where program begins */ + unsigned int a_trsize; + unsigned int a_drsize; +}; + +#endif /* !__ASSEMBLY__ */ + +/* Where in the file does the text information begin? */ +#define N_TXTOFF(x) (N_MAGIC(x) == ZMAGIC ? 0 : sizeof (struct exec)) + +/* Where do the Symbols start? */ +#define N_SYMOFF(x) (N_TXTOFF(x) + (x).a_text + \ + (x).a_data + (x).a_trsize + \ + (x).a_drsize) + +/* Where does text segment go in memory after being loaded? */ +#define N_TXTADDR(x) (unsigned long)(((N_MAGIC(x) == ZMAGIC) && \ + ((x).a_entry < SPARC_PGSIZE)) ? \ + 0 : SPARC_PGSIZE) + +/* And same for the data segment.. */ +#define N_DATADDR(x) (N_MAGIC(x)==OMAGIC ? \ + (N_TXTADDR(x) + (x).a_text) \ + : (unsigned long)(_N_SEGMENT_ROUND (_N_TXTENDADDR(x)))) + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +#ifndef __ASSEMBLY__ + +/* + * Sparc relocation types + */ +enum reloc_type +{ + RELOC_8, + RELOC_16, + RELOC_32, /* simplest relocs */ + RELOC_DISP8, + RELOC_DISP16, + RELOC_DISP32, /* Disp's (pc-rel) */ + RELOC_WDISP30, + RELOC_WDISP22, /* SR word disp's */ + RELOC_HI22, + RELOC_22, /* SR 22-bit relocs */ + RELOC_13, + RELOC_LO10, /* SR 13&10-bit relocs */ + RELOC_SFA_BASE, + RELOC_SFA_OFF13, /* SR S.F.A. relocs */ + RELOC_BASE10, + RELOC_BASE13, + RELOC_BASE22, /* base_relative pic */ + RELOC_PC10, + RELOC_PC22, /* special pc-rel pic */ + RELOC_JMP_TBL, /* jmp_tbl_rel in pic */ + RELOC_SEGOFF16, /* ShLib offset-in-seg */ + RELOC_GLOB_DAT, + RELOC_JMP_SLOT, + RELOC_RELATIVE /* rtld relocs */ +}; + +/* + * Format of a relocation datum. + */ +struct relocation_info /* used when header.a_machtype == M_SPARC */ +{ + unsigned int r_address; /* relocation addr */ + unsigned int r_index:24; /* segment index or symbol index */ + unsigned int r_extern:1; /* if F, r_index==SEG#; if T, SYM idx */ + int r_pad:2; /* <unused> */ + enum reloc_type r_type:5; /* type of relocation to perform */ + int r_addend; /* addend for relocation value */ +}; + +#define N_RELOCATION_INFO_DECLARED 1 + +#ifdef __KERNEL__ + +#define STACK_TOP (test_thread_flag(TIF_32BIT) ? 0xf0000000 : 0x80000000000L) + +#endif + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(__SPARC64_A_OUT_H__) */ diff --git a/include/asm-sparc64/agp.h b/include/asm-sparc64/agp.h new file mode 100644 index 000000000000..ba05bdf9a211 --- /dev/null +++ b/include/asm-sparc64/agp.h @@ -0,0 +1,11 @@ +#ifndef AGP_H +#define AGP_H 1 + +/* dummy for now */ + +#define map_page_into_agp(page) +#define unmap_page_from_agp(page) +#define flush_agp_mappings() +#define flush_agp_cache() mb() + +#endif diff --git a/include/asm-sparc64/apb.h b/include/asm-sparc64/apb.h new file mode 100644 index 000000000000..80f0df289a66 --- /dev/null +++ b/include/asm-sparc64/apb.h @@ -0,0 +1,36 @@ +/* $Id: apb.h,v 1.2 1998/04/01 20:41:49 ecd Exp $ + * apb.h: Advanced PCI Bridge Configuration Registers and Bits + * + * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) + */ + +#ifndef _SPARC64_APB_H +#define _SPARC64_APB_H + +#define APB_TICK_REGISTER 0xb0 +#define APB_INT_ACK 0xb8 +#define APB_PRIMARY_MASTER_RETRY_LIMIT 0xc0 +#define APB_DMA_ASFR 0xc8 +#define APB_DMA_AFAR 0xd0 +#define APB_PIO_TARGET_RETRY_LIMIT 0xd8 +#define APB_PIO_TARGET_LATENCY_TIMER 0xd9 +#define APB_DMA_TARGET_RETRY_LIMIT 0xda +#define APB_DMA_TARGET_LATENCY_TIMER 0xdb +#define APB_SECONDARY_MASTER_RETRY_LIMIT 0xdc +#define APB_SECONDARY_CONTROL 0xdd +#define APB_IO_ADDRESS_MAP 0xde +#define APB_MEM_ADDRESS_MAP 0xdf + +#define APB_PCI_CONTROL_LOW 0xe0 +# define APB_PCI_CTL_LOW_ARB_PARK (1 << 21) +# define APB_PCI_CTL_LOW_ERRINT_EN (1 << 8) + +#define APB_PCI_CONTROL_HIGH 0xe4 +# define APB_PCI_CTL_HIGH_SERR (1 << 2) +# define APB_PCI_CTL_HIGH_ARBITER_EN (1 << 0) + +#define APB_PIO_ASFR 0xe8 +#define APB_PIO_AFAR 0xf0 +#define APB_DIAG_REGISTER 0xf8 + +#endif /* !(_SPARC64_APB_H) */ diff --git a/include/asm-sparc64/asi.h b/include/asm-sparc64/asi.h new file mode 100644 index 000000000000..534855660f2a --- /dev/null +++ b/include/asm-sparc64/asi.h @@ -0,0 +1,145 @@ +/* $Id: asi.h,v 1.5 2001/03/29 11:47:47 davem Exp $ */ +#ifndef _SPARC64_ASI_H +#define _SPARC64_ASI_H + +/* asi.h: Address Space Identifier values for the V9. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +/* V9 Architecture mandary ASIs. */ +#define ASI_N 0x04 /* Nucleus */ +#define ASI_NL 0x0c /* Nucleus, little endian */ +#define ASI_AIUP 0x10 /* Primary, user */ +#define ASI_AIUS 0x11 /* Secondary, user */ +#define ASI_AIUPL 0x18 /* Primary, user, little endian */ +#define ASI_AIUSL 0x19 /* Secondary, user, little endian */ +#define ASI_P 0x80 /* Primary, implicit */ +#define ASI_S 0x81 /* Secondary, implicit */ +#define ASI_PNF 0x82 /* Primary, no fault */ +#define ASI_SNF 0x83 /* Secondary, no fault */ +#define ASI_PL 0x88 /* Primary, implicit, l-endian */ +#define ASI_SL 0x89 /* Secondary, implicit, l-endian */ +#define ASI_PNFL 0x8a /* Primary, no fault, l-endian */ +#define ASI_SNFL 0x8b /* Secondary, no fault, l-endian */ + +/* SpitFire and later extended ASIs. The "(III)" marker designates + * UltraSparc-III and later specific ASIs. The "(CMT)" marker designates + * Chip Multi Threading specific ASIs. + */ +#define ASI_PHYS_USE_EC 0x14 /* PADDR, E-cachable */ +#define ASI_PHYS_BYPASS_EC_E 0x15 /* PADDR, E-bit */ +#define ASI_PHYS_USE_EC_L 0x1c /* PADDR, E-cachable, little endian*/ +#define ASI_PHYS_BYPASS_EC_E_L 0x1d /* PADDR, E-bit, little endian */ +#define ASI_NUCLEUS_QUAD_LDD 0x24 /* Cachable, qword load */ +#define ASI_NUCLEUS_QUAD_LDD_L 0x2c /* Cachable, qword load, l-endian */ +#define ASI_PCACHE_DATA_STATUS 0x30 /* (III) PCache data stat RAM diag */ +#define ASI_PCACHE_DATA 0x31 /* (III) PCache data RAM diag */ +#define ASI_PCACHE_TAG 0x32 /* (III) PCache tag RAM diag */ +#define ASI_PCACHE_SNOOP_TAG 0x33 /* (III) PCache snoop tag RAM diag */ +#define ASI_QUAD_LDD_PHYS 0x34 /* (III+) PADDR, qword load */ +#define ASI_WCACHE_VALID_BITS 0x38 /* (III) WCache Valid Bits diag */ +#define ASI_WCACHE_DATA 0x39 /* (III) WCache data RAM diag */ +#define ASI_WCACHE_TAG 0x3a /* (III) WCache tag RAM diag */ +#define ASI_WCACHE_SNOOP_TAG 0x3b /* (III) WCache snoop tag RAM diag */ +#define ASI_QUAD_LDD_PHYS_L 0x3c /* (III+) PADDR, qw-load, l-endian */ +#define ASI_SRAM_FAST_INIT 0x40 /* (III+) Fast SRAM init */ +#define ASI_CORE_AVAILABLE 0x41 /* (CMT) LP Available */ +#define ASI_CORE_ENABLE_STAT 0x41 /* (CMT) LP Enable Status */ +#define ASI_CORE_ENABLE 0x41 /* (CMT) LP Enable RW */ +#define ASI_XIR_STEERING 0x41 /* (CMT) XIR Steering RW */ +#define ASI_CORE_RUNNING_RW 0x41 /* (CMT) LP Running RW */ +#define ASI_CORE_RUNNING_W1S 0x41 /* (CMT) LP Running Write-One Set */ +#define ASI_CORE_RUNNING_W1C 0x41 /* (CMT) LP Running Write-One Clr */ +#define ASI_CORE_RUNNING_STAT 0x41 /* (CMT) LP Running Status */ +#define ASI_CMT_ERROR_STEERING 0x41 /* (CMT) Error Steering RW */ +#define ASI_DCACHE_INVALIDATE 0x42 /* (III) DCache Invalidate diag */ +#define ASI_DCACHE_UTAG 0x43 /* (III) DCache uTag diag */ +#define ASI_DCACHE_SNOOP_TAG 0x44 /* (III) DCache snoop tag RAM diag */ +#define ASI_LSU_CONTROL 0x45 /* Load-store control unit */ +#define ASI_DCU_CONTROL_REG 0x45 /* (III) DCache Unit Control reg */ +#define ASI_DCACHE_DATA 0x46 /* DCache data-ram diag access */ +#define ASI_DCACHE_TAG 0x47 /* Dcache tag/valid ram diag access*/ +#define ASI_INTR_DISPATCH_STAT 0x48 /* IRQ vector dispatch status */ +#define ASI_INTR_RECEIVE 0x49 /* IRQ vector receive status */ +#define ASI_UPA_CONFIG 0x4a /* UPA config space */ +#define ASI_JBUS_CONFIG 0x4a /* (IIIi) JBUS Config Register */ +#define ASI_SAFARI_CONFIG 0x4a /* (III) Safari Config Register */ +#define ASI_SAFARI_ADDRESS 0x4a /* (III) Safari Address Register */ +#define ASI_ESTATE_ERROR_EN 0x4b /* E-cache error enable space */ +#define ASI_AFSR 0x4c /* Async fault status register */ +#define ASI_AFAR 0x4d /* Async fault address register */ +#define ASI_EC_TAG_DATA 0x4e /* E-cache tag/valid ram diag acc */ +#define ASI_IMMU 0x50 /* Insn-MMU main register space */ +#define ASI_IMMU_TSB_8KB_PTR 0x51 /* Insn-MMU 8KB TSB pointer reg */ +#define ASI_IMMU_TSB_64KB_PTR 0x52 /* Insn-MMU 64KB TSB pointer reg */ +#define ASI_ITLB_DATA_IN 0x54 /* Insn-MMU TLB data in reg */ +#define ASI_ITLB_DATA_ACCESS 0x55 /* Insn-MMU TLB data access reg */ +#define ASI_ITLB_TAG_READ 0x56 /* Insn-MMU TLB tag read reg */ +#define ASI_IMMU_DEMAP 0x57 /* Insn-MMU TLB demap */ +#define ASI_DMMU 0x58 /* Data-MMU main register space */ +#define ASI_DMMU_TSB_8KB_PTR 0x59 /* Data-MMU 8KB TSB pointer reg */ +#define ASI_DMMU_TSB_64KB_PTR 0x5a /* Data-MMU 16KB TSB pointer reg */ +#define ASI_DMMU_TSB_DIRECT_PTR 0x5b /* Data-MMU TSB direct pointer reg */ +#define ASI_DTLB_DATA_IN 0x5c /* Data-MMU TLB data in reg */ +#define ASI_DTLB_DATA_ACCESS 0x5d /* Data-MMU TLB data access reg */ +#define ASI_DTLB_TAG_READ 0x5e /* Data-MMU TLB tag read reg */ +#define ASI_DMMU_DEMAP 0x5f /* Data-MMU TLB demap */ +#define ASI_IIU_INST_TRAP 0x60 /* (III) Instruction Breakpoint */ +#define ASI_INTR_ID 0x63 /* (CMT) Interrupt ID register */ +#define ASI_CORE_ID 0x63 /* (CMT) LP ID register */ +#define ASI_CESR_ID 0x63 /* (CMT) CESR ID register */ +#define ASI_IC_INSTR 0x66 /* Insn cache instrucion ram diag */ +#define ASI_IC_TAG 0x67 /* Insn cache tag/valid ram diag */ +#define ASI_IC_STAG 0x68 /* (III) Insn cache snoop tag ram */ +#define ASI_IC_PRE_DECODE 0x6e /* Insn cache pre-decode ram diag */ +#define ASI_IC_NEXT_FIELD 0x6f /* Insn cache next-field ram diag */ +#define ASI_BRPRED_ARRAY 0x6f /* (III) Branch Prediction RAM diag*/ +#define ASI_BLK_AIUP 0x70 /* Primary, user, block load/store */ +#define ASI_BLK_AIUS 0x71 /* Secondary, user, block ld/st */ +#define ASI_MCU_CTRL_REG 0x72 /* (III) Memory controller regs */ +#define ASI_EC_DATA 0x74 /* (III) E-cache data staging reg */ +#define ASI_EC_CTRL 0x75 /* (III) E-cache control reg */ +#define ASI_EC_W 0x76 /* E-cache diag write access */ +#define ASI_UDB_ERROR_W 0x77 /* External UDB error regs W */ +#define ASI_UDB_CONTROL_W 0x77 /* External UDB control regs W */ +#define ASI_INTR_W 0x77 /* IRQ vector dispatch write */ +#define ASI_INTR_DATAN_W 0x77 /* (III) Out irq vector data reg N */ +#define ASI_INTR_DISPATCH_W 0x77 /* (III) Interrupt vector dispatch */ +#define ASI_BLK_AIUPL 0x78 /* Primary, user, little, blk ld/st*/ +#define ASI_BLK_AIUSL 0x79 /* Secondary, user, little, blk ld/st*/ +#define ASI_EC_R 0x7e /* E-cache diag read access */ +#define ASI_UDBH_ERROR_R 0x7f /* External UDB error regs rd hi */ +#define ASI_UDBL_ERROR_R 0x7f /* External UDB error regs rd low */ +#define ASI_UDBH_CONTROL_R 0x7f /* External UDB control regs rd hi */ +#define ASI_UDBL_CONTROL_R 0x7f /* External UDB control regs rd low*/ +#define ASI_INTR_R 0x7f /* IRQ vector dispatch read */ +#define ASI_INTR_DATAN_R 0x7f /* (III) In irq vector data reg N */ +#define ASI_PST8_P 0xc0 /* Primary, 8 8-bit, partial */ +#define ASI_PST8_S 0xc1 /* Secondary, 8 8-bit, partial */ +#define ASI_PST16_P 0xc2 /* Primary, 4 16-bit, partial */ +#define ASI_PST16_S 0xc3 /* Secondary, 4 16-bit, partial */ +#define ASI_PST32_P 0xc4 /* Primary, 2 32-bit, partial */ +#define ASI_PST32_S 0xc5 /* Secondary, 2 32-bit, partial */ +#define ASI_PST8_PL 0xc8 /* Primary, 8 8-bit, partial, L */ +#define ASI_PST8_SL 0xc9 /* Secondary, 8 8-bit, partial, L */ +#define ASI_PST16_PL 0xca /* Primary, 4 16-bit, partial, L */ +#define ASI_PST16_SL 0xcb /* Secondary, 4 16-bit, partial, L */ +#define ASI_PST32_PL 0xcc /* Primary, 2 32-bit, partial, L */ +#define ASI_PST32_SL 0xcd /* Secondary, 2 32-bit, partial, L */ +#define ASI_FL8_P 0xd0 /* Primary, 1 8-bit, fpu ld/st */ +#define ASI_FL8_S 0xd1 /* Secondary, 1 8-bit, fpu ld/st */ +#define ASI_FL16_P 0xd2 /* Primary, 1 16-bit, fpu ld/st */ +#define ASI_FL16_S 0xd3 /* Secondary, 1 16-bit, fpu ld/st */ +#define ASI_FL8_PL 0xd8 /* Primary, 1 8-bit, fpu ld/st, L */ +#define ASI_FL8_SL 0xd9 /* Secondary, 1 8-bit, fpu ld/st, L*/ +#define ASI_FL16_PL 0xda /* Primary, 1 16-bit, fpu ld/st, L */ +#define ASI_FL16_SL 0xdb /* Secondary, 1 16-bit, fpu ld/st,L*/ +#define ASI_BLK_COMMIT_P 0xe0 /* Primary, blk store commit */ +#define ASI_BLK_COMMIT_S 0xe1 /* Secondary, blk store commit */ +#define ASI_BLK_P 0xf0 /* Primary, blk ld/st */ +#define ASI_BLK_S 0xf1 /* Secondary, blk ld/st */ +#define ASI_BLK_PL 0xf8 /* Primary, blk ld/st, little */ +#define ASI_BLK_SL 0xf9 /* Secondary, blk ld/st, little */ + +#endif /* _SPARC64_ASI_H */ diff --git a/include/asm-sparc64/atomic.h b/include/asm-sparc64/atomic.h new file mode 100644 index 000000000000..d80f3379669b --- /dev/null +++ b/include/asm-sparc64/atomic.h @@ -0,0 +1,86 @@ +/* $Id: atomic.h,v 1.22 2001/07/11 23:56:07 davem Exp $ + * atomic.h: Thankfully the V9 is at least reasonable for this + * stuff. + * + * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com) + */ + +#ifndef __ARCH_SPARC64_ATOMIC__ +#define __ARCH_SPARC64_ATOMIC__ + +#include <linux/config.h> +#include <linux/types.h> + +typedef struct { volatile int counter; } atomic_t; +typedef struct { volatile __s64 counter; } atomic64_t; + +#define ATOMIC_INIT(i) { (i) } +#define ATOMIC64_INIT(i) { (i) } + +#define atomic_read(v) ((v)->counter) +#define atomic64_read(v) ((v)->counter) + +#define atomic_set(v, i) (((v)->counter) = i) +#define atomic64_set(v, i) (((v)->counter) = i) + +extern void atomic_add(int, atomic_t *); +extern void atomic64_add(int, atomic64_t *); +extern void atomic_sub(int, atomic_t *); +extern void atomic64_sub(int, atomic64_t *); + +extern int atomic_add_ret(int, atomic_t *); +extern int atomic64_add_ret(int, atomic64_t *); +extern int atomic_sub_ret(int, atomic_t *); +extern int atomic64_sub_ret(int, atomic64_t *); + +#define atomic_dec_return(v) atomic_sub_ret(1, v) +#define atomic64_dec_return(v) atomic64_sub_ret(1, v) + +#define atomic_inc_return(v) atomic_add_ret(1, v) +#define atomic64_inc_return(v) atomic64_add_ret(1, v) + +#define atomic_sub_return(i, v) atomic_sub_ret(i, v) +#define atomic64_sub_return(i, v) atomic64_sub_ret(i, v) + +#define atomic_add_return(i, v) atomic_add_ret(i, v) +#define atomic64_add_return(i, v) atomic64_add_ret(i, v) + +/* + * atomic_inc_and_test - increment and test + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1 + * and returns true if the result is zero, or false for all + * other cases. + */ +#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) + +#define atomic_sub_and_test(i, v) (atomic_sub_ret(i, v) == 0) +#define atomic64_sub_and_test(i, v) (atomic64_sub_ret(i, v) == 0) + +#define atomic_dec_and_test(v) (atomic_sub_ret(1, v) == 0) +#define atomic64_dec_and_test(v) (atomic64_sub_ret(1, v) == 0) + +#define atomic_inc(v) atomic_add(1, v) +#define atomic64_inc(v) atomic64_add(1, v) + +#define atomic_dec(v) atomic_sub(1, v) +#define atomic64_dec(v) atomic64_sub(1, v) + +#define atomic_add_negative(i, v) (atomic_add_ret(i, v) < 0) +#define atomic64_add_negative(i, v) (atomic64_add_ret(i, v) < 0) + +/* Atomic operations are already serializing */ +#ifdef CONFIG_SMP +#define smp_mb__before_atomic_dec() membar("#StoreLoad | #LoadLoad") +#define smp_mb__after_atomic_dec() membar("#StoreLoad | #StoreStore") +#define smp_mb__before_atomic_inc() membar("#StoreLoad | #LoadLoad") +#define smp_mb__after_atomic_inc() membar("#StoreLoad | #StoreStore") +#else +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() +#endif + +#endif /* !(__ARCH_SPARC64_ATOMIC__) */ diff --git a/include/asm-sparc64/audioio.h b/include/asm-sparc64/audioio.h new file mode 100644 index 000000000000..cf16173f521b --- /dev/null +++ b/include/asm-sparc64/audioio.h @@ -0,0 +1,234 @@ +/* + * include/asm-sparc/audioio.h + * + * Sparc Audio Midlayer + * Copyright (C) 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu) + */ + +#ifndef _AUDIOIO_H_ +#define _AUDIOIO_H_ + +/* + * SunOS/Solaris /dev/audio interface + */ + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) +#include <linux/types.h> +#include <linux/time.h> +#include <linux/ioctl.h> +#endif + +/* + * This structure contains state information for audio device IO streams. + */ +typedef struct audio_prinfo { + /* + * The following values describe the audio data encoding. + */ + unsigned int sample_rate; /* samples per second */ + unsigned int channels; /* number of interleaved channels */ + unsigned int precision; /* bit-width of each sample */ + unsigned int encoding; /* data encoding method */ + + /* + * The following values control audio device configuration + */ + unsigned int gain; /* gain level: 0 - 255 */ + unsigned int port; /* selected I/O port (see below) */ + unsigned int avail_ports; /* available I/O ports (see below) */ + unsigned int _xxx[2]; /* Reserved for future use */ + + unsigned int buffer_size; /* I/O buffer size */ + + /* + * The following values describe driver state + */ + unsigned int samples; /* number of samples converted */ + unsigned int eof; /* End Of File counter (play only) */ + + unsigned char pause; /* non-zero for pause, zero to resume */ + unsigned char error; /* non-zero if overflow/underflow */ + unsigned char waiting; /* non-zero if a process wants access */ + unsigned char balance; /* stereo channel balance */ + + unsigned short minordev; + + /* + * The following values are read-only state flags + */ + unsigned char open; /* non-zero if open access permitted */ + unsigned char active; /* non-zero if I/O is active */ +} audio_prinfo_t; + + +/* + * This structure describes the current state of the audio device. + */ +typedef struct audio_info { + /* + * Per-stream information + */ + audio_prinfo_t play; /* output status information */ + audio_prinfo_t record; /* input status information */ + + /* + * Per-unit/channel information + */ + unsigned int monitor_gain; /* input to output mix: 0 - 255 */ + unsigned char output_muted; /* non-zero if output is muted */ + unsigned char _xxx[3]; /* Reserved for future use */ + unsigned int _yyy[3]; /* Reserved for future use */ +} audio_info_t; + + +/* + * Audio encoding types + */ +#define AUDIO_ENCODING_NONE (0) /* no encoding assigned */ +#define AUDIO_ENCODING_ULAW (1) /* u-law encoding */ +#define AUDIO_ENCODING_ALAW (2) /* A-law encoding */ +#define AUDIO_ENCODING_LINEAR (3) /* Linear PCM encoding */ +#define AUDIO_ENCODING_FLOAT (4) /* IEEE float (-1. <-> +1.) */ +#define AUDIO_ENCODING_DVI (104) /* DVI ADPCM */ +#define AUDIO_ENCODING_LINEAR8 (105) /* 8 bit UNSIGNED */ +#define AUDIO_ENCODING_LINEARLE (106) /* Linear PCM LE encoding */ + +/* + * These ranges apply to record, play, and monitor gain values + */ +#define AUDIO_MIN_GAIN (0) /* minimum gain value */ +#define AUDIO_MAX_GAIN (255) /* maximum gain value */ + +/* + * These values apply to the balance field to adjust channel gain values + */ +#define AUDIO_LEFT_BALANCE (0) /* left channel only */ +#define AUDIO_MID_BALANCE (32) /* equal left/right channel */ +#define AUDIO_RIGHT_BALANCE (64) /* right channel only */ +#define AUDIO_BALANCE_SHIFT (3) + +/* + * Generic minimum/maximum limits for number of channels, both modes + */ +#define AUDIO_MIN_PLAY_CHANNELS (1) +#define AUDIO_MAX_PLAY_CHANNELS (4) +#define AUDIO_MIN_REC_CHANNELS (1) +#define AUDIO_MAX_REC_CHANNELS (4) + +/* + * Generic minimum/maximum limits for sample precision + */ +#define AUDIO_MIN_PLAY_PRECISION (8) +#define AUDIO_MAX_PLAY_PRECISION (32) +#define AUDIO_MIN_REC_PRECISION (8) +#define AUDIO_MAX_REC_PRECISION (32) + +/* + * Define some convenient names for typical audio ports + */ +/* + * output ports (several may be enabled simultaneously) + */ +#define AUDIO_SPEAKER 0x01 /* output to built-in speaker */ +#define AUDIO_HEADPHONE 0x02 /* output to headphone jack */ +#define AUDIO_LINE_OUT 0x04 /* output to line out */ + +/* + * input ports (usually only one at a time) + */ +#define AUDIO_MICROPHONE 0x01 /* input from microphone */ +#define AUDIO_LINE_IN 0x02 /* input from line in */ +#define AUDIO_CD 0x04 /* input from on-board CD inputs */ +#define AUDIO_INTERNAL_CD_IN AUDIO_CD /* input from internal CDROM */ +#define AUDIO_ANALOG_LOOPBACK 0x40 /* input from output */ + + +/* + * This macro initializes an audio_info structure to 'harmless' values. + * Note that (~0) might not be a harmless value for a flag that was + * a signed int. + */ +#define AUDIO_INITINFO(i) { \ + unsigned int *__x__; \ + for (__x__ = (unsigned int *)(i); \ + (char *) __x__ < (((char *)(i)) + sizeof (audio_info_t)); \ + *__x__++ = ~0); \ +} + +/* + * These allow testing for what the user wants to set + */ +#define AUD_INITVALUE (~0) +#define Modify(X) ((unsigned int)(X) != AUD_INITVALUE) +#define Modifys(X) ((X) != (unsigned short)AUD_INITVALUE) +#define Modifyc(X) ((X) != (unsigned char)AUD_INITVALUE) + +/* + * Parameter for the AUDIO_GETDEV ioctl to determine current + * audio devices. + */ +#define MAX_AUDIO_DEV_LEN (16) +typedef struct audio_device { + char name[MAX_AUDIO_DEV_LEN]; + char version[MAX_AUDIO_DEV_LEN]; + char config[MAX_AUDIO_DEV_LEN]; +} audio_device_t; + + +/* + * Ioctl calls for the audio device. + */ + +/* + * AUDIO_GETINFO retrieves the current state of the audio device. + * + * AUDIO_SETINFO copies all fields of the audio_info structure whose + * values are not set to the initialized value (-1) to the device state. + * It performs an implicit AUDIO_GETINFO to return the new state of the + * device. Note that the record.samples and play.samples fields are set + * to the last value before the AUDIO_SETINFO took effect. This allows + * an application to reset the counters while atomically retrieving the + * last value. + * + * AUDIO_DRAIN suspends the calling process until the write buffers are + * empty. + * + * AUDIO_GETDEV returns a structure of type audio_device_t which contains + * three strings. The string "name" is a short identifying string (for + * example, the SBus Fcode name string), the string "version" identifies + * the current version of the device, and the "config" string identifies + * the specific configuration of the audio stream. All fields are + * device-dependent -- see the device specific manual pages for details. + * + * AUDIO_GETDEV_SUNOS returns a number which is an audio device defined + * herein (making it not too portable) + * + * AUDIO_FLUSH stops all playback and recording, clears all queued buffers, + * resets error counters, and restarts recording and playback as appropriate + * for the current sampling mode. + */ +#define AUDIO_GETINFO _IOR('A', 1, audio_info_t) +#define AUDIO_SETINFO _IOWR('A', 2, audio_info_t) +#define AUDIO_DRAIN _IO('A', 3) +#define AUDIO_GETDEV _IOR('A', 4, audio_device_t) +#define AUDIO_GETDEV_SUNOS _IOR('A', 4, int) +#define AUDIO_FLUSH _IO('A', 5) + +/* Define possible audio hardware configurations for + * old SunOS-style AUDIO_GETDEV ioctl */ +#define AUDIO_DEV_UNKNOWN (0) /* not defined */ +#define AUDIO_DEV_AMD (1) /* audioamd device */ +#define AUDIO_DEV_SPEAKERBOX (2) /* dbri device with speakerbox */ +#define AUDIO_DEV_CODEC (3) /* dbri device (internal speaker) */ +#define AUDIO_DEV_CS4231 (5) /* cs4231 device */ + +/* + * The following ioctl sets the audio device into an internal loopback mode, + * if the hardware supports this. The argument is TRUE to set loopback, + * FALSE to reset to normal operation. If the hardware does not support + * internal loopback, the ioctl should fail with EINVAL. + * Causes ADC data to be digitally mixed in and sent to the DAC. + */ +#define AUDIO_DIAG_LOOPBACK _IOW('A', 101, int) + +#endif /* _AUDIOIO_H_ */ diff --git a/include/asm-sparc64/auxio.h b/include/asm-sparc64/auxio.h new file mode 100644 index 000000000000..5eb01dd47150 --- /dev/null +++ b/include/asm-sparc64/auxio.h @@ -0,0 +1,98 @@ +/* $Id: auxio.h,v 1.3 2001/06/05 08:16:34 davem Exp $ + * auxio.h: Definitions and code for the Auxiliary I/O registers. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * + * Refactoring for unified NCR/PCIO support 2002 Eric Brower (ebrower@usa.net) + */ +#ifndef _SPARC64_AUXIO_H +#define _SPARC64_AUXIO_H + +/* AUXIO implementations: + * sbus-based NCR89C105 "Slavio" + * LED/Floppy (AUX1) register + * Power (AUX2) register + * + * ebus-based auxio on PCIO + * LED Auxio Register + * Power Auxio Register + * + * Register definitions from NCR _NCR89C105 Chip Specification_ + * + * SLAVIO AUX1 @ 0x1900000 + * ------------------------------------------------- + * | (R) | (R) | D | (R) | E | M | T | L | + * ------------------------------------------------- + * (R) - bit 7:6,4 are reserved and should be masked in s/w + * D - Floppy Density Sense (1=high density) R/O + * E - Link Test Enable, directly reflected on AT&T 7213 LTE pin + * M - Monitor/Mouse Mux, directly reflected on MON_MSE_MUX pin + * T - Terminal Count: sends TC pulse to 82077 floppy controller + * L - System LED on front panel (0=off, 1=on) + */ +#define AUXIO_AUX1_MASK 0xc0 /* Mask bits */ +#define AUXIO_AUX1_FDENS 0x20 /* Floppy Density Sense */ +#define AUXIO_AUX1_LTE 0x08 /* Link Test Enable */ +#define AUXIO_AUX1_MMUX 0x04 /* Monitor/Mouse Mux */ +#define AUXIO_AUX1_FTCNT 0x02 /* Terminal Count, */ +#define AUXIO_AUX1_LED 0x01 /* System LED */ + +/* SLAVIO AUX2 @ 0x1910000 + * ------------------------------------------------- + * | (R) | (R) | D | (R) | (R) | (R) | C | F | + * ------------------------------------------------- + * (R) - bits 7:6,4:2 are reserved and should be masked in s/w + * D - Power Failure Detect (1=power fail) + * C - Clear Power Failure Detect Int (1=clear) + * F - Power Off (1=power off) + */ +#define AUXIO_AUX2_MASK 0xdc /* Mask Bits */ +#define AUXIO_AUX2_PFAILDET 0x20 /* Power Fail Detect */ +#define AUXIO_AUX2_PFAILCLR 0x02 /* Clear Pwr Fail Det Intr */ +#define AUXIO_AUX2_PWR_OFF 0x01 /* Power Off */ + +/* Register definitions from Sun Microsystems _PCIO_ p/n 802-7837 + * + * PCIO LED Auxio @ 0x726000 + * ------------------------------------------------- + * | 31:1 Unused | LED | + * ------------------------------------------------- + * Bits 31:1 unused + * LED - System LED on front panel (0=off, 1=on) + */ +#define AUXIO_PCIO_LED 0x01 /* System LED */ + +/* PCIO Power Auxio @ 0x724000 + * ------------------------------------------------- + * | 31:2 Unused | CPO | SPO | + * ------------------------------------------------- + * Bits 31:2 unused + * CPO - Courtesy Power Off (1=off) + * SPO - System Power Off (1=off) + */ +#define AUXIO_PCIO_CPWR_OFF 0x02 /* Courtesy Power Off */ +#define AUXIO_PCIO_SPWR_OFF 0x01 /* System Power Off */ + +#ifndef __ASSEMBLY__ + +#define AUXIO_LTE_ON 1 +#define AUXIO_LTE_OFF 0 + +/* auxio_set_lte - Set Link Test Enable (TPE Link Detect) + * + * on - AUXIO_LTE_ON or AUXIO_LTE_OFF + */ +extern void auxio_set_lte(int on); + +#define AUXIO_LED_ON 1 +#define AUXIO_LED_OFF 0 + +/* auxio_set_led - Set system front panel LED + * + * on - AUXIO_LED_ON or AUXIO_LED_OFF + */ +extern void auxio_set_led(int on); + +#endif /* ifndef __ASSEMBLY__ */ + +#endif /* !(_SPARC64_AUXIO_H) */ diff --git a/include/asm-sparc64/bbc.h b/include/asm-sparc64/bbc.h new file mode 100644 index 000000000000..368fce4eedba --- /dev/null +++ b/include/asm-sparc64/bbc.h @@ -0,0 +1,225 @@ +/* $Id: bbc.h,v 1.2 2001/03/26 23:47:18 davem Exp $ + * bbc.h: Defines for BootBus Controller found on UltraSPARC-III + * systems. + * + * Copyright (C) 2000 David S. Miller (davem@redhat.com) + */ + +#ifndef _SPARC64_BBC_H +#define _SPARC64_BBC_H + +/* Register sizes are indicated by "B" (Byte, 1-byte), + * "H" (Half-word, 2 bytes), "W" (Word, 4 bytes) or + * "Q" (Quad, 8 bytes) inside brackets. + */ + +#define BBC_AID 0x00 /* [B] Agent ID */ +#define BBC_DEVP 0x01 /* [B] Device Present */ +#define BBC_ARB 0x02 /* [B] Arbitration */ +#define BBC_QUIESCE 0x03 /* [B] Quiesce */ +#define BBC_WDACTION 0x04 /* [B] Watchdog Action */ +#define BBC_SPG 0x06 /* [B] Soft POR Gen */ +#define BBC_SXG 0x07 /* [B] Soft XIR Gen */ +#define BBC_PSRC 0x08 /* [W] POR Source */ +#define BBC_XSRC 0x0c /* [B] XIR Source */ +#define BBC_CSC 0x0d /* [B] Clock Synthesizers Control*/ +#define BBC_ES_CTRL 0x0e /* [H] Energy Star Control */ +#define BBC_ES_ACT 0x10 /* [W] E* Assert Change Time */ +#define BBC_ES_DACT 0x14 /* [B] E* De-Assert Change Time */ +#define BBC_ES_DABT 0x15 /* [B] E* De-Assert Bypass Time */ +#define BBC_ES_ABT 0x16 /* [H] E* Assert Bypass Time */ +#define BBC_ES_PST 0x18 /* [W] E* PLL Settle Time */ +#define BBC_ES_FSL 0x1c /* [W] E* Frequency Switch Latency*/ +#define BBC_EBUST 0x20 /* [Q] EBUS Timing */ +#define BBC_JTAG_CMD 0x28 /* [W] JTAG+ Command */ +#define BBC_JTAG_CTRL 0x2c /* [B] JTAG+ Control */ +#define BBC_I2C_SEL 0x2d /* [B] I2C Selection */ +#define BBC_I2C_0_S1 0x2e /* [B] I2C ctrlr-0 reg S1 */ +#define BBC_I2C_0_S0 0x2f /* [B] I2C ctrlr-0 regs S0,S0',S2,S3*/ +#define BBC_I2C_1_S1 0x30 /* [B] I2C ctrlr-1 reg S1 */ +#define BBC_I2C_1_S0 0x31 /* [B] I2C ctrlr-1 regs S0,S0',S2,S3*/ +#define BBC_KBD_BEEP 0x32 /* [B] Keyboard Beep */ +#define BBC_KBD_BCNT 0x34 /* [W] Keyboard Beep Counter */ + +#define BBC_REGS_SIZE 0x40 + +/* There is a 2K scratch ram area at offset 0x80000 but I doubt + * we will use it for anything. + */ + +/* Agent ID register. This register shows the Safari Agent ID + * for the processors. The value returned depends upon which + * cpu is reading the register. + */ +#define BBC_AID_ID 0x07 /* Safari ID */ +#define BBC_AID_RESV 0xf8 /* Reserved */ + +/* Device Present register. One can determine which cpus are actually + * present in the machine by interrogating this register. + */ +#define BBC_DEVP_CPU0 0x01 /* Processor 0 present */ +#define BBC_DEVP_CPU1 0x02 /* Processor 1 present */ +#define BBC_DEVP_CPU2 0x04 /* Processor 2 present */ +#define BBC_DEVP_CPU3 0x08 /* Processor 3 present */ +#define BBC_DEVP_RESV 0xf0 /* Reserved */ + +/* Arbitration register. This register is used to block access to + * the BBC from a particular cpu. + */ +#define BBC_ARB_CPU0 0x01 /* Enable cpu 0 BBC arbitratrion */ +#define BBC_ARB_CPU1 0x02 /* Enable cpu 1 BBC arbitratrion */ +#define BBC_ARB_CPU2 0x04 /* Enable cpu 2 BBC arbitratrion */ +#define BBC_ARB_CPU3 0x08 /* Enable cpu 3 BBC arbitratrion */ +#define BBC_ARB_RESV 0xf0 /* Reserved */ + +/* Quiesce register. Bus and BBC segments for cpus can be disabled + * with this register, ie. for hot plugging. + */ +#define BBC_QUIESCE_S02 0x01 /* Quiesce Safari segment for cpu 0 and 2 */ +#define BBC_QUIESCE_S13 0x02 /* Quiesce Safari segment for cpu 1 and 3 */ +#define BBC_QUIESCE_B02 0x04 /* Quiesce BBC segment for cpu 0 and 2 */ +#define BBC_QUIESCE_B13 0x08 /* Quiesce BBC segment for cpu 1 and 3 */ +#define BBC_QUIESCE_FD0 0x10 /* Disable Fatal_Error[0] reporting */ +#define BBC_QUIESCE_FD1 0x20 /* Disable Fatal_Error[1] reporting */ +#define BBC_QUIESCE_FD2 0x40 /* Disable Fatal_Error[2] reporting */ +#define BBC_QUIESCE_FD3 0x80 /* Disable Fatal_Error[3] reporting */ + +/* Watchdog Action register. When the watchdog device timer expires + * a line is enabled to the BBC. The action BBC takes when this line + * is asserted can be controlled by this regiser. + */ +#define BBC_WDACTION_RST 0x01 /* When set, watchdog causes system reset. + * When clear, BBC ignores watchdog signal. + */ +#define BBC_WDACTION_RESV 0xfe /* Reserved */ + +/* Soft_POR_GEN register. The POR (Power On Reset) signal may be asserted + * for specific processors or all processors via this register. + */ +#define BBC_SPG_CPU0 0x01 /* Assert POR for processor 0 */ +#define BBC_SPG_CPU1 0x02 /* Assert POR for processor 1 */ +#define BBC_SPG_CPU2 0x04 /* Assert POR for processor 2 */ +#define BBC_SPG_CPU3 0x08 /* Assert POR for processor 3 */ +#define BBC_SPG_CPUALL 0x10 /* Reset all processors and reset + * the entire system. + */ +#define BBC_SPG_RESV 0xe0 /* Reserved */ + +/* Soft_XIR_GEN register. The XIR (eXternally Initiated Reset) signal + * may be asserted to specific processors via this register. + */ +#define BBC_SXG_CPU0 0x01 /* Assert XIR for processor 0 */ +#define BBC_SXG_CPU1 0x02 /* Assert XIR for processor 1 */ +#define BBC_SXG_CPU2 0x04 /* Assert XIR for processor 2 */ +#define BBC_SXG_CPU3 0x08 /* Assert XIR for processor 3 */ +#define BBC_SXG_RESV 0xf0 /* Reserved */ + +/* POR Source register. One may identify the cause of the most recent + * reset by reading this register. + */ +#define BBC_PSRC_SPG0 0x0001 /* CPU 0 reset via BBC_SPG register */ +#define BBC_PSRC_SPG1 0x0002 /* CPU 1 reset via BBC_SPG register */ +#define BBC_PSRC_SPG2 0x0004 /* CPU 2 reset via BBC_SPG register */ +#define BBC_PSRC_SPG3 0x0008 /* CPU 3 reset via BBC_SPG register */ +#define BBC_PSRC_SPGSYS 0x0010 /* System reset via BBC_SPG register */ +#define BBC_PSRC_JTAG 0x0020 /* System reset via JTAG+ */ +#define BBC_PSRC_BUTTON 0x0040 /* System reset via push-button dongle */ +#define BBC_PSRC_PWRUP 0x0080 /* System reset via power-up */ +#define BBC_PSRC_FE0 0x0100 /* CPU 0 reported Fatal_Error */ +#define BBC_PSRC_FE1 0x0200 /* CPU 1 reported Fatal_Error */ +#define BBC_PSRC_FE2 0x0400 /* CPU 2 reported Fatal_Error */ +#define BBC_PSRC_FE3 0x0800 /* CPU 3 reported Fatal_Error */ +#define BBC_PSRC_FE4 0x1000 /* Schizo reported Fatal_Error */ +#define BBC_PSRC_FE5 0x2000 /* Safari device 5 reported Fatal_Error */ +#define BBC_PSRC_FE6 0x4000 /* CPMS reported Fatal_Error */ +#define BBC_PSRC_SYNTH 0x8000 /* System reset when on-board clock synthesizers + * were updated. + */ +#define BBC_PSRC_WDT 0x10000 /* System reset via Super I/O watchdog */ +#define BBC_PSRC_RSC 0x20000 /* System reset via RSC remote monitoring + * device + */ + +/* XIR Source register. The source of an XIR event sent to a processor may + * be determined via this register. + */ +#define BBC_XSRC_SXG0 0x01 /* CPU 0 received XIR via Soft_XIR_GEN reg */ +#define BBC_XSRC_SXG1 0x02 /* CPU 1 received XIR via Soft_XIR_GEN reg */ +#define BBC_XSRC_SXG2 0x04 /* CPU 2 received XIR via Soft_XIR_GEN reg */ +#define BBC_XSRC_SXG3 0x08 /* CPU 3 received XIR via Soft_XIR_GEN reg */ +#define BBC_XSRC_JTAG 0x10 /* All CPUs received XIR via JTAG+ */ +#define BBC_XSRC_W_OR_B 0x20 /* All CPUs received XIR either because: + * a) Super I/O watchdog fired, or + * b) XIR push button was activated + */ +#define BBC_XSRC_RESV 0xc0 /* Reserved */ + +/* Clock Synthesizers Control register. This register provides the big-bang + * programming interface to the two clock synthesizers of the machine. + */ +#define BBC_CSC_SLOAD 0x01 /* Directly connected to S_LOAD pins */ +#define BBC_CSC_SDATA 0x02 /* Directly connected to S_DATA pins */ +#define BBC_CSC_SCLOCK 0x04 /* Directly connected to S_CLOCK pins */ +#define BBC_CSC_RESV 0x78 /* Reserved */ +#define BBC_CSC_RST 0x80 /* Generate system reset when S_LOAD==1 */ + +/* Energy Star Control register. This register is used to generate the + * clock frequency change trigger to the main system devices (Schizo and + * the processors). The transition occurs when bits in this register + * go from 0 to 1, only one bit must be set at once else no action + * occurs. Basically the sequence of events is: + * a) Choose new frequency: full, 1/2 or 1/32 + * b) Program this desired frequency into the cpus and Schizo. + * c) Set the same value in this register. + * d) 16 system clocks later, clear this register. + */ +#define BBC_ES_CTRL_1_1 0x01 /* Full frequency */ +#define BBC_ES_CTRL_1_2 0x02 /* 1/2 frequency */ +#define BBC_ES_CTRL_1_32 0x20 /* 1/32 frequency */ +#define BBC_ES_RESV 0xdc /* Reserved */ + +/* Energy Star Assert Change Time register. This determines the number + * of BBC clock cycles (which is half the system frequency) between + * the detection of FREEZE_ACK being asserted and the assertion of + * the CLK_CHANGE_L[2:0] signals. + */ +#define BBC_ES_ACT_VAL 0xff + +/* Energy Star Assert Bypass Time register. This determines the number + * of BBC clock cycles (which is half the system frequency) between + * the assertion of the CLK_CHANGE_L[2:0] signals and the assertion of + * the ESTAR_PLL_BYPASS signal. + */ +#define BBC_ES_ABT_VAL 0xffff + +/* Energy Star PLL Settle Time register. This determines the number of + * BBC clock cycles (which is half the system frequency) between the + * de-assertion of CLK_CHANGE_L[2:0] and the de-assertion of the FREEZE_L + * signal. + */ +#define BBC_ES_PST_VAL 0xffffffff + +/* Energy Star Frequency Switch Latency register. This is the number of + * BBC clocks between the de-assertion of CLK_CHANGE_L[2:0] and the first + * edge of the Safari clock at the new frequency. + */ +#define BBC_ES_FSL_VAL 0xffffffff + +/* Keyboard Beep control register. This is a simple enabler for the audio + * beep sound. + */ +#define BBC_KBD_BEEP_ENABLE 0x01 /* Enable beep */ +#define BBC_KBD_BEEP_RESV 0xfe /* Reserved */ + +/* Keyboard Beep Counter register. There is a free-running counter inside + * the BBC which runs at half the system clock. The bit set in this register + * determines when the audio sound is generated. So for example if bit + * 10 is set, the audio beep will oscillate at 1/(2**12). The keyboard beep + * generator automatically selects a different bit to use if the system clock + * is changed via Energy Star. + */ +#define BBC_KBD_BCNT_BITS 0x0007fc00 +#define BBC_KBC_BCNT_RESV 0xfff803ff + +#endif /* _SPARC64_BBC_H */ + diff --git a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h new file mode 100644 index 000000000000..9d722dc8cca3 --- /dev/null +++ b/include/asm-sparc64/bitops.h @@ -0,0 +1,294 @@ +/* $Id: bitops.h,v 1.39 2002/01/30 01:40:00 davem Exp $ + * bitops.h: Bit string operations on the V9. + * + * Copyright 1996, 1997 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC64_BITOPS_H +#define _SPARC64_BITOPS_H + +#include <linux/config.h> +#include <linux/compiler.h> +#include <asm/byteorder.h> + +extern int test_and_set_bit(unsigned long nr, volatile unsigned long *addr); +extern int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr); +extern int test_and_change_bit(unsigned long nr, volatile unsigned long *addr); +extern void set_bit(unsigned long nr, volatile unsigned long *addr); +extern void clear_bit(unsigned long nr, volatile unsigned long *addr); +extern void change_bit(unsigned long nr, volatile unsigned long *addr); + +/* "non-atomic" versions... */ + +static __inline__ void __set_bit(int nr, volatile unsigned long *addr) +{ + volatile unsigned long *m = addr + (nr >> 6); + + *m |= (1UL << (nr & 63)); +} + +static __inline__ void __clear_bit(int nr, volatile unsigned long *addr) +{ + volatile unsigned long *m = addr + (nr >> 6); + + *m &= ~(1UL << (nr & 63)); +} + +static __inline__ void __change_bit(int nr, volatile unsigned long *addr) +{ + volatile unsigned long *m = addr + (nr >> 6); + + *m ^= (1UL << (nr & 63)); +} + +static __inline__ int __test_and_set_bit(int nr, volatile unsigned long *addr) +{ + volatile unsigned long *m = addr + (nr >> 6); + long old = *m; + long mask = (1UL << (nr & 63)); + + *m = (old | mask); + return ((old & mask) != 0); +} + +static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long *addr) +{ + volatile unsigned long *m = addr + (nr >> 6); + long old = *m; + long mask = (1UL << (nr & 63)); + + *m = (old & ~mask); + return ((old & mask) != 0); +} + +static __inline__ int __test_and_change_bit(int nr, volatile unsigned long *addr) +{ + volatile unsigned long *m = addr + (nr >> 6); + long old = *m; + long mask = (1UL << (nr & 63)); + + *m = (old ^ mask); + return ((old & mask) != 0); +} + +#ifdef CONFIG_SMP +#define smp_mb__before_clear_bit() membar("#StoreLoad | #LoadLoad") +#define smp_mb__after_clear_bit() membar("#StoreLoad | #StoreStore") +#else +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() +#endif + +static __inline__ int test_bit(int nr, __const__ volatile unsigned long *addr) +{ + return (1UL & ((addr)[nr >> 6] >> (nr & 63))) != 0UL; +} + +/* The easy/cheese version for now. */ +static __inline__ unsigned long ffz(unsigned long word) +{ + unsigned long result; + + result = 0; + while(word & 1) { + result++; + word >>= 1; + } + return result; +} + +/** + * __ffs - find first bit in word. + * @word: The word to search + * + * Undefined if no bit exists, so code should check against 0 first. + */ +static __inline__ unsigned long __ffs(unsigned long word) +{ + unsigned long result = 0; + + while (!(word & 1UL)) { + result++; + word >>= 1; + } + return result; +} + +/* + * fls: find last bit set. + */ + +#define fls(x) generic_fls(x) + +#ifdef __KERNEL__ + +/* + * Every architecture must define this function. It's the fastest + * way of searching a 140-bit bitmap where the first 100 bits are + * unlikely to be set. It's guaranteed that at least one of the 140 + * bits is cleared. + */ +static inline int sched_find_first_bit(unsigned long *b) +{ + if (unlikely(b[0])) + return __ffs(b[0]); + if (unlikely(((unsigned int)b[1]))) + return __ffs(b[1]) + 64; + if (b[1] >> 32) + return __ffs(b[1] >> 32) + 96; + return __ffs(b[2]) + 128; +} + +/* + * ffs: find first bit set. This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ +static __inline__ int ffs(int x) +{ + if (!x) + return 0; + return __ffs((unsigned long)x) + 1; +} + +/* + * hweightN: returns the hamming weight (i.e. the number + * of bits set) of a N-bit word + */ + +#ifdef ULTRA_HAS_POPULATION_COUNT + +static __inline__ unsigned int hweight64(unsigned long w) +{ + unsigned int res; + + __asm__ ("popc %1,%0" : "=r" (res) : "r" (w)); + return res; +} + +static __inline__ unsigned int hweight32(unsigned int w) +{ + unsigned int res; + + __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffffffff)); + return res; +} + +static __inline__ unsigned int hweight16(unsigned int w) +{ + unsigned int res; + + __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffff)); + return res; +} + +static __inline__ unsigned int hweight8(unsigned int w) +{ + unsigned int res; + + __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xff)); + return res; +} + +#else + +#define hweight64(x) generic_hweight64(x) +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +#endif +#endif /* __KERNEL__ */ + +/** + * find_next_bit - find the next set bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +extern unsigned long find_next_bit(const unsigned long *, unsigned long, + unsigned long); + +/** + * find_first_bit - find the first set bit in a memory region + * @addr: The address to start the search at + * @size: The maximum size to search + * + * Returns the bit-number of the first set bit, not the number of the byte + * containing a bit. + */ +#define find_first_bit(addr, size) \ + find_next_bit((addr), (size), 0) + +/* find_next_zero_bit() finds the first zero bit in a bit string of length + * 'size' bits, starting the search at bit 'offset'. This is largely based + * on Linus's ALPHA routines, which are pretty portable BTW. + */ + +extern unsigned long find_next_zero_bit(const unsigned long *, + unsigned long, unsigned long); + +#define find_first_zero_bit(addr, size) \ + find_next_zero_bit((addr), (size), 0) + +#define test_and_set_le_bit(nr,addr) \ + test_and_set_bit((nr) ^ 0x38, (addr)) +#define test_and_clear_le_bit(nr,addr) \ + test_and_clear_bit((nr) ^ 0x38, (addr)) + +static __inline__ int test_le_bit(int nr, __const__ unsigned long * addr) +{ + int mask; + __const__ unsigned char *ADDR = (__const__ unsigned char *) addr; + + ADDR += nr >> 3; + mask = 1 << (nr & 0x07); + return ((mask & *ADDR) != 0); +} + +#define find_first_zero_le_bit(addr, size) \ + find_next_zero_le_bit((addr), (size), 0) + +extern unsigned long find_next_zero_le_bit(unsigned long *, unsigned long, unsigned long); + +#ifdef __KERNEL__ + +#define __set_le_bit(nr, addr) \ + __set_bit((nr) ^ 0x38, (addr)) +#define __clear_le_bit(nr, addr) \ + __clear_bit((nr) ^ 0x38, (addr)) +#define __test_and_clear_le_bit(nr, addr) \ + __test_and_clear_bit((nr) ^ 0x38, (addr)) +#define __test_and_set_le_bit(nr, addr) \ + __test_and_set_bit((nr) ^ 0x38, (addr)) + +#define ext2_set_bit(nr,addr) \ + __test_and_set_le_bit((nr),(unsigned long *)(addr)) +#define ext2_set_bit_atomic(lock,nr,addr) \ + test_and_set_le_bit((nr),(unsigned long *)(addr)) +#define ext2_clear_bit(nr,addr) \ + __test_and_clear_le_bit((nr),(unsigned long *)(addr)) +#define ext2_clear_bit_atomic(lock,nr,addr) \ + test_and_clear_le_bit((nr),(unsigned long *)(addr)) +#define ext2_test_bit(nr,addr) \ + test_le_bit((nr),(unsigned long *)(addr)) +#define ext2_find_first_zero_bit(addr, size) \ + find_first_zero_le_bit((unsigned long *)(addr), (size)) +#define ext2_find_next_zero_bit(addr, size, off) \ + find_next_zero_le_bit((unsigned long *)(addr), (size), (off)) + +/* Bitmap functions for the minix filesystem. */ +#define minix_test_and_set_bit(nr,addr) \ + test_and_set_bit((nr),(unsigned long *)(addr)) +#define minix_set_bit(nr,addr) \ + set_bit((nr),(unsigned long *)(addr)) +#define minix_test_and_clear_bit(nr,addr) \ + test_and_clear_bit((nr),(unsigned long *)(addr)) +#define minix_test_bit(nr,addr) \ + test_bit((nr),(unsigned long *)(addr)) +#define minix_find_first_zero_bit(addr,size) \ + find_first_zero_bit((unsigned long *)(addr),(size)) + +#endif /* __KERNEL__ */ + +#endif /* defined(_SPARC64_BITOPS_H) */ diff --git a/include/asm-sparc64/bpp.h b/include/asm-sparc64/bpp.h new file mode 100644 index 000000000000..abe163a50382 --- /dev/null +++ b/include/asm-sparc64/bpp.h @@ -0,0 +1,73 @@ +#ifndef _SPARC64_BPP_H +#define _SPARC64_BPP_H + +/* + * Copyright (c) 1995 Picture Elements + * Stephen Williams + * Gus Baldauf + * + * Linux/SPARC port by Peter Zaitcev. + * Integration into SPARC tree by Tom Dyas. + */ + +#include <linux/ioctl.h> + +/* + * This is a driver that supports IEEE Std 1284-1994 communications + * with compliant or compatible devices. It will use whatever features + * the device supports, prefering those that are typically faster. + * + * When the device is opened, it is left in COMPATIBILITY mode, and + * writes work like any printer device. The driver only attempt to + * negotiate 1284 modes when needed so that plugs can be pulled, + * switch boxes switched, etc., without disrupting things. It will + * also leave the device in compatibility mode when closed. + */ + + + +/* + * This driver also supplies ioctls to manually manipulate the + * pins. This is great for testing devices, or writing code to deal + * with bizzarro-mode of the ACME Special TurboThingy Plus. + * + * NOTE: These ioctl currently do not interact well with + * read/write. Caveat emptor. + * + * PUT_PINS allows us to assign the sense of all the pins, including + * the data pins if being driven by the host. The GET_PINS returns the + * pins that the peripheral drives, including data if appropriate. + */ + +# define BPP_PUT_PINS _IOW('B', 1, int) +# define BPP_GET_PINS _IOR('B', 2, char) /* that's bogus - should've been _IO */ +# define BPP_PUT_DATA _IOW('B', 3, int) +# define BPP_GET_DATA _IOR('B', 4, char) /* ditto */ + +/* + * Set the data bus to input mode. Disengage the data bin driver and + * be prepared to read values from the peripheral. If the arg is 0, + * then revert the bus to output mode. + */ +# define BPP_SET_INPUT _IOW('B', 5, int) + +/* + * These bits apply to the PUT operation... + */ +# define BPP_PP_nStrobe 0x0001 +# define BPP_PP_nAutoFd 0x0002 +# define BPP_PP_nInit 0x0004 +# define BPP_PP_nSelectIn 0x0008 + +/* + * These apply to the GET operation, which also reads the current value + * of the previously put values. A bit mask of these will be returned + * as a bit mask in the return code of the ioctl(). + */ +# define BPP_GP_nAck 0x0100 +# define BPP_GP_Busy 0x0200 +# define BPP_GP_PError 0x0400 +# define BPP_GP_Select 0x0800 +# define BPP_GP_nFault 0x1000 + +#endif diff --git a/include/asm-sparc64/bsderrno.h b/include/asm-sparc64/bsderrno.h new file mode 100644 index 000000000000..52fe880d2af8 --- /dev/null +++ b/include/asm-sparc64/bsderrno.h @@ -0,0 +1,94 @@ +/* $Id: bsderrno.h,v 1.1 1996/12/26 13:25:21 davem Exp $ + * bsderrno.h: Error numbers for NetBSD binary compatibility + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC64_BSDERRNO_H +#define _SPARC64_BSDERRNO_H + +#define BSD_EPERM 1 /* Operation not permitted */ +#define BSD_ENOENT 2 /* No such file or directory */ +#define BSD_ESRCH 3 /* No such process */ +#define BSD_EINTR 4 /* Interrupted system call */ +#define BSD_EIO 5 /* Input/output error */ +#define BSD_ENXIO 6 /* Device not configured */ +#define BSD_E2BIG 7 /* Argument list too long */ +#define BSD_ENOEXEC 8 /* Exec format error */ +#define BSD_EBADF 9 /* Bad file descriptor */ +#define BSD_ECHILD 10 /* No child processes */ +#define BSD_EDEADLK 11 /* Resource deadlock avoided */ +#define BSD_ENOMEM 12 /* Cannot allocate memory */ +#define BSD_EACCES 13 /* Permission denied */ +#define BSD_EFAULT 14 /* Bad address */ +#define BSD_ENOTBLK 15 /* Block device required */ +#define BSD_EBUSY 16 /* Device busy */ +#define BSD_EEXIST 17 /* File exists */ +#define BSD_EXDEV 18 /* Cross-device link */ +#define BSD_ENODEV 19 /* Operation not supported by device */ +#define BSD_ENOTDIR 20 /* Not a directory */ +#define BSD_EISDIR 21 /* Is a directory */ +#define BSD_EINVAL 22 /* Invalid argument */ +#define BSD_ENFILE 23 /* Too many open files in system */ +#define BSD_EMFILE 24 /* Too many open files */ +#define BSD_ENOTTY 25 /* Inappropriate ioctl for device */ +#define BSD_ETXTBSY 26 /* Text file busy */ +#define BSD_EFBIG 27 /* File too large */ +#define BSD_ENOSPC 28 /* No space left on device */ +#define BSD_ESPIPE 29 /* Illegal seek */ +#define BSD_EROFS 30 /* Read-only file system */ +#define BSD_EMLINK 31 /* Too many links */ +#define BSD_EPIPE 32 /* Broken pipe */ +#define BSD_EDOM 33 /* Numerical argument out of domain */ +#define BSD_ERANGE 34 /* Result too large */ +#define BSD_EAGAIN 35 /* Resource temporarily unavailable */ +#define BSD_EWOULDBLOCK EAGAIN /* Operation would block */ +#define BSD_EINPROGRESS 36 /* Operation now in progress */ +#define BSD_EALREADY 37 /* Operation already in progress */ +#define BSD_ENOTSOCK 38 /* Socket operation on non-socket */ +#define BSD_EDESTADDRREQ 39 /* Destination address required */ +#define BSD_EMSGSIZE 40 /* Message too long */ +#define BSD_EPROTOTYPE 41 /* Protocol wrong type for socket */ +#define BSD_ENOPROTOOPT 42 /* Protocol not available */ +#define BSD_EPROTONOSUPPORT 43 /* Protocol not supported */ +#define BSD_ESOCKTNOSUPPORT 44 /* Socket type not supported */ +#define BSD_EOPNOTSUPP 45 /* Operation not supported */ +#define BSD_EPFNOSUPPORT 46 /* Protocol family not supported */ +#define BSD_EAFNOSUPPORT 47 /* Address family not supported by protocol family */ +#define BSD_EADDRINUSE 48 /* Address already in use */ +#define BSD_EADDRNOTAVAIL 49 /* Can't assign requested address */ +#define BSD_ENETDOWN 50 /* Network is down */ +#define BSD_ENETUNREACH 51 /* Network is unreachable */ +#define BSD_ENETRESET 52 /* Network dropped connection on reset */ +#define BSD_ECONNABORTED 53 /* Software caused connection abort */ +#define BSD_ECONNRESET 54 /* Connection reset by peer */ +#define BSD_ENOBUFS 55 /* No buffer space available */ +#define BSD_EISCONN 56 /* Socket is already connected */ +#define BSD_ENOTCONN 57 /* Socket is not connected */ +#define BSD_ESHUTDOWN 58 /* Can't send after socket shutdown */ +#define BSD_ETOOMANYREFS 59 /* Too many references: can't splice */ +#define BSD_ETIMEDOUT 60 /* Operation timed out */ +#define BSD_ECONNREFUSED 61 /* Connection refused */ +#define BSD_ELOOP 62 /* Too many levels of symbolic links */ +#define BSD_ENAMETOOLONG 63 /* File name too long */ +#define BSD_EHOSTDOWN 64 /* Host is down */ +#define BSD_EHOSTUNREACH 65 /* No route to host */ +#define BSD_ENOTEMPTY 66 /* Directory not empty */ +#define BSD_EPROCLIM 67 /* Too many processes */ +#define BSD_EUSERS 68 /* Too many users */ +#define BSD_EDQUOT 69 /* Disc quota exceeded */ +#define BSD_ESTALE 70 /* Stale NFS file handle */ +#define BSD_EREMOTE 71 /* Too many levels of remote in path */ +#define BSD_EBADRPC 72 /* RPC struct is bad */ +#define BSD_ERPCMISMATCH 73 /* RPC version wrong */ +#define BSD_EPROGUNAVAIL 74 /* RPC prog. not avail */ +#define BSD_EPROGMISMATCH 75 /* Program version wrong */ +#define BSD_EPROCUNAVAIL 76 /* Bad procedure for program */ +#define BSD_ENOLCK 77 /* No locks available */ +#define BSD_ENOSYS 78 /* Function not implemented */ +#define BSD_EFTYPE 79 /* Inappropriate file type or format */ +#define BSD_EAUTH 80 /* Authentication error */ +#define BSD_ENEEDAUTH 81 /* Need authenticator */ +#define BSD_ELAST 81 /* Must be equal largest errno */ + +#endif /* !(_SPARC64_BSDERRNO_H) */ diff --git a/include/asm-sparc64/bug.h b/include/asm-sparc64/bug.h new file mode 100644 index 000000000000..25c5b1dfe378 --- /dev/null +++ b/include/asm-sparc64/bug.h @@ -0,0 +1,19 @@ +#ifndef _SPARC64_BUG_H +#define _SPARC64_BUG_H + +#include <linux/compiler.h> + +#ifdef CONFIG_DEBUG_BUGVERBOSE +extern void do_BUG(const char *file, int line); +#define BUG() do { \ + do_BUG(__FILE__, __LINE__); \ + __builtin_trap(); \ +} while (0) +#else +#define BUG() __builtin_trap() +#endif + +#define HAVE_ARCH_BUG +#include <asm-generic/bug.h> + +#endif diff --git a/include/asm-sparc64/bugs.h b/include/asm-sparc64/bugs.h new file mode 100644 index 000000000000..360dd04ed8e4 --- /dev/null +++ b/include/asm-sparc64/bugs.h @@ -0,0 +1,16 @@ +/* $Id: bugs.h,v 1.1 1996/12/26 13:25:20 davem Exp $ + * include/asm-sparc64/bugs.h: Sparc probes for various bugs. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#include <linux/config.h> + +extern unsigned long loops_per_jiffy; + +static void __init check_bugs(void) +{ +#ifndef CONFIG_SMP + cpu_data(0).udelay_val = loops_per_jiffy; +#endif +} diff --git a/include/asm-sparc64/byteorder.h b/include/asm-sparc64/byteorder.h new file mode 100644 index 000000000000..c69b08af5fe0 --- /dev/null +++ b/include/asm-sparc64/byteorder.h @@ -0,0 +1,50 @@ +/* $Id: byteorder.h,v 1.8 1997/12/18 02:44:14 ecd Exp $ */ +#ifndef _SPARC64_BYTEORDER_H +#define _SPARC64_BYTEORDER_H + +#include <asm/types.h> +#include <asm/asi.h> + +#ifdef __GNUC__ + +static __inline__ __u16 ___arch__swab16p(const __u16 *addr) +{ + __u16 ret; + + __asm__ __volatile__ ("lduha [%1] %2, %0" + : "=r" (ret) + : "r" (addr), "i" (ASI_PL)); + return ret; +} + +static __inline__ __u32 ___arch__swab32p(const __u32 *addr) +{ + __u32 ret; + + __asm__ __volatile__ ("lduwa [%1] %2, %0" + : "=r" (ret) + : "r" (addr), "i" (ASI_PL)); + return ret; +} + +static __inline__ __u64 ___arch__swab64p(const __u64 *addr) +{ + __u64 ret; + + __asm__ __volatile__ ("ldxa [%1] %2, %0" + : "=r" (ret) + : "r" (addr), "i" (ASI_PL)); + return ret; +} + +#define __arch__swab16p(x) ___arch__swab16p(x) +#define __arch__swab32p(x) ___arch__swab32p(x) +#define __arch__swab64p(x) ___arch__swab64p(x) + +#define __BYTEORDER_HAS_U64__ + +#endif /* __GNUC__ */ + +#include <linux/byteorder/big_endian.h> + +#endif /* _SPARC64_BYTEORDER_H */ diff --git a/include/asm-sparc64/cache.h b/include/asm-sparc64/cache.h new file mode 100644 index 000000000000..ade5ec3bfd5a --- /dev/null +++ b/include/asm-sparc64/cache.h @@ -0,0 +1,17 @@ +/* + * include/asm-sparc64/cache.h + */ +#ifndef __ARCH_SPARC64_CACHE_H +#define __ARCH_SPARC64_CACHE_H + +/* bytes per L1 cache line */ +#define L1_CACHE_SHIFT 5 +#define L1_CACHE_BYTES 32 /* Two 16-byte sub-blocks per line. */ + +#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)) +#define L1_CACHE_SHIFT_MAX 5 /* largest L1 which this arch supports */ + +#define SMP_CACHE_BYTES_SHIFT 6 +#define SMP_CACHE_BYTES (1 << SMP_CACHE_BYTES_SHIFT) /* L2 cache line size. */ + +#endif diff --git a/include/asm-sparc64/cacheflush.h b/include/asm-sparc64/cacheflush.h new file mode 100644 index 000000000000..86f02937ff1b --- /dev/null +++ b/include/asm-sparc64/cacheflush.h @@ -0,0 +1,72 @@ +#ifndef _SPARC64_CACHEFLUSH_H +#define _SPARC64_CACHEFLUSH_H + +#include <linux/config.h> +#include <asm/page.h> + +/* Flushing for D-cache alias handling is only needed if + * the page size is smaller than 16K. + */ +#if PAGE_SHIFT < 14 +#define DCACHE_ALIASING_POSSIBLE +#endif + +#ifndef __ASSEMBLY__ + +#include <linux/mm.h> + +/* Cache flush operations. */ + +/* These are the same regardless of whether this is an SMP kernel or not. */ +#define flush_cache_mm(__mm) \ + do { if ((__mm) == current->mm) flushw_user(); } while(0) +#define flush_cache_range(vma, start, end) \ + flush_cache_mm((vma)->vm_mm) +#define flush_cache_page(vma, page, pfn) \ + flush_cache_mm((vma)->vm_mm) + +/* + * On spitfire, the icache doesn't snoop local stores and we don't + * use block commit stores (which invalidate icache lines) during + * module load, so we need this. + */ +extern void flush_icache_range(unsigned long start, unsigned long end); +extern void __flush_icache_page(unsigned long); + +extern void __flush_dcache_page(void *addr, int flush_icache); +extern void flush_dcache_page_impl(struct page *page); +#ifdef CONFIG_SMP +extern void smp_flush_dcache_page_impl(struct page *page, int cpu); +extern void flush_dcache_page_all(struct mm_struct *mm, struct page *page); +#else +#define smp_flush_dcache_page_impl(page,cpu) flush_dcache_page_impl(page) +#define flush_dcache_page_all(mm,page) flush_dcache_page_impl(page) +#endif + +extern void __flush_dcache_range(unsigned long start, unsigned long end); +extern void flush_dcache_page(struct page *page); + +#define flush_icache_page(vma, pg) do { } while(0) +#define flush_icache_user_range(vma,pg,adr,len) do { } while (0) + +#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ + do { \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ + memcpy(dst, src, len); \ + } while (0) + +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ + do { \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ + memcpy(dst, src, len); \ + } while (0) + +#define flush_dcache_mmap_lock(mapping) do { } while (0) +#define flush_dcache_mmap_unlock(mapping) do { } while (0) + +#define flush_cache_vmap(start, end) do { } while (0) +#define flush_cache_vunmap(start, end) do { } while (0) + +#endif /* !__ASSEMBLY__ */ + +#endif /* _SPARC64_CACHEFLUSH_H */ diff --git a/include/asm-sparc64/chafsr.h b/include/asm-sparc64/chafsr.h new file mode 100644 index 000000000000..fd1688335ace --- /dev/null +++ b/include/asm-sparc64/chafsr.h @@ -0,0 +1,242 @@ +/* $Id: chafsr.h,v 1.1 2001/03/28 10:56:34 davem Exp $ */ +#ifndef _SPARC64_CHAFSR_H +#define _SPARC64_CHAFSR_H + +/* Cheetah Asynchronous Fault Status register, ASI=0x4C VA<63:0>=0x0 */ + +/* Comments indicate which processor variants on which the bit definition + * is valid. Codes are: + * ch --> cheetah + * ch+ --> cheetah plus + * jp --> jalapeno + */ + +/* All bits of this register except M_SYNDROME and E_SYNDROME are + * read, write 1 to clear. M_SYNDROME and E_SYNDROME are read-only. + */ + +/* Software bit set by linux trap handlers to indicate that the trap was + * signalled at %tl >= 1. + */ +#define CHAFSR_TL1 (1UL << 63UL) /* n/a */ + +/* Unmapped error from system bus for prefetch queue or + * store queue read operation + */ +#define CHPAFSR_DTO (1UL << 59UL) /* ch+ */ + +/* Bus error from system bus for prefetch queue or store queue + * read operation + */ +#define CHPAFSR_DBERR (1UL << 58UL) /* ch+ */ + +/* Hardware corrected E-cache Tag ECC error */ +#define CHPAFSR_THCE (1UL << 57UL) /* ch+ */ +/* System interface protocol error, hw timeout caused */ +#define JPAFSR_JETO (1UL << 57UL) /* jp */ + +/* SW handled correctable E-cache Tag ECC error */ +#define CHPAFSR_TSCE (1UL << 56UL) /* ch+ */ +/* Parity error on system snoop results */ +#define JPAFSR_SCE (1UL << 56UL) /* jp */ + +/* Uncorrectable E-cache Tag ECC error */ +#define CHPAFSR_TUE (1UL << 55UL) /* ch+ */ +/* System interface protocol error, illegal command detected */ +#define JPAFSR_JEIC (1UL << 55UL) /* jp */ + +/* Uncorrectable system bus data ECC error due to prefetch + * or store fill request + */ +#define CHPAFSR_DUE (1UL << 54UL) /* ch+ */ +/* System interface protocol error, illegal ADTYPE detected */ +#define JPAFSR_JEIT (1UL << 54UL) /* jp */ + +/* Multiple errors of the same type have occurred. This bit is set when + * an uncorrectable error or a SW correctable error occurs and the status + * bit to report that error is already set. When multiple errors of + * different types are indicated by setting multiple status bits. + * + * This bit is not set if multiple HW corrected errors with the same + * status bit occur, only uncorrectable and SW correctable ones have + * this behavior. + * + * This bit is not set when multiple ECC errors happen within a single + * 64-byte system bus transaction. Only the first ECC error in a 16-byte + * subunit will be logged. All errors in subsequent 16-byte subunits + * from the same 64-byte transaction are ignored. + */ +#define CHAFSR_ME (1UL << 53UL) /* ch,ch+,jp */ + +/* Privileged state error has occurred. This is a capture of PSTATE.PRIV + * at the time the error is detected. + */ +#define CHAFSR_PRIV (1UL << 52UL) /* ch,ch+,jp */ + +/* The following bits 51 (CHAFSR_PERR) to 33 (CHAFSR_CE) are sticky error + * bits and record the most recently detected errors. Bits accumulate + * errors that have been detected since the last write to clear the bit. + */ + +/* System interface protocol error. The processor asserts its' ERROR + * pin when this event occurs and it also logs a specific cause code + * into a JTAG scannable flop. + */ +#define CHAFSR_PERR (1UL << 51UL) /* ch,ch+,jp */ + +/* Internal processor error. The processor asserts its' ERROR + * pin when this event occurs and it also logs a specific cause code + * into a JTAG scannable flop. + */ +#define CHAFSR_IERR (1UL << 50UL) /* ch,ch+,jp */ + +/* System request parity error on incoming address */ +#define CHAFSR_ISAP (1UL << 49UL) /* ch,ch+,jp */ + +/* HW Corrected system bus MTAG ECC error */ +#define CHAFSR_EMC (1UL << 48UL) /* ch,ch+ */ +/* Parity error on L2 cache tag SRAM */ +#define JPAFSR_ETP (1UL << 48UL) /* jp */ + +/* Uncorrectable system bus MTAG ECC error */ +#define CHAFSR_EMU (1UL << 47UL) /* ch,ch+ */ +/* Out of range memory error has occurred */ +#define JPAFSR_OM (1UL << 47UL) /* jp */ + +/* HW Corrected system bus data ECC error for read of interrupt vector */ +#define CHAFSR_IVC (1UL << 46UL) /* ch,ch+ */ +/* Error due to unsupported store */ +#define JPAFSR_UMS (1UL << 46UL) /* jp */ + +/* Uncorrectable system bus data ECC error for read of interrupt vector */ +#define CHAFSR_IVU (1UL << 45UL) /* ch,ch+,jp */ + +/* Unmapped error from system bus */ +#define CHAFSR_TO (1UL << 44UL) /* ch,ch+,jp */ + +/* Bus error response from system bus */ +#define CHAFSR_BERR (1UL << 43UL) /* ch,ch+,jp */ + +/* SW Correctable E-cache ECC error for instruction fetch or data access + * other than block load. + */ +#define CHAFSR_UCC (1UL << 42UL) /* ch,ch+,jp */ + +/* Uncorrectable E-cache ECC error for instruction fetch or data access + * other than block load. + */ +#define CHAFSR_UCU (1UL << 41UL) /* ch,ch+,jp */ + +/* Copyout HW Corrected ECC error */ +#define CHAFSR_CPC (1UL << 40UL) /* ch,ch+,jp */ + +/* Copyout Uncorrectable ECC error */ +#define CHAFSR_CPU (1UL << 39UL) /* ch,ch+,jp */ + +/* HW Corrected ECC error from E-cache for writeback */ +#define CHAFSR_WDC (1UL << 38UL) /* ch,ch+,jp */ + +/* Uncorrectable ECC error from E-cache for writeback */ +#define CHAFSR_WDU (1UL << 37UL) /* ch,ch+,jp */ + +/* HW Corrected ECC error from E-cache for store merge or block load */ +#define CHAFSR_EDC (1UL << 36UL) /* ch,ch+,jp */ + +/* Uncorrectable ECC error from E-cache for store merge or block load */ +#define CHAFSR_EDU (1UL << 35UL) /* ch,ch+,jp */ + +/* Uncorrectable system bus data ECC error for read of memory or I/O */ +#define CHAFSR_UE (1UL << 34UL) /* ch,ch+,jp */ + +/* HW Corrected system bus data ECC error for read of memory or I/O */ +#define CHAFSR_CE (1UL << 33UL) /* ch,ch+,jp */ + +/* Uncorrectable ECC error from remote cache/memory */ +#define JPAFSR_RUE (1UL << 32UL) /* jp */ + +/* Correctable ECC error from remote cache/memory */ +#define JPAFSR_RCE (1UL << 31UL) /* jp */ + +/* JBUS parity error on returned read data */ +#define JPAFSR_BP (1UL << 30UL) /* jp */ + +/* JBUS parity error on data for writeback or block store */ +#define JPAFSR_WBP (1UL << 29UL) /* jp */ + +/* Foreign read to DRAM incurring correctable ECC error */ +#define JPAFSR_FRC (1UL << 28UL) /* jp */ + +/* Foreign read to DRAM incurring uncorrectable ECC error */ +#define JPAFSR_FRU (1UL << 27UL) /* jp */ + +#define CHAFSR_ERRORS (CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP | CHAFSR_EMC | \ + CHAFSR_EMU | CHAFSR_IVC | CHAFSR_IVU | CHAFSR_TO | \ + CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | CHAFSR_CPC | \ + CHAFSR_CPU | CHAFSR_WDC | CHAFSR_WDU | CHAFSR_EDC | \ + CHAFSR_EDU | CHAFSR_UE | CHAFSR_CE) +#define CHPAFSR_ERRORS (CHPAFSR_DTO | CHPAFSR_DBERR | CHPAFSR_THCE | \ + CHPAFSR_TSCE | CHPAFSR_TUE | CHPAFSR_DUE | \ + CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP | CHAFSR_EMC | \ + CHAFSR_EMU | CHAFSR_IVC | CHAFSR_IVU | CHAFSR_TO | \ + CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | CHAFSR_CPC | \ + CHAFSR_CPU | CHAFSR_WDC | CHAFSR_WDU | CHAFSR_EDC | \ + CHAFSR_EDU | CHAFSR_UE | CHAFSR_CE) +#define JPAFSR_ERRORS (JPAFSR_JETO | JPAFSR_SCE | JPAFSR_JEIC | \ + JPAFSR_JEIT | CHAFSR_PERR | CHAFSR_IERR | \ + CHAFSR_ISAP | JPAFSR_ETP | JPAFSR_OM | \ + JPAFSR_UMS | CHAFSR_IVU | CHAFSR_TO | \ + CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | \ + CHAFSR_CPC | CHAFSR_CPU | CHAFSR_WDC | \ + CHAFSR_WDU | CHAFSR_EDC | CHAFSR_EDU | \ + CHAFSR_UE | CHAFSR_CE | JPAFSR_RUE | \ + JPAFSR_RCE | JPAFSR_BP | JPAFSR_WBP | \ + JPAFSR_FRC | JPAFSR_FRU) + +/* Active JBUS request signal when error occurred */ +#define JPAFSR_JBREQ (0x7UL << 24UL) /* jp */ +#define JPAFSR_JBREQ_SHIFT 24UL + +/* L2 cache way information */ +#define JPAFSR_ETW (0x3UL << 22UL) /* jp */ +#define JPAFSR_ETW_SHIFT 22UL + +/* System bus MTAG ECC syndrome. This field captures the status of the + * first occurrence of the highest-priority error according to the M_SYND + * overwrite policy. After the AFSR sticky bit, corresponding to the error + * for which the M_SYND is reported, is cleared, the contents of the M_SYND + * field will be unchanged by will be unfrozen for further error capture. + */ +#define CHAFSR_M_SYNDROME (0xfUL << 16UL) /* ch,ch+,jp */ +#define CHAFSR_M_SYNDROME_SHIFT 16UL + +/* Agenid Id of the foreign device causing the UE/CE errors */ +#define JPAFSR_AID (0x1fUL << 9UL) /* jp */ +#define JPAFSR_AID_SHIFT 9UL + +/* System bus or E-cache data ECC syndrome. This field captures the status + * of the first occurrence of the highest-priority error according to the + * E_SYND overwrite policy. After the AFSR sticky bit, corresponding to the + * error for which the E_SYND is reported, is cleare, the contents of the E_SYND + * field will be unchanged but will be unfrozen for further error capture. + */ +#define CHAFSR_E_SYNDROME (0x1ffUL << 0UL) /* ch,ch+,jp */ +#define CHAFSR_E_SYNDROME_SHIFT 0UL + +/* The AFSR must be explicitly cleared by software, it is not cleared automatically + * by a read. Writes to bits <51:33> with bits set will clear the corresponding + * bits in the AFSR. Bits associated with disrupting traps must be cleared before + * interrupts are re-enabled to prevent multiple traps for the same error. I.e. + * PSTATE.IE and AFSR bits control delivery of disrupting traps. + * + * Since there is only one AFAR, when multiple events have been logged by the + * bits in the AFSR, at most one of these events will have its status captured + * in the AFAR. The highest priority of those event bits will get AFAR logging. + * The AFAR will be unlocked and available to capture the address of another event + * as soon as the one bit in AFSR that corresponds to the event logged in AFAR is + * cleared. For example, if AFSR.CE is detected, then AFSR.UE (which overwrites + * the AFAR), and AFSR.UE is cleared by not AFSR.CE, then the AFAR will be unlocked + * and ready for another event, even though AFSR.CE is still set. The same rules + * also apply to the M_SYNDROME and E_SYNDROME fields of the AFSR. + */ + +#endif /* _SPARC64_CHAFSR_H */ diff --git a/include/asm-sparc64/checksum.h b/include/asm-sparc64/checksum.h new file mode 100644 index 000000000000..dc8bed246fc9 --- /dev/null +++ b/include/asm-sparc64/checksum.h @@ -0,0 +1,173 @@ +/* $Id: checksum.h,v 1.19 2002/02/09 19:49:31 davem Exp $ */ +#ifndef __SPARC64_CHECKSUM_H +#define __SPARC64_CHECKSUM_H + +/* checksum.h: IP/UDP/TCP checksum routines on the V9. + * + * Copyright(C) 1995 Linus Torvalds + * Copyright(C) 1995 Miguel de Icaza + * Copyright(C) 1996 David S. Miller + * Copyright(C) 1996 Eddie C. Dost + * Copyright(C) 1997 Jakub Jelinek + * + * derived from: + * Alpha checksum c-code + * ix86 inline assembly + * RFC1071 Computing the Internet Checksum + */ + +#include <linux/in6.h> +#include <asm/uaccess.h> + +/* 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 user space while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ +extern unsigned int csum_partial_copy_nocheck(const unsigned char *src, + unsigned char *dst, + int len, unsigned int sum); + +extern long __csum_partial_copy_from_user(const unsigned char __user *src, + unsigned char *dst, int len, + unsigned int sum); + +static inline unsigned int +csum_partial_copy_from_user(const unsigned char __user *src, + unsigned char *dst, int len, + unsigned int sum, int *err) +{ + long ret = __csum_partial_copy_from_user(src, dst, len, sum); + if (ret < 0) + *err = -EFAULT; + return (unsigned int) ret; +} + +/* + * Copy and checksum to user + */ +#define HAVE_CSUM_COPY_USER +extern long __csum_partial_copy_to_user(const unsigned char *src, + unsigned char __user *dst, int len, + unsigned int sum); + +static inline unsigned int +csum_and_copy_to_user(const unsigned char *src, + unsigned char __user *dst, int len, + unsigned int sum, int *err) +{ + long ret = __csum_partial_copy_to_user(src, dst, len, sum); + if (ret < 0) + *err = -EFAULT; + return (unsigned int) ret; +} + +/* ihl is always 5 or greater, almost always is 5, and iph is word aligned + * the majority of the time. + */ +extern unsigned short ip_fast_csum(__const__ unsigned char *iph, + unsigned int ihl); + +/* Fold a partial checksum without adding pseudo headers. */ +static inline unsigned short csum_fold(unsigned int sum) +{ + unsigned int tmp; + + __asm__ __volatile__( +" addcc %0, %1, %1\n" +" srl %1, 16, %1\n" +" addc %1, %%g0, %1\n" +" xnor %%g0, %1, %0\n" + : "=&r" (sum), "=r" (tmp) + : "0" (sum), "1" (sum<<16) + : "cc"); + return (sum & 0xffff); +} + +static inline unsigned long csum_tcpudp_nofold(unsigned long saddr, + unsigned long daddr, + unsigned int len, + unsigned short proto, + unsigned int sum) +{ + __asm__ __volatile__( +" addcc %1, %0, %0\n" +" addccc %2, %0, %0\n" +" addccc %3, %0, %0\n" +" addc %0, %%g0, %0\n" + : "=r" (sum), "=r" (saddr) + : "r" (daddr), "r" ((proto<<16)+len), "0" (sum), "1" (saddr) + : "cc"); + return sum; +} + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, + unsigned int sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); +} + +#define _HAVE_ARCH_IPV6_CSUM + +static inline unsigned short int csum_ipv6_magic(struct in6_addr *saddr, + struct in6_addr *daddr, + __u32 len, + unsigned short proto, + unsigned int sum) +{ + __asm__ __volatile__ ( +" addcc %3, %4, %%g7\n" +" addccc %5, %%g7, %%g7\n" +" lduw [%2 + 0x0c], %%g2\n" +" lduw [%2 + 0x08], %%g3\n" +" addccc %%g2, %%g7, %%g7\n" +" lduw [%2 + 0x04], %%g2\n" +" addccc %%g3, %%g7, %%g7\n" +" lduw [%2 + 0x00], %%g3\n" +" addccc %%g2, %%g7, %%g7\n" +" lduw [%1 + 0x0c], %%g2\n" +" addccc %%g3, %%g7, %%g7\n" +" lduw [%1 + 0x08], %%g3\n" +" addccc %%g2, %%g7, %%g7\n" +" lduw [%1 + 0x04], %%g2\n" +" addccc %%g3, %%g7, %%g7\n" +" lduw [%1 + 0x00], %%g3\n" +" addccc %%g2, %%g7, %%g7\n" +" addccc %%g3, %%g7, %0\n" +" addc 0, %0, %0\n" + : "=&r" (sum) + : "r" (saddr), "r" (daddr), "r"(htonl(len)), + "r"(htonl(proto)), "r"(sum) + : "g2", "g3", "g7", "cc"); + + return csum_fold(sum); +} + +/* this routine is used for miscellaneous IP-like checksums, mainly in icmp.c */ +static inline unsigned short ip_compute_csum(unsigned char * buff, int len) +{ + return csum_fold(csum_partial(buff, len, 0)); +} + +#endif /* !(__SPARC64_CHECKSUM_H) */ diff --git a/include/asm-sparc64/chmctrl.h b/include/asm-sparc64/chmctrl.h new file mode 100644 index 000000000000..53047f9f6423 --- /dev/null +++ b/include/asm-sparc64/chmctrl.h @@ -0,0 +1,184 @@ +/* $Id: chmctrl.h,v 1.1 2001/03/29 11:43:28 davem Exp $ */ +#ifndef _SPARC64_CHMCTRL_H +#define _SPARC64_CHMCTRL_H + +/* Cheetah memory controller programmable registers. */ +#define CHMCTRL_TCTRL1 0x00 /* Memory Timing Control I */ +#define CHMCTRL_TCTRL2 0x08 /* Memory Timing Control II */ +#define CHMCTRL_TCTRL3 0x38 /* Memory Timing Control III */ +#define CHMCTRL_TCTRL4 0x40 /* Memory Timing Control IV */ +#define CHMCTRL_DECODE1 0x10 /* Memory Address Decode I */ +#define CHMCTRL_DECODE2 0x18 /* Memory Address Decode II */ +#define CHMCTRL_DECODE3 0x20 /* Memory Address Decode III */ +#define CHMCTRL_DECODE4 0x28 /* Memory Address Decode IV */ +#define CHMCTRL_MACTRL 0x30 /* Memory Address Control */ + +/* Memory Timing Control I */ +#define TCTRL1_SDRAMCTL_DLY 0xf000000000000000UL +#define TCTRL1_SDRAMCTL_DLY_SHIFT 60 +#define TCTRL1_SDRAMCLK_DLY 0x0e00000000000000UL +#define TCTRL1_SDRAMCLK_DLY_SHIFT 57 +#define TCTRL1_R 0x0100000000000000UL +#define TCTRL1_R_SHIFT 56 +#define TCTRL1_AUTORFR_CYCLE 0x00fe000000000000UL +#define TCTRL1_AUTORFR_CYCLE_SHIFT 49 +#define TCTRL1_RD_WAIT 0x0001f00000000000UL +#define TCTRL1_RD_WAIT_SHIFT 44 +#define TCTRL1_PC_CYCLE 0x00000fc000000000UL +#define TCTRL1_PC_CYCLE_SHIFT 38 +#define TCTRL1_WR_MORE_RAS_PW 0x0000003f00000000UL +#define TCTRL1_WR_MORE_RAS_PW_SHIFT 32 +#define TCTRL1_RD_MORE_RAW_PW 0x00000000fc000000UL +#define TCTRL1_RD_MORE_RAS_PW_SHIFT 26 +#define TCTRL1_ACT_WR_DLY 0x0000000003f00000UL +#define TCTRL1_ACT_WR_DLY_SHIFT 20 +#define TCTRL1_ACT_RD_DLY 0x00000000000fc000UL +#define TCTRL1_ACT_RD_DLY_SHIFT 14 +#define TCTRL1_BANK_PRESENT 0x0000000000003000UL +#define TCTRL1_BANK_PRESENT_SHIFT 12 +#define TCTRL1_RFR_INT 0x0000000000000ff8UL +#define TCTRL1_RFR_INT_SHIFT 3 +#define TCTRL1_SET_MODE_REG 0x0000000000000004UL +#define TCTRL1_SET_MODE_REG_SHIFT 2 +#define TCTRL1_RFR_ENABLE 0x0000000000000002UL +#define TCTRL1_RFR_ENABLE_SHIFT 1 +#define TCTRL1_PRECHG_ALL 0x0000000000000001UL +#define TCTRL1_PRECHG_ALL_SHIFT 0 + +/* Memory Timing Control II */ +#define TCTRL2_WR_MSEL_DLY 0xfc00000000000000UL +#define TCTRL2_WR_MSEL_DLY_SHIFT 58 +#define TCTRL2_RD_MSEL_DLY 0x03f0000000000000UL +#define TCTRL2_RD_MSEL_DLY_SHIFT 52 +#define TCTRL2_WRDATA_THLD 0x000c000000000000UL +#define TCTRL2_WRDATA_THLD_SHIFT 50 +#define TCTRL2_RDWR_RD_TI_DLY 0x0003f00000000000UL +#define TCTRL2_RDWR_RD_TI_DLY_SHIFT 44 +#define TCTRL2_AUTOPRECHG_ENBL 0x0000080000000000UL +#define TCTRL2_AUTOPRECHG_ENBL_SHIFT 43 +#define TCTRL2_RDWR_PI_MORE_DLY 0x000007c000000000UL +#define TCTRL2_RDWR_PI_MORE_DLY_SHIFT 38 +#define TCTRL2_RDWR_1_DLY 0x0000003f00000000UL +#define TCTRL2_RDWR_1_DLY_SHIFT 32 +#define TCTRL2_WRWR_PI_MORE_DLY 0x00000000f8000000UL +#define TCTRL2_WRWR_PI_MORE_DLY_SHIFT 27 +#define TCTRL2_WRWR_1_DLY 0x0000000007e00000UL +#define TCTRL2_WRWR_1_DLY_SHIFT 21 +#define TCTRL2_RDWR_RD_PI_MORE_DLY 0x00000000001f0000UL +#define TCTRL2_RDWR_RD_PI_MORE_DLY_SHIFT 16 +#define TCTRL2_R 0x0000000000008000UL +#define TCTRL2_R_SHIFT 15 +#define TCTRL2_SDRAM_MODE_REG_DATA 0x0000000000007fffUL +#define TCTRL2_SDRAM_MODE_REG_DATA_SHIFT 0 + +/* Memory Timing Control III */ +#define TCTRL3_SDRAM_CTL_DLY 0xf000000000000000UL +#define TCTRL3_SDRAM_CTL_DLY_SHIFT 60 +#define TCTRL3_SDRAM_CLK_DLY 0x0e00000000000000UL +#define TCTRL3_SDRAM_CLK_DLY_SHIFT 57 +#define TCTRL3_R 0x0100000000000000UL +#define TCTRL3_R_SHIFT 56 +#define TCTRL3_AUTO_RFR_CYCLE 0x00fe000000000000UL +#define TCTRL3_AUTO_RFR_CYCLE_SHIFT 49 +#define TCTRL3_RD_WAIT 0x0001f00000000000UL +#define TCTRL3_RD_WAIT_SHIFT 44 +#define TCTRL3_PC_CYCLE 0x00000fc000000000UL +#define TCTRL3_PC_CYCLE_SHIFT 38 +#define TCTRL3_WR_MORE_RAW_PW 0x0000003f00000000UL +#define TCTRL3_WR_MORE_RAW_PW_SHIFT 32 +#define TCTRL3_RD_MORE_RAW_PW 0x00000000fc000000UL +#define TCTRL3_RD_MORE_RAW_PW_SHIFT 26 +#define TCTRL3_ACT_WR_DLY 0x0000000003f00000UL +#define TCTRL3_ACT_WR_DLY_SHIFT 20 +#define TCTRL3_ACT_RD_DLY 0x00000000000fc000UL +#define TCTRL3_ACT_RD_DLY_SHIFT 14 +#define TCTRL3_BANK_PRESENT 0x0000000000003000UL +#define TCTRL3_BANK_PRESENT_SHIFT 12 +#define TCTRL3_RFR_INT 0x0000000000000ff8UL +#define TCTRL3_RFR_INT_SHIFT 3 +#define TCTRL3_SET_MODE_REG 0x0000000000000004UL +#define TCTRL3_SET_MODE_REG_SHIFT 2 +#define TCTRL3_RFR_ENABLE 0x0000000000000002UL +#define TCTRL3_RFR_ENABLE_SHIFT 1 +#define TCTRL3_PRECHG_ALL 0x0000000000000001UL +#define TCTRL3_PRECHG_ALL_SHIFT 0 + +/* Memory Timing Control IV */ +#define TCTRL4_WR_MSEL_DLY 0xfc00000000000000UL +#define TCTRL4_WR_MSEL_DLY_SHIFT 58 +#define TCTRL4_RD_MSEL_DLY 0x03f0000000000000UL +#define TCTRL4_RD_MSEL_DLY_SHIFT 52 +#define TCTRL4_WRDATA_THLD 0x000c000000000000UL +#define TCTRL4_WRDATA_THLD_SHIFT 50 +#define TCTRL4_RDWR_RD_RI_DLY 0x0003f00000000000UL +#define TCTRL4_RDWR_RD_RI_DLY_SHIFT 44 +#define TCTRL4_AUTO_PRECHG_ENBL 0x0000080000000000UL +#define TCTRL4_AUTO_PRECHG_ENBL_SHIFT 43 +#define TCTRL4_RD_WR_PI_MORE_DLY 0x000007c000000000UL +#define TCTRL4_RD_WR_PI_MORE_DLY_SHIFT 38 +#define TCTRL4_RD_WR_TI_DLY 0x0000003f00000000UL +#define TCTRL4_RD_WR_TI_DLY_SHIFT 32 +#define TCTRL4_WR_WR_PI_MORE_DLY 0x00000000f8000000UL +#define TCTRL4_WR_WR_PI_MORE_DLY_SHIFT 27 +#define TCTRL4_WR_WR_TI_DLY 0x0000000007e00000UL +#define TCTRL4_WR_WR_TI_DLY_SHIFT 21 +#define TCTRL4_RDWR_RD_PI_MORE_DLY 0x00000000001f000UL0 +#define TCTRL4_RDWR_RD_PI_MORE_DLY_SHIFT 16 +#define TCTRL4_R 0x0000000000008000UL +#define TCTRL4_R_SHIFT 15 +#define TCTRL4_SDRAM_MODE_REG_DATA 0x0000000000007fffUL +#define TCTRL4_SDRAM_MODE_REG_DATA_SHIFT 0 + +/* All 4 memory address decoding registers have the + * same layout. + */ +#define MEM_DECODE_VALID 0x8000000000000000UL /* Valid */ +#define MEM_DECODE_VALID_SHIFT 63 +#define MEM_DECODE_UK 0x001ffe0000000000UL /* Upper mask */ +#define MEM_DECODE_UK_SHIFT 41 +#define MEM_DECODE_UM 0x0000001ffff00000UL /* Upper match */ +#define MEM_DECODE_UM_SHIFT 20 +#define MEM_DECODE_LK 0x000000000003c000UL /* Lower mask */ +#define MEM_DECODE_LK_SHIFT 14 +#define MEM_DECODE_LM 0x0000000000000f00UL /* Lower match */ +#define MEM_DECODE_LM_SHIFT 8 + +#define PA_UPPER_BITS 0x000007fffc000000UL +#define PA_UPPER_BITS_SHIFT 26 +#define PA_LOWER_BITS 0x00000000000003c0UL +#define PA_LOWER_BITS_SHIFT 6 + +#define MACTRL_R0 0x8000000000000000UL +#define MACTRL_R0_SHIFT 63 +#define MACTRL_ADDR_LE_PW 0x7000000000000000UL +#define MACTRL_ADDR_LE_PW_SHIFT 60 +#define MACTRL_CMD_PW 0x0f00000000000000UL +#define MACTRL_CMD_PW_SHIFT 56 +#define MACTRL_HALF_MODE_WR_MSEL_DLY 0x00fc000000000000UL +#define MACTRL_HALF_MODE_WR_MSEL_DLY_SHIFT 50 +#define MACTRL_HALF_MODE_RD_MSEL_DLY 0x0003f00000000000UL +#define MACTRL_HALF_MODE_RD_MSEL_DLY_SHIFT 44 +#define MACTRL_HALF_MODE_SDRAM_CTL_DLY 0x00000f0000000000UL +#define MACTRL_HALF_MODE_SDRAM_CTL_DLY_SHIFT 40 +#define MACTRL_HALF_MODE_SDRAM_CLK_DLY 0x000000e000000000UL +#define MACTRL_HALF_MODE_SDRAM_CLK_DLY_SHIFT 37 +#define MACTRL_R1 0x0000001000000000UL +#define MACTRL_R1_SHIFT 36 +#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B3 0x0000000f00000000UL +#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B3_SHIFT 32 +#define MACTRL_ENC_INTLV_B3 0x00000000f8000000UL +#define MACTRL_ENC_INTLV_B3_SHIFT 27 +#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B2 0x0000000007800000UL +#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B2_SHIFT 23 +#define MACTRL_ENC_INTLV_B2 0x00000000007c0000UL +#define MACTRL_ENC_INTLV_B2_SHIFT 18 +#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B1 0x000000000003c000UL +#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B1_SHIFT 14 +#define MACTRL_ENC_INTLV_B1 0x0000000000003e00UL +#define MACTRL_ENC_INTLV_B1_SHIFT 9 +#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B0 0x00000000000001e0UL +#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B0_SHIFT 5 +#define MACTRL_ENC_INTLV_B0 0x000000000000001fUL +#define MACTRL_ENC_INTLV_B0_SHIFT 0 + +#endif /* _SPARC64_CHMCTRL_H */ diff --git a/include/asm-sparc64/cmt.h b/include/asm-sparc64/cmt.h new file mode 100644 index 000000000000..870db5928577 --- /dev/null +++ b/include/asm-sparc64/cmt.h @@ -0,0 +1,59 @@ +#ifndef _SPARC64_CMT_H +#define _SPARC64_CMT_H + +/* cmt.h: Chip Multi-Threading register definitions + * + * Copyright (C) 2004 David S. Miller (davem@redhat.com) + */ + +/* ASI_CORE_ID - private */ +#define LP_ID 0x0000000000000010UL +#define LP_ID_MAX 0x00000000003f0000UL +#define LP_ID_ID 0x000000000000003fUL + +/* ASI_INTR_ID - private */ +#define LP_INTR_ID 0x0000000000000000UL +#define LP_INTR_ID_ID 0x00000000000003ffUL + +/* ASI_CESR_ID - private */ +#define CESR_ID 0x0000000000000040UL +#define CESR_ID_ID 0x00000000000000ffUL + +/* ASI_CORE_AVAILABLE - shared */ +#define LP_AVAIL 0x0000000000000000UL +#define LP_AVAIL_1 0x0000000000000002UL +#define LP_AVAIL_0 0x0000000000000001UL + +/* ASI_CORE_ENABLE_STATUS - shared */ +#define LP_ENAB_STAT 0x0000000000000010UL +#define LP_ENAB_STAT_1 0x0000000000000002UL +#define LP_ENAB_STAT_0 0x0000000000000001UL + +/* ASI_CORE_ENABLE - shared */ +#define LP_ENAB 0x0000000000000020UL +#define LP_ENAB_1 0x0000000000000002UL +#define LP_ENAB_0 0x0000000000000001UL + +/* ASI_CORE_RUNNING - shared */ +#define LP_RUNNING_RW 0x0000000000000050UL +#define LP_RUNNING_W1S 0x0000000000000060UL +#define LP_RUNNING_W1C 0x0000000000000068UL +#define LP_RUNNING_1 0x0000000000000002UL +#define LP_RUNNING_0 0x0000000000000001UL + +/* ASI_CORE_RUNNING_STAT - shared */ +#define LP_RUN_STAT 0x0000000000000058UL +#define LP_RUN_STAT_1 0x0000000000000002UL +#define LP_RUN_STAT_0 0x0000000000000001UL + +/* ASI_XIR_STEERING - shared */ +#define LP_XIR_STEER 0x0000000000000030UL +#define LP_XIR_STEER_1 0x0000000000000002UL +#define LP_XIR_STEER_0 0x0000000000000001UL + +/* ASI_CMT_ERROR_STEERING - shared */ +#define CMT_ER_STEER 0x0000000000000040UL +#define CMT_ER_STEER_1 0x0000000000000002UL +#define CMT_ER_STEER_0 0x0000000000000001UL + +#endif /* _SPARC64_CMT_H */ diff --git a/include/asm-sparc64/compat.h b/include/asm-sparc64/compat.h new file mode 100644 index 000000000000..2950279dd776 --- /dev/null +++ b/include/asm-sparc64/compat.h @@ -0,0 +1,201 @@ +#ifndef _ASM_SPARC64_COMPAT_H +#define _ASM_SPARC64_COMPAT_H +/* + * Architecture specific compatibility types + */ +#include <linux/types.h> + +#define COMPAT_USER_HZ 100 + +typedef u32 compat_size_t; +typedef s32 compat_ssize_t; +typedef s32 compat_time_t; +typedef s32 compat_clock_t; +typedef s32 compat_pid_t; +typedef u16 compat_uid_t; +typedef u16 compat_gid_t; +typedef u16 compat_mode_t; +typedef u32 compat_ino_t; +typedef u16 compat_dev_t; +typedef s32 compat_off_t; +typedef s64 compat_loff_t; +typedef s16 compat_nlink_t; +typedef u16 compat_ipc_pid_t; +typedef s32 compat_daddr_t; +typedef u32 compat_caddr_t; +typedef __kernel_fsid_t compat_fsid_t; +typedef s32 compat_key_t; + +typedef s32 compat_int_t; +typedef s32 compat_long_t; +typedef u32 compat_uint_t; +typedef u32 compat_ulong_t; + +struct compat_timespec { + compat_time_t tv_sec; + s32 tv_nsec; +}; + +struct compat_timeval { + compat_time_t tv_sec; + s32 tv_usec; +}; + +struct compat_stat { + compat_dev_t st_dev; + compat_ino_t st_ino; + compat_mode_t st_mode; + compat_nlink_t st_nlink; + compat_uid_t st_uid; + compat_gid_t st_gid; + compat_dev_t st_rdev; + compat_off_t st_size; + compat_time_t st_atime; + u32 __unused1; + compat_time_t st_mtime; + u32 __unused2; + compat_time_t st_ctime; + u32 __unused3; + compat_off_t st_blksize; + compat_off_t st_blocks; + u32 __unused4[2]; +}; + +struct compat_flock { + short l_type; + short l_whence; + compat_off_t l_start; + compat_off_t l_len; + compat_pid_t l_pid; + short __unused; +}; + +#define F_GETLK64 12 +#define F_SETLK64 13 +#define F_SETLKW64 14 + +struct compat_flock64 { + short l_type; + short l_whence; + compat_loff_t l_start; + compat_loff_t l_len; + compat_pid_t l_pid; + short __unused; +}; + +struct compat_statfs { + int f_type; + int f_bsize; + int f_blocks; + int f_bfree; + int f_bavail; + int f_files; + int f_ffree; + compat_fsid_t f_fsid; + int f_namelen; /* SunOS ignores this field. */ + int f_frsize; + int f_spare[5]; +}; + +#define COMPAT_RLIM_INFINITY 0x7fffffff + +typedef u32 compat_old_sigset_t; + +#define _COMPAT_NSIG 64 +#define _COMPAT_NSIG_BPW 32 + +typedef u32 compat_sigset_word; + +#define COMPAT_OFF_T_MAX 0x7fffffff +#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL + +/* + * A pointer passed in from user mode. This should not + * be used for syscall parameters, just declare them + * as pointers because the syscall entry code will have + * appropriately comverted them already. + */ +typedef u32 compat_uptr_t; + +static inline void __user *compat_ptr(compat_uptr_t uptr) +{ + return (void __user *)(unsigned long)uptr; +} + +static inline compat_uptr_t ptr_to_compat(void __user *uptr) +{ + return (u32)(unsigned long)uptr; +} + +static __inline__ void __user *compat_alloc_user_space(long len) +{ + struct pt_regs *regs = current_thread_info()->kregs; + unsigned long usp = regs->u_regs[UREG_I6]; + + if (!(test_thread_flag(TIF_32BIT))) + usp += STACK_BIAS; + else + usp &= 0xffffffffUL; + + return (void __user *) (usp - len); +} + +struct compat_ipc64_perm { + compat_key_t key; + __kernel_uid_t uid; + __kernel_gid_t gid; + __kernel_uid_t cuid; + __kernel_gid_t cgid; + unsigned short __pad1; + compat_mode_t mode; + unsigned short __pad2; + unsigned short seq; + unsigned long __unused1; /* yes they really are 64bit pads */ + unsigned long __unused2; +}; + +struct compat_semid64_ds { + struct compat_ipc64_perm sem_perm; + unsigned int __pad1; + compat_time_t sem_otime; + unsigned int __pad2; + compat_time_t sem_ctime; + u32 sem_nsems; + u32 __unused1; + u32 __unused2; +}; + +struct compat_msqid64_ds { + struct compat_ipc64_perm msg_perm; + unsigned int __pad1; + compat_time_t msg_stime; + unsigned int __pad2; + compat_time_t msg_rtime; + unsigned int __pad3; + compat_time_t msg_ctime; + unsigned int msg_cbytes; + unsigned int msg_qnum; + unsigned int msg_qbytes; + compat_pid_t msg_lspid; + compat_pid_t msg_lrpid; + unsigned int __unused1; + unsigned int __unused2; +}; + +struct compat_shmid64_ds { + struct compat_ipc64_perm shm_perm; + unsigned int __pad1; + compat_time_t shm_atime; + unsigned int __pad2; + compat_time_t shm_dtime; + unsigned int __pad3; + compat_time_t shm_ctime; + compat_size_t shm_segsz; + compat_pid_t shm_cpid; + compat_pid_t shm_lpid; + unsigned int shm_nattch; + unsigned int __unused1; + unsigned int __unused2; +}; + +#endif /* _ASM_SPARC64_COMPAT_H */ diff --git a/include/asm-sparc64/const.h b/include/asm-sparc64/const.h new file mode 100644 index 000000000000..8ad902b2ce04 --- /dev/null +++ b/include/asm-sparc64/const.h @@ -0,0 +1,19 @@ +/* const.h: Macros for dealing with constants. */ + +#ifndef _SPARC64_CONST_H +#define _SPARC64_CONST_H + +/* Some constant macros are used in both assembler and + * C code. Therefore we cannot annotate them always with + * 'UL' and other type specificers unilaterally. We + * use the following macros to deal with this. + */ + +#ifdef __ASSEMBLY__ +#define _AC(X,Y) X +#else +#define _AC(X,Y) (X##Y) +#endif + + +#endif /* !(_SPARC64_CONST_H) */ diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h new file mode 100644 index 000000000000..cc7198aaac50 --- /dev/null +++ b/include/asm-sparc64/cpudata.h @@ -0,0 +1,31 @@ +/* cpudata.h: Per-cpu parameters. + * + * Copyright (C) 2003 David S. Miller (davem@redhat.com) + */ + +#ifndef _SPARC64_CPUDATA_H +#define _SPARC64_CPUDATA_H + +#include <linux/percpu.h> + +typedef struct { + /* Dcache line 1 */ + unsigned int __pad0; /* bh_count moved to irq_stat for consistency. KAO */ + unsigned int multiplier; + unsigned int counter; + unsigned int idle_volume; + unsigned long clock_tick; /* %tick's per second */ + unsigned long udelay_val; + + /* Dcache line 2 */ + unsigned int pgcache_size; + unsigned int __pad1; + unsigned long *pte_cache[2]; + unsigned long *pgd_cache; +} cpuinfo_sparc; + +DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data); +#define cpu_data(__cpu) per_cpu(__cpu_data, (__cpu)) +#define local_cpu_data() __get_cpu_var(__cpu_data) + +#endif /* _SPARC64_CPUDATA_H */ diff --git a/include/asm-sparc64/cputime.h b/include/asm-sparc64/cputime.h new file mode 100644 index 000000000000..dec2fc7a36f8 --- /dev/null +++ b/include/asm-sparc64/cputime.h @@ -0,0 +1,6 @@ +#ifndef __SPARC64_CPUTIME_H +#define __SPARC64_CPUTIME_H + +#include <asm-generic/cputime.h> + +#endif /* __SPARC64_CPUTIME_H */ diff --git a/include/asm-sparc64/current.h b/include/asm-sparc64/current.h new file mode 100644 index 000000000000..6c21e4ee2475 --- /dev/null +++ b/include/asm-sparc64/current.h @@ -0,0 +1,8 @@ +#ifndef _SPARC64_CURRENT_H +#define _SPARC64_CURRENT_H + +#include <linux/thread_info.h> + +register struct task_struct *current asm("g4"); + +#endif /* !(_SPARC64_CURRENT_H) */ diff --git a/include/asm-sparc64/dcr.h b/include/asm-sparc64/dcr.h new file mode 100644 index 000000000000..e9a3f305815d --- /dev/null +++ b/include/asm-sparc64/dcr.h @@ -0,0 +1,15 @@ +/* $Id: dcr.h,v 1.4 2001/03/09 17:56:37 davem Exp $ */ +#ifndef _SPARC64_DCR_H +#define _SPARC64_DCR_H + +/* UltraSparc-III/III+ Dispatch Control Register, ASR 0x12 */ +#define DCR_DPE 0x0000000000001000 /* III+: D$ Parity Error Enable */ +#define DCR_OBS 0x0000000000000fc0 /* Observability Bus Controls */ +#define DCR_BPE 0x0000000000000020 /* Branch Predict Enable */ +#define DCR_RPE 0x0000000000000010 /* Return Address Prediction Enable */ +#define DCR_SI 0x0000000000000008 /* Single Instruction Disable */ +#define DCR_IPE 0x0000000000000004 /* III+: I$ Parity Error Enable */ +#define DCR_IFPOE 0x0000000000000002 /* IRQ FP Operation Enable */ +#define DCR_MS 0x0000000000000001 /* Multi-Scalar dispatch */ + +#endif /* _SPARC64_DCR_H */ diff --git a/include/asm-sparc64/dcu.h b/include/asm-sparc64/dcu.h new file mode 100644 index 000000000000..ecbed2ae548f --- /dev/null +++ b/include/asm-sparc64/dcu.h @@ -0,0 +1,26 @@ +/* $Id: dcu.h,v 1.2 2001/03/01 23:23:33 davem Exp $ */ +#ifndef _SPARC64_DCU_H +#define _SPARC64_DCU_H + +/* UltraSparc-III Data Cache Unit Control Register */ +#define DCU_CP 0x0002000000000000 /* Physical Cache Enable w/o mmu*/ +#define DCU_CV 0x0001000000000000 /* Virtual Cache Enable w/o mmu */ +#define DCU_ME 0x0000800000000000 /* NC-store Merging Enable */ +#define DCU_RE 0x0000400000000000 /* RAW bypass Enable */ +#define DCU_PE 0x0000200000000000 /* PCache Enable */ +#define DCU_HPE 0x0000100000000000 /* HW prefetch Enable */ +#define DCU_SPE 0x0000080000000000 /* SW prefetch Enable */ +#define DCU_SL 0x0000040000000000 /* Secondary load steering Enab */ +#define DCU_WE 0x0000020000000000 /* WCache enable */ +#define DCU_PM 0x000001fe00000000 /* PA Watchpoint Byte Mask */ +#define DCU_VM 0x00000001fe000000 /* VA Watchpoint Byte Mask */ +#define DCU_PR 0x0000000001000000 /* PA Watchpoint Read Enable */ +#define DCU_PW 0x0000000000800000 /* PA Watchpoint Write Enable */ +#define DCU_VR 0x0000000000400000 /* VA Watchpoint Read Enable */ +#define DCU_VW 0x0000000000200000 /* VA Watchpoint Write Enable */ +#define DCU_DM 0x0000000000000008 /* DMMU Enable */ +#define DCU_IM 0x0000000000000004 /* IMMU Enable */ +#define DCU_DC 0x0000000000000002 /* Data Cache Enable */ +#define DCU_IC 0x0000000000000001 /* Instruction Cache Enable */ + +#endif /* _SPARC64_DCU_H */ diff --git a/include/asm-sparc64/delay.h b/include/asm-sparc64/delay.h new file mode 100644 index 000000000000..2901ea0c342d --- /dev/null +++ b/include/asm-sparc64/delay.h @@ -0,0 +1,38 @@ +/* delay.h: Linux delay routines on sparc64. + * + * Copyright (C) 1996, 2004 David S. Miller (davem@davemloft.net). + * + * Based heavily upon x86 variant which is: + * Copyright (C) 1993 Linus Torvalds + * + * Delay routines calling functions in arch/sparc64/lib/delay.c + */ + +#ifndef __SPARC64_DELAY_H +#define __SPARC64_DELAY_H + +#include <linux/config.h> +#include <linux/param.h> +#include <asm/cpudata.h> + +#ifndef __ASSEMBLY__ + +extern void __bad_udelay(void); +extern void __bad_ndelay(void); + +extern void __udelay(unsigned long usecs); +extern void __ndelay(unsigned long nsecs); +extern void __const_udelay(unsigned long usecs); +extern void __delay(unsigned long loops); + +#define udelay(n) (__builtin_constant_p(n) ? \ + ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \ + __udelay(n)) + +#define ndelay(n) (__builtin_constant_p(n) ? \ + ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ + __ndelay(n)) + +#endif /* !__ASSEMBLY__ */ + +#endif /* defined(__SPARC64_DELAY_H) */ diff --git a/include/asm-sparc64/display7seg.h b/include/asm-sparc64/display7seg.h new file mode 100644 index 000000000000..955a3502218e --- /dev/null +++ b/include/asm-sparc64/display7seg.h @@ -0,0 +1,79 @@ +/* $Id: display7seg.h,v 1.2 2000/08/02 06:22:35 davem Exp $ + * + * display7seg - Driver interface for the 7-segment display + * present on Sun Microsystems CP1400 and CP1500 + * + * Copyright (c) 2000 Eric Brower <ebrower@usa.net> + * + */ + +#ifndef __display7seg_h__ +#define __display7seg_h__ + +#define D7S_IOC 'p' + +#define D7SIOCRD _IOR(D7S_IOC, 0x45, int) /* Read device state */ +#define D7SIOCWR _IOW(D7S_IOC, 0x46, int) /* Write device state */ +#define D7SIOCTM _IO (D7S_IOC, 0x47) /* Translate mode (FLIP)*/ + +/* + * ioctl flag definitions + * + * POINT - Toggle decimal point (0=absent 1=present) + * ALARM - Toggle alarm LED (0=green 1=red) + * FLIP - Toggle inverted mode (0=normal 1=flipped) + * bits 0-4 - Character displayed (see definitions below) + * + * Display segments are defined as follows, + * subject to D7S_FLIP register state: + * + * a + * --- + * f| |b + * -g- + * e| |c + * --- + * d + */ + +#define D7S_POINT (1 << 7) /* Decimal point*/ +#define D7S_ALARM (1 << 6) /* Alarm LED */ +#define D7S_FLIP (1 << 5) /* Flip display */ + +#define D7S_0 0x00 /* Numerals 0-9 */ +#define D7S_1 0x01 +#define D7S_2 0x02 +#define D7S_3 0x03 +#define D7S_4 0x04 +#define D7S_5 0x05 +#define D7S_6 0x06 +#define D7S_7 0x07 +#define D7S_8 0x08 +#define D7S_9 0x09 +#define D7S_A 0x0A /* Letters A-F, H, L, P */ +#define D7S_B 0x0B +#define D7S_C 0x0C +#define D7S_D 0x0D +#define D7S_E 0x0E +#define D7S_F 0x0F +#define D7S_H 0x10 +#define D7S_E2 0x11 +#define D7S_L 0x12 +#define D7S_P 0x13 +#define D7S_SEGA 0x14 /* Individual segments */ +#define D7S_SEGB 0x15 +#define D7S_SEGC 0x16 +#define D7S_SEGD 0x17 +#define D7S_SEGE 0x18 +#define D7S_SEGF 0x19 +#define D7S_SEGG 0x1A +#define D7S_SEGABFG 0x1B /* Segment groupings */ +#define D7S_SEGCDEG 0x1C +#define D7S_SEGBCEF 0x1D +#define D7S_SEGADG 0x1E +#define D7S_BLANK 0x1F /* Clear all segments */ + +#define D7S_MIN_VAL 0x0 +#define D7S_MAX_VAL 0x1F + +#endif /* ifndef __display7seg_h__ */ diff --git a/include/asm-sparc64/div64.h b/include/asm-sparc64/div64.h new file mode 100644 index 000000000000..6cd978cefb28 --- /dev/null +++ b/include/asm-sparc64/div64.h @@ -0,0 +1 @@ +#include <asm-generic/div64.h> diff --git a/include/asm-sparc64/dma-mapping.h b/include/asm-sparc64/dma-mapping.h new file mode 100644 index 000000000000..1c5da41653a4 --- /dev/null +++ b/include/asm-sparc64/dma-mapping.h @@ -0,0 +1,27 @@ +#ifndef _ASM_SPARC64_DMA_MAPPING_H +#define _ASM_SPARC64_DMA_MAPPING_H + +#include <linux/config.h> + +#ifdef CONFIG_PCI +#include <asm-generic/dma-mapping.h> +#else + +struct device; + +static inline void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, int flag) +{ + BUG(); + return NULL; +} + +static inline void dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + BUG(); +} + +#endif /* PCI */ + +#endif /* _ASM_SPARC64_DMA_MAPPING_H */ diff --git a/include/asm-sparc64/dma.h b/include/asm-sparc64/dma.h new file mode 100644 index 000000000000..1aab3c8dce2b --- /dev/null +++ b/include/asm-sparc64/dma.h @@ -0,0 +1,221 @@ +/* $Id: dma.h,v 1.21 2001/12/13 04:16:52 davem Exp $ + * include/asm-sparc64/dma.h + * + * Copyright 1996 (C) David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _ASM_SPARC64_DMA_H +#define _ASM_SPARC64_DMA_H + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/spinlock.h> + +#include <asm/sbus.h> +#include <asm/delay.h> +#include <asm/oplib.h> + +extern spinlock_t dma_spin_lock; + +#define claim_dma_lock() \ +({ unsigned long flags; \ + spin_lock_irqsave(&dma_spin_lock, flags); \ + flags; \ +}) + +#define release_dma_lock(__flags) \ + spin_unlock_irqrestore(&dma_spin_lock, __flags); + +/* These are irrelevant for Sparc DMA, but we leave it in so that + * things can compile. + */ +#define MAX_DMA_CHANNELS 8 +#define DMA_MODE_READ 1 +#define DMA_MODE_WRITE 2 +#define MAX_DMA_ADDRESS (~0UL) + +/* Useful constants */ +#define SIZE_16MB (16*1024*1024) +#define SIZE_64K (64*1024) + +/* SBUS DMA controller reg offsets */ +#define DMA_CSR 0x00UL /* rw DMA control/status register 0x00 */ +#define DMA_ADDR 0x04UL /* rw DMA transfer address register 0x04 */ +#define DMA_COUNT 0x08UL /* rw DMA transfer count register 0x08 */ +#define DMA_TEST 0x0cUL /* rw DMA test/debug register 0x0c */ + +/* DVMA chip revisions */ +enum dvma_rev { + dvmarev0, + dvmaesc1, + dvmarev1, + dvmarev2, + dvmarev3, + dvmarevplus, + dvmahme +}; + +#define DMA_HASCOUNT(rev) ((rev)==dvmaesc1) + +/* Linux DMA information structure, filled during probe. */ +struct sbus_dma { + struct sbus_dma *next; + struct sbus_dev *sdev; + void __iomem *regs; + + /* Status, misc info */ + int node; /* Prom node for this DMA device */ + int running; /* Are we doing DMA now? */ + int allocated; /* Are we "owned" by anyone yet? */ + + /* Transfer information. */ + u32 addr; /* Start address of current transfer */ + int nbytes; /* Size of current transfer */ + int realbytes; /* For splitting up large transfers, etc. */ + + /* DMA revision */ + enum dvma_rev revision; +}; + +extern struct sbus_dma *dma_chain; + +/* Broken hardware... */ +#define DMA_ISBROKEN(dma) ((dma)->revision == dvmarev1) +#define DMA_ISESC1(dma) ((dma)->revision == dvmaesc1) + +/* Main routines in dma.c */ +extern void dvma_init(struct sbus_bus *); + +/* Fields in the cond_reg register */ +/* First, the version identification bits */ +#define DMA_DEVICE_ID 0xf0000000 /* Device identification bits */ +#define DMA_VERS0 0x00000000 /* Sunray DMA version */ +#define DMA_ESCV1 0x40000000 /* DMA ESC Version 1 */ +#define DMA_VERS1 0x80000000 /* DMA rev 1 */ +#define DMA_VERS2 0xa0000000 /* DMA rev 2 */ +#define DMA_VERHME 0xb0000000 /* DMA hme gate array */ +#define DMA_VERSPLUS 0x90000000 /* DMA rev 1 PLUS */ + +#define DMA_HNDL_INTR 0x00000001 /* An IRQ needs to be handled */ +#define DMA_HNDL_ERROR 0x00000002 /* We need to take an error */ +#define DMA_FIFO_ISDRAIN 0x0000000c /* The DMA FIFO is draining */ +#define DMA_INT_ENAB 0x00000010 /* Turn on interrupts */ +#define DMA_FIFO_INV 0x00000020 /* Invalidate the FIFO */ +#define DMA_ACC_SZ_ERR 0x00000040 /* The access size was bad */ +#define DMA_FIFO_STDRAIN 0x00000040 /* DMA_VERS1 Drain the FIFO */ +#define DMA_RST_SCSI 0x00000080 /* Reset the SCSI controller */ +#define DMA_RST_ENET DMA_RST_SCSI /* Reset the ENET controller */ +#define DMA_ST_WRITE 0x00000100 /* write from device to memory */ +#define DMA_ENABLE 0x00000200 /* Fire up DMA, handle requests */ +#define DMA_PEND_READ 0x00000400 /* DMA_VERS1/0/PLUS Pending Read */ +#define DMA_ESC_BURST 0x00000800 /* 1=16byte 0=32byte */ +#define DMA_READ_AHEAD 0x00001800 /* DMA read ahead partial longword */ +#define DMA_DSBL_RD_DRN 0x00001000 /* No EC drain on slave reads */ +#define DMA_BCNT_ENAB 0x00002000 /* If on, use the byte counter */ +#define DMA_TERM_CNTR 0x00004000 /* Terminal counter */ +#define DMA_SCSI_SBUS64 0x00008000 /* HME: Enable 64-bit SBUS mode. */ +#define DMA_CSR_DISAB 0x00010000 /* No FIFO drains during csr */ +#define DMA_SCSI_DISAB 0x00020000 /* No FIFO drains during reg */ +#define DMA_DSBL_WR_INV 0x00020000 /* No EC inval. on slave writes */ +#define DMA_ADD_ENABLE 0x00040000 /* Special ESC DVMA optimization */ +#define DMA_E_BURSTS 0x000c0000 /* ENET: SBUS r/w burst mask */ +#define DMA_E_BURST32 0x00040000 /* ENET: SBUS 32 byte r/w burst */ +#define DMA_E_BURST16 0x00000000 /* ENET: SBUS 16 byte r/w burst */ +#define DMA_BRST_SZ 0x000c0000 /* SCSI: SBUS r/w burst size */ +#define DMA_BRST64 0x000c0000 /* SCSI: 64byte bursts (HME on UltraSparc only) */ +#define DMA_BRST32 0x00040000 /* SCSI: 32byte bursts */ +#define DMA_BRST16 0x00000000 /* SCSI: 16byte bursts */ +#define DMA_BRST0 0x00080000 /* SCSI: no bursts (non-HME gate arrays) */ +#define DMA_ADDR_DISAB 0x00100000 /* No FIFO drains during addr */ +#define DMA_2CLKS 0x00200000 /* Each transfer = 2 clock ticks */ +#define DMA_3CLKS 0x00400000 /* Each transfer = 3 clock ticks */ +#define DMA_EN_ENETAUI DMA_3CLKS /* Put lance into AUI-cable mode */ +#define DMA_CNTR_DISAB 0x00800000 /* No IRQ when DMA_TERM_CNTR set */ +#define DMA_AUTO_NADDR 0x01000000 /* Use "auto nxt addr" feature */ +#define DMA_SCSI_ON 0x02000000 /* Enable SCSI dma */ +#define DMA_PARITY_OFF 0x02000000 /* HME: disable parity checking */ +#define DMA_LOADED_ADDR 0x04000000 /* Address has been loaded */ +#define DMA_LOADED_NADDR 0x08000000 /* Next address has been loaded */ +#define DMA_RESET_FAS366 0x08000000 /* HME: Assert RESET to FAS366 */ + +/* Values describing the burst-size property from the PROM */ +#define DMA_BURST1 0x01 +#define DMA_BURST2 0x02 +#define DMA_BURST4 0x04 +#define DMA_BURST8 0x08 +#define DMA_BURST16 0x10 +#define DMA_BURST32 0x20 +#define DMA_BURST64 0x40 +#define DMA_BURSTBITS 0x7f + +/* Determine highest possible final transfer address given a base */ +#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL)) + +/* Yes, I hack a lot of elisp in my spare time... */ +#define DMA_ERROR_P(regs) (((sbus_readl((regs) + DMA_CSR) & DMA_HNDL_ERROR)) +#define DMA_IRQ_P(regs) (((sbus_readl((regs) + DMA_CSR)) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))) +#define DMA_WRITE_P(regs) (((sbus_readl((regs) + DMA_CSR) & DMA_ST_WRITE)) +#define DMA_OFF(__regs) \ +do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \ + tmp &= ~DMA_ENABLE; \ + sbus_writel(tmp, (__regs) + DMA_CSR); \ +} while(0) +#define DMA_INTSOFF(__regs) \ +do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \ + tmp &= ~DMA_INT_ENAB; \ + sbus_writel(tmp, (__regs) + DMA_CSR); \ +} while(0) +#define DMA_INTSON(__regs) \ +do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \ + tmp |= DMA_INT_ENAB; \ + sbus_writel(tmp, (__regs) + DMA_CSR); \ +} while(0) +#define DMA_PUNTFIFO(__regs) \ +do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \ + tmp |= DMA_FIFO_INV; \ + sbus_writel(tmp, (__regs) + DMA_CSR); \ +} while(0) +#define DMA_SETSTART(__regs, __addr) \ + sbus_writel((u32)(__addr), (__regs) + DMA_ADDR); +#define DMA_BEGINDMA_W(__regs) \ +do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \ + tmp |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB); \ + sbus_writel(tmp, (__regs) + DMA_CSR); \ +} while(0) +#define DMA_BEGINDMA_R(__regs) \ +do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \ + tmp |= (DMA_ENABLE|DMA_INT_ENAB); \ + tmp &= ~DMA_ST_WRITE; \ + sbus_writel(tmp, (__regs) + DMA_CSR); \ +} while(0) + +/* For certain DMA chips, we need to disable ints upon irq entry + * and turn them back on when we are done. So in any ESP interrupt + * handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT + * when leaving the handler. You have been warned... + */ +#define DMA_IRQ_ENTRY(dma, dregs) do { \ + if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \ + } while (0) + +#define DMA_IRQ_EXIT(dma, dregs) do { \ + if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \ + } while(0) + +#define for_each_dvma(dma) \ + for((dma) = dma_chain; (dma); (dma) = (dma)->next) + +extern int get_dma_list(char *); +extern int request_dma(unsigned int, __const__ char *); +extern void free_dma(unsigned int); + +/* From PCI */ + +#ifdef CONFIG_PCI +extern int isa_dma_bridge_buggy; +#else +#define isa_dma_bridge_buggy (0) +#endif + +#endif /* !(_ASM_SPARC64_DMA_H) */ diff --git a/include/asm-sparc64/ebus.h b/include/asm-sparc64/ebus.h new file mode 100644 index 000000000000..543e4e500a72 --- /dev/null +++ b/include/asm-sparc64/ebus.h @@ -0,0 +1,97 @@ +/* $Id: ebus.h,v 1.10 2001/03/14 05:00:55 davem Exp $ + * ebus.h: PCI to Ebus pseudo driver software state. + * + * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) + * Copyright (C) 1999 David S. Miller (davem@redhat.com) + */ + +#ifndef __SPARC64_EBUS_H +#define __SPARC64_EBUS_H + +#include <asm/pbm.h> +#include <asm/oplib.h> + +struct linux_ebus_child { + struct linux_ebus_child *next; + struct linux_ebus_device *parent; + struct linux_ebus *bus; + int prom_node; + char prom_name[64]; + struct resource resource[PROMREG_MAX]; + int num_addrs; + unsigned int irqs[PROMINTR_MAX]; + int num_irqs; +}; + +struct linux_ebus_device { + struct linux_ebus_device *next; + struct linux_ebus_child *children; + struct linux_ebus *bus; + int prom_node; + char prom_name[64]; + struct resource resource[PROMREG_MAX]; + int num_addrs; + unsigned int irqs[PROMINTR_MAX]; + int num_irqs; +}; + +struct linux_ebus { + struct linux_ebus *next; + struct linux_ebus_device *devices; + struct pci_pbm_info *parent; + struct pci_dev *self; + int index; + int is_rio; + int prom_node; + char prom_name[64]; + struct linux_prom_ebus_ranges ebus_ranges[PROMREG_MAX]; + int num_ebus_ranges; + struct linux_prom_ebus_intmap ebus_intmap[PROMREG_MAX]; + int num_ebus_intmap; + struct linux_prom_ebus_intmask ebus_intmask; +}; + +struct ebus_dma_info { + spinlock_t lock; + void __iomem *regs; + + unsigned int flags; +#define EBUS_DMA_FLAG_USE_EBDMA_HANDLER 0x00000001 +#define EBUS_DMA_FLAG_TCI_DISABLE 0x00000002 + + /* These are only valid is EBUS_DMA_FLAG_USE_EBDMA_HANDLER is + * set. + */ + void (*callback)(struct ebus_dma_info *p, int event, void *cookie); + void *client_cookie; + unsigned int irq; +#define EBUS_DMA_EVENT_ERROR 1 +#define EBUS_DMA_EVENT_DMA 2 +#define EBUS_DMA_EVENT_DEVICE 4 + + unsigned char name[64]; +}; + +extern int ebus_dma_register(struct ebus_dma_info *p); +extern int ebus_dma_irq_enable(struct ebus_dma_info *p, int on); +extern void ebus_dma_unregister(struct ebus_dma_info *p); +extern int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr, + size_t len); +extern void ebus_dma_prepare(struct ebus_dma_info *p, int write); +extern unsigned int ebus_dma_residue(struct ebus_dma_info *p); +extern void ebus_dma_enable(struct ebus_dma_info *p, int on); + +extern struct linux_ebus *ebus_chain; + +extern void ebus_init(void); + +#define for_each_ebus(bus) \ + for((bus) = ebus_chain; (bus); (bus) = (bus)->next) + +#define for_each_ebusdev(dev, bus) \ + for((dev) = (bus)->devices; (dev); (dev) = (dev)->next) + +#define for_each_edevchild(dev, child) \ + for((child) = (dev)->children; (child); (child) = (child)->next) + +#endif /* !(__SPARC64_EBUS_H) */ diff --git a/include/asm-sparc64/elf.h b/include/asm-sparc64/elf.h new file mode 100644 index 000000000000..91458118277e --- /dev/null +++ b/include/asm-sparc64/elf.h @@ -0,0 +1,181 @@ +/* $Id: elf.h,v 1.32 2002/02/09 19:49:31 davem Exp $ */ +#ifndef __ASM_SPARC64_ELF_H +#define __ASM_SPARC64_ELF_H + +/* + * ELF register definitions.. + */ + +#include <asm/ptrace.h> +#ifdef __KERNEL__ +#include <asm/processor.h> +#include <asm/uaccess.h> +#endif + +/* + * Sparc section types + */ +#define STT_REGISTER 13 + +/* + * Sparc ELF relocation types + */ +#define R_SPARC_NONE 0 +#define R_SPARC_8 1 +#define R_SPARC_16 2 +#define R_SPARC_32 3 +#define R_SPARC_DISP8 4 +#define R_SPARC_DISP16 5 +#define R_SPARC_DISP32 6 +#define R_SPARC_WDISP30 7 +#define R_SPARC_WDISP22 8 +#define R_SPARC_HI22 9 +#define R_SPARC_22 10 +#define R_SPARC_13 11 +#define R_SPARC_LO10 12 +#define R_SPARC_GOT10 13 +#define R_SPARC_GOT13 14 +#define R_SPARC_GOT22 15 +#define R_SPARC_PC10 16 +#define R_SPARC_PC22 17 +#define R_SPARC_WPLT30 18 +#define R_SPARC_COPY 19 +#define R_SPARC_GLOB_DAT 20 +#define R_SPARC_JMP_SLOT 21 +#define R_SPARC_RELATIVE 22 +#define R_SPARC_UA32 23 +#define R_SPARC_PLT32 24 +#define R_SPARC_HIPLT22 25 +#define R_SPARC_LOPLT10 26 +#define R_SPARC_PCPLT32 27 +#define R_SPARC_PCPLT22 28 +#define R_SPARC_PCPLT10 29 +#define R_SPARC_10 30 +#define R_SPARC_11 31 +#define R_SPARC_64 32 +#define R_SPARC_OLO10 33 +#define R_SPARC_WDISP16 40 +#define R_SPARC_WDISP19 41 +#define R_SPARC_7 43 +#define R_SPARC_5 44 +#define R_SPARC_6 45 + +/* Bits present in AT_HWCAP, primarily for Sparc32. */ + +#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */ +#define HWCAP_SPARC_STBAR 2 +#define HWCAP_SPARC_SWAP 4 +#define HWCAP_SPARC_MULDIV 8 +#define HWCAP_SPARC_V9 16 +#define HWCAP_SPARC_ULTRA3 32 + +/* + * These are used to set parameters in the core dumps. + */ +#ifndef ELF_ARCH +#define ELF_ARCH EM_SPARCV9 +#define ELF_CLASS ELFCLASS64 +#define ELF_DATA ELFDATA2MSB + +typedef unsigned long elf_greg_t; + +#define ELF_NGREG 36 +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; +/* Format of 64-bit elf_gregset_t is: + * G0 --> G7 + * O0 --> O7 + * L0 --> L7 + * I0 --> I7 + * TSTATE + * TPC + * TNPC + * Y + */ +#define ELF_CORE_COPY_REGS(__elf_regs, __pt_regs) \ +do { unsigned long *dest = &(__elf_regs[0]); \ + struct pt_regs *src = (__pt_regs); \ + unsigned long __user *sp; \ + int i; \ + for(i = 0; i < 16; i++) \ + dest[i] = src->u_regs[i]; \ + /* Don't try this at home kids... */ \ + sp = (unsigned long __user *) \ + ((src->u_regs[14] + STACK_BIAS) \ + & 0xfffffffffffffff8UL); \ + for(i = 0; i < 16; i++) \ + __get_user(dest[i+16], &sp[i]); \ + dest[32] = src->tstate; \ + dest[33] = src->tpc; \ + dest[34] = src->tnpc; \ + dest[35] = src->y; \ +} while (0); + +typedef struct { + unsigned long pr_regs[32]; + unsigned long pr_fsr; + unsigned long pr_gsr; + unsigned long pr_fprs; +} elf_fpregset_t; +#endif + +#define ELF_CORE_COPY_TASK_REGS(__tsk, __elf_regs) \ + ({ ELF_CORE_COPY_REGS((*(__elf_regs)), (__tsk)->thread_info->kregs); 1; }) + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#ifndef elf_check_arch +#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH) /* Might be EM_SPARCV9 or EM_SPARC */ +#endif + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE PAGE_SIZE + +/* This is the location that an ET_DYN program is loaded if exec'ed. Typical + use of this is to invoke "./ld.so someprog" to test out a new version of + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +#ifndef ELF_ET_DYN_BASE +#define ELF_ET_DYN_BASE 0x0000010000000000UL +#endif + + +/* This yields a mask that user programs can use to figure out what + instruction set this cpu supports. */ + +/* On Ultra, we support all of the v8 capabilities. */ +#define ELF_HWCAP ((HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \ + HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | \ + HWCAP_SPARC_V9) | \ + ((tlb_type == cheetah || tlb_type == cheetah_plus) ? \ + HWCAP_SPARC_ULTRA3 : 0)) + +/* This yields a string that ld.so will use to load implementation + specific libraries for optimization. This is more specific in + intent than poking at uname or /proc/cpuinfo. */ + +#define ELF_PLATFORM (NULL) + +#ifdef __KERNEL__ +#define SET_PERSONALITY(ex, ibcs2) \ +do { unsigned long new_flags = current_thread_info()->flags; \ + new_flags &= _TIF_32BIT; \ + if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ + new_flags |= _TIF_32BIT; \ + else \ + new_flags &= ~_TIF_32BIT; \ + if ((current_thread_info()->flags & _TIF_32BIT) \ + != new_flags) \ + set_thread_flag(TIF_ABI_PENDING); \ + else \ + clear_thread_flag(TIF_ABI_PENDING); \ + /* flush_thread will update pgd cache */ \ + if (ibcs2) \ + set_personality(PER_SVR4); \ + else if (current->personality != PER_LINUX32) \ + set_personality(PER_LINUX); \ +} while (0) +#endif + +#endif /* !(__ASM_SPARC64_ELF_H) */ diff --git a/include/asm-sparc64/envctrl.h b/include/asm-sparc64/envctrl.h new file mode 100644 index 000000000000..53a6653815eb --- /dev/null +++ b/include/asm-sparc64/envctrl.h @@ -0,0 +1,103 @@ +/* $Id: envctrl.h,v 1.3 2000/11/03 00:37:40 davem Exp $ + * + * envctrl.h: Definitions for access to the i2c environment + * monitoring on Ultrasparc systems. + * + * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) + * Copyright (C) 2000 Vinh Truong (vinh.truong@eng.sun.com) + * VT - Add all ioctl commands and environment status definitions + * VT - Add application note + */ +#ifndef _SPARC64_ENVCTRL_H +#define _SPARC64_ENVCTRL_H 1 + +#include <linux/ioctl.h> + +/* Application note: + * + * The driver supports 4 operations: open(), close(), ioctl(), read() + * The device name is /dev/envctrl. + * Below is sample usage: + * + * fd = open("/dev/envtrl", O_RDONLY); + * if (ioctl(fd, ENVCTRL_READ_SHUTDOWN_TEMPERATURE, 0) < 0) + * printf("error\n"); + * ret = read(fd, buf, 10); + * close(fd); + * + * Notice in the case of cpu voltage and temperature, the default is + * cpu0. If we need to know the info of cpu1, cpu2, cpu3, we need to + * pass in cpu number in ioctl() last parameter. For example, to + * get the voltage of cpu2: + * + * ioctlbuf[0] = 2; + * if (ioctl(fd, ENVCTRL_READ_CPU_VOLTAGE, ioctlbuf) < 0) + * printf("error\n"); + * ret = read(fd, buf, 10); + * + * All the return values are in ascii. So check read return value + * and do appropriate conversions in your application. + */ + +/* IOCTL commands */ + +/* Note: these commands reflect possible monitor features. + * Some boards choose to support some of the features only. + */ +#define ENVCTRL_RD_CPU_TEMPERATURE _IOR('p', 0x40, int) +#define ENVCTRL_RD_CPU_VOLTAGE _IOR('p', 0x41, int) +#define ENVCTRL_RD_FAN_STATUS _IOR('p', 0x42, int) +#define ENVCTRL_RD_WARNING_TEMPERATURE _IOR('p', 0x43, int) +#define ENVCTRL_RD_SHUTDOWN_TEMPERATURE _IOR('p', 0x44, int) +#define ENVCTRL_RD_VOLTAGE_STATUS _IOR('p', 0x45, int) +#define ENVCTRL_RD_SCSI_TEMPERATURE _IOR('p', 0x46, int) +#define ENVCTRL_RD_ETHERNET_TEMPERATURE _IOR('p', 0x47, int) +#define ENVCTRL_RD_MTHRBD_TEMPERATURE _IOR('p', 0x48, int) + +#define ENVCTRL_RD_GLOBALADDRESS _IOR('p', 0x49, int) + +/* Read return values for a voltage status request. */ +#define ENVCTRL_VOLTAGE_POWERSUPPLY_GOOD 0x01 +#define ENVCTRL_VOLTAGE_BAD 0x02 +#define ENVCTRL_POWERSUPPLY_BAD 0x03 +#define ENVCTRL_VOLTAGE_POWERSUPPLY_BAD 0x04 + +/* Read return values for a fan status request. + * A failure match means either the fan fails or + * the fan is not connected. Some boards have optional + * connectors to connect extra fans. + * + * There are maximum 8 monitor fans. Some are cpu fans + * some are system fans. The mask below only indicates + * fan by order number. + * Below is a sample application: + * + * if (ioctl(fd, ENVCTRL_READ_FAN_STATUS, 0) < 0) { + * printf("ioctl fan failed\n"); + * } + * if (read(fd, rslt, 1) <= 0) { + * printf("error or fan not monitored\n"); + * } else { + * if (rslt[0] == ENVCTRL_ALL_FANS_GOOD) { + * printf("all fans good\n"); + * } else if (rslt[0] == ENVCTRL_ALL_FANS_BAD) { + * printf("all fans bad\n"); + * } else { + * if (rslt[0] & ENVCTRL_FAN0_FAILURE_MASK) { + * printf("fan 0 failed or not connected\n"); + * } + * ...... + */ + +#define ENVCTRL_ALL_FANS_GOOD 0x00 +#define ENVCTRL_FAN0_FAILURE_MASK 0x01 +#define ENVCTRL_FAN1_FAILURE_MASK 0x02 +#define ENVCTRL_FAN2_FAILURE_MASK 0x04 +#define ENVCTRL_FAN3_FAILURE_MASK 0x08 +#define ENVCTRL_FAN4_FAILURE_MASK 0x10 +#define ENVCTRL_FAN5_FAILURE_MASK 0x20 +#define ENVCTRL_FAN6_FAILURE_MASK 0x40 +#define ENVCTRL_FAN7_FAILURE_MASK 0x80 +#define ENVCTRL_ALL_FANS_BAD 0xFF + +#endif /* !(_SPARC64_ENVCTRL_H) */ diff --git a/include/asm-sparc64/errno.h b/include/asm-sparc64/errno.h new file mode 100644 index 000000000000..cc98a73b55a7 --- /dev/null +++ b/include/asm-sparc64/errno.h @@ -0,0 +1,110 @@ +/* $Id: errno.h,v 1.2 1997/04/15 12:46:11 jj Exp $ */ +#ifndef _SPARC64_ERRNO_H +#define _SPARC64_ERRNO_H + +/* These match the SunOS error numbering scheme. */ + +#include <asm-generic/errno-base.h> + +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define EINPROGRESS 36 /* Operation now in progress */ +#define EALREADY 37 /* Operation already in progress */ +#define ENOTSOCK 38 /* Socket operation on non-socket */ +#define EDESTADDRREQ 39 /* Destination address required */ +#define EMSGSIZE 40 /* Message too long */ +#define EPROTOTYPE 41 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 42 /* Protocol not available */ +#define EPROTONOSUPPORT 43 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 44 /* Socket type not supported */ +#define EOPNOTSUPP 45 /* Op not supported on transport endpoint */ +#define EPFNOSUPPORT 46 /* Protocol family not supported */ +#define EAFNOSUPPORT 47 /* Address family not supported by protocol */ +#define EADDRINUSE 48 /* Address already in use */ +#define EADDRNOTAVAIL 49 /* Cannot assign requested address */ +#define ENETDOWN 50 /* Network is down */ +#define ENETUNREACH 51 /* Network is unreachable */ +#define ENETRESET 52 /* Net dropped connection because of reset */ +#define ECONNABORTED 53 /* Software caused connection abort */ +#define ECONNRESET 54 /* Connection reset by peer */ +#define ENOBUFS 55 /* No buffer space available */ +#define EISCONN 56 /* Transport endpoint is already connected */ +#define ENOTCONN 57 /* Transport endpoint is not connected */ +#define ESHUTDOWN 58 /* No send after transport endpoint shutdown */ +#define ETOOMANYREFS 59 /* Too many references: cannot splice */ +#define ETIMEDOUT 60 /* Connection timed out */ +#define ECONNREFUSED 61 /* Connection refused */ +#define ELOOP 62 /* Too many symbolic links encountered */ +#define ENAMETOOLONG 63 /* File name too long */ +#define EHOSTDOWN 64 /* Host is down */ +#define EHOSTUNREACH 65 /* No route to host */ +#define ENOTEMPTY 66 /* Directory not empty */ +#define EPROCLIM 67 /* SUNOS: Too many processes */ +#define EUSERS 68 /* Too many users */ +#define EDQUOT 69 /* Quota exceeded */ +#define ESTALE 70 /* Stale NFS file handle */ +#define EREMOTE 71 /* Object is remote */ +#define ENOSTR 72 /* Device not a stream */ +#define ETIME 73 /* Timer expired */ +#define ENOSR 74 /* Out of streams resources */ +#define ENOMSG 75 /* No message of desired type */ +#define EBADMSG 76 /* Not a data message */ +#define EIDRM 77 /* Identifier removed */ +#define EDEADLK 78 /* Resource deadlock would occur */ +#define ENOLCK 79 /* No record locks available */ +#define ENONET 80 /* Machine is not on the network */ +#define ERREMOTE 81 /* SunOS: Too many lvls of remote in path */ +#define ENOLINK 82 /* Link has been severed */ +#define EADV 83 /* Advertise error */ +#define ESRMNT 84 /* Srmount error */ +#define ECOMM 85 /* Communication error on send */ +#define EPROTO 86 /* Protocol error */ +#define EMULTIHOP 87 /* Multihop attempted */ +#define EDOTDOT 88 /* RFS specific error */ +#define EREMCHG 89 /* Remote address changed */ +#define ENOSYS 90 /* Function not implemented */ + +/* The rest have no SunOS equivalent. */ +#define ESTRPIPE 91 /* Streams pipe error */ +#define EOVERFLOW 92 /* Value too large for defined data type */ +#define EBADFD 93 /* File descriptor in bad state */ +#define ECHRNG 94 /* Channel number out of range */ +#define EL2NSYNC 95 /* Level 2 not synchronized */ +#define EL3HLT 96 /* Level 3 halted */ +#define EL3RST 97 /* Level 3 reset */ +#define ELNRNG 98 /* Link number out of range */ +#define EUNATCH 99 /* Protocol driver not attached */ +#define ENOCSI 100 /* No CSI structure available */ +#define EL2HLT 101 /* Level 2 halted */ +#define EBADE 102 /* Invalid exchange */ +#define EBADR 103 /* Invalid request descriptor */ +#define EXFULL 104 /* Exchange full */ +#define ENOANO 105 /* No anode */ +#define EBADRQC 106 /* Invalid request code */ +#define EBADSLT 107 /* Invalid slot */ +#define EDEADLOCK 108 /* File locking deadlock error */ +#define EBFONT 109 /* Bad font file format */ +#define ELIBEXEC 110 /* Cannot exec a shared library directly */ +#define ENODATA 111 /* No data available */ +#define ELIBBAD 112 /* Accessing a corrupted shared library */ +#define ENOPKG 113 /* Package not installed */ +#define ELIBACC 114 /* Can not access a needed shared library */ +#define ENOTUNIQ 115 /* Name not unique on network */ +#define ERESTART 116 /* Interrupted syscall should be restarted */ +#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 EILSEQ 122 /* Illegal byte sequence */ +#define ELIBMAX 123 /* Atmpt to link in too many shared libs */ +#define ELIBSCN 124 /* .lib section in a.out corrupted */ + +#define ENOMEDIUM 125 /* No medium found */ +#define EMEDIUMTYPE 126 /* Wrong medium type */ +#define ECANCELED 127 /* Operation Cancelled */ +#define ENOKEY 128 /* Required key not available */ +#define EKEYEXPIRED 129 /* Key has expired */ +#define EKEYREVOKED 130 /* Key has been revoked */ +#define EKEYREJECTED 131 /* Key was rejected by service */ + +#endif /* !(_SPARC64_ERRNO_H) */ diff --git a/include/asm-sparc64/estate.h b/include/asm-sparc64/estate.h new file mode 100644 index 000000000000..a719c3d2f6b1 --- /dev/null +++ b/include/asm-sparc64/estate.h @@ -0,0 +1,50 @@ +/* $Id: estate.h,v 1.1 2001/03/28 10:56:34 davem Exp $ */ +#ifndef _SPARC64_ESTATE_H +#define _SPARC64_ESTATE_H + +/* UltraSPARC-III E-cache Error Enable */ +#define ESTATE_ERROR_FMT 0x0000000000040000 /* Force MTAG ECC */ +#define ESTATE_ERROR_FMESS 0x000000000003c000 /* Forced MTAG ECC val */ +#define ESTATE_ERROR_FMD 0x0000000000002000 /* Force DATA ECC */ +#define ESTATE_ERROR_FDECC 0x0000000000001ff0 /* Forced DATA ECC val */ +#define ESTATE_ERROR_UCEEN 0x0000000000000008 /* See below */ +#define ESTATE_ERROR_NCEEN 0x0000000000000002 /* See below */ +#define ESTATE_ERROR_CEEN 0x0000000000000001 /* See below */ + +/* UCEEN enables the fast_ECC_error trap for: 1) software correctable E-cache + * errors 2) uncorrectable E-cache errors. Such events only occur on reads + * of the E-cache by the local processor for: 1) data loads 2) instruction + * fetches 3) atomic operations. Such events _cannot_ occur for: 1) merge + * 2) writeback 2) copyout. The AFSR bits associated with these traps are + * UCC and UCU. + */ + +/* NCEEN enables instruction_access_error, data_access_error, and ECC_error traps + * for uncorrectable ECC errors and system errors. + * + * Uncorrectable system bus data error or MTAG ECC error, system bus TimeOUT, + * or system bus BusERR: + * 1) As the result of an instruction fetch, will generate instruction_access_error + * 2) As the result of a load etc. will generate data_access_error. + * 3) As the result of store merge completion, writeback, or copyout will + * generate a disrupting ECC_error trap. + * 4) As the result of such errors on instruction vector fetch can generate any + * of the 3 trap types. + * + * The AFSR bits associated with these traps are EMU, EDU, WDU, CPU, IVU, UE, + * BERR, and TO. + */ + +/* CEEN enables the ECC_error trap for hardware corrected ECC errors. System bus + * reads resulting in a hardware corrected data or MTAG ECC error will generate an + * ECC_error disrupting trap with this bit enabled. + * + * This same trap will also be generated when a hardware corrected ECC error results + * during store merge, writeback, and copyout operations. + */ + +/* In general, if the trap enable bits above are disabled the AFSR bits will still + * log the events even though the trap will not be generated by the processor. + */ + +#endif /* _SPARC64_ESTATE_H */ diff --git a/include/asm-sparc64/fbio.h b/include/asm-sparc64/fbio.h new file mode 100644 index 000000000000..500026d9f6e1 --- /dev/null +++ b/include/asm-sparc64/fbio.h @@ -0,0 +1,302 @@ +#ifndef __LINUX_FBIO_H +#define __LINUX_FBIO_H + +#include <linux/compiler.h> + +/* Constants used for fbio SunOS compatibility */ +/* (C) 1996 Miguel de Icaza */ + +/* Frame buffer types */ +#define FBTYPE_NOTYPE -1 +#define FBTYPE_SUN1BW 0 /* mono */ +#define FBTYPE_SUN1COLOR 1 +#define FBTYPE_SUN2BW 2 +#define FBTYPE_SUN2COLOR 3 +#define FBTYPE_SUN2GP 4 +#define FBTYPE_SUN5COLOR 5 +#define FBTYPE_SUN3COLOR 6 +#define FBTYPE_MEMCOLOR 7 +#define FBTYPE_SUN4COLOR 8 + +#define FBTYPE_NOTSUN1 9 +#define FBTYPE_NOTSUN2 10 +#define FBTYPE_NOTSUN3 11 + +#define FBTYPE_SUNFAST_COLOR 12 /* cg6 */ +#define FBTYPE_SUNROP_COLOR 13 +#define FBTYPE_SUNFB_VIDEO 14 +#define FBTYPE_SUNGIFB 15 +#define FBTYPE_SUNGPLAS 16 +#define FBTYPE_SUNGP3 17 +#define FBTYPE_SUNGT 18 +#define FBTYPE_SUNLEO 19 /* zx Leo card */ +#define FBTYPE_MDICOLOR 20 /* cg14 */ +#define FBTYPE_TCXCOLOR 21 /* SUNW,tcx card */ + +#define FBTYPE_LASTPLUSONE 21 /* This is not last + 1 in fact... */ + +/* Does not seem to be listed in the Sun file either */ +#define FBTYPE_CREATOR 22 +#define FBTYPE_PCI_IGA1682 23 +#define FBTYPE_P9100COLOR 24 + +#define FBTYPE_PCI_GENERIC 1000 +#define FBTYPE_PCI_MACH64 1001 + +/* fbio ioctls */ +/* Returned by FBIOGTYPE */ +struct fbtype { + int fb_type; /* fb type, see above */ + int fb_height; /* pixels */ + int fb_width; /* pixels */ + int fb_depth; + int fb_cmsize; /* color map entries */ + int fb_size; /* fb size in bytes */ +}; +#define FBIOGTYPE _IOR('F', 0, struct fbtype) + +struct fbcmap { + int index; /* first element (0 origin) */ + int count; + unsigned char __user *red; + unsigned char __user *green; + unsigned char __user *blue; +}; + +#ifdef __KERNEL__ +#define FBIOPUTCMAP_SPARC _IOW('F', 3, struct fbcmap) +#define FBIOGETCMAP_SPARC _IOW('F', 4, struct fbcmap) +#else +#define FBIOPUTCMAP _IOW('F', 3, struct fbcmap) +#define FBIOGETCMAP _IOW('F', 4, struct fbcmap) +#endif + +/* # of device specific values */ +#define FB_ATTR_NDEVSPECIFIC 8 +/* # of possible emulations */ +#define FB_ATTR_NEMUTYPES 4 + +struct fbsattr { + int flags; + int emu_type; /* -1 if none */ + int dev_specific[FB_ATTR_NDEVSPECIFIC]; +}; + +struct fbgattr { + int real_type; /* real frame buffer type */ + int owner; /* unknown */ + struct fbtype fbtype; /* real frame buffer fbtype */ + struct fbsattr sattr; + int emu_types[FB_ATTR_NEMUTYPES]; /* supported emulations */ +}; +#define FBIOSATTR _IOW('F', 5, struct fbgattr) /* Unsupported: */ +#define FBIOGATTR _IOR('F', 6, struct fbgattr) /* supported */ + +#define FBIOSVIDEO _IOW('F', 7, int) +#define FBIOGVIDEO _IOR('F', 8, int) + +struct fbcursor { + short set; /* what to set, choose from the list above */ + short enable; /* cursor on/off */ + struct fbcurpos pos; /* cursor position */ + struct fbcurpos hot; /* cursor hot spot */ + struct fbcmap cmap; /* color map info */ + struct fbcurpos size; /* cursor bit map size */ + char __user *image; /* cursor image bits */ + char __user *mask; /* cursor mask bits */ +}; + +/* set/get cursor attributes/shape */ +#define FBIOSCURSOR _IOW('F', 24, struct fbcursor) +#define FBIOGCURSOR _IOWR('F', 25, struct fbcursor) + +/* set/get cursor position */ +#define FBIOSCURPOS _IOW('F', 26, struct fbcurpos) +#define FBIOGCURPOS _IOW('F', 27, struct fbcurpos) + +/* get max cursor size */ +#define FBIOGCURMAX _IOR('F', 28, struct fbcurpos) + +/* wid manipulation */ +struct fb_wid_alloc { +#define FB_WID_SHARED_8 0 +#define FB_WID_SHARED_24 1 +#define FB_WID_DBL_8 2 +#define FB_WID_DBL_24 3 + __u32 wa_type; + __s32 wa_index; /* Set on return */ + __u32 wa_count; +}; +struct fb_wid_item { + __u32 wi_type; + __s32 wi_index; + __u32 wi_attrs; + __u32 wi_values[32]; +}; +struct fb_wid_list { + __u32 wl_flags; + __u32 wl_count; + struct fb_wid_item *wl_list; +}; + +#define FBIO_WID_ALLOC _IOWR('F', 30, struct fb_wid_alloc) +#define FBIO_WID_FREE _IOW('F', 31, struct fb_wid_alloc) +#define FBIO_WID_PUT _IOW('F', 32, struct fb_wid_list) +#define FBIO_WID_GET _IOWR('F', 33, struct fb_wid_list) + +/* Creator ioctls */ +#define FFB_IOCTL ('F'<<8) +#define FFB_SYS_INFO (FFB_IOCTL|80) +#define FFB_CLUTREAD (FFB_IOCTL|81) +#define FFB_CLUTPOST (FFB_IOCTL|82) +#define FFB_SETDIAGMODE (FFB_IOCTL|83) +#define FFB_GETMONITORID (FFB_IOCTL|84) +#define FFB_GETVIDEOMODE (FFB_IOCTL|85) +#define FFB_SETVIDEOMODE (FFB_IOCTL|86) +#define FFB_SETSERVER (FFB_IOCTL|87) +#define FFB_SETOVCTL (FFB_IOCTL|88) +#define FFB_GETOVCTL (FFB_IOCTL|89) +#define FFB_GETSAXNUM (FFB_IOCTL|90) +#define FFB_FBDEBUG (FFB_IOCTL|91) + +/* Cg14 ioctls */ +#define MDI_IOCTL ('M'<<8) +#define MDI_RESET (MDI_IOCTL|1) +#define MDI_GET_CFGINFO (MDI_IOCTL|2) +#define MDI_SET_PIXELMODE (MDI_IOCTL|3) +# define MDI_32_PIX 32 +# define MDI_16_PIX 16 +# define MDI_8_PIX 8 + +struct mdi_cfginfo { + int mdi_ncluts; /* Number of implemented CLUTs in this MDI */ + int mdi_type; /* FBTYPE name */ + int mdi_height; /* height */ + int mdi_width; /* widht */ + int mdi_size; /* available ram */ + int mdi_mode; /* 8bpp, 16bpp or 32bpp */ + int mdi_pixfreq; /* pixel clock (from PROM) */ +}; + +/* SparcLinux specific ioctl for the MDI, should be replaced for + * the SET_XLUT/SET_CLUTn ioctls instead + */ +#define MDI_CLEAR_XLUT (MDI_IOCTL|9) + +/* leo & ffb ioctls */ +struct fb_clut_alloc { + __u32 clutid; /* Set on return */ + __u32 flag; + __u32 index; +}; + +struct fb_clut { +#define FB_CLUT_WAIT 0x00000001 /* Not yet implemented */ + __u32 flag; + __u32 clutid; + __u32 offset; + __u32 count; + char * red; + char * green; + char * blue; +}; + +struct fb_clut32 { + __u32 flag; + __u32 clutid; + __u32 offset; + __u32 count; + __u32 red; + __u32 green; + __u32 blue; +}; + +#define LEO_CLUTALLOC _IOWR('L', 53, struct fb_clut_alloc) +#define LEO_CLUTFREE _IOW('L', 54, struct fb_clut_alloc) +#define LEO_CLUTREAD _IOW('L', 55, struct fb_clut) +#define LEO_CLUTPOST _IOW('L', 56, struct fb_clut) +#define LEO_SETGAMMA _IOW('L', 68, int) /* Not yet implemented */ +#define LEO_GETGAMMA _IOR('L', 69, int) /* Not yet implemented */ + +#ifdef __KERNEL__ +/* Addresses on the fd of a cgsix that are mappable */ +#define CG6_FBC 0x70000000 +#define CG6_TEC 0x70001000 +#define CG6_BTREGS 0x70002000 +#define CG6_FHC 0x70004000 +#define CG6_THC 0x70005000 +#define CG6_ROM 0x70006000 +#define CG6_RAM 0x70016000 +#define CG6_DHC 0x80000000 + +#define CG3_MMAP_OFFSET 0x4000000 + +/* Addresses on the fd of a tcx that are mappable */ +#define TCX_RAM8BIT 0x00000000 +#define TCX_RAM24BIT 0x01000000 +#define TCX_UNK3 0x10000000 +#define TCX_UNK4 0x20000000 +#define TCX_CONTROLPLANE 0x28000000 +#define TCX_UNK6 0x30000000 +#define TCX_UNK7 0x38000000 +#define TCX_TEC 0x70000000 +#define TCX_BTREGS 0x70002000 +#define TCX_THC 0x70004000 +#define TCX_DHC 0x70008000 +#define TCX_ALT 0x7000a000 +#define TCX_SYNC 0x7000e000 +#define TCX_UNK2 0x70010000 + +/* CG14 definitions */ + +/* Offsets into the OBIO space: */ +#define CG14_REGS 0 /* registers */ +#define CG14_CURSORREGS 0x1000 /* cursor registers */ +#define CG14_DACREGS 0x2000 /* DAC registers */ +#define CG14_XLUT 0x3000 /* X Look Up Table -- ??? */ +#define CG14_CLUT1 0x4000 /* Color Look Up Table */ +#define CG14_CLUT2 0x5000 /* Color Look Up Table */ +#define CG14_CLUT3 0x6000 /* Color Look Up Table */ +#define CG14_AUTO 0xf000 + +#endif /* KERNEL */ + +/* These are exported to userland for applications to use */ +/* Mappable offsets for the cg14: control registers */ +#define MDI_DIRECT_MAP 0x10000000 +#define MDI_CTLREG_MAP 0x20000000 +#define MDI_CURSOR_MAP 0x30000000 +#define MDI_SHDW_VRT_MAP 0x40000000 + +/* Mappable offsets for the cg14: frame buffer resolutions */ +/* 32 bits */ +#define MDI_CHUNKY_XBGR_MAP 0x50000000 +#define MDI_CHUNKY_BGR_MAP 0x60000000 + +/* 16 bits */ +#define MDI_PLANAR_X16_MAP 0x70000000 +#define MDI_PLANAR_C16_MAP 0x80000000 + +/* 8 bit is done as CG3 MMAP offset */ +/* 32 bits, planar */ +#define MDI_PLANAR_X32_MAP 0x90000000 +#define MDI_PLANAR_B32_MAP 0xa0000000 +#define MDI_PLANAR_G32_MAP 0xb0000000 +#define MDI_PLANAR_R32_MAP 0xc0000000 + +/* Mappable offsets on leo */ +#define LEO_SS0_MAP 0x00000000 +#define LEO_LC_SS0_USR_MAP 0x00800000 +#define LEO_LD_SS0_MAP 0x00801000 +#define LEO_LX_CURSOR_MAP 0x00802000 +#define LEO_SS1_MAP 0x00803000 +#define LEO_LC_SS1_USR_MAP 0x01003000 +#define LEO_LD_SS1_MAP 0x01004000 +#define LEO_UNK_MAP 0x01005000 +#define LEO_LX_KRN_MAP 0x01006000 +#define LEO_LC_SS0_KRN_MAP 0x01007000 +#define LEO_LC_SS1_KRN_MAP 0x01008000 +#define LEO_LD_GBL_MAP 0x01009000 +#define LEO_UNK2_MAP 0x0100a000 + +#endif /* __LINUX_FBIO_H */ diff --git a/include/asm-sparc64/fcntl.h b/include/asm-sparc64/fcntl.h new file mode 100644 index 000000000000..e36def0d0d80 --- /dev/null +++ b/include/asm-sparc64/fcntl.h @@ -0,0 +1,78 @@ +/* $Id: fcntl.h,v 1.12 2001/09/20 00:35:34 davem Exp $ */ +#ifndef _SPARC64_FCNTL_H +#define _SPARC64_FCNTL_H + +/* open/fcntl - O_SYNC is only implemented on blocks devices and on files + located on an ext2 file system */ +#define O_RDONLY 0x0000 +#define O_WRONLY 0x0001 +#define O_RDWR 0x0002 +#define O_ACCMODE 0x0003 +#define O_NDELAY 0x0004 +#define O_APPEND 0x0008 +#define FASYNC 0x0040 /* fcntl, for BSD compatibility */ +#define O_CREAT 0x0200 /* not fcntl */ +#define O_TRUNC 0x0400 /* not fcntl */ +#define O_EXCL 0x0800 /* not fcntl */ +#define O_SYNC 0x2000 +#define O_NONBLOCK 0x4000 +#define O_NOCTTY 0x8000 /* not fcntl */ +#define O_DIRECTORY 0x10000 /* must be a directory */ +#define O_NOFOLLOW 0x20000 /* don't follow links */ +#define O_LARGEFILE 0x40000 +#define O_DIRECT 0x100000 /* direct disk access hint */ +#define O_NOATIME 0x200000 + + +#define F_DUPFD 0 /* dup */ +#define F_GETFD 1 /* get close_on_exec */ +#define F_SETFD 2 /* set/clear close_on_exec */ +#define F_GETFL 3 /* get file->f_flags */ +#define F_SETFL 4 /* set file->f_flags */ +#define F_GETOWN 5 /* for sockets. */ +#define F_SETOWN 6 /* for sockets. */ +#define F_GETLK 7 +#define F_SETLK 8 +#define F_SETLKW 9 +#define F_SETSIG 10 /* for sockets. */ +#define F_GETSIG 11 /* for sockets. */ + +/* for F_[GET|SET]FL */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* for posix fcntl() and lockf() */ +#define F_RDLCK 1 +#define F_WRLCK 2 +#define F_UNLCK 3 + +/* for old implementation of bsd flock () */ +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ + +/* for leases */ +#define F_INPROGRESS 16 + +/* 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 */ + +#define LOCK_MAND 32 /* This is a mandatory flock */ +#define LOCK_READ 64 /* ... Which allows concurrent read operations */ +#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */ +#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */ + +struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; + short __unused; +}; + +#define F_LINUX_SPECIFIC_BASE 1024 + +#endif /* !(_SPARC64_FCNTL_H) */ diff --git a/include/asm-sparc64/fhc.h b/include/asm-sparc64/fhc.h new file mode 100644 index 000000000000..f29eaa254055 --- /dev/null +++ b/include/asm-sparc64/fhc.h @@ -0,0 +1,132 @@ +/* $Id: fhc.h,v 1.5 1999/09/21 14:39:29 davem Exp $ + * fhc.h: Structures for central/fhc pseudo driver on Sunfire/Starfire/Wildfire. + * + * Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com) + */ + +#ifndef _SPARC64_FHC_H +#define _SPARC64_FHC_H + +#include <linux/timer.h> + +#include <asm/oplib.h> +#include <asm/upa.h> + +struct linux_fhc; + +/* Clock board register offsets. */ +#define CLOCK_CTRL 0x00UL /* Main control */ +#define CLOCK_STAT1 0x10UL /* Status one */ +#define CLOCK_STAT2 0x20UL /* Status two */ +#define CLOCK_PWRSTAT 0x30UL /* Power status */ +#define CLOCK_PWRPRES 0x40UL /* Power presence */ +#define CLOCK_TEMP 0x50UL /* Temperature */ +#define CLOCK_IRQDIAG 0x60UL /* IRQ diagnostics */ +#define CLOCK_PWRSTAT2 0x70UL /* Power status two */ + +#define CLOCK_CTRL_LLED 0x04 /* Left LED, 0 == on */ +#define CLOCK_CTRL_MLED 0x02 /* Mid LED, 1 == on */ +#define CLOCK_CTRL_RLED 0x01 /* RIght LED, 1 == on */ + +struct linux_central { + struct linux_fhc *child; + unsigned long cfreg; + unsigned long clkregs; + unsigned long clkver; + int slots; + int prom_node; + char prom_name[64]; + + struct linux_prom_ranges central_ranges[PROMREG_MAX]; + int num_central_ranges; +}; + +/* Firehose controller register offsets */ +struct fhc_regs { + unsigned long pregs; /* FHC internal regs */ +#define FHC_PREGS_ID 0x00UL /* FHC ID */ +#define FHC_ID_VERS 0xf0000000 /* Version of this FHC */ +#define FHC_ID_PARTID 0x0ffff000 /* Part ID code (0x0f9f == FHC) */ +#define FHC_ID_MANUF 0x0000007e /* Manufacturer (0x3e == SUN's JEDEC)*/ +#define FHC_ID_RESV 0x00000001 /* Read as one */ +#define FHC_PREGS_RCS 0x10UL /* FHC Reset Control/Status Register */ +#define FHC_RCS_POR 0x80000000 /* Last reset was a power cycle */ +#define FHC_RCS_SPOR 0x40000000 /* Last reset was sw power on reset */ +#define FHC_RCS_SXIR 0x20000000 /* Last reset was sw XIR reset */ +#define FHC_RCS_BPOR 0x10000000 /* Last reset was due to POR button */ +#define FHC_RCS_BXIR 0x08000000 /* Last reset was due to XIR button */ +#define FHC_RCS_WEVENT 0x04000000 /* CPU reset was due to wakeup event */ +#define FHC_RCS_CFATAL 0x02000000 /* Centerplane Fatal Error signalled */ +#define FHC_RCS_FENAB 0x01000000 /* Fatal errors elicit system reset */ +#define FHC_PREGS_CTRL 0x20UL /* FHC Control Register */ +#define FHC_CONTROL_ICS 0x00100000 /* Ignore Centerplane Signals */ +#define FHC_CONTROL_FRST 0x00080000 /* Fatal Error Reset Enable */ +#define FHC_CONTROL_LFAT 0x00040000 /* AC/DC signalled a local error */ +#define FHC_CONTROL_SLINE 0x00010000 /* Firmware Synchronization Line */ +#define FHC_CONTROL_DCD 0x00008000 /* DC-->DC Converter Disable */ +#define FHC_CONTROL_POFF 0x00004000 /* AC/DC Controller PLL Disable */ +#define FHC_CONTROL_FOFF 0x00002000 /* FHC Controller PLL Disable */ +#define FHC_CONTROL_AOFF 0x00001000 /* CPU A SRAM/SBD Low Power Mode */ +#define FHC_CONTROL_BOFF 0x00000800 /* CPU B SRAM/SBD Low Power Mode */ +#define FHC_CONTROL_PSOFF 0x00000400 /* Turns off this FHC's power supply */ +#define FHC_CONTROL_IXIST 0x00000200 /* 0=FHC tells clock board it exists */ +#define FHC_CONTROL_XMSTR 0x00000100 /* 1=Causes this FHC to be XIR master*/ +#define FHC_CONTROL_LLED 0x00000040 /* 0=Left LED ON */ +#define FHC_CONTROL_MLED 0x00000020 /* 1=Middle LED ON */ +#define FHC_CONTROL_RLED 0x00000010 /* 1=Right LED */ +#define FHC_CONTROL_BPINS 0x00000003 /* Spare Bidirectional Pins */ +#define FHC_PREGS_BSR 0x30UL /* FHC Board Status Register */ +#define FHC_BSR_DA64 0x00040000 /* Port A: 0=128bit 1=64bit data path */ +#define FHC_BSR_DB64 0x00020000 /* Port B: 0=128bit 1=64bit data path */ +#define FHC_BSR_BID 0x0001e000 /* Board ID */ +#define FHC_BSR_SA 0x00001c00 /* Port A UPA Speed (from the pins) */ +#define FHC_BSR_SB 0x00000380 /* Port B UPA Speed (from the pins) */ +#define FHC_BSR_NDIAG 0x00000040 /* Not in Diag Mode */ +#define FHC_BSR_NTBED 0x00000020 /* Not in TestBED Mode */ +#define FHC_BSR_NIA 0x0000001c /* Jumper, bit 18 in PROM space */ +#define FHC_BSR_SI 0x00000001 /* Spare input pin value */ +#define FHC_PREGS_ECC 0x40UL /* FHC ECC Control Register (16 bits) */ +#define FHC_PREGS_JCTRL 0xf0UL /* FHC JTAG Control Register */ +#define FHC_JTAG_CTRL_MENAB 0x80000000 /* Indicates this is JTAG Master */ +#define FHC_JTAG_CTRL_MNONE 0x40000000 /* Indicates no JTAG Master present */ +#define FHC_PREGS_JCMD 0x100UL /* FHC JTAG Command Register */ + unsigned long ireg; /* FHC IGN reg */ +#define FHC_IREG_IGN 0x00UL /* This FHC's IGN */ + unsigned long ffregs; /* FHC fanfail regs */ +#define FHC_FFREGS_IMAP 0x00UL /* FHC Fanfail IMAP */ +#define FHC_FFREGS_ICLR 0x10UL /* FHC Fanfail ICLR */ + unsigned long sregs; /* FHC system regs */ +#define FHC_SREGS_IMAP 0x00UL /* FHC System IMAP */ +#define FHC_SREGS_ICLR 0x10UL /* FHC System ICLR */ + unsigned long uregs; /* FHC uart regs */ +#define FHC_UREGS_IMAP 0x00UL /* FHC Uart IMAP */ +#define FHC_UREGS_ICLR 0x10UL /* FHC Uart ICLR */ + unsigned long tregs; /* FHC TOD regs */ +#define FHC_TREGS_IMAP 0x00UL /* FHC TOD IMAP */ +#define FHC_TREGS_ICLR 0x10UL /* FHC TOD ICLR */ +}; + +struct linux_fhc { + struct linux_fhc *next; + struct linux_central *parent; /* NULL if not central FHC */ + struct fhc_regs fhc_regs; + int board; + int jtag_master; + int prom_node; + char prom_name[64]; + + struct linux_prom_ranges fhc_ranges[PROMREG_MAX]; + int num_fhc_ranges; +}; + +extern struct linux_central *central_bus; + +extern void apply_central_ranges(struct linux_central *central, + struct linux_prom_registers *regs, + int nregs); + +extern void apply_fhc_ranges(struct linux_fhc *fhc, + struct linux_prom_registers *regs, + int nregs); + +#endif /* !(_SPARC64_FHC_H) */ diff --git a/include/asm-sparc64/floppy.h b/include/asm-sparc64/floppy.h new file mode 100644 index 000000000000..e071b4b4edfd --- /dev/null +++ b/include/asm-sparc64/floppy.h @@ -0,0 +1,811 @@ +/* $Id: floppy.h,v 1.32 2001/10/26 17:59:36 davem Exp $ + * asm-sparc64/floppy.h: Sparc specific parts of the Floppy driver. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * + * Ultra/PCI support added: Sep 1997 Eddie C. Dost (ecd@skynet.be) + */ + +#ifndef __ASM_SPARC64_FLOPPY_H +#define __ASM_SPARC64_FLOPPY_H + +#include <linux/config.h> +#include <linux/init.h> + +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/idprom.h> +#include <asm/oplib.h> +#include <asm/auxio.h> +#include <asm/sbus.h> +#include <asm/irq.h> + + +/* + * Define this to enable exchanging drive 0 and 1 if only drive 1 is + * probed on PCI machines. + */ +#undef PCI_FDC_SWAP_DRIVES + + +/* References: + * 1) Netbsd Sun floppy driver. + * 2) NCR 82077 controller manual + * 3) Intel 82077 controller manual + */ +struct sun_flpy_controller { + volatile unsigned char status1_82077; /* Auxiliary Status reg. 1 */ + volatile unsigned char status2_82077; /* Auxiliary Status reg. 2 */ + volatile unsigned char dor_82077; /* Digital Output reg. */ + volatile unsigned char tapectl_82077; /* Tape Control reg */ + volatile unsigned char status_82077; /* Main Status Register. */ +#define drs_82077 status_82077 /* Digital Rate Select reg. */ + volatile unsigned char data_82077; /* Data fifo. */ + volatile unsigned char ___unused; + volatile unsigned char dir_82077; /* Digital Input reg. */ +#define dcr_82077 dir_82077 /* Config Control reg. */ +}; + +/* You'll only ever find one controller on an Ultra anyways. */ +static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1; +unsigned long fdc_status; +static struct sbus_dev *floppy_sdev = NULL; + +struct sun_floppy_ops { + unsigned char (*fd_inb) (unsigned long port); + void (*fd_outb) (unsigned char value, unsigned long port); + void (*fd_enable_dma) (void); + void (*fd_disable_dma) (void); + void (*fd_set_dma_mode) (int); + void (*fd_set_dma_addr) (char *); + void (*fd_set_dma_count) (int); + unsigned int (*get_dma_residue) (void); + int (*fd_request_irq) (void); + void (*fd_free_irq) (void); + int (*fd_eject) (int); +}; + +static struct sun_floppy_ops sun_fdops; + +#define fd_inb(port) sun_fdops.fd_inb(port) +#define fd_outb(value,port) sun_fdops.fd_outb(value,port) +#define fd_enable_dma() sun_fdops.fd_enable_dma() +#define fd_disable_dma() sun_fdops.fd_disable_dma() +#define fd_request_dma() (0) /* nothing... */ +#define fd_free_dma() /* nothing... */ +#define fd_clear_dma_ff() /* nothing... */ +#define fd_set_dma_mode(mode) sun_fdops.fd_set_dma_mode(mode) +#define fd_set_dma_addr(addr) sun_fdops.fd_set_dma_addr(addr) +#define fd_set_dma_count(count) sun_fdops.fd_set_dma_count(count) +#define get_dma_residue(x) sun_fdops.get_dma_residue() +#define fd_cacheflush(addr, size) /* nothing... */ +#define fd_request_irq() sun_fdops.fd_request_irq() +#define fd_free_irq() sun_fdops.fd_free_irq() +#define fd_eject(drive) sun_fdops.fd_eject(drive) + +static int FLOPPY_MOTOR_MASK = 0x10; + +/* Super paranoid... */ +#undef HAVE_DISABLE_HLT + +static int sun_floppy_types[2] = { 0, 0 }; + +/* Here is where we catch the floppy driver trying to initialize, + * therefore this is where we call the PROM device tree probing + * routine etc. on the Sparc. + */ +#define FLOPPY0_TYPE sun_floppy_init() +#define FLOPPY1_TYPE sun_floppy_types[1] + +#define FDC1 ((unsigned long)sun_fdc) + +#define N_FDC 1 +#define N_DRIVE 8 + +/* No 64k boundary crossing problems on the Sparc. */ +#define CROSS_64KB(a,s) (0) + +static unsigned char sun_82077_fd_inb(unsigned long port) +{ + udelay(5); + switch(port & 7) { + default: + printk("floppy: Asked to read unknown port %lx\n", port); + panic("floppy: Port bolixed."); + case 4: /* FD_STATUS */ + return sbus_readb(&sun_fdc->status_82077) & ~STATUS_DMA; + case 5: /* FD_DATA */ + return sbus_readb(&sun_fdc->data_82077); + case 7: /* FD_DIR */ + /* XXX: Is DCL on 0x80 in sun4m? */ + return sbus_readb(&sun_fdc->dir_82077); + }; + panic("sun_82072_fd_inb: How did I get here?"); +} + +static void sun_82077_fd_outb(unsigned char value, unsigned long port) +{ + udelay(5); + switch(port & 7) { + default: + printk("floppy: Asked to write to unknown port %lx\n", port); + panic("floppy: Port bolixed."); + case 2: /* FD_DOR */ + /* Happily, the 82077 has a real DOR register. */ + sbus_writeb(value, &sun_fdc->dor_82077); + break; + case 5: /* FD_DATA */ + sbus_writeb(value, &sun_fdc->data_82077); + break; + case 7: /* FD_DCR */ + sbus_writeb(value, &sun_fdc->dcr_82077); + break; + case 4: /* FD_STATUS */ + sbus_writeb(value, &sun_fdc->status_82077); + break; + }; + return; +} + +/* For pseudo-dma (Sun floppy drives have no real DMA available to + * them so we must eat the data fifo bytes directly ourselves) we have + * three state variables. doing_pdma tells our inline low-level + * assembly floppy interrupt entry point whether it should sit and eat + * bytes from the fifo or just transfer control up to the higher level + * floppy interrupt c-code. I tried very hard but I could not get the + * pseudo-dma to work in c-code without getting many overruns and + * underruns. If non-zero, doing_pdma encodes the direction of + * the transfer for debugging. 1=read 2=write + */ +char *pdma_vaddr; +unsigned long pdma_size; +volatile int doing_pdma = 0; + +/* This is software state */ +char *pdma_base = NULL; +unsigned long pdma_areasize; + +/* Common routines to all controller types on the Sparc. */ +static void sun_fd_disable_dma(void) +{ + doing_pdma = 0; + if (pdma_base) { + mmu_unlockarea(pdma_base, pdma_areasize); + pdma_base = NULL; + } +} + +static void sun_fd_set_dma_mode(int mode) +{ + switch(mode) { + case DMA_MODE_READ: + doing_pdma = 1; + break; + case DMA_MODE_WRITE: + doing_pdma = 2; + break; + default: + printk("Unknown dma mode %d\n", mode); + panic("floppy: Giving up..."); + } +} + +static void sun_fd_set_dma_addr(char *buffer) +{ + pdma_vaddr = buffer; +} + +static void sun_fd_set_dma_count(int length) +{ + pdma_size = length; +} + +static void sun_fd_enable_dma(void) +{ + pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size); + pdma_base = pdma_vaddr; + pdma_areasize = pdma_size; +} + +/* Our low-level entry point in arch/sparc/kernel/entry.S */ +extern irqreturn_t floppy_hardint(int irq, void *unused, struct pt_regs *regs); + +static int sun_fd_request_irq(void) +{ + static int once = 0; + int error; + + if(!once) { + once = 1; + + error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, + SA_INTERRUPT, "floppy", NULL); + + return ((error == 0) ? 0 : -1); + } + return 0; +} + +static void sun_fd_free_irq(void) +{ +} + +static unsigned int sun_get_dma_residue(void) +{ + /* XXX This isn't really correct. XXX */ + return 0; +} + +static int sun_fd_eject(int drive) +{ + set_dor(0x00, 0xff, 0x90); + udelay(500); + set_dor(0x00, 0x6f, 0x00); + udelay(500); + return 0; +} + +#ifdef CONFIG_PCI +#include <asm/ebus.h> +#include <asm/isa.h> +#include <asm/ns87303.h> + +static struct ebus_dma_info sun_pci_fd_ebus_dma; +static struct pci_dev *sun_pci_ebus_dev; +static int sun_pci_broken_drive = -1; + +struct sun_pci_dma_op { + unsigned int addr; + int len; + int direction; + char *buf; +}; +static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL}; +static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL}; + +extern irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs); + +static unsigned char sun_pci_fd_inb(unsigned long port) +{ + udelay(5); + return inb(port); +} + +static void sun_pci_fd_outb(unsigned char val, unsigned long port) +{ + udelay(5); + outb(val, port); +} + +static void sun_pci_fd_broken_outb(unsigned char val, unsigned long port) +{ + udelay(5); + /* + * XXX: Due to SUN's broken floppy connector on AX and AXi + * we need to turn on MOTOR_0 also, if the floppy is + * jumpered to DS1 (like most PC floppies are). I hope + * this does not hurt correct hardware like the AXmp. + * (Eddie, Sep 12 1998). + */ + if (port == ((unsigned long)sun_fdc) + 2) { + if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x20)) { + val |= 0x10; + } + } + outb(val, port); +} + +#ifdef PCI_FDC_SWAP_DRIVES +static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long port) +{ + udelay(5); + /* + * XXX: Due to SUN's broken floppy connector on AX and AXi + * we need to turn on MOTOR_0 also, if the floppy is + * jumpered to DS1 (like most PC floppies are). I hope + * this does not hurt correct hardware like the AXmp. + * (Eddie, Sep 12 1998). + */ + if (port == ((unsigned long)sun_fdc) + 2) { + if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x10)) { + val &= ~(0x03); + val |= 0x21; + } + } + outb(val, port); +} +#endif /* PCI_FDC_SWAP_DRIVES */ + +static void sun_pci_fd_enable_dma(void) +{ + BUG_ON((NULL == sun_pci_dma_pending.buf) || + (0 == sun_pci_dma_pending.len) || + (0 == sun_pci_dma_pending.direction)); + + sun_pci_dma_current.buf = sun_pci_dma_pending.buf; + sun_pci_dma_current.len = sun_pci_dma_pending.len; + sun_pci_dma_current.direction = sun_pci_dma_pending.direction; + + sun_pci_dma_pending.buf = NULL; + sun_pci_dma_pending.len = 0; + sun_pci_dma_pending.direction = 0; + sun_pci_dma_pending.addr = -1U; + + sun_pci_dma_current.addr = + pci_map_single(sun_pci_ebus_dev, + sun_pci_dma_current.buf, + sun_pci_dma_current.len, + sun_pci_dma_current.direction); + + ebus_dma_enable(&sun_pci_fd_ebus_dma, 1); + + if (ebus_dma_request(&sun_pci_fd_ebus_dma, + sun_pci_dma_current.addr, + sun_pci_dma_current.len)) + BUG(); +} + +static void sun_pci_fd_disable_dma(void) +{ + ebus_dma_enable(&sun_pci_fd_ebus_dma, 0); + if (sun_pci_dma_current.addr != -1U) + pci_unmap_single(sun_pci_ebus_dev, + sun_pci_dma_current.addr, + sun_pci_dma_current.len, + sun_pci_dma_current.direction); + sun_pci_dma_current.addr = -1U; +} + +static void sun_pci_fd_set_dma_mode(int mode) +{ + if (mode == DMA_MODE_WRITE) + sun_pci_dma_pending.direction = PCI_DMA_TODEVICE; + else + sun_pci_dma_pending.direction = PCI_DMA_FROMDEVICE; + + ebus_dma_prepare(&sun_pci_fd_ebus_dma, mode != DMA_MODE_WRITE); +} + +static void sun_pci_fd_set_dma_count(int length) +{ + sun_pci_dma_pending.len = length; +} + +static void sun_pci_fd_set_dma_addr(char *buffer) +{ + sun_pci_dma_pending.buf = buffer; +} + +static unsigned int sun_pci_get_dma_residue(void) +{ + return ebus_dma_residue(&sun_pci_fd_ebus_dma); +} + +static int sun_pci_fd_request_irq(void) +{ + return ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 1); +} + +static void sun_pci_fd_free_irq(void) +{ + ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 0); +} + +static int sun_pci_fd_eject(int drive) +{ + return -EINVAL; +} + +void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie) +{ + floppy_interrupt(0, NULL, NULL); +} + +/* + * Floppy probing, we'd like to use /dev/fd0 for a single Floppy on PCI, + * even if this is configured using DS1, thus looks like /dev/fd1 with + * the cabling used in Ultras. + */ +#define DOR (port + 2) +#define MSR (port + 4) +#define FIFO (port + 5) + +static void sun_pci_fd_out_byte(unsigned long port, unsigned char val, + unsigned long reg) +{ + unsigned char status; + int timeout = 1000; + + while (!((status = inb(MSR)) & 0x80) && --timeout) + udelay(100); + outb(val, reg); +} + +static unsigned char sun_pci_fd_sensei(unsigned long port) +{ + unsigned char result[2] = { 0x70, 0x00 }; + unsigned char status; + int i = 0; + + sun_pci_fd_out_byte(port, 0x08, FIFO); + do { + int timeout = 1000; + + while (!((status = inb(MSR)) & 0x80) && --timeout) + udelay(100); + + if (!timeout) + break; + + if ((status & 0xf0) == 0xd0) + result[i++] = inb(FIFO); + else + break; + } while (i < 2); + + return result[0]; +} + +static void sun_pci_fd_reset(unsigned long port) +{ + unsigned char mask = 0x00; + unsigned char status; + int timeout = 10000; + + outb(0x80, MSR); + do { + status = sun_pci_fd_sensei(port); + if ((status & 0xc0) == 0xc0) + mask |= 1 << (status & 0x03); + else + udelay(100); + } while ((mask != 0x0f) && --timeout); +} + +static int sun_pci_fd_test_drive(unsigned long port, int drive) +{ + unsigned char status, data; + int timeout = 1000; + int ready; + + sun_pci_fd_reset(port); + + data = (0x10 << drive) | 0x0c | drive; + sun_pci_fd_out_byte(port, data, DOR); + + sun_pci_fd_out_byte(port, 0x07, FIFO); + sun_pci_fd_out_byte(port, drive & 0x03, FIFO); + + do { + udelay(100); + status = sun_pci_fd_sensei(port); + } while (((status & 0xc0) == 0x80) && --timeout); + + if (!timeout) + ready = 0; + else + ready = (status & 0x10) ? 0 : 1; + + sun_pci_fd_reset(port); + return ready; +} +#undef FIFO +#undef MSR +#undef DOR + +#endif /* CONFIG_PCI */ + +#ifdef CONFIG_PCI +static int __init ebus_fdthree_p(struct linux_ebus_device *edev) +{ + if (!strcmp(edev->prom_name, "fdthree")) + return 1; + if (!strcmp(edev->prom_name, "floppy")) { + char compat[16]; + prom_getstring(edev->prom_node, + "compatible", + compat, sizeof(compat)); + compat[15] = '\0'; + if (!strcmp(compat, "fdthree")) + return 1; + } + return 0; +} +#endif + +#ifdef CONFIG_PCI +#undef ISA_FLOPPY_WORKS + +#ifdef ISA_FLOPPY_WORKS +static unsigned long __init isa_floppy_init(void) +{ + struct sparc_isa_bridge *isa_br; + struct sparc_isa_device *isa_dev = NULL; + + for_each_isa(isa_br) { + for_each_isadev(isa_dev, isa_br) { + if (!strcmp(isa_dev->prom_name, "dma")) { + struct sparc_isa_device *child = + isa_dev->child; + + while (child) { + if (!strcmp(child->prom_name, + "floppy")) { + isa_dev = child; + goto isa_done; + } + child = child->next; + } + } + } + } +isa_done: + if (!isa_dev) + return 0; + + /* We could use DMA on devices behind the ISA bridge, but... + * + * There is a slight problem. Normally on x86 kit the x86 processor + * delays I/O port instructions when the ISA bus "dma in progress" + * signal is active. Well, sparc64 systems do not monitor this + * signal thus we would need to block all I/O port accesses in software + * when a dma transfer is active for some device. + */ + + sun_fdc = (struct sun_flpy_controller *)isa_dev->resource.start; + FLOPPY_IRQ = isa_dev->irq; + + sun_fdops.fd_inb = sun_pci_fd_inb; + sun_fdops.fd_outb = sun_pci_fd_outb; + + can_use_virtual_dma = use_virtual_dma = 1; + sun_fdops.fd_enable_dma = sun_fd_enable_dma; + sun_fdops.fd_disable_dma = sun_fd_disable_dma; + sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode; + sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr; + sun_fdops.fd_set_dma_count = sun_fd_set_dma_count; + sun_fdops.get_dma_residue = sun_get_dma_residue; + + sun_fdops.fd_request_irq = sun_fd_request_irq; + sun_fdops.fd_free_irq = sun_fd_free_irq; + + /* Floppy eject is manual. Actually, could determine this + * via presence of 'manual' property in OBP node. + */ + sun_fdops.fd_eject = sun_pci_fd_eject; + + fdc_status = (unsigned long) &sun_fdc->status_82077; + FLOPPY_MOTOR_MASK = 0xf0; + + allowed_drive_mask = 0; + sun_floppy_types[0] = 0; + sun_floppy_types[1] = 4; + + sun_pci_broken_drive = 1; + sun_fdops.fd_outb = sun_pci_fd_broken_outb; + + return sun_floppy_types[0]; +} +#endif /* ISA_FLOPPY_WORKS */ + +#endif + +static unsigned long __init sun_floppy_init(void) +{ + char state[128]; + struct sbus_bus *bus; + struct sbus_dev *sdev = NULL; + static int initialized = 0; + + if (initialized) + return sun_floppy_types[0]; + initialized = 1; + + for_all_sbusdev (sdev, bus) { + if (!strcmp(sdev->prom_name, "SUNW,fdtwo")) + break; + } + if(sdev) { + floppy_sdev = sdev; + FLOPPY_IRQ = sdev->irqs[0]; + } else { +#ifdef CONFIG_PCI + struct linux_ebus *ebus; + struct linux_ebus_device *edev = NULL; + unsigned long config = 0; + unsigned long auxio_reg; + + for_each_ebus(ebus) { + for_each_ebusdev(edev, ebus) { + if (ebus_fdthree_p(edev)) + goto ebus_done; + } + } + ebus_done: + if (!edev) { +#ifdef ISA_FLOPPY_WORKS + return isa_floppy_init(); +#else + return 0; +#endif + } + + prom_getproperty(edev->prom_node, "status", + state, sizeof(state)); + if (!strncmp(state, "disabled", 8)) + return 0; + + FLOPPY_IRQ = edev->irqs[0]; + + /* Make sure the high density bit is set, some systems + * (most notably Ultra5/Ultra10) come up with it clear. + */ + auxio_reg = edev->resource[2].start; + writel(readl(auxio_reg)|0x2, auxio_reg); + + sun_pci_ebus_dev = ebus->self; + + spin_lock_init(&sun_pci_fd_ebus_dma.lock); + + /* XXX ioremap */ + sun_pci_fd_ebus_dma.regs = edev->resource[1].start; + if (!sun_pci_fd_ebus_dma.regs) + return 0; + + sun_pci_fd_ebus_dma.flags = (EBUS_DMA_FLAG_USE_EBDMA_HANDLER | + EBUS_DMA_FLAG_TCI_DISABLE); + sun_pci_fd_ebus_dma.callback = sun_pci_fd_dma_callback; + sun_pci_fd_ebus_dma.client_cookie = NULL; + sun_pci_fd_ebus_dma.irq = FLOPPY_IRQ; + strcpy(sun_pci_fd_ebus_dma.name, "floppy"); + if (ebus_dma_register(&sun_pci_fd_ebus_dma)) + return 0; + + /* XXX ioremap */ + sun_fdc = (struct sun_flpy_controller *)edev->resource[0].start; + + sun_fdops.fd_inb = sun_pci_fd_inb; + sun_fdops.fd_outb = sun_pci_fd_outb; + + can_use_virtual_dma = use_virtual_dma = 0; + sun_fdops.fd_enable_dma = sun_pci_fd_enable_dma; + sun_fdops.fd_disable_dma = sun_pci_fd_disable_dma; + sun_fdops.fd_set_dma_mode = sun_pci_fd_set_dma_mode; + sun_fdops.fd_set_dma_addr = sun_pci_fd_set_dma_addr; + sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count; + sun_fdops.get_dma_residue = sun_pci_get_dma_residue; + + sun_fdops.fd_request_irq = sun_pci_fd_request_irq; + sun_fdops.fd_free_irq = sun_pci_fd_free_irq; + + sun_fdops.fd_eject = sun_pci_fd_eject; + + fdc_status = (unsigned long) &sun_fdc->status_82077; + FLOPPY_MOTOR_MASK = 0xf0; + + /* + * XXX: Find out on which machines this is really needed. + */ + if (1) { + sun_pci_broken_drive = 1; + sun_fdops.fd_outb = sun_pci_fd_broken_outb; + } + + allowed_drive_mask = 0; + if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 0)) + sun_floppy_types[0] = 4; + if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 1)) + sun_floppy_types[1] = 4; + + /* + * Find NS87303 SuperIO config registers (through ecpp). + */ + for_each_ebus(ebus) { + for_each_ebusdev(edev, ebus) { + if (!strcmp(edev->prom_name, "ecpp")) { + config = edev->resource[1].start; + goto config_done; + } + } + } + config_done: + + /* + * Sanity check, is this really the NS87303? + */ + switch (config & 0x3ff) { + case 0x02e: + case 0x15c: + case 0x26e: + case 0x398: + break; + default: + config = 0; + } + + if (!config) + return sun_floppy_types[0]; + + /* Enable PC-AT mode. */ + ns87303_modify(config, ASC, 0, 0xc0); + +#ifdef PCI_FDC_SWAP_DRIVES + /* + * If only Floppy 1 is present, swap drives. + */ + if (!sun_floppy_types[0] && sun_floppy_types[1]) { + /* + * Set the drive exchange bit in FCR on NS87303, + * make shure other bits are sane before doing so. + */ + ns87303_modify(config, FER, FER_EDM, 0); + ns87303_modify(config, ASC, ASC_DRV2_SEL, 0); + ns87303_modify(config, FCR, 0, FCR_LDE); + + config = sun_floppy_types[0]; + sun_floppy_types[0] = sun_floppy_types[1]; + sun_floppy_types[1] = config; + + if (sun_pci_broken_drive != -1) { + sun_pci_broken_drive = 1 - sun_pci_broken_drive; + sun_fdops.fd_outb = sun_pci_fd_lde_broken_outb; + } + } +#endif /* PCI_FDC_SWAP_DRIVES */ + + return sun_floppy_types[0]; +#else + return 0; +#endif + } + prom_getproperty(sdev->prom_node, "status", state, sizeof(state)); + if(!strncmp(state, "disabled", 8)) + return 0; + + /* + * We cannot do sbus_ioremap here: it does request_region, + * which the generic floppy driver tries to do once again. + * But we must use the sdev resource values as they have + * had parent ranges applied. + */ + sun_fdc = (struct sun_flpy_controller *) + (sdev->resource[0].start + + ((sdev->resource[0].flags & 0x1ffUL) << 32UL)); + + /* Last minute sanity check... */ + if(sbus_readb(&sun_fdc->status1_82077) == 0xff) { + sun_fdc = (struct sun_flpy_controller *)-1; + return 0; + } + + sun_fdops.fd_inb = sun_82077_fd_inb; + sun_fdops.fd_outb = sun_82077_fd_outb; + + can_use_virtual_dma = use_virtual_dma = 1; + sun_fdops.fd_enable_dma = sun_fd_enable_dma; + sun_fdops.fd_disable_dma = sun_fd_disable_dma; + sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode; + sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr; + sun_fdops.fd_set_dma_count = sun_fd_set_dma_count; + sun_fdops.get_dma_residue = sun_get_dma_residue; + + sun_fdops.fd_request_irq = sun_fd_request_irq; + sun_fdops.fd_free_irq = sun_fd_free_irq; + + sun_fdops.fd_eject = sun_fd_eject; + + fdc_status = (unsigned long) &sun_fdc->status_82077; + + /* Success... */ + allowed_drive_mask = 0x01; + sun_floppy_types[0] = 4; + sun_floppy_types[1] = 0; + + return sun_floppy_types[0]; +} + +#define EXTRA_FLOPPY_PARAMS + +#endif /* !(__ASM_SPARC64_FLOPPY_H) */ diff --git a/include/asm-sparc64/fpumacro.h b/include/asm-sparc64/fpumacro.h new file mode 100644 index 000000000000..d583e5efd75d --- /dev/null +++ b/include/asm-sparc64/fpumacro.h @@ -0,0 +1,33 @@ +/* fpumacro.h: FPU related macros. + * + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC64_FPUMACRO_H +#define _SPARC64_FPUMACRO_H + +#include <asm/asi.h> +#include <asm/visasm.h> + +struct fpustate { + u32 regs[64]; +}; + +#define FPUSTATE (struct fpustate *)(current_thread_info()->fpregs) + +static __inline__ unsigned long fprs_read(void) +{ + unsigned long retval; + + __asm__ __volatile__("rd %%fprs, %0" : "=r" (retval)); + + return retval; +} + +static __inline__ void fprs_write(unsigned long val) +{ + __asm__ __volatile__("wr %0, 0x0, %%fprs" : : "r" (val)); +} + +#endif /* !(_SPARC64_FPUMACRO_H) */ diff --git a/include/asm-sparc64/hardirq.h b/include/asm-sparc64/hardirq.h new file mode 100644 index 000000000000..d6db1aed7645 --- /dev/null +++ b/include/asm-sparc64/hardirq.h @@ -0,0 +1,23 @@ +/* hardirq.h: 64-bit Sparc hard IRQ support. + * + * Copyright (C) 1997, 1998 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef __SPARC64_HARDIRQ_H +#define __SPARC64_HARDIRQ_H + +#include <linux/config.h> +#include <linux/threads.h> +#include <linux/spinlock.h> +#include <linux/cache.h> + +/* rtrap.S is sensitive to the offsets of these fields */ +typedef struct { + unsigned int __softirq_pending; +} ____cacheline_aligned irq_cpustat_t; + +#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ + +#define HARDIRQ_BITS 8 + +#endif /* !(__SPARC64_HARDIRQ_H) */ diff --git a/include/asm-sparc64/hdreg.h b/include/asm-sparc64/hdreg.h new file mode 100644 index 000000000000..7f7fd1af0af3 --- /dev/null +++ b/include/asm-sparc64/hdreg.h @@ -0,0 +1 @@ +#include <asm-generic/hdreg.h> diff --git a/include/asm-sparc64/head.h b/include/asm-sparc64/head.h new file mode 100644 index 000000000000..b63a33cf4971 --- /dev/null +++ b/include/asm-sparc64/head.h @@ -0,0 +1,59 @@ +/* $Id: head.h,v 1.30 1997/08/08 08:34:33 jj Exp $ */ +#ifndef _SPARC64_HEAD_H +#define _SPARC64_HEAD_H + +#include <asm/pstate.h> + +#define KERNBASE 0x400000 + +#define PTREGS_OFF (STACK_BIAS + STACKFRAME_SZ) + +#define __CHEETAH_ID 0x003e0014 +#define __JALAPENO_ID 0x003e0016 + +#define CHEETAH_MANUF 0x003e +#define CHEETAH_IMPL 0x0014 +#define CHEETAH_PLUS_IMPL 0x0015 +#define JALAPENO_IMPL 0x0016 + +#define BRANCH_IF_CHEETAH_BASE(tmp1,tmp2,label) \ + rdpr %ver, %tmp1; \ + sethi %hi(__CHEETAH_ID), %tmp2; \ + srlx %tmp1, 32, %tmp1; \ + or %tmp2, %lo(__CHEETAH_ID), %tmp2;\ + cmp %tmp1, %tmp2; \ + be,pn %icc, label; \ + nop; + +#define BRANCH_IF_JALAPENO(tmp1,tmp2,label) \ + rdpr %ver, %tmp1; \ + sethi %hi(__JALAPENO_ID), %tmp2; \ + srlx %tmp1, 32, %tmp1; \ + or %tmp2, %lo(__JALAPENO_ID), %tmp2;\ + cmp %tmp1, %tmp2; \ + be,pn %icc, label; \ + nop; + +#define BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(tmp1,tmp2,label) \ + rdpr %ver, %tmp1; \ + srlx %tmp1, (32 + 16), %tmp2; \ + cmp %tmp2, CHEETAH_MANUF; \ + bne,pt %xcc, 99f; \ + sllx %tmp1, 16, %tmp1; \ + srlx %tmp1, (32 + 16), %tmp2; \ + cmp %tmp2, CHEETAH_PLUS_IMPL; \ + bgeu,pt %xcc, label; \ +99: nop; + +#define BRANCH_IF_ANY_CHEETAH(tmp1,tmp2,label) \ + rdpr %ver, %tmp1; \ + srlx %tmp1, (32 + 16), %tmp2; \ + cmp %tmp2, CHEETAH_MANUF; \ + bne,pt %xcc, 99f; \ + sllx %tmp1, 16, %tmp1; \ + srlx %tmp1, (32 + 16), %tmp2; \ + cmp %tmp2, CHEETAH_IMPL; \ + bgeu,pt %xcc, label; \ +99: nop; + +#endif /* !(_SPARC64_HEAD_H) */ diff --git a/include/asm-sparc64/hw_irq.h b/include/asm-sparc64/hw_irq.h new file mode 100644 index 000000000000..153cae2ddaee --- /dev/null +++ b/include/asm-sparc64/hw_irq.h @@ -0,0 +1,6 @@ +#ifndef __ASM_SPARC64_HW_IRQ_H +#define __ASM_SPARC64_HW_IRQ_H + +/* Dummy include. */ + +#endif diff --git a/include/asm-sparc64/ide.h b/include/asm-sparc64/ide.h new file mode 100644 index 000000000000..4c1098474c73 --- /dev/null +++ b/include/asm-sparc64/ide.h @@ -0,0 +1,121 @@ +/* $Id: ide.h,v 1.21 2001/09/25 20:21:48 kanoj Exp $ + * ide.h: Ultra/PCI specific IDE glue. + * + * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) + */ + +#ifndef _SPARC64_IDE_H +#define _SPARC64_IDE_H + +#ifdef __KERNEL__ + +#include <linux/config.h> +#include <asm/pgalloc.h> +#include <asm/io.h> +#include <asm/spitfire.h> +#include <asm/cacheflush.h> + +#ifndef MAX_HWIFS +# ifdef CONFIG_BLK_DEV_IDEPCI +#define MAX_HWIFS 10 +# else +#define MAX_HWIFS 2 +# endif +#endif + +#define IDE_ARCH_OBSOLETE_INIT +#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */ + +#define __ide_insl(data_reg, buffer, wcount) \ + __ide_insw(data_reg, buffer, (wcount)<<1) +#define __ide_outsl(data_reg, buffer, wcount) \ + __ide_outsw(data_reg, buffer, (wcount)<<1) + +/* On sparc64, I/O ports and MMIO registers are accessed identically. */ +#define __ide_mm_insw __ide_insw +#define __ide_mm_insl __ide_insl +#define __ide_mm_outsw __ide_outsw +#define __ide_mm_outsl __ide_outsl + +static inline unsigned int inw_be(void __iomem *addr) +{ + unsigned int ret; + + __asm__ __volatile__("lduha [%1] %2, %0" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +static inline void __ide_insw(void __iomem *port, void *dst, u32 count) +{ +#ifdef DCACHE_ALIASING_POSSIBLE + unsigned long end = (unsigned long)dst + (count << 1); +#endif + u16 *ps = dst; + u32 *pi; + + if(((u64)ps) & 0x2) { + *ps++ = inw_be(port); + count--; + } + pi = (u32 *)ps; + while(count >= 2) { + u32 w; + + w = inw_be(port) << 16; + w |= inw_be(port); + *pi++ = w; + count -= 2; + } + ps = (u16 *)pi; + if(count) + *ps++ = inw_be(port); + +#ifdef DCACHE_ALIASING_POSSIBLE + __flush_dcache_range((unsigned long)dst, end); +#endif +} + +static inline void outw_be(unsigned short w, void __iomem *addr) +{ + __asm__ __volatile__("stha %0, [%1] %2" + : /* no outputs */ + : "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +static inline void __ide_outsw(void __iomem *port, void *src, u32 count) +{ +#ifdef DCACHE_ALIASING_POSSIBLE + unsigned long end = (unsigned long)src + (count << 1); +#endif + const u16 *ps = src; + const u32 *pi; + + if(((u64)src) & 0x2) { + outw_be(*ps++, port); + count--; + } + pi = (const u32 *)ps; + while(count >= 2) { + u32 w; + + w = *pi++; + outw_be((w >> 16), port); + outw_be(w, port); + count -= 2; + } + ps = (const u16 *)pi; + if(count) + outw_be(*ps, port); + +#ifdef DCACHE_ALIASING_POSSIBLE + __flush_dcache_range((unsigned long)src, end); +#endif +} + +#endif /* __KERNEL__ */ + +#endif /* _SPARC64_IDE_H */ diff --git a/include/asm-sparc64/idprom.h b/include/asm-sparc64/idprom.h new file mode 100644 index 000000000000..701483c5465d --- /dev/null +++ b/include/asm-sparc64/idprom.h @@ -0,0 +1,35 @@ +/* $Id: idprom.h,v 1.2 1997/04/04 00:50:16 davem Exp $ + * idprom.h: Macros and defines for idprom routines + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC64_IDPROM_H +#define _SPARC64_IDPROM_H + +#include <linux/types.h> + +/* Offset into the EEPROM where the id PROM is located on the 4c */ +#define IDPROM_OFFSET 0x7d8 + +/* On sun4m; physical. */ +/* MicroSPARC(-II) does not decode 31rd bit, but it works. */ +#define IDPROM_OFFSET_M 0xfd8 + +struct idprom +{ + u8 id_format; /* Format identifier (always 0x01) */ + u8 id_machtype; /* Machine type */ + u8 id_ethaddr[6]; /* Hardware ethernet address */ + s32 id_date; /* Date of manufacture */ + u32 id_sernum:24; /* Unique serial number */ + u8 id_cksum; /* Checksum - xor of the data bytes */ + u8 reserved[16]; +}; + +extern struct idprom *idprom; +extern void idprom_init(void); + +#define IDPROM_SIZE (sizeof(struct idprom)) + +#endif /* !(_SPARC_IDPROM_H) */ diff --git a/include/asm-sparc64/io.h b/include/asm-sparc64/io.h new file mode 100644 index 000000000000..afdcea90707a --- /dev/null +++ b/include/asm-sparc64/io.h @@ -0,0 +1,501 @@ +/* $Id: io.h,v 1.47 2001/12/13 10:36:02 davem Exp $ */ +#ifndef __SPARC64_IO_H +#define __SPARC64_IO_H + +#include <linux/kernel.h> +#include <linux/compiler.h> +#include <linux/types.h> + +#include <asm/page.h> /* IO address mapping routines need this */ +#include <asm/system.h> +#include <asm/asi.h> + +/* PC crapola... */ +#define __SLOW_DOWN_IO do { } while (0) +#define SLOW_DOWN_IO do { } while (0) + +extern unsigned long virt_to_bus_not_defined_use_pci_map(volatile void *addr); +#define virt_to_bus virt_to_bus_not_defined_use_pci_map +extern unsigned long bus_to_virt_not_defined_use_pci_map(volatile void *addr); +#define bus_to_virt bus_to_virt_not_defined_use_pci_map + +/* BIO layer definitions. */ +extern unsigned long kern_base, kern_size; +#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) +#define BIO_VMERGE_BOUNDARY 8192 + +/* Different PCI controllers we support have their PCI MEM space + * mapped to an either 2GB (Psycho) or 4GB (Sabre) aligned area, + * so need to chop off the top 33 or 32 bits. + */ +extern unsigned long pci_memspace_mask; + +#define bus_dvma_to_mem(__vaddr) ((__vaddr) & pci_memspace_mask) + +static __inline__ u8 _inb(unsigned long addr) +{ + u8 ret; + + __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_inb */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); + + return ret; +} + +static __inline__ u16 _inw(unsigned long addr) +{ + u16 ret; + + __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_inw */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); + + return ret; +} + +static __inline__ u32 _inl(unsigned long addr) +{ + u32 ret; + + __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_inl */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); + + return ret; +} + +static __inline__ void _outb(u8 b, unsigned long addr) +{ + __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_outb */" + : /* no outputs */ + : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); +} + +static __inline__ void _outw(u16 w, unsigned long addr) +{ + __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_outw */" + : /* no outputs */ + : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); +} + +static __inline__ void _outl(u32 l, unsigned long addr) +{ + __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_outl */" + : /* no outputs */ + : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); +} + +#define inb(__addr) (_inb((unsigned long)(__addr))) +#define inw(__addr) (_inw((unsigned long)(__addr))) +#define inl(__addr) (_inl((unsigned long)(__addr))) +#define outb(__b, __addr) (_outb((u8)(__b), (unsigned long)(__addr))) +#define outw(__w, __addr) (_outw((u16)(__w), (unsigned long)(__addr))) +#define outl(__l, __addr) (_outl((u32)(__l), (unsigned long)(__addr))) + +#define inb_p(__addr) inb(__addr) +#define outb_p(__b, __addr) outb(__b, __addr) +#define inw_p(__addr) inw(__addr) +#define outw_p(__w, __addr) outw(__w, __addr) +#define inl_p(__addr) inl(__addr) +#define outl_p(__l, __addr) outl(__l, __addr) + +extern void outsb(void __iomem *addr, const void *src, unsigned long count); +extern void outsw(void __iomem *addr, const void *src, unsigned long count); +extern void outsl(void __iomem *addr, const void *src, unsigned long count); +extern void insb(void __iomem *addr, void *dst, unsigned long count); +extern void insw(void __iomem *addr, void *dst, unsigned long count); +extern void insl(void __iomem *addr, void *dst, unsigned long count); +#define ioread8_rep(a,d,c) insb(a,d,c) +#define ioread16_rep(a,d,c) insw(a,d,c) +#define ioread32_rep(a,d,c) insl(a,d,c) +#define iowrite8_rep(a,s,c) outsb(a,s,c) +#define iowrite16_rep(a,s,c) outsw(a,s,c) +#define iowrite32_rep(a,s,c) outsl(a,s,c) + +/* Memory functions, same as I/O accesses on Ultra. */ +static inline u8 _readb(const volatile void __iomem *addr) +{ u8 ret; + + __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_readb */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); + return ret; +} + +static inline u16 _readw(const volatile void __iomem *addr) +{ u16 ret; + + __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_readw */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); + + return ret; +} + +static inline u32 _readl(const volatile void __iomem *addr) +{ u32 ret; + + __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_readl */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); + + return ret; +} + +static inline u64 _readq(const volatile void __iomem *addr) +{ u64 ret; + + __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_readq */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); + + return ret; +} + +static inline void _writeb(u8 b, volatile void __iomem *addr) +{ + __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_writeb */" + : /* no outputs */ + : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); +} + +static inline void _writew(u16 w, volatile void __iomem *addr) +{ + __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_writew */" + : /* no outputs */ + : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); +} + +static inline void _writel(u32 l, volatile void __iomem *addr) +{ + __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */" + : /* no outputs */ + : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); +} + +static inline void _writeq(u64 q, volatile void __iomem *addr) +{ + __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_writeq */" + : /* no outputs */ + : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); +} + +#define readb(__addr) _readb(__addr) +#define readw(__addr) _readw(__addr) +#define readl(__addr) _readl(__addr) +#define readq(__addr) _readq(__addr) +#define readb_relaxed(__addr) _readb(__addr) +#define readw_relaxed(__addr) _readw(__addr) +#define readl_relaxed(__addr) _readl(__addr) +#define readq_relaxed(__addr) _readq(__addr) +#define writeb(__b, __addr) _writeb(__b, __addr) +#define writew(__w, __addr) _writew(__w, __addr) +#define writel(__l, __addr) _writel(__l, __addr) +#define writeq(__q, __addr) _writeq(__q, __addr) + +/* Now versions without byte-swapping. */ +static __inline__ u8 _raw_readb(unsigned long addr) +{ + u8 ret; + + __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_raw_readb */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +static __inline__ u16 _raw_readw(unsigned long addr) +{ + u16 ret; + + __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_raw_readw */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +static __inline__ u32 _raw_readl(unsigned long addr) +{ + u32 ret; + + __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_raw_readl */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +static __inline__ u64 _raw_readq(unsigned long addr) +{ + u64 ret; + + __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_raw_readq */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +static __inline__ void _raw_writeb(u8 b, unsigned long addr) +{ + __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */" + : /* no outputs */ + : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +static __inline__ void _raw_writew(u16 w, unsigned long addr) +{ + __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */" + : /* no outputs */ + : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +static __inline__ void _raw_writel(u32 l, unsigned long addr) +{ + __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */" + : /* no outputs */ + : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +static __inline__ void _raw_writeq(u64 q, unsigned long addr) +{ + __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_raw_writeq */" + : /* no outputs */ + : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +#define __raw_readb(__addr) (_raw_readb((unsigned long)(__addr))) +#define __raw_readw(__addr) (_raw_readw((unsigned long)(__addr))) +#define __raw_readl(__addr) (_raw_readl((unsigned long)(__addr))) +#define __raw_readq(__addr) (_raw_readq((unsigned long)(__addr))) +#define __raw_writeb(__b, __addr) (_raw_writeb((u8)(__b), (unsigned long)(__addr))) +#define __raw_writew(__w, __addr) (_raw_writew((u16)(__w), (unsigned long)(__addr))) +#define __raw_writel(__l, __addr) (_raw_writel((u32)(__l), (unsigned long)(__addr))) +#define __raw_writeq(__q, __addr) (_raw_writeq((u64)(__q), (unsigned long)(__addr))) + +/* Valid I/O Space regions are anywhere, because each PCI bus supported + * can live in an arbitrary area of the physical address range. + */ +#define IO_SPACE_LIMIT 0xffffffffffffffffUL + +/* Now, SBUS variants, only difference from PCI is that we do + * not use little-endian ASIs. + */ +static inline u8 _sbus_readb(const volatile void __iomem *addr) +{ + u8 ret; + + __asm__ __volatile__("lduba\t[%1] %2, %0\t/* sbus_readb */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +static inline u16 _sbus_readw(const volatile void __iomem *addr) +{ + u16 ret; + + __asm__ __volatile__("lduha\t[%1] %2, %0\t/* sbus_readw */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +static inline u32 _sbus_readl(const volatile void __iomem *addr) +{ + u32 ret; + + __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* sbus_readl */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +static inline u64 _sbus_readq(const volatile void __iomem *addr) +{ + u64 ret; + + __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* sbus_readq */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +static inline void _sbus_writeb(u8 b, volatile void __iomem *addr) +{ + __asm__ __volatile__("stba\t%r0, [%1] %2\t/* sbus_writeb */" + : /* no outputs */ + : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +static inline void _sbus_writew(u16 w, volatile void __iomem *addr) +{ + __asm__ __volatile__("stha\t%r0, [%1] %2\t/* sbus_writew */" + : /* no outputs */ + : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +static inline void _sbus_writel(u32 l, volatile void __iomem *addr) +{ + __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* sbus_writel */" + : /* no outputs */ + : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +static inline void _sbus_writeq(u64 l, volatile void __iomem *addr) +{ + __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* sbus_writeq */" + : /* no outputs */ + : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +#define sbus_readb(__addr) _sbus_readb(__addr) +#define sbus_readw(__addr) _sbus_readw(__addr) +#define sbus_readl(__addr) _sbus_readl(__addr) +#define sbus_readq(__addr) _sbus_readq(__addr) +#define sbus_writeb(__b, __addr) _sbus_writeb(__b, __addr) +#define sbus_writew(__w, __addr) _sbus_writew(__w, __addr) +#define sbus_writel(__l, __addr) _sbus_writel(__l, __addr) +#define sbus_writeq(__l, __addr) _sbus_writeq(__l, __addr) + +static inline void _sbus_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n) +{ + while(n--) { + sbus_writeb(c, dst); + dst++; + } +} + +#define sbus_memset_io(d,c,sz) _sbus_memset_io(d,c,sz) + +static inline void +_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n) +{ + volatile void __iomem *d = dst; + + while (n--) { + writeb(c, d); + d++; + } +} + +#define memset_io(d,c,sz) _memset_io(d,c,sz) + +static inline void +_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n) +{ + char *d = dst; + + while (n--) { + char tmp = readb(src); + *d++ = tmp; + src++; + } +} + +#define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz) + +static inline void +_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n) +{ + const char *s = src; + volatile void __iomem *d = dst; + + while (n--) { + char tmp = *s++; + writeb(tmp, d); + d++; + } +} + +#define memcpy_toio(d,s,sz) _memcpy_toio(d,s,sz) + +static inline int check_signature(void __iomem *io_addr, + const unsigned char *signature, + int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature++) + goto out; + io_addr++; + } while (--length); + retval = 1; +out: + return retval; +} + +#define mmiowb() + +#ifdef __KERNEL__ + +/* On sparc64 we have the whole physical IO address space accessible + * using physically addressed loads and stores, so this does nothing. + */ +static inline void __iomem *ioremap(unsigned long offset, unsigned long size) +{ + return (void __iomem *)offset; +} + +#define ioremap_nocache(X,Y) ioremap((X),(Y)) + +static inline void iounmap(volatile void __iomem *addr) +{ +} + +#define ioread8(X) readb(X) +#define ioread16(X) readw(X) +#define ioread32(X) readl(X) +#define iowrite8(val,X) writeb(val,X) +#define iowrite16(val,X) writew(val,X) +#define iowrite32(val,X) writel(val,X) + +/* Create a virtual mapping cookie for an IO port range */ +extern void __iomem *ioport_map(unsigned long port, unsigned int nr); +extern void ioport_unmap(void __iomem *); + +/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ +struct pci_dev; +extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); +extern void pci_iounmap(struct pci_dev *dev, void __iomem *); + +/* Similarly for SBUS. */ +#define sbus_ioremap(__res, __offset, __size, __name) \ +({ unsigned long __ret; \ + __ret = (__res)->start + (((__res)->flags & 0x1ffUL) << 32UL); \ + __ret += (unsigned long) (__offset); \ + if (! request_region((__ret), (__size), (__name))) \ + __ret = 0UL; \ + (void __iomem *) __ret; \ +}) + +#define sbus_iounmap(__addr, __size) \ + release_region((unsigned long)(__addr), (__size)) + +/* Nothing to do */ + +#define dma_cache_inv(_start,_size) do { } while (0) +#define dma_cache_wback(_start,_size) do { } while (0) +#define dma_cache_wback_inv(_start,_size) do { } while (0) + +/* + * Convert a physical pointer to a virtual kernel pointer for /dev/mem + * access + */ +#define xlate_dev_mem_ptr(p) __va(p) + +/* + * Convert a virtual cached pointer to an uncached pointer + */ +#define xlate_dev_kmem_ptr(p) p + +#endif + +#endif /* !(__SPARC64_IO_H) */ diff --git a/include/asm-sparc64/ioctl.h b/include/asm-sparc64/ioctl.h new file mode 100644 index 000000000000..253d0b57b316 --- /dev/null +++ b/include/asm-sparc64/ioctl.h @@ -0,0 +1,68 @@ +/* $Id: ioctl.h,v 1.2 1998/10/15 05:40:38 jj Exp $ */ +#ifndef _SPARC64_IOCTL_H +#define _SPARC64_IOCTL_H + +/* + * Our DIR and SIZE overlap in order to simulteneously provide + * a non-zero _IOC_NONE (for binary compatibility) and + * 14 bits of size as on i386. Here's the layout: + * + * 0xE0000000 DIR + * 0x80000000 DIR = WRITE + * 0x40000000 DIR = READ + * 0x20000000 DIR = NONE + * 0x3FFF0000 SIZE (overlaps NONE bit) + * 0x0000FF00 TYPE + * 0x000000FF NR (CMD) + */ + +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 +#define _IOC_SIZEBITS 13 /* Actually 14, see below. */ +#define _IOC_DIRBITS 3 + +#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) +#define _IOC_XSIZEMASK ((1 << (_IOC_SIZEBITS+1))-1) +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) + +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT + _IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT + _IOC_TYPEBITS) +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT + _IOC_SIZEBITS) + +#define _IOC_NONE 1U +#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 _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) + +/* Used to decode ioctl numbers in drivers despite the leading underscore... */ +#define _IOC_DIR(nr) \ + ( (((((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) & (_IOC_WRITE|_IOC_READ)) != 0)? \ + (((nr) >> _IOC_DIRSHIFT) & (_IOC_WRITE|_IOC_READ)): \ + (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) ) +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) +#define _IOC_SIZE(nr) \ + ((((((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) & (_IOC_WRITE|_IOC_READ)) == 0)? \ + 0: (((nr) >> _IOC_SIZESHIFT) & _IOC_XSIZEMASK)) + +/* ...and for the PCMCIA and sound. */ +#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_XSIZEMASK << _IOC_SIZESHIFT) +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) + +#endif /* !(_SPARC64_IOCTL_H) */ diff --git a/include/asm-sparc64/ioctls.h b/include/asm-sparc64/ioctls.h new file mode 100644 index 000000000000..2223b6d0e5ed --- /dev/null +++ b/include/asm-sparc64/ioctls.h @@ -0,0 +1,135 @@ +/* $Id: ioctls.h,v 1.7 1998/02/23 02:49:41 davem Exp $ */ +#ifndef _ASM_SPARC64_IOCTLS_H +#define _ASM_SPARC64_IOCTLS_H + +#include <asm/ioctl.h> + +/* Big T */ +#define TCGETA _IOR('T', 1, struct termio) +#define TCSETA _IOW('T', 2, struct termio) +#define TCSETAW _IOW('T', 3, struct termio) +#define TCSETAF _IOW('T', 4, struct termio) +#define TCSBRK _IO('T', 5) +#define TCXONC _IO('T', 6) +#define TCFLSH _IO('T', 7) +#define TCGETS _IOR('T', 8, struct termios) +#define TCSETS _IOW('T', 9, struct termios) +#define TCSETSW _IOW('T', 10, struct termios) +#define TCSETSF _IOW('T', 11, struct termios) + +/* Note that all the ioctls that are not available in Linux have a + * double underscore on the front to: a) avoid some programs to + * think we support some ioctls under Linux (autoconfiguration stuff) + */ +/* Little t */ +#define TIOCGETD _IOR('t', 0, int) +#define TIOCSETD _IOW('t', 1, int) +#define __TIOCHPCL _IO('t', 2) /* SunOS Specific */ +#define __TIOCMODG _IOR('t', 3, int) /* SunOS Specific */ +#define __TIOCMODS _IOW('t', 4, int) /* SunOS Specific */ +#define __TIOCGETP _IOR('t', 8, struct sgttyb) /* SunOS Specific */ +#define __TIOCSETP _IOW('t', 9, struct sgttyb) /* SunOS Specific */ +#define __TIOCSETN _IOW('t', 10, struct sgttyb) /* SunOS Specific */ +#define TIOCEXCL _IO('t', 13) +#define TIOCNXCL _IO('t', 14) +#define __TIOCFLUSH _IOW('t', 16, int) /* SunOS Specific */ +#define __TIOCSETC _IOW('t', 17, struct tchars) /* SunOS Specific */ +#define __TIOCGETC _IOR('t', 18, struct tchars) /* SunOS Specific */ +#define __TIOCTCNTL _IOW('t', 32, int) /* SunOS Specific */ +#define __TIOCSIGNAL _IOW('t', 33, int) /* SunOS Specific */ +#define __TIOCSETX _IOW('t', 34, int) /* SunOS Specific */ +#define __TIOCGETX _IOR('t', 35, int) /* SunOS Specific */ +#define TIOCCONS _IO('t', 36) +#define __TIOCSSIZE _IOW('t', 37, struct sunos_ttysize) /* SunOS Specific */ +#define __TIOCGSIZE _IOR('t', 38, struct sunos_ttysize) /* SunOS Specific */ +#define TIOCGSOFTCAR _IOR('t', 100, int) +#define TIOCSSOFTCAR _IOW('t', 101, int) +#define __TIOCUCNTL _IOW('t', 102, int) /* SunOS Specific */ +#define TIOCSWINSZ _IOW('t', 103, struct winsize) +#define TIOCGWINSZ _IOR('t', 104, struct winsize) +#define __TIOCREMOTE _IOW('t', 105, int) /* SunOS Specific */ +#define TIOCMGET _IOR('t', 106, int) +#define TIOCMBIC _IOW('t', 107, int) +#define TIOCMBIS _IOW('t', 108, int) +#define TIOCMSET _IOW('t', 109, int) +#define TIOCSTART _IO('t', 110) +#define TIOCSTOP _IO('t', 111) +#define TIOCPKT _IOW('t', 112, int) +#define TIOCNOTTY _IO('t', 113) +#define TIOCSTI _IOW('t', 114, char) +#define TIOCOUTQ _IOR('t', 115, int) +#define __TIOCGLTC _IOR('t', 116, struct ltchars) /* SunOS Specific */ +#define __TIOCSLTC _IOW('t', 117, struct ltchars) /* SunOS Specific */ +/* 118 is the non-posix setpgrp tty ioctl */ +/* 119 is the non-posix getpgrp tty ioctl */ +#define __TIOCCDTR _IO('t', 120) /* SunOS Specific */ +#define __TIOCSDTR _IO('t', 121) /* SunOS Specific */ +#define TIOCCBRK _IO('t', 122) +#define TIOCSBRK _IO('t', 123) +#define __TIOCLGET _IOW('t', 124, int) /* SunOS Specific */ +#define __TIOCLSET _IOW('t', 125, int) /* SunOS Specific */ +#define __TIOCLBIC _IOW('t', 126, int) /* SunOS Specific */ +#define __TIOCLBIS _IOW('t', 127, int) /* SunOS Specific */ +#define __TIOCISPACE _IOR('t', 128, int) /* SunOS Specific */ +#define __TIOCISIZE _IOR('t', 129, int) /* SunOS Specific */ +#define TIOCSPGRP _IOW('t', 130, int) +#define TIOCGPGRP _IOR('t', 131, int) +#define TIOCSCTTY _IO('t', 132) +#define TIOCGSID _IOR('t', 133, int) +/* Get minor device of a pty master's FD -- Solaris equiv is ISPTM */ +#define TIOCGPTN _IOR('t', 134, unsigned int) /* Get Pty Number */ +#define TIOCSPTLCK _IOW('t', 135, int) /* Lock/unlock PTY */ + +/* Little f */ +#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 FIOQSIZE _IOR('f', 128, loff_t) + +/* SCARY Rutgers local SunOS kernel hackery, perhaps I will support it + * someday. This is completely bogus, I know... + */ +#define __TCGETSTAT _IO('T', 200) /* Rutgers specific */ +#define __TCSETSTAT _IO('T', 201) /* Rutgers specific */ + +/* Linux specific, no SunOS equivalent. */ +#define TIOCLINUX 0x541C +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TCSBRKP 0x5425 +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ +#define TIOCMIWAIT 0x545C /* Wait for change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* Read serial port inline interrupt counts */ + +/* Kernel definitions */ +#ifdef __KERNEL__ +#define TIOCGETC __TIOCGETC +#define TIOCGETP __TIOCGETP +#define TIOCGLTC __TIOCGLTC +#define TIOCSLTC __TIOCSLTC +#define TIOCSETP __TIOCSETP +#define TIOCSETN __TIOCSETN +#define TIOCSETC __TIOCSETC +#endif + +/* 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 + +#endif /* !(_ASM_SPARC64_IOCTLS_H) */ diff --git a/include/asm-sparc64/iommu.h b/include/asm-sparc64/iommu.h new file mode 100644 index 000000000000..5fd16e42a045 --- /dev/null +++ b/include/asm-sparc64/iommu.h @@ -0,0 +1,19 @@ +/* $Id: iommu.h,v 1.10 2001/03/08 09:55:56 davem Exp $ + * iommu.h: Definitions for the sun5 IOMMU. + * + * Copyright (C) 1996, 1999 David S. Miller (davem@caip.rutgers.edu) + */ +#ifndef _SPARC64_IOMMU_H +#define _SPARC64_IOMMU_H + +/* The format of an iopte in the page tables. */ +#define IOPTE_VALID 0x8000000000000000UL /* IOPTE is valid */ +#define IOPTE_64K 0x2000000000000000UL /* IOPTE is for 64k page */ +#define IOPTE_STBUF 0x1000000000000000UL /* DVMA can use streaming buffer */ +#define IOPTE_INTRA 0x0800000000000000UL /* SBUS slot-->slot direct transfer*/ +#define IOPTE_CONTEXT 0x07ff800000000000UL /* Context number */ +#define IOPTE_PAGE 0x00007fffffffe000UL /* Physical page number (PA[42:13])*/ +#define IOPTE_CACHE 0x0000000000000010UL /* Cached (in UPA E-cache) */ +#define IOPTE_WRITE 0x0000000000000002UL /* Writeable */ + +#endif /* !(_SPARC_IOMMU_H) */ diff --git a/include/asm-sparc64/ipc.h b/include/asm-sparc64/ipc.h new file mode 100644 index 000000000000..a46e3d9c2a3f --- /dev/null +++ b/include/asm-sparc64/ipc.h @@ -0,0 +1 @@ +#include <asm-generic/ipc.h> diff --git a/include/asm-sparc64/ipcbuf.h b/include/asm-sparc64/ipcbuf.h new file mode 100644 index 000000000000..9c5bf1bc423f --- /dev/null +++ b/include/asm-sparc64/ipcbuf.h @@ -0,0 +1,28 @@ +#ifndef _SPARC64_IPCBUF_H +#define _SPARC64_IPCBUF_H + +/* + * The ipc64_perm structure for sparc64 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 32-bit seq + * - 2 miscellaneous 64-bit values + */ + +struct ipc64_perm +{ + __kernel_key_t key; + __kernel_uid_t uid; + __kernel_gid_t gid; + __kernel_uid_t cuid; + __kernel_gid_t cgid; + __kernel_mode_t mode; + unsigned short __pad1; + unsigned short seq; + unsigned long __unused1; + unsigned long __unused2; +}; + +#endif /* _SPARC64_IPCBUF_H */ diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h new file mode 100644 index 000000000000..3aef0ca67750 --- /dev/null +++ b/include/asm-sparc64/irq.h @@ -0,0 +1,157 @@ +/* $Id: irq.h,v 1.21 2002/01/23 11:27:36 davem Exp $ + * irq.h: IRQ registers on the 64-bit Sparc. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) + */ + +#ifndef _SPARC64_IRQ_H +#define _SPARC64_IRQ_H + +#include <linux/config.h> +#include <linux/linkage.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/interrupt.h> +#include <asm/pil.h> +#include <asm/ptrace.h> + +/* You should not mess with this directly. That's the job of irq.c. + * + * If you make changes here, please update hand coded assembler of + * SBUS/floppy interrupt handler in entry.S -DaveM + * + * This is currently one DCACHE line, two buckets per L2 cache + * line. Keep this in mind please. + */ +struct ino_bucket { + /* Next handler in per-CPU PIL worklist. We know that + * bucket pointers have the high 32-bits clear, so to + * save space we only store the bits we need. + */ +/*0x00*/unsigned int irq_chain; + + /* PIL to schedule this IVEC at. */ +/*0x04*/unsigned char pil; + + /* If an IVEC arrives while irq_info is NULL, we + * set this to notify request_irq() about the event. + */ +/*0x05*/unsigned char pending; + + /* Miscellaneous flags. */ +/*0x06*/unsigned char flags; + + /* This is used to deal with IBF_DMA_SYNC on + * Sabre systems. + */ +/*0x07*/unsigned char synctab_ent; + + /* Reference to handler for this IRQ. If this is + * non-NULL this means it is active and should be + * serviced. Else the pending member is set to one + * and later registry of the interrupt checks for + * this condition. + * + * Normally this is just an irq_action structure. + * But, on PCI, if multiple interrupt sources behind + * a bridge have multiple interrupt sources that share + * the same INO bucket, this points to an array of + * pointers to four IRQ action structures. + */ +/*0x08*/void *irq_info; + + /* Sun5 Interrupt Clear Register. */ +/*0x10*/unsigned long iclr; + + /* Sun5 Interrupt Mapping Register. */ +/*0x18*/unsigned long imap; + +}; + +#ifdef CONFIG_PCI +extern unsigned long pci_dma_wsync; +extern unsigned long dma_sync_reg_table[256]; +extern unsigned char dma_sync_reg_table_entry; +#endif + +/* IMAP/ICLR register defines */ +#define IMAP_VALID 0x80000000 /* IRQ Enabled */ +#define IMAP_TID_UPA 0x7c000000 /* UPA TargetID */ +#define IMAP_TID_JBUS 0x7c000000 /* JBUS TargetID */ +#define IMAP_AID_SAFARI 0x7c000000 /* Safari AgentID */ +#define IMAP_NID_SAFARI 0x03e00000 /* Safari NodeID */ +#define IMAP_IGN 0x000007c0 /* IRQ Group Number */ +#define IMAP_INO 0x0000003f /* IRQ Number */ +#define IMAP_INR 0x000007ff /* Full interrupt number*/ + +#define ICLR_IDLE 0x00000000 /* Idle state */ +#define ICLR_TRANSMIT 0x00000001 /* Transmit state */ +#define ICLR_PENDING 0x00000003 /* Pending state */ + +/* Only 8-bits are available, be careful. -DaveM */ +#define IBF_DMA_SYNC 0x01 /* DMA synchronization behind PCI bridge needed. */ +#define IBF_PCI 0x02 /* Indicates PSYCHO/SABRE/SCHIZO PCI interrupt. */ +#define IBF_ACTIVE 0x04 /* This interrupt is active and has a handler. */ +#define IBF_MULTI 0x08 /* On PCI, indicates shared bucket. */ +#define IBF_INPROGRESS 0x10 /* IRQ is being serviced. */ + +#define NUM_IVECS (IMAP_INR + 1) +extern struct ino_bucket ivector_table[NUM_IVECS]; + +#define __irq_ino(irq) \ + (((struct ino_bucket *)(unsigned long)(irq)) - &ivector_table[0]) +#define __irq_pil(irq) ((struct ino_bucket *)(unsigned long)(irq))->pil +#define __bucket(irq) ((struct ino_bucket *)(unsigned long)(irq)) +#define __irq(bucket) ((unsigned int)(unsigned long)(bucket)) + +static __inline__ char *__irq_itoa(unsigned int irq) +{ + static char buff[16]; + + sprintf(buff, "%d,%x", __irq_pil(irq), (unsigned int)__irq_ino(irq)); + return buff; +} + +#define NR_IRQS 16 + +#define irq_canonicalize(irq) (irq) +extern void disable_irq(unsigned int); +#define disable_irq_nosync disable_irq +extern void enable_irq(unsigned int); +extern unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap); +extern unsigned int sbus_build_irq(void *sbus, unsigned int ino); + +extern int request_fast_irq(unsigned int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long flags, __const__ char *devname, + void *dev_id); + +static __inline__ void set_softint(unsigned long bits) +{ + __asm__ __volatile__("wr %0, 0x0, %%set_softint" + : /* No outputs */ + : "r" (bits)); +} + +static __inline__ void clear_softint(unsigned long bits) +{ + __asm__ __volatile__("wr %0, 0x0, %%clear_softint" + : /* No outputs */ + : "r" (bits)); +} + +static __inline__ unsigned long get_softint(void) +{ + unsigned long retval; + + __asm__ __volatile__("rd %%softint, %0" + : "=r" (retval)); + return retval; +} + +struct irqaction; +struct pt_regs; +int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *); + +#endif diff --git a/include/asm-sparc64/isa.h b/include/asm-sparc64/isa.h new file mode 100644 index 000000000000..4601bbfc3e7b --- /dev/null +++ b/include/asm-sparc64/isa.h @@ -0,0 +1,54 @@ +/* $Id: isa.h,v 1.1 2001/05/11 04:31:55 davem Exp $ + * isa.h: Sparc64 layer for PCI to ISA bridge devices. + * + * Copyright (C) 2001 David S. Miller (davem@redhat.com) + */ + +#ifndef __SPARC64_ISA_H +#define __SPARC64_ISA_H + +#include <asm/pbm.h> +#include <asm/oplib.h> + +struct sparc_isa_bridge; + +struct sparc_isa_device { + struct sparc_isa_device *next; + struct sparc_isa_device *child; + struct sparc_isa_bridge *bus; + int prom_node; + char prom_name[64]; + char compatible[64]; + struct resource resource; + unsigned int irq; +}; + +struct sparc_isa_bridge { + struct sparc_isa_bridge *next; + struct sparc_isa_device *devices; + struct pci_pbm_info *parent; + struct pci_dev *self; + int index; + int prom_node; + char prom_name[64]; +#define linux_prom_isa_ranges linux_prom_ebus_ranges + struct linux_prom_isa_ranges isa_ranges[PROMREG_MAX]; + int num_isa_ranges; +#define linux_prom_isa_intmap linux_prom_ebus_intmap + struct linux_prom_isa_intmap isa_intmap[PROMREG_MAX]; + int num_isa_intmap; +#define linux_prom_isa_intmask linux_prom_ebus_intmask + struct linux_prom_isa_intmap isa_intmask; +}; + +extern struct sparc_isa_bridge *isa_chain; + +extern void isa_init(void); + +#define for_each_isa(bus) \ + for((bus) = isa_chain; (bus); (bus) = (bus)->next) + +#define for_each_isadev(dev, bus) \ + for((dev) = (bus)->devices; (dev); (dev) = (dev)->next) + +#endif /* !(__SPARC64_ISA_H) */ diff --git a/include/asm-sparc64/kbio.h b/include/asm-sparc64/kbio.h new file mode 100644 index 000000000000..3cf496bdf399 --- /dev/null +++ b/include/asm-sparc64/kbio.h @@ -0,0 +1,56 @@ +#ifndef __LINUX_KBIO_H +#define __LINUX_KBIO_H + +/* Return keyboard type */ +#define KIOCTYPE _IOR('k', 9, int) +/* Return Keyboard layout */ +#define KIOCLAYOUT _IOR('k', 20, int) + +enum { + TR_NONE, + TR_ASCII, /* keyboard is in regular state */ + TR_EVENT, /* keystrokes sent as firm events */ + TR_UNTRANS_EVENT /* EVENT+up and down+no translation */ +}; + +/* Return the current keyboard translation */ +#define KIOCGTRANS _IOR('k', 5, int) +/* Set the keyboard translation */ +#define KIOCTRANS _IOW('k', 0, int) + +/* Send a keyboard command */ +#define KIOCCMD _IOW('k', 8, int) + +/* Return if keystrokes are being sent to /dev/kbd */ + +/* Set routing of keystrokes to /dev/kbd */ +#define KIOCSDIRECT _IOW('k', 10, int) + +/* Set keyboard leds */ +#define KIOCSLED _IOW('k', 14, unsigned char) + +/* Get keyboard leds */ +#define KIOCGLED _IOR('k', 15, unsigned char) + +/* Used by KIOC[GS]RATE */ +struct kbd_rate { + unsigned char delay; /* Delay in Hz before first repeat. */ + unsigned char rate; /* In characters per second (0..50). */ +}; + +/* Set keyboard rate */ +#define KIOCSRATE _IOW('k', 40, struct kbd_rate) + +/* Get keyboard rate */ +#define KIOCGRATE _IOW('k', 41, struct kbd_rate) + +/* Top bit records if the key is up or down */ +#define KBD_UP 0x80 + +/* Usable information */ +#define KBD_KEYMASK 0x7f + +/* All keys up */ +#define KBD_IDLE 0x75 + +#endif /* __LINUX_KBIO_H */ diff --git a/include/asm-sparc64/kdebug.h b/include/asm-sparc64/kdebug.h new file mode 100644 index 000000000000..f70d3dad01f9 --- /dev/null +++ b/include/asm-sparc64/kdebug.h @@ -0,0 +1,52 @@ +#ifndef _SPARC64_KDEBUG_H +#define _SPARC64_KDEBUG_H + +/* Nearly identical to x86_64/i386 code. */ + +#include <linux/notifier.h> + +struct pt_regs; + +struct die_args { + struct pt_regs *regs; + const char *str; + long err; + int trapnr; + int signr; +}; + +/* Note - you should never unregister because that can race with NMIs. + * If you really want to do it first unregister - then synchronize_kernel + * - then free. + */ +int register_die_notifier(struct notifier_block *nb); +extern struct notifier_block *sparc64die_chain; + +extern void bad_trap(struct pt_regs *, long); + +/* Grossly misnamed. */ +enum die_val { + DIE_OOPS = 1, + DIE_DEBUG, /* ta 0x70 */ + DIE_DEBUG_2, /* ta 0x71 */ + DIE_DIE, + DIE_TRAP, + DIE_TRAP_TL1, + DIE_GPF, + DIE_CALL, + DIE_PAGE_FAULT, +}; + +static inline int notify_die(enum die_val val,char *str, struct pt_regs *regs, + long err, int trap, int sig) +{ + struct die_args args = { .regs = regs, + .str = str, + .err = err, + .trapnr = trap, + .signr = sig }; + + return notifier_call_chain(&sparc64die_chain, val, &args); +} + +#endif diff --git a/include/asm-sparc64/kmap_types.h b/include/asm-sparc64/kmap_types.h new file mode 100644 index 000000000000..34c1d3d9a3b0 --- /dev/null +++ b/include/asm-sparc64/kmap_types.h @@ -0,0 +1,25 @@ +#ifndef _ASM_KMAP_TYPES_H +#define _ASM_KMAP_TYPES_H + +/* Dummy header just to define km_type. None of this + * is actually used on sparc64. -DaveM + */ + +enum km_type { + KM_BOUNCE_READ, + KM_SKB_SUNRPC_DATA, + KM_SKB_DATA_SOFTIRQ, + KM_USER0, + KM_USER1, + KM_BIO_SRC_IRQ, + KM_BIO_DST_IRQ, + KM_PTE0, + KM_PTE1, + KM_IRQ0, + KM_IRQ1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, + KM_TYPE_NR +}; + +#endif diff --git a/include/asm-sparc64/kprobes.h b/include/asm-sparc64/kprobes.h new file mode 100644 index 000000000000..a8d326a598f0 --- /dev/null +++ b/include/asm-sparc64/kprobes.h @@ -0,0 +1,32 @@ +#ifndef _SPARC64_KPROBES_H +#define _SPARC64_KPROBES_H + +#include <linux/config.h> +#include <linux/types.h> + +typedef u32 kprobe_opcode_t; + +#define BREAKPOINT_INSTRUCTION 0x91d02070 /* ta 0x70 */ +#define BREAKPOINT_INSTRUCTION_2 0x91d02071 /* ta 0x71 */ +#define MAX_INSN_SIZE 2 + +#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry + +/* Architecture specific copy of original instruction*/ +struct arch_specific_insn { + /* copy of the original instruction */ + kprobe_opcode_t insn[MAX_INSN_SIZE]; +}; + +#ifdef CONFIG_KPROBES +extern int kprobe_exceptions_notify(struct notifier_block *self, + unsigned long val, void *data); +#else /* !CONFIG_KPROBES */ +static inline int kprobe_exceptions_notify(struct notifier_block *self, + unsigned long val, void *data) +{ + return 0; +} +#endif + +#endif /* _SPARC64_KPROBES_H */ diff --git a/include/asm-sparc64/linkage.h b/include/asm-sparc64/linkage.h new file mode 100644 index 000000000000..291c2d01c44f --- /dev/null +++ b/include/asm-sparc64/linkage.h @@ -0,0 +1,6 @@ +#ifndef __ASM_LINKAGE_H +#define __ASM_LINKAGE_H + +/* Nothing to see here... */ + +#endif diff --git a/include/asm-sparc64/local.h b/include/asm-sparc64/local.h new file mode 100644 index 000000000000..dfde115ac892 --- /dev/null +++ b/include/asm-sparc64/local.h @@ -0,0 +1,40 @@ +#ifndef _ARCH_SPARC64_LOCAL_H +#define _ARCH_SPARC64_LOCAL_H + +#include <linux/percpu.h> +#include <asm/atomic.h> + +typedef atomic64_t local_t; + +#define LOCAL_INIT(i) ATOMIC64_INIT(i) +#define local_read(v) atomic64_read(v) +#define local_set(v,i) atomic64_set(v,i) + +#define local_inc(v) atomic64_inc(v) +#define local_dec(v) atomic64_dec(v) +#define local_add(i, v) atomic64_add(i, v) +#define local_sub(i, v) atomic64_sub(i, v) + +#define __local_inc(v) ((v)->counter++) +#define __local_dec(v) ((v)->counter--) +#define __local_add(i,v) ((v)->counter+=(i)) +#define __local_sub(i,v) ((v)->counter-=(i)) + +/* Use these for per-cpu local_t variables: on some archs they are + * much more efficient than these naive implementations. Note they take + * a variable, not an address. + */ +#define cpu_local_read(v) local_read(&__get_cpu_var(v)) +#define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i)) + +#define cpu_local_inc(v) local_inc(&__get_cpu_var(v)) +#define cpu_local_dec(v) local_dec(&__get_cpu_var(v)) +#define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v)) +#define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v)) + +#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v)) +#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v)) +#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v)) +#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v)) + +#endif /* _ARCH_SPARC64_LOCAL_H */ diff --git a/include/asm-sparc64/lsu.h b/include/asm-sparc64/lsu.h new file mode 100644 index 000000000000..e5329c7f5833 --- /dev/null +++ b/include/asm-sparc64/lsu.h @@ -0,0 +1,20 @@ +/* $Id: lsu.h,v 1.2 1997/04/04 00:50:22 davem Exp $ */ +#ifndef _SPARC64_LSU_H +#define _SPARC64_LSU_H + +#include <asm/const.h> + +/* LSU Control Register */ +#define LSU_CONTROL_PM _AC(0x000001fe00000000,UL) /* Phys-watchpoint byte mask*/ +#define LSU_CONTROL_VM _AC(0x00000001fe000000,UL) /* Virt-watchpoint byte mask*/ +#define LSU_CONTROL_PR _AC(0x0000000001000000,UL) /* Phys-rd watchpoint enable*/ +#define LSU_CONTROL_PW _AC(0x0000000000800000,UL) /* Phys-wr watchpoint enable*/ +#define LSU_CONTROL_VR _AC(0x0000000000400000,UL) /* Virt-rd watchpoint enable*/ +#define LSU_CONTROL_VW _AC(0x0000000000200000,UL) /* Virt-wr watchpoint enable*/ +#define LSU_CONTROL_FM _AC(0x00000000000ffff0,UL) /* Parity mask enables. */ +#define LSU_CONTROL_DM _AC(0x0000000000000008,UL) /* Data MMU enable. */ +#define LSU_CONTROL_IM _AC(0x0000000000000004,UL) /* Instruction MMU enable. */ +#define LSU_CONTROL_DC _AC(0x0000000000000002,UL) /* Data cache enable. */ +#define LSU_CONTROL_IC _AC(0x0000000000000001,UL) /* Instruction cache enable.*/ + +#endif /* !(_SPARC64_LSU_H) */ diff --git a/include/asm-sparc64/mc146818rtc.h b/include/asm-sparc64/mc146818rtc.h new file mode 100644 index 000000000000..75bd572b35fe --- /dev/null +++ b/include/asm-sparc64/mc146818rtc.h @@ -0,0 +1,35 @@ +/* + * Machine dependent access functions for RTC registers. + */ +#ifndef __ASM_SPARC64_MC146818RTC_H +#define __ASM_SPARC64_MC146818RTC_H + +#include <linux/config.h> +#include <asm/io.h> + +#ifndef RTC_PORT +#ifdef CONFIG_PCI +extern unsigned long ds1287_regs; +#else +#define ds1287_regs (0UL) +#endif +#define RTC_PORT(x) (ds1287_regs + (x)) +#define RTC_ALWAYS_BCD 0 +#endif + +/* + * The yet supported machines all access the RTC index register via + * an ISA port access but the way to access the date register differs ... + */ +#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)); \ +}) + +#define RTC_IRQ 8 + +#endif /* __ASM_SPARC64_MC146818RTC_H */ diff --git a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h new file mode 100644 index 000000000000..01cecf54357b --- /dev/null +++ b/include/asm-sparc64/mman.h @@ -0,0 +1,62 @@ +/* $Id: mman.h,v 1.2 2000/03/15 02:44:26 davem Exp $ */ +#ifndef __SPARC64_MMAN_H__ +#define __SPARC64_MMAN_H__ + +/* SunOS'ified... */ + +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_SEM 0x8 /* page may be used for atomic ops */ +#define PROT_NONE 0x0 /* page can not be accessed */ +#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ +#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ + +#define MAP_SHARED 0x01 /* Share changes */ +#define MAP_PRIVATE 0x02 /* Changes are private */ +#define MAP_TYPE 0x0f /* Mask for type of mapping */ +#define MAP_FIXED 0x10 /* Interpret addr exactly */ +#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ +#define MAP_NORESERVE 0x40 /* don't reserve swap pages */ +#define MAP_INHERIT 0x80 /* SunOS doesn't do this, but... */ +#define MAP_LOCKED 0x100 /* lock the mapping */ +#define _MAP_NEW 0x80000000 /* Binary compatibility is fun... */ + +#define MAP_GROWSDOWN 0x0200 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ + +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_INVALIDATE 2 /* invalidate the caches */ +#define MS_SYNC 4 /* synchronous memory sync */ + +#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */ +#define MCL_FUTURE 0x4000 /* lock all additions to address space */ + +#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ +#define MAP_NONBLOCK 0x10000 /* do not block on IO */ + +/* XXX Need to add flags to SunOS's mctl, mlockall, and madvise system + * XXX calls. + */ + +/* SunOS sys_mctl() stuff... */ +#define MC_SYNC 1 /* Sync pages in memory with storage (usu. a file) */ +#define MC_LOCK 2 /* Lock pages into core ram, do not allow swapping of them */ +#define MC_UNLOCK 3 /* Unlock pages locked via previous mctl() with MC_LOCK arg */ +#define MC_LOCKAS 5 /* Lock an entire address space of the calling process */ +#define MC_UNLOCKAS 6 /* Unlock entire address space of calling process */ + +#define MADV_NORMAL 0x0 /* default page-in behavior */ +#define MADV_RANDOM 0x1 /* page-in minimum required */ +#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ +#define MADV_WILLNEED 0x3 /* pre-fault pages */ +#define MADV_DONTNEED 0x4 /* discard these pages */ +#define MADV_FREE 0x5 /* (Solaris) contents can be freed */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif /* __SPARC64_MMAN_H__ */ diff --git a/include/asm-sparc64/mmu.h b/include/asm-sparc64/mmu.h new file mode 100644 index 000000000000..8627eed6e83d --- /dev/null +++ b/include/asm-sparc64/mmu.h @@ -0,0 +1,99 @@ +#ifndef __MMU_H +#define __MMU_H + +#include <linux/config.h> +#include <asm/page.h> +#include <asm/const.h> + +/* + * For the 8k pagesize kernel, use only 10 hw context bits to optimize some + * shifts in the fast tlbmiss handlers, instead of all 13 bits (specifically + * for vpte offset calculation). For other pagesizes, this optimization in + * the tlbhandlers can not be done; but still, all 13 bits can not be used + * because the tlb handlers use "andcc" instruction which sign extends 13 + * bit arguments. + */ +#if PAGE_SHIFT == 13 +#define CTX_NR_BITS 10 +#else +#define CTX_NR_BITS 12 +#endif + +#define TAG_CONTEXT_BITS ((_AC(1,UL) << CTX_NR_BITS) - _AC(1,UL)) + +/* UltraSPARC-III+ and later have a feature whereby you can + * select what page size the various Data-TLB instances in the + * chip. In order to gracefully support this, we put the version + * field in a spot outside of the areas of the context register + * where this parameter is specified. + */ +#define CTX_VERSION_SHIFT 22 +#define CTX_VERSION_MASK ((~0UL) << CTX_VERSION_SHIFT) + +#define CTX_PGSZ_8KB _AC(0x0,UL) +#define CTX_PGSZ_64KB _AC(0x1,UL) +#define CTX_PGSZ_512KB _AC(0x2,UL) +#define CTX_PGSZ_4MB _AC(0x3,UL) +#define CTX_PGSZ_BITS _AC(0x7,UL) +#define CTX_PGSZ0_NUC_SHIFT 61 +#define CTX_PGSZ1_NUC_SHIFT 58 +#define CTX_PGSZ0_SHIFT 16 +#define CTX_PGSZ1_SHIFT 19 +#define CTX_PGSZ_MASK ((CTX_PGSZ_BITS << CTX_PGSZ0_SHIFT) | \ + (CTX_PGSZ_BITS << CTX_PGSZ1_SHIFT)) + +#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB) +#define CTX_PGSZ_BASE CTX_PGSZ_8KB +#elif defined(CONFIG_SPARC64_PAGE_SIZE_64KB) +#define CTX_PGSZ_BASE CTX_PGSZ_64KB +#elif defined(CONFIG_SPARC64_PAGE_SIZE_512KB) +#define CTX_PGSZ_BASE CTX_PGSZ_512KB +#elif defined(CONFIG_SPARC64_PAGE_SIZE_4MB) +#define CTX_PGSZ_BASE CTX_PGSZ_4MB +#else +#error No page size specified in kernel configuration +#endif + +#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB) +#define CTX_PGSZ_HUGE CTX_PGSZ_4MB +#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K) +#define CTX_PGSZ_HUGE CTX_PGSZ_512KB +#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K) +#define CTX_PGSZ_HUGE CTX_PGSZ_64KB +#endif + +#define CTX_PGSZ_KERN CTX_PGSZ_4MB + +/* Thus, when running on UltraSPARC-III+ and later, we use the following + * PRIMARY_CONTEXT register values for the kernel context. + */ +#define CTX_CHEETAH_PLUS_NUC \ + ((CTX_PGSZ_KERN << CTX_PGSZ0_NUC_SHIFT) | \ + (CTX_PGSZ_BASE << CTX_PGSZ1_NUC_SHIFT)) + +#define CTX_CHEETAH_PLUS_CTX0 \ + ((CTX_PGSZ_KERN << CTX_PGSZ0_SHIFT) | \ + (CTX_PGSZ_BASE << CTX_PGSZ1_SHIFT)) + +/* If you want "the TLB context number" use CTX_NR_MASK. If you + * want "the bits I program into the context registers" use + * CTX_HW_MASK. + */ +#define CTX_NR_MASK TAG_CONTEXT_BITS +#define CTX_HW_MASK (CTX_NR_MASK | CTX_PGSZ_MASK) + +#define CTX_FIRST_VERSION ((_AC(1,UL) << CTX_VERSION_SHIFT) + _AC(1,UL)) +#define CTX_VALID(__ctx) \ + (!(((__ctx.sparc64_ctx_val) ^ tlb_context_cache) & CTX_VERSION_MASK)) +#define CTX_HWBITS(__ctx) ((__ctx.sparc64_ctx_val) & CTX_HW_MASK) +#define CTX_NRBITS(__ctx) ((__ctx.sparc64_ctx_val) & CTX_NR_MASK) + +#ifndef __ASSEMBLY__ + +typedef struct { + unsigned long sparc64_ctx_val; +} mm_context_t; + +#endif /* !__ASSEMBLY__ */ + +#endif /* __MMU_H */ diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h new file mode 100644 index 000000000000..87c43c67866e --- /dev/null +++ b/include/asm-sparc64/mmu_context.h @@ -0,0 +1,145 @@ +/* $Id: mmu_context.h,v 1.54 2002/02/09 19:49:31 davem Exp $ */ +#ifndef __SPARC64_MMU_CONTEXT_H +#define __SPARC64_MMU_CONTEXT_H + +/* Derived heavily from Linus's Alpha/AXP ASN code... */ + +#ifndef __ASSEMBLY__ + +#include <linux/spinlock.h> +#include <asm/system.h> +#include <asm/spitfire.h> + +static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) +{ +} + +extern spinlock_t ctx_alloc_lock; +extern unsigned long tlb_context_cache; +extern unsigned long mmu_context_bmap[]; + +extern void get_new_mmu_context(struct mm_struct *mm); + +/* Initialize a new mmu context. This is invoked when a new + * address space instance (unique or shared) is instantiated. + * This just needs to set mm->context to an invalid context. + */ +#define init_new_context(__tsk, __mm) \ + (((__mm)->context.sparc64_ctx_val = 0UL), 0) + +/* Destroy a dead context. This occurs when mmput drops the + * mm_users count to zero, the mmaps have been released, and + * all the page tables have been flushed. Our job is to destroy + * any remaining processor-specific state, and in the sparc64 + * case this just means freeing up the mmu context ID held by + * this task if valid. + */ +#define destroy_context(__mm) \ +do { spin_lock(&ctx_alloc_lock); \ + if (CTX_VALID((__mm)->context)) { \ + unsigned long nr = CTX_NRBITS((__mm)->context); \ + mmu_context_bmap[nr>>6] &= ~(1UL << (nr & 63)); \ + } \ + spin_unlock(&ctx_alloc_lock); \ +} while(0) + +/* Reload the two core values used by TLB miss handler + * processing on sparc64. They are: + * 1) The physical address of mm->pgd, when full page + * table walks are necessary, this is where the + * search begins. + * 2) A "PGD cache". For 32-bit tasks only pgd[0] is + * ever used since that maps the entire low 4GB + * completely. To speed up TLB miss processing we + * make this value available to the handlers. This + * decreases the amount of memory traffic incurred. + */ +#define reload_tlbmiss_state(__tsk, __mm) \ +do { \ + register unsigned long paddr asm("o5"); \ + register unsigned long pgd_cache asm("o4"); \ + paddr = __pa((__mm)->pgd); \ + pgd_cache = 0UL; \ + if ((__tsk)->thread_info->flags & _TIF_32BIT) \ + pgd_cache = get_pgd_cache((__mm)->pgd); \ + __asm__ __volatile__("wrpr %%g0, 0x494, %%pstate\n\t" \ + "mov %3, %%g4\n\t" \ + "mov %0, %%g7\n\t" \ + "stxa %1, [%%g4] %2\n\t" \ + "membar #Sync\n\t" \ + "wrpr %%g0, 0x096, %%pstate" \ + : /* no outputs */ \ + : "r" (paddr), "r" (pgd_cache),\ + "i" (ASI_DMMU), "i" (TSB_REG)); \ +} while(0) + +/* Set MMU context in the actual hardware. */ +#define load_secondary_context(__mm) \ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" \ + "flush %%g6" \ + : /* No outputs */ \ + : "r" (CTX_HWBITS((__mm)->context)), \ + "r" (SECONDARY_CONTEXT), "i" (ASI_DMMU)) + +extern void __flush_tlb_mm(unsigned long, unsigned long); + +/* Switch the current MM context. */ +static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, struct task_struct *tsk) +{ + unsigned long ctx_valid; + + spin_lock(&mm->page_table_lock); + if (CTX_VALID(mm->context)) + ctx_valid = 1; + else + ctx_valid = 0; + + if (!ctx_valid || (old_mm != mm)) { + if (!ctx_valid) + get_new_mmu_context(mm); + + load_secondary_context(mm); + reload_tlbmiss_state(tsk, mm); + } + + { + int cpu = smp_processor_id(); + + /* Even if (mm == old_mm) we _must_ check + * the cpu_vm_mask. If we do not we could + * corrupt the TLB state because of how + * smp_flush_tlb_{page,range,mm} on sparc64 + * and lazy tlb switches work. -DaveM + */ + if (!ctx_valid || !cpu_isset(cpu, mm->cpu_vm_mask)) { + cpu_set(cpu, mm->cpu_vm_mask); + __flush_tlb_mm(CTX_HWBITS(mm->context), + SECONDARY_CONTEXT); + } + } + spin_unlock(&mm->page_table_lock); +} + +#define deactivate_mm(tsk,mm) do { } while (0) + +/* Activate a new MM instance for the current task. */ +static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm) +{ + int cpu; + + spin_lock(&mm->page_table_lock); + if (!CTX_VALID(mm->context)) + get_new_mmu_context(mm); + cpu = smp_processor_id(); + if (!cpu_isset(cpu, mm->cpu_vm_mask)) + cpu_set(cpu, mm->cpu_vm_mask); + spin_unlock(&mm->page_table_lock); + + load_secondary_context(mm); + __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT); + reload_tlbmiss_state(current, mm); +} + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(__SPARC64_MMU_CONTEXT_H) */ diff --git a/include/asm-sparc64/module.h b/include/asm-sparc64/module.h new file mode 100644 index 000000000000..3d77ba465783 --- /dev/null +++ b/include/asm-sparc64/module.h @@ -0,0 +1,7 @@ +#ifndef _ASM_SPARC64_MODULE_H +#define _ASM_SPARC64_MODULE_H +struct mod_arch_specific { }; +#define Elf_Shdr Elf64_Shdr +#define Elf_Sym Elf64_Sym +#define Elf_Ehdr Elf64_Ehdr +#endif /* _ASM_SPARC64_MODULE_H */ diff --git a/include/asm-sparc64/mostek.h b/include/asm-sparc64/mostek.h new file mode 100644 index 000000000000..ccf2f5f82d7f --- /dev/null +++ b/include/asm-sparc64/mostek.h @@ -0,0 +1,144 @@ +/* $Id: mostek.h,v 1.4 2001/01/11 15:07:09 davem Exp $ + * mostek.h: Describes the various Mostek time of day clock registers. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu) + */ + +#ifndef _SPARC64_MOSTEK_H +#define _SPARC64_MOSTEK_H + +#include <asm/idprom.h> + +/* M48T02 Register Map (adapted from Sun NVRAM/Hostid FAQ) + * + * Data + * Address Function + * Bit 7 Bit 6 Bit 5 Bit 4Bit 3 Bit 2 Bit 1 Bit 0 + * 7ff - - - - - - - - Year 00-99 + * 7fe 0 0 0 - - - - - Month 01-12 + * 7fd 0 0 - - - - - - Date 01-31 + * 7fc 0 FT 0 0 0 - - - Day 01-07 + * 7fb KS 0 - - - - - - Hours 00-23 + * 7fa 0 - - - - - - - Minutes 00-59 + * 7f9 ST - - - - - - - Seconds 00-59 + * 7f8 W R S - - - - - Control + * + * * ST is STOP BIT + * * W is WRITE BIT + * * R is READ BIT + * * S is SIGN BIT + * * FT is FREQ TEST BIT + * * KS is KICK START BIT + */ + +/* The Mostek 48t02 real time clock and NVRAM chip. The registers + * other than the control register are in binary coded decimal. Some + * control bits also live outside the control register. + * + * We now deal with physical addresses for I/O to the chip. -DaveM + */ +static __inline__ u8 mostek_read(unsigned long addr) +{ + u8 ret; + + __asm__ __volatile__("lduba [%1] %2, %0" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + return ret; +} + +static __inline__ void mostek_write(unsigned long addr, u8 val) +{ + __asm__ __volatile__("stba %0, [%1] %2" + : /* no outputs */ + : "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +#define MOSTEK_EEPROM 0x0000UL +#define MOSTEK_IDPROM 0x07d8UL +#define MOSTEK_CREG 0x07f8UL +#define MOSTEK_SEC 0x07f9UL +#define MOSTEK_MIN 0x07faUL +#define MOSTEK_HOUR 0x07fbUL +#define MOSTEK_DOW 0x07fcUL +#define MOSTEK_DOM 0x07fdUL +#define MOSTEK_MONTH 0x07feUL +#define MOSTEK_YEAR 0x07ffUL + +extern spinlock_t mostek_lock; +extern unsigned long mstk48t02_regs; + +/* Control register values. */ +#define MSTK_CREG_WRITE 0x80 /* Must set this before placing values. */ +#define MSTK_CREG_READ 0x40 /* Stop updates to allow a clean read. */ +#define MSTK_CREG_SIGN 0x20 /* Slow/speed clock in calibration mode. */ + +/* Control bits that live in the other registers. */ +#define MSTK_STOP 0x80 /* Stop the clock oscillator. (sec) */ +#define MSTK_KICK_START 0x80 /* Kick start the clock chip. (hour) */ +#define MSTK_FREQ_TEST 0x40 /* Frequency test mode. (day) */ + +#define MSTK_YEAR_ZERO 1968 /* If year reg has zero, it is 1968. */ +#define MSTK_CVT_YEAR(yr) ((yr) + MSTK_YEAR_ZERO) + +/* Masks that define how much space each value takes up. */ +#define MSTK_SEC_MASK 0x7f +#define MSTK_MIN_MASK 0x7f +#define MSTK_HOUR_MASK 0x3f +#define MSTK_DOW_MASK 0x07 +#define MSTK_DOM_MASK 0x3f +#define MSTK_MONTH_MASK 0x1f +#define MSTK_YEAR_MASK 0xff + +/* Binary coded decimal conversion macros. */ +#define MSTK_REGVAL_TO_DECIMAL(x) (((x) & 0x0F) + 0x0A * ((x) >> 0x04)) +#define MSTK_DECIMAL_TO_REGVAL(x) ((((x) / 0x0A) << 0x04) + ((x) % 0x0A)) + +/* Generic register set and get macros for internal use. */ +#define MSTK_GET(regs,name) \ + (MSTK_REGVAL_TO_DECIMAL(mostek_read(regs + MOSTEK_ ## name) & MSTK_ ## name ## _MASK)) +#define MSTK_SET(regs,name,value) \ +do { u8 __val = mostek_read(regs + MOSTEK_ ## name); \ + __val &= ~(MSTK_ ## name ## _MASK); \ + __val |= (MSTK_DECIMAL_TO_REGVAL(value) & \ + (MSTK_ ## name ## _MASK)); \ + mostek_write(regs + MOSTEK_ ## name, __val); \ +} while(0) + +/* Macros to make register access easier on our fingers. These give you + * the decimal value of the register requested if applicable. You pass + * the a pointer to a 'struct mostek48t02'. + */ +#define MSTK_REG_CREG(regs) (mostek_read((regs) + MOSTEK_CREG)) +#define MSTK_REG_SEC(regs) MSTK_GET(regs,SEC) +#define MSTK_REG_MIN(regs) MSTK_GET(regs,MIN) +#define MSTK_REG_HOUR(regs) MSTK_GET(regs,HOUR) +#define MSTK_REG_DOW(regs) MSTK_GET(regs,DOW) +#define MSTK_REG_DOM(regs) MSTK_GET(regs,DOM) +#define MSTK_REG_MONTH(regs) MSTK_GET(regs,MONTH) +#define MSTK_REG_YEAR(regs) MSTK_GET(regs,YEAR) + +#define MSTK_SET_REG_SEC(regs,value) MSTK_SET(regs,SEC,value) +#define MSTK_SET_REG_MIN(regs,value) MSTK_SET(regs,MIN,value) +#define MSTK_SET_REG_HOUR(regs,value) MSTK_SET(regs,HOUR,value) +#define MSTK_SET_REG_DOW(regs,value) MSTK_SET(regs,DOW,value) +#define MSTK_SET_REG_DOM(regs,value) MSTK_SET(regs,DOM,value) +#define MSTK_SET_REG_MONTH(regs,value) MSTK_SET(regs,MONTH,value) +#define MSTK_SET_REG_YEAR(regs,value) MSTK_SET(regs,YEAR,value) + + +/* The Mostek 48t08 clock chip. Found on Sun4m's I think. It has the + * same (basically) layout of the 48t02 chip except for the extra + * NVRAM on board (8 KB against the 48t02's 2 KB). + */ +#define MOSTEK_48T08_OFFSET 0x0000UL /* Lower NVRAM portions */ +#define MOSTEK_48T08_48T02 0x1800UL /* Offset to 48T02 chip */ + +/* SUN5 systems usually have 48t59 model clock chipsets. But we keep the older + * clock chip definitions around just in case. + */ +#define MOSTEK_48T59_OFFSET 0x0000UL /* Lower NVRAM portions */ +#define MOSTEK_48T59_48T02 0x1800UL /* Offset to 48T02 chip */ + +#endif /* !(_SPARC64_MOSTEK_H) */ diff --git a/include/asm-sparc64/msgbuf.h b/include/asm-sparc64/msgbuf.h new file mode 100644 index 000000000000..55c101bd0e7d --- /dev/null +++ b/include/asm-sparc64/msgbuf.h @@ -0,0 +1,27 @@ +#ifndef _SPARC64_MSGBUF_H +#define _SPARC64_MSGBUF_H + +/* + * The msqid64_ds structure for sparc64 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 2 miscellaneous 64-bit values + */ + +struct msqid64_ds { + struct ipc64_perm msg_perm; + __kernel_time_t msg_stime; /* last msgsnd time */ + __kernel_time_t msg_rtime; /* last msgrcv time */ + __kernel_time_t msg_ctime; /* last change time */ + unsigned long msg_cbytes; /* current number of bytes on queue */ + unsigned long msg_qnum; /* number of messages in queue */ + unsigned long msg_qbytes; /* max number of bytes on queue */ + __kernel_pid_t msg_lspid; /* pid of last msgsnd */ + __kernel_pid_t msg_lrpid; /* last receive pid */ + unsigned long __unused1; + unsigned long __unused2; +}; + +#endif /* _SPARC64_MSGBUF_H */ diff --git a/include/asm-sparc64/namei.h b/include/asm-sparc64/namei.h new file mode 100644 index 000000000000..ccda19e28695 --- /dev/null +++ b/include/asm-sparc64/namei.h @@ -0,0 +1,26 @@ +/* $Id: namei.h,v 1.17 2000/04/13 00:55:54 davem Exp $ + * linux/include/asm-sparc64/namei.h + * + * Routines to handle famous /usr/gnemul/s*. + * Included from linux/fs/namei.c + */ + +#ifndef __SPARC64_NAMEI_H +#define __SPARC64_NAMEI_H + +#define SPARC_BSD_EMUL "/usr/gnemul/sunos/" +#define SPARC_SOL_EMUL "/usr/gnemul/solaris/" + +static inline char * __emul_prefix(void) +{ + switch (current->personality) { + case PER_SUNOS: + return SPARC_BSD_EMUL; + case PER_SVR4: + return SPARC_SOL_EMUL; + default: + return NULL; + } +} + +#endif /* __SPARC64_NAMEI_H */ diff --git a/include/asm-sparc64/ns87303.h b/include/asm-sparc64/ns87303.h new file mode 100644 index 000000000000..6d58fdf349b5 --- /dev/null +++ b/include/asm-sparc64/ns87303.h @@ -0,0 +1,119 @@ +/* $Id: ns87303.h,v 1.3 2000/01/09 15:16:34 ecd Exp $ + * ns87303.h: Configuration Register Description for the + * National Semiconductor PC87303 (SuperIO). + * + * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) + */ + +#ifndef _SPARC_NS87303_H +#define _SPARC_NS87303_H 1 + +/* + * Control Register Index Values + */ +#define FER 0x00 +#define FAR 0x01 +#define PTR 0x02 +#define FCR 0x03 +#define PCR 0x04 +#define KRR 0x05 +#define PMC 0x06 +#define TUP 0x07 +#define SID 0x08 +#define ASC 0x09 +#define CS0CF0 0x0a +#define CS0CF1 0x0b +#define CS1CF0 0x0c +#define CS1CF1 0x0d + +/* Function Enable Register (FER) bits */ +#define FER_EDM 0x10 /* Encoded Drive and Motor pin information */ + +/* Function Address Register (FAR) bits */ +#define FAR_LPT_MASK 0x03 +#define FAR_LPTB 0x00 +#define FAR_LPTA 0x01 +#define FAR_LPTC 0x02 + +/* Power and Test Register (PTR) bits */ +#define PTR_LPTB_IRQ7 0x08 +#define PTR_LEVEL_IRQ 0x80 /* When not ECP/EPP: Use level IRQ */ +#define PTR_LPT_REG_DIR 0x80 /* When ECP/EPP: LPT CTR controlls direction */ + /* of the parallel port */ + +/* Function Control Register (FCR) bits */ +#define FCR_LDE 0x10 /* Logical Drive Exchange */ +#define FCR_ZWS_ENA 0x20 /* Enable short host read/write in ECP/EPP */ + +/* Printer Control Register (PCR) bits */ +#define PCR_EPP_ENABLE 0x01 +#define PCR_EPP_IEEE 0x02 /* Enable EPP Version 1.9 (IEEE 1284) */ +#define PCR_ECP_ENABLE 0x04 +#define PCR_ECP_CLK_ENA 0x08 /* If 0 ECP Clock is stopped on Power down */ +#define PCR_IRQ_POLAR 0x20 /* If 0 IRQ is level high or negative pulse, */ + /* if 1 polarity is inverted */ +#define PCR_IRQ_ODRAIN 0x40 /* If 1, IRQ is open drain */ + +/* Tape UARTs and Parallel Port Config Register (TUP) bits */ +#define TUP_EPP_TIMO 0x02 /* Enable EPP timeout IRQ */ + +/* Advanced SuperIO Config Register (ASC) bits */ +#define ASC_LPT_IRQ7 0x01 /* Always use IRQ7 for LPT */ +#define ASC_DRV2_SEL 0x02 /* Logical Drive Exchange controlled by TDR */ + +#define FER_RESERVED 0x00 +#define FAR_RESERVED 0x00 +#define PTR_RESERVED 0x73 +#define FCR_RESERVED 0xc4 +#define PCR_RESERVED 0x10 +#define KRR_RESERVED 0x00 +#define PMC_RESERVED 0x98 +#define TUP_RESERVED 0xfb +#define SIP_RESERVED 0x00 +#define ASC_RESERVED 0x18 +#define CS0CF0_RESERVED 0x00 +#define CS0CF1_RESERVED 0x08 +#define CS1CF0_RESERVED 0x00 +#define CS1CF1_RESERVED 0x08 + +#ifdef __KERNEL__ + +#include <linux/spinlock.h> + +#include <asm/system.h> +#include <asm/io.h> + +extern spinlock_t ns87303_lock; + +static __inline__ int ns87303_modify(unsigned long port, unsigned int index, + unsigned char clr, unsigned char set) +{ + static unsigned char reserved[] = { + FER_RESERVED, FAR_RESERVED, PTR_RESERVED, FCR_RESERVED, + PCR_RESERVED, KRR_RESERVED, PMC_RESERVED, TUP_RESERVED, + SIP_RESERVED, ASC_RESERVED, CS0CF0_RESERVED, CS0CF1_RESERVED, + CS1CF0_RESERVED, CS1CF1_RESERVED + }; + unsigned long flags; + unsigned char value; + + if (index > 0x0d) + return -EINVAL; + + spin_lock_irqsave(&ns87303_lock, flags); + + outb(index, port); + value = inb(port + 1); + value &= ~(reserved[index] | clr); + value |= set; + outb(value, port + 1); + outb(value, port + 1); + + spin_unlock_irqrestore(&ns87303_lock, flags); + + return 0; +} + +#endif /* __KERNEL__ */ + +#endif /* !(_SPARC_NS87303_H) */ diff --git a/include/asm-sparc64/openprom.h b/include/asm-sparc64/openprom.h new file mode 100644 index 000000000000..0a336901d585 --- /dev/null +++ b/include/asm-sparc64/openprom.h @@ -0,0 +1,281 @@ +/* $Id: openprom.h,v 1.9 2001/03/16 10:22:02 davem Exp $ */ +#ifndef __SPARC64_OPENPROM_H +#define __SPARC64_OPENPROM_H + +/* openprom.h: Prom structures and defines for access to the OPENBOOT + * prom routines and data areas. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef __ASSEMBLY__ +/* V0 prom device operations. */ +struct linux_dev_v0_funcs { + int (*v0_devopen)(char *device_str); + int (*v0_devclose)(int dev_desc); + int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf); + int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf); + int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf); + int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf); + int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf); + int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf); + int (*v0_seekdev)(int dev_desc, long logical_offst, int from); +}; + +/* V2 and later prom device operations. */ +struct linux_dev_v2_funcs { + int (*v2_inst2pkg)(int d); /* Convert ihandle to phandle */ + char * (*v2_dumb_mem_alloc)(char *va, unsigned sz); + void (*v2_dumb_mem_free)(char *va, unsigned sz); + + /* To map devices into virtual I/O space. */ + char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz); + void (*v2_dumb_munmap)(char *virta, unsigned size); + + int (*v2_dev_open)(char *devpath); + void (*v2_dev_close)(int d); + int (*v2_dev_read)(int d, char *buf, int nbytes); + int (*v2_dev_write)(int d, char *buf, int nbytes); + int (*v2_dev_seek)(int d, int hi, int lo); + + /* Never issued (multistage load support) */ + void (*v2_wheee2)(void); + void (*v2_wheee3)(void); +}; + +struct linux_mlist_v0 { + struct linux_mlist_v0 *theres_more; + unsigned start_adr; + unsigned num_bytes; +}; + +struct linux_mem_v0 { + struct linux_mlist_v0 **v0_totphys; + struct linux_mlist_v0 **v0_prommap; + struct linux_mlist_v0 **v0_available; /* What we can use */ +}; + +/* Arguments sent to the kernel from the boot prompt. */ +struct linux_arguments_v0 { + char *argv[8]; + char args[100]; + char boot_dev[2]; + int boot_dev_ctrl; + int boot_dev_unit; + int dev_partition; + char *kernel_file_name; + void *aieee1; /* XXX */ +}; + +/* V2 and up boot things. */ +struct linux_bootargs_v2 { + char **bootpath; + char **bootargs; + int *fd_stdin; + int *fd_stdout; +}; + +/* The top level PROM vector. */ +struct linux_romvec { + /* Version numbers. */ + unsigned int pv_magic_cookie; + unsigned int pv_romvers; + unsigned int pv_plugin_revision; + unsigned int pv_printrev; + + /* Version 0 memory descriptors. */ + struct linux_mem_v0 pv_v0mem; + + /* Node operations. */ + struct linux_nodeops *pv_nodeops; + + char **pv_bootstr; + struct linux_dev_v0_funcs pv_v0devops; + + char *pv_stdin; + char *pv_stdout; +#define PROMDEV_KBD 0 /* input from keyboard */ +#define PROMDEV_SCREEN 0 /* output to screen */ +#define PROMDEV_TTYA 1 /* in/out to ttya */ +#define PROMDEV_TTYB 2 /* in/out to ttyb */ + + /* Blocking getchar/putchar. NOT REENTRANT! (grr) */ + int (*pv_getchar)(void); + void (*pv_putchar)(int ch); + + /* Non-blocking variants. */ + int (*pv_nbgetchar)(void); + int (*pv_nbputchar)(int ch); + + void (*pv_putstr)(char *str, int len); + + /* Miscellany. */ + void (*pv_reboot)(char *bootstr); + void (*pv_printf)(__const__ char *fmt, ...); + void (*pv_abort)(void); + __volatile__ int *pv_ticks; + void (*pv_halt)(void); + void (**pv_synchook)(void); + + /* Evaluate a forth string, not different proto for V0 and V2->up. */ + union { + void (*v0_eval)(int len, char *str); + void (*v2_eval)(char *str); + } pv_fortheval; + + struct linux_arguments_v0 **pv_v0bootargs; + + /* Get ether address. */ + unsigned int (*pv_enaddr)(int d, char *enaddr); + + struct linux_bootargs_v2 pv_v2bootargs; + struct linux_dev_v2_funcs pv_v2devops; + + int filler[15]; + + /* This one is sun4c/sun4 only. */ + void (*pv_setctxt)(int ctxt, char *va, int pmeg); + + /* Prom version 3 Multiprocessor routines. This stuff is crazy. + * No joke. Calling these when there is only one cpu probably + * crashes the machine, have to test this. :-) + */ + + /* v3_cpustart() will start the cpu 'whichcpu' in mmu-context + * 'thiscontext' executing at address 'prog_counter' + */ + int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr, + int thiscontext, char *prog_counter); + + /* v3_cpustop() will cause cpu 'whichcpu' to stop executing + * until a resume cpu call is made. + */ + int (*v3_cpustop)(unsigned int whichcpu); + + /* v3_cpuidle() will idle cpu 'whichcpu' until a stop or + * resume cpu call is made. + */ + int (*v3_cpuidle)(unsigned int whichcpu); + + /* v3_cpuresume() will resume processor 'whichcpu' executing + * starting with whatever 'pc' and 'npc' were left at the + * last 'idle' or 'stop' call. + */ + int (*v3_cpuresume)(unsigned int whichcpu); +}; + +/* Routines for traversing the prom device tree. */ +struct linux_nodeops { + int (*no_nextnode)(int node); + int (*no_child)(int node); + int (*no_proplen)(int node, char *name); + int (*no_getprop)(int node, char *name, char *val); + int (*no_setprop)(int node, char *name, char *val, int len); + char * (*no_nextprop)(int node, char *name); +}; + +/* More fun PROM structures for device probing. */ +#define PROMREG_MAX 16 +#define PROMVADDR_MAX 16 +#define PROMINTR_MAX 15 + +struct linux_prom_registers { + unsigned which_io; /* hi part of physical address */ + unsigned phys_addr; /* The physical address of this register */ + int reg_size; /* How many bytes does this register take up? */ +}; + +struct linux_prom64_registers { + long phys_addr; + long reg_size; +}; + +struct linux_prom_irqs { + int pri; /* IRQ priority */ + int vector; /* This is foobar, what does it do? */ +}; + +/* Element of the "ranges" vector */ +struct linux_prom_ranges { + unsigned int ot_child_space; + unsigned int ot_child_base; /* Bus feels this */ + unsigned int ot_parent_space; + unsigned int ot_parent_base; /* CPU looks from here */ + unsigned int or_size; +}; + +struct linux_prom64_ranges { + unsigned long ot_child_base; /* Bus feels this */ + unsigned long ot_parent_base; /* CPU looks from here */ + unsigned long or_size; +}; + +/* Ranges and reg properties are a bit different for PCI. */ +struct linux_prom_pci_registers { + unsigned int phys_hi; + unsigned int phys_mid; + unsigned int phys_lo; + + unsigned int size_hi; + unsigned int size_lo; +}; + +struct linux_prom_pci_ranges { + unsigned int child_phys_hi; /* Only certain bits are encoded here. */ + unsigned int child_phys_mid; + unsigned int child_phys_lo; + + unsigned int parent_phys_hi; + unsigned int parent_phys_lo; + + unsigned int size_hi; + unsigned int size_lo; +}; + +struct linux_prom_pci_intmap { + unsigned int phys_hi; + unsigned int phys_mid; + unsigned int phys_lo; + + unsigned int interrupt; + + int cnode; + unsigned int cinterrupt; +}; + +struct linux_prom_pci_intmask { + unsigned int phys_hi; + unsigned int phys_mid; + unsigned int phys_lo; + unsigned int interrupt; +}; + +struct linux_prom_ebus_ranges { + unsigned int child_phys_hi; + unsigned int child_phys_lo; + + unsigned int parent_phys_hi; + unsigned int parent_phys_mid; + unsigned int parent_phys_lo; + + unsigned int size; +}; + +struct linux_prom_ebus_intmap { + unsigned int phys_hi; + unsigned int phys_lo; + + unsigned int interrupt; + + int cnode; + unsigned int cinterrupt; +}; + +struct linux_prom_ebus_intmask { + unsigned int phys_hi; + unsigned int phys_lo; + unsigned int interrupt; +}; +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(__SPARC64_OPENPROM_H) */ diff --git a/include/asm-sparc64/openpromio.h b/include/asm-sparc64/openpromio.h new file mode 100644 index 000000000000..847ce2326ad5 --- /dev/null +++ b/include/asm-sparc64/openpromio.h @@ -0,0 +1,69 @@ +#ifndef _SPARC64_OPENPROMIO_H +#define _SPARC64_OPENPROMIO_H + +#include <linux/compiler.h> +#include <linux/ioctl.h> +#include <linux/types.h> + +/* + * SunOS and Solaris /dev/openprom definitions. The ioctl values + * were chosen to be exactly equal to the SunOS equivalents. + */ + +struct openpromio +{ + u_int oprom_size; /* Actual size of the oprom_array. */ + char oprom_array[1]; /* Holds property names and values. */ +}; + +#define OPROMMAXPARAM 4096 /* Maximum size of oprom_array. */ + +#define OPROMGETOPT 0x20004F01 +#define OPROMSETOPT 0x20004F02 +#define OPROMNXTOPT 0x20004F03 +#define OPROMSETOPT2 0x20004F04 +#define OPROMNEXT 0x20004F05 +#define OPROMCHILD 0x20004F06 +#define OPROMGETPROP 0x20004F07 +#define OPROMNXTPROP 0x20004F08 +#define OPROMU2P 0x20004F09 +#define OPROMGETCONS 0x20004F0A +#define OPROMGETFBNAME 0x20004F0B +#define OPROMGETBOOTARGS 0x20004F0C +/* Linux extensions */ /* Arguments in oprom_array: */ +#define OPROMSETCUR 0x20004FF0 /* int node - Sets current node */ +#define OPROMPCI2NODE 0x20004FF1 /* int pci_bus, pci_devfn - Sets current node to PCI device's node */ +#define OPROMPATH2NODE 0x20004FF2 /* char path[] - Set current node from fully qualified PROM path */ + +/* + * Return values from OPROMGETCONS: + */ + +#define OPROMCONS_NOT_WSCONS 0 +#define OPROMCONS_STDIN_IS_KBD 0x1 /* stdin device is kbd */ +#define OPROMCONS_STDOUT_IS_FB 0x2 /* stdout is a framebuffer */ +#define OPROMCONS_OPENPROM 0x4 /* supports openboot */ + + +/* + * NetBSD/OpenBSD /dev/openprom definitions. + */ + +struct opiocdesc +{ + int op_nodeid; /* PROM Node ID (value-result) */ + int op_namelen; /* Length of op_name. */ + char __user *op_name; /* Pointer to the property name. */ + int op_buflen; /* Length of op_buf (value-result) */ + char __user *op_buf; /* Pointer to buffer. */ +}; + +#define OPIOCGET _IOWR('O', 1, struct opiocdesc) +#define OPIOCSET _IOW('O', 2, struct opiocdesc) +#define OPIOCNEXTPROP _IOWR('O', 3, struct opiocdesc) +#define OPIOCGETOPTNODE _IOR('O', 4, int) +#define OPIOCGETNEXT _IOWR('O', 5, int) +#define OPIOCGETCHILD _IOWR('O', 6, int) + +#endif /* _SPARC64_OPENPROMIO_H */ + diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h new file mode 100644 index 000000000000..a432d9e7daaa --- /dev/null +++ b/include/asm-sparc64/oplib.h @@ -0,0 +1,360 @@ +/* $Id: oplib.h,v 1.14 2001/12/19 00:29:51 davem Exp $ + * oplib.h: Describes the interface and available routines in the + * Linux Prom library. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +#ifndef __SPARC64_OPLIB_H +#define __SPARC64_OPLIB_H + +#include <linux/config.h> +#include <asm/openprom.h> + +/* Enumeration to describe the prom major version we have detected. */ +enum prom_major_version { + PROM_V0, /* Original sun4c V0 prom */ + PROM_V2, /* sun4c and early sun4m V2 prom */ + PROM_V3, /* sun4m and later, up to sun4d/sun4e machines V3 */ + PROM_P1275, /* IEEE compliant ISA based Sun PROM, only sun4u */ + PROM_AP1000, /* actually no prom at all */ +}; + +extern enum prom_major_version prom_vers; +/* Revision, and firmware revision. */ +extern unsigned int prom_rev, prom_prev; + +/* Root node of the prom device tree, this stays constant after + * initialization is complete. + */ +extern int prom_root_node; + +/* PROM stdin and stdout */ +extern int prom_stdin, prom_stdout; + +/* /chosen node of the prom device tree, this stays constant after + * initialization is complete. + */ +extern int prom_chosen_node; + +struct linux_mlist_p1275 { + struct linux_mlist_p1275 *theres_more; + unsigned long start_adr; + unsigned long num_bytes; +}; + +struct linux_mem_p1275 { + struct linux_mlist_p1275 **p1275_totphys; + struct linux_mlist_p1275 **p1275_prommap; + struct linux_mlist_p1275 **p1275_available; /* What we can use */ +}; + +/* The functions... */ + +/* You must call prom_init() before using any of the library services, + * preferably as early as possible. Pass it the romvec pointer. + */ +extern void prom_init(void *cif_handler, void *cif_stack); + +/* Boot argument acquisition, returns the boot command line string. */ +extern char *prom_getbootargs(void); + +/* Device utilities. */ + +/* Device operations. */ + +/* Open the device described by the passed string. Note, that the format + * of the string is different on V0 vs. V2->higher proms. The caller must + * know what he/she is doing! Returns the device descriptor, an int. + */ +extern int prom_devopen(char *device_string); + +/* Close a previously opened device described by the passed integer + * descriptor. + */ +extern int prom_devclose(int device_handle); + +/* Do a seek operation on the device described by the passed integer + * descriptor. + */ +extern void prom_seek(int device_handle, unsigned int seek_hival, + unsigned int seek_lowval); + +/* Machine memory configuration routine. */ + +/* This function returns a V0 format memory descriptor table, it has three + * entries. One for the total amount of physical ram on the machine, one + * for the amount of physical ram available, and one describing the virtual + * areas which are allocated by the prom. So, in a sense the physical + * available is a calculation of the total physical minus the physical mapped + * by the prom with virtual mappings. + * + * These lists are returned pre-sorted, this should make your life easier + * since the prom itself is way too lazy to do such nice things. + */ +extern struct linux_mem_p1275 *prom_meminfo(void); + +/* Miscellaneous routines, don't really fit in any category per se. */ + +/* Reboot the machine with the command line passed. */ +extern void prom_reboot(char *boot_command); + +/* Evaluate the forth string passed. */ +extern void prom_feval(char *forth_string); + +/* Enter the prom, with possibility of continuation with the 'go' + * command in newer proms. + */ +extern void prom_cmdline(void); + +/* Enter the prom, with no chance of continuation for the stand-alone + * which calls this. + */ +extern void prom_halt(void) __attribute__ ((noreturn)); + +/* Halt and power-off the machine. */ +extern void prom_halt_power_off(void) __attribute__ ((noreturn)); + +/* Set the PROM 'sync' callback function to the passed function pointer. + * When the user gives the 'sync' command at the prom prompt while the + * kernel is still active, the prom will call this routine. + * + */ +typedef int (*callback_func_t)(long *cmd); +extern void prom_setcallback(callback_func_t func_ptr); + +/* Acquire the IDPROM of the root node in the prom device tree. This + * gets passed a buffer where you would like it stuffed. The return value + * is the format type of this idprom or 0xff on error. + */ +extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); + +/* Get the prom major version. */ +extern int prom_version(void); + +/* Get the prom plugin revision. */ +extern int prom_getrev(void); + +/* Get the prom firmware revision. */ +extern int prom_getprev(void); + +/* Character operations to/from the console.... */ + +/* Non-blocking get character from console. */ +extern int prom_nbgetchar(void); + +/* Non-blocking put character to console. */ +extern int prom_nbputchar(char character); + +/* Blocking get character from console. */ +extern char prom_getchar(void); + +/* Blocking put character to console. */ +extern void prom_putchar(char character); + +/* Prom's internal routines, don't use in kernel/boot code. */ +extern void prom_printf(char *fmt, ...); +extern void prom_write(const char *buf, unsigned int len); + +/* Query for input device type */ + +enum prom_input_device { + PROMDEV_IKBD, /* input from keyboard */ + PROMDEV_ITTYA, /* input from ttya */ + PROMDEV_ITTYB, /* input from ttyb */ + PROMDEV_I_UNK, +}; + +extern enum prom_input_device prom_query_input_device(void); + +/* Query for output device type */ + +enum prom_output_device { + PROMDEV_OSCREEN, /* to screen */ + PROMDEV_OTTYA, /* to ttya */ + PROMDEV_OTTYB, /* to ttyb */ + PROMDEV_O_UNK, +}; + +extern enum prom_output_device prom_query_output_device(void); + +/* Multiprocessor operations... */ +#ifdef CONFIG_SMP +/* Start the CPU with the given device tree node, context table, and context + * at the passed program counter. + */ +extern void prom_startcpu(int cpunode, unsigned long pc, unsigned long o0); + +/* Stop the current CPU. */ +extern void prom_stopself(void); + +/* Idle the current CPU. */ +extern void prom_idleself(void); + +/* Resume the CPU with the passed device tree node. */ +extern void prom_resumecpu(int cpunode); +#endif + +/* Power management interfaces. */ + +/* Put the current CPU to sleep. */ +extern void prom_sleepself(void); + +/* Put the entire system to sleep. */ +extern int prom_sleepsystem(void); + +/* Initiate a wakeup event. */ +extern int prom_wakeupsystem(void); + +/* MMU and memory related OBP interfaces. */ + +/* Get unique string identifying SIMM at given physical address. */ +extern int prom_getunumber(int syndrome_code, + unsigned long phys_addr, + char *buf, int buflen); + +/* Retain physical memory to the caller across soft resets. */ +extern unsigned long prom_retain(char *name, + unsigned long pa_low, unsigned long pa_high, + long size, long align); + +/* Load explicit I/D TLB entries into the calling processor. */ +extern long prom_itlb_load(unsigned long index, + unsigned long tte_data, + unsigned long vaddr); + +extern long prom_dtlb_load(unsigned long index, + unsigned long tte_data, + unsigned long vaddr); + +/* Map/Unmap client program address ranges. First the format of + * the mapping mode argument. + */ +#define PROM_MAP_WRITE 0x0001 /* Writable */ +#define PROM_MAP_READ 0x0002 /* Readable - sw */ +#define PROM_MAP_EXEC 0x0004 /* Executable - sw */ +#define PROM_MAP_LOCKED 0x0010 /* Locked, use i/dtlb load calls for this instead */ +#define PROM_MAP_CACHED 0x0020 /* Cacheable in both L1 and L2 caches */ +#define PROM_MAP_SE 0x0040 /* Side-Effects */ +#define PROM_MAP_GLOB 0x0080 /* Global */ +#define PROM_MAP_IE 0x0100 /* Invert-Endianness */ +#define PROM_MAP_DEFAULT (PROM_MAP_WRITE | PROM_MAP_READ | PROM_MAP_EXEC | PROM_MAP_CACHED) + +extern int prom_map(int mode, unsigned long size, + unsigned long vaddr, unsigned long paddr); +extern void prom_unmap(unsigned long size, unsigned long vaddr); + + +/* PROM device tree traversal functions... */ + +#ifdef PROMLIB_INTERNAL + +/* Internal version of prom_getchild. */ +extern int __prom_getchild(int parent_node); + +/* Internal version of prom_getsibling. */ +extern int __prom_getsibling(int node); + +#endif + +/* Get the child node of the given node, or zero if no child exists. */ +extern int prom_getchild(int parent_node); + +/* Get the next sibling node of the given node, or zero if no further + * siblings exist. + */ +extern int prom_getsibling(int node); + +/* Get the length, at the passed node, of the given property type. + * Returns -1 on error (ie. no such property at this node). + */ +extern int prom_getproplen(int thisnode, char *property); + +/* Fetch the requested property using the given buffer. Returns + * the number of bytes the prom put into your buffer or -1 on error. + */ +extern int prom_getproperty(int thisnode, char *property, + char *prop_buffer, int propbuf_size); + +/* Acquire an integer property. */ +extern int prom_getint(int node, char *property); + +/* Acquire an integer property, with a default value. */ +extern int prom_getintdefault(int node, char *property, int defval); + +/* Acquire a boolean property, 0=FALSE 1=TRUE. */ +extern int prom_getbool(int node, char *prop); + +/* Acquire a string property, null string on error. */ +extern void prom_getstring(int node, char *prop, char *buf, int bufsize); + +/* Does the passed node have the given "name"? YES=1 NO=0 */ +extern int prom_nodematch(int thisnode, char *name); + +/* Puts in buffer a prom name in the form name@x,y or name (x for which_io + * and y for first regs phys address + */ +extern int prom_getname(int node, char *buf, int buflen); + +/* Search all siblings starting at the passed node for "name" matching + * the given string. Returns the node on success, zero on failure. + */ +extern int prom_searchsiblings(int node_start, char *name); + +/* Return the first property type, as a string, for the given node. + * Returns a null string on error. Buffer should be at least 32B long. + */ +extern char *prom_firstprop(int node, char *buffer); + +/* Returns the next property after the passed property for the given + * node. Returns null string on failure. Buffer should be at least 32B long. + */ +extern char *prom_nextprop(int node, char *prev_property, char *buffer); + +/* Returns 1 if the specified node has given property. */ +extern int prom_node_has_property(int node, char *property); + +/* Returns phandle of the path specified */ +extern int prom_finddevice(char *name); + +/* Set the indicated property at the given node with the passed value. + * Returns the number of bytes of your value that the prom took. + */ +extern int prom_setprop(int node, char *prop_name, char *prop_value, + int value_size); + +extern int prom_pathtoinode(char *path); +extern int prom_inst2pkg(int); + +/* CPU probing helpers. */ +int cpu_find_by_instance(int instance, int *prom_node, int *mid); +int cpu_find_by_mid(int mid, int *prom_node); + +/* Client interface level routines. */ +extern void prom_set_trap_table(unsigned long tba); + +extern long p1275_cmd (char *, long, ...); + + +#if 0 +#define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x)) +#else +#define P1275_SIZE(x) x +#endif + +/* We support at most 16 input and 1 output argument */ +#define P1275_ARG_NUMBER 0 +#define P1275_ARG_IN_STRING 1 +#define P1275_ARG_OUT_BUF 2 +#define P1275_ARG_OUT_32B 3 +#define P1275_ARG_IN_FUNCTION 4 +#define P1275_ARG_IN_BUF 5 +#define P1275_ARG_IN_64B 6 + +#define P1275_IN(x) ((x) & 0xf) +#define P1275_OUT(x) (((x) << 4) & 0xf0) +#define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o)) +#define P1275_ARG(n,x) ((x) << ((n)*3 + 8)) + +#endif /* !(__SPARC64_OPLIB_H) */ diff --git a/include/asm-sparc64/page.h b/include/asm-sparc64/page.h new file mode 100644 index 000000000000..219ea043a14a --- /dev/null +++ b/include/asm-sparc64/page.h @@ -0,0 +1,172 @@ +/* $Id: page.h,v 1.39 2002/02/09 19:49:31 davem Exp $ */ + +#ifndef _SPARC64_PAGE_H +#define _SPARC64_PAGE_H + +#include <linux/config.h> +#include <asm/const.h> + +#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB) +#define PAGE_SHIFT 13 +#elif defined(CONFIG_SPARC64_PAGE_SIZE_64KB) +#define PAGE_SHIFT 16 +#elif defined(CONFIG_SPARC64_PAGE_SIZE_512KB) +#define PAGE_SHIFT 19 +#elif defined(CONFIG_SPARC64_PAGE_SIZE_4MB) +#define PAGE_SHIFT 22 +#else +#error No page size specified in kernel configuration +#endif + +#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ + +extern void _clear_page(void *page); +#define clear_page(X) _clear_page((void *)(X)) +struct page; +extern void clear_user_page(void *addr, unsigned long vaddr, struct page *page); +#define copy_page(X,Y) memcpy((void *)(X), (void *)(Y), PAGE_SIZE) +extern void copy_user_page(void *to, void *from, unsigned long vaddr, struct page *topage); + +/* Unlike sparc32, sparc64's parameter passing API is more + * sane in that structures which as small enough are passed + * in registers instead of on the stack. Thus, setting + * STRICT_MM_TYPECHECKS does not generate worse code so + * let's enable it to get the type checking. + */ + +#define STRICT_MM_TYPECHECKS + +#ifdef STRICT_MM_TYPECHECKS +/* These are used to make use of C type-checking.. */ +typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long iopte; } iopte_t; +typedef struct { unsigned int pmd; } pmd_t; +typedef struct { unsigned int pgd; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; + +#define pte_val(x) ((x).pte) +#define iopte_val(x) ((x).iopte) +#define pmd_val(x) ((x).pmd) +#define pgd_val(x) ((x).pgd) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) } ) +#define __iopte(x) ((iopte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgd(x) ((pgd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +#else +/* .. while these make it easier on the compiler */ +typedef unsigned long pte_t; +typedef unsigned long iopte_t; +typedef unsigned int pmd_t; +typedef unsigned int pgd_t; +typedef unsigned long pgprot_t; + +#define pte_val(x) (x) +#define iopte_val(x) (x) +#define pmd_val(x) (x) +#define pgd_val(x) (x) +#define pgprot_val(x) (x) + +#define __pte(x) (x) +#define __iopte(x) (x) +#define __pmd(x) (x) +#define __pgd(x) (x) +#define __pgprot(x) (x) + +#endif /* (STRICT_MM_TYPECHECKS) */ + +#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB) +#define HPAGE_SHIFT 22 +#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K) +#define HPAGE_SHIFT 19 +#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K) +#define HPAGE_SHIFT 16 +#endif + +#ifdef CONFIG_HUGETLB_PAGE +#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT) +#define HPAGE_MASK (~(HPAGE_SIZE - 1UL)) +#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) +#endif + +#define TASK_UNMAPPED_BASE (test_thread_flag(TIF_32BIT) ? \ + (_AC(0x0000000070000000,UL)) : (PAGE_OFFSET)) + +#endif /* !(__ASSEMBLY__) */ + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +/* We used to stick this into a hard-coded global register (%g4) + * but that does not make sense anymore. + */ +#define PAGE_OFFSET _AC(0xFFFFF80000000000,UL) + +#ifndef __ASSEMBLY__ + +#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET) +#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) + +/* PFNs are real physical page numbers. However, mem_map only begins to record + * per-page information starting at pfn_base. This is to handle systems where + * the first physical page in the machine is at some huge physical address, + * such as 4GB. This is common on a partitioned E10000, for example. + */ +extern struct page *pfn_to_page(unsigned long pfn); +extern unsigned long page_to_pfn(struct page *); + +#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr)>>PAGE_SHIFT) + +#define pfn_valid(pfn) (((pfn)-(pfn_base)) < max_mapnr) +#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) + +#define virt_to_phys __pa +#define phys_to_virt __va + +/* The following structure is used to hold the physical + * memory configuration of the machine. This is filled in + * probe_memory() and is later used by mem_init() to set up + * mem_map[]. We statically allocate SPARC_PHYS_BANKS of + * these structs, this is arbitrary. The entry after the + * last valid one has num_bytes==0. + */ + +struct sparc_phys_banks { + unsigned long base_addr; + unsigned long num_bytes; +}; + +#define SPARC_PHYS_BANKS 32 + +extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS]; + +/* Pure 2^n version of get_order */ +static __inline__ int get_order(unsigned long size) +{ + int order; + + size = (size-1) >> (PAGE_SHIFT-1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} + +#endif /* !(__ASSEMBLY__) */ + +#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#endif /* !(__KERNEL__) */ + +#endif /* !(_SPARC64_PAGE_H) */ diff --git a/include/asm-sparc64/param.h b/include/asm-sparc64/param.h new file mode 100644 index 000000000000..6a12f3ac0359 --- /dev/null +++ b/include/asm-sparc64/param.h @@ -0,0 +1,23 @@ +/* $Id: param.h,v 1.2 2000/10/30 21:01:41 davem Exp $ */ +#ifndef _ASMSPARC64_PARAM_H +#define _ASMSPARC64_PARAM_H + +#ifdef __KERNEL__ +# define HZ 1000 /* Internal kernel timer frequency */ +# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ +# define CLOCKS_PER_SEC (USER_HZ) +#endif + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 8192 /* Thanks for sun4's we carry baggage... */ + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif /* _ASMSPARC64_PARAM_H */ diff --git a/include/asm-sparc64/parport.h b/include/asm-sparc64/parport.h new file mode 100644 index 000000000000..ab88349ddadc --- /dev/null +++ b/include/asm-sparc64/parport.h @@ -0,0 +1,175 @@ +/* $Id: parport.h,v 1.11 2001/05/11 07:54:24 davem Exp $ + * parport.h: sparc64 specific parport initialization and dma. + * + * Copyright (C) 1999 Eddie C. Dost (ecd@skynet.be) + */ + +#ifndef _ASM_SPARC64_PARPORT_H +#define _ASM_SPARC64_PARPORT_H 1 + +#include <asm/ebus.h> +#include <asm/isa.h> +#include <asm/ns87303.h> + +#define PARPORT_PC_MAX_PORTS PARPORT_MAX + +static struct sparc_ebus_info { + struct ebus_dma_info info; + unsigned int addr; + unsigned int count; +} sparc_ebus_dmas[PARPORT_PC_MAX_PORTS]; + +static __inline__ void enable_dma(unsigned int dmanr) +{ + if (ebus_dma_request(&sparc_ebus_dmas[dmanr].info, + sparc_ebus_dmas[dmanr].addr, + sparc_ebus_dmas[dmanr].count)) + BUG(); + + ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1); +} + +static __inline__ void disable_dma(unsigned int dmanr) +{ + ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 0); +} + +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ + /* nothing */ +} + +static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +{ + ebus_dma_prepare(&sparc_ebus_dmas[dmanr].info, (mode != DMA_MODE_WRITE)); +} + +static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int addr) +{ + sparc_ebus_dmas[dmanr].addr = addr; +} + +static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +{ + sparc_ebus_dmas[dmanr].count = count; +} + +static __inline__ unsigned int get_dma_residue(unsigned int dmanr) +{ + return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info); +} + +static int ebus_ecpp_p(struct linux_ebus_device *edev) +{ + if (!strcmp(edev->prom_name, "ecpp")) + return 1; + if (!strcmp(edev->prom_name, "parallel")) { + char compat[19]; + prom_getstring(edev->prom_node, + "compatible", + compat, sizeof(compat)); + compat[18] = '\0'; + if (!strcmp(compat, "ecpp")) + return 1; + if (!strcmp(compat, "ns87317-ecpp") && + !strcmp(compat + 13, "ecpp")) + return 1; + } + return 0; +} + +static int parport_isa_probe(int count) +{ + struct sparc_isa_bridge *isa_br; + struct sparc_isa_device *isa_dev; + + for_each_isa(isa_br) { + for_each_isadev(isa_dev, isa_br) { + struct sparc_isa_device *child; + unsigned long base; + + if (strcmp(isa_dev->prom_name, "dma")) + continue; + + child = isa_dev->child; + while (child) { + if (!strcmp(child->prom_name, "parallel")) + break; + child = child->next; + } + if (!child) + continue; + + base = child->resource.start; + + /* No DMA, see commentary in + * asm-sparc64/floppy.h:isa_floppy_init() + */ + if (parport_pc_probe_port(base, base + 0x400, + child->irq, PARPORT_DMA_NOFIFO, + child->bus->self)) + count++; + } + } + + return count; +} + +static int parport_pc_find_nonpci_ports (int autoirq, int autodma) +{ + struct linux_ebus *ebus; + struct linux_ebus_device *edev; + int count = 0; + + for_each_ebus(ebus) { + for_each_ebusdev(edev, ebus) { + if (ebus_ecpp_p(edev)) { + unsigned long base = edev->resource[0].start; + unsigned long config = edev->resource[1].start; + unsigned long d_base = edev->resource[2].start; + unsigned long d_len; + + spin_lock_init(&sparc_ebus_dmas[count].info.lock); + d_len = (edev->resource[2].end - + d_base) + 1; + sparc_ebus_dmas[count].info.regs = + ioremap(d_base, d_len); + if (!sparc_ebus_dmas[count].info.regs) + continue; + sparc_ebus_dmas[count].info.flags = 0; + sparc_ebus_dmas[count].info.callback = NULL; + sparc_ebus_dmas[count].info.client_cookie = NULL; + sparc_ebus_dmas[count].info.irq = 0xdeadbeef; + strcpy(sparc_ebus_dmas[count].info.name, "parport"); + if (ebus_dma_register(&sparc_ebus_dmas[count].info)) + continue; + ebus_dma_irq_enable(&sparc_ebus_dmas[count].info, 1); + + /* Configure IRQ to Push Pull, Level Low */ + /* Enable ECP, set bit 2 of the CTR first */ + outb(0x04, base + 0x02); + ns87303_modify(config, PCR, + PCR_EPP_ENABLE | + PCR_IRQ_ODRAIN, + PCR_ECP_ENABLE | + PCR_ECP_CLK_ENA | + PCR_IRQ_POLAR); + + /* CTR bit 5 controls direction of port */ + ns87303_modify(config, PTR, + 0, PTR_LPT_REG_DIR); + + if (parport_pc_probe_port(base, base + 0x400, + edev->irqs[0], + count, ebus->self)) + count++; + } + } + } + + count = parport_isa_probe(count); + + return count; +} + +#endif /* !(_ASM_SPARC64_PARPORT_H */ diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h new file mode 100644 index 000000000000..92999631c819 --- /dev/null +++ b/include/asm-sparc64/pbm.h @@ -0,0 +1,248 @@ +/* $Id: pbm.h,v 1.27 2001/08/12 13:18:23 davem Exp $ + * pbm.h: UltraSparc PCI controller software state. + * + * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) + */ + +#ifndef __SPARC64_PBM_H +#define __SPARC64_PBM_H + +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/ioport.h> +#include <linux/spinlock.h> + +#include <asm/io.h> +#include <asm/page.h> +#include <asm/oplib.h> + +/* The abstraction used here is that there are PCI controllers, + * each with one (Sabre) or two (PSYCHO/SCHIZO) PCI bus modules + * underneath. Each PCI bus module uses an IOMMU (shared by both + * PBMs of a controller, or per-PBM), and if a streaming buffer + * is present, each PCI bus module has it's own. (ie. the IOMMU + * might be shared between PBMs, the STC is never shared) + * Furthermore, each PCI bus module controls it's own autonomous + * PCI bus. + */ + +#define PBM_LOGCLUSTERS 3 +#define PBM_NCLUSTERS (1 << PBM_LOGCLUSTERS) + +struct pci_controller_info; + +/* This contains the software state necessary to drive a PCI + * controller's IOMMU. + */ +struct pci_iommu { + /* This protects the controller's IOMMU and all + * streaming buffers underneath. + */ + spinlock_t lock; + + /* Context allocator. */ + unsigned int iommu_cur_ctx; + + /* IOMMU page table, a linear array of ioptes. */ + iopte_t *page_table; /* The page table itself. */ + int page_table_sz_bits; /* log2 of ow many pages does it map? */ + + /* Base PCI memory space address where IOMMU mappings + * begin. + */ + u32 page_table_map_base; + + /* IOMMU Controller Registers */ + unsigned long iommu_control; /* IOMMU control register */ + unsigned long iommu_tsbbase; /* IOMMU page table base register */ + unsigned long iommu_flush; /* IOMMU page flush register */ + unsigned long iommu_ctxflush; /* IOMMU context flush register */ + + /* This is a register in the PCI controller, which if + * read will have no side-effects but will guarantee + * completion of all previous writes into IOMMU/STC. + */ + unsigned long write_complete_reg; + + /* The lowest used consistent mapping entry. Since + * we allocate consistent maps out of cluster 0 this + * is relative to the beginning of closter 0. + */ + u32 lowest_consistent_map; + + /* In order to deal with some buggy third-party PCI bridges that + * do wrong prefetching, we never mark valid mappings as invalid. + * Instead we point them at this dummy page. + */ + unsigned long dummy_page; + unsigned long dummy_page_pa; + + /* If PBM_NCLUSTERS is ever decreased to 4 or lower, + * or if largest supported page_table_sz * 8K goes above + * 2GB, you must increase the size of the type of + * these counters. You have been duly warned. -DaveM + */ + struct { + u16 next; + u16 flush; + } alloc_info[PBM_NCLUSTERS]; + + /* Here a PCI controller driver describes the areas of + * PCI memory space where DMA to/from physical memory + * are addressed. Drivers interrogate the PCI layer + * if their device has addressing limitations. They + * do so via pci_dma_supported, and pass in a mask of + * DMA address bits their device can actually drive. + * + * The test for being usable is: + * (device_mask & dma_addr_mask) == dma_addr_mask + */ + u32 dma_addr_mask; +}; + +extern void pci_iommu_table_init(struct pci_iommu *, int); + +/* This describes a PCI bus module's streaming buffer. */ +struct pci_strbuf { + int strbuf_enabled; /* Present and using it? */ + + /* Streaming Buffer Control Registers */ + unsigned long strbuf_control; /* STC control register */ + unsigned long strbuf_pflush; /* STC page flush register */ + unsigned long strbuf_fsync; /* STC flush synchronization reg */ + unsigned long strbuf_ctxflush; /* STC context flush register */ + unsigned long strbuf_ctxmatch_base; /* STC context flush match reg */ + unsigned long strbuf_flushflag_pa; /* Physical address of flush flag */ + volatile unsigned long *strbuf_flushflag; /* The flush flag itself */ + + /* And this is the actual flush flag area. + * We allocate extra because the chips require + * a 64-byte aligned area. + */ + volatile unsigned long __flushflag_buf[(64 + (64 - 1)) / sizeof(long)]; +}; + +#define PCI_STC_FLUSHFLAG_INIT(STC) \ + (*((STC)->strbuf_flushflag) = 0UL) +#define PCI_STC_FLUSHFLAG_SET(STC) \ + (*((STC)->strbuf_flushflag) != 0UL) + +/* There can be quite a few ranges and interrupt maps on a PCI + * segment. Thus... + */ +#define PROM_PCIRNG_MAX 64 +#define PROM_PCIIMAP_MAX 64 + +struct pci_pbm_info { + /* PCI controller we sit under. */ + struct pci_controller_info *parent; + + /* Physical address base of controller registers. */ + unsigned long controller_regs; + + /* Physical address base of PBM registers. */ + unsigned long pbm_regs; + + /* Opaque 32-bit system bus Port ID. */ + u32 portid; + + /* Chipset version information. */ + int chip_type; +#define PBM_CHIP_TYPE_SABRE 1 +#define PBM_CHIP_TYPE_PSYCHO 2 +#define PBM_CHIP_TYPE_SCHIZO 3 +#define PBM_CHIP_TYPE_SCHIZO_PLUS 4 +#define PBM_CHIP_TYPE_TOMATILLO 5 + int chip_version; + int chip_revision; + + /* Name used for top-level resources. */ + char name[64]; + + /* OBP specific information. */ + int prom_node; + char prom_name[64]; + struct linux_prom_pci_ranges pbm_ranges[PROM_PCIRNG_MAX]; + int num_pbm_ranges; + struct linux_prom_pci_intmap pbm_intmap[PROM_PCIIMAP_MAX]; + int num_pbm_intmap; + struct linux_prom_pci_intmask pbm_intmask; + u64 ino_bitmap; + + /* PBM I/O and Memory space resources. */ + struct resource io_space; + struct resource mem_space; + + /* Base of PCI Config space, can be per-PBM or shared. */ + unsigned long config_space; + + /* State of 66MHz capabilities on this PBM. */ + int is_66mhz_capable; + int all_devs_66mhz; + + /* This PBM's streaming buffer. */ + struct pci_strbuf stc; + + /* IOMMU state, potentially shared by both PBM segments. */ + struct pci_iommu *iommu; + + /* PCI slot mapping. */ + unsigned int pci_first_slot; + + /* Now things for the actual PCI bus probes. */ + unsigned int pci_first_busno; + unsigned int pci_last_busno; + struct pci_bus *pci_bus; +}; + +struct pci_controller_info { + /* List of all PCI controllers. */ + struct pci_controller_info *next; + + /* Each controller gets a unique index, used mostly for + * error logging purposes. + */ + int index; + + /* Do the PBMs both exist in the same PCI domain? */ + int pbms_same_domain; + + /* The PCI bus modules controlled by us. */ + struct pci_pbm_info pbm_A; + struct pci_pbm_info pbm_B; + + /* Operations which are controller specific. */ + void (*scan_bus)(struct pci_controller_info *); + unsigned int (*irq_build)(struct pci_pbm_info *, struct pci_dev *, unsigned int); + void (*base_address_update)(struct pci_dev *, int); + void (*resource_adjust)(struct pci_dev *, struct resource *, struct resource *); + + /* Now things for the actual PCI bus probes. */ + struct pci_ops *pci_ops; + unsigned int pci_first_busno; + unsigned int pci_last_busno; + + void *starfire_cookie; +}; + +/* PCI devices which are not bridges have this placed in their pci_dev + * sysdata member. This makes OBP aware PCI device drivers easier to + * code. + */ +struct pcidev_cookie { + struct pci_pbm_info *pbm; + char prom_name[64]; + int prom_node; + struct linux_prom_pci_registers prom_regs[PROMREG_MAX]; + int num_prom_regs; + struct linux_prom_pci_registers prom_assignments[PROMREG_MAX]; + int num_prom_assignments; +}; + +/* Currently these are the same across all PCI controllers + * we support. Someday they may not be... + */ +#define PCI_IRQ_IGN 0x000007c0 /* Interrupt Group Number */ +#define PCI_IRQ_INO 0x0000003f /* Interrupt Number */ + +#endif /* !(__SPARC64_PBM_H) */ diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h new file mode 100644 index 000000000000..2a0c85cd1c11 --- /dev/null +++ b/include/asm-sparc64/pci.h @@ -0,0 +1,264 @@ +#ifndef __SPARC64_PCI_H +#define __SPARC64_PCI_H + +#ifdef __KERNEL__ + +#include <linux/fs.h> +#include <linux/mm.h> + +/* Can be used to override the logic in pci_scan_bus for skipping + * already-configured bus numbers - to be used for buggy BIOSes + * or architectures with incomplete PCI setup by the loader. + */ +#define pcibios_assign_all_busses() 0 +#define pcibios_scan_all_fns(a, b) 0 + +#define PCIBIOS_MIN_IO 0UL +#define PCIBIOS_MIN_MEM 0UL + +#define PCI_IRQ_NONE 0xffffffff + +static inline void pcibios_set_master(struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} + +static inline void pcibios_penalize_isa_irq(int irq) +{ + /* We don't do dynamic PCI IRQ allocation */ +} + +/* Dynamic DMA mapping stuff. + */ + +/* The PCI address space does not equal the physical memory + * address space. The networking and block device layers use + * this boolean for bounce buffer decisions. + */ +#define PCI_DMA_BUS_IS_PHYS (0) + +#include <asm/scatterlist.h> + +struct pci_dev; + +/* Allocate and map kernel buffer using consistent mode DMA for a device. + * hwdev should be valid struct pci_dev pointer for PCI devices. + */ +extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle); + +/* Free and unmap a consistent DMA buffer. + * cpu_addr is what was returned from pci_alloc_consistent, + * size must be the same as what as passed into pci_alloc_consistent, + * and likewise dma_addr must be the same as what *dma_addrp was set to. + * + * References to the memory and mappings associated with cpu_addr/dma_addr + * past this call are illegal. + */ +extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); + +/* Map a single buffer of the indicated size for DMA in streaming mode. + * The 32-bit bus address to use is returned. + * + * Once the device is given the dma address, the device owns this memory + * until either pci_unmap_single or pci_dma_sync_single_for_cpu is performed. + */ +extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction); + +/* Unmap a single streaming mode DMA translation. The dma_addr and size + * must match what was provided for in a previous pci_map_single call. All + * other usages are undefined. + * + * After this call, reads by the cpu to the buffer are guaranteed to see + * whatever the device wrote there. + */ +extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction); + +/* No highmem on sparc64, plus we have an IOMMU, so mapping pages is easy. */ +#define pci_map_page(dev, page, off, size, dir) \ + pci_map_single(dev, (page_address(page) + (off)), size, dir) +#define pci_unmap_page(dev,addr,sz,dir) pci_unmap_single(dev,addr,sz,dir) + +/* pci_unmap_{single,page} is not a nop, thus... */ +#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ + dma_addr_t ADDR_NAME; +#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \ + __u32 LEN_NAME; +#define pci_unmap_addr(PTR, ADDR_NAME) \ + ((PTR)->ADDR_NAME) +#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \ + (((PTR)->ADDR_NAME) = (VAL)) +#define pci_unmap_len(PTR, LEN_NAME) \ + ((PTR)->LEN_NAME) +#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ + (((PTR)->LEN_NAME) = (VAL)) + +/* Map a set of buffers described by scatterlist in streaming + * mode for DMA. This is the scatter-gather version of the + * above pci_map_single interface. Here the scatter gather list + * elements are each tagged with the appropriate dma address + * and length. They are obtained via sg_dma_{address,length}(SG). + * + * NOTE: An implementation may be able to use a smaller number of + * DMA address/length pairs than there are SG table elements. + * (for example via virtual mapping capabilities) + * The routine returns the number of addr/length pairs actually + * used, at most nents. + * + * Device ownership issues as mentioned above for pci_map_single are + * the same here. + */ +extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nents, int direction); + +/* Unmap a set of streaming mode DMA translations. + * Again, cpu read rules concerning calls here are the same as for + * pci_unmap_single() above. + */ +extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nhwents, int direction); + +/* Make physical memory consistent for a single + * streaming mode DMA translation after a transfer. + * + * If you perform a pci_map_single() but wish to interrogate the + * buffer using the cpu, yet do not wish to teardown the PCI dma + * mapping, you must call this function before doing so. At the + * next point you give the PCI dma address back to the card, you + * must first perform a pci_dma_sync_for_device, and then the + * device again owns the buffer. + */ +extern void pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle, + size_t size, int direction); + +static inline void +pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle, + size_t size, int direction) +{ + /* No flushing needed to sync cpu writes to the device. */ + BUG_ON(direction == PCI_DMA_NONE); +} + +/* Make physical memory consistent for a set of streaming + * mode DMA translations after a transfer. + * + * The same as pci_dma_sync_single_* but for a scatter-gather list, + * same rules and usage. + */ +extern void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction); + +static inline void +pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, + int nelems, int direction) +{ + /* No flushing needed to sync cpu writes to the device. */ + BUG_ON(direction == PCI_DMA_NONE); +} + +/* Return whether the given PCI device DMA address mask can + * be supported properly. For example, if your device can + * only drive the low 24-bits during PCI bus mastering, then + * you would pass 0x00ffffff as the mask to this function. + */ +extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask); + +/* PCI IOMMU mapping bypass support. */ + +/* PCI 64-bit addressing works for all slots on all controller + * types on sparc64. However, it requires that the device + * can drive enough of the 64 bits. + */ +#define PCI64_REQUIRED_MASK (~(dma64_addr_t)0) +#define PCI64_ADDR_BASE 0xfffc000000000000UL + +/* Usage of the pci_dac_foo interfaces is only valid if this + * test passes. + */ +#define pci_dac_dma_supported(pci_dev, mask) \ + ((((mask) & PCI64_REQUIRED_MASK) == PCI64_REQUIRED_MASK) ? 1 : 0) + +static inline dma64_addr_t +pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction) +{ + return (PCI64_ADDR_BASE + + __pa(page_address(page)) + offset); +} + +static inline struct page * +pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr) +{ + unsigned long paddr = (dma_addr & PAGE_MASK) - PCI64_ADDR_BASE; + + return virt_to_page(__va(paddr)); +} + +static inline unsigned long +pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr) +{ + return (dma_addr & ~PAGE_MASK); +} + +static inline void +pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction) +{ + /* DAC cycle addressing does not make use of the + * PCI controller's streaming cache, so nothing to do. + */ +} + +static inline void +pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction) +{ + /* DAC cycle addressing does not make use of the + * PCI controller's streaming cache, so nothing to do. + */ +} + +#define PCI_DMA_ERROR_CODE (~(dma_addr_t)0x0) + +static inline int pci_dma_mapping_error(dma_addr_t dma_addr) +{ + return (dma_addr == PCI_DMA_ERROR_CODE); +} + +/* Return the index of the PCI controller for device PDEV. */ + +extern int pci_domain_nr(struct pci_bus *bus); +static inline int pci_proc_domain(struct pci_bus *bus) +{ + return 1; +} + +/* Platform support for /proc/bus/pci/X/Y mmap()s. */ + +#define HAVE_PCI_MMAP +#define HAVE_ARCH_PCI_GET_UNMAPPED_AREA +#define get_pci_unmapped_area get_fb_unmapped_area + +extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, + int write_combine); + +/* Platform specific MWI support. */ +#define HAVE_ARCH_PCI_MWI +extern int pcibios_prep_mwi(struct pci_dev *dev); + +extern void +pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, + struct resource *res); + +extern void +pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, + struct pci_bus_region *region); + +static inline void pcibios_add_platform_entries(struct pci_dev *dev) +{ +} + +static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) +{ + return PCI_IRQ_NONE; +} + +#endif /* __KERNEL__ */ + +#endif /* __SPARC64_PCI_H */ diff --git a/include/asm-sparc64/pconf.h b/include/asm-sparc64/pconf.h new file mode 100644 index 000000000000..aad106a70908 --- /dev/null +++ b/include/asm-sparc64/pconf.h @@ -0,0 +1,25 @@ +/* $Id: pconf.h,v 1.1 1996/12/02 00:09:10 davem Exp $ + * pconf.h: pathconf() and fpathconf() defines for SunOS + * system call compatibility. + * + * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC64_PCONF_H +#define _SPARC64_PCONF_H + +#include <linux/fs.h> +#include <linux/limits.h> + +#define _PCONF_LINK 1 /* Max number of links to an object */ +#define _PCONF_CANON 2 /* TTY input buffer line size */ +#define _PCONF_INPUT 3 /* Biggest packet a tty can imbibe at once */ +#define _PCONF_NAME 4 /* Filename length max */ +#define _PCONF_PATH 5 /* Max size of a pathname */ +#define _PCONF_PIPE 6 /* Buffer size for a pipe */ +#define _PCONF_CHRESTRICT 7 /* Can only root chown files? */ +#define _PCONF_NOTRUNC 8 /* Are pathnames truncated if too big? */ +#define _PCONF_VDISABLE 9 /* Magic char to disable special tty chars */ +#define _PCONF_MAXPCONF 9 + +#endif /* !(_SPARC64_PCONF_H) */ diff --git a/include/asm-sparc64/percpu.h b/include/asm-sparc64/percpu.h new file mode 100644 index 000000000000..aea4e51e7cd1 --- /dev/null +++ b/include/asm-sparc64/percpu.h @@ -0,0 +1,49 @@ +#ifndef __ARCH_SPARC64_PERCPU__ +#define __ARCH_SPARC64_PERCPU__ + +#include <linux/compiler.h> + +#ifdef CONFIG_SMP + +extern void setup_per_cpu_areas(void); + +extern unsigned long __per_cpu_base; +extern unsigned long __per_cpu_shift; +#define __per_cpu_offset(__cpu) \ + (__per_cpu_base + ((unsigned long)(__cpu) << __per_cpu_shift)) + +/* Separate out the type, so (int[3], foo) works. */ +#define DEFINE_PER_CPU(type, name) \ + __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name + +register unsigned long __local_per_cpu_offset asm("g5"); + +/* var is in discarded region: offset to particular copy we want */ +#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu))) +#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __local_per_cpu_offset)) + +/* A macro to avoid #include hell... */ +#define percpu_modcopy(pcpudst, src, size) \ +do { \ + unsigned int __i; \ + for (__i = 0; __i < NR_CPUS; __i++) \ + if (cpu_possible(__i)) \ + memcpy((pcpudst)+__per_cpu_offset(__i), \ + (src), (size)); \ +} while (0) +#else /* ! SMP */ + +#define DEFINE_PER_CPU(type, name) \ + __typeof__(type) per_cpu__##name + +#define per_cpu(var, cpu) (*((void)cpu, &per_cpu__##var)) +#define __get_cpu_var(var) per_cpu__##var + +#endif /* SMP */ + +#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name + +#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) +#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) + +#endif /* __ARCH_SPARC64_PERCPU__ */ diff --git a/include/asm-sparc64/perfctr.h b/include/asm-sparc64/perfctr.h new file mode 100644 index 000000000000..836873002b75 --- /dev/null +++ b/include/asm-sparc64/perfctr.h @@ -0,0 +1,173 @@ +/*---------------------------------------- + PERFORMANCE INSTRUMENTATION + Guillaume Thouvenin 08/10/98 + David S. Miller 10/06/98 + ---------------------------------------*/ +#ifndef PERF_COUNTER_API +#define PERF_COUNTER_API + +/* sys_perfctr() interface. First arg is operation code + * from enumeration below. The meaning of further arguments + * are determined by the operation code. + * + * int sys_perfctr(int opcode, unsigned long arg0, + * unsigned long arg1, unsigned long arg2) + * + * Pointers which are passed by the user are pointers to 64-bit + * integers. + * + * Once enabled, performance counter state is retained until the + * process either exits or performs an exec. That is, performance + * counters remain enabled for fork/clone children. + */ +enum perfctr_opcode { + /* Enable UltraSparc performance counters, ARG0 is pointer + * to 64-bit accumulator for D0 counter in PIC, ARG1 is pointer + * to 64-bit accumulator for D1 counter. ARG2 is a pointer to + * the initial PCR register value to use. + */ + PERFCTR_ON, + + /* Disable UltraSparc performance counters. The PCR is written + * with zero and the user counter accumulator pointers and + * working PCR register value are forgotten. + */ + PERFCTR_OFF, + + /* Add current D0 and D1 PIC values into user pointers given + * in PERFCTR_ON operation. The PIC is cleared before returning. + */ + PERFCTR_READ, + + /* Clear the PIC register. */ + PERFCTR_CLRPIC, + + /* Begin using a new PCR value, the pointer to which is passed + * in ARG0. The PIC is also cleared after the new PCR value is + * written. + */ + PERFCTR_SETPCR, + + /* Store in pointer given in ARG0 the current PCR register value + * being used. + */ + PERFCTR_GETPCR +}; + +/* I don't want the kernel's namespace to be polluted with this + * stuff when this file is included. --DaveM + */ +#ifndef __KERNEL__ + +#define PRIV 0x00000001 +#define SYS 0x00000002 +#define USR 0x00000004 + +/* Pic.S0 Selection Bit Field Encoding, Ultra-I/II */ +#define CYCLE_CNT 0x00000000 +#define INSTR_CNT 0x00000010 +#define DISPATCH0_IC_MISS 0x00000020 +#define DISPATCH0_STOREBUF 0x00000030 +#define IC_REF 0x00000080 +#define DC_RD 0x00000090 +#define DC_WR 0x000000A0 +#define LOAD_USE 0x000000B0 +#define EC_REF 0x000000C0 +#define EC_WRITE_HIT_RDO 0x000000D0 +#define EC_SNOOP_INV 0x000000E0 +#define EC_RD_HIT 0x000000F0 + +/* Pic.S0 Selection Bit Field Encoding, Ultra-III */ +#define US3_CYCLE_CNT 0x00000000 +#define US3_INSTR_CNT 0x00000010 +#define US3_DISPATCH0_IC_MISS 0x00000020 +#define US3_DISPATCH0_BR_TGT 0x00000030 +#define US3_DISPATCH0_2ND_BR 0x00000040 +#define US3_RSTALL_STOREQ 0x00000050 +#define US3_RSTALL_IU_USE 0x00000060 +#define US3_IC_REF 0x00000080 +#define US3_DC_RD 0x00000090 +#define US3_DC_WR 0x000000a0 +#define US3_EC_REF 0x000000c0 +#define US3_EC_WR_HIT_RTO 0x000000d0 +#define US3_EC_SNOOP_INV 0x000000e0 +#define US3_EC_RD_MISS 0x000000f0 +#define US3_PC_PORT0_RD 0x00000100 +#define US3_SI_SNOOP 0x00000110 +#define US3_SI_CIQ_FLOW 0x00000120 +#define US3_SI_OWNED 0x00000130 +#define US3_SW_COUNT_0 0x00000140 +#define US3_IU_BR_MISS_TAKEN 0x00000150 +#define US3_IU_BR_COUNT_TAKEN 0x00000160 +#define US3_DISP_RS_MISPRED 0x00000170 +#define US3_FA_PIPE_COMPL 0x00000180 +#define US3_MC_READS_0 0x00000200 +#define US3_MC_READS_1 0x00000210 +#define US3_MC_READS_2 0x00000220 +#define US3_MC_READS_3 0x00000230 +#define US3_MC_STALLS_0 0x00000240 +#define US3_MC_STALLS_2 0x00000250 + +/* Pic.S1 Selection Bit Field Encoding, Ultra-I/II */ +#define CYCLE_CNT_D1 0x00000000 +#define INSTR_CNT_D1 0x00000800 +#define DISPATCH0_IC_MISPRED 0x00001000 +#define DISPATCH0_FP_USE 0x00001800 +#define IC_HIT 0x00004000 +#define DC_RD_HIT 0x00004800 +#define DC_WR_HIT 0x00005000 +#define LOAD_USE_RAW 0x00005800 +#define EC_HIT 0x00006000 +#define EC_WB 0x00006800 +#define EC_SNOOP_CB 0x00007000 +#define EC_IT_HIT 0x00007800 + +/* Pic.S1 Selection Bit Field Encoding, Ultra-III */ +#define US3_CYCLE_CNT_D1 0x00000000 +#define US3_INSTR_CNT_D1 0x00000800 +#define US3_DISPATCH0_MISPRED 0x00001000 +#define US3_IC_MISS_CANCELLED 0x00001800 +#define US3_RE_ENDIAN_MISS 0x00002000 +#define US3_RE_FPU_BYPASS 0x00002800 +#define US3_RE_DC_MISS 0x00003000 +#define US3_RE_EC_MISS 0x00003800 +#define US3_IC_MISS 0x00004000 +#define US3_DC_RD_MISS 0x00004800 +#define US3_DC_WR_MISS 0x00005000 +#define US3_RSTALL_FP_USE 0x00005800 +#define US3_EC_MISSES 0x00006000 +#define US3_EC_WB 0x00006800 +#define US3_EC_SNOOP_CB 0x00007000 +#define US3_EC_IC_MISS 0x00007800 +#define US3_RE_PC_MISS 0x00008000 +#define US3_ITLB_MISS 0x00008800 +#define US3_DTLB_MISS 0x00009000 +#define US3_WC_MISS 0x00009800 +#define US3_WC_SNOOP_CB 0x0000a000 +#define US3_WC_SCRUBBED 0x0000a800 +#define US3_WC_WB_WO_READ 0x0000b000 +#define US3_PC_SOFT_HIT 0x0000c000 +#define US3_PC_SNOOP_INV 0x0000c800 +#define US3_PC_HARD_HIT 0x0000d000 +#define US3_PC_PORT1_RD 0x0000d800 +#define US3_SW_COUNT_1 0x0000e000 +#define US3_IU_STAT_BR_MIS_UNTAKEN 0x0000e800 +#define US3_IU_STAT_BR_COUNT_UNTAKEN 0x0000f000 +#define US3_PC_MS_MISSES 0x0000f800 +#define US3_MC_WRITES_0 0x00010800 +#define US3_MC_WRITES_1 0x00011000 +#define US3_MC_WRITES_2 0x00011800 +#define US3_MC_WRITES_3 0x00012000 +#define US3_MC_STALLS_1 0x00012800 +#define US3_MC_STALLS_3 0x00013000 +#define US3_RE_RAW_MISS 0x00013800 +#define US3_FM_PIPE_COMPLETION 0x00014000 + +struct vcounter_struct { + unsigned long long vcnt0; + unsigned long long vcnt1; +}; + +#endif /* !(__KERNEL__) */ + +#endif /* !(PERF_COUNTER_API) */ diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h new file mode 100644 index 000000000000..2c28e1f605b7 --- /dev/null +++ b/include/asm-sparc64/pgalloc.h @@ -0,0 +1,188 @@ +/* $Id: pgalloc.h,v 1.30 2001/12/21 04:56:17 davem Exp $ */ +#ifndef _SPARC64_PGALLOC_H +#define _SPARC64_PGALLOC_H + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/spitfire.h> +#include <asm/cpudata.h> +#include <asm/cacheflush.h> + +/* Page table allocation/freeing. */ +#ifdef CONFIG_SMP +/* Sliiiicck */ +#define pgt_quicklists local_cpu_data() +#else +extern struct pgtable_cache_struct { + unsigned long *pgd_cache; + unsigned long *pte_cache[2]; + unsigned int pgcache_size; +} pgt_quicklists; +#endif +#define pgd_quicklist (pgt_quicklists.pgd_cache) +#define pmd_quicklist ((unsigned long *)0) +#define pte_quicklist (pgt_quicklists.pte_cache) +#define pgtable_cache_size (pgt_quicklists.pgcache_size) + +static __inline__ void free_pgd_fast(pgd_t *pgd) +{ + preempt_disable(); + *(unsigned long *)pgd = (unsigned long) pgd_quicklist; + pgd_quicklist = (unsigned long *) pgd; + pgtable_cache_size++; + preempt_enable(); +} + +static __inline__ pgd_t *get_pgd_fast(void) +{ + unsigned long *ret; + + preempt_disable(); + if((ret = pgd_quicklist) != NULL) { + pgd_quicklist = (unsigned long *)(*ret); + ret[0] = 0; + pgtable_cache_size--; + preempt_enable(); + } else { + preempt_enable(); + ret = (unsigned long *) __get_free_page(GFP_KERNEL|__GFP_REPEAT); + if(ret) + memset(ret, 0, PAGE_SIZE); + } + return (pgd_t *)ret; +} + +static __inline__ void free_pgd_slow(pgd_t *pgd) +{ + free_page((unsigned long)pgd); +} + +#ifdef DCACHE_ALIASING_POSSIBLE +#define VPTE_COLOR(address) (((address) >> (PAGE_SHIFT + 10)) & 1UL) +#define DCACHE_COLOR(address) (((address) >> PAGE_SHIFT) & 1UL) +#else +#define VPTE_COLOR(address) 0 +#define DCACHE_COLOR(address) 0 +#endif + +#define pud_populate(MM, PUD, PMD) pud_set(PUD, PMD) + +static __inline__ pmd_t *pmd_alloc_one_fast(struct mm_struct *mm, unsigned long address) +{ + unsigned long *ret; + int color = 0; + + preempt_disable(); + if (pte_quicklist[color] == NULL) + color = 1; + + if((ret = (unsigned long *)pte_quicklist[color]) != NULL) { + pte_quicklist[color] = (unsigned long *)(*ret); + ret[0] = 0; + pgtable_cache_size--; + } + preempt_enable(); + + return (pmd_t *)ret; +} + +static __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) +{ + pmd_t *pmd; + + pmd = pmd_alloc_one_fast(mm, address); + if (!pmd) { + pmd = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); + if (pmd) + memset(pmd, 0, PAGE_SIZE); + } + return pmd; +} + +static __inline__ void free_pmd_fast(pmd_t *pmd) +{ + unsigned long color = DCACHE_COLOR((unsigned long)pmd); + + preempt_disable(); + *(unsigned long *)pmd = (unsigned long) pte_quicklist[color]; + pte_quicklist[color] = (unsigned long *) pmd; + pgtable_cache_size++; + preempt_enable(); +} + +static __inline__ void free_pmd_slow(pmd_t *pmd) +{ + free_page((unsigned long)pmd); +} + +#define pmd_populate_kernel(MM, PMD, PTE) pmd_set(PMD, PTE) +#define pmd_populate(MM,PMD,PTE_PAGE) \ + pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE)) + +extern pte_t *__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address); + +static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) +{ + return __pte_alloc_one_kernel(mm, address); +} + +static inline struct page * +pte_alloc_one(struct mm_struct *mm, unsigned long addr) +{ + pte_t *pte = __pte_alloc_one_kernel(mm, addr); + + if (pte) + return virt_to_page(pte); + + return NULL; +} + +static __inline__ pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address) +{ + unsigned long color = VPTE_COLOR(address); + unsigned long *ret; + + preempt_disable(); + if((ret = (unsigned long *)pte_quicklist[color]) != NULL) { + pte_quicklist[color] = (unsigned long *)(*ret); + ret[0] = 0; + pgtable_cache_size--; + } + preempt_enable(); + return (pte_t *)ret; +} + +static __inline__ void free_pte_fast(pte_t *pte) +{ + unsigned long color = DCACHE_COLOR((unsigned long)pte); + + preempt_disable(); + *(unsigned long *)pte = (unsigned long) pte_quicklist[color]; + pte_quicklist[color] = (unsigned long *) pte; + pgtable_cache_size++; + preempt_enable(); +} + +static __inline__ void free_pte_slow(pte_t *pte) +{ + free_page((unsigned long)pte); +} + +static inline void pte_free_kernel(pte_t *pte) +{ + free_pte_fast(pte); +} + +static inline void pte_free(struct page *ptepage) +{ + free_pte_fast(page_address(ptepage)); +} + +#define pmd_free(pmd) free_pmd_fast(pmd) +#define pgd_free(pgd) free_pgd_fast(pgd) +#define pgd_alloc(mm) get_pgd_fast() + +#endif /* _SPARC64_PGALLOC_H */ diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h new file mode 100644 index 000000000000..ca04ac105b69 --- /dev/null +++ b/include/asm-sparc64/pgtable.h @@ -0,0 +1,464 @@ +/* $Id: pgtable.h,v 1.156 2002/02/09 19:49:31 davem Exp $ + * pgtable.h: SpitFire page table operations. + * + * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu) + * Copyright 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +#ifndef _SPARC64_PGTABLE_H +#define _SPARC64_PGTABLE_H + +/* This file contains the functions and defines necessary to modify and use + * the SpitFire page tables. + */ + +#include <asm-generic/pgtable-nopud.h> + +#include <linux/config.h> +#include <linux/compiler.h> +#include <asm/types.h> +#include <asm/spitfire.h> +#include <asm/asi.h> +#include <asm/system.h> +#include <asm/page.h> +#include <asm/processor.h> +#include <asm/const.h> + +/* The kernel image occupies 0x4000000 to 0x1000000 (4MB --> 16MB). + * The page copy blockops use 0x1000000 to 0x18000000 (16MB --> 24MB). + * The PROM resides in an area spanning 0xf0000000 to 0x100000000. + * The vmalloc area spans 0x140000000 to 0x200000000. + * There is a single static kernel PMD which maps from 0x0 to address + * 0x400000000. + */ +#define TLBTEMP_BASE _AC(0x0000000001000000,UL) +#define MODULES_VADDR _AC(0x0000000002000000,UL) +#define MODULES_LEN _AC(0x000000007e000000,UL) +#define MODULES_END _AC(0x0000000080000000,UL) +#define VMALLOC_START _AC(0x0000000140000000,UL) +#define VMALLOC_END _AC(0x0000000200000000,UL) +#define LOW_OBP_ADDRESS _AC(0x00000000f0000000,UL) +#define HI_OBP_ADDRESS _AC(0x0000000100000000,UL) + +/* XXX All of this needs to be rethought so we can take advantage + * XXX cheetah's full 64-bit virtual address space, ie. no more hole + * XXX in the middle like on spitfire. -DaveM + */ +/* + * Given a virtual address, the lowest PAGE_SHIFT bits determine offset + * into the page; the next higher PAGE_SHIFT-3 bits determine the pte# + * in the proper pagetable (the -3 is from the 8 byte ptes, and each page + * table is a single page long). The next higher PMD_BITS determine pmd# + * in the proper pmdtable (where we must have PMD_BITS <= (PAGE_SHIFT-2) + * since the pmd entries are 4 bytes, and each pmd page is a single page + * long). Finally, the higher few bits determine pgde#. + */ + +/* 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) +#define PMD_MASK (~(PMD_SIZE-1)) +#define PMD_BITS (PAGE_SHIFT - 2) + +/* PGDIR_SHIFT determines what a third-level page table entry can map */ +#define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3) + PMD_BITS) +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) +#define PGDIR_BITS (PAGE_SHIFT - 2) + +#ifndef __ASSEMBLY__ + +#include <linux/sched.h> + +/* Entries per page directory level. */ +#define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3)) +#define PTRS_PER_PMD (1UL << PMD_BITS) +#define PTRS_PER_PGD (1UL << PGDIR_BITS) + +/* Kernel has a separate 44bit address space. */ +#define FIRST_USER_PGD_NR 0 + +#define pte_ERROR(e) __builtin_trap() +#define pmd_ERROR(e) __builtin_trap() +#define pgd_ERROR(e) __builtin_trap() + +#endif /* !(__ASSEMBLY__) */ + +/* Spitfire/Cheetah TTE bits. */ +#define _PAGE_VALID _AC(0x8000000000000000,UL) /* Valid TTE */ +#define _PAGE_R _AC(0x8000000000000000,UL) /* Keep ref bit up to date*/ +#define _PAGE_SZ4MB _AC(0x6000000000000000,UL) /* 4MB Page */ +#define _PAGE_SZ512K _AC(0x4000000000000000,UL) /* 512K Page */ +#define _PAGE_SZ64K _AC(0x2000000000000000,UL) /* 64K Page */ +#define _PAGE_SZ8K _AC(0x0000000000000000,UL) /* 8K Page */ +#define _PAGE_NFO _AC(0x1000000000000000,UL) /* No Fault Only */ +#define _PAGE_IE _AC(0x0800000000000000,UL) /* Invert Endianness */ +#define _PAGE_SOFT2 _AC(0x07FC000000000000,UL) /* Software bits, set 2 */ +#define _PAGE_RES1 _AC(0x0003000000000000,UL) /* Reserved */ +#define _PAGE_SN _AC(0x0000800000000000,UL) /* (Cheetah) Snoop */ +#define _PAGE_RES2 _AC(0x0000780000000000,UL) /* Reserved */ +#define _PAGE_PADDR_SF _AC(0x000001FFFFFFE000,UL) /* (Spitfire) paddr[40:13]*/ +#define _PAGE_PADDR _AC(0x000007FFFFFFE000,UL) /* (Cheetah) paddr[42:13] */ +#define _PAGE_SOFT _AC(0x0000000000001F80,UL) /* Software bits */ +#define _PAGE_L _AC(0x0000000000000040,UL) /* Locked TTE */ +#define _PAGE_CP _AC(0x0000000000000020,UL) /* Cacheable in P-Cache */ +#define _PAGE_CV _AC(0x0000000000000010,UL) /* Cacheable in V-Cache */ +#define _PAGE_E _AC(0x0000000000000008,UL) /* side-Effect */ +#define _PAGE_P _AC(0x0000000000000004,UL) /* Privileged Page */ +#define _PAGE_W _AC(0x0000000000000002,UL) /* Writable */ +#define _PAGE_G _AC(0x0000000000000001,UL) /* Global */ + +/* Here are the SpitFire software bits we use in the TTE's. + * + * WARNING: If you are going to try and start using some + * of the soft2 bits, you will need to make + * modifications to the swap entry implementation. + * For example, one thing that could happen is that + * swp_entry_to_pte() would BUG_ON() if you tried + * to use one of the soft2 bits for _PAGE_FILE. + * + * Like other architectures, I have aliased _PAGE_FILE with + * _PAGE_MODIFIED. This works because _PAGE_FILE is never + * interpreted that way unless _PAGE_PRESENT is clear. + */ +#define _PAGE_EXEC _AC(0x0000000000001000,UL) /* Executable SW bit */ +#define _PAGE_MODIFIED _AC(0x0000000000000800,UL) /* Modified (dirty) */ +#define _PAGE_FILE _AC(0x0000000000000800,UL) /* Pagecache page */ +#define _PAGE_ACCESSED _AC(0x0000000000000400,UL) /* Accessed (ref'd) */ +#define _PAGE_READ _AC(0x0000000000000200,UL) /* Readable SW Bit */ +#define _PAGE_WRITE _AC(0x0000000000000100,UL) /* Writable SW Bit */ +#define _PAGE_PRESENT _AC(0x0000000000000080,UL) /* Present */ + +#if PAGE_SHIFT == 13 +#define _PAGE_SZBITS _PAGE_SZ8K +#elif PAGE_SHIFT == 16 +#define _PAGE_SZBITS _PAGE_SZ64K +#elif PAGE_SHIFT == 19 +#define _PAGE_SZBITS _PAGE_SZ512K +#elif PAGE_SHIFT == 22 +#define _PAGE_SZBITS _PAGE_SZ4MB +#else +#error Wrong PAGE_SHIFT specified +#endif + +#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB) +#define _PAGE_SZHUGE _PAGE_SZ4MB +#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K) +#define _PAGE_SZHUGE _PAGE_SZ512K +#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K) +#define _PAGE_SZHUGE _PAGE_SZ64K +#endif + +#define _PAGE_CACHE (_PAGE_CP | _PAGE_CV) + +#define __DIRTY_BITS (_PAGE_MODIFIED | _PAGE_WRITE | _PAGE_W) +#define __ACCESS_BITS (_PAGE_ACCESSED | _PAGE_READ | _PAGE_R) +#define __PRIV_BITS _PAGE_P + +#define PAGE_NONE __pgprot (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_CACHE) + +/* Don't set the TTE _PAGE_W bit here, else the dirty bit never gets set. */ +#define PAGE_SHARED __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ + __ACCESS_BITS | _PAGE_WRITE | _PAGE_EXEC) + +#define PAGE_COPY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ + __ACCESS_BITS | _PAGE_EXEC) + +#define PAGE_READONLY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ + __ACCESS_BITS | _PAGE_EXEC) + +#define PAGE_KERNEL __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ + __PRIV_BITS | \ + __ACCESS_BITS | __DIRTY_BITS | _PAGE_EXEC) + +#define PAGE_SHARED_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | \ + _PAGE_CACHE | \ + __ACCESS_BITS | _PAGE_WRITE) + +#define PAGE_COPY_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | \ + _PAGE_CACHE | __ACCESS_BITS) + +#define PAGE_READONLY_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | \ + _PAGE_CACHE | __ACCESS_BITS) + +#define _PFN_MASK _PAGE_PADDR + +#define pg_iobits (_PAGE_VALID | _PAGE_PRESENT | __DIRTY_BITS | \ + __ACCESS_BITS | _PAGE_E) + +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY_NOEXEC +#define __P010 PAGE_COPY_NOEXEC +#define __P011 PAGE_COPY_NOEXEC +#define __P100 PAGE_READONLY +#define __P101 PAGE_READONLY +#define __P110 PAGE_COPY +#define __P111 PAGE_COPY + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY_NOEXEC +#define __S010 PAGE_SHARED_NOEXEC +#define __S011 PAGE_SHARED_NOEXEC +#define __S100 PAGE_READONLY +#define __S101 PAGE_READONLY +#define __S110 PAGE_SHARED +#define __S111 PAGE_SHARED + +#ifndef __ASSEMBLY__ + +extern unsigned long phys_base; +extern unsigned long pfn_base; + +extern struct page *mem_map_zero; +#define ZERO_PAGE(vaddr) (mem_map_zero) + +/* PFNs are real physical page numbers. However, mem_map only begins to record + * per-page information starting at pfn_base. This is to handle systems where + * the first physical page in the machine is at some huge physical address, + * such as 4GB. This is common on a partitioned E10000, for example. + */ + +#define pfn_pte(pfn, prot) \ + __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot) | _PAGE_SZBITS) +#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) + +#define pte_pfn(x) ((pte_val(x) & _PAGE_PADDR)>>PAGE_SHIFT) +#define pte_page(x) pfn_to_page(pte_pfn(x)) + +#define page_pte_prot(page, prot) mk_pte(page, prot) +#define page_pte(page) page_pte_prot(page, __pgprot(0)) + +static inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot) +{ + pte_t __pte; + const unsigned long preserve_mask = (_PFN_MASK | + _PAGE_MODIFIED | _PAGE_ACCESSED | + _PAGE_CACHE | _PAGE_E | + _PAGE_PRESENT | _PAGE_SZBITS); + + pte_val(__pte) = (pte_val(orig_pte) & preserve_mask) | + (pgprot_val(new_prot) & ~preserve_mask); + + return __pte; +} +#define pmd_set(pmdp, ptep) \ + (pmd_val(*(pmdp)) = (__pa((unsigned long) (ptep)) >> 11UL)) +#define pud_set(pudp, pmdp) \ + (pud_val(*(pudp)) = (__pa((unsigned long) (pmdp)) >> 11UL)) +#define __pmd_page(pmd) \ + ((unsigned long) __va((((unsigned long)pmd_val(pmd))<<11UL))) +#define pmd_page(pmd) virt_to_page((void *)__pmd_page(pmd)) +#define pud_page(pud) \ + ((unsigned long) __va((((unsigned long)pud_val(pud))<<11UL))) +#define pte_none(pte) (!pte_val(pte)) +#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT) +#define pmd_none(pmd) (!pmd_val(pmd)) +#define pmd_bad(pmd) (0) +#define pmd_present(pmd) (pmd_val(pmd) != 0U) +#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0U) +#define pud_none(pud) (!pud_val(pud)) +#define pud_bad(pud) (0) +#define pud_present(pud) (pud_val(pud) != 0U) +#define pud_clear(pudp) (pud_val(*(pudp)) = 0U) + +/* The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +#define pte_read(pte) (pte_val(pte) & _PAGE_READ) +#define pte_exec(pte) (pte_val(pte) & _PAGE_EXEC) +#define pte_write(pte) (pte_val(pte) & _PAGE_WRITE) +#define pte_dirty(pte) (pte_val(pte) & _PAGE_MODIFIED) +#define pte_young(pte) (pte_val(pte) & _PAGE_ACCESSED) +#define pte_wrprotect(pte) (__pte(pte_val(pte) & ~(_PAGE_WRITE|_PAGE_W))) +#define pte_rdprotect(pte) \ + (__pte(((pte_val(pte)<<1UL)>>1UL) & ~_PAGE_READ)) +#define pte_mkclean(pte) \ + (__pte(pte_val(pte) & ~(_PAGE_MODIFIED|_PAGE_W))) +#define pte_mkold(pte) \ + (__pte(((pte_val(pte)<<1UL)>>1UL) & ~_PAGE_ACCESSED)) + +/* Permanent address of a page. */ +#define __page_address(page) page_address(page) + +/* Be very careful when you change these three, they are delicate. */ +#define pte_mkyoung(pte) (__pte(pte_val(pte) | _PAGE_ACCESSED | _PAGE_R)) +#define pte_mkwrite(pte) (__pte(pte_val(pte) | _PAGE_WRITE)) +#define pte_mkdirty(pte) (__pte(pte_val(pte) | _PAGE_MODIFIED | _PAGE_W)) + +/* to find an entry in a page-table-directory. */ +#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) +#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) + +/* to find an entry in a kernel page-table-directory */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) + +/* extract the pgd cache used for optimizing the tlb miss + * slow path when executing 32-bit compat processes + */ +#define get_pgd_cache(pgd) ((unsigned long) pgd_val(*pgd) << 11) + +/* Find an entry in the second-level page table.. */ +#define pmd_offset(pudp, address) \ + ((pmd_t *) pud_page(*(pudp)) + \ + (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))) + +/* Find an entry in the third-level page table.. */ +#define pte_index(dir, address) \ + ((pte_t *) __pmd_page(*(dir)) + \ + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) +#define pte_offset_kernel pte_index +#define pte_offset_map pte_index +#define pte_offset_map_nested pte_index +#define pte_unmap(pte) do { } while (0) +#define pte_unmap_nested(pte) do { } while (0) + +/* Actual page table PTE updates. */ +extern void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t orig); + +static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) +{ + pte_t orig = *ptep; + + *ptep = pte; + + /* It is more efficient to let flush_tlb_kernel_range() + * handle init_mm tlb flushes. + */ + if (likely(mm != &init_mm) && (pte_val(orig) & _PAGE_VALID)) + tlb_batch_add(mm, addr, ptep, orig); +} + +#define pte_clear(mm,addr,ptep) \ + set_pte_at((mm), (addr), (ptep), __pte(0UL)) + +extern pgd_t swapper_pg_dir[1]; + +/* These do nothing with the way I have things setup. */ +#define mmu_lockarea(vaddr, len) (vaddr) +#define mmu_unlockarea(vaddr, len) do { } while(0) + +struct vm_area_struct; +extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t); + +/* Make a non-present pseudo-TTE. */ +static inline pte_t mk_pte_io(unsigned long page, pgprot_t prot, int space) +{ + pte_t pte; + pte_val(pte) = (((page) | pgprot_val(prot) | _PAGE_E) & + ~(unsigned long)_PAGE_CACHE); + pte_val(pte) |= (((unsigned long)space) << 32); + return pte; +} + +/* Encode and de-code a swap entry */ +#define __swp_type(entry) (((entry).val >> PAGE_SHIFT) & 0xffUL) +#define __swp_offset(entry) ((entry).val >> (PAGE_SHIFT + 8UL)) +#define __swp_entry(type, offset) \ + ( (swp_entry_t) \ + { \ + (((long)(type) << PAGE_SHIFT) | \ + ((long)(offset) << (PAGE_SHIFT + 8UL))) \ + } ) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) + +/* File offset in PTE support. */ +#define pte_file(pte) (pte_val(pte) & _PAGE_FILE) +#define pte_to_pgoff(pte) (pte_val(pte) >> PAGE_SHIFT) +#define pgoff_to_pte(off) (__pte(((off) << PAGE_SHIFT) | _PAGE_FILE)) +#define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL) + +extern unsigned long prom_virt_to_phys(unsigned long, int *); + +static __inline__ unsigned long +sun4u_get_pte (unsigned long addr) +{ + pgd_t *pgdp; + pud_t *pudp; + pmd_t *pmdp; + pte_t *ptep; + + if (addr >= PAGE_OFFSET) + return addr & _PAGE_PADDR; + if ((addr >= LOW_OBP_ADDRESS) && (addr < HI_OBP_ADDRESS)) + return prom_virt_to_phys(addr, NULL); + pgdp = pgd_offset_k(addr); + pudp = pud_offset(pgdp, addr); + pmdp = pmd_offset(pudp, addr); + ptep = pte_offset_kernel(pmdp, addr); + return pte_val(*ptep) & _PAGE_PADDR; +} + +static __inline__ unsigned long +__get_phys (unsigned long addr) +{ + return sun4u_get_pte (addr); +} + +static __inline__ int +__get_iospace (unsigned long addr) +{ + return ((sun4u_get_pte (addr) & 0xf0000000) >> 28); +} + +extern unsigned long *sparc64_valid_addr_bitmap; + +/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ +#define kern_addr_valid(addr) \ + (test_bit(__pa((unsigned long)(addr))>>22, sparc64_valid_addr_bitmap)) + +extern int io_remap_page_range(struct vm_area_struct *vma, unsigned long from, + unsigned long offset, + unsigned long size, pgprot_t prot, int space); +extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, + unsigned long pfn, + unsigned long size, pgprot_t prot); + +/* + * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in + * its high 4 bits. These macros/functions put it there or get it from there. + */ +#define MK_IOSPACE_PFN(space, pfn) (pfn | (space << (BITS_PER_LONG - 4))) +#define GET_IOSPACE(pfn) (pfn >> (BITS_PER_LONG - 4)) +#define GET_PFN(pfn) (pfn & 0x0fffffffffffffffUL) + +/* Override for {pgd,pmd}_addr_end() to deal with the virtual address + * space hole. We simply sign extend bit 43. + */ +#define pgd_addr_end(addr, end) \ +({ unsigned long __boundary = ((addr) + PGDIR_SIZE) & PGDIR_MASK; \ + __boundary = ((long) (__boundary << 20)) >> 20; \ + (__boundary - 1 < (end) - 1)? __boundary: (end); \ +}) + +#define pmd_addr_end(addr, end) \ +({ unsigned long __boundary = ((addr) + PMD_SIZE) & PMD_MASK; \ + __boundary = ((long) (__boundary << 20)) >> 20; \ + (__boundary - 1 < (end) - 1)? __boundary: (end); \ +}) + +#include <asm-generic/pgtable.h> + +/* We provide our own get_unmapped_area to cope with VA holes for userland */ +#define HAVE_ARCH_UNMAPPED_AREA + +/* We provide a special get_unmapped_area for framebuffer mmaps to try and use + * the largest alignment possible such that larget PTEs can be used. + */ +extern unsigned long get_fb_unmapped_area(struct file *filp, unsigned long, + unsigned long, unsigned long, + unsigned long); +#define HAVE_ARCH_FB_UNMAPPED_AREA + +/* + * No page table caches to initialise + */ +#define pgtable_cache_init() do { } while (0) + +extern void check_pgt_cache(void); + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(_SPARC64_PGTABLE_H) */ diff --git a/include/asm-sparc64/pil.h b/include/asm-sparc64/pil.h new file mode 100644 index 000000000000..8f87750c3517 --- /dev/null +++ b/include/asm-sparc64/pil.h @@ -0,0 +1,26 @@ +/* $Id: pil.h,v 1.1 2002/01/23 11:27:36 davem Exp $ */ +#ifndef _SPARC64_PIL_H +#define _SPARC64_PIL_H + +/* To avoid some locking problems, we hard allocate certain PILs + * for SMP cross call messages that must do a etrap/rtrap. + * + * A cli() does not block the cross call delivery, so when SMP + * locking is an issue we reschedule the event into a PIL interrupt + * which is blocked by cli(). + * + * In fact any XCALL which has to etrap/rtrap has a problem because + * it is difficult to prevent rtrap from running BH's, and that would + * need to be done if the XCALL arrived while %pil==15. + */ +#define PIL_SMP_CALL_FUNC 1 +#define PIL_SMP_RECEIVE_SIGNAL 2 +#define PIL_SMP_CAPTURE 3 + +#ifndef __ASSEMBLY__ +#define PIL_RESERVED(PIL) ((PIL) == PIL_SMP_CALL_FUNC || \ + (PIL) == PIL_SMP_RECEIVE_SIGNAL || \ + (PIL) == PIL_SMP_CAPTURE) +#endif + +#endif /* !(_SPARC64_PIL_H) */ diff --git a/include/asm-sparc64/poll.h b/include/asm-sparc64/poll.h new file mode 100644 index 000000000000..31b611aa7468 --- /dev/null +++ b/include/asm-sparc64/poll.h @@ -0,0 +1,23 @@ +#ifndef __SPARC64_POLL_H +#define __SPARC64_POLL_H + +#define POLLIN 1 +#define POLLPRI 2 +#define POLLOUT 4 +#define POLLERR 8 +#define POLLHUP 16 +#define POLLNVAL 32 +#define POLLRDNORM 64 +#define POLLWRNORM POLLOUT +#define POLLRDBAND 128 +#define POLLWRBAND 256 +#define POLLMSG 512 +#define POLLREMOVE 1024 + +struct pollfd { + int fd; + short events; + short revents; +}; + +#endif diff --git a/include/asm-sparc64/posix_types.h b/include/asm-sparc64/posix_types.h new file mode 100644 index 000000000000..c86b9452c683 --- /dev/null +++ b/include/asm-sparc64/posix_types.h @@ -0,0 +1,126 @@ +#ifndef __ARCH_SPARC64_POSIX_TYPES_H +#define __ARCH_SPARC64_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 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_pid_t; +typedef int __kernel_ipc_pid_t; +typedef unsigned int __kernel_uid_t; +typedef unsigned int __kernel_gid_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned int __kernel_mode_t; +typedef unsigned short __kernel_umode_t; +typedef unsigned int __kernel_nlink_t; +typedef int __kernel_daddr_t; +typedef long __kernel_off_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef int __kernel_clockid_t; +typedef int __kernel_timer_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; +typedef __kernel_uid_t __kernel_uid32_t; +typedef __kernel_gid_t __kernel_gid32_t; + +typedef unsigned int __kernel_old_dev_t; + +/* Note this piece of asymmetry from the v9 ABI. */ +typedef int __kernel_suseconds_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#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 cases (8 or 32 longs, + * for 256 and 1024-bit fd_sets respectively) + */ +#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 32: + 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; + tmp[16] = 0; tmp[17] = 0; tmp[18] = 0; tmp[19] = 0; + tmp[20] = 0; tmp[21] = 0; tmp[22] = 0; tmp[23] = 0; + tmp[24] = 0; tmp[25] = 0; tmp[26] = 0; tmp[27] = 0; + tmp[28] = 0; tmp[29] = 0; tmp[30] = 0; tmp[31] = 0; + return; + 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 /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ + +#endif /* !(__ARCH_SPARC64_POSIX_TYPES_H) */ diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h new file mode 100644 index 000000000000..bc1445b904ef --- /dev/null +++ b/include/asm-sparc64/processor.h @@ -0,0 +1,197 @@ +/* $Id: processor.h,v 1.83 2002/02/10 06:04:33 davem Exp $ + * include/asm-sparc64/processor.h + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef __ASM_SPARC64_PROCESSOR_H +#define __ASM_SPARC64_PROCESSOR_H + +/* + * Sparc64 implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ void *pc; __asm__("rd %%pc, %0" : "=r" (pc)); pc; }) + +#include <linux/config.h> +#include <asm/asi.h> +#include <asm/a.out.h> +#include <asm/pstate.h> +#include <asm/ptrace.h> +#include <asm/segment.h> +#include <asm/page.h> + +/* The sparc has no problems with write protection */ +#define wp_works_ok 1 +#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ + +/* + * User lives in his very own context, and cannot reference us. Note + * that TASK_SIZE is a misnomer, it really gives maximum user virtual + * address that the kernel will allocate out. + */ +#define VA_BITS 44 +#ifndef __ASSEMBLY__ +#define VPTE_SIZE (1UL << (VA_BITS - PAGE_SHIFT + 3)) +#else +#define VPTE_SIZE (1 << (VA_BITS - PAGE_SHIFT + 3)) +#endif +#define TASK_SIZE ((unsigned long)-VPTE_SIZE) + +/* + * The vpte base must be able to hold the entire vpte, half + * of which lives above, and half below, the base. And it + * is placed as close to the highest address range as possible. + */ +#define VPTE_BASE_SPITFIRE (-(VPTE_SIZE/2)) +#if 1 +#define VPTE_BASE_CHEETAH VPTE_BASE_SPITFIRE +#else +#define VPTE_BASE_CHEETAH 0xffe0000000000000 +#endif + +#ifndef __ASSEMBLY__ + +typedef struct { + unsigned char seg; +} mm_segment_t; + +/* The Sparc processor specific thread struct. */ +/* XXX This should die, everything can go into thread_info now. */ +struct thread_struct { +#ifdef CONFIG_DEBUG_SPINLOCK + /* How many spinlocks held by this thread. + * Used with spin lock debugging to catch tasks + * sleeping illegally with locks held. + */ + int smp_lock_count; + unsigned int smp_lock_pc; +#else + int dummy; /* f'in gcc bug... */ +#endif +}; + +#endif /* !(__ASSEMBLY__) */ + +#ifndef CONFIG_DEBUG_SPINLOCK +#define INIT_THREAD { \ + 0, \ +} +#else /* CONFIG_DEBUG_SPINLOCK */ +#define INIT_THREAD { \ +/* smp_lock_count, smp_lock_pc, */ \ + 0, 0, \ +} +#endif /* !(CONFIG_DEBUG_SPINLOCK) */ + +#ifndef __ASSEMBLY__ + +#include <linux/types.h> + +/* Return saved PC of a blocked thread. */ +struct task_struct; +extern unsigned long thread_saved_pc(struct task_struct *); + +/* On Uniprocessor, even in RMO processes see TSO semantics */ +#ifdef CONFIG_SMP +#define TSTATE_INITIAL_MM TSTATE_TSO +#else +#define TSTATE_INITIAL_MM TSTATE_RMO +#endif + +/* Do necessary setup to start up a newly executed thread. */ +#define start_thread(regs, pc, sp) \ +do { \ + regs->tstate = (regs->tstate & (TSTATE_CWP)) | (TSTATE_INITIAL_MM|TSTATE_IE) | (ASI_PNF << 24); \ + regs->tpc = ((pc & (~3)) - 4); \ + regs->tnpc = regs->tpc + 4; \ + regs->y = 0; \ + set_thread_wstate(1 << 3); \ + if (current_thread_info()->utraps) { \ + if (*(current_thread_info()->utraps) < 2) \ + kfree(current_thread_info()->utraps); \ + else \ + (*(current_thread_info()->utraps))--; \ + current_thread_info()->utraps = NULL; \ + } \ + __asm__ __volatile__( \ + "stx %%g0, [%0 + %2 + 0x00]\n\t" \ + "stx %%g0, [%0 + %2 + 0x08]\n\t" \ + "stx %%g0, [%0 + %2 + 0x10]\n\t" \ + "stx %%g0, [%0 + %2 + 0x18]\n\t" \ + "stx %%g0, [%0 + %2 + 0x20]\n\t" \ + "stx %%g0, [%0 + %2 + 0x28]\n\t" \ + "stx %%g0, [%0 + %2 + 0x30]\n\t" \ + "stx %%g0, [%0 + %2 + 0x38]\n\t" \ + "stx %%g0, [%0 + %2 + 0x40]\n\t" \ + "stx %%g0, [%0 + %2 + 0x48]\n\t" \ + "stx %%g0, [%0 + %2 + 0x50]\n\t" \ + "stx %%g0, [%0 + %2 + 0x58]\n\t" \ + "stx %%g0, [%0 + %2 + 0x60]\n\t" \ + "stx %%g0, [%0 + %2 + 0x68]\n\t" \ + "stx %1, [%0 + %2 + 0x70]\n\t" \ + "stx %%g0, [%0 + %2 + 0x78]\n\t" \ + "wrpr %%g0, (1 << 3), %%wstate\n\t" \ + : \ + : "r" (regs), "r" (sp - sizeof(struct reg_window) - STACK_BIAS), \ + "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \ +} while (0) + +#define start_thread32(regs, pc, sp) \ +do { \ + pc &= 0x00000000ffffffffUL; \ + sp &= 0x00000000ffffffffUL; \ +\ + regs->tstate = (regs->tstate & (TSTATE_CWP))|(TSTATE_INITIAL_MM|TSTATE_IE|TSTATE_AM); \ + regs->tpc = ((pc & (~3)) - 4); \ + regs->tnpc = regs->tpc + 4; \ + regs->y = 0; \ + set_thread_wstate(2 << 3); \ + if (current_thread_info()->utraps) { \ + if (*(current_thread_info()->utraps) < 2) \ + kfree(current_thread_info()->utraps); \ + else \ + (*(current_thread_info()->utraps))--; \ + current_thread_info()->utraps = NULL; \ + } \ + __asm__ __volatile__( \ + "stx %%g0, [%0 + %2 + 0x00]\n\t" \ + "stx %%g0, [%0 + %2 + 0x08]\n\t" \ + "stx %%g0, [%0 + %2 + 0x10]\n\t" \ + "stx %%g0, [%0 + %2 + 0x18]\n\t" \ + "stx %%g0, [%0 + %2 + 0x20]\n\t" \ + "stx %%g0, [%0 + %2 + 0x28]\n\t" \ + "stx %%g0, [%0 + %2 + 0x30]\n\t" \ + "stx %%g0, [%0 + %2 + 0x38]\n\t" \ + "stx %%g0, [%0 + %2 + 0x40]\n\t" \ + "stx %%g0, [%0 + %2 + 0x48]\n\t" \ + "stx %%g0, [%0 + %2 + 0x50]\n\t" \ + "stx %%g0, [%0 + %2 + 0x58]\n\t" \ + "stx %%g0, [%0 + %2 + 0x60]\n\t" \ + "stx %%g0, [%0 + %2 + 0x68]\n\t" \ + "stx %1, [%0 + %2 + 0x70]\n\t" \ + "stx %%g0, [%0 + %2 + 0x78]\n\t" \ + "wrpr %%g0, (2 << 3), %%wstate\n\t" \ + : \ + : "r" (regs), "r" (sp - sizeof(struct reg_window32)), \ + "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \ +} while (0) + +/* Free all resources held by a thread. */ +#define release_thread(tsk) do { } while (0) + +/* Prepare to copy thread state - unlazy all lazy status */ +#define prepare_to_copy(tsk) do { } while (0) + +extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); + +extern unsigned long get_wchan(struct task_struct *task); + +#define KSTK_EIP(tsk) ((tsk)->thread_info->kregs->tpc) +#define KSTK_ESP(tsk) ((tsk)->thread_info->kregs->u_regs[UREG_FP]) + +#define cpu_relax() barrier() + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(__ASM_SPARC64_PROCESSOR_H) */ diff --git a/include/asm-sparc64/psrcompat.h b/include/asm-sparc64/psrcompat.h new file mode 100644 index 000000000000..5590ce6bd076 --- /dev/null +++ b/include/asm-sparc64/psrcompat.h @@ -0,0 +1,44 @@ +/* $Id: psrcompat.h,v 1.5 1998/10/06 09:28:39 jj Exp $ */ +#ifndef _SPARC64_PSRCOMPAT_H +#define _SPARC64_PSRCOMPAT_H + +#include <asm/pstate.h> + +/* Old 32-bit PSR fields for the compatibility conversion code. */ +#define PSR_CWP 0x0000001f /* current window pointer */ +#define PSR_ET 0x00000020 /* enable traps field */ +#define PSR_PS 0x00000040 /* previous privilege level */ +#define PSR_S 0x00000080 /* current privilege level */ +#define PSR_PIL 0x00000f00 /* processor interrupt level */ +#define PSR_EF 0x00001000 /* enable floating point */ +#define PSR_EC 0x00002000 /* enable co-processor */ +#define PSR_LE 0x00008000 /* SuperSparcII little-endian */ +#define PSR_ICC 0x00f00000 /* integer condition codes */ +#define PSR_C 0x00100000 /* carry bit */ +#define PSR_V 0x00200000 /* overflow bit */ +#define PSR_Z 0x00400000 /* zero bit */ +#define PSR_N 0x00800000 /* negative bit */ +#define PSR_VERS 0x0f000000 /* cpu-version field */ +#define PSR_IMPL 0xf0000000 /* cpu-implementation field */ + +#define PSR_V8PLUS 0xff000000 /* fake impl/ver, meaning a 64bit CPU is present */ +#define PSR_XCC 0x000f0000 /* if PSR_V8PLUS, this is %xcc */ + +static inline unsigned int tstate_to_psr(unsigned long tstate) +{ + return ((tstate & TSTATE_CWP) | + PSR_S | + ((tstate & TSTATE_ICC) >> 12) | + ((tstate & TSTATE_XCC) >> 20) | + PSR_V8PLUS); +} + +static inline unsigned long psr_to_tstate_icc(unsigned int psr) +{ + unsigned long tstate = ((unsigned long)(psr & PSR_ICC)) << 12; + if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) + tstate |= ((unsigned long)(psr & PSR_XCC)) << 20; + return tstate; +} + +#endif /* !(_SPARC64_PSRCOMPAT_H) */ diff --git a/include/asm-sparc64/pstate.h b/include/asm-sparc64/pstate.h new file mode 100644 index 000000000000..29fb74aa805d --- /dev/null +++ b/include/asm-sparc64/pstate.h @@ -0,0 +1,90 @@ +/* $Id: pstate.h,v 1.6 1997/06/25 07:39:45 jj Exp $ */ +#ifndef _SPARC64_PSTATE_H +#define _SPARC64_PSTATE_H + +#include <asm/const.h> + +/* The V9 PSTATE Register (with SpitFire extensions). + * + * ----------------------------------------------------------------------- + * | Resv | IG | MG | CLE | TLE | MM | RED | PEF | AM | PRIV | IE | AG | + * ----------------------------------------------------------------------- + * 63 12 11 10 9 8 7 6 5 4 3 2 1 0 + */ +#define PSTATE_IG _AC(0x0000000000000800,UL) /* Interrupt Globals. */ +#define PSTATE_MG _AC(0x0000000000000400,UL) /* MMU Globals. */ +#define PSTATE_CLE _AC(0x0000000000000200,UL) /* Current Little Endian.*/ +#define PSTATE_TLE _AC(0x0000000000000100,UL) /* Trap Little Endian. */ +#define PSTATE_MM _AC(0x00000000000000c0,UL) /* Memory Model. */ +#define PSTATE_TSO _AC(0x0000000000000000,UL) /* MM: TotalStoreOrder */ +#define PSTATE_PSO _AC(0x0000000000000040,UL) /* MM: PartialStoreOrder */ +#define PSTATE_RMO _AC(0x0000000000000080,UL) /* MM: RelaxedMemoryOrder*/ +#define PSTATE_RED _AC(0x0000000000000020,UL) /* Reset Error Debug. */ +#define PSTATE_PEF _AC(0x0000000000000010,UL) /* Floating Point Enable.*/ +#define PSTATE_AM _AC(0x0000000000000008,UL) /* Address Mask. */ +#define PSTATE_PRIV _AC(0x0000000000000004,UL) /* Privilege. */ +#define PSTATE_IE _AC(0x0000000000000002,UL) /* Interrupt Enable. */ +#define PSTATE_AG _AC(0x0000000000000001,UL) /* Alternate Globals. */ + +/* The V9 TSTATE Register (with SpitFire and Linux extensions). + * + * --------------------------------------------------------------- + * | Resv | CCR | ASI | %pil | PSTATE | Resv | CWP | + * --------------------------------------------------------------- + * 63 40 39 32 31 24 23 20 19 8 7 5 4 0 + */ +#define TSTATE_CCR _AC(0x000000ff00000000,UL) /* Condition Codes. */ +#define TSTATE_XCC _AC(0x000000f000000000,UL) /* Condition Codes. */ +#define TSTATE_XNEG _AC(0x0000008000000000,UL) /* %xcc Negative. */ +#define TSTATE_XZERO _AC(0x0000004000000000,UL) /* %xcc Zero. */ +#define TSTATE_XOVFL _AC(0x0000002000000000,UL) /* %xcc Overflow. */ +#define TSTATE_XCARRY _AC(0x0000001000000000,UL) /* %xcc Carry. */ +#define TSTATE_ICC _AC(0x0000000f00000000,UL) /* Condition Codes. */ +#define TSTATE_INEG _AC(0x0000000800000000,UL) /* %icc Negative. */ +#define TSTATE_IZERO _AC(0x0000000400000000,UL) /* %icc Zero. */ +#define TSTATE_IOVFL _AC(0x0000000200000000,UL) /* %icc Overflow. */ +#define TSTATE_ICARRY _AC(0x0000000100000000,UL) /* %icc Carry. */ +#define TSTATE_ASI _AC(0x00000000ff000000,UL) /* AddrSpace ID. */ +#define TSTATE_PIL _AC(0x0000000000f00000,UL) /* %pil (Linux traps)*/ +#define TSTATE_PSTATE _AC(0x00000000000fff00,UL) /* PSTATE. */ +#define TSTATE_IG _AC(0x0000000000080000,UL) /* Interrupt Globals.*/ +#define TSTATE_MG _AC(0x0000000000040000,UL) /* MMU Globals. */ +#define TSTATE_CLE _AC(0x0000000000020000,UL) /* CurrLittleEndian. */ +#define TSTATE_TLE _AC(0x0000000000010000,UL) /* TrapLittleEndian. */ +#define TSTATE_MM _AC(0x000000000000c000,UL) /* Memory Model. */ +#define TSTATE_TSO _AC(0x0000000000000000,UL) /* MM: TSO */ +#define TSTATE_PSO _AC(0x0000000000004000,UL) /* MM: PSO */ +#define TSTATE_RMO _AC(0x0000000000008000,UL) /* MM: RMO */ +#define TSTATE_RED _AC(0x0000000000002000,UL) /* Reset Error Debug.*/ +#define TSTATE_PEF _AC(0x0000000000001000,UL) /* FPU Enable. */ +#define TSTATE_AM _AC(0x0000000000000800,UL) /* Address Mask. */ +#define TSTATE_PRIV _AC(0x0000000000000400,UL) /* Privilege. */ +#define TSTATE_IE _AC(0x0000000000000200,UL) /* Interrupt Enable. */ +#define TSTATE_AG _AC(0x0000000000000100,UL) /* Alternate Globals.*/ +#define TSTATE_CWP _AC(0x000000000000001f,UL) /* Curr Win-Pointer. */ + +/* Floating-Point Registers State Register. + * + * -------------------------------- + * | Resv | FEF | DU | DL | + * -------------------------------- + * 63 3 2 1 0 + */ +#define FPRS_FEF _AC(0x0000000000000004,UL) /* FPU Enable. */ +#define FPRS_DU _AC(0x0000000000000002,UL) /* Dirty Upper. */ +#define FPRS_DL _AC(0x0000000000000001,UL) /* Dirty Lower. */ + +/* Version Register. + * + * ------------------------------------------------------ + * | MANUF | IMPL | MASK | Resv | MAXTL | Resv | MAXWIN | + * ------------------------------------------------------ + * 63 48 47 32 31 24 23 16 15 8 7 5 4 0 + */ +#define VERS_MANUF _AC(0xffff000000000000,UL) /* Manufacturer. */ +#define VERS_IMPL _AC(0x0000ffff00000000,UL) /* Implementation. */ +#define VERS_MASK _AC(0x00000000ff000000,UL) /* Mask Set Revision.*/ +#define VERS_MAXTL _AC(0x000000000000ff00,UL) /* Max Trap Level. */ +#define VERS_MAXWIN _AC(0x000000000000001f,UL) /* Max RegWindow Idx.*/ + +#endif /* !(_SPARC64_PSTATE_H) */ diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h new file mode 100644 index 000000000000..2d2b5a113d24 --- /dev/null +++ b/include/asm-sparc64/ptrace.h @@ -0,0 +1,297 @@ +/* $Id: ptrace.h,v 1.14 2002/02/09 19:49:32 davem Exp $ */ +#ifndef _SPARC64_PTRACE_H +#define _SPARC64_PTRACE_H + +#include <asm/pstate.h> + +/* This struct defines the way the registers are stored on the + * stack during a system call and basically all traps. + */ + +#ifndef __ASSEMBLY__ + +struct pt_regs { + unsigned long u_regs[16]; /* globals and ins */ + unsigned long tstate; + unsigned long tpc; + unsigned long tnpc; + unsigned int y; + unsigned int fprs; +}; + +struct pt_regs32 { + unsigned int psr; + unsigned int pc; + unsigned int npc; + unsigned int y; + unsigned int u_regs[16]; /* globals and ins */ +}; + +#define UREG_G0 0 +#define UREG_G1 1 +#define UREG_G2 2 +#define UREG_G3 3 +#define UREG_G4 4 +#define UREG_G5 5 +#define UREG_G6 6 +#define UREG_G7 7 +#define UREG_I0 8 +#define UREG_I1 9 +#define UREG_I2 10 +#define UREG_I3 11 +#define UREG_I4 12 +#define UREG_I5 13 +#define UREG_I6 14 +#define UREG_I7 15 +#define UREG_FP UREG_I6 +#define UREG_RETPC UREG_I7 + +/* A V9 register window */ +struct reg_window { + unsigned long locals[8]; + unsigned long ins[8]; +}; + +/* A 32-bit register window. */ +struct reg_window32 { + unsigned int locals[8]; + unsigned int ins[8]; +}; + +/* A V9 Sparc stack frame */ +struct sparc_stackf { + unsigned long locals[8]; + unsigned long ins[6]; + struct sparc_stackf *fp; + unsigned long callers_pc; + char *structptr; + unsigned long xargs[6]; + unsigned long xxargs[1]; +}; + +/* A 32-bit Sparc stack frame */ +struct sparc_stackf32 { + unsigned int locals[8]; + unsigned int ins[6]; + unsigned int fp; + unsigned int callers_pc; + unsigned int structptr; + unsigned int xargs[6]; + unsigned int xxargs[1]; +}; + +struct sparc_trapf { + unsigned long locals[8]; + unsigned long ins[8]; + unsigned long _unused; + struct pt_regs *regs; +}; + +#define TRACEREG_SZ sizeof(struct pt_regs) +#define STACKFRAME_SZ sizeof(struct sparc_stackf) + +#define TRACEREG32_SZ sizeof(struct pt_regs32) +#define STACKFRAME32_SZ sizeof(struct sparc_stackf32) + +#ifdef __KERNEL__ +#define force_successful_syscall_return() \ + set_thread_flag(TIF_SYSCALL_SUCCESS) +#define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV)) +#define instruction_pointer(regs) ((regs)->tpc) +#ifdef CONFIG_SMP +extern unsigned long profile_pc(struct pt_regs *); +#else +#define profile_pc(regs) instruction_pointer(regs) +#endif +extern void show_regs(struct pt_regs *); +#endif + +#else /* __ASSEMBLY__ */ +/* For assembly code. */ +#define TRACEREG_SZ 0xa0 +#define STACKFRAME_SZ 0xc0 + +#define TRACEREG32_SZ 0x50 +#define STACKFRAME32_SZ 0x60 +#endif + +#ifdef __KERNEL__ +#define STACK_BIAS 2047 +#endif + +/* These are for pt_regs. */ +#define PT_V9_G0 0x00 +#define PT_V9_G1 0x08 +#define PT_V9_G2 0x10 +#define PT_V9_G3 0x18 +#define PT_V9_G4 0x20 +#define PT_V9_G5 0x28 +#define PT_V9_G6 0x30 +#define PT_V9_G7 0x38 +#define PT_V9_I0 0x40 +#define PT_V9_I1 0x48 +#define PT_V9_I2 0x50 +#define PT_V9_I3 0x58 +#define PT_V9_I4 0x60 +#define PT_V9_I5 0x68 +#define PT_V9_I6 0x70 +#define PT_V9_FP PT_V9_I6 +#define PT_V9_I7 0x78 +#define PT_V9_TSTATE 0x80 +#define PT_V9_TPC 0x88 +#define PT_V9_TNPC 0x90 +#define PT_V9_Y 0x98 +#define PT_V9_FPRS 0x9c +#define PT_TSTATE PT_V9_TSTATE +#define PT_TPC PT_V9_TPC +#define PT_TNPC PT_V9_TNPC + +/* These for pt_regs32. */ +#define PT_PSR 0x0 +#define PT_PC 0x4 +#define PT_NPC 0x8 +#define PT_Y 0xc +#define PT_G0 0x10 +#define PT_WIM PT_G0 +#define PT_G1 0x14 +#define PT_G2 0x18 +#define PT_G3 0x1c +#define PT_G4 0x20 +#define PT_G5 0x24 +#define PT_G6 0x28 +#define PT_G7 0x2c +#define PT_I0 0x30 +#define PT_I1 0x34 +#define PT_I2 0x38 +#define PT_I3 0x3c +#define PT_I4 0x40 +#define PT_I5 0x44 +#define PT_I6 0x48 +#define PT_FP PT_I6 +#define PT_I7 0x4c + +/* Reg_window offsets */ +#define RW_V9_L0 0x00 +#define RW_V9_L1 0x08 +#define RW_V9_L2 0x10 +#define RW_V9_L3 0x18 +#define RW_V9_L4 0x20 +#define RW_V9_L5 0x28 +#define RW_V9_L6 0x30 +#define RW_V9_L7 0x38 +#define RW_V9_I0 0x40 +#define RW_V9_I1 0x48 +#define RW_V9_I2 0x50 +#define RW_V9_I3 0x58 +#define RW_V9_I4 0x60 +#define RW_V9_I5 0x68 +#define RW_V9_I6 0x70 +#define RW_V9_I7 0x78 + +#define RW_L0 0x00 +#define RW_L1 0x04 +#define RW_L2 0x08 +#define RW_L3 0x0c +#define RW_L4 0x10 +#define RW_L5 0x14 +#define RW_L6 0x18 +#define RW_L7 0x1c +#define RW_I0 0x20 +#define RW_I1 0x24 +#define RW_I2 0x28 +#define RW_I3 0x2c +#define RW_I4 0x30 +#define RW_I5 0x34 +#define RW_I6 0x38 +#define RW_I7 0x3c + +/* Stack_frame offsets */ +#define SF_V9_L0 0x00 +#define SF_V9_L1 0x08 +#define SF_V9_L2 0x10 +#define SF_V9_L3 0x18 +#define SF_V9_L4 0x20 +#define SF_V9_L5 0x28 +#define SF_V9_L6 0x30 +#define SF_V9_L7 0x38 +#define SF_V9_I0 0x40 +#define SF_V9_I1 0x48 +#define SF_V9_I2 0x50 +#define SF_V9_I3 0x58 +#define SF_V9_I4 0x60 +#define SF_V9_I5 0x68 +#define SF_V9_FP 0x70 +#define SF_V9_PC 0x78 +#define SF_V9_RETP 0x80 +#define SF_V9_XARG0 0x88 +#define SF_V9_XARG1 0x90 +#define SF_V9_XARG2 0x98 +#define SF_V9_XARG3 0xa0 +#define SF_V9_XARG4 0xa8 +#define SF_V9_XARG5 0xb0 +#define SF_V9_XXARG 0xb8 + +#define SF_L0 0x00 +#define SF_L1 0x04 +#define SF_L2 0x08 +#define SF_L3 0x0c +#define SF_L4 0x10 +#define SF_L5 0x14 +#define SF_L6 0x18 +#define SF_L7 0x1c +#define SF_I0 0x20 +#define SF_I1 0x24 +#define SF_I2 0x28 +#define SF_I3 0x2c +#define SF_I4 0x30 +#define SF_I5 0x34 +#define SF_FP 0x38 +#define SF_PC 0x3c +#define SF_RETP 0x40 +#define SF_XARG0 0x44 +#define SF_XARG1 0x48 +#define SF_XARG2 0x4c +#define SF_XARG3 0x50 +#define SF_XARG4 0x54 +#define SF_XARG5 0x58 +#define SF_XXARG 0x5c + +/* Stuff for the ptrace system call */ +#define PTRACE_SUNATTACH 10 +#define PTRACE_SUNDETACH 11 +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 +#define PTRACE_READDATA 16 +#define PTRACE_WRITEDATA 17 +#define PTRACE_READTEXT 18 +#define PTRACE_WRITETEXT 19 +#define PTRACE_GETFPAREGS 20 +#define PTRACE_SETFPAREGS 21 + +/* There are for debugging 64-bit processes, either from a 32 or 64 bit + * parent. Thus their complements are for debugging 32-bit processes only. + */ + +#define PTRACE_GETREGS64 22 +#define PTRACE_SETREGS64 23 +/* PTRACE_SYSCALL is 24 */ +#define PTRACE_GETFPREGS64 25 +#define PTRACE_SETFPREGS64 26 + +#define PTRACE_GETUCODE 29 /* stupid bsd-ism */ + +/* These are for 32-bit processes debugging 64-bit ones. + * Here addr and addr2 are passed in %g2 and %g3 respectively. + */ +#define PTRACE_PEEKTEXT64 (30 + PTRACE_PEEKTEXT) +#define PTRACE_POKETEXT64 (30 + PTRACE_POKETEXT) +#define PTRACE_PEEKDATA64 (30 + PTRACE_PEEKDATA) +#define PTRACE_POKEDATA64 (30 + PTRACE_POKEDATA) +#define PTRACE_READDATA64 (30 + PTRACE_READDATA) +#define PTRACE_WRITEDATA64 (30 + PTRACE_WRITEDATA) +#define PTRACE_READTEXT64 (30 + PTRACE_READTEXT) +#define PTRACE_WRITETEXT64 (30 + PTRACE_WRITETEXT) + +#endif /* !(_SPARC64_PTRACE_H) */ diff --git a/include/asm-sparc64/reg.h b/include/asm-sparc64/reg.h new file mode 100644 index 000000000000..fc68f90181b3 --- /dev/null +++ b/include/asm-sparc64/reg.h @@ -0,0 +1,56 @@ +/* $Id: reg.h,v 1.6 1999/09/06 08:22:10 jj Exp $ + * linux/asm-sparc64/reg.h + * Layout of the registers as expected by gdb on the Sparc + * we should replace the user.h definitions with those in + * this file, we don't even use the other + * -miguel + * + * The names of the structures, constants and aliases in this file + * have the same names as the sunos ones, some programs rely on these + * names (gdb for example). + * + */ + +#ifndef __SPARC64_REG_H +#define __SPARC64_REG_H + +struct regs { + unsigned long r_g1; + unsigned long r_g2; + unsigned long r_g3; + unsigned long r_g4; + unsigned long r_g5; + unsigned long r_g6; + unsigned long r_g7; + unsigned long r_o0; + unsigned long r_o1; + unsigned long r_o2; + unsigned long r_o3; + unsigned long r_o4; + unsigned long r_o5; + unsigned long r_o6; + unsigned long r_o7; + unsigned long __pad; + unsigned long r_tstate; + unsigned long r_tpc; + unsigned long r_tnpc; + unsigned int r_y; + unsigned int r_fprs; +}; + +#define FPU_REGS_TYPE unsigned int +#define FPU_FSR_TYPE unsigned long + +struct fp_status { + unsigned long fpu_fr[32]; + unsigned long Fpu_fsr; +}; + +struct fpu { + struct fp_status f_fpstatus; +}; + +#define fpu_regs f_fpstatus.fpu_fr +#define fpu_fsr f_fpstatus.Fpu_fsr + +#endif /* __SPARC64_REG_H */ diff --git a/include/asm-sparc64/resource.h b/include/asm-sparc64/resource.h new file mode 100644 index 000000000000..aa469795a6b0 --- /dev/null +++ b/include/asm-sparc64/resource.h @@ -0,0 +1,19 @@ +/* $Id: resource.h,v 1.8 2000/09/23 02:09:21 davem Exp $ + * resource.h: Resource definitions. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC64_RESOURCE_H +#define _SPARC64_RESOURCE_H + +/* + * These two resource limit IDs have a Sparc/Linux-specific ordering, + * the rest comes from the generic header: + */ +#define RLIMIT_NOFILE 6 /* max number of open files */ +#define RLIMIT_NPROC 7 /* max number of processes */ + +#include <asm-generic/resource.h> + +#endif /* !(_SPARC64_RESOURCE_H) */ diff --git a/include/asm-sparc64/rtc.h b/include/asm-sparc64/rtc.h new file mode 100644 index 000000000000..cb17334595c9 --- /dev/null +++ b/include/asm-sparc64/rtc.h @@ -0,0 +1,27 @@ +/* $Id: rtc.h,v 1.1 1996/12/26 14:22:35 davem Exp $ + * + * rtc.h: Definitions for access to the Mostek real time clock + * + * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu) + */ + +#ifndef _RTC_H +#define _RTC_H + +#include <linux/ioctl.h> + +struct rtc_time +{ + int sec; /* Seconds (0-59) */ + int min; /* Minutes (0-59) */ + int hour; /* Hour (0-23) */ + int dow; /* Day of the week (1-7) */ + int dom; /* Day of the month (1-31) */ + int month; /* Month of year (1-12) */ + int year; /* Year (0-99) */ +}; + +#define RTCGET _IOR('p', 20, struct rtc_time) +#define RTCSET _IOW('p', 21, struct rtc_time) + +#endif diff --git a/include/asm-sparc64/rwsem-const.h b/include/asm-sparc64/rwsem-const.h new file mode 100644 index 000000000000..a303c9d64d84 --- /dev/null +++ b/include/asm-sparc64/rwsem-const.h @@ -0,0 +1,12 @@ +/* rwsem-const.h: RW semaphore counter constants. */ +#ifndef _SPARC64_RWSEM_CONST_H +#define _SPARC64_RWSEM_CONST_H + +#define RWSEM_UNLOCKED_VALUE 0x00000000 +#define RWSEM_ACTIVE_BIAS 0x00000001 +#define RWSEM_ACTIVE_MASK 0x0000ffff +#define RWSEM_WAITING_BIAS 0xffff0000 +#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS +#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) + +#endif /* _SPARC64_RWSEM_CONST_H */ diff --git a/include/asm-sparc64/rwsem.h b/include/asm-sparc64/rwsem.h new file mode 100644 index 000000000000..bf2ae90ed3df --- /dev/null +++ b/include/asm-sparc64/rwsem.h @@ -0,0 +1,100 @@ +/* $Id: rwsem.h,v 1.5 2001/11/18 00:12:56 davem Exp $ + * rwsem.h: R/W semaphores implemented using CAS + * + * Written by David S. Miller (davem@redhat.com), 2001. + * Derived from asm-i386/rwsem.h + */ +#ifndef _SPARC64_RWSEM_H +#define _SPARC64_RWSEM_H + +#ifndef _LINUX_RWSEM_H +#error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead" +#endif + +#ifdef __KERNEL__ + +#include <linux/list.h> +#include <linux/spinlock.h> +#include <asm/rwsem-const.h> + +struct rwsem_waiter; + +struct rw_semaphore { + signed int count; + spinlock_t wait_lock; + struct list_head wait_list; +}; + +#define __RWSEM_INITIALIZER(name) \ +{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) } + +#define DECLARE_RWSEM(name) \ + struct rw_semaphore name = __RWSEM_INITIALIZER(name) + +static __inline__ void init_rwsem(struct rw_semaphore *sem) +{ + sem->count = RWSEM_UNLOCKED_VALUE; + spin_lock_init(&sem->wait_lock); + INIT_LIST_HEAD(&sem->wait_list); +} + +extern void __down_read(struct rw_semaphore *sem); +extern int __down_read_trylock(struct rw_semaphore *sem); +extern void __down_write(struct rw_semaphore *sem); +extern int __down_write_trylock(struct rw_semaphore *sem); +extern void __up_read(struct rw_semaphore *sem); +extern void __up_write(struct rw_semaphore *sem); +extern void __downgrade_write(struct rw_semaphore *sem); + +static __inline__ int rwsem_atomic_update(int delta, struct rw_semaphore *sem) +{ + int tmp = delta; + + __asm__ __volatile__( + "1:\tlduw [%2], %%g1\n\t" + "add %%g1, %1, %%g7\n\t" + "cas [%2], %%g1, %%g7\n\t" + "cmp %%g1, %%g7\n\t" + "bne,pn %%icc, 1b\n\t" + " membar #StoreLoad | #StoreStore\n\t" + "mov %%g7, %0\n\t" + : "=&r" (tmp) + : "0" (tmp), "r" (sem) + : "g1", "g7", "memory", "cc"); + + return tmp + delta; +} + +#define rwsem_atomic_add rwsem_atomic_update + +static __inline__ __u16 rwsem_cmpxchgw(struct rw_semaphore *sem, __u16 __old, __u16 __new) +{ + u32 old = (sem->count & 0xffff0000) | (u32) __old; + u32 new = (old & 0xffff0000) | (u32) __new; + u32 prev; + +again: + __asm__ __volatile__("cas [%2], %3, %0\n\t" + "membar #StoreLoad | #StoreStore" + : "=&r" (prev) + : "0" (new), "r" (sem), "r" (old) + : "memory"); + + /* To give the same semantics as x86 cmpxchgw, keep trying + * if only the upper 16-bits changed. + */ + if (prev != old && + ((prev & 0xffff) == (old & 0xffff))) + goto again; + + return prev & 0xffff; +} + +static __inline__ signed long rwsem_cmpxchg(struct rw_semaphore *sem, signed long old, signed long new) +{ + return cmpxchg(&sem->count,old,new); +} + +#endif /* __KERNEL__ */ + +#endif /* _SPARC64_RWSEM_H */ diff --git a/include/asm-sparc64/sbus.h b/include/asm-sparc64/sbus.h new file mode 100644 index 000000000000..48279e10f385 --- /dev/null +++ b/include/asm-sparc64/sbus.h @@ -0,0 +1,122 @@ +/* $Id: sbus.h,v 1.14 2000/02/18 13:50:55 davem Exp $ + * sbus.h: Defines for the Sun SBus. + * + * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com) + */ + +#ifndef _SPARC64_SBUS_H +#define _SPARC64_SBUS_H + +#include <linux/dma-mapping.h> +#include <linux/ioport.h> + +#include <asm/oplib.h> +#include <asm/iommu.h> +#include <asm/scatterlist.h> + +/* We scan which devices are on the SBus using the PROM node device + * tree. SBus devices are described in two different ways. You can + * either get an absolute address at which to access the device, or + * you can get a SBus 'slot' number and an offset within that slot. + */ + +/* The base address at which to calculate device OBIO addresses. */ +#define SUN_SBUS_BVADDR 0x00000000 +#define SBUS_OFF_MASK 0x0fffffff + +/* These routines are used to calculate device address from slot + * numbers + offsets, and vice versa. + */ + +static __inline__ unsigned long sbus_devaddr(int slotnum, unsigned long offset) +{ + return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<28)+(offset)); +} + +static __inline__ int sbus_dev_slot(unsigned long dev_addr) +{ + return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>28); +} + +struct sbus_bus; + +/* Linux SBUS device tables */ +struct sbus_dev { + struct sbus_bus *bus; /* Our toplevel parent SBUS */ + struct sbus_dev *next; /* Chain of siblings */ + struct sbus_dev *child; /* Chain of children */ + struct sbus_dev *parent;/* Parent device if not toplevel*/ + int prom_node; /* OBP node of this device */ + char prom_name[64]; /* OBP device name property */ + int slot; /* SBUS slot number */ + + struct resource resource[PROMREG_MAX]; + + struct linux_prom_registers reg_addrs[PROMREG_MAX]; + int num_registers, ranges_applied; + + struct linux_prom_ranges device_ranges[PROMREG_MAX]; + int num_device_ranges; + + unsigned int irqs[4]; + int num_irqs; +}; + +/* This struct describes the SBus(s) found on this machine. */ +struct sbus_bus { + void *iommu; /* Opaque IOMMU cookie */ + struct sbus_dev *devices; /* Tree of SBUS devices */ + struct sbus_bus *next; /* Next SBUS in system */ + int prom_node; /* OBP node of SBUS */ + char prom_name[64]; /* Usually "sbus" or "sbi" */ + int clock_freq; + + struct linux_prom_ranges sbus_ranges[PROMREG_MAX]; + int num_sbus_ranges; + + int portid; + void *starfire_cookie; +}; + +extern struct sbus_bus *sbus_root; + +/* Device probing routines could find these handy */ +#define for_each_sbus(bus) \ + for((bus) = sbus_root; (bus); (bus)=(bus)->next) + +#define for_each_sbusdev(device, bus) \ + for((device) = (bus)->devices; (device); (device)=(device)->next) + +#define for_all_sbusdev(device, bus) \ + for ((bus) = sbus_root; (bus); (bus) = (bus)->next) \ + for ((device) = (bus)->devices; (device); (device) = (device)->next) + +/* Driver DVMA interfaces. */ +#define sbus_can_dma_64bit(sdev) (1) +#define sbus_can_burst64(sdev) (1) +extern void sbus_set_sbus64(struct sbus_dev *, int); + +/* These yield IOMMU mappings in consistent mode. */ +extern void *sbus_alloc_consistent(struct sbus_dev *, size_t, dma_addr_t *dma_addrp); +extern void sbus_free_consistent(struct sbus_dev *, size_t, void *, dma_addr_t); + +#define SBUS_DMA_BIDIRECTIONAL DMA_BIDIRECTIONAL +#define SBUS_DMA_TODEVICE DMA_TO_DEVICE +#define SBUS_DMA_FROMDEVICE DMA_FROM_DEVICE +#define SBUS_DMA_NONE DMA_NONE + +/* All the rest use streaming mode mappings. */ +extern dma_addr_t sbus_map_single(struct sbus_dev *, void *, size_t, int); +extern void sbus_unmap_single(struct sbus_dev *, dma_addr_t, size_t, int); +extern int sbus_map_sg(struct sbus_dev *, struct scatterlist *, int, int); +extern void sbus_unmap_sg(struct sbus_dev *, struct scatterlist *, int, int); + +/* Finally, allow explicit synchronization of streamable mappings. */ +extern void sbus_dma_sync_single_for_cpu(struct sbus_dev *, dma_addr_t, size_t, int); +#define sbus_dma_sync_single sbus_dma_sync_single_for_cpu +extern void sbus_dma_sync_single_for_device(struct sbus_dev *, dma_addr_t, size_t, int); +extern void sbus_dma_sync_sg_for_cpu(struct sbus_dev *, struct scatterlist *, int, int); +#define sbus_dma_sync_sg sbus_dma_sync_sg_for_cpu +extern void sbus_dma_sync_sg_for_device(struct sbus_dev *, struct scatterlist *, int, int); + +#endif /* !(_SPARC64_SBUS_H) */ diff --git a/include/asm-sparc64/scatterlist.h b/include/asm-sparc64/scatterlist.h new file mode 100644 index 000000000000..ec4f3c63fe98 --- /dev/null +++ b/include/asm-sparc64/scatterlist.h @@ -0,0 +1,22 @@ +/* $Id: scatterlist.h,v 1.11 2001/12/17 07:05:15 davem Exp $ */ +#ifndef _SPARC64_SCATTERLIST_H +#define _SPARC64_SCATTERLIST_H + +#include <asm/page.h> + +struct scatterlist { + struct page *page; + unsigned int offset; + + unsigned int length; + + dma_addr_t dma_address; + __u32 dma_length; +}; + +#define sg_dma_address(sg) ((sg)->dma_address) +#define sg_dma_len(sg) ((sg)->dma_length) + +#define ISA_DMA_THRESHOLD (~0UL) + +#endif /* !(_SPARC64_SCATTERLIST_H) */ diff --git a/include/asm-sparc64/sections.h b/include/asm-sparc64/sections.h new file mode 100644 index 000000000000..3f4b9fdc28d0 --- /dev/null +++ b/include/asm-sparc64/sections.h @@ -0,0 +1,9 @@ +#ifndef _SPARC64_SECTIONS_H +#define _SPARC64_SECTIONS_H + +/* nothing to see, move along */ +#include <asm-generic/sections.h> + +extern char _start[]; + +#endif diff --git a/include/asm-sparc64/segment.h b/include/asm-sparc64/segment.h new file mode 100644 index 000000000000..b03e709fc945 --- /dev/null +++ b/include/asm-sparc64/segment.h @@ -0,0 +1,6 @@ +#ifndef __SPARC64_SEGMENT_H +#define __SPARC64_SEGMENT_H + +/* Only here because we have some old header files that expect it.. */ + +#endif diff --git a/include/asm-sparc64/semaphore.h b/include/asm-sparc64/semaphore.h new file mode 100644 index 000000000000..7419dd88b49e --- /dev/null +++ b/include/asm-sparc64/semaphore.h @@ -0,0 +1,57 @@ +#ifndef _SPARC64_SEMAPHORE_H +#define _SPARC64_SEMAPHORE_H + +/* These are actually reasonable on the V9. + * + * See asm-ppc/semaphore.h for implementation commentary, + * only sparc64 specific issues are commented here. + */ +#ifdef __KERNEL__ + +#include <asm/atomic.h> +#include <asm/system.h> +#include <linux/wait.h> +#include <linux/rwsem.h> + +struct semaphore { + atomic_t count; + wait_queue_head_t wait; +}; + +#define __SEMAPHORE_INITIALIZER(name, count) \ + { ATOMIC_INIT(count), \ + __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) } + +#define __MUTEX_INITIALIZER(name) \ + __SEMAPHORE_INITIALIZER(name, 1) + +#define __DECLARE_SEMAPHORE_GENERIC(name, count) \ + struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) + +#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) +#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0) + +static inline void sema_init (struct semaphore *sem, int val) +{ + atomic_set(&sem->count, val); + init_waitqueue_head(&sem->wait); +} + +static inline void init_MUTEX (struct semaphore *sem) +{ + sema_init(sem, 1); +} + +static inline void init_MUTEX_LOCKED (struct semaphore *sem) +{ + sema_init(sem, 0); +} + +extern void up(struct semaphore *sem); +extern void down(struct semaphore *sem); +extern int down_trylock(struct semaphore *sem); +extern int down_interruptible(struct semaphore *sem); + +#endif /* __KERNEL__ */ + +#endif /* !(_SPARC64_SEMAPHORE_H) */ diff --git a/include/asm-sparc64/sembuf.h b/include/asm-sparc64/sembuf.h new file mode 100644 index 000000000000..99f04e4e288c --- /dev/null +++ b/include/asm-sparc64/sembuf.h @@ -0,0 +1,22 @@ +#ifndef _SPARC64_SEMBUF_H +#define _SPARC64_SEMBUF_H + +/* + * The semid64_ds structure for sparc64 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 2 miscellaneous 64-bit values + */ + +struct semid64_ds { + struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ + __kernel_time_t sem_otime; /* last semop time */ + __kernel_time_t sem_ctime; /* last change time */ + unsigned long sem_nsems; /* no. of semaphores in array */ + unsigned long __unused1; + unsigned long __unused2; +}; + +#endif /* _SPARC64_SEMBUF_H */ diff --git a/include/asm-sparc64/setup.h b/include/asm-sparc64/setup.h new file mode 100644 index 000000000000..b356ee2cda92 --- /dev/null +++ b/include/asm-sparc64/setup.h @@ -0,0 +1,10 @@ +/* + * Just a place holder. + */ + +#ifndef _SPARC64_SETUP_H +#define _SPARC64_SETUP_H + +#define COMMAND_LINE_SIZE 256 + +#endif /* _SPARC64_SETUP_H */ diff --git a/include/asm-sparc64/sfp-machine.h b/include/asm-sparc64/sfp-machine.h new file mode 100644 index 000000000000..5015bb8d6c32 --- /dev/null +++ b/include/asm-sparc64/sfp-machine.h @@ -0,0 +1,91 @@ +/* Machine-dependent software floating-point definitions. + Sparc64 kernel version. + Copyright (C) 1997,1998,1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Richard Henderson (rth@cygnus.com), + Jakub Jelinek (jj@ultra.linux.cz) and + David S. Miller (davem@redhat.com). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _SFP_MACHINE_H +#define _SFP_MACHINE_H + +#define _FP_W_TYPE_SIZE 64 +#define _FP_W_TYPE unsigned long +#define _FP_WS_TYPE signed long +#define _FP_I_TYPE long + +#define _FP_MUL_MEAT_S(R,X,Y) \ + _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y) +#define _FP_MUL_MEAT_D(R,X,Y) \ + _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) +#define _FP_MUL_MEAT_Q(R,X,Y) \ + _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) + +#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm) +#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y) +#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y) + +#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1) +#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1) +#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1 +#define _FP_NANSIGN_S 0 +#define _FP_NANSIGN_D 0 +#define _FP_NANSIGN_Q 0 + +#define _FP_KEEPNANFRACP 1 + +/* If one NaN is signaling and the other is not, + * we choose that one, otherwise we choose X. + */ +/* For _Qp_* and _Q_*, this should prefer X, for + * CPU instruction emulation this should prefer Y. + * (see SPAMv9 B.2.2 section). + */ +#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ + do { \ + if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs) \ + && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \ + { \ + R##_s = X##_s; \ + _FP_FRAC_COPY_##wc(R,X); \ + } \ + else \ + { \ + R##_s = Y##_s; \ + _FP_FRAC_COPY_##wc(R,Y); \ + } \ + R##_c = FP_CLS_NAN; \ + } while (0) + +/* Obtain the current rounding mode. */ +#ifndef FP_ROUNDMODE +#define FP_ROUNDMODE ((current_thread_info()->xfsr[0] >> 30) & 0x3) +#endif + +/* Exception flags. */ +#define FP_EX_INVALID (1 << 4) +#define FP_EX_OVERFLOW (1 << 3) +#define FP_EX_UNDERFLOW (1 << 2) +#define FP_EX_DIVZERO (1 << 1) +#define FP_EX_INEXACT (1 << 0) + +#define FP_HANDLE_EXCEPTIONS return _fex + +#define FP_INHIBIT_RESULTS ((current_thread_info()->xfsr[0] >> 23) & _fex) + +#endif diff --git a/include/asm-sparc64/shmbuf.h b/include/asm-sparc64/shmbuf.h new file mode 100644 index 000000000000..61c2ef42eba3 --- /dev/null +++ b/include/asm-sparc64/shmbuf.h @@ -0,0 +1,38 @@ +#ifndef _SPARC64_SHMBUF_H +#define _SPARC64_SHMBUF_H + +/* + * The shmid64_ds structure for sparc64 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 2 miscellaneous 64-bit values + */ + +struct shmid64_ds { + struct ipc64_perm shm_perm; /* operation perms */ + __kernel_time_t shm_atime; /* last attach time */ + __kernel_time_t shm_dtime; /* last detach time */ + __kernel_time_t shm_ctime; /* last change time */ + size_t shm_segsz; /* size of segment (bytes) */ + __kernel_pid_t shm_cpid; /* pid of creator */ + __kernel_pid_t shm_lpid; /* pid of last operator */ + unsigned long shm_nattch; /* no. of current attaches */ + unsigned long __unused1; + unsigned long __unused2; +}; + +struct shminfo64 { + unsigned long shmmax; + unsigned long shmmin; + unsigned long shmmni; + unsigned long shmseg; + unsigned long shmall; + unsigned long __unused1; + unsigned long __unused2; + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _SPARC64_SHMBUF_H */ diff --git a/include/asm-sparc64/shmparam.h b/include/asm-sparc64/shmparam.h new file mode 100644 index 000000000000..8c66fded8a32 --- /dev/null +++ b/include/asm-sparc64/shmparam.h @@ -0,0 +1,11 @@ +/* $Id: shmparam.h,v 1.5 2001/09/24 21:17:57 kanoj Exp $ */ +#ifndef _ASMSPARC64_SHMPARAM_H +#define _ASMSPARC64_SHMPARAM_H + +#include <asm/spitfire.h> + +#define __ARCH_FORCE_SHMLBA 1 +/* attach addr a multiple of this */ +#define SHMLBA ((PAGE_SIZE > L1DCACHE_SIZE) ? PAGE_SIZE : L1DCACHE_SIZE) + +#endif /* _ASMSPARC64_SHMPARAM_H */ diff --git a/include/asm-sparc64/sigcontext.h b/include/asm-sparc64/sigcontext.h new file mode 100644 index 000000000000..d8073373db8c --- /dev/null +++ b/include/asm-sparc64/sigcontext.h @@ -0,0 +1,88 @@ +/* $Id: sigcontext.h,v 1.12 1999/09/06 08:22:09 jj Exp $ */ +#ifndef __SPARC64_SIGCONTEXT_H +#define __SPARC64_SIGCONTEXT_H + +#ifdef __KERNEL__ +#include <asm/ptrace.h> +#endif + +#ifndef __ASSEMBLY__ + +#ifdef __KERNEL__ + +#define __SUNOS_MAXWIN 31 + +/* This is what SunOS does, so shall I unless we use new 32bit signals or rt signals. */ +struct sigcontext32 { + int sigc_onstack; /* state to restore */ + int sigc_mask; /* sigmask to restore */ + int sigc_sp; /* stack pointer */ + int sigc_pc; /* program counter */ + int sigc_npc; /* next program counter */ + int sigc_psr; /* for condition codes etc */ + int sigc_g1; /* User uses these two registers */ + int sigc_o0; /* within the trampoline code. */ + + /* Now comes information regarding the users window set + * at the time of the signal. + */ + int sigc_oswins; /* outstanding windows */ + + /* stack ptrs for each regwin buf */ + unsigned sigc_spbuf[__SUNOS_MAXWIN]; + + /* Windows to restore after signal */ + struct reg_window32 sigc_wbuf[__SUNOS_MAXWIN]; +}; + +#endif + +#ifdef __KERNEL__ + +/* This is what we use for 32bit new non-rt signals. */ + +typedef struct { + struct { + unsigned int psr; + unsigned int pc; + unsigned int npc; + unsigned int y; + unsigned int u_regs[16]; /* globals and ins */ + } si_regs; + int si_mask; +} __siginfo32_t; + +#endif + +typedef struct { + unsigned int si_float_regs [64]; + unsigned long si_fsr; + unsigned long si_gsr; + unsigned long si_fprs; +} __siginfo_fpu_t; + +/* This is what SunOS doesn't, so we have to write this alone + and do it properly. */ +struct sigcontext { + /* The size of this array has to match SI_MAX_SIZE from siginfo.h */ + char sigc_info[128]; + struct { + unsigned long u_regs[16]; /* globals and ins */ + unsigned long tstate; + unsigned long tpc; + unsigned long tnpc; + unsigned int y; + unsigned int fprs; + } sigc_regs; + __siginfo_fpu_t * sigc_fpu_save; + struct { + void * ss_sp; + int ss_flags; + unsigned long ss_size; + } sigc_stack; + unsigned long sigc_mask; +}; + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(__SPARC64_SIGCONTEXT_H) */ diff --git a/include/asm-sparc64/siginfo.h b/include/asm-sparc64/siginfo.h new file mode 100644 index 000000000000..7160449e7cab --- /dev/null +++ b/include/asm-sparc64/siginfo.h @@ -0,0 +1,35 @@ +#ifndef _SPARC64_SIGINFO_H +#define _SPARC64_SIGINFO_H + +#define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3) + +#define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 4) + +#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) +#define __ARCH_SI_TRAPNO +#define __ARCH_SI_BAND_T int + +#include <asm-generic/siginfo.h> + +#ifdef __KERNEL__ + +#include <linux/config.h> +#include <linux/compat.h> + +#ifdef CONFIG_COMPAT + +struct compat_siginfo; + +#endif /* CONFIG_COMPAT */ + +#endif /* __KERNEL__ */ + +#define SI_NOINFO 32767 /* no information in siginfo_t */ + +/* + * SIGEMT si_codes + */ +#define EMT_TAGOVF (__SI_FAULT|1) /* tag overflow */ +#define NSIGEMT 1 + +#endif diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h new file mode 100644 index 000000000000..6428e366c38c --- /dev/null +++ b/include/asm-sparc64/signal.h @@ -0,0 +1,276 @@ +/* $Id: signal.h,v 1.9 1999/09/06 08:22:11 jj Exp $ */ +#ifndef _ASMSPARC64_SIGNAL_H +#define _ASMSPARC64_SIGNAL_H + +#include <asm/sigcontext.h> + +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ +#include <linux/config.h> +#include <linux/personality.h> +#include <linux/types.h> +#include <linux/compat.h> +#endif +#endif + +/* On the Sparc the signal handlers get passed a 'sub-signal' code + * for certain signal types, which we document here. + */ +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SUBSIG_STACK 0 +#define SUBSIG_ILLINST 2 +#define SUBSIG_PRIVINST 3 +#define SUBSIG_BADTRAP(t) (0x80 + (t)) + +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 + +#define SIGEMT 7 +#define SUBSIG_TAG 10 + +#define SIGFPE 8 +#define SUBSIG_FPDISABLED 0x400 +#define SUBSIG_FPERROR 0x404 +#define SUBSIG_FPINTOVFL 0x001 +#define SUBSIG_FPSTSIG 0x002 +#define SUBSIG_IDIVZERO 0x014 +#define SUBSIG_FPINEXACT 0x0c4 +#define SUBSIG_FPDIVZERO 0x0c8 +#define SUBSIG_FPUNFLOW 0x0cc +#define SUBSIG_FPOPERROR 0x0d0 +#define SUBSIG_FPOVFLOW 0x0d4 + +#define SIGKILL 9 +#define SIGBUS 10 +#define SUBSIG_BUSTIMEOUT 1 +#define SUBSIG_ALIGNMENT 2 +#define SUBSIG_MISCERROR 5 + +#define SIGSEGV 11 +#define SUBSIG_NOMAPPING 3 +#define SUBSIG_PROTECTION 4 +#define SUBSIG_SEGERROR 5 + +#define SIGSYS 12 + +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGURG 16 + +/* SunOS values which deviate from the Linux/i386 ones */ +#define SIGSTOP 17 +#define SIGTSTP 18 +#define SIGCONT 19 +#define SIGCHLD 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGIO 23 +#define SIGPOLL SIGIO /* SysV name for SIGIO */ +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGLOST 29 +#define SIGPWR SIGLOST +#define SIGUSR1 30 +#define SIGUSR2 31 + +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +#define __OLD_NSIG 32 +#define __NEW_NSIG 64 +#define _NSIG_BPW 64 +#define _NSIG_WORDS (__NEW_NSIG / _NSIG_BPW) + +#define SIGRTMIN 32 +#define SIGRTMAX __NEW_NSIG + +#if defined(__KERNEL__) || defined(__WANT_POSIX1B_SIGNALS__) +#define _NSIG __NEW_NSIG +#define __new_sigset_t sigset_t +#define __new_sigaction sigaction +#define __new_sigaction32 sigaction32 +#define __old_sigset_t old_sigset_t +#define __old_sigaction old_sigaction +#define __old_sigaction32 old_sigaction32 +#else +#define _NSIG __OLD_NSIG +#define NSIG _NSIG +#define __old_sigset_t sigset_t +#define __old_sigaction sigaction +#define __old_sigaction32 sigaction32 +#endif + +#ifndef __ASSEMBLY__ + +typedef unsigned long __old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} __new_sigset_t; + +/* A SunOS sigstack */ +struct sigstack { + /* XXX 32-bit pointers pinhead XXX */ + char *the_stack; + int cur_status; +}; + +/* Sigvec flags */ +#define _SV_SSTACK 1u /* This signal handler should use sig-stack */ +#define _SV_INTR 2u /* Sig return should not restart system call */ +#define _SV_RESET 4u /* Set handler to SIG_DFL upon taken signal */ +#define _SV_IGNCHILD 8u /* Do not send SIGCHLD */ + +/* + * sa_flags values: SA_STACK is not currently supported, but will allow the + * usage of signal stacks by using the (now obsolete) sa_restorer field in + * the sigaction structure as a stack pointer. This is now possible due to + * 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 _SV_IGNCHILD +#define SA_STACK _SV_SSTACK +#define SA_ONSTACK _SV_SSTACK +#define SA_RESTART _SV_INTR +#define SA_ONESHOT _SV_RESET +#define SA_INTERRUPT 0x10u +#define SA_NOMASK 0x20u +#define SA_SHIRQ 0x40u +#define SA_NOCLDWAIT 0x100u +#define SA_SIGINFO 0x200u + + +#define SIG_BLOCK 0x01 /* for blocking signals */ +#define SIG_UNBLOCK 0x02 /* for unblocking signals */ +#define SIG_SETMASK 0x04 /* for setting the signal mask */ + +/* + * sigaltstack controls + */ +#define SS_ONSTACK 1 +#define SS_DISABLE 2 + +#define MINSIGSTKSZ 4096 +#define SIGSTKSZ 16384 + +#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. + * + * DJHR + * SA_STATIC_ALLOC is used for the SPARC system to indicate that this + * interrupt handler's irq structure should be statically allocated + * by the request_irq routine. + * The alternative is that arch/sparc/kernel/irq.c has carnal knowledge + * of interrupt usage and that sucks. Also without a flag like this + * it may be possible for the free_irq routine to attempt to free + * statically allocated data.. which is NOT GOOD. + * + */ +#define SA_PROBE SA_ONESHOT +#define SA_SAMPLE_RANDOM SA_RESTART +#define SA_STATIC_ALLOC 0x80 +#endif + +/* Type of a signal handler. */ +#ifdef __KERNEL__ +typedef void __signalfn_t(int); +typedef __signalfn_t __user *__sighandler_t; + +typedef void __restorefn_t(void); +typedef __restorefn_t __user *__sigrestore_t; +#else +typedef void (*__sighandler_t)(int); +typedef void (*__sigrestore_t)(void); +#endif + +#define SIG_DFL ((__sighandler_t)0) /* default signal handling */ +#define SIG_IGN ((__sighandler_t)1) /* ignore signal */ +#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ + +struct __new_sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + __sigrestore_t sa_restorer; /* not used by Linux/SPARC yet */ + __new_sigset_t sa_mask; +}; + +#ifdef __KERNEL__ + +#ifdef CONFIG_COMPAT +struct __new_sigaction32 { + unsigned sa_handler; + unsigned int sa_flags; + unsigned sa_restorer; /* not used by Linux/SPARC yet */ + compat_sigset_t sa_mask; +}; +#endif + +struct k_sigaction { + struct __new_sigaction sa; + void __user *ka_restorer; +}; +#endif + +struct __old_sigaction { + __sighandler_t sa_handler; + __old_sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); /* not used by Linux/SPARC yet */ +}; + +#ifdef __KERNEL__ + +#ifdef CONFIG_COMPAT +struct __old_sigaction32 { + unsigned sa_handler; + compat_old_sigset_t sa_mask; + unsigned int sa_flags; + unsigned sa_restorer; /* not used by Linux/SPARC yet */ +}; +#endif + +#endif + +typedef struct sigaltstack { + void __user *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +#ifdef __KERNEL__ + +#ifdef CONFIG_COMPAT +typedef struct sigaltstack32 { + u32 ss_sp; + int ss_flags; + compat_size_t ss_size; +} stack_t32; +#endif + +struct signal_deliver_cookie { + int restart_syscall; + unsigned long orig_i0; +}; + +struct pt_regs; +extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie); + +#endif /* !(__KERNEL__) */ + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(_ASMSPARC64_SIGNAL_H) */ diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h new file mode 100644 index 000000000000..5e3e06d908fe --- /dev/null +++ b/include/asm-sparc64/smp.h @@ -0,0 +1,75 @@ +/* smp.h: Sparc64 specific SMP stuff. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC64_SMP_H +#define _SPARC64_SMP_H + +#include <linux/config.h> +#include <linux/threads.h> +#include <asm/asi.h> +#include <asm/starfire.h> +#include <asm/spitfire.h> + +#ifndef __ASSEMBLY__ + +#include <linux/cpumask.h> +#include <linux/cache.h> + +#endif /* !(__ASSEMBLY__) */ + +#ifdef CONFIG_SMP + +#ifndef __ASSEMBLY__ + +/* + * Private routines/data + */ + +#include <asm/bitops.h> +#include <asm/atomic.h> + +extern cpumask_t phys_cpu_present_map; +#define cpu_possible_map phys_cpu_present_map + +/* + * General functions that each host system must provide. + */ + +static __inline__ int hard_smp_processor_id(void) +{ + if (tlb_type == cheetah || tlb_type == cheetah_plus) { + unsigned long cfg, ver; + __asm__ __volatile__("rdpr %%ver, %0" : "=r" (ver)); + if ((ver >> 32) == 0x003e0016) { + __asm__ __volatile__("ldxa [%%g0] %1, %0" + : "=r" (cfg) + : "i" (ASI_JBUS_CONFIG)); + return ((cfg >> 17) & 0x1f); + } else { + __asm__ __volatile__("ldxa [%%g0] %1, %0" + : "=r" (cfg) + : "i" (ASI_SAFARI_CONFIG)); + return ((cfg >> 17) & 0x3ff); + } + } else if (this_is_starfire != 0) { + return starfire_hard_smp_processor_id(); + } else { + unsigned long upaconfig; + __asm__ __volatile__("ldxa [%%g0] %1, %0" + : "=r" (upaconfig) + : "i" (ASI_UPA_CONFIG)); + return ((upaconfig >> 17) & 0x1f); + } +} + +#define smp_processor_id() (current_thread_info()->cpu) + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(CONFIG_SMP) */ + +#define NO_PROC_ID 0xFF + +#endif /* !(_SPARC64_SMP_H) */ diff --git a/include/asm-sparc64/socket.h b/include/asm-sparc64/socket.h new file mode 100644 index 000000000000..865547a23908 --- /dev/null +++ b/include/asm-sparc64/socket.h @@ -0,0 +1,55 @@ +/* $Id: socket.h,v 1.10 2001/06/13 16:25:03 davem Exp $ */ +#ifndef _ASM_SOCKET_H +#define _ASM_SOCKET_H + +#include <asm/sockios.h> + +/* For setsockopt(2) */ +#define SOL_SOCKET 0xffff + +#define SO_DEBUG 0x0001 +#define SO_PASSCRED 0x0002 +#define SO_REUSEADDR 0x0004 +#define SO_KEEPALIVE 0x0008 +#define SO_DONTROUTE 0x0010 +#define SO_BROADCAST 0x0020 +#define SO_PEERCRED 0x0040 +#define SO_LINGER 0x0080 +#define SO_OOBINLINE 0x0100 +/* To add :#define SO_REUSEPORT 0x0200 */ +#define SO_BSDCOMPAT 0x0400 +#define SO_RCVLOWAT 0x0800 +#define SO_SNDLOWAT 0x1000 +#define SO_RCVTIMEO 0x2000 +#define SO_SNDTIMEO 0x4000 +#define SO_ACCEPTCONN 0x8000 + +/* wha!??? */ +#define SO_DONTLINGER (~SO_LINGER) /* Older SunOS compat. hack */ + +#define SO_SNDBUF 0x1001 +#define SO_RCVBUF 0x1002 +#define SO_ERROR 0x1007 +#define SO_TYPE 0x1008 + +/* Linux specific, keep the same. */ +#define SO_NO_CHECK 0x000b +#define SO_PRIORITY 0x000c + +#define SO_BINDTODEVICE 0x000d + +#define SO_ATTACH_FILTER 0x001a +#define SO_DETACH_FILTER 0x001b + +#define SO_PEERNAME 0x001c +#define SO_TIMESTAMP 0x001d +#define SCM_TIMESTAMP SO_TIMESTAMP + +#define SO_PEERSEC 0x001e + +/* Security levels - as per NRL IPv6 - don't actually do anything */ +#define SO_SECURITY_AUTHENTICATION 0x5001 +#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 +#define SO_SECURITY_ENCRYPTION_NETWORK 0x5004 + +#endif /* _ASM_SOCKET_H */ diff --git a/include/asm-sparc64/sockios.h b/include/asm-sparc64/sockios.h new file mode 100644 index 000000000000..6735bab4f39d --- /dev/null +++ b/include/asm-sparc64/sockios.h @@ -0,0 +1,13 @@ +#ifndef _ASM_SPARC64_SOCKIOS_H +#define _ASM_SPARC64_SOCKIOS_H + +/* Socket-level I/O control calls. */ +#define FIOSETOWN 0x8901 +#define SIOCSPGRP 0x8902 +#define FIOGETOWN 0x8903 +#define SIOCGPGRP 0x8904 +#define SIOCATMARK 0x8905 +#define SIOCGSTAMP 0x8906 /* Get stamp */ + +#endif /* !(_ASM_SPARC64_SOCKIOS_H) */ + diff --git a/include/asm-sparc64/solerrno.h b/include/asm-sparc64/solerrno.h new file mode 100644 index 000000000000..a2ea6fcf3446 --- /dev/null +++ b/include/asm-sparc64/solerrno.h @@ -0,0 +1,132 @@ +/* $Id: solerrno.h,v 1.1 1996/12/26 14:22:40 davem Exp $ + * solerrno.h: Solaris error return codes for compatibility. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC64_SOLERRNO_H +#define _SPARC64_SOLERRNO_H + +#define SOL_EPERM 1 /* Required superuser access perms */ +#define SOL_ENOENT 2 /* File or directory does not exist */ +#define SOL_ESRCH 3 /* Process did not exist */ +#define SOL_EINTR 4 /* System call was interrupted */ +#define SOL_EIO 5 /* An i/o error occurred */ +#define SOL_ENXIO 6 /* Device or Address does not exist */ +#define SOL_E2BIG 7 /* Too many arguments were given */ +#define SOL_ENOEXEC 8 /* Header of executable was munged */ +#define SOL_EBADF 9 /* Bogus file number */ +#define SOL_ECHILD 10 /* No children of process exist */ +#define SOL_EAGAIN 11 /* beep beep, "try again later" */ +#define SOL_ENOMEM 12 /* No memory available */ +#define SOL_EACCES 13 /* Access not allowed */ +#define SOL_EFAULT 14 /* Address passed was invalid */ +#define SOL_ENOTBLK 15 /* blkdev op on non-block device */ +#define SOL_EBUSY 16 /* Mounted device was busy */ +#define SOL_EEXIST 17 /* File specified already exists */ +#define SOL_EXDEV 18 /* Link request across diff devices */ +#define SOL_ENODEV 19 /* Device does not exist on system */ +#define SOL_ENOTDIR 20 /* Dir operation on non-directory */ +#define SOL_EISDIR 21 /* File was of directory type */ +#define SOL_EINVAL 22 /* Argument passed was invalid */ +#define SOL_ENFILE 23 /* No more room in file table */ +#define SOL_EMFILE 24 /* Proc has too many files open */ +#define SOL_ENOTTY 25 /* Ioctl was invalid for req device */ +#define SOL_ETXTBSY 26 /* Text file in busy state */ +#define SOL_EFBIG 27 /* Too big of a file for operation */ +#define SOL_ENOSPC 28 /* Disk is full */ +#define SOL_ESPIPE 29 /* Seek attempted on non-seeking dev*/ +#define SOL_EROFS 30 /* Write attempted on read-only fs */ +#define SOL_EMLINK 31 /* Too many links in file search */ +#define SOL_EPIPE 32 /* Call a plumber */ +#define SOL_EDOM 33 /* Argument was out of fct domain */ +#define SOL_ERANGE 34 /* Could not represent math result */ +#define SOL_ENOMSG 35 /* Message of req type doesn't exist */ +#define SOL_EIDRM 36 /* Identifier has been removed */ +#define SOL_ECHRNG 37 /* Req channel number out of range */ +#define SOL_EL2NSYNC 38 /* Could not sync at run level 2 */ +#define SOL_EL3HLT 39 /* Halted at run level 3 */ +#define SOL_EL3RST 40 /* Reset at run level 3 */ +#define SOL_ELNRNG 41 /* Out of range link number */ +#define SOL_EUNATCH 42 /* Driver for protocol not attached */ +#define SOL_ENOCSI 43 /* CSI structure not around */ +#define SOL_EL2HLT 44 /* Halted at run level 2 */ +#define SOL_EDEADLK 45 /* Deadlock condition detected */ +#define SOL_ENOLCK 46 /* Record locks unavailable */ +#define SOL_ECANCELED 47 /* Cancellation of oper. happened */ +#define SOL_ENOTSUP 48 /* Attempt of unsupported operation */ +#define SOL_EDQUOT 49 /* Users disk quota exceeded */ +#define SOL_EBADE 50 /* Invalid exchange */ +#define SOL_EBADR 51 /* Request descriptor was invalid */ +#define SOL_EXFULL 52 /* Full exchange */ +#define SOL_ENOANO 53 /* ano does not exist */ +#define SOL_EBADRQC 54 /* Req code was invalid */ +#define SOL_EBADSLT 55 /* Bad slot number */ +#define SOL_EDEADLOCK 56 /* Deadlock in fs error */ +#define SOL_EBFONT 57 /* Font file format invalid */ +/* YOW, I LOVE SYSV STREAMS!!!! */ +#define SOL_ENOSTR 60 /* Stream-op on non-stream dev */ +#define SOL_ENODATA 61 /* No data avail at this time */ +#define SOL_ETIME 62 /* Expiration of time occurred */ +#define SOL_ENOSR 63 /* Streams resources exhausted */ +#define SOL_ENONET 64 /* No network connected */ +#define SOL_ENOPKG 65 /* Non-installed package */ +#define SOL_EREMOTE 66 /* Object was on remote machine */ +#define SOL_ENOLINK 67 /* Cut link */ +#define SOL_EADV 68 /* Error in advertise */ +#define SOL_ESRMNT 69 /* Some magic srmount problem */ +#define SOL_ECOMM 70 /* During send, comm error occurred */ +#define SOL_EPROTO 71 /* Protocol botch */ +#define SOL_EMULTIHOP 74 /* Multihop attempted */ +#define SOL_EBADMSG 77 /* Message was unreadable */ +#define SOL_ENAMETOOLONG 78 /* Too long of a path name */ +#define SOL_EOVERFLOW 79 /* Data type too small for datum */ +#define SOL_ENOTUNIQ 80 /* Logical name was not unique */ +#define SOL_EBADFD 81 /* Op cannot be performed on fd */ +#define SOL_EREMCHG 82 /* Remote address is now different */ +#define SOL_ELIBACC 83 /* Shared lib could not be accessed */ +#define SOL_ELIBBAD 84 /* ShLib is corrupted in some way */ +#define SOL_ELIBSCN 85 /* A.out ShLib problems */ +#define SOL_ELIBMAX 86 /* Exceeded ShLib linkage limit */ +#define SOL_ELIBEXEC 87 /* Execution of ShLib attempted */ +#define SOL_EILSEQ 88 /* Bad byte sequence found */ +#define SOL_ENOSYS 89 /* Invalid filesystem operation */ +#define SOL_ELOOP 90 /* Detected loop in symbolic links */ +#define SOL_ERESTART 91 /* System call is restartable */ +#define SOL_ESTRPIPE 92 /* Do not sleep in head of stream */ +#define SOL_ENOTEMPTY 93 /* Rmdir of non-empty directory */ +#define SOL_EUSERS 94 /* Over abundance of users for ufs */ +#define SOL_ENOTSOCK 95 /* Sock-op on non-sock */ +#define SOL_EDESTADDRREQ 96 /* No dest addr given, but needed */ +#define SOL_EMSGSIZE 97 /* Msg too big */ +#define SOL_EPROTOTYPE 98 /* Bad socket protocol */ +#define SOL_ENOPROTOOPT 99 /* Unavailable protocol */ +#define SOL_EPROTONOSUPPORT 120 /* Unsupported protocol */ +#define SOL_ESOCKTNOSUPPORT 121 /* Unsupported socket type */ +#define SOL_EOPNOTSUPP 122 /* Unsupported sock-op */ +#define SOL_EPFNOSUPPORT 123 /* Unsupported protocol family */ +#define SOL_EAFNOSUPPORT 124 /* Unsup addr family for protocol */ +#define SOL_EADDRINUSE 125 /* Req addr is already in use */ +#define SOL_EADDRNOTAVAIL 126 /* Req addr not available right now */ +#define SOL_ENETDOWN 127 /* Your subnet is on fire */ +#define SOL_ENETUNREACH 128 /* Someone playing with gateway and */ + /* did not tell you he was going to */ +#define SOL_ENETRESET 129 /* Buy less-buggy ethernet cards */ +#define SOL_ECONNABORTED 130 /* Aborted connection due to sw */ +#define SOL_ECONNRESET 131 /* Your peers reset your connection */ +#define SOL_ENOBUFS 132 /* No buffer space available */ +#define SOL_EISCONN 133 /* Connect on already connected */ + /* socket attempted */ +#define SOL_ENOTCONN 134 /* Comm on non-connected socket */ +#define SOL_ESHUTDOWN 143 /* Op attempted after sock-shutdown */ +#define SOL_ETOOMANYREFS 144 /* Reference limit exceeded */ +#define SOL_ETIMEDOUT 145 /* Timed out connection */ +#define SOL_ECONNREFUSED 146 /* Connection refused by remote host*/ +#define SOL_EHOSTDOWN 147 /* Remote host is up in flames */ +#define SOL_EHOSTUNREACH 148 /* Make a left at Easton Ave..... */ +#define SOL_EWOULDBLOCK EAGAIN /* Just an alias */ +#define SOL_EALREADY 149 /* Operation is already occurring */ +#define SOL_EINPROGRESS 150 /* Operation is happening now */ +#define SOL_ESTALE 151 /* Fungus growth on NFS file handle */ + +#endif /* !(_SPARC64_SOLERRNO_H) */ diff --git a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h new file mode 100644 index 000000000000..11efa474865b --- /dev/null +++ b/include/asm-sparc64/spinlock.h @@ -0,0 +1,310 @@ +/* spinlock.h: 64-bit Sparc spinlock support. + * + * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef __SPARC64_SPINLOCK_H +#define __SPARC64_SPINLOCK_H + +#include <linux/config.h> +#include <linux/threads.h> /* For NR_CPUS */ + +#ifndef __ASSEMBLY__ + +/* To get debugging spinlocks which detect and catch + * deadlock situations, set CONFIG_DEBUG_SPINLOCK + * and rebuild your kernel. + */ + +/* All of these locking primitives are expected to work properly + * even in an RMO memory model, which currently is what the kernel + * runs in. + * + * There is another issue. Because we play games to save cycles + * in the non-contention case, we need to be extra careful about + * branch targets into the "spinning" code. They live in their + * own section, but the newer V9 branches have a shorter range + * than the traditional 32-bit sparc branch variants. The rule + * is that the branches that go into and out of the spinner sections + * must be pre-V9 branches. + */ + +#ifndef CONFIG_DEBUG_SPINLOCK + +typedef unsigned char spinlock_t; +#define SPIN_LOCK_UNLOCKED 0 + +#define spin_lock_init(lock) (*((unsigned char *)(lock)) = 0) +#define spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0) + +#define spin_unlock_wait(lock) \ +do { membar("#LoadLoad"); \ +} while(*((volatile unsigned char *)lock)) + +static inline void _raw_spin_lock(spinlock_t *lock) +{ + unsigned long tmp; + + __asm__ __volatile__( +"1: ldstub [%1], %0\n" +" brnz,pn %0, 2f\n" +" membar #StoreLoad | #StoreStore\n" +" .subsection 2\n" +"2: ldub [%1], %0\n" +" brnz,pt %0, 2b\n" +" membar #LoadLoad\n" +" ba,a,pt %%xcc, 1b\n" +" .previous" + : "=&r" (tmp) + : "r" (lock) + : "memory"); +} + +static inline int _raw_spin_trylock(spinlock_t *lock) +{ + unsigned long result; + + __asm__ __volatile__( +" ldstub [%1], %0\n" +" membar #StoreLoad | #StoreStore" + : "=r" (result) + : "r" (lock) + : "memory"); + + return (result == 0UL); +} + +static inline void _raw_spin_unlock(spinlock_t *lock) +{ + __asm__ __volatile__( +" membar #StoreStore | #LoadStore\n" +" stb %%g0, [%0]" + : /* No outputs */ + : "r" (lock) + : "memory"); +} + +static inline void _raw_spin_lock_flags(spinlock_t *lock, unsigned long flags) +{ + unsigned long tmp1, tmp2; + + __asm__ __volatile__( +"1: ldstub [%2], %0\n" +" brnz,pn %0, 2f\n" +" membar #StoreLoad | #StoreStore\n" +" .subsection 2\n" +"2: rdpr %%pil, %1\n" +" wrpr %3, %%pil\n" +"3: ldub [%2], %0\n" +" brnz,pt %0, 3b\n" +" membar #LoadLoad\n" +" ba,pt %%xcc, 1b\n" +" wrpr %1, %%pil\n" +" .previous" + : "=&r" (tmp1), "=&r" (tmp2) + : "r"(lock), "r"(flags) + : "memory"); +} + +#else /* !(CONFIG_DEBUG_SPINLOCK) */ + +typedef struct { + unsigned char lock; + unsigned int owner_pc, owner_cpu; +} spinlock_t; +#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0, 0, 0xff } +#define spin_lock_init(__lock) \ +do { (__lock)->lock = 0; \ + (__lock)->owner_pc = 0; \ + (__lock)->owner_cpu = 0xff; \ +} while(0) +#define spin_is_locked(__lock) (*((volatile unsigned char *)(&((__lock)->lock))) != 0) +#define spin_unlock_wait(__lock) \ +do { \ + membar("#LoadLoad"); \ +} while(*((volatile unsigned char *)(&((__lock)->lock)))) + +extern void _do_spin_lock (spinlock_t *lock, char *str); +extern void _do_spin_unlock (spinlock_t *lock); +extern int _do_spin_trylock (spinlock_t *lock); + +#define _raw_spin_trylock(lp) _do_spin_trylock(lp) +#define _raw_spin_lock(lock) _do_spin_lock(lock, "spin_lock") +#define _raw_spin_unlock(lock) _do_spin_unlock(lock) +#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) + +#endif /* CONFIG_DEBUG_SPINLOCK */ + +/* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */ + +#ifndef CONFIG_DEBUG_SPINLOCK + +typedef unsigned int rwlock_t; +#define RW_LOCK_UNLOCKED 0 +#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0) + +static void inline __read_lock(rwlock_t *lock) +{ + unsigned long tmp1, tmp2; + + __asm__ __volatile__ ( +"1: ldsw [%2], %0\n" +" brlz,pn %0, 2f\n" +"4: add %0, 1, %1\n" +" cas [%2], %0, %1\n" +" cmp %0, %1\n" +" bne,pn %%icc, 1b\n" +" membar #StoreLoad | #StoreStore\n" +" .subsection 2\n" +"2: ldsw [%2], %0\n" +" brlz,pt %0, 2b\n" +" membar #LoadLoad\n" +" ba,a,pt %%xcc, 4b\n" +" .previous" + : "=&r" (tmp1), "=&r" (tmp2) + : "r" (lock) + : "memory"); +} + +static void inline __read_unlock(rwlock_t *lock) +{ + unsigned long tmp1, tmp2; + + __asm__ __volatile__( +" membar #StoreLoad | #LoadLoad\n" +"1: lduw [%2], %0\n" +" sub %0, 1, %1\n" +" cas [%2], %0, %1\n" +" cmp %0, %1\n" +" bne,pn %%xcc, 1b\n" +" nop" + : "=&r" (tmp1), "=&r" (tmp2) + : "r" (lock) + : "memory"); +} + +static void inline __write_lock(rwlock_t *lock) +{ + unsigned long mask, tmp1, tmp2; + + mask = 0x80000000UL; + + __asm__ __volatile__( +"1: lduw [%2], %0\n" +" brnz,pn %0, 2f\n" +"4: or %0, %3, %1\n" +" cas [%2], %0, %1\n" +" cmp %0, %1\n" +" bne,pn %%icc, 1b\n" +" membar #StoreLoad | #StoreStore\n" +" .subsection 2\n" +"2: lduw [%2], %0\n" +" brnz,pt %0, 2b\n" +" membar #LoadLoad\n" +" ba,a,pt %%xcc, 4b\n" +" .previous" + : "=&r" (tmp1), "=&r" (tmp2) + : "r" (lock), "r" (mask) + : "memory"); +} + +static void inline __write_unlock(rwlock_t *lock) +{ + __asm__ __volatile__( +" membar #LoadStore | #StoreStore\n" +" stw %%g0, [%0]" + : /* no outputs */ + : "r" (lock) + : "memory"); +} + +static int inline __write_trylock(rwlock_t *lock) +{ + unsigned long mask, tmp1, tmp2, result; + + mask = 0x80000000UL; + + __asm__ __volatile__( +" mov 0, %2\n" +"1: lduw [%3], %0\n" +" brnz,pn %0, 2f\n" +" or %0, %4, %1\n" +" cas [%3], %0, %1\n" +" cmp %0, %1\n" +" bne,pn %%icc, 1b\n" +" membar #StoreLoad | #StoreStore\n" +" mov 1, %2\n" +"2:" + : "=&r" (tmp1), "=&r" (tmp2), "=&r" (result) + : "r" (lock), "r" (mask) + : "memory"); + + return result; +} + +#define _raw_read_lock(p) __read_lock(p) +#define _raw_read_unlock(p) __read_unlock(p) +#define _raw_write_lock(p) __write_lock(p) +#define _raw_write_unlock(p) __write_unlock(p) +#define _raw_write_trylock(p) __write_trylock(p) + +#else /* !(CONFIG_DEBUG_SPINLOCK) */ + +typedef struct { + unsigned long lock; + unsigned int writer_pc, writer_cpu; + unsigned int reader_pc[NR_CPUS]; +} rwlock_t; +#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0xff, { } } +#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0) + +extern void _do_read_lock(rwlock_t *rw, char *str); +extern void _do_read_unlock(rwlock_t *rw, char *str); +extern void _do_write_lock(rwlock_t *rw, char *str); +extern void _do_write_unlock(rwlock_t *rw); +extern int _do_write_trylock(rwlock_t *rw, char *str); + +#define _raw_read_lock(lock) \ +do { unsigned long flags; \ + local_irq_save(flags); \ + _do_read_lock(lock, "read_lock"); \ + local_irq_restore(flags); \ +} while(0) + +#define _raw_read_unlock(lock) \ +do { unsigned long flags; \ + local_irq_save(flags); \ + _do_read_unlock(lock, "read_unlock"); \ + local_irq_restore(flags); \ +} while(0) + +#define _raw_write_lock(lock) \ +do { unsigned long flags; \ + local_irq_save(flags); \ + _do_write_lock(lock, "write_lock"); \ + local_irq_restore(flags); \ +} while(0) + +#define _raw_write_unlock(lock) \ +do { unsigned long flags; \ + local_irq_save(flags); \ + _do_write_unlock(lock); \ + local_irq_restore(flags); \ +} while(0) + +#define _raw_write_trylock(lock) \ +({ unsigned long flags; \ + int val; \ + local_irq_save(flags); \ + val = _do_write_trylock(lock, "write_trylock"); \ + local_irq_restore(flags); \ + val; \ +}) + +#endif /* CONFIG_DEBUG_SPINLOCK */ + +#define _raw_read_trylock(lock) generic_raw_read_trylock(lock) + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(__SPARC64_SPINLOCK_H) */ diff --git a/include/asm-sparc64/spitfire.h b/include/asm-sparc64/spitfire.h new file mode 100644 index 000000000000..ad78ce64d69e --- /dev/null +++ b/include/asm-sparc64/spitfire.h @@ -0,0 +1,461 @@ +/* $Id: spitfire.h,v 1.18 2001/11/29 16:42:10 kanoj Exp $ + * spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC64_SPITFIRE_H +#define _SPARC64_SPITFIRE_H + +#include <asm/asi.h> + +/* The following register addresses are accessible via ASI_DMMU + * and ASI_IMMU, that is there is a distinct and unique copy of + * each these registers for each TLB. + */ +#define TSB_TAG_TARGET 0x0000000000000000 /* All chips */ +#define TLB_SFSR 0x0000000000000018 /* All chips */ +#define TSB_REG 0x0000000000000028 /* All chips */ +#define TLB_TAG_ACCESS 0x0000000000000030 /* All chips */ +#define VIRT_WATCHPOINT 0x0000000000000038 /* All chips */ +#define PHYS_WATCHPOINT 0x0000000000000040 /* All chips */ +#define TSB_EXTENSION_P 0x0000000000000048 /* Ultra-III and later */ +#define TSB_EXTENSION_S 0x0000000000000050 /* Ultra-III and later, D-TLB only */ +#define TSB_EXTENSION_N 0x0000000000000058 /* Ultra-III and later */ +#define TLB_TAG_ACCESS_EXT 0x0000000000000060 /* Ultra-III+ and later */ + +/* These registers only exist as one entity, and are accessed + * via ASI_DMMU only. + */ +#define PRIMARY_CONTEXT 0x0000000000000008 +#define SECONDARY_CONTEXT 0x0000000000000010 +#define DMMU_SFAR 0x0000000000000020 +#define VIRT_WATCHPOINT 0x0000000000000038 +#define PHYS_WATCHPOINT 0x0000000000000040 + +#define SPITFIRE_HIGHEST_LOCKED_TLBENT (64 - 1) +#define CHEETAH_HIGHEST_LOCKED_TLBENT (16 - 1) + +#define L1DCACHE_SIZE 0x4000 + +#ifndef __ASSEMBLY__ + +enum ultra_tlb_layout { + spitfire = 0, + cheetah = 1, + cheetah_plus = 2, +}; + +extern enum ultra_tlb_layout tlb_type; + +#define sparc64_highest_locked_tlbent() \ + (tlb_type == spitfire ? \ + SPITFIRE_HIGHEST_LOCKED_TLBENT : \ + CHEETAH_HIGHEST_LOCKED_TLBENT) + +static __inline__ unsigned long spitfire_get_isfsr(void) +{ + unsigned long ret; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (ret) + : "r" (TLB_SFSR), "i" (ASI_IMMU)); + return ret; +} + +static __inline__ unsigned long spitfire_get_dsfsr(void) +{ + unsigned long ret; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (ret) + : "r" (TLB_SFSR), "i" (ASI_DMMU)); + return ret; +} + +static __inline__ unsigned long spitfire_get_sfar(void) +{ + unsigned long ret; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (ret) + : "r" (DMMU_SFAR), "i" (ASI_DMMU)); + return ret; +} + +static __inline__ void spitfire_put_isfsr(unsigned long sfsr) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* no outputs */ + : "r" (sfsr), "r" (TLB_SFSR), "i" (ASI_IMMU)); +} + +static __inline__ void spitfire_put_dsfsr(unsigned long sfsr) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* no outputs */ + : "r" (sfsr), "r" (TLB_SFSR), "i" (ASI_DMMU)); +} + +/* The data cache is write through, so this just invalidates the + * specified line. + */ +static __inline__ void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG)); + __asm__ __volatile__ ("membar #Sync" : : : "memory"); +} + +/* The instruction cache lines are flushed with this, but note that + * this does not flush the pipeline. It is possible for a line to + * get flushed but stale instructions to still be in the pipeline, + * a flush instruction (to any address) is sufficient to handle + * this issue after the line is invalidated. + */ +static __inline__ void spitfire_put_icache_tag(unsigned long addr, unsigned long tag) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (tag), "r" (addr), "i" (ASI_IC_TAG)); +} + +static __inline__ unsigned long spitfire_get_dtlb_data(int entry) +{ + unsigned long data; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (data) + : "r" (entry << 3), "i" (ASI_DTLB_DATA_ACCESS)); + + /* Clear TTE diag bits. */ + data &= ~0x0003fe0000000000UL; + + return data; +} + +static __inline__ unsigned long spitfire_get_dtlb_tag(int entry) +{ + unsigned long tag; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (tag) + : "r" (entry << 3), "i" (ASI_DTLB_TAG_READ)); + return tag; +} + +static __inline__ void spitfire_put_dtlb_data(int entry, unsigned long data) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (data), "r" (entry << 3), + "i" (ASI_DTLB_DATA_ACCESS)); +} + +static __inline__ unsigned long spitfire_get_itlb_data(int entry) +{ + unsigned long data; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (data) + : "r" (entry << 3), "i" (ASI_ITLB_DATA_ACCESS)); + + /* Clear TTE diag bits. */ + data &= ~0x0003fe0000000000UL; + + return data; +} + +static __inline__ unsigned long spitfire_get_itlb_tag(int entry) +{ + unsigned long tag; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (tag) + : "r" (entry << 3), "i" (ASI_ITLB_TAG_READ)); + return tag; +} + +static __inline__ void spitfire_put_itlb_data(int entry, unsigned long data) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (data), "r" (entry << 3), + "i" (ASI_ITLB_DATA_ACCESS)); +} + +/* Spitfire hardware assisted TLB flushes. */ + +/* Context level flushes. */ +static __inline__ void spitfire_flush_dtlb_primary_context(void) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (0x40), "i" (ASI_DMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_itlb_primary_context(void) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (0x40), "i" (ASI_IMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_dtlb_secondary_context(void) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (0x50), "i" (ASI_DMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_itlb_secondary_context(void) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (0x50), "i" (ASI_IMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_dtlb_nucleus_context(void) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (0x60), "i" (ASI_DMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_itlb_nucleus_context(void) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (0x60), "i" (ASI_IMMU_DEMAP)); +} + +/* Page level flushes. */ +static __inline__ void spitfire_flush_dtlb_primary_page(unsigned long page) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (page), "i" (ASI_DMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_itlb_primary_page(unsigned long page) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (page), "i" (ASI_IMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_dtlb_secondary_page(unsigned long page) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (page | 0x10), "i" (ASI_DMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_itlb_secondary_page(unsigned long page) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (page | 0x10), "i" (ASI_IMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_dtlb_nucleus_page(unsigned long page) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (page | 0x20), "i" (ASI_DMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_itlb_nucleus_page(unsigned long page) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (page | 0x20), "i" (ASI_IMMU_DEMAP)); +} + +/* Cheetah has "all non-locked" tlb flushes. */ +static __inline__ void cheetah_flush_dtlb_all(void) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (0x80), "i" (ASI_DMMU_DEMAP)); +} + +static __inline__ void cheetah_flush_itlb_all(void) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (0x80), "i" (ASI_IMMU_DEMAP)); +} + +/* Cheetah has a 4-tlb layout so direct access is a bit different. + * The first two TLBs are fully assosciative, hold 16 entries, and are + * used only for locked and >8K sized translations. One exists for + * data accesses and one for instruction accesses. + * + * The third TLB is for data accesses to 8K non-locked translations, is + * 2 way assosciative, and holds 512 entries. The fourth TLB is for + * instruction accesses to 8K non-locked translations, is 2 way + * assosciative, and holds 128 entries. + * + * Cheetah has some bug where bogus data can be returned from + * ASI_{D,I}TLB_DATA_ACCESS loads, doing the load twice fixes + * the problem for me. -DaveM + */ +static __inline__ unsigned long cheetah_get_ldtlb_data(int entry) +{ + unsigned long data; + + __asm__ __volatile__("ldxa [%1] %2, %%g0\n\t" + "ldxa [%1] %2, %0" + : "=r" (data) + : "r" ((0 << 16) | (entry << 3)), + "i" (ASI_DTLB_DATA_ACCESS)); + + return data; +} + +static __inline__ unsigned long cheetah_get_litlb_data(int entry) +{ + unsigned long data; + + __asm__ __volatile__("ldxa [%1] %2, %%g0\n\t" + "ldxa [%1] %2, %0" + : "=r" (data) + : "r" ((0 << 16) | (entry << 3)), + "i" (ASI_ITLB_DATA_ACCESS)); + + return data; +} + +static __inline__ unsigned long cheetah_get_ldtlb_tag(int entry) +{ + unsigned long tag; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (tag) + : "r" ((0 << 16) | (entry << 3)), + "i" (ASI_DTLB_TAG_READ)); + + return tag; +} + +static __inline__ unsigned long cheetah_get_litlb_tag(int entry) +{ + unsigned long tag; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (tag) + : "r" ((0 << 16) | (entry << 3)), + "i" (ASI_ITLB_TAG_READ)); + + return tag; +} + +static __inline__ void cheetah_put_ldtlb_data(int entry, unsigned long data) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (data), + "r" ((0 << 16) | (entry << 3)), + "i" (ASI_DTLB_DATA_ACCESS)); +} + +static __inline__ void cheetah_put_litlb_data(int entry, unsigned long data) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (data), + "r" ((0 << 16) | (entry << 3)), + "i" (ASI_ITLB_DATA_ACCESS)); +} + +static __inline__ unsigned long cheetah_get_dtlb_data(int entry, int tlb) +{ + unsigned long data; + + __asm__ __volatile__("ldxa [%1] %2, %%g0\n\t" + "ldxa [%1] %2, %0" + : "=r" (data) + : "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_DATA_ACCESS)); + + return data; +} + +static __inline__ unsigned long cheetah_get_dtlb_tag(int entry, int tlb) +{ + unsigned long tag; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (tag) + : "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_TAG_READ)); + return tag; +} + +static __inline__ void cheetah_put_dtlb_data(int entry, unsigned long data, int tlb) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (data), + "r" ((tlb << 16) | (entry << 3)), + "i" (ASI_DTLB_DATA_ACCESS)); +} + +static __inline__ unsigned long cheetah_get_itlb_data(int entry) +{ + unsigned long data; + + __asm__ __volatile__("ldxa [%1] %2, %%g0\n\t" + "ldxa [%1] %2, %0" + : "=r" (data) + : "r" ((2 << 16) | (entry << 3)), + "i" (ASI_ITLB_DATA_ACCESS)); + + return data; +} + +static __inline__ unsigned long cheetah_get_itlb_tag(int entry) +{ + unsigned long tag; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (tag) + : "r" ((2 << 16) | (entry << 3)), "i" (ASI_ITLB_TAG_READ)); + return tag; +} + +static __inline__ void cheetah_put_itlb_data(int entry, unsigned long data) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (data), "r" ((2 << 16) | (entry << 3)), + "i" (ASI_ITLB_DATA_ACCESS)); +} + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(_SPARC64_SPITFIRE_H) */ diff --git a/include/asm-sparc64/starfire.h b/include/asm-sparc64/starfire.h new file mode 100644 index 000000000000..b606cb2b32a8 --- /dev/null +++ b/include/asm-sparc64/starfire.h @@ -0,0 +1,21 @@ +/* $Id: starfire.h,v 1.2 2001/07/04 00:18:18 davem Exp $ + * starfire.h: Group all starfire specific code together. + * + * Copyright (C) 2000 Anton Blanchard (anton@samba.org) + */ + +#ifndef _SPARC64_STARFIRE_H +#define _SPARC64_STARFIRE_H + +#ifndef __ASSEMBLY__ + +extern int this_is_starfire; + +extern void check_if_starfire(void); +extern void starfire_cpu_setup(void); +extern int starfire_hard_smp_processor_id(void); +extern void *starfire_hookup(int); +extern unsigned int starfire_translate(unsigned long imap, unsigned int upaid); + +#endif +#endif diff --git a/include/asm-sparc64/stat.h b/include/asm-sparc64/stat.h new file mode 100644 index 000000000000..48e06618a5a4 --- /dev/null +++ b/include/asm-sparc64/stat.h @@ -0,0 +1,63 @@ +/* $Id: stat.h,v 1.7 2000/08/04 05:35:55 davem Exp $ */ +#ifndef _SPARC64_STAT_H +#define _SPARC64_STAT_H + +#include <linux/types.h> + +struct stat { + unsigned st_dev; + ino_t st_ino; + mode_t st_mode; + short st_nlink; + uid_t st_uid; + gid_t st_gid; + unsigned st_rdev; + off_t st_size; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; + off_t st_blksize; + off_t st_blocks; + unsigned long __unused4[2]; +}; + +#ifdef __KERNEL__ +/* This is sparc32 stat64 structure. */ + +struct stat64 { + unsigned long long st_dev; + + unsigned long long st_ino; + + unsigned int st_mode; + unsigned int st_nlink; + + unsigned int st_uid; + unsigned int st_gid; + + unsigned long long st_rdev; + + unsigned char __pad3[8]; + + long long st_size; + unsigned int st_blksize; + + unsigned char __pad4[8]; + unsigned int st_blocks; + + unsigned int st_atime; + unsigned int st_atime_nsec; + + unsigned int st_mtime; + unsigned int st_mtime_nsec; + + unsigned int st_ctime; + unsigned int st_ctime_nsec; + + unsigned int __unused4; + unsigned int __unused5; +}; + +#endif + +#endif diff --git a/include/asm-sparc64/statfs.h b/include/asm-sparc64/statfs.h new file mode 100644 index 000000000000..185b6c481b24 --- /dev/null +++ b/include/asm-sparc64/statfs.h @@ -0,0 +1,55 @@ +/* $Id: statfs.h,v 1.2 1997/04/14 17:05:22 jj Exp $ */ +#ifndef _SPARC64_STATFS_H +#define _SPARC64_STATFS_H + +#ifndef __KERNEL_STRICT_NAMES + +#include <linux/types.h> + +typedef __kernel_fsid_t fsid_t; + +#endif + +struct statfs { + long f_type; + long f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; + __kernel_fsid_t f_fsid; + long f_namelen; + long f_frsize; + long f_spare[5]; +}; + +struct statfs64 { + long f_type; + long f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; + __kernel_fsid_t f_fsid; + long f_namelen; + long f_frsize; + long f_spare[5]; +}; + +struct compat_statfs64 { + __u32 f_type; + __u32 f_bsize; + __u64 f_blocks; + __u64 f_bfree; + __u64 f_bavail; + __u64 f_files; + __u64 f_ffree; + __kernel_fsid_t f_fsid; + __u32 f_namelen; + __u32 f_frsize; + __u32 f_spare[5]; +}; + +#endif diff --git a/include/asm-sparc64/string.h b/include/asm-sparc64/string.h new file mode 100644 index 000000000000..c7d88622cb27 --- /dev/null +++ b/include/asm-sparc64/string.h @@ -0,0 +1,83 @@ +/* $Id: string.h,v 1.20 2001/09/27 04:36:24 kanoj Exp $ + * string.h: External definitions for optimized assembly string + * routines for the Linux Kernel. + * + * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996,1997,1999 Jakub Jelinek (jakub@redhat.com) + */ + +#ifndef __SPARC64_STRING_H__ +#define __SPARC64_STRING_H__ + +/* Really, userland/ksyms should not see any of this stuff. */ + +#ifdef __KERNEL__ + +#include <asm/asi.h> + +extern void *__memset(void *,int,__kernel_size_t); + +#ifndef EXPORT_SYMTAB_STROPS + +/* First the mem*() things. */ +#define __HAVE_ARCH_MEMMOVE +extern void *memmove(void *, const void *, __kernel_size_t); + +#define __HAVE_ARCH_MEMCPY +extern void *memcpy(void *, const void *, __kernel_size_t); + +#define __HAVE_ARCH_MEMSET +extern void *__builtin_memset(void *,int,__kernel_size_t); + +static inline void *__constant_memset(void *s, int c, __kernel_size_t count) +{ + extern __kernel_size_t __bzero(void *, __kernel_size_t); + + if (!c) { + __bzero(s, count); + return s; + } else + return __memset(s, c, count); +} + +#undef memset +#define memset(s, c, count) \ +((__builtin_constant_p(count) && (count) <= 32) ? \ + __builtin_memset((s), (c), (count)) : \ + (__builtin_constant_p(c) ? \ + __constant_memset((s), (c), (count)) : \ + __memset((s), (c), (count)))) + +#define __HAVE_ARCH_MEMSCAN + +#undef memscan +#define memscan(__arg0, __char, __arg2) \ +({ \ + extern void *__memscan_zero(void *, size_t); \ + extern void *__memscan_generic(void *, int, size_t); \ + void *__retval, *__addr = (__arg0); \ + size_t __size = (__arg2); \ + \ + if(__builtin_constant_p(__char) && !(__char)) \ + __retval = __memscan_zero(__addr, __size); \ + else \ + __retval = __memscan_generic(__addr, (__char), __size); \ + \ + __retval; \ +}) + +#define __HAVE_ARCH_MEMCMP +extern int memcmp(const void *,const void *,__kernel_size_t); + +/* Now the str*() stuff... */ +#define __HAVE_ARCH_STRLEN +extern __kernel_size_t strlen(const char *); + +#define __HAVE_ARCH_STRNCMP +extern int strncmp(const char *, const char *, __kernel_size_t); + +#endif /* !EXPORT_SYMTAB_STROPS */ + +#endif /* __KERNEL__ */ + +#endif /* !(__SPARC64_STRING_H__) */ diff --git a/include/asm-sparc64/sunbpp.h b/include/asm-sparc64/sunbpp.h new file mode 100644 index 000000000000..b441cc9c426c --- /dev/null +++ b/include/asm-sparc64/sunbpp.h @@ -0,0 +1,80 @@ +/* $Id: sunbpp.h,v 1.1 1999/08/13 06:21:44 shadow Exp $ + * include/asm-sparc64/sunbpp.h + */ + +#ifndef _ASM_SPARC64_SUNBPP_H +#define _ASM_SPARC64_SUNBPP_H + +struct bpp_regs { + /* DMA registers */ + __volatile__ __u32 p_csr; /* DMA Control/Status Register */ + __volatile__ __u32 p_addr; /* Address Register */ + __volatile__ __u32 p_bcnt; /* Byte Count Register */ + __volatile__ __u32 p_tst_csr; /* Test Control/Status (DMA2 only) */ + /* Parallel Port registers */ + __volatile__ __u16 p_hcr; /* Hardware Configuration Register */ + __volatile__ __u16 p_ocr; /* Operation Configuration Register */ + __volatile__ __u8 p_dr; /* Parallel Data Register */ + __volatile__ __u8 p_tcr; /* Transfer Control Register */ + __volatile__ __u8 p_or; /* Output Register */ + __volatile__ __u8 p_ir; /* Input Register */ + __volatile__ __u16 p_icr; /* Interrupt Control Register */ +}; + +/* P_HCR. Time is in increments of SBus clock. */ +#define P_HCR_TEST 0x8000 /* Allows buried counters to be read */ +#define P_HCR_DSW 0x7f00 /* Data strobe width (in ticks) */ +#define P_HCR_DDS 0x007f /* Data setup before strobe (in ticks) */ + +/* P_OCR. */ +#define P_OCR_MEM_CLR 0x8000 +#define P_OCR_DATA_SRC 0x4000 /* ) */ +#define P_OCR_DS_DSEL 0x2000 /* ) Bidirectional */ +#define P_OCR_BUSY_DSEL 0x1000 /* ) selects */ +#define P_OCR_ACK_DSEL 0x0800 /* ) */ +#define P_OCR_EN_DIAG 0x0400 +#define P_OCR_BUSY_OP 0x0200 /* Busy operation */ +#define P_OCR_ACK_OP 0x0100 /* Ack operation */ +#define P_OCR_SRST 0x0080 /* Reset state machines. Not selfcleaning. */ +#define P_OCR_IDLE 0x0008 /* PP data transfer state machine is idle */ +#define P_OCR_V_ILCK 0x0002 /* Versatec faded. Zebra only. */ +#define P_OCR_EN_VER 0x0001 /* Enable Versatec (0 - enable). Zebra only. */ + +/* P_TCR */ +#define P_TCR_DIR 0x08 +#define P_TCR_BUSY 0x04 +#define P_TCR_ACK 0x02 +#define P_TCR_DS 0x01 /* Strobe */ + +/* P_OR */ +#define P_OR_V3 0x20 /* ) */ +#define P_OR_V2 0x10 /* ) on Zebra only */ +#define P_OR_V1 0x08 /* ) */ +#define P_OR_INIT 0x04 +#define P_OR_AFXN 0x02 /* Auto Feed */ +#define P_OR_SLCT_IN 0x01 + +/* P_IR */ +#define P_IR_PE 0x04 +#define P_IR_SLCT 0x02 +#define P_IR_ERR 0x01 + +/* P_ICR */ +#define P_DS_IRQ 0x8000 /* RW1 */ +#define P_ACK_IRQ 0x4000 /* RW1 */ +#define P_BUSY_IRQ 0x2000 /* RW1 */ +#define P_PE_IRQ 0x1000 /* RW1 */ +#define P_SLCT_IRQ 0x0800 /* RW1 */ +#define P_ERR_IRQ 0x0400 /* RW1 */ +#define P_DS_IRQ_EN 0x0200 /* RW Always on rising edge */ +#define P_ACK_IRQ_EN 0x0100 /* RW Always on rising edge */ +#define P_BUSY_IRP 0x0080 /* RW 1= rising edge */ +#define P_BUSY_IRQ_EN 0x0040 /* RW */ +#define P_PE_IRP 0x0020 /* RW 1= rising edge */ +#define P_PE_IRQ_EN 0x0010 /* RW */ +#define P_SLCT_IRP 0x0008 /* RW 1= rising edge */ +#define P_SLCT_IRQ_EN 0x0004 /* RW */ +#define P_ERR_IRP 0x0002 /* RW1 1= rising edge */ +#define P_ERR_IRQ_EN 0x0001 /* RW */ + +#endif /* !(_ASM_SPARC64_SUNBPP_H) */ diff --git a/include/asm-sparc64/svr4.h b/include/asm-sparc64/svr4.h new file mode 100644 index 000000000000..c96d5f116e1c --- /dev/null +++ b/include/asm-sparc64/svr4.h @@ -0,0 +1,120 @@ +/* Solaris/SPARC constants and definitions -- + * (C) 1996 Miguel de Icaza + * + * This file is not meant to be included by user level applications + * but the solaris syscall emulator + */ + +#ifndef _SPARC64_SVR4_H +#define _SPARC64_SVR4_H + +/* Signals as used by svr4 */ +typedef struct { /* signal set type */ + uint sigbits[4]; +} svr4_sigset_t; + +/* Values for siginfo.code */ +#define SVR4_SINOINFO 32767 +/* Siginfo, sucker expects bunch of information on those parameters */ +typedef union { + char total_size [128]; + struct { + int signo; + int code; + int error; + union { + } data; + } siginfo; +} svr4_siginfo_t; + +/* Context definition */ + +/* Location of the user stored registers into a greg_t */ +enum { + SVR4_PSR, SVR4_PC, SVR4_NPC, SVR4_Y, + SVR4_G1, SVR4_G2, SVR4_G3, SVR4_G4, + SVR4_G5, SVR4_G6, SVR4_G7, SVR4_O0, + SVR4_O1, SVR4_O2, SVR4_O3, SVR4_O4, + SVR4_O5, SVR4_O6, SVR4_O7 +}; + +/* sizeof (regs) / sizeof (greg_t), defined in the ABI */ +#define SVR4_NREGS 19 +#define SVR4_MAXWIN 31 + +typedef struct { + u32 rwin_lo[8]; + u32 rwin_in[8]; +} svr4_rwindow_t; + +typedef struct { + int count; + u32 winptr [SVR4_MAXWIN]; /* pointer to the windows */ + + svr4_rwindow_t win[SVR4_MAXWIN]; /* the windows */ +} svr4_gwindows_t; + +typedef int svr4_gregset_t[SVR4_NREGS]; + +typedef struct { + u64 fpu_regs[32]; + u32 fp_q; + u32 fp_fsr; + u_char fp_nqel; + u_char fp_nqsize; + u_char inuse; /* if fpu is in use */ +} svr4_fregset_t; + +typedef struct { + u32 id; /* if this holds "xrs" string => ptr is valid */ + u32 ptr; +} svr4_xrs_t; + +/* Machine dependent context */ +typedef struct { + svr4_gregset_t greg; /* registers 0..19 (see top) */ + u32 gwin; /* may point to register windows */ + svr4_fregset_t freg; /* floating point registers */ + svr4_xrs_t xrs; /* mhm? */ + int pad[19]; +} svr4_mcontext_t; + +/* flags for stack_t.flags */ +enum svr4_stack_flags { + SVR4_SS_ONSTACK, + SVR4_SS_DISABLE, +}; + +/* signal stack execution place, unsupported */ +typedef struct svr4_stack_t { + u32 sp; + int size; + int flags; +} svr4_stack_t; + +/* Context used by getcontext and setcontext */ +typedef struct svr4_ucontext_t { + u32 flags; /* context flags, indicate what is loaded */ + u32 link; + svr4_sigset_t sigmask; + svr4_stack_t stack; + svr4_mcontext_t mcontext; + int pad[23]; +} svr4_ucontext_t; + +/* windows hold the windows as they were at signal time, + * ucontext->mcontext holds a pointer to them. + * addresses for uc and si are passed as parameters to svr4 signal + * handler + */ + +/* This is the signal frame that is passed to the signal handler */ +typedef struct { + svr4_gwindows_t gw; /* windows */ + svr4_ucontext_t uc; /* machine context */ + svr4_siginfo_t si; /* siginfo */ +} svr4_signal_frame_t; + +#define SVR4_SF_ALIGNED (((sizeof (svr4_signal_frame_t) + 7) & (~7))) + +#endif /* include control */ diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h new file mode 100644 index 000000000000..fd12ca386f48 --- /dev/null +++ b/include/asm-sparc64/system.h @@ -0,0 +1,350 @@ +/* $Id: system.h,v 1.69 2002/02/09 19:49:31 davem Exp $ */ +#ifndef __SPARC64_SYSTEM_H +#define __SPARC64_SYSTEM_H + +#include <linux/config.h> +#include <asm/ptrace.h> +#include <asm/processor.h> +#include <asm/visasm.h> + +#ifndef __ASSEMBLY__ +/* + * Sparc (general) CPU types + */ +enum sparc_cpu { + sun4 = 0x00, + sun4c = 0x01, + sun4m = 0x02, + sun4d = 0x03, + sun4e = 0x04, + sun4u = 0x05, /* V8 ploos ploos */ + sun_unknown = 0x06, + ap1000 = 0x07, /* almost a sun4m */ +}; + +#define sparc_cpu_model sun4u + +/* This cannot ever be a sun4c nor sun4 :) That's just history. */ +#define ARCH_SUN4C_SUN4 0 +#define ARCH_SUN4 0 + +#endif + +#define setipl(__new_ipl) \ + __asm__ __volatile__("wrpr %0, %%pil" : : "r" (__new_ipl) : "memory") + +#define local_irq_disable() \ + __asm__ __volatile__("wrpr 15, %%pil" : : : "memory") + +#define local_irq_enable() \ + __asm__ __volatile__("wrpr 0, %%pil" : : : "memory") + +#define getipl() \ +({ unsigned long retval; __asm__ __volatile__("rdpr %%pil, %0" : "=r" (retval)); retval; }) + +#define swap_pil(__new_pil) \ +({ unsigned long retval; \ + __asm__ __volatile__("rdpr %%pil, %0\n\t" \ + "wrpr %1, %%pil" \ + : "=&r" (retval) \ + : "r" (__new_pil) \ + : "memory"); \ + retval; \ +}) + +#define read_pil_and_cli() \ +({ unsigned long retval; \ + __asm__ __volatile__("rdpr %%pil, %0\n\t" \ + "wrpr 15, %%pil" \ + : "=r" (retval) \ + : : "memory"); \ + retval; \ +}) + +#define local_save_flags(flags) ((flags) = getipl()) +#define local_irq_save(flags) ((flags) = read_pil_and_cli()) +#define local_irq_restore(flags) setipl((flags)) + +/* On sparc64 IRQ flags are the PIL register. A value of zero + * means all interrupt levels are enabled, any other value means + * only IRQ levels greater than that value will be received. + * Consequently this means that the lowest IRQ level is one. + */ +#define irqs_disabled() \ +({ unsigned long flags; \ + local_save_flags(flags);\ + (flags > 0); \ +}) + +#define nop() __asm__ __volatile__ ("nop") + +#define membar(type) __asm__ __volatile__ ("membar " type : : : "memory") +#define mb() \ + membar("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad") +#define rmb() membar("#LoadLoad") +#define wmb() membar("#StoreStore") +#define read_barrier_depends() do { } while(0) +#define set_mb(__var, __value) \ + do { __var = __value; membar("#StoreLoad | #StoreStore"); } while(0) +#define set_wmb(__var, __value) \ + do { __var = __value; membar("#StoreStore"); } while(0) + +#ifdef CONFIG_SMP +#define smp_mb() mb() +#define smp_rmb() rmb() +#define smp_wmb() wmb() +#define smp_read_barrier_depends() read_barrier_depends() +#else +#define smp_mb() __asm__ __volatile__("":::"memory") +#define smp_rmb() __asm__ __volatile__("":::"memory") +#define smp_wmb() __asm__ __volatile__("":::"memory") +#define smp_read_barrier_depends() do { } while(0) +#endif + +#define flushi(addr) __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory") + +#define flushw_all() __asm__ __volatile__("flushw") + +/* Performance counter register access. */ +#define read_pcr(__p) __asm__ __volatile__("rd %%pcr, %0" : "=r" (__p)) +#define write_pcr(__p) __asm__ __volatile__("wr %0, 0x0, %%pcr" : : "r" (__p)) +#define read_pic(__p) __asm__ __volatile__("rd %%pic, %0" : "=r" (__p)) + +/* Blackbird errata workaround. See commentary in + * arch/sparc64/kernel/smp.c:smp_percpu_timer_interrupt() + * for more information. + */ +#define reset_pic() \ + __asm__ __volatile__("ba,pt %xcc, 99f\n\t" \ + ".align 64\n" \ + "99:wr %g0, 0x0, %pic\n\t" \ + "rd %pic, %g0") + +#ifndef __ASSEMBLY__ + +extern void sun_do_break(void); +extern int serial_console; +extern int stop_a_enabled; + +static __inline__ int con_is_present(void) +{ + return serial_console ? 0 : 1; +} + +extern void synchronize_user_stack(void); + +extern void __flushw_user(void); +#define flushw_user() __flushw_user() + +#define flush_user_windows flushw_user +#define flush_register_windows flushw_all + +#define prepare_arch_switch(rq, next) \ +do { spin_lock(&(next)->switch_lock); \ + spin_unlock(&(rq)->lock); \ + flushw_all(); \ +} while (0) + +#define finish_arch_switch(rq, prev) \ +do { spin_unlock_irq(&(prev)->switch_lock); \ +} while (0) + +#define task_running(rq, p) \ + ((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock)) + + /* See what happens when you design the chip correctly? + * + * We tell gcc we clobber all non-fixed-usage registers except + * for l0/l1. It will use one for 'next' and the other to hold + * the output value of 'last'. 'next' is not referenced again + * past the invocation of switch_to in the scheduler, so we need + * not preserve it's value. Hairy, but it lets us remove 2 loads + * and 2 stores in this critical code path. -DaveM + */ +#if __GNUC__ >= 3 +#define EXTRA_CLOBBER ,"%l1" +#else +#define EXTRA_CLOBBER +#endif +#define switch_to(prev, next, last) \ +do { if (test_thread_flag(TIF_PERFCTR)) { \ + unsigned long __tmp; \ + read_pcr(__tmp); \ + current_thread_info()->pcr_reg = __tmp; \ + read_pic(__tmp); \ + current_thread_info()->kernel_cntd0 += (unsigned int)(__tmp);\ + current_thread_info()->kernel_cntd1 += ((__tmp) >> 32); \ + } \ + flush_tlb_pending(); \ + save_and_clear_fpu(); \ + /* If you are tempted to conditionalize the following */ \ + /* so that ASI is only written if it changes, think again. */ \ + __asm__ __volatile__("wr %%g0, %0, %%asi" \ + : : "r" (__thread_flag_byte_ptr(next->thread_info)[TI_FLAG_BYTE_CURRENT_DS]));\ + __asm__ __volatile__( \ + "mov %%g4, %%g7\n\t" \ + "wrpr %%g0, 0x95, %%pstate\n\t" \ + "stx %%i6, [%%sp + 2047 + 0x70]\n\t" \ + "stx %%i7, [%%sp + 2047 + 0x78]\n\t" \ + "rdpr %%wstate, %%o5\n\t" \ + "stx %%o6, [%%g6 + %3]\n\t" \ + "stb %%o5, [%%g6 + %2]\n\t" \ + "rdpr %%cwp, %%o5\n\t" \ + "stb %%o5, [%%g6 + %5]\n\t" \ + "mov %1, %%g6\n\t" \ + "ldub [%1 + %5], %%g1\n\t" \ + "wrpr %%g1, %%cwp\n\t" \ + "ldx [%%g6 + %3], %%o6\n\t" \ + "ldub [%%g6 + %2], %%o5\n\t" \ + "ldx [%%g6 + %4], %%o7\n\t" \ + "mov %%g6, %%l2\n\t" \ + "wrpr %%o5, 0x0, %%wstate\n\t" \ + "ldx [%%sp + 2047 + 0x70], %%i6\n\t" \ + "ldx [%%sp + 2047 + 0x78], %%i7\n\t" \ + "wrpr %%g0, 0x94, %%pstate\n\t" \ + "mov %%l2, %%g6\n\t" \ + "ldx [%%g6 + %7], %%g4\n\t" \ + "wrpr %%g0, 0x96, %%pstate\n\t" \ + "andcc %%o7, %6, %%g0\n\t" \ + "beq,pt %%icc, 1f\n\t" \ + " mov %%g7, %0\n\t" \ + "b,a ret_from_syscall\n\t" \ + "1:\n\t" \ + : "=&r" (last) \ + : "0" (next->thread_info), \ + "i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_FLAGS), "i" (TI_CWP), \ + "i" (_TIF_NEWCHILD), "i" (TI_TASK) \ + : "cc", \ + "g1", "g2", "g3", "g7", \ + "l2", "l3", "l4", "l5", "l6", "l7", \ + "i0", "i1", "i2", "i3", "i4", "i5", \ + "o0", "o1", "o2", "o3", "o4", "o5", "o7" EXTRA_CLOBBER);\ + /* If you fuck with this, update ret_from_syscall code too. */ \ + if (test_thread_flag(TIF_PERFCTR)) { \ + write_pcr(current_thread_info()->pcr_reg); \ + reset_pic(); \ + } \ +} while(0) + +static inline unsigned long xchg32(__volatile__ unsigned int *m, unsigned int val) +{ + unsigned long tmp1, tmp2; + + __asm__ __volatile__( +" membar #StoreLoad | #LoadLoad\n" +" mov %0, %1\n" +"1: lduw [%4], %2\n" +" cas [%4], %2, %0\n" +" cmp %2, %0\n" +" bne,a,pn %%icc, 1b\n" +" mov %1, %0\n" +" membar #StoreLoad | #StoreStore\n" + : "=&r" (val), "=&r" (tmp1), "=&r" (tmp2) + : "0" (val), "r" (m) + : "cc", "memory"); + return val; +} + +static inline unsigned long xchg64(__volatile__ unsigned long *m, unsigned long val) +{ + unsigned long tmp1, tmp2; + + __asm__ __volatile__( +" membar #StoreLoad | #LoadLoad\n" +" mov %0, %1\n" +"1: ldx [%4], %2\n" +" casx [%4], %2, %0\n" +" cmp %2, %0\n" +" bne,a,pn %%xcc, 1b\n" +" mov %1, %0\n" +" membar #StoreLoad | #StoreStore\n" + : "=&r" (val), "=&r" (tmp1), "=&r" (tmp2) + : "0" (val), "r" (m) + : "cc", "memory"); + return val; +} + +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define tas(ptr) (xchg((ptr),1)) + +extern void __xchg_called_with_bad_pointer(void); + +static __inline__ unsigned long __xchg(unsigned long x, __volatile__ void * ptr, + int size) +{ + switch (size) { + case 4: + return xchg32(ptr, x); + case 8: + return xchg64(ptr, x); + }; + __xchg_called_with_bad_pointer(); + return x; +} + +extern void die_if_kernel(char *str, struct pt_regs *regs) __attribute__ ((noreturn)); + +/* + * Atomic compare and exchange. Compare OLD with MEM, if identical, + * store NEW in MEM. Return the initial value in MEM. Success is + * indicated by comparing RETURN with OLD. + */ + +#define __HAVE_ARCH_CMPXCHG 1 + +static __inline__ unsigned long +__cmpxchg_u32(volatile int *m, int old, int new) +{ + __asm__ __volatile__("membar #StoreLoad | #LoadLoad\n" + "cas [%2], %3, %0\n\t" + "membar #StoreLoad | #StoreStore" + : "=&r" (new) + : "0" (new), "r" (m), "r" (old) + : "memory"); + + return new; +} + +static __inline__ unsigned long +__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new) +{ + __asm__ __volatile__("membar #StoreLoad | #LoadLoad\n" + "casx [%2], %3, %0\n\t" + "membar #StoreLoad | #StoreStore" + : "=&r" (new) + : "0" (new), "r" (m), "r" (old) + : "memory"); + + return new; +} + +/* This function doesn't exist, so you'll get a linker error + if something tries to do an invalid cmpxchg(). */ +extern void __cmpxchg_called_with_bad_pointer(void); + +static __inline__ unsigned long +__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) +{ + switch (size) { + case 4: + return __cmpxchg_u32(ptr, old, new); + case 8: + return __cmpxchg_u64(ptr, old, new); + } + __cmpxchg_called_with_bad_pointer(); + return old; +} + +#define cmpxchg(ptr,o,n) \ + ({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, sizeof(*(ptr))); \ + }) + +#endif /* !(__ASSEMBLY__) */ + +#define arch_align_stack(x) (x) + +#endif /* !(__SPARC64_SYSTEM_H) */ diff --git a/include/asm-sparc64/termbits.h b/include/asm-sparc64/termbits.h new file mode 100644 index 000000000000..b07715273ed4 --- /dev/null +++ b/include/asm-sparc64/termbits.h @@ -0,0 +1,235 @@ +#ifndef _SPARC64_TERMBITS_H +#define _SPARC64_TERMBITS_H + +#include <linux/posix_types.h> + +typedef unsigned char cc_t; +typedef unsigned int speed_t; + +/* XXX is this right for sparc64? it was an unsigned long... XXX */ +typedef unsigned int tcflag_t; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +#define NCCS 17 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +#ifdef __KERNEL__ +#define SIZEOF_USER_TERMIOS sizeof (struct termios) - (2*sizeof (cc_t)) + cc_t _x_cc[2]; /* We need them to hold vmin/vtime */ +#endif +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VEOL 5 +#define VEOL2 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 + + + +#define VSUSP 10 +#define VDSUSP 11 /* SunOS POSIX nicety I do believe... */ +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 + +/* Kernel keeps vmin/vtime separated, user apps assume vmin/vtime is + * shared with eof/eol + */ +#ifdef __KERNEL__ +#define VMIN 16 +#define VTIME 17 +#else +#define VMIN VEOF +#define VTIME VEOL +#endif + +/* c_iflag bits */ +#define IGNBRK 0x00000001 +#define BRKINT 0x00000002 +#define IGNPAR 0x00000004 +#define PARMRK 0x00000008 +#define INPCK 0x00000010 +#define ISTRIP 0x00000020 +#define INLCR 0x00000040 +#define IGNCR 0x00000080 +#define ICRNL 0x00000100 +#define IUCLC 0x00000200 +#define IXON 0x00000400 +#define IXANY 0x00000800 +#define IXOFF 0x00001000 +#define IMAXBEL 0x00002000 +#define IUTF8 0x00004000 + +/* c_oflag bits */ +#define OPOST 0x00000001 +#define OLCUC 0x00000002 +#define ONLCR 0x00000004 +#define OCRNL 0x00000008 +#define ONOCR 0x00000010 +#define ONLRET 0x00000020 +#define OFILL 0x00000040 +#define OFDEL 0x00000080 +#define NLDLY 0x00000100 +#define NL0 0x00000000 +#define NL1 0x00000100 +#define CRDLY 0x00000600 +#define CR0 0x00000000 +#define CR1 0x00000200 +#define CR2 0x00000400 +#define CR3 0x00000600 +#define TABDLY 0x00001800 +#define TAB0 0x00000000 +#define TAB1 0x00000800 +#define TAB2 0x00001000 +#define TAB3 0x00001800 +#define XTABS 0x00001800 +#define BSDLY 0x00002000 +#define BS0 0x00000000 +#define BS1 0x00002000 +#define VTDLY 0x00004000 +#define VT0 0x00000000 +#define VT1 0x00004000 +#define FFDLY 0x00008000 +#define FF0 0x00000000 +#define FF1 0x00008000 +#define PAGEOUT 0x00010000 /* SUNOS specific */ +#define WRAP 0x00020000 /* SUNOS specific */ + +/* c_cflag bit meaning */ +#define CBAUD 0x0000100f +#define B0 0x00000000 /* hang up */ +#define B50 0x00000001 +#define B75 0x00000002 +#define B110 0x00000003 +#define B134 0x00000004 +#define B150 0x00000005 +#define B200 0x00000006 +#define B300 0x00000007 +#define B600 0x00000008 +#define B1200 0x00000009 +#define B1800 0x0000000a +#define B2400 0x0000000b +#define B4800 0x0000000c +#define B9600 0x0000000d +#define B19200 0x0000000e +#define B38400 0x0000000f +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0x00000030 +#define CS5 0x00000000 +#define CS6 0x00000010 +#define CS7 0x00000020 +#define CS8 0x00000030 +#define CSTOPB 0x00000040 +#define CREAD 0x00000080 +#define PARENB 0x00000100 +#define PARODD 0x00000200 +#define HUPCL 0x00000400 +#define CLOCAL 0x00000800 +#define CBAUDEX 0x00001000 +#define B57600 0x00001001 +#define B115200 0x00001002 +#define B230400 0x00001003 +#define B460800 0x00001004 +/* This is what we can do with the Zilogs. */ +#define B76800 0x00001005 +/* This is what we can do with the SAB82532. */ +#define B153600 0x00001006 +#define B307200 0x00001007 +#define B614400 0x00001008 +#define B921600 0x00001009 +/* And these are the rest... */ +#define B500000 0x0000100a +#define B576000 0x0000100b +#define B1000000 0x0000100c +#define B1152000 0x0000100d +#define B1500000 0x0000100e +#define B2000000 0x0000100f +/* These have totally bogus values and nobody uses them + so far. Later on we'd have to use say 0x10000x and + adjust CBAUD constant and drivers accordingly. +#define B2500000 0x00001010 +#define B3000000 0x00001011 +#define B3500000 0x00001012 +#define B4000000 0x00001013 */ +#define CIBAUD 0x100f0000 /* input baud rate (not used) */ +#define CMSPAR 0x40000000 /* mark or space (stick) parity */ +#define CRTSCTS 0x80000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0x00000001 +#define ICANON 0x00000002 +#define XCASE 0x00000004 +#define ECHO 0x00000008 +#define ECHOE 0x00000010 +#define ECHOK 0x00000020 +#define ECHONL 0x00000040 +#define NOFLSH 0x00000080 +#define TOSTOP 0x00000100 +#define ECHOCTL 0x00000200 +#define ECHOPRT 0x00000400 +#define ECHOKE 0x00000800 +#define DEFECHO 0x00001000 /* SUNOS thing, what is it? */ +#define FLUSHO 0x00002000 +#define PENDIN 0x00004000 +#define IEXTEN 0x00008000 + +/* 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 +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 + +/* 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 + +#endif /* !(_SPARC64_TERMBITS_H) */ diff --git a/include/asm-sparc64/termios.h b/include/asm-sparc64/termios.h new file mode 100644 index 000000000000..8effce0da087 --- /dev/null +++ b/include/asm-sparc64/termios.h @@ -0,0 +1,173 @@ +/* $Id: termios.h,v 1.11 2001/06/01 08:12:11 davem Exp $ */ +#ifndef _SPARC64_TERMIOS_H +#define _SPARC64_TERMIOS_H + +#include <asm/ioctls.h> +#include <asm/termbits.h> + +#if defined(__KERNEL__) || defined(__DEFINE_BSD_TERMIOS) +struct sgttyb { + char sg_ispeed; + char sg_ospeed; + char sg_erase; + char sg_kill; + short sg_flags; +}; + +struct tchars { + char t_intrc; + char t_quitc; + char t_startc; + char t_stopc; + char t_eofc; + char t_brkc; +}; + +struct ltchars { + char t_suspc; + char t_dsuspc; + char t_rprntc; + char t_flushc; + char t_werasc; + char t_lnextc; +}; +#endif /* __KERNEL__ */ + +struct sunos_ttysize { + int st_lines; /* Lines on the terminal */ + int st_columns; /* Columns on the terminal */ +}; + +/* 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; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +/* line disciplines */ +#define N_TTY 0 +#define N_SLIP 1 +#define N_MOUSE 2 +#define N_PPP 3 +#define N_STRIP 4 +#define N_AX25 5 +#define N_X25 6 +#define N_6PACK 7 +#define N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */ +#define N_R3964 9 /* Reserved for Simatic R3964 module */ +#define N_PROFIBUS_FDL 10 /* Reserved for Profibus <Dave@mvhi.com> */ +#define N_IRDA 11 /* Linux IrDa - http://irda.sourceforge.net/ */ +#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ +#define N_HDLC 13 /* synchronous HDLC */ +#define N_SYNC_PPP 14 /* synchronous PPP */ +#define N_HCI 15 /* Bluetooth HCI UART */ + +#ifdef __KERNEL__ +#include <linux/module.h> + +/* + * 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 _VMIN 4 +#define _VTIME 5 + +/* intr=^C quit=^\ erase=del kill=^U + eof=^D eol=\0 eol2=\0 sxtc=\0 + start=^Q stop=^S susp=^Z dsusp=^Y + reprint=^R discard=^U werase=^W lnext=^V + vmin=\1 vtime=\0 +*/ +#define INIT_C_CC "\003\034\177\025\004\000\000\000\021\023\032\031\022\025\027\026\001" + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +#define user_termio_to_kernel_termios(termios, termio) \ +({ \ + unsigned short tmp; \ + get_user(tmp, &(termio)->c_iflag); \ + (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \ + get_user(tmp, &(termio)->c_oflag); \ + (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \ + get_user(tmp, &(termio)->c_cflag); \ + (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \ + get_user(tmp, &(termio)->c_lflag); \ + (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \ + copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ + 0; \ +}) + +/* + * Translate a "termios" structure into a "termio". Ugh. + * + * Note the "fun" _VMIN overloading. + */ +#define kernel_termios_to_user_termio(termio, termios) \ +({ \ + put_user((termios)->c_iflag, &(termio)->c_iflag); \ + put_user((termios)->c_oflag, &(termio)->c_oflag); \ + put_user((termios)->c_cflag, &(termio)->c_cflag); \ + put_user((termios)->c_lflag, &(termio)->c_lflag); \ + put_user((termios)->c_line, &(termio)->c_line); \ + copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ + if (!((termios)->c_lflag & ICANON)) { \ + put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \ + put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \ + } \ + 0; \ +}) + +#define user_termios_to_kernel_termios(k, u) \ +({ \ + get_user((k)->c_iflag, &(u)->c_iflag); \ + get_user((k)->c_oflag, &(u)->c_oflag); \ + get_user((k)->c_cflag, &(u)->c_cflag); \ + get_user((k)->c_lflag, &(u)->c_lflag); \ + get_user((k)->c_line, &(u)->c_line); \ + copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \ + if((k)->c_lflag & ICANON) { \ + get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ + get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ + } else { \ + get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ + get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ + } \ + 0; \ +}) + +#define kernel_termios_to_user_termios(u, k) \ +({ \ + put_user((k)->c_iflag, &(u)->c_iflag); \ + put_user((k)->c_oflag, &(u)->c_oflag); \ + put_user((k)->c_cflag, &(u)->c_cflag); \ + put_user((k)->c_lflag, &(u)->c_lflag); \ + put_user((k)->c_line, &(u)->c_line); \ + copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \ + if(!((k)->c_lflag & ICANON)) { \ + put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ + put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ + } else { \ + put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ + put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ + } \ + 0; \ +}) + +#endif /* __KERNEL__ */ + +#endif /* _SPARC64_TERMIOS_H */ diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h new file mode 100644 index 000000000000..517caaba1c87 --- /dev/null +++ b/include/asm-sparc64/thread_info.h @@ -0,0 +1,252 @@ +/* $Id: thread_info.h,v 1.1 2002/02/10 00:00:58 davem Exp $ + * thread_info.h: sparc64 low-level thread information + * + * Copyright (C) 2002 David S. Miller (davem@redhat.com) + */ + +#ifndef _ASM_THREAD_INFO_H +#define _ASM_THREAD_INFO_H + +#ifdef __KERNEL__ + +#define NSWINS 7 + +#define TI_FLAG_BYTE_FAULT_CODE 0 +#define TI_FLAG_FAULT_CODE_SHIFT 56 +#define TI_FLAG_BYTE_WSTATE 1 +#define TI_FLAG_WSTATE_SHIFT 48 +#define TI_FLAG_BYTE_CWP 2 +#define TI_FLAG_CWP_SHIFT 40 +#define TI_FLAG_BYTE_CURRENT_DS 3 +#define TI_FLAG_CURRENT_DS_SHIFT 32 +#define TI_FLAG_BYTE_FPDEPTH 4 +#define TI_FLAG_FPDEPTH_SHIFT 24 +#define TI_FLAG_BYTE_WSAVED 5 +#define TI_FLAG_WSAVED_SHIFT 16 + +#include <asm/page.h> + +#ifndef __ASSEMBLY__ + +#include <asm/ptrace.h> +#include <asm/types.h> + +struct task_struct; +struct exec_domain; + +struct thread_info { + /* D$ line 1 */ + struct task_struct *task; + unsigned long flags; + __u8 cpu; + __u8 fpsaved[7]; + unsigned long ksp; + + /* D$ line 2 */ + unsigned long fault_address; + struct pt_regs *kregs; + struct exec_domain *exec_domain; + int preempt_count; + int __pad; + + unsigned long *utraps; + + struct reg_window reg_window[NSWINS]; + unsigned long rwbuf_stkptrs[NSWINS]; + + unsigned long gsr[7]; + unsigned long xfsr[7]; + + __u64 __user *user_cntd0; + __u64 __user *user_cntd1; + __u64 kernel_cntd0, kernel_cntd1; + __u64 pcr_reg; + + __u64 cee_stuff; + + struct restart_block restart_block; + + unsigned long fpregs[0] __attribute__ ((aligned(64))); +}; + +#endif /* !(__ASSEMBLY__) */ + +/* offsets into the thread_info struct for assembly code access */ +#define TI_TASK 0x00000000 +#define TI_FLAGS 0x00000008 +#define TI_FAULT_CODE (TI_FLAGS + TI_FLAG_BYTE_FAULT_CODE) +#define TI_WSTATE (TI_FLAGS + TI_FLAG_BYTE_WSTATE) +#define TI_CWP (TI_FLAGS + TI_FLAG_BYTE_CWP) +#define TI_CURRENT_DS (TI_FLAGS + TI_FLAG_BYTE_CURRENT_DS) +#define TI_FPDEPTH (TI_FLAGS + TI_FLAG_BYTE_FPDEPTH) +#define TI_WSAVED (TI_FLAGS + TI_FLAG_BYTE_WSAVED) +#define TI_CPU 0x00000010 +#define TI_FPSAVED 0x00000011 +#define TI_KSP 0x00000018 +#define TI_FAULT_ADDR 0x00000020 +#define TI_KREGS 0x00000028 +#define TI_EXEC_DOMAIN 0x00000030 +#define TI_PRE_COUNT 0x00000038 +#define TI_UTRAPS 0x00000040 +#define TI_REG_WINDOW 0x00000048 +#define TI_RWIN_SPTRS 0x000003c8 +#define TI_GSR 0x00000400 +#define TI_XFSR 0x00000438 +#define TI_USER_CNTD0 0x00000470 +#define TI_USER_CNTD1 0x00000478 +#define TI_KERN_CNTD0 0x00000480 +#define TI_KERN_CNTD1 0x00000488 +#define TI_PCR 0x00000490 +#define TI_CEE_STUFF 0x00000498 +#define TI_RESTART_BLOCK 0x000004a0 +#define TI_FPREGS 0x00000500 + +/* We embed this in the uppermost byte of thread_info->flags */ +#define FAULT_CODE_WRITE 0x01 /* Write access, implies D-TLB */ +#define FAULT_CODE_DTLB 0x02 /* Miss happened in D-TLB */ +#define FAULT_CODE_ITLB 0x04 /* Miss happened in I-TLB */ +#define FAULT_CODE_WINFIXUP 0x08 /* Miss happened during spill/fill */ +#define FAULT_CODE_BLKCOMMIT 0x10 /* Use blk-commit ASI in copy_page */ + +#if PAGE_SHIFT == 13 +#define THREAD_SIZE (2*PAGE_SIZE) +#define THREAD_SHIFT (PAGE_SHIFT + 1) +#else /* PAGE_SHIFT == 13 */ +#define THREAD_SIZE PAGE_SIZE +#define THREAD_SHIFT PAGE_SHIFT +#endif /* PAGE_SHIFT == 13 */ + +#define PREEMPT_ACTIVE 0x4000000 + +/* + * macros/functions for gaining access to the thread information structure + * + * preempt_count needs to be 1 initially, until the scheduler is functional. + */ +#ifndef __ASSEMBLY__ + +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .flags = ((unsigned long)ASI_P) << TI_FLAG_CURRENT_DS_SHIFT, \ + .exec_domain = &default_exec_domain, \ + .preempt_count = 1, \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ +} + +#define init_thread_info (init_thread_union.thread_info) +#define init_stack (init_thread_union.stack) + +/* how to get the thread information struct from C */ +register struct thread_info *current_thread_info_reg asm("g6"); +#define current_thread_info() (current_thread_info_reg) + +/* thread information allocation */ +#if PAGE_SHIFT == 13 +#define __THREAD_INFO_ORDER 1 +#else /* PAGE_SHIFT == 13 */ +#define __THREAD_INFO_ORDER 0 +#endif /* PAGE_SHIFT == 13 */ + +#ifdef CONFIG_DEBUG_STACK_USAGE +#define alloc_thread_info(tsk) \ +({ \ + struct thread_info *ret; \ + \ + ret = (struct thread_info *) \ + __get_free_pages(GFP_KERNEL, __THREAD_INFO_ORDER); \ + if (ret) \ + memset(ret, 0, PAGE_SIZE<<__THREAD_INFO_ORDER); \ + ret; \ +}) +#else +#define alloc_thread_info(tsk) \ + ((struct thread_info *)__get_free_pages(GFP_KERNEL, __THREAD_INFO_ORDER)) +#endif + +#define free_thread_info(ti) \ + free_pages((unsigned long)(ti),__THREAD_INFO_ORDER) + +#define __thread_flag_byte_ptr(ti) \ + ((unsigned char *)(&((ti)->flags))) +#define __cur_thread_flag_byte_ptr __thread_flag_byte_ptr(current_thread_info()) + +#define get_thread_fault_code() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FAULT_CODE]) +#define set_thread_fault_code(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FAULT_CODE] = (val)) +#define get_thread_wstate() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSTATE]) +#define set_thread_wstate(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSTATE] = (val)) +#define get_thread_cwp() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP]) +#define set_thread_cwp(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP] = (val)) +#define get_thread_current_ds() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS]) +#define set_thread_current_ds(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS] = (val)) +#define get_thread_fpdepth() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH]) +#define set_thread_fpdepth(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH] = (val)) +#define get_thread_wsaved() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED]) +#define set_thread_wsaved(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED] = (val)) + +#endif /* !(__ASSEMBLY__) */ + +/* + * Thread information flags, only 16 bits are available as we encode + * other values into the upper 6 bytes. + * + * On trap return we need to test several values: + * + * user: need_resched, notify_resume, sigpending, wsaved, perfctr + * kernel: fpdepth + * + * So to check for work in the kernel case we simply load the fpdepth + * byte out of the flags and test it. For the user case we encode the + * lower 3 bytes of flags as follows: + * ---------------------------------------- + * | wsaved | flags byte 1 | flags byte 2 | + * ---------------------------------------- + * This optimizes the user test into: + * ldx [%g6 + TI_FLAGS], REG1 + * sethi %hi(_TIF_USER_WORK_MASK), REG2 + * or REG2, %lo(_TIF_USER_WORK_MASK), REG2 + * andcc REG1, REG2, %g0 + * be,pt no_work_to_do + * nop + */ +#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ +#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ +#define TIF_SIGPENDING 2 /* signal pending */ +#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ +#define TIF_PERFCTR 4 /* performance counters active */ +#define TIF_UNALIGNED 5 /* allowed to do unaligned accesses */ +#define TIF_NEWSIGNALS 6 /* wants new-style signals */ +#define TIF_32BIT 7 /* 32-bit binary */ +#define TIF_NEWCHILD 8 /* just-spawned child process */ +/* TIF_* value 9 is available */ +#define TIF_POLLING_NRFLAG 10 +#define TIF_SYSCALL_SUCCESS 11 +/* NOTE: Thread flags >= 12 should be ones we have no interest + * in using in assembly, else we can't use the mask as + * an immediate value in instructions such as andcc. + */ +#define TIF_ABI_PENDING 12 +#define TIF_MEMDIE 13 + +#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) +#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) +#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) +#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) +#define _TIF_PERFCTR (1<<TIF_PERFCTR) +#define _TIF_UNALIGNED (1<<TIF_UNALIGNED) +#define _TIF_NEWSIGNALS (1<<TIF_NEWSIGNALS) +#define _TIF_32BIT (1<<TIF_32BIT) +#define _TIF_NEWCHILD (1<<TIF_NEWCHILD) +#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) +#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING) +#define _TIF_SYSCALL_SUCCESS (1<<TIF_SYSCALL_SUCCESS) + +#define _TIF_USER_WORK_MASK ((0xff << TI_FLAG_WSAVED_SHIFT) | \ + (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \ + _TIF_NEED_RESCHED | _TIF_PERFCTR)) + +#endif /* __KERNEL__ */ + +#endif /* _ASM_THREAD_INFO_H */ diff --git a/include/asm-sparc64/timer.h b/include/asm-sparc64/timer.h new file mode 100644 index 000000000000..ba33a2b6b7bd --- /dev/null +++ b/include/asm-sparc64/timer.h @@ -0,0 +1,74 @@ +/* $Id: timer.h,v 1.3 2000/05/09 17:40:15 davem Exp $ + * timer.h: System timer definitions for sun5. + * + * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC64_TIMER_H +#define _SPARC64_TIMER_H + +#include <linux/types.h> + +/* How timers work: + * + * On uniprocessors we just use counter zero for the system wide + * ticker, this performs thread scheduling, clock book keeping, + * and runs timer based events. Previously we used the Ultra + * %tick interrupt for this purpose. + * + * On multiprocessors we pick one cpu as the master level 10 tick + * processor. Here this counter zero tick handles clock book + * keeping and timer events only. Each Ultra has it's level + * 14 %tick interrupt set to fire off as well, even the master + * tick cpu runs this locally. This ticker performs thread + * scheduling, system/user tick counting for the current thread, + * and also profiling if enabled. + */ + +#include <linux/config.h> + +/* Two timers, traditionally steered to PIL's 10 and 14 respectively. + * But since INO packets are used on sun5, we could use any PIL level + * we like, however for now we use the normal ones. + * + * The 'reg' and 'interrupts' properties for these live in nodes named + * 'counter-timer'. The first of three 'reg' properties describe where + * the sun5_timer registers are. The other two I have no idea. (XXX) + */ +struct sun5_timer { + u64 count0; + u64 limit0; + u64 count1; + u64 limit1; +}; + +#define SUN5_LIMIT_ENABLE 0x80000000 +#define SUN5_LIMIT_TOZERO 0x40000000 +#define SUN5_LIMIT_ZRESTART 0x20000000 +#define SUN5_LIMIT_CMASK 0x1fffffff + +/* Given a HZ value, set the limit register to so that the timer IRQ + * gets delivered that often. + */ +#define SUN5_HZ_TO_LIMIT(__hz) (1000000/(__hz)) + +struct sparc64_tick_ops { + void (*init_tick)(unsigned long); + unsigned long (*get_tick)(void); + unsigned long (*get_compare)(void); + unsigned long (*add_tick)(unsigned long, unsigned long); + unsigned long (*add_compare)(unsigned long); + unsigned long softint_mask; +}; + +extern struct sparc64_tick_ops *tick_ops; + +#ifdef CONFIG_SMP +extern unsigned long timer_tick_offset; +struct pt_regs; +extern void timer_tick_interrupt(struct pt_regs *); +#endif + +extern unsigned long sparc64_get_clock_tick(unsigned int cpu); + +#endif /* _SPARC64_TIMER_H */ diff --git a/include/asm-sparc64/timex.h b/include/asm-sparc64/timex.h new file mode 100644 index 000000000000..9e8d4175bcb2 --- /dev/null +++ b/include/asm-sparc64/timex.h @@ -0,0 +1,17 @@ +/* + * linux/include/asm-sparc64/timex.h + * + * sparc64 architecture timex specifications + */ +#ifndef _ASMsparc64_TIMEX_H +#define _ASMsparc64_TIMEX_H + +#include <asm/timer.h> + +#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ + +/* Getting on the cycle counter on sparc64. */ +typedef unsigned long cycles_t; +#define get_cycles() tick_ops->get_tick() + +#endif diff --git a/include/asm-sparc64/tlb.h b/include/asm-sparc64/tlb.h new file mode 100644 index 000000000000..9baf57db01d2 --- /dev/null +++ b/include/asm-sparc64/tlb.h @@ -0,0 +1,128 @@ +#ifndef _SPARC64_TLB_H +#define _SPARC64_TLB_H + +#include <linux/config.h> +#include <linux/swap.h> +#include <asm/pgalloc.h> +#include <asm/tlbflush.h> +#include <asm/mmu_context.h> + +#define TLB_BATCH_NR 192 + +/* + * For UP we don't need to worry about TLB flush + * and page free order so much.. + */ +#ifdef CONFIG_SMP + #define FREE_PTE_NR 506 + #define tlb_fast_mode(bp) ((bp)->pages_nr == ~0U) +#else + #define FREE_PTE_NR 1 + #define tlb_fast_mode(bp) 1 +#endif + +struct mmu_gather { + struct mm_struct *mm; + unsigned int pages_nr; + unsigned int need_flush; + unsigned int tlb_frozen; + unsigned int tlb_nr; + unsigned long freed; + unsigned long vaddrs[TLB_BATCH_NR]; + struct page *pages[FREE_PTE_NR]; +}; + +DECLARE_PER_CPU(struct mmu_gather, mmu_gathers); + +#ifdef CONFIG_SMP +extern void smp_flush_tlb_pending(struct mm_struct *, + unsigned long, unsigned long *); +#endif + +extern void __flush_tlb_pending(unsigned long, unsigned long, unsigned long *); +extern void flush_tlb_pending(void); + +static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush) +{ + struct mmu_gather *mp = &__get_cpu_var(mmu_gathers); + + BUG_ON(mp->tlb_nr); + + mp->mm = mm; + mp->pages_nr = num_online_cpus() > 1 ? 0U : ~0U; + mp->tlb_frozen = full_mm_flush; + mp->freed = 0; + + return mp; +} + + +static inline void tlb_flush_mmu(struct mmu_gather *mp) +{ + if (mp->need_flush) { + mp->need_flush = 0; + if (!tlb_fast_mode(mp)) { + free_pages_and_swap_cache(mp->pages, mp->pages_nr); + mp->pages_nr = 0; + } + } + +} + +#ifdef CONFIG_SMP +extern void smp_flush_tlb_mm(struct mm_struct *mm); +#define do_flush_tlb_mm(mm) smp_flush_tlb_mm(mm) +#else +#define do_flush_tlb_mm(mm) __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT) +#endif + +static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, unsigned long end) +{ + unsigned long freed = mp->freed; + struct mm_struct *mm = mp->mm; + unsigned long rss = get_mm_counter(mm, rss); + + if (rss < freed) + freed = rss; + add_mm_counter(mm, rss, -freed); + + tlb_flush_mmu(mp); + + if (mp->tlb_frozen) { + if (CTX_VALID(mm->context)) + do_flush_tlb_mm(mm); + mp->tlb_frozen = 0; + } else + flush_tlb_pending(); + + /* keep the page table cache within bounds */ + check_pgt_cache(); +} + +static inline unsigned int tlb_is_full_mm(struct mmu_gather *mp) +{ + return mp->tlb_frozen; +} + +static inline void tlb_remove_page(struct mmu_gather *mp, struct page *page) +{ + mp->need_flush = 1; + if (tlb_fast_mode(mp)) { + free_page_and_swap_cache(page); + return; + } + mp->pages[mp->pages_nr++] = page; + if (mp->pages_nr >= FREE_PTE_NR) + tlb_flush_mmu(mp); +} + +#define tlb_remove_tlb_entry(mp,ptep,addr) do { } while (0) +#define pte_free_tlb(mp,ptepage) pte_free(ptepage) +#define pmd_free_tlb(mp,pmdp) pmd_free(pmdp) +#define pud_free_tlb(tlb,pudp) __pud_free_tlb(tlb,pudp) + +#define tlb_migrate_finish(mm) do { } while (0) +#define tlb_start_vma(tlb, vma) do { } while (0) +#define tlb_end_vma(tlb, vma) do { } while (0) + +#endif /* _SPARC64_TLB_H */ diff --git a/include/asm-sparc64/tlbflush.h b/include/asm-sparc64/tlbflush.h new file mode 100644 index 000000000000..3ef9909ac3ac --- /dev/null +++ b/include/asm-sparc64/tlbflush.h @@ -0,0 +1,41 @@ +#ifndef _SPARC64_TLBFLUSH_H +#define _SPARC64_TLBFLUSH_H + +#include <linux/config.h> +#include <linux/mm.h> +#include <asm/mmu_context.h> + +/* TLB flush operations. */ + +extern void flush_tlb_pending(void); + +#define flush_tlb_range(vma,start,end) \ + do { (void)(start); flush_tlb_pending(); } while (0) +#define flush_tlb_page(vma,addr) flush_tlb_pending() +#define flush_tlb_mm(mm) flush_tlb_pending() + +extern void __flush_tlb_all(void); +extern void __flush_tlb_page(unsigned long context, unsigned long page, unsigned long r); + +extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end); + +#ifndef CONFIG_SMP + +#define flush_tlb_all() __flush_tlb_all() +#define flush_tlb_kernel_range(start,end) \ + __flush_tlb_kernel_range(start,end) + +#else /* CONFIG_SMP */ + +extern void smp_flush_tlb_all(void); +extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end); + +#define flush_tlb_all() smp_flush_tlb_all() +#define flush_tlb_kernel_range(start, end) \ + smp_flush_tlb_kernel_range(start, end) + +#endif /* ! CONFIG_SMP */ + +extern void flush_tlb_pgtables(struct mm_struct *, unsigned long, unsigned long); + +#endif /* _SPARC64_TLBFLUSH_H */ diff --git a/include/asm-sparc64/topology.h b/include/asm-sparc64/topology.h new file mode 100644 index 000000000000..0e234e201bd6 --- /dev/null +++ b/include/asm-sparc64/topology.h @@ -0,0 +1,6 @@ +#ifndef _ASM_SPARC64_TOPOLOGY_H +#define _ASM_SPARC64_TOPOLOGY_H + +#include <asm-generic/topology.h> + +#endif /* _ASM_SPARC64_TOPOLOGY_H */ diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h new file mode 100644 index 000000000000..2784f80094c3 --- /dev/null +++ b/include/asm-sparc64/ttable.h @@ -0,0 +1,407 @@ +/* $Id: ttable.h,v 1.18 2002/02/09 19:49:32 davem Exp $ */ +#ifndef _SPARC64_TTABLE_H +#define _SPARC64_TTABLE_H + +#include <linux/config.h> +#include <asm/utrap.h> + +#ifdef __ASSEMBLY__ +#include <asm/thread_info.h> +#endif + +#define BOOT_KERNEL b sparc64_boot; nop; nop; nop; nop; nop; nop; nop; + +/* We need a "cleaned" instruction... */ +#define CLEAN_WINDOW \ + rdpr %cleanwin, %l0; add %l0, 1, %l0; \ + wrpr %l0, 0x0, %cleanwin; \ + clr %o0; clr %o1; clr %o2; clr %o3; \ + clr %o4; clr %o5; clr %o6; clr %o7; \ + clr %l0; clr %l1; clr %l2; clr %l3; \ + clr %l4; clr %l5; clr %l6; clr %l7; \ + retry; \ + nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; + +#define TRAP(routine) \ + sethi %hi(109f), %g7; \ + ba,pt %xcc, etrap; \ +109: or %g7, %lo(109b), %g7; \ + call routine; \ + add %sp, PTREGS_OFF, %o0; \ + ba,pt %xcc, rtrap; \ + clr %l6; \ + nop; + +#define TRAP_7INSNS(routine) \ + sethi %hi(109f), %g7; \ + ba,pt %xcc, etrap; \ +109: or %g7, %lo(109b), %g7; \ + call routine; \ + add %sp, PTREGS_OFF, %o0; \ + ba,pt %xcc, rtrap; \ + clr %l6; + +#define TRAP_SAVEFPU(routine) \ + sethi %hi(109f), %g7; \ + ba,pt %xcc, do_fptrap; \ +109: or %g7, %lo(109b), %g7; \ + call routine; \ + add %sp, PTREGS_OFF, %o0; \ + ba,pt %xcc, rtrap; \ + clr %l6; \ + nop; + +#define TRAP_NOSAVE(routine) \ + ba,pt %xcc, routine; \ + nop; \ + nop; nop; nop; nop; nop; nop; + +#define TRAP_NOSAVE_7INSNS(routine) \ + ba,pt %xcc, routine; \ + nop; \ + nop; nop; nop; nop; nop; + +#define TRAPTL1(routine) \ + sethi %hi(109f), %g7; \ + ba,pt %xcc, etraptl1; \ +109: or %g7, %lo(109b), %g7; \ + call routine; \ + add %sp, PTREGS_OFF, %o0; \ + ba,pt %xcc, rtrap; \ + clr %l6; \ + nop; + +#define TRAP_ARG(routine, arg) \ + sethi %hi(109f), %g7; \ + ba,pt %xcc, etrap; \ +109: or %g7, %lo(109b), %g7; \ + add %sp, PTREGS_OFF, %o0; \ + call routine; \ + mov arg, %o1; \ + ba,pt %xcc, rtrap; \ + clr %l6; + +#define TRAPTL1_ARG(routine, arg) \ + sethi %hi(109f), %g7; \ + ba,pt %xcc, etraptl1; \ +109: or %g7, %lo(109b), %g7; \ + add %sp, PTREGS_OFF, %o0; \ + call routine; \ + mov arg, %o1; \ + ba,pt %xcc, rtrap; \ + clr %l6; + +#define SYSCALL_TRAP(routine, systbl) \ + sethi %hi(109f), %g7; \ + ba,pt %xcc, scetrap; \ +109: or %g7, %lo(109b), %g7; \ + sethi %hi(systbl), %l7; \ + ba,pt %xcc, routine; \ + or %l7, %lo(systbl), %l7; \ + nop; nop; + +#define INDIRECT_SOLARIS_SYSCALL(num) \ + sethi %hi(109f), %g7; \ + ba,pt %xcc, etrap; \ +109: or %g7, %lo(109b), %g7; \ + ba,pt %xcc, tl0_solaris + 0xc; \ + mov num, %g1; \ + nop;nop;nop; + +#define TRAP_UTRAP(handler,lvl) \ + ldx [%g6 + TI_UTRAPS], %g1; \ + sethi %hi(109f), %g7; \ + brz,pn %g1, utrap; \ + or %g7, %lo(109f), %g7; \ + ba,pt %xcc, utrap; \ +109: ldx [%g1 + handler*8], %g1; \ + ba,pt %xcc, utrap_ill; \ + mov lvl, %o1; + +#ifdef CONFIG_SUNOS_EMUL +#define SUNOS_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sunos_sys_table) +#else +#define SUNOS_SYSCALL_TRAP TRAP(sunos_syscall) +#endif +#ifdef CONFIG_COMPAT +#define LINUX_32BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sys_call_table32) +#else +#define LINUX_32BIT_SYSCALL_TRAP BTRAP(0x110) +#endif +#define LINUX_64BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall, sys_call_table64) +#define GETCC_TRAP TRAP(getcc) +#define SETCC_TRAP TRAP(setcc) +#ifdef CONFIG_SOLARIS_EMUL +#define SOLARIS_SYSCALL_TRAP TRAP(solaris_sparc_syscall) +#else +#define SOLARIS_SYSCALL_TRAP TRAP(solaris_syscall) +#endif +/* FIXME: Write these actually */ +#define NETBSD_SYSCALL_TRAP TRAP(netbsd_syscall) +#define BREAKPOINT_TRAP TRAP(breakpoint_trap) + +#define TRAP_IRQ(routine, level) \ + rdpr %pil, %g2; \ + wrpr %g0, 15, %pil; \ + b,pt %xcc, etrap_irq; \ + rd %pc, %g7; \ + mov level, %o0; \ + call routine; \ + add %sp, PTREGS_OFF, %o1; \ + ba,a,pt %xcc, rtrap_irq; + +#define TICK_SMP_IRQ \ + rdpr %pil, %g2; \ + wrpr %g0, 15, %pil; \ + sethi %hi(109f), %g7; \ + b,pt %xcc, etrap_irq; \ +109: or %g7, %lo(109b), %g7; \ + call smp_percpu_timer_interrupt; \ + add %sp, PTREGS_OFF, %o0; \ + ba,a,pt %xcc, rtrap_irq; + +#define TRAP_IVEC TRAP_NOSAVE(do_ivec) + +#define BTRAP(lvl) TRAP_ARG(bad_trap, lvl) + +#define BTRAPTL1(lvl) TRAPTL1_ARG(bad_trap_tl1, lvl) + +#define FLUSH_WINDOW_TRAP \ + ba,pt %xcc, etrap; \ + rd %pc, %g7; \ + flushw; \ + ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1; \ + add %l1, 4, %l2; \ + stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]; \ + ba,pt %xcc, rtrap_clr_l6; \ + stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]; + +#ifdef CONFIG_KPROBES +#define KPROBES_TRAP(lvl) TRAP_IRQ(kprobe_trap, lvl) +#else +#define KPROBES_TRAP(lvl) TRAP_ARG(bad_trap, lvl) +#endif + +/* Before touching these macros, you owe it to yourself to go and + * see how arch/sparc64/kernel/winfixup.S works... -DaveM + * + * For the user cases we used to use the %asi register, but + * it turns out that the "wr xxx, %asi" costs ~5 cycles, so + * now we use immediate ASI loads and stores instead. Kudos + * to Greg Onufer for pointing out this performance anomaly. + * + * Further note that we cannot use the g2, g4, g5, and g7 alternate + * globals in the spill routines, check out the save instruction in + * arch/sparc64/kernel/etrap.S to see what I mean about g2, and + * g4/g5 are the globals which are preserved by etrap processing + * for the caller of it. The g7 register is the return pc for + * etrap. Finally, g6 is the current thread register so we cannot + * us it in the spill handlers either. Most of these rules do not + * apply to fill processing, only g6 is not usable. + */ + +/* Normal kernel spill */ +#define SPILL_0_NORMAL \ + stx %l0, [%sp + STACK_BIAS + 0x00]; \ + stx %l1, [%sp + STACK_BIAS + 0x08]; \ + stx %l2, [%sp + STACK_BIAS + 0x10]; \ + stx %l3, [%sp + STACK_BIAS + 0x18]; \ + stx %l4, [%sp + STACK_BIAS + 0x20]; \ + stx %l5, [%sp + STACK_BIAS + 0x28]; \ + stx %l6, [%sp + STACK_BIAS + 0x30]; \ + stx %l7, [%sp + STACK_BIAS + 0x38]; \ + stx %i0, [%sp + STACK_BIAS + 0x40]; \ + stx %i1, [%sp + STACK_BIAS + 0x48]; \ + stx %i2, [%sp + STACK_BIAS + 0x50]; \ + stx %i3, [%sp + STACK_BIAS + 0x58]; \ + stx %i4, [%sp + STACK_BIAS + 0x60]; \ + stx %i5, [%sp + STACK_BIAS + 0x68]; \ + stx %i6, [%sp + STACK_BIAS + 0x70]; \ + stx %i7, [%sp + STACK_BIAS + 0x78]; \ + saved; retry; nop; nop; nop; nop; nop; nop; \ + nop; nop; nop; nop; nop; nop; nop; nop; + +/* Normal 64bit spill */ +#define SPILL_1_GENERIC(ASI) \ + add %sp, STACK_BIAS + 0x00, %g1; \ + stxa %l0, [%g1 + %g0] ASI; \ + mov 0x08, %g3; \ + stxa %l1, [%g1 + %g3] ASI; \ + add %g1, 0x10, %g1; \ + stxa %l2, [%g1 + %g0] ASI; \ + stxa %l3, [%g1 + %g3] ASI; \ + add %g1, 0x10, %g1; \ + stxa %l4, [%g1 + %g0] ASI; \ + stxa %l5, [%g1 + %g3] ASI; \ + add %g1, 0x10, %g1; \ + stxa %l6, [%g1 + %g0] ASI; \ + stxa %l7, [%g1 + %g3] ASI; \ + add %g1, 0x10, %g1; \ + stxa %i0, [%g1 + %g0] ASI; \ + stxa %i1, [%g1 + %g3] ASI; \ + add %g1, 0x10, %g1; \ + stxa %i2, [%g1 + %g0] ASI; \ + stxa %i3, [%g1 + %g3] ASI; \ + add %g1, 0x10, %g1; \ + stxa %i4, [%g1 + %g0] ASI; \ + stxa %i5, [%g1 + %g3] ASI; \ + add %g1, 0x10, %g1; \ + stxa %i6, [%g1 + %g0] ASI; \ + stxa %i7, [%g1 + %g3] ASI; \ + saved; \ + retry; nop; nop; \ + b,a,pt %xcc, spill_fixup_dax; \ + b,a,pt %xcc, spill_fixup_mna; \ + b,a,pt %xcc, spill_fixup; + +/* Normal 32bit spill */ +#define SPILL_2_GENERIC(ASI) \ + srl %sp, 0, %sp; \ + stwa %l0, [%sp + %g0] ASI; \ + mov 0x04, %g3; \ + stwa %l1, [%sp + %g3] ASI; \ + add %sp, 0x08, %g1; \ + stwa %l2, [%g1 + %g0] ASI; \ + stwa %l3, [%g1 + %g3] ASI; \ + add %g1, 0x08, %g1; \ + stwa %l4, [%g1 + %g0] ASI; \ + stwa %l5, [%g1 + %g3] ASI; \ + add %g1, 0x08, %g1; \ + stwa %l6, [%g1 + %g0] ASI; \ + stwa %l7, [%g1 + %g3] ASI; \ + add %g1, 0x08, %g1; \ + stwa %i0, [%g1 + %g0] ASI; \ + stwa %i1, [%g1 + %g3] ASI; \ + add %g1, 0x08, %g1; \ + stwa %i2, [%g1 + %g0] ASI; \ + stwa %i3, [%g1 + %g3] ASI; \ + add %g1, 0x08, %g1; \ + stwa %i4, [%g1 + %g0] ASI; \ + stwa %i5, [%g1 + %g3] ASI; \ + add %g1, 0x08, %g1; \ + stwa %i6, [%g1 + %g0] ASI; \ + stwa %i7, [%g1 + %g3] ASI; \ + saved; \ + retry; nop; nop; \ + b,a,pt %xcc, spill_fixup_dax; \ + b,a,pt %xcc, spill_fixup_mna; \ + b,a,pt %xcc, spill_fixup; + +#define SPILL_1_NORMAL SPILL_1_GENERIC(ASI_AIUP) +#define SPILL_2_NORMAL SPILL_2_GENERIC(ASI_AIUP) +#define SPILL_3_NORMAL SPILL_0_NORMAL +#define SPILL_4_NORMAL SPILL_0_NORMAL +#define SPILL_5_NORMAL SPILL_0_NORMAL +#define SPILL_6_NORMAL SPILL_0_NORMAL +#define SPILL_7_NORMAL SPILL_0_NORMAL + +#define SPILL_0_OTHER SPILL_0_NORMAL +#define SPILL_1_OTHER SPILL_1_GENERIC(ASI_AIUS) +#define SPILL_2_OTHER SPILL_2_GENERIC(ASI_AIUS) +#define SPILL_3_OTHER SPILL_3_NORMAL +#define SPILL_4_OTHER SPILL_4_NORMAL +#define SPILL_5_OTHER SPILL_5_NORMAL +#define SPILL_6_OTHER SPILL_6_NORMAL +#define SPILL_7_OTHER SPILL_7_NORMAL + +/* Normal kernel fill */ +#define FILL_0_NORMAL \ + ldx [%sp + STACK_BIAS + 0x00], %l0; \ + ldx [%sp + STACK_BIAS + 0x08], %l1; \ + ldx [%sp + STACK_BIAS + 0x10], %l2; \ + ldx [%sp + STACK_BIAS + 0x18], %l3; \ + ldx [%sp + STACK_BIAS + 0x20], %l4; \ + ldx [%sp + STACK_BIAS + 0x28], %l5; \ + ldx [%sp + STACK_BIAS + 0x30], %l6; \ + ldx [%sp + STACK_BIAS + 0x38], %l7; \ + ldx [%sp + STACK_BIAS + 0x40], %i0; \ + ldx [%sp + STACK_BIAS + 0x48], %i1; \ + ldx [%sp + STACK_BIAS + 0x50], %i2; \ + ldx [%sp + STACK_BIAS + 0x58], %i3; \ + ldx [%sp + STACK_BIAS + 0x60], %i4; \ + ldx [%sp + STACK_BIAS + 0x68], %i5; \ + ldx [%sp + STACK_BIAS + 0x70], %i6; \ + ldx [%sp + STACK_BIAS + 0x78], %i7; \ + restored; retry; nop; nop; nop; nop; nop; nop; \ + nop; nop; nop; nop; nop; nop; nop; nop; + +/* Normal 64bit fill */ +#define FILL_1_GENERIC(ASI) \ + add %sp, STACK_BIAS + 0x00, %g1; \ + ldxa [%g1 + %g0] ASI, %l0; \ + mov 0x08, %g2; \ + mov 0x10, %g3; \ + ldxa [%g1 + %g2] ASI, %l1; \ + mov 0x18, %g5; \ + ldxa [%g1 + %g3] ASI, %l2; \ + ldxa [%g1 + %g5] ASI, %l3; \ + add %g1, 0x20, %g1; \ + ldxa [%g1 + %g0] ASI, %l4; \ + ldxa [%g1 + %g2] ASI, %l5; \ + ldxa [%g1 + %g3] ASI, %l6; \ + ldxa [%g1 + %g5] ASI, %l7; \ + add %g1, 0x20, %g1; \ + ldxa [%g1 + %g0] ASI, %i0; \ + ldxa [%g1 + %g2] ASI, %i1; \ + ldxa [%g1 + %g3] ASI, %i2; \ + ldxa [%g1 + %g5] ASI, %i3; \ + add %g1, 0x20, %g1; \ + ldxa [%g1 + %g0] ASI, %i4; \ + ldxa [%g1 + %g2] ASI, %i5; \ + ldxa [%g1 + %g3] ASI, %i6; \ + ldxa [%g1 + %g5] ASI, %i7; \ + restored; \ + retry; nop; nop; nop; nop; \ + b,a,pt %xcc, fill_fixup_dax; \ + b,a,pt %xcc, fill_fixup_mna; \ + b,a,pt %xcc, fill_fixup; + +/* Normal 32bit fill */ +#define FILL_2_GENERIC(ASI) \ + srl %sp, 0, %sp; \ + lduwa [%sp + %g0] ASI, %l0; \ + mov 0x04, %g2; \ + mov 0x08, %g3; \ + lduwa [%sp + %g2] ASI, %l1; \ + mov 0x0c, %g5; \ + lduwa [%sp + %g3] ASI, %l2; \ + lduwa [%sp + %g5] ASI, %l3; \ + add %sp, 0x10, %g1; \ + lduwa [%g1 + %g0] ASI, %l4; \ + lduwa [%g1 + %g2] ASI, %l5; \ + lduwa [%g1 + %g3] ASI, %l6; \ + lduwa [%g1 + %g5] ASI, %l7; \ + add %g1, 0x10, %g1; \ + lduwa [%g1 + %g0] ASI, %i0; \ + lduwa [%g1 + %g2] ASI, %i1; \ + lduwa [%g1 + %g3] ASI, %i2; \ + lduwa [%g1 + %g5] ASI, %i3; \ + add %g1, 0x10, %g1; \ + lduwa [%g1 + %g0] ASI, %i4; \ + lduwa [%g1 + %g2] ASI, %i5; \ + lduwa [%g1 + %g3] ASI, %i6; \ + lduwa [%g1 + %g5] ASI, %i7; \ + restored; \ + retry; nop; nop; nop; nop; \ + b,a,pt %xcc, fill_fixup_dax; \ + b,a,pt %xcc, fill_fixup_mna; \ + b,a,pt %xcc, fill_fixup; + +#define FILL_1_NORMAL FILL_1_GENERIC(ASI_AIUP) +#define FILL_2_NORMAL FILL_2_GENERIC(ASI_AIUP) +#define FILL_3_NORMAL FILL_0_NORMAL +#define FILL_4_NORMAL FILL_0_NORMAL +#define FILL_5_NORMAL FILL_0_NORMAL +#define FILL_6_NORMAL FILL_0_NORMAL +#define FILL_7_NORMAL FILL_0_NORMAL + +#define FILL_0_OTHER FILL_0_NORMAL +#define FILL_1_OTHER FILL_1_GENERIC(ASI_AIUS) +#define FILL_2_OTHER FILL_2_GENERIC(ASI_AIUS) +#define FILL_3_OTHER FILL_3_NORMAL +#define FILL_4_OTHER FILL_4_NORMAL +#define FILL_5_OTHER FILL_5_NORMAL +#define FILL_6_OTHER FILL_6_NORMAL +#define FILL_7_OTHER FILL_7_NORMAL + +#endif /* !(_SPARC64_TTABLE_H) */ diff --git a/include/asm-sparc64/types.h b/include/asm-sparc64/types.h new file mode 100644 index 000000000000..6248ed1a9a7a --- /dev/null +++ b/include/asm-sparc64/types.h @@ -0,0 +1,65 @@ +/* $Id: types.h,v 1.4 2001/10/09 02:24:35 davem Exp $ */ +#ifndef _SPARC64_TYPES_H +#define _SPARC64_TYPES_H + +/* + * 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. + */ + +#ifndef __ASSEMBLY__ + +typedef unsigned short umode_t; + +/* + * _xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space. + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +typedef __signed__ long __s64; +typedef unsigned long __u64; + +#endif /* __ASSEMBLY__ */ + +#ifdef __KERNEL__ + +#define BITS_PER_LONG 64 + +#ifndef __ASSEMBLY__ + +typedef __signed__ char s8; +typedef unsigned char u8; + +typedef __signed__ short s16; +typedef unsigned short u16; + +typedef __signed__ int s32; +typedef unsigned int u32; + +typedef __signed__ long s64; +typedef unsigned long u64; + +/* Dma addresses come in generic and 64-bit flavours. */ + +typedef u32 dma_addr_t; +typedef u64 dma64_addr_t; + +typedef unsigned short kmem_bufctl_t; + +#endif /* __ASSEMBLY__ */ + +#endif /* __KERNEL__ */ + +#endif /* defined(_SPARC64_TYPES_H) */ diff --git a/include/asm-sparc64/uaccess.h b/include/asm-sparc64/uaccess.h new file mode 100644 index 000000000000..5690142f82de --- /dev/null +++ b/include/asm-sparc64/uaccess.h @@ -0,0 +1,335 @@ +/* $Id: uaccess.h,v 1.35 2002/02/09 19:49:31 davem Exp $ */ +#ifndef _ASM_UACCESS_H +#define _ASM_UACCESS_H + +/* + * User space memory access functions + */ + +#ifdef __KERNEL__ +#include <linux/compiler.h> +#include <linux/sched.h> +#include <linux/string.h> +#include <asm/a.out.h> +#include <asm/asi.h> +#include <asm/system.h> +#include <asm/spitfire.h> +#include <asm-generic/uaccess.h> +#endif + +#ifndef __ASSEMBLY__ + +/* + * Sparc64 is segmented, though more like the M68K than the I386. + * We use the secondary ASI to address user memory, which references a + * completely different VM map, thus there is zero chance of the user + * doing something queer and tricking us into poking kernel memory. + * + * What is left here is basically what is needed for the other parts of + * the kernel that expect to be able to manipulate, erum, "segments". + * Or perhaps more properly, permissions. + * + * "For historical reasons, these macros are grossly misnamed." -Linus + */ + +#define KERNEL_DS ((mm_segment_t) { ASI_P }) +#define USER_DS ((mm_segment_t) { ASI_AIUS }) /* har har har */ + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +#define get_fs() ((mm_segment_t) { get_thread_current_ds() }) +#define get_ds() (KERNEL_DS) + +#define segment_eq(a,b) ((a).seg == (b).seg) + +#define set_fs(val) \ +do { \ + set_thread_current_ds((val).seg); \ + __asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg)); \ +} while(0) + +static inline int __access_ok(const void __user * addr, unsigned long size) +{ + return 1; +} + +static inline int access_ok(int type, const void __user * addr, unsigned long size) +{ + return 1; +} + +/* this function will go away soon - use access_ok() instead */ +static inline int __deprecated verify_area(int type, const void __user * addr, unsigned long size) +{ + return 0; +} + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + * + * There is a special way how to put a range of potentially faulting + * insns (like twenty ldd/std's with now intervening other instructions) + * You specify address of first in insn and 0 in fixup and in the next + * exception_table_entry you specify last potentially faulting insn + 1 + * and in fixup the routine which should handle the fault. + * That fixup code will get + * (faulting_insn_address - first_insn_in_the_range_address)/4 + * in %g2 (ie. index of the faulting instruction in the range). + */ + +struct exception_table_entry +{ + unsigned insn, fixup; +}; + +/* Special exable search, which handles ranges. Returns fixup */ +unsigned long search_extables_range(unsigned long addr, unsigned long *g2); + +extern void __ret_efault(void); + +/* Uh, these should become the main single-value transfer routines.. + * They automatically use the right size if we just have the right + * pointer type.. + * + * This gets kind of ugly. We want to return _two_ values in "get_user()" + * and yet we don't want to do any pointers, because that is too much + * of a performance impact. Thus we have a few rather ugly macros here, + * and hide all the ugliness from the user. + */ +#define put_user(x,ptr) ({ \ +unsigned long __pu_addr = (unsigned long)(ptr); \ +__chk_user_ptr(ptr); \ +__put_user_nocheck((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); }) + +#define get_user(x,ptr) ({ \ +unsigned long __gu_addr = (unsigned long)(ptr); \ +__chk_user_ptr(ptr); \ +__get_user_nocheck((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); }) + +#define __put_user(x,ptr) put_user(x,ptr) +#define __get_user(x,ptr) get_user(x,ptr) + +struct __large_struct { unsigned long buf[100]; }; +#define __m(x) ((struct __large_struct *)(x)) + +#define __put_user_nocheck(data,addr,size) ({ \ +register int __pu_ret; \ +switch (size) { \ +case 1: __put_user_asm(data,b,addr,__pu_ret); break; \ +case 2: __put_user_asm(data,h,addr,__pu_ret); break; \ +case 4: __put_user_asm(data,w,addr,__pu_ret); break; \ +case 8: __put_user_asm(data,x,addr,__pu_ret); break; \ +default: __pu_ret = __put_user_bad(); break; \ +} __pu_ret; }) + +#define __put_user_nocheck_ret(data,addr,size,retval) ({ \ +register int __foo __asm__ ("l1"); \ +switch (size) { \ +case 1: __put_user_asm_ret(data,b,addr,retval,__foo); break; \ +case 2: __put_user_asm_ret(data,h,addr,retval,__foo); break; \ +case 4: __put_user_asm_ret(data,w,addr,retval,__foo); break; \ +case 8: __put_user_asm_ret(data,x,addr,retval,__foo); break; \ +default: if (__put_user_bad()) return retval; break; \ +} }) + +#define __put_user_asm(x,size,addr,ret) \ +__asm__ __volatile__( \ + "/* Put user asm, inline. */\n" \ +"1:\t" "st"#size "a %1, [%2] %%asi\n\t" \ + "clr %0\n" \ +"2:\n\n\t" \ + ".section .fixup,#alloc,#execinstr\n\t" \ + ".align 4\n" \ +"3:\n\t" \ + "b 2b\n\t" \ + " mov %3, %0\n\n\t" \ + ".previous\n\t" \ + ".section __ex_table,#alloc\n\t" \ + ".align 4\n\t" \ + ".word 1b, 3b\n\t" \ + ".previous\n\n\t" \ + : "=r" (ret) : "r" (x), "r" (__m(addr)), \ + "i" (-EFAULT)) + +#define __put_user_asm_ret(x,size,addr,ret,foo) \ +if (__builtin_constant_p(ret) && ret == -EFAULT) \ +__asm__ __volatile__( \ + "/* Put user asm ret, inline. */\n" \ +"1:\t" "st"#size "a %1, [%2] %%asi\n\n\t" \ + ".section __ex_table,#alloc\n\t" \ + ".align 4\n\t" \ + ".word 1b, __ret_efault\n\n\t" \ + ".previous\n\n\t" \ + : "=r" (foo) : "r" (x), "r" (__m(addr))); \ +else \ +__asm__ __volatile__( \ + "/* Put user asm ret, inline. */\n" \ +"1:\t" "st"#size "a %1, [%2] %%asi\n\n\t" \ + ".section .fixup,#alloc,#execinstr\n\t" \ + ".align 4\n" \ +"3:\n\t" \ + "ret\n\t" \ + " restore %%g0, %3, %%o0\n\n\t" \ + ".previous\n\t" \ + ".section __ex_table,#alloc\n\t" \ + ".align 4\n\t" \ + ".word 1b, 3b\n\n\t" \ + ".previous\n\n\t" \ + : "=r" (foo) : "r" (x), "r" (__m(addr)), \ + "i" (ret)) + +extern int __put_user_bad(void); + +#define __get_user_nocheck(data,addr,size,type) ({ \ +register int __gu_ret; \ +register unsigned long __gu_val; \ +switch (size) { \ +case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \ +case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \ +case 4: __get_user_asm(__gu_val,uw,addr,__gu_ret); break; \ +case 8: __get_user_asm(__gu_val,x,addr,__gu_ret); break; \ +default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \ +} data = (type) __gu_val; __gu_ret; }) + +#define __get_user_nocheck_ret(data,addr,size,type,retval) ({ \ +register unsigned long __gu_val __asm__ ("l1"); \ +switch (size) { \ +case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \ +case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \ +case 4: __get_user_asm_ret(__gu_val,uw,addr,retval); break; \ +case 8: __get_user_asm_ret(__gu_val,x,addr,retval); break; \ +default: if (__get_user_bad()) return retval; \ +} data = (type) __gu_val; }) + +#define __get_user_asm(x,size,addr,ret) \ +__asm__ __volatile__( \ + "/* Get user asm, inline. */\n" \ +"1:\t" "ld"#size "a [%2] %%asi, %1\n\t" \ + "clr %0\n" \ +"2:\n\n\t" \ + ".section .fixup,#alloc,#execinstr\n\t" \ + ".align 4\n" \ +"3:\n\t" \ + "clr %1\n\t" \ + "b 2b\n\t" \ + " mov %3, %0\n\n\t" \ + ".previous\n\t" \ + ".section __ex_table,#alloc\n\t" \ + ".align 4\n\t" \ + ".word 1b, 3b\n\n\t" \ + ".previous\n\t" \ + : "=r" (ret), "=r" (x) : "r" (__m(addr)), \ + "i" (-EFAULT)) + +#define __get_user_asm_ret(x,size,addr,retval) \ +if (__builtin_constant_p(retval) && retval == -EFAULT) \ +__asm__ __volatile__( \ + "/* Get user asm ret, inline. */\n" \ +"1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t" \ + ".section __ex_table,#alloc\n\t" \ + ".align 4\n\t" \ + ".word 1b,__ret_efault\n\n\t" \ + ".previous\n\t" \ + : "=r" (x) : "r" (__m(addr))); \ +else \ +__asm__ __volatile__( \ + "/* Get user asm ret, inline. */\n" \ +"1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t" \ + ".section .fixup,#alloc,#execinstr\n\t" \ + ".align 4\n" \ +"3:\n\t" \ + "ret\n\t" \ + " restore %%g0, %2, %%o0\n\n\t" \ + ".previous\n\t" \ + ".section __ex_table,#alloc\n\t" \ + ".align 4\n\t" \ + ".word 1b, 3b\n\n\t" \ + ".previous\n\t" \ + : "=r" (x) : "r" (__m(addr)), "i" (retval)) + +extern int __get_user_bad(void); + +extern unsigned long __must_check ___copy_from_user(void *to, + const void __user *from, + unsigned long size); +extern unsigned long copy_from_user_fixup(void *to, const void __user *from, + unsigned long size); +static inline unsigned long __must_check +copy_from_user(void *to, const void __user *from, unsigned long size) +{ + unsigned long ret = ___copy_from_user(to, from, size); + + if (ret) + ret = copy_from_user_fixup(to, from, size); + return ret; +} +#define __copy_from_user copy_from_user + +extern unsigned long __must_check ___copy_to_user(void __user *to, + const void *from, + unsigned long size); +extern unsigned long copy_to_user_fixup(void __user *to, const void *from, + unsigned long size); +static inline unsigned long __must_check +copy_to_user(void __user *to, const void *from, unsigned long size) +{ + unsigned long ret = ___copy_to_user(to, from, size); + + if (ret) + ret = copy_to_user_fixup(to, from, size); + return ret; +} +#define __copy_to_user copy_to_user + +extern unsigned long __must_check ___copy_in_user(void __user *to, + const void __user *from, + unsigned long size); +extern unsigned long copy_in_user_fixup(void __user *to, void __user *from, + unsigned long size); +static inline unsigned long __must_check +copy_in_user(void __user *to, void __user *from, unsigned long size) +{ + unsigned long ret = ___copy_in_user(to, from, size); + + if (ret) + ret = copy_in_user_fixup(to, from, size); + return ret; +} +#define __copy_in_user copy_in_user + +extern unsigned long __must_check __bzero_noasi(void __user *, unsigned long); + +static inline unsigned long __must_check +__clear_user(void __user *addr, unsigned long size) +{ + + return __bzero_noasi(addr, size); +} + +#define clear_user __clear_user + +extern long __must_check __strncpy_from_user(char *dest, const char __user *src, long count); + +#define strncpy_from_user __strncpy_from_user + +extern long __strlen_user(const char __user *); +extern long __strnlen_user(const char __user *, long len); + +#define strlen_user __strlen_user +#define strnlen_user __strnlen_user +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_UACCESS_H */ diff --git a/include/asm-sparc64/uctx.h b/include/asm-sparc64/uctx.h new file mode 100644 index 000000000000..6eaf16ef23f6 --- /dev/null +++ b/include/asm-sparc64/uctx.h @@ -0,0 +1,71 @@ +/* $Id: uctx.h,v 1.1 1997/06/18 16:51:58 davem Exp $ + * uctx.h: Sparc64 {set,get}context() register state layouts. + * + * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef __SPARC64_UCTX_H +#define __SPARC64_UCTX_H + +#define MC_TSTATE 0 +#define MC_PC 1 +#define MC_NPC 2 +#define MC_Y 3 +#define MC_G1 4 +#define MC_G2 5 +#define MC_G3 6 +#define MC_G4 7 +#define MC_G5 8 +#define MC_G6 9 +#define MC_G7 10 +#define MC_O0 11 +#define MC_O1 12 +#define MC_O2 13 +#define MC_O3 14 +#define MC_O4 15 +#define MC_O5 16 +#define MC_O6 17 +#define MC_O7 18 +#define MC_NGREG 19 + +typedef unsigned long mc_greg_t; +typedef mc_greg_t mc_gregset_t[MC_NGREG]; + +#define MC_MAXFPQ 16 +struct mc_fq { + unsigned long *mcfq_addr; + unsigned int mcfq_insn; +}; + +struct mc_fpu { + union { + unsigned int sregs[32]; + unsigned long dregs[32]; + long double qregs[16]; + } mcfpu_fregs; + unsigned long mcfpu_fsr; + unsigned long mcfpu_fprs; + unsigned long mcfpu_gsr; + struct mc_fq *mcfpu_fq; + unsigned char mcfpu_qcnt; + unsigned char mcfpu_qentsz; + unsigned char mcfpu_enab; +}; +typedef struct mc_fpu mc_fpu_t; + +typedef struct { + mc_gregset_t mc_gregs; + mc_greg_t mc_fp; + mc_greg_t mc_i7; + mc_fpu_t mc_fpregs; +} mcontext_t; + +struct ucontext { + struct ucontext *uc_link; + unsigned long uc_flags; + sigset_t uc_sigmask; + mcontext_t uc_mcontext; +}; +typedef struct ucontext ucontext_t; + +#endif /* __SPARC64_UCTX_H */ diff --git a/include/asm-sparc64/unaligned.h b/include/asm-sparc64/unaligned.h new file mode 100644 index 000000000000..1ed3ba537772 --- /dev/null +++ b/include/asm-sparc64/unaligned.h @@ -0,0 +1,6 @@ +#ifndef _ASM_SPARC64_UNALIGNED_H_ +#define _ASM_SPARC64_UNALIGNED_H_ + +#include <asm-generic/unaligned.h> + +#endif /* _ASM_SPARC64_UNALIGNED_H */ diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h new file mode 100644 index 000000000000..3c00065eea80 --- /dev/null +++ b/include/asm-sparc64/unistd.h @@ -0,0 +1,514 @@ +/* $Id: unistd.h,v 1.50 2002/02/08 03:57:18 davem Exp $ */ +#ifndef _SPARC64_UNISTD_H +#define _SPARC64_UNISTD_H + +/* + * System calls under the Sparc. + * + * Don't be scared by the ugly clobbers, it is the only way I can + * think of right now to force the arguments into fixed registers + * before the trap into the system call with gcc 'asm' statements. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * + * SunOS compatibility based upon preliminary work which is: + * + * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu) + */ + +#define __NR_restart_syscall 0 /* Linux Specific */ +#define __NR_exit 1 /* Common */ +#define __NR_fork 2 /* Common */ +#define __NR_read 3 /* Common */ +#define __NR_write 4 /* Common */ +#define __NR_open 5 /* Common */ +#define __NR_close 6 /* Common */ +#define __NR_wait4 7 /* Common */ +#define __NR_creat 8 /* Common */ +#define __NR_link 9 /* Common */ +#define __NR_unlink 10 /* Common */ +#define __NR_execv 11 /* SunOS Specific */ +#define __NR_chdir 12 /* Common */ +#define __NR_chown 13 /* Common */ +#define __NR_mknod 14 /* Common */ +#define __NR_chmod 15 /* Common */ +#define __NR_lchown 16 /* Common */ +#define __NR_brk 17 /* Common */ +#define __NR_perfctr 18 /* Performance counter operations */ +#define __NR_lseek 19 /* Common */ +#define __NR_getpid 20 /* Common */ +#define __NR_capget 21 /* Linux Specific */ +#define __NR_capset 22 /* Linux Specific */ +#define __NR_setuid 23 /* Implemented via setreuid in SunOS */ +#define __NR_getuid 24 /* Common */ +/* #define __NR_time alias 25 ENOSYS under SunOS */ +#define __NR_ptrace 26 /* Common */ +#define __NR_alarm 27 /* Implemented via setitimer in SunOS */ +#define __NR_sigaltstack 28 /* Common */ +#define __NR_pause 29 /* Is sigblock(0)->sigpause() in SunOS */ +#define __NR_utime 30 /* Implemented via utimes() under SunOS */ +/* #define __NR_lchown32 31 Linux sparc32 specific */ +/* #define __NR_fchown32 32 Linux sparc32 specific */ +#define __NR_access 33 /* Common */ +#define __NR_nice 34 /* Implemented via get/setpriority() in SunOS */ +/* #define __NR_chown32 35 Linux sparc32 specific */ +#define __NR_sync 36 /* Common */ +#define __NR_kill 37 /* Common */ +#define __NR_stat 38 /* Common */ +#define __NR_sendfile 39 /* Linux Specific */ +#define __NR_lstat 40 /* Common */ +#define __NR_dup 41 /* Common */ +#define __NR_pipe 42 /* Common */ +#define __NR_times 43 /* Implemented via getrusage() in SunOS */ +/* #define __NR_getuid32 44 Linux sparc32 specific */ +#define __NR_umount2 45 /* Linux Specific */ +#define __NR_setgid 46 /* Implemented via setregid() in SunOS */ +#define __NR_getgid 47 /* Common */ +#define __NR_signal 48 /* Implemented via sigvec() in SunOS */ +#define __NR_geteuid 49 /* SunOS calls getuid() */ +#define __NR_getegid 50 /* SunOS calls getgid() */ +#define __NR_acct 51 /* Common */ +#define __NR_memory_ordering 52 /* Linux Specific */ +/* #define __NR_getgid32 53 Linux sparc32 specific */ +#define __NR_ioctl 54 /* Common */ +#define __NR_reboot 55 /* Common */ +/* #define __NR_mmap2 56 Linux sparc32 Specific */ +#define __NR_symlink 57 /* Common */ +#define __NR_readlink 58 /* Common */ +#define __NR_execve 59 /* Common */ +#define __NR_umask 60 /* Common */ +#define __NR_chroot 61 /* Common */ +#define __NR_fstat 62 /* Common */ +/* #define __NR_fstat64 63 Linux sparc32 Specific */ +#define __NR_getpagesize 64 /* Common */ +#define __NR_msync 65 /* Common in newer 1.3.x revs... */ +#define __NR_vfork 66 /* Common */ +#define __NR_pread64 67 /* Linux Specific */ +#define __NR_pwrite64 68 /* Linux Specific */ +/* #define __NR_geteuid32 69 Linux sparc32, sbrk under SunOS */ +/* #define __NR_getegid32 70 Linux sparc32, sstk under SunOS */ +#define __NR_mmap 71 /* Common */ +/* #define __NR_setreuid32 72 Linux sparc32, vadvise under SunOS */ +#define __NR_munmap 73 /* Common */ +#define __NR_mprotect 74 /* Common */ +#define __NR_madvise 75 /* Common */ +#define __NR_vhangup 76 /* Common */ +/* #define __NR_truncate64 77 Linux sparc32 Specific */ +#define __NR_mincore 78 /* Common */ +#define __NR_getgroups 79 /* Common */ +#define __NR_setgroups 80 /* Common */ +#define __NR_getpgrp 81 /* Common */ +/* #define __NR_setgroups32 82 Linux sparc32, setpgrp under SunOS */ +#define __NR_setitimer 83 /* Common */ +/* #define __NR_ftruncate64 84 Linux sparc32 Specific */ +#define __NR_swapon 85 /* Common */ +#define __NR_getitimer 86 /* Common */ +/* #define __NR_setuid32 87 Linux sparc32, gethostname under SunOS */ +#define __NR_sethostname 88 /* Common */ +/* #define __NR_setgid32 89 Linux sparc32, getdtablesize under SunOS */ +#define __NR_dup2 90 /* Common */ +/* #define __NR_setfsuid32 91 Linux sparc32, getdopt under SunOS */ +#define __NR_fcntl 92 /* Common */ +#define __NR_select 93 /* Common */ +/* #define __NR_setfsgid32 94 Linux sparc32, setdopt under SunOS */ +#define __NR_fsync 95 /* Common */ +#define __NR_setpriority 96 /* Common */ +#define __NR_socket 97 /* Common */ +#define __NR_connect 98 /* Common */ +#define __NR_accept 99 /* Common */ +#define __NR_getpriority 100 /* Common */ +#define __NR_rt_sigreturn 101 /* Linux Specific */ +#define __NR_rt_sigaction 102 /* Linux Specific */ +#define __NR_rt_sigprocmask 103 /* Linux Specific */ +#define __NR_rt_sigpending 104 /* Linux Specific */ +#define __NR_rt_sigtimedwait 105 /* Linux Specific */ +#define __NR_rt_sigqueueinfo 106 /* Linux Specific */ +#define __NR_rt_sigsuspend 107 /* Linux Specific */ +#define __NR_setresuid 108 /* Linux Specific, sigvec under SunOS */ +#define __NR_getresuid 109 /* Linux Specific, sigblock under SunOS */ +#define __NR_setresgid 110 /* Linux Specific, sigsetmask under SunOS */ +#define __NR_getresgid 111 /* Linux Specific, sigpause under SunOS */ +/* #define __NR_setregid32 75 Linux sparc32, sigstack under SunOS */ +#define __NR_recvmsg 113 /* Common */ +#define __NR_sendmsg 114 /* Common */ +/* #define __NR_getgroups32 115 Linux sparc32, vtrace under SunOS */ +#define __NR_gettimeofday 116 /* Common */ +#define __NR_getrusage 117 /* Common */ +#define __NR_getsockopt 118 /* Common */ +#define __NR_getcwd 119 /* Linux Specific */ +#define __NR_readv 120 /* Common */ +#define __NR_writev 121 /* Common */ +#define __NR_settimeofday 122 /* Common */ +#define __NR_fchown 123 /* Common */ +#define __NR_fchmod 124 /* Common */ +#define __NR_recvfrom 125 /* Common */ +#define __NR_setreuid 126 /* Common */ +#define __NR_setregid 127 /* Common */ +#define __NR_rename 128 /* Common */ +#define __NR_truncate 129 /* Common */ +#define __NR_ftruncate 130 /* Common */ +#define __NR_flock 131 /* Common */ +/* #define __NR_lstat64 132 Linux sparc32 Specific */ +#define __NR_sendto 133 /* Common */ +#define __NR_shutdown 134 /* Common */ +#define __NR_socketpair 135 /* Common */ +#define __NR_mkdir 136 /* Common */ +#define __NR_rmdir 137 /* Common */ +#define __NR_utimes 138 /* SunOS Specific */ +/* #define __NR_stat64 139 Linux sparc32 Specific */ +#define __NR_sendfile64 140 /* adjtime under SunOS */ +#define __NR_getpeername 141 /* Common */ +#define __NR_futex 142 /* gethostid under SunOS */ +#define __NR_gettid 143 /* ENOSYS under SunOS */ +#define __NR_getrlimit 144 /* Common */ +#define __NR_setrlimit 145 /* Common */ +#define __NR_pivot_root 146 /* Linux Specific, killpg under SunOS */ +#define __NR_prctl 147 /* ENOSYS under SunOS */ +#define __NR_pciconfig_read 148 /* ENOSYS under SunOS */ +#define __NR_pciconfig_write 149 /* ENOSYS under SunOS */ +#define __NR_getsockname 150 /* Common */ +/* #define __NR_getmsg 151 SunOS Specific */ +/* #define __NR_putmsg 152 SunOS Specific */ +#define __NR_poll 153 /* Common */ +#define __NR_getdents64 154 /* Linux specific */ +/* #define __NR_fcntl64 155 Linux sparc32 Specific */ +/* #define __NR_getdirentries 156 SunOS Specific */ +#define __NR_statfs 157 /* Common */ +#define __NR_fstatfs 158 /* Common */ +#define __NR_umount 159 /* Common */ +#define __NR_sched_set_affinity 160 /* Linux specific, async_daemon under SunOS */ +#define __NR_sched_get_affinity 161 /* Linux specific, getfh under SunOS */ +#define __NR_getdomainname 162 /* SunOS Specific */ +#define __NR_setdomainname 163 /* Common */ +#define __NR_utrap_install 164 /* SYSV ABI/v9 required */ +#define __NR_quotactl 165 /* Common */ +#define __NR_set_tid_address 166 /* Linux specific, exportfs under SunOS */ +#define __NR_mount 167 /* Common */ +#define __NR_ustat 168 /* Common */ +#define __NR_setxattr 169 /* SunOS: semsys */ +#define __NR_lsetxattr 170 /* SunOS: msgsys */ +#define __NR_fsetxattr 171 /* SunOS: shmsys */ +#define __NR_getxattr 172 /* SunOS: auditsys */ +#define __NR_lgetxattr 173 /* SunOS: rfssys */ +#define __NR_getdents 174 /* Common */ +#define __NR_setsid 175 /* Common */ +#define __NR_fchdir 176 /* Common */ +#define __NR_fgetxattr 177 /* SunOS: fchroot */ +#define __NR_listxattr 178 /* SunOS: vpixsys */ +#define __NR_llistxattr 179 /* SunOS: aioread */ +#define __NR_flistxattr 180 /* SunOS: aiowrite */ +#define __NR_removexattr 181 /* SunOS: aiowait */ +#define __NR_lremovexattr 182 /* SunOS: aiocancel */ +#define __NR_sigpending 183 /* Common */ +#define __NR_query_module 184 /* Linux Specific */ +#define __NR_setpgid 185 /* Common */ +#define __NR_fremovexattr 186 /* SunOS: pathconf */ +#define __NR_tkill 187 /* SunOS: fpathconf */ +#define __NR_exit_group 188 /* Linux specific, sysconf undef SunOS */ +#define __NR_uname 189 /* Linux Specific */ +#define __NR_init_module 190 /* Linux Specific */ +#define __NR_personality 191 /* Linux Specific */ +#define __NR_remap_file_pages 192 /* Linux Specific */ +#define __NR_epoll_create 193 /* Linux Specific */ +#define __NR_epoll_ctl 194 /* Linux Specific */ +#define __NR_epoll_wait 195 /* Linux Specific */ +/* #define __NR_ulimit 196 Linux Specific */ +#define __NR_getppid 197 /* Linux Specific */ +#define __NR_sigaction 198 /* Linux Specific */ +#define __NR_sgetmask 199 /* Linux Specific */ +#define __NR_ssetmask 200 /* Linux Specific */ +#define __NR_sigsuspend 201 /* Linux Specific */ +#define __NR_oldlstat 202 /* Linux Specific */ +#define __NR_uselib 203 /* Linux Specific */ +#define __NR_readdir 204 /* Linux Specific */ +#define __NR_readahead 205 /* Linux Specific */ +#define __NR_socketcall 206 /* Linux Specific */ +#define __NR_syslog 207 /* Linux Specific */ +#define __NR_lookup_dcookie 208 /* Linux Specific */ +#define __NR_fadvise64 209 /* Linux Specific */ +#define __NR_fadvise64_64 210 /* Linux Specific */ +#define __NR_tgkill 211 /* Linux Specific */ +#define __NR_waitpid 212 /* Linux Specific */ +#define __NR_swapoff 213 /* Linux Specific */ +#define __NR_sysinfo 214 /* Linux Specific */ +#define __NR_ipc 215 /* Linux Specific */ +#define __NR_sigreturn 216 /* Linux Specific */ +#define __NR_clone 217 /* Linux Specific */ +/* #define __NR_modify_ldt 218 Linux Specific - i386 specific, unused */ +#define __NR_adjtimex 219 /* Linux Specific */ +#define __NR_sigprocmask 220 /* Linux Specific */ +#define __NR_create_module 221 /* Linux Specific */ +#define __NR_delete_module 222 /* Linux Specific */ +#define __NR_get_kernel_syms 223 /* Linux Specific */ +#define __NR_getpgid 224 /* Linux Specific */ +#define __NR_bdflush 225 /* Linux Specific */ +#define __NR_sysfs 226 /* Linux Specific */ +#define __NR_afs_syscall 227 /* Linux Specific */ +#define __NR_setfsuid 228 /* Linux Specific */ +#define __NR_setfsgid 229 /* Linux Specific */ +#define __NR__newselect 230 /* Linux Specific */ +#ifdef __KERNEL__ +#define __NR_time 231 /* Linux sparc32 */ +#endif +/* #define __NR_oldstat 232 Linux Specific */ +#define __NR_stime 233 /* Linux Specific */ +#define __NR_statfs64 234 /* Linux Specific */ +#define __NR_fstatfs64 235 /* Linux Specific */ +#define __NR__llseek 236 /* Linux Specific */ +#define __NR_mlock 237 +#define __NR_munlock 238 +#define __NR_mlockall 239 +#define __NR_munlockall 240 +#define __NR_sched_setparam 241 +#define __NR_sched_getparam 242 +#define __NR_sched_setscheduler 243 +#define __NR_sched_getscheduler 244 +#define __NR_sched_yield 245 +#define __NR_sched_get_priority_max 246 +#define __NR_sched_get_priority_min 247 +#define __NR_sched_rr_get_interval 248 +#define __NR_nanosleep 249 +#define __NR_mremap 250 +#define __NR__sysctl 251 +#define __NR_getsid 252 +#define __NR_fdatasync 253 +#define __NR_nfsservctl 254 +#define __NR_aplib 255 +#define __NR_clock_settime 256 +#define __NR_clock_gettime 257 +#define __NR_clock_getres 258 +#define __NR_clock_nanosleep 259 +#define __NR_sched_getaffinity 260 +#define __NR_sched_setaffinity 261 +#define __NR_timer_settime 262 +#define __NR_timer_gettime 263 +#define __NR_timer_getoverrun 264 +#define __NR_timer_delete 265 +#define __NR_timer_create 266 +/* #define __NR_vserver 267 Reserved for VSERVER */ +#define __NR_io_setup 268 +#define __NR_io_destroy 269 +#define __NR_io_submit 270 +#define __NR_io_cancel 271 +#define __NR_io_getevents 272 +#define __NR_mq_open 273 +#define __NR_mq_unlink 274 +#define __NR_mq_timedsend 275 +#define __NR_mq_timedreceive 276 +#define __NR_mq_notify 277 +#define __NR_mq_getsetattr 278 +#define __NR_waitid 279 +/*#define __NR_sys_setaltroot 280 available (was setaltroot) */ +#define __NR_add_key 281 +#define __NR_request_key 282 +#define __NR_keyctl 283 + +/* WARNING: You MAY NOT add syscall numbers larger than 283, since + * all of the syscall tables in the Sparc kernel are + * sized to have 283 entries (starting at zero). Therefore + * find a free slot in the 0-282 range. + */ + +#define _syscall0(type,name) \ +type name(void) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +__asm__ __volatile__ ("t 0x6d\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "movcc %%xcc, %%o0, %0\n\t" \ + : "=r" (__res)\ + : "r" (__g1) \ + : "o0", "cc"); \ +if (__res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register long __o0 __asm__ ("o0") = (long)(arg1); \ +__asm__ __volatile__ ("t 0x6d\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "movcc %%xcc, %%o0, %0\n\t" \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__g1) \ + : "cc"); \ +if (__res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register long __o0 __asm__ ("o0") = (long)(arg1); \ +register long __o1 __asm__ ("o1") = (long)(arg2); \ +__asm__ __volatile__ ("t 0x6d\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "movcc %%xcc, %%o0, %0\n\t" \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__o1), "r" (__g1) \ + : "cc"); \ +if (__res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register long __o0 __asm__ ("o0") = (long)(arg1); \ +register long __o1 __asm__ ("o1") = (long)(arg2); \ +register long __o2 __asm__ ("o2") = (long)(arg3); \ +__asm__ __volatile__ ("t 0x6d\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "movcc %%xcc, %%o0, %0\n\t" \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \ + : "cc"); \ +if (__res>=0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register long __o0 __asm__ ("o0") = (long)(arg1); \ +register long __o1 __asm__ ("o1") = (long)(arg2); \ +register long __o2 __asm__ ("o2") = (long)(arg3); \ +register long __o3 __asm__ ("o3") = (long)(arg4); \ +__asm__ __volatile__ ("t 0x6d\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "movcc %%xcc, %%o0, %0\n\t" \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \ + : "cc"); \ +if (__res>=0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register long __o0 __asm__ ("o0") = (long)(arg1); \ +register long __o1 __asm__ ("o1") = (long)(arg2); \ +register long __o2 __asm__ ("o2") = (long)(arg3); \ +register long __o3 __asm__ ("o3") = (long)(arg4); \ +register long __o4 __asm__ ("o4") = (long)(arg5); \ +__asm__ __volatile__ ("t 0x6d\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "movcc %%xcc, %%o0, %0\n\t" \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \ + : "cc"); \ +if (__res>=0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} +#ifdef __KERNEL_SYSCALLS__ + +#include <linux/compiler.h> +#include <linux/types.h> + +/* + * we need this inline - forking from kernel space will result + * in NO COPY ON WRITE (!!!), until an execve is executed. This + * is no problem, but for the stack. This is handled by not letting + * main() use the stack at all after fork(). Thus, no function + * calls - which means inline code for fork too, as otherwise we + * would use the stack upon exit from 'fork()'. + * + * Actually only pause and fork are needed inline, so that there + * won't be any messing with the stack from main(), but we define + * some others too. + */ +#define __NR__exit __NR_exit +static __inline__ _syscall0(pid_t,setsid) +static __inline__ _syscall3(int,write,int,fd,__const__ char *,buf,off_t,count) +static __inline__ _syscall3(int,read,int,fd,char *,buf,off_t,count) +static __inline__ _syscall3(off_t,lseek,int,fd,off_t,offset,int,count) +static __inline__ _syscall1(int,dup,int,fd) +static __inline__ _syscall3(int,execve,__const__ char *,file,char **,argv,char **,envp) +static __inline__ _syscall3(int,open,__const__ char *,file,int,flag,int,mode) +static __inline__ _syscall1(int,close,int,fd) +static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) + +#include <linux/linkage.h> + +asmlinkage unsigned long sys_mmap( + unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long off); +struct sigaction; +asmlinkage long sys_rt_sigaction(int sig, + const struct sigaction __user *act, + struct sigaction __user *oact, + void __user *restorer, + size_t sigsetsize); + +#endif /* __KERNEL_SYSCALLS__ */ + +#ifdef __KERNEL__ +/* sysconf options, for SunOS compatibility */ +#define _SC_ARG_MAX 1 +#define _SC_CHILD_MAX 2 +#define _SC_CLK_TCK 3 +#define _SC_NGROUPS_MAX 4 +#define _SC_OPEN_MAX 5 +#define _SC_JOB_CONTROL 6 +#define _SC_SAVED_IDS 7 +#define _SC_VERSION 8 + +#define __ARCH_WANT_IPC_PARSE_VERSION +#define __ARCH_WANT_OLD_READDIR +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_ALARM +#define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_PAUSE +#define __ARCH_WANT_SYS_SGETMASK +#define __ARCH_WANT_SYS_SIGNAL +#define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_COMPAT_SYS_TIME +#define __ARCH_WANT_SYS_UTIME +#define __ARCH_WANT_SYS_WAITPID +#define __ARCH_WANT_SYS_SOCKETCALL +#define __ARCH_WANT_SYS_FADVISE64 +#define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK +#define __ARCH_WANT_SYS_NICE +#define __ARCH_WANT_SYS_OLD_GETRLIMIT +#define __ARCH_WANT_SYS_OLDUMOUNT +#define __ARCH_WANT_SYS_SIGPENDING +#define __ARCH_WANT_SYS_SIGPROCMASK +#endif + +/* + * "Conditional" syscalls + * + * What we want is __attribute__((weak,alias("sys_ni_syscall"))), + * but it doesn't work on all toolchains, so we just do it by hand + */ +#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") + +#endif /* _SPARC64_UNISTD_H */ diff --git a/include/asm-sparc64/upa.h b/include/asm-sparc64/upa.h new file mode 100644 index 000000000000..7ae09a22e408 --- /dev/null +++ b/include/asm-sparc64/upa.h @@ -0,0 +1,110 @@ +/* $Id: upa.h,v 1.3 1999/09/21 14:39:47 davem Exp $ */ +#ifndef _SPARC64_UPA_H +#define _SPARC64_UPA_H + +#include <asm/asi.h> + +/* UPA level registers and defines. */ + +/* UPA Config Register */ +#define UPA_CONFIG_RESV 0xffffffffc0000000 /* Reserved. */ +#define UPA_CONFIG_PCON 0x000000003fc00000 /* Depth of various sys queues. */ +#define UPA_CONFIG_MID 0x00000000003e0000 /* Module ID. */ +#define UPA_CONFIG_PCAP 0x000000000001ffff /* Port Capabilities. */ + +/* UPA Port ID Register */ +#define UPA_PORTID_FNP 0xff00000000000000 /* Hardcoded to 0xfc on ultra. */ +#define UPA_PORTID_RESV 0x00fffff800000000 /* Reserved. */ +#define UPA_PORTID_ECCVALID 0x0000000400000000 /* Zero if mod can generate ECC */ +#define UPA_PORTID_ONEREAD 0x0000000200000000 /* Set if mod generates P_RASB */ +#define UPA_PORTID_PINTRDQ 0x0000000180000000 /* # outstanding P_INT_REQ's */ +#define UPA_PORTID_PREQDQ 0x000000007e000000 /* slave-wr's to mod supported */ +#define UPA_PORTID_PREQRD 0x0000000001e00000 /* # incoming P_REQ's supported */ +#define UPA_PORTID_UPACAP 0x00000000001f0000 /* UPA capabilities of mod */ +#define UPA_PORTID_ID 0x000000000000ffff /* Module Identification bits */ + +/* UPA I/O space accessors */ +#if defined(__KERNEL__) && !defined(__ASSEMBLY__) +static __inline__ unsigned char _upa_readb(unsigned long addr) +{ + unsigned char ret; + + __asm__ __volatile__("lduba\t[%1] %2, %0\t/* upa_readb */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +static __inline__ unsigned short _upa_readw(unsigned long addr) +{ + unsigned short ret; + + __asm__ __volatile__("lduha\t[%1] %2, %0\t/* upa_readw */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +static __inline__ unsigned int _upa_readl(unsigned long addr) +{ + unsigned int ret; + + __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* upa_readl */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +static __inline__ unsigned long _upa_readq(unsigned long addr) +{ + unsigned long ret; + + __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* upa_readq */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +static __inline__ void _upa_writeb(unsigned char b, unsigned long addr) +{ + __asm__ __volatile__("stba\t%0, [%1] %2\t/* upa_writeb */" + : /* no outputs */ + : "r" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +static __inline__ void _upa_writew(unsigned short w, unsigned long addr) +{ + __asm__ __volatile__("stha\t%0, [%1] %2\t/* upa_writew */" + : /* no outputs */ + : "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +static __inline__ void _upa_writel(unsigned int l, unsigned long addr) +{ + __asm__ __volatile__("stwa\t%0, [%1] %2\t/* upa_writel */" + : /* no outputs */ + : "r" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +static __inline__ void _upa_writeq(unsigned long q, unsigned long addr) +{ + __asm__ __volatile__("stxa\t%0, [%1] %2\t/* upa_writeq */" + : /* no outputs */ + : "r" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +#define upa_readb(__addr) (_upa_readb((unsigned long)(__addr))) +#define upa_readw(__addr) (_upa_readw((unsigned long)(__addr))) +#define upa_readl(__addr) (_upa_readl((unsigned long)(__addr))) +#define upa_readq(__addr) (_upa_readq((unsigned long)(__addr))) +#define upa_writeb(__b, __addr) (_upa_writeb((__b), (unsigned long)(__addr))) +#define upa_writew(__w, __addr) (_upa_writew((__w), (unsigned long)(__addr))) +#define upa_writel(__l, __addr) (_upa_writel((__l), (unsigned long)(__addr))) +#define upa_writeq(__q, __addr) (_upa_writeq((__q), (unsigned long)(__addr))) +#endif /* __KERNEL__ && !__ASSEMBLY__ */ + +#endif /* !(_SPARC64_UPA_H) */ diff --git a/include/asm-sparc64/user.h b/include/asm-sparc64/user.h new file mode 100644 index 000000000000..fce4e857dfc3 --- /dev/null +++ b/include/asm-sparc64/user.h @@ -0,0 +1,60 @@ +/* $Id: user.h,v 1.1 1996/12/26 14:22:44 davem Exp $ + * asm-sparc64/user.h: Core file definitions for the Sparc. + * + * Keep in sync with reg.h. Actually, we could get rid of this + * one, since we won't a.out core dump that much anyways - miguel. + * Copyright (C) 1995 (davem@caip.rutgers.edu) + */ +#ifndef _SPARC64_USER_H +#define _SPARC64_USER_H + +#include <asm/a.out.h> +struct sunos_regs { + unsigned int psr, pc, npc, y; + unsigned int regs[15]; +}; + +struct sunos_fpqueue { + unsigned int *addr; + unsigned int inst; +}; + +struct sunos_fp { + union { + unsigned int regs[32]; + double reg_dbls[16]; + } fregs; + unsigned int fsr; + unsigned int flags; + unsigned int extra; + unsigned int fpq_count; + struct sunos_fpqueue fpq[16]; +}; + +struct sunos_fpu { + struct sunos_fp fpstatus; +}; + +/* The SunOS core file header layout. */ +struct user { + unsigned int magic; + unsigned int len; + struct sunos_regs regs; + struct exec uexec; + int signal; + size_t u_tsize; /* all of these in bytes! */ + size_t u_dsize; + size_t u_ssize; + char u_comm[17]; + struct sunos_fpu fpu; + unsigned int sigcode; /* Special sigcontext subcode, if any */ +}; + +#define NBPG PAGE_SIZE /* XXX 4096 maybe? */ +#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) +#define SUNOS_CORE_MAGIC 0x080456 + +#endif /* !(_SPARC64_USER_H) */ diff --git a/include/asm-sparc64/utrap.h b/include/asm-sparc64/utrap.h new file mode 100644 index 000000000000..81b0ebf3736c --- /dev/null +++ b/include/asm-sparc64/utrap.h @@ -0,0 +1,51 @@ +/* $Id: utrap.h,v 1.1 1997/10/14 16:21:31 jj Exp $ + * include/asm-sparc64/utrap.h + * + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +#ifndef __ASM_SPARC64_UTRAP_H +#define __ASM_SPARC64_UTRAP_H + +#define UT_INSTRUCTION_EXCEPTION 1 +#define UT_INSTRUCTION_ERROR 2 +#define UT_INSTRUCTION_PROTECTION 3 +#define UT_ILLTRAP_INSTRUCTION 4 +#define UT_ILLEGAL_INSTRUCTION 5 +#define UT_PRIVILEGED_OPCODE 6 +#define UT_FP_DISABLED 7 +#define UT_FP_EXCEPTION_IEEE_754 8 +#define UT_FP_EXCEPTION_OTHER 9 +#define UT_TAG_OVERVIEW 10 +#define UT_DIVISION_BY_ZERO 11 +#define UT_DATA_EXCEPTION 12 +#define UT_DATA_ERROR 13 +#define UT_DATA_PROTECTION 14 +#define UT_MEM_ADDRESS_NOT_ALIGNED 15 +#define UT_PRIVILEGED_ACTION 16 +#define UT_ASYNC_DATA_ERROR 17 +#define UT_TRAP_INSTRUCTION_16 18 +#define UT_TRAP_INSTRUCTION_17 19 +#define UT_TRAP_INSTRUCTION_18 20 +#define UT_TRAP_INSTRUCTION_19 21 +#define UT_TRAP_INSTRUCTION_20 22 +#define UT_TRAP_INSTRUCTION_21 23 +#define UT_TRAP_INSTRUCTION_22 24 +#define UT_TRAP_INSTRUCTION_23 25 +#define UT_TRAP_INSTRUCTION_24 26 +#define UT_TRAP_INSTRUCTION_25 27 +#define UT_TRAP_INSTRUCTION_26 28 +#define UT_TRAP_INSTRUCTION_27 29 +#define UT_TRAP_INSTRUCTION_28 30 +#define UT_TRAP_INSTRUCTION_29 31 +#define UT_TRAP_INSTRUCTION_30 32 +#define UT_TRAP_INSTRUCTION_31 33 + +#define UTH_NOCHANGE (-1) + +#ifndef __ASSEMBLY__ +typedef int utrap_entry_t; +typedef void *utrap_handler_t; +#endif /* __ASSEMBLY__ */ + +#endif /* !(__ASM_SPARC64_PROCESSOR_H) */ diff --git a/include/asm-sparc64/vga.h b/include/asm-sparc64/vga.h new file mode 100644 index 000000000000..9c57eb363b40 --- /dev/null +++ b/include/asm-sparc64/vga.h @@ -0,0 +1,33 @@ +/* + * Access to VGA videoram + * + * (c) 1998 Martin Mares <mj@ucw.cz> + */ + +#ifndef _LINUX_ASM_VGA_H_ +#define _LINUX_ASM_VGA_H_ + +#include <asm/types.h> + +#define VT_BUF_HAVE_RW + +#undef scr_writew +#undef scr_readw + +static inline void scr_writew(u16 val, u16 *addr) +{ + BUG_ON((long) addr >= 0); + + *addr = val; +} + +static inline u16 scr_readw(const u16 *addr) +{ + BUG_ON((long) addr >= 0); + + return *addr; +} + +#define VGA_MAP_MEM(x) (x) + +#endif diff --git a/include/asm-sparc64/visasm.h b/include/asm-sparc64/visasm.h new file mode 100644 index 000000000000..a74078551e0f --- /dev/null +++ b/include/asm-sparc64/visasm.h @@ -0,0 +1,63 @@ +/* $Id: visasm.h,v 1.5 2001/04/24 01:09:12 davem Exp $ */ +#ifndef _SPARC64_VISASM_H +#define _SPARC64_VISASM_H + +/* visasm.h: FPU saving macros for VIS routines + * + * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) + */ + +#include <asm/pstate.h> +#include <asm/ptrace.h> + +/* Clobbers %o5, %g1, %g2, %g3, %g7, %icc, %xcc */ + +#define VISEntry \ + rd %fprs, %o5; \ + andcc %o5, (FPRS_FEF|FPRS_DU), %g0; \ + be,pt %icc, 297f; \ + sethi %hi(297f), %g7; \ + sethi %hi(VISenter), %g1; \ + jmpl %g1 + %lo(VISenter), %g0; \ + or %g7, %lo(297f), %g7; \ +297: wr %g0, FPRS_FEF, %fprs; \ + +#define VISExit \ + wr %g0, 0, %fprs; + +/* Clobbers %o5, %g1, %g2, %g3, %g7, %icc, %xcc. + * Must preserve %o5 between VISEntryHalf and VISExitHalf */ + +#define VISEntryHalf \ + rd %fprs, %o5; \ + andcc %o5, FPRS_FEF, %g0; \ + be,pt %icc, 297f; \ + sethi %hi(298f), %g7; \ + sethi %hi(VISenterhalf), %g1; \ + jmpl %g1 + %lo(VISenterhalf), %g0; \ + or %g7, %lo(298f), %g7; \ + clr %o5; \ +297: wr %o5, FPRS_FEF, %fprs; \ +298: + +#define VISExitHalf \ + wr %o5, 0, %fprs; + +#ifndef __ASSEMBLY__ +static __inline__ void save_and_clear_fpu(void) { + __asm__ __volatile__ ( +" rd %%fprs, %%o5\n" +" andcc %%o5, %0, %%g0\n" +" be,pt %%icc, 299f\n" +" sethi %%hi(298f), %%g7\n" +" sethi %%hi(VISenter), %%g1\n" +" jmpl %%g1 + %%lo(VISenter), %%g0\n" +" or %%g7, %%lo(298f), %%g7\n" +" 298: wr %%g0, 0, %%fprs\n" +" 299:\n" +" " : : "i" (FPRS_FEF|FPRS_DU) : + "o5", "g1", "g2", "g3", "g7", "cc"); +} +#endif + +#endif /* _SPARC64_ASI_H */ diff --git a/include/asm-sparc64/vuid_event.h b/include/asm-sparc64/vuid_event.h new file mode 100644 index 000000000000..9ef4d17ad08f --- /dev/null +++ b/include/asm-sparc64/vuid_event.h @@ -0,0 +1,40 @@ +/* SunOS Virtual User Input Device (VUID) compatibility */ + +typedef struct firm_event { + unsigned short id; /* tag for this event */ + unsigned char pair_type; /* unused by X11 */ + unsigned char pair; /* unused by X11 */ + int value; /* VKEY_UP, VKEY_DOWN or delta */ + struct timeval time; +} Firm_event; + +enum { + FE_PAIR_NONE, + FE_PAIR_SET, + FE_PAIR_DELTA, + FE_PAIR_ABSOLUTE +}; + +/* VUID stream formats */ +#define VUID_NATIVE 0 /* Native byte stream format */ +#define VUID_FIRM_EVENT 1 /* send firm_event structures */ + +/* ioctls */ + /* Set input device byte stream format (any of VUID_{NATIVE,FIRM_EVENT}) */ +#define VUIDSFORMAT _IOW('v', 1, int) + /* Retrieve input device byte stream format */ +#define VUIDGFORMAT _IOR('v', 2, int) + +/* Possible tag values */ +/* mouse buttons: */ +#define MS_LEFT 0x7f20 +#define MS_MIDDLE 0x7f21 +#define MS_RIGHT 0x7f22 +/* motion: */ +#define LOC_X_DELTA 0x7f80 +#define LOC_Y_DELTA 0x7f81 +#define LOC_X_ABSOLUTE 0x7f82 /* X compat, unsupported */ +#define LOC_Y_ABSOLUTE 0x7f83 /* X compat, unsupported */ + +#define VKEY_UP 0 +#define VKEY_DOWN 1 diff --git a/include/asm-sparc64/watchdog.h b/include/asm-sparc64/watchdog.h new file mode 100644 index 000000000000..4d5b03b60e4d --- /dev/null +++ b/include/asm-sparc64/watchdog.h @@ -0,0 +1,31 @@ +/* $Id: watchdog.h,v 1.1 2001/01/18 04:47:44 davem Exp $ + * + * watchdog - Driver interface for the hardware watchdog timers + * present on Sun Microsystems boardsets + * + * Copyright (c) 2000 Eric Brower <ebrower@usa.net> + * + */ + +#ifndef _SPARC64_WATCHDOG_H +#define _SPARC64_WATCHDOG_H + +#include <linux/watchdog.h> + +/* Solaris compatibility ioctls-- + * Ref. <linux/watchdog.h> for standard linux watchdog ioctls + */ +#define WIOCSTART _IO (WATCHDOG_IOCTL_BASE, 10) /* Start Timer */ +#define WIOCSTOP _IO (WATCHDOG_IOCTL_BASE, 11) /* Stop Timer */ +#define WIOCGSTAT _IOR(WATCHDOG_IOCTL_BASE, 12, int)/* Get Timer Status */ + +/* Status flags from WIOCGSTAT ioctl + */ +#define WD_FREERUN 0x01 /* timer is running, interrupts disabled */ +#define WD_EXPIRED 0x02 /* timer has expired */ +#define WD_RUNNING 0x04 /* timer is running, interrupts enabled */ +#define WD_STOPPED 0x08 /* timer has not been started */ +#define WD_SERVICED 0x10 /* timer interrupt was serviced */ + +#endif /* ifndef _SPARC64_WATCHDOG_H */ + diff --git a/include/asm-sparc64/xor.h b/include/asm-sparc64/xor.h new file mode 100644 index 000000000000..8b3a7e4b6062 --- /dev/null +++ b/include/asm-sparc64/xor.h @@ -0,0 +1,40 @@ +/* + * include/asm-sparc64/xor.h + * + * High speed xor_block operation for RAID4/5 utilizing the + * UltraSparc Visual Instruction Set. + * + * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * You should have received a copy of the GNU General Public License + * (for example /usr/src/linux/COPYING); if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <asm/pstate.h> +#include <asm/asi.h> + +extern void xor_vis_2(unsigned long, unsigned long *, unsigned long *); +extern void xor_vis_3(unsigned long, unsigned long *, unsigned long *, + unsigned long *); +extern void xor_vis_4(unsigned long, unsigned long *, unsigned long *, + unsigned long *, unsigned long *); +extern void xor_vis_5(unsigned long, unsigned long *, unsigned long *, + unsigned long *, unsigned long *, unsigned long *); + +/* XXX Ugh, write cheetah versions... -DaveM */ + +static struct xor_block_template xor_block_VIS = { + .name = "VIS", + .do_2 = xor_vis_2, + .do_3 = xor_vis_3, + .do_4 = xor_vis_4, + .do_5 = xor_vis_5, +}; + +#define XOR_TRY_TEMPLATES xor_speed(&xor_block_VIS) |