diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-05 06:47:02 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-05 06:47:02 +0000 |
commit | 99a7e12f34b3661a0d1354eef83a0eef4df5e34c (patch) | |
tree | 3560aca9ca86792f9ab7bd87861ea143a1b3c7a3 /include/asm-sparc64 | |
parent | e73a04659c0b8cdee4dd40e58630e2cf63afb316 (diff) |
Merge with Linux 2.3.38.
Diffstat (limited to 'include/asm-sparc64')
41 files changed, 1582 insertions, 1403 deletions
diff --git a/include/asm-sparc64/asm_offsets.h b/include/asm-sparc64/asm_offsets.h index 4b39659eb..8c36daca1 100644 --- a/include/asm-sparc64/asm_offsets.h +++ b/include/asm-sparc64/asm_offsets.h @@ -186,7 +186,13 @@ #define ASIZ_task_sas_ss_sp 0x00000008 #define AOFF_task_sas_ss_size 0x00000820 #define ASIZ_task_sas_ss_size 0x00000008 -#define ASIZ_task 0x00000830 +#define AOFF_task_parent_exec_id 0x00000828 +#define ASIZ_task_parent_exec_id 0x00000004 +#define AOFF_task_self_exec_id 0x0000082c +#define ASIZ_task_self_exec_id 0x00000004 +#define AOFF_task_exit_sem 0x00000830 +#define ASIZ_task_exit_sem 0x00000030 +#define ASIZ_task 0x00000860 #define AOFF_mm_mmap 0x00000000 #define ASIZ_mm_mmap 0x00000008 #define AOFF_mm_mmap_avl 0x00000008 @@ -474,7 +480,13 @@ #define ASIZ_task_sas_ss_sp 0x00000008 #define AOFF_task_sas_ss_size 0x00000a18 #define ASIZ_task_sas_ss_size 0x00000008 -#define ASIZ_task 0x00000a20 +#define AOFF_task_parent_exec_id 0x00000a20 +#define ASIZ_task_parent_exec_id 0x00000004 +#define AOFF_task_self_exec_id 0x00000a24 +#define ASIZ_task_self_exec_id 0x00000004 +#define AOFF_task_exit_sem 0x00000a28 +#define ASIZ_task_exit_sem 0x00000038 +#define ASIZ_task 0x00000a60 #define AOFF_mm_mmap 0x00000000 #define ASIZ_mm_mmap 0x00000008 #define AOFF_mm_mmap_avl 0x00000008 @@ -760,7 +772,13 @@ #define ASIZ_task_sas_ss_sp 0x00000008 #define AOFF_task_sas_ss_size 0x00000a30 #define ASIZ_task_sas_ss_size 0x00000008 -#define ASIZ_task 0x00000a40 +#define AOFF_task_parent_exec_id 0x00000a38 +#define ASIZ_task_parent_exec_id 0x00000004 +#define AOFF_task_self_exec_id 0x00000a3c +#define ASIZ_task_self_exec_id 0x00000004 +#define AOFF_task_exit_sem 0x00000a40 +#define ASIZ_task_exit_sem 0x00000040 +#define ASIZ_task 0x00000a80 #define AOFF_mm_mmap 0x00000000 #define ASIZ_mm_mmap 0x00000008 #define AOFF_mm_mmap_avl 0x00000008 diff --git a/include/asm-sparc64/audioio.h b/include/asm-sparc64/audioio.h index cb9a213a3..28fe82dc7 100644 --- a/include/asm-sparc64/audioio.h +++ b/include/asm-sparc64/audioio.h @@ -271,7 +271,7 @@ struct sparcaudio_driver int index; /* This device */ - struct linux_sbus_device *dev; + struct sbus_dev *dev; /* Processes blocked on open() sit here. */ wait_queue_head_t open_wait; diff --git a/include/asm-sparc64/auxio.h b/include/asm-sparc64/auxio.h index 53360bccb..d93054e88 100644 --- a/include/asm-sparc64/auxio.h +++ b/include/asm-sparc64/auxio.h @@ -1,4 +1,4 @@ -/* $Id: auxio.h,v 1.1 1997/03/14 21:05:27 jj Exp $ +/* $Id: auxio.h,v 1.2 1999/09/21 14:39:25 davem Exp $ * auxio.h: Definitions and code for the Auxiliary I/O register. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -11,7 +11,7 @@ /* FIXME: All of this should be checked for sun4u. It has /sbus/auxio, but I don't know whether it is the same and don't have a floppy */ -extern unsigned char *auxio_register; +extern unsigned long auxio_register; /* This register is an unsigned char in IO space. It does two things. * First, it is used to control the front panel LED light on machines @@ -33,16 +33,50 @@ extern unsigned char *auxio_register; #define AUXIO_FLPY_EJCT 0x02 /* Eject floppy disk. Write only. */ #define AUXIO_LED 0x01 /* On if set, off if unset. Read/Write */ -#define AUXREG ((volatile unsigned char *)(auxio_register)) +#define AUXREG (auxio_register) /* These are available on sun4c */ -#define TURN_ON_LED if (AUXREG) *AUXREG = (*AUXREG | AUXIO_ORMEIN | AUXIO_LED) -#define TURN_OFF_LED if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) & (~AUXIO_LED)) -#define FLIP_LED if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) ^ AUXIO_LED) -#define FLPY_MOTORON if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) | AUXIO_FLPY_DSEL) -#define FLPY_MOTOROFF if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) & (~AUXIO_FLPY_DSEL)) -#define FLPY_TCNTON if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) | AUXIO_FLPY_TCNT) -#define FLPY_TCNTOFF if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) & (~AUXIO_FLPY_TCNT)) +#define TURN_ON_LED \ +do { if (AUXREG) \ + sbus_writeb(sbus_readb(AUXREG) | \ + (AUXIO_ORMEIN | AUXIO_LED), AUXREG); \ +} while(0) +#define TURN_OFF_LED \ +do { if (AUXREG) \ + sbus_writeb((sbus_readb(AUXREG) | \ + AUXIO_ORMEIN) & (~AUXIO_LED), \ + AUXREG); \ +} while(0) +#define FLIP_LED \ +do { if (AUXREG) \ + sbus_writeb((sbus_readb(AUXREG) | \ + AUXIO_ORMEIN) ^ AUXIO_LEN, \ + AUXREG); \ +} while(0) +#define FLPY_MOTORON \ +do { if (AUXREG) \ + sbus_writeb(sbus_readb(AUXREG) | \ + (AUXIO_ORMEIN | AUXIO_FLPY_DSEL), \ + AUXREG); \ +} while(0) +#define FLPY_MOTOROFF \ +do { if (AUXREG) \ + sbus_writeb((sbus_readb(AUXREG) | \ + AUXIO_ORMEIN) & (~AUXIO_FLPY_DSEL), \ + AUXREG); \ +} while(0) +#define FLPY_TCNTON \ +do { if (AUXREG) \ + sbus_writeb((sbus_readb(AUXREG) | \ + AUXIO_ORMEIN) | AUXIO_FLPY_TCNT, \ + AUXREG); \ +} while(0) +#define FLPY_TCNTOFF \ +do { if (AUXREG) \ + sbus_writeb((sbus_readb(AUXREG) | \ + AUXIO_ORMEIN) & (~AUXIO_FLPY_TCNT), \ + AUXREG); \ +} while(0) #ifndef __ASSEMBLY__ extern __inline__ void set_auxio(unsigned char bits_on, unsigned char bits_off) @@ -53,8 +87,13 @@ extern __inline__ void set_auxio(unsigned char bits_on, unsigned char bits_off) save_flags(flags); cli(); if(AUXREG) { - regval = *AUXREG; - *AUXREG = ((regval | bits_on) & ~bits_off) | AUXIO_ORMEIN4M; + unsigned char newval; + + regval = sbus_readb(AUXREG); + newval = regval | bits_on; + newval &= ~bits_off; + newval |= AUXIO_ORMEIN4M; + sbus_writeb(newval, AUXREG); } restore_flags(flags); } diff --git a/include/asm-sparc64/checksum.h b/include/asm-sparc64/checksum.h index 519074118..6f6f8fe06 100644 --- a/include/asm-sparc64/checksum.h +++ b/include/asm-sparc64/checksum.h @@ -1,4 +1,4 @@ -/* $Id: checksum.h,v 1.13 1999/07/30 09:31:13 davem Exp $ */ +/* $Id: checksum.h,v 1.14 2000/01/05 21:27:42 davem Exp $ */ #ifndef __SPARC64_CHECKSUM_H #define __SPARC64_CHECKSUM_H @@ -29,7 +29,7 @@ * * it's best to have buff aligned on a 32-bit boundary */ -extern unsigned int csum_partial(unsigned char * buff, int len, unsigned int sum); +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 @@ -67,7 +67,7 @@ csum_partial_copy_from_user(const char *src, char *dst, int len, } #if 0 -/* Not implemented, but nobody uses it yet... */ +/* XXX should implement this now... -DaveM */ extern __inline__ unsigned int csum_partial_copy_to_user(const char *src, char *dst, int len, unsigned int sum, int *err) diff --git a/include/asm-sparc64/div64.h b/include/asm-sparc64/div64.h new file mode 100644 index 000000000..a36d2443d --- /dev/null +++ b/include/asm-sparc64/div64.h @@ -0,0 +1,14 @@ +#ifndef __SPARC64_DIV64 +#define __SPARC64_DIV64 + +/* + * Hey, we're already 64-bit, no + * need to play games.. + */ +#define do_div(n,base) ({ \ + int __res; \ + __res = ((unsigned long) n) % (unsigned) base; \ + n = ((unsigned long) n) / (unsigned) base; \ + __res; }) + +#endif /* __SPARC64_DIV64 */ diff --git a/include/asm-sparc64/dma.h b/include/asm-sparc64/dma.h index b21cbcc9f..9bab4ebca 100644 --- a/include/asm-sparc64/dma.h +++ b/include/asm-sparc64/dma.h @@ -1,4 +1,4 @@ -/* $Id: dma.h,v 1.16 1999/09/10 10:44:32 davem Exp $ +/* $Id: dma.h,v 1.18 1999/12/01 10:47:22 davem Exp $ * include/asm-sparc64/dma.h * * Copyright 1996 (C) David S. Miller (davem@caip.rutgers.edu) @@ -33,22 +33,17 @@ extern spinlock_t dma_spin_lock; #define MAX_DMA_CHANNELS 8 #define DMA_MODE_READ 1 #define DMA_MODE_WRITE 2 - -/* This is actually used. */ -extern unsigned long phys_base; -#define MAX_DMA_ADDRESS (phys_base + (0xfe000000UL) + PAGE_OFFSET) +#define MAX_DMA_ADDRESS (~0UL) /* Useful constants */ #define SIZE_16MB (16*1024*1024) #define SIZE_64K (64*1024) -/* Structure to describe the current status of DMA registers on the Sparc */ -struct sparc_dma_registers { - __volatile__ __u32 cond_reg; /* DMA condition register */ - __volatile__ __u32 st_addr; /* Start address of this transfer */ - __volatile__ __u32 cnt; /* How many bytes to transfer */ - __volatile__ __u32 dma_test; /* DMA test register */ -}; +/* 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 { @@ -64,10 +59,10 @@ enum dvma_rev { #define DMA_HASCOUNT(rev) ((rev)==dvmaesc1) /* Linux DMA information structure, filled during probe. */ -struct Linux_SBus_DMA { - struct Linux_SBus_DMA *next; - struct linux_sbus_device *SBus_dev; - struct sparc_dma_registers *regs; +struct sbus_dma { + struct sbus_dma *next; + struct sbus_dev *sdev; + unsigned long regs; /* Status, misc info */ int node; /* Prom node for this DMA device */ @@ -75,7 +70,7 @@ struct Linux_SBus_DMA { int allocated; /* Are we "owned" by anyone yet? */ /* Transfer information. */ - unsigned int addr; /* Start address of current transfer */ + u32 addr; /* Start address of current transfer */ int nbytes; /* Size of current transfer */ int realbytes; /* For splitting up large transfers, etc. */ @@ -83,14 +78,14 @@ struct Linux_SBus_DMA { enum dvma_rev revision; }; -extern struct Linux_SBus_DMA *dma_chain; +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 linux_sbus *); +extern void dvma_init(struct sbus_bus *); /* Fields in the cond_reg register */ /* First, the version identification bits */ @@ -124,7 +119,9 @@ extern void dvma_init(struct linux_sbus *); #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_BURST8 0x00040000 /* ENET: SBUS r/w burst size */ +#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 */ @@ -156,18 +153,42 @@ extern void dvma_init(struct linux_sbus *); #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) ((((regs)->cond_reg) & DMA_HNDL_ERROR)) -#define DMA_IRQ_P(regs) ((((regs)->cond_reg) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))) -#define DMA_WRITE_P(regs) ((((regs)->cond_reg) & DMA_ST_WRITE)) -#define DMA_OFF(regs) ((((regs)->cond_reg) &= (~DMA_ENABLE))) -#define DMA_INTSOFF(regs) ((((regs)->cond_reg) &= (~DMA_INT_ENAB))) -#define DMA_INTSON(regs) ((((regs)->cond_reg) |= (DMA_INT_ENAB))) -#define DMA_PUNTFIFO(regs) ((((regs)->cond_reg) |= DMA_FIFO_INV)) -#define DMA_SETSTART(regs, addr) ((((regs)->st_addr) = (char *) addr)) -#define DMA_BEGINDMA_W(regs) \ - ((((regs)->cond_reg |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB)))) -#define DMA_BEGINDMA_R(regs) \ - ((((regs)->cond_reg |= ((DMA_ENABLE|DMA_INT_ENAB)&(~DMA_ST_WRITE))))) +#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 diff --git a/include/asm-sparc64/elf.h b/include/asm-sparc64/elf.h index 6fc6c3c03..e99eea697 100644 --- a/include/asm-sparc64/elf.h +++ b/include/asm-sparc64/elf.h @@ -1,4 +1,4 @@ -/* $Id: elf.h,v 1.21 1999/08/04 07:04:23 jj Exp $ */ +/* $Id: elf.h,v 1.23 1999/12/15 14:19:06 davem Exp $ */ #ifndef __ASM_SPARC64_ELF_H #define __ASM_SPARC64_ELF_H @@ -48,7 +48,7 @@ typedef struct { that it will "exec", and that there is sufficient room for the brk. */ #ifndef ELF_ET_DYN_BASE -#define ELF_ET_DYN_BASE 0xfffff80000000000UL +#define ELF_ET_DYN_BASE 0x0000010000000000UL #endif @@ -75,9 +75,17 @@ do { unsigned char flags = current->thread.flags; \ flags &= ~SPARC_FLAG_32BIT; \ if (flags != current->thread.flags) { \ unsigned long pgd_cache = 0UL; \ - if (flags & SPARC_FLAG_32BIT) \ - pgd_cache = \ - pgd_val(current->mm->pgd[0])<<11UL; \ + if (flags & SPARC_FLAG_32BIT) { \ + pgd_t *pgd0 = ¤t->mm->pgd[0]; \ + if (pgd_none (*pgd0)) { \ + pmd_t *page = get_pmd_fast(); \ + if (!page) \ + (void) get_pmd_slow(pgd0, 0); \ + else \ + pgd_set(pgd0, page); \ + } \ + pgd_cache = pgd_val(*pgd0) << 11UL; \ + } \ __asm__ __volatile__( \ "stxa\t%0, [%1] %2" \ : /* no outputs */ \ diff --git a/include/asm-sparc64/fcntl.h b/include/asm-sparc64/fcntl.h index e0352b8d9..a55386944 100644 --- a/include/asm-sparc64/fcntl.h +++ b/include/asm-sparc64/fcntl.h @@ -1,4 +1,4 @@ -/* $Id: fcntl.h,v 1.5 1998/10/26 20:03:15 davem Exp $ */ +/* $Id: fcntl.h,v 1.7 2000/01/04 23:54:58 davem Exp $ */ #ifndef _SPARC64_FCNTL_H #define _SPARC64_FCNTL_H @@ -19,6 +19,7 @@ #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 F_DUPFD 0 /* dup */ #define F_GETFD 1 /* get f_flags */ diff --git a/include/asm-sparc64/fhc.h b/include/asm-sparc64/fhc.h index d93fdd733..288b4a428 100644 --- a/include/asm-sparc64/fhc.h +++ b/include/asm-sparc64/fhc.h @@ -1,7 +1,7 @@ -/* $Id: fhc.h,v 1.4 1998/12/14 12:18:20 davem Exp $ +/* $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 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com) */ #ifndef _SPARC64_FHC_H @@ -9,29 +9,20 @@ #include <linux/timer.h> -#include <asm/firehose.h> #include <asm/oplib.h> +#include <asm/upa.h> struct linux_fhc; -struct clock_board_regs { - u8 control; - u8 _unused1[0x10 - 0x01]; - u8 stat1; - u8 _unused2[0x10 - 0x01]; - u8 stat2; - u8 _unused3[0x10 - 0x01]; - u8 pwr_stat; - u8 _unused4[0x10 - 0x01]; - u8 pwr_presence; - u8 _unused5[0x10 - 0x01]; - u8 temperature; - u8 _unused6[0x10 - 0x01]; - u8 irq_diag; - u8 _unused7[0x10 - 0x01]; - u8 pwr_stat2; - u8 _unused8[0x10 - 0x01]; -}; +/* 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 */ @@ -39,9 +30,9 @@ struct clock_board_regs { struct linux_central { struct linux_fhc *child; - volatile u8 *cfreg; - struct clock_board_regs *clkregs; - volatile u8 *clkver; + unsigned long cfreg; + unsigned long clkregs; + unsigned long clkver; int slots; int prom_node; char prom_name[64]; @@ -50,6 +41,71 @@ struct linux_central { 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 0x50UL /* 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 0x60UL /* 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 */ @@ -65,12 +121,12 @@ struct linux_fhc { extern struct linux_central *central_bus; -extern void prom_apply_central_ranges(struct linux_central *central, - struct linux_prom_registers *regs, - int nregs); +extern void apply_central_ranges(struct linux_central *central, + struct linux_prom_registers *regs, + int nregs); -extern void prom_apply_fhc_ranges(struct linux_fhc *fhc, - 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/firehose.h b/include/asm-sparc64/firehose.h deleted file mode 100644 index d6031c927..000000000 --- a/include/asm-sparc64/firehose.h +++ /dev/null @@ -1,141 +0,0 @@ -/* $Id: firehose.h,v 1.4 1998/12/02 10:16:47 davem Exp $ - * firehose.h: Defines for the Fire Hose Controller (FHC) found - * on Sunfire/Starfire/Wildfire systems. - * - * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) - */ - -#ifndef _SPARC64_FIREHOSE_H -#define _SPARC64_FIREHOSE_H - -#include <linux/types.h> - -/* Fire Hose Controller Internal Registers */ -struct fhc_internal_regs { -/*0x0000*/ u32 fhc_id; /* FHC ID Register */ - u32 _unused1[3]; -/*0x0010*/ u32 fhc_rcs; /* FHC Reset Control/Status Register */ - u32 _unused2[3]; -/*0x0020*/ u32 fhc_control; /* FHC Control Register */ - u32 _unused3[3]; -/*0x0030*/ u32 fhc_bsr; /* FHC Board Status Register */ - u32 _unused4[3]; -/*0x0040*/ u32 fhc_ecc; /* FHC ECC Control Register (16 bits) */ - u32 _unused5[43]; -/*0x00f0*/ u32 fhc_jtag_ctrl; /* FHC JTAG Control Register */ - u32 _unused6[3]; -/*0x0100*/ u32 fhc_jtag_cmd; /* FHC JTAG Command Register */ -}; - -/* Part of same space of regs, but mapped separately in PROM reg property - * for the FHC, thus we have the following few structs... - */ -struct fhc_ign_reg { -/*0x2000*/ u32 fhc_ign; /* FHC Interrupt Group Number */ -}; - -struct fhc_fanfail_regs { -/*0x4000*/ u32 fhc_ff_imap; /* FHC FanFail Interrupt Map */ - u32 _pad[3]; -/*0x4010*/ u32 fhc_ff_iclr; /* FHC FanFail Interrupt Clear */ -}; - -struct fhc_system_regs { -/*0x6000*/ u32 fhc_sys_imap; /* FHC System Interrupt Map */ - u32 _pad[3]; -/*0x6010*/ u32 fhc_sys_iclr; /* FHC System Interrupt Clear */ -}; - -struct fhc_uart_regs { -/*0x8000*/ u32 fhc_uart_imap; /* FHC UART Interrupt Map */ - u32 _pad[3]; -/*0x8010*/ u32 fhc_uart_iclr; /* FHC UART Interrupt Clear */ -}; - -struct fhc_tod_regs { -/*0xa000*/ u32 fhc_tod_imap; /* FHC TOD Interrupt Map */ - u32 _pad1[3]; -/*0xa010*/ u32 fhc_tod_iclr; /* FHC TOD Interrupt Clear */ -}; - -/* All of the above. */ -struct fhc_regs { - struct fhc_internal_regs *pregs; - struct fhc_ign_reg *ireg; - struct fhc_fanfail_regs *ffregs; - struct fhc_system_regs *sregs; - struct fhc_uart_regs *uregs; - struct fhc_tod_regs *tregs; -}; - -/* FHC ID Register */ -#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 */ - -/* 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 */ - -/* 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 */ - -/* 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 */ - -/* 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 */ - -/* FHC then has an Interrupt Group Number register, essentially this is a 32-bit - * register with the low 5 bits specifying the IGN of this FHC for interrupt - * generation purposes, it is a product of the BoardID/Pins seen by the FHC - * at power on time. I suspect the firmware really sets this value though - * during POST. On board FHC devices generate fixed INO interrupt packet - * values, of course these are concatenated with the IGN before it reaches the - * CPU: - * - * IRQ Source INO Value - * ---------------------------------------- - * "System" Interrupt 0x38 - * Zilogs 0x39 - * Mostek 0x3a - * Fan Failure 0x3b - * Spare 1 0x3c - * Spare 2 0x3d - * - * Consult the sysio.h header for the layout of the Interrupt Mapping and - * Interrupt Clear register bits as they are the same. -DaveM - */ - -#endif /* !(_SPARC64_FIREHOSE_H) */ diff --git a/include/asm-sparc64/floppy.h b/include/asm-sparc64/floppy.h index 8ac72c3ac..fda381c48 100644 --- a/include/asm-sparc64/floppy.h +++ b/include/asm-sparc64/floppy.h @@ -1,4 +1,4 @@ -/* $Id: floppy.h,v 1.22 1999/08/31 07:02:12 davem Exp $ +/* $Id: floppy.h,v 1.23 1999/09/21 14:39:34 davem Exp $ * asm-sparc64/floppy.h: Sparc specific parts of the Floppy driver. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -50,8 +50,8 @@ struct sun_flpy_controller { /* You'll only ever find one controller on an Ultra anyways. */ static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1; -volatile unsigned char *fdc_status; -static struct linux_sbus_device *floppy_sdev = NULL; +unsigned long fdc_status; +static struct sbus_dev *floppy_sdev = NULL; struct sun_floppy_ops { unsigned char (*fd_inb) (unsigned long port); @@ -120,12 +120,12 @@ static unsigned char sun_82077_fd_inb(unsigned long port) printk("floppy: Asked to read unknown port %lx\n", port); panic("floppy: Port bolixed."); case 4: /* FD_STATUS */ - return sun_fdc->status_82077 & ~STATUS_DMA; + return sbus_readb(&sun_fdc->status_82077) & ~STATUS_DMA; case 5: /* FD_DATA */ - return sun_fdc->data_82077; + return sbus_readb(&sun_fdc->data_82077); case 7: /* FD_DIR */ /* XXX: Is DCL on 0x80 in sun4m? */ - return sun_fdc->dir_82077; + return sbus_readb(&sun_fdc->dir_82077); }; panic("sun_82072_fd_inb: How did I get here?"); } @@ -139,16 +139,16 @@ static void sun_82077_fd_outb(unsigned char value, unsigned long port) panic("floppy: Port bolixed."); case 2: /* FD_DOR */ /* Happily, the 82077 has a real DOR register. */ - sun_fdc->dor_82077 = value; + sbus_writeb(value, &sun_fdc->dor_82077); break; case 5: /* FD_DATA */ - sun_fdc->data_82077 = value; + sbus_writeb(value, &sun_fdc->data_82077); break; case 7: /* FD_DCR */ - sun_fdc->dcr_82077 = value; + sbus_writeb(value, &sun_fdc->dcr_82077); break; case 4: /* FD_STATUS */ - sun_fdc->status_82077 = value; + sbus_writeb(value, &sun_fdc->status_82077); break; }; return; @@ -553,8 +553,8 @@ static unsigned long __init sun_floppy_init(void) { char state[128]; int fd_node, num_regs; - struct linux_sbus *bus; - struct linux_sbus_device *sdev = NULL; + struct sbus_bus *bus; + struct sbus_dev *sdev = NULL; static int initialized = 0; if (initialized) @@ -622,7 +622,7 @@ static unsigned long __init sun_floppy_init(void) sun_fdops.fd_eject = sun_pci_fd_eject; - fdc_status = &sun_fdc->status_82077; + fdc_status = (unsigned long) &sun_fdc->status_82077; FLOPPY_MOTOR_MASK = 0xf0; /* @@ -715,17 +715,17 @@ static unsigned long __init sun_floppy_init(void) num_regs = prom_getproperty(fd_node, "reg", (char *) fd_regs, sizeof(fd_regs)); num_regs = (num_regs / sizeof(fd_regs[0])); - prom_apply_sbus_ranges(sdev->my_bus, fd_regs, num_regs, sdev); + /* * We cannot do sparc_alloc_io here: it does request_region, * which the generic floppy driver tries to do once again. */ sun_fdc = (struct sun_flpy_controller *) - (PAGE_OFFSET + fd_regs[0].phys_addr + - (((unsigned long)fd_regs[0].which_io) << 32)); + (PAGE_OFFSET + fd_regs[0].phys_addr + + (((unsigned long)fd_regs[0].which_io) << 32)); /* Last minute sanity check... */ - if(sun_fdc->status1_82077 == 0xff) { + if(sbus_readb(&sun_fdc->status1_82077) == 0xff) { sun_fdc = (struct sun_flpy_controller *)-1; return 0; } @@ -748,7 +748,7 @@ static unsigned long __init sun_floppy_init(void) sun_fdops.fd_eject = sun_fd_eject; - fdc_status = &sun_fdc->status_82077; + fdc_status = (unsigned long) &sun_fdc->status_82077; /* Success... */ allowed_drive_mask = 0x01; diff --git a/include/asm-sparc64/ide.h b/include/asm-sparc64/ide.h index 0f6d0de23..385baa7a4 100644 --- a/include/asm-sparc64/ide.h +++ b/include/asm-sparc64/ide.h @@ -1,4 +1,4 @@ -/* $Id: ide.h,v 1.16 1999/08/30 10:14:42 davem Exp $ +/* $Id: ide.h,v 1.17 1999/12/15 22:18:49 davem Exp $ * ide.h: Ultra/PCI specific IDE glue. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -11,7 +11,7 @@ #ifdef __KERNEL__ #include <linux/config.h> -#include <asm/pgtable.h> +#include <asm/pgalloc.h> #include <asm/io.h> #include <asm/hdreg.h> diff --git a/include/asm-sparc64/io.h b/include/asm-sparc64/io.h index 8295a17ce..5dc5c88c6 100644 --- a/include/asm-sparc64/io.h +++ b/include/asm-sparc64/io.h @@ -1,4 +1,4 @@ -/* $Id: io.h,v 1.24 1999/09/06 01:17:54 davem Exp $ */ +/* $Id: io.h,v 1.29 1999/12/20 04:58:42 davem Exp $ */ #ifndef __SPARC64_IO_H #define __SPARC64_IO_H @@ -13,7 +13,9 @@ #define __SLOW_DOWN_IO do { } while (0) #define SLOW_DOWN_IO do { } while (0) +#undef NEW_PCI_DMA_MAP +#ifndef NEW_PCI_DMA_MAP #define PCI_DVMA_HASHSZ 256 extern unsigned long pci_dvma_v2p_hash[PCI_DVMA_HASHSZ]; @@ -21,7 +23,7 @@ extern unsigned long pci_dvma_p2v_hash[PCI_DVMA_HASHSZ]; #define pci_dvma_ahashfn(addr) (((addr) >> 24) & 0xff) -extern __inline__ unsigned long virt_to_phys(volatile void *addr) +extern __inline__ unsigned long virt_to_bus(volatile void *addr) { unsigned long vaddr = (unsigned long)addr; unsigned long off; @@ -34,7 +36,7 @@ extern __inline__ unsigned long virt_to_phys(volatile void *addr) return vaddr + off; } -extern __inline__ void *phys_to_virt(unsigned long addr) +extern __inline__ void *bus_to_virt(unsigned long addr) { unsigned long paddr = addr & 0xffffffffUL; unsigned long off; @@ -42,9 +44,12 @@ extern __inline__ void *phys_to_virt(unsigned long addr) off = pci_dvma_p2v_hash[pci_dvma_ahashfn(paddr)]; return (void *)(paddr + off); } - -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt +#else +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 +#endif /* Different PCI controllers we support have their PCI MEM space * mapped to an either 2GB (Psycho) or 4GB (Sabre) aligned area, @@ -58,7 +63,7 @@ extern __inline__ unsigned int inb(unsigned long addr) { unsigned int ret; - __asm__ __volatile__("lduba [%1] %2, %0" + __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_inb */" : "=r" (ret) : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); @@ -69,7 +74,7 @@ extern __inline__ unsigned int inw(unsigned long addr) { unsigned int ret; - __asm__ __volatile__("lduha [%1] %2, %0" + __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_inw */" : "=r" (ret) : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); @@ -80,7 +85,7 @@ extern __inline__ unsigned int inl(unsigned long addr) { unsigned int ret; - __asm__ __volatile__("lduwa [%1] %2, %0" + __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_inl */" : "=r" (ret) : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); @@ -89,23 +94,23 @@ extern __inline__ unsigned int inl(unsigned long addr) extern __inline__ void outb(unsigned char b, unsigned long addr) { - __asm__ __volatile__("stba %0, [%1] %2" + __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_outb */" : /* no outputs */ - : "r" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); + : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); } extern __inline__ void outw(unsigned short w, unsigned long addr) { - __asm__ __volatile__("stha %0, [%1] %2" + __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_outw */" : /* no outputs */ - : "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); + : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); } extern __inline__ void outl(unsigned int l, unsigned long addr) { - __asm__ __volatile__("stwa %0, [%1] %2" + __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_outl */" : /* no outputs */ - : "r" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); + : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); } #define inb_p inb @@ -123,7 +128,7 @@ extern __inline__ unsigned int _readb(unsigned long addr) { unsigned int ret; - __asm__ __volatile__("lduba [%1] %2, %0" + __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_readb */" : "=r" (ret) : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); @@ -134,7 +139,7 @@ extern __inline__ unsigned int _readw(unsigned long addr) { unsigned int ret; - __asm__ __volatile__("lduha [%1] %2, %0" + __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_readw */" : "=r" (ret) : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); @@ -145,7 +150,7 @@ extern __inline__ unsigned int _readl(unsigned long addr) { unsigned int ret; - __asm__ __volatile__("lduwa [%1] %2, %0" + __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_readl */" : "=r" (ret) : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); @@ -154,23 +159,23 @@ extern __inline__ unsigned int _readl(unsigned long addr) extern __inline__ void _writeb(unsigned char b, unsigned long addr) { - __asm__ __volatile__("stba %0, [%1] %2" + __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_writeb */" : /* no outputs */ - : "r" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); + : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); } extern __inline__ void _writew(unsigned short w, unsigned long addr) { - __asm__ __volatile__("stha %0, [%1] %2" + __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_writew */" : /* no outputs */ - : "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); + : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); } extern __inline__ void _writel(unsigned int l, unsigned long addr) { - __asm__ __volatile__("stwa %0, [%1] %2" + __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */" : /* no outputs */ - : "r" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); + : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); } #define readb(__addr) (_readb((unsigned long)(__addr))) @@ -180,56 +185,126 @@ extern __inline__ void _writel(unsigned int l, unsigned long addr) #define writew(__w, __addr) (_writew((__w), (unsigned long)(__addr))) #define writel(__l, __addr) (_writel((__l), (unsigned long)(__addr))) -#define IO_SPACE_LIMIT 0xffffffff - -/* - * Memcpy to/from I/O space is just a regular memory operation on - * Ultra as well. +/* 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 -/* - * FIXME: Write faster routines using ASL_*L for this. +/* Now, SBUS variants, only difference from PCI is that we do + * not use little-endian ASIs. */ -static inline void * -memset_io(void *dst, int c, __kernel_size_t n) +extern __inline__ unsigned int _sbus_readb(unsigned long addr) { - char *d = dst; + unsigned int ret; - while (n--) - *d++ = c; + __asm__ __volatile__("lduba\t[%1] %2, %0\t/* sbus_readb */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); - return dst; + return ret; +} + +extern __inline__ unsigned int _sbus_readw(unsigned long addr) +{ + unsigned int ret; + + __asm__ __volatile__("lduha\t[%1] %2, %0\t/* sbus_readw */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +extern __inline__ unsigned int _sbus_readl(unsigned long addr) +{ + unsigned int ret; + + __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* sbus_readl */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +extern __inline__ void _sbus_writeb(unsigned char b, unsigned long addr) +{ + __asm__ __volatile__("stba\t%r0, [%1] %2\t/* sbus_writeb */" + : /* no outputs */ + : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +extern __inline__ void _sbus_writew(unsigned short w, unsigned long addr) +{ + __asm__ __volatile__("stha\t%r0, [%1] %2\t/* sbus_writew */" + : /* no outputs */ + : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +extern __inline__ void _sbus_writel(unsigned int l, unsigned long addr) +{ + __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* sbus_writel */" + : /* no outputs */ + : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +#define sbus_readb(__addr) (_sbus_readb((unsigned long)(__addr))) +#define sbus_readw(__addr) (_sbus_readw((unsigned long)(__addr))) +#define sbus_readl(__addr) (_sbus_readl((unsigned long)(__addr))) +#define sbus_writeb(__b, __addr) (_sbus_writeb((__b), (unsigned long)(__addr))) +#define sbus_writew(__w, __addr) (_sbus_writew((__w), (unsigned long)(__addr))) +#define sbus_writel(__l, __addr) (_sbus_writel((__l), (unsigned long)(__addr))) + +static inline void *sbus_memset_io(void *__dst, int c, __kernel_size_t n) +{ + unsigned long dst = (unsigned long)__dst; + + while(n--) { + sbus_writeb(c, dst); + dst++; + } + return (void *) dst; } static inline void * -memcpy_fromio(void *dst, const void *src, __kernel_size_t n) +memset_io(void *dst, int c, __kernel_size_t n) { - const char *s = src; char *d = dst; - while (n--) - *d++ = *s++; + while (n--) { + writeb(c, d); + d++; + } return dst; } static inline void * -memcpy_toio(void *dst, const void *src, __kernel_size_t n) +memcpy_fromio(void *dst, unsigned long src, __kernel_size_t n) { - const char *s = src; char *d = dst; - while (n--) - *d++ = *s++; + while (n--) { + char tmp = readb(src); + *d++ = tmp; + src++; + } return dst; } -#if 0 /* XXX Not exactly, we need to use ASI_*L from/to the I/O end, - * XXX so these are disabled until we code that stuff. - */ -#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),((char *)(b)),(c),(d)) -#endif +static inline void * +memcpy_toio(unsigned long dst, const void *src, __kernel_size_t n) +{ + const char *s = src; + unsigned long d = dst; + + while (n--) { + char tmp = *s++; + writeb(tmp, d); + d++; + } + return (void *)dst; +} static inline int check_signature(unsigned long io_addr, const unsigned char *signature, @@ -251,27 +326,18 @@ out: #define ioremap(__offset, __size) ((void *)(__offset)) #define iounmap(__addr) do { } while(0) -extern void sparc_ultra_mapioaddr(unsigned long physaddr, - unsigned long virt_addr, - int bus, int rdonly); -extern void sparc_ultra_unmapioaddr(unsigned long virt_addr); - -extern __inline__ void mapioaddr(unsigned long physaddr, - unsigned long virt_addr, - int bus, int rdonly) -{ - sparc_ultra_mapioaddr(physaddr, virt_addr, bus, rdonly); -} - -extern __inline__ void unmapioaddr(unsigned long virt_addr) -{ - sparc_ultra_unmapioaddr(virt_addr); -} - -extern void *sparc_alloc_io(u32 pa, void *va, int sz, char *name, - u32 io, int rdonly); -extern void sparc_free_io (void *va, int sz); -extern void *sparc_dvma_malloc (int sz, char *name, __u32 *dvma_addr); +/* 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; \ + __ret; \ +}) + +#define sbus_iounmap(__addr, __size) \ + release_region((__addr), (__size)) /* Nothing to do */ diff --git a/include/asm-sparc64/iommu.h b/include/asm-sparc64/iommu.h index 9c21b9dc3..4e709ee25 100644 --- a/include/asm-sparc64/iommu.h +++ b/include/asm-sparc64/iommu.h @@ -1,40 +1,12 @@ -/* iommu.h: Definitions for the sun5 IOMMU. +/* $Id: iommu.h,v 1.9 1999/09/21 14:39:39 davem Exp $ + * iommu.h: Definitions for the sun5 IOMMU. * - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996, 1999 David S. Miller (davem@caip.rutgers.edu) */ #ifndef _SPARC64_IOMMU_H #define _SPARC64_IOMMU_H -#include <linux/spinlock.h> -#include <asm/page.h> -#include <asm/sysio.h> - -/* The iommu handles all virtual to physical address translations - * that occur between the SYSIO and physical memory. Access by - * the cpu to IO registers and similar go over the UPA so are - * translated by the on chip TLB's. The iommu and the TLB do - * not need to have the same translations at all, in fact most - * of the time the translations they handle are a disjoint set. - * Basically the iommu handles all SYSIO dvma translations. - */ - -/* The IOMMU register set. */ -#define IOMMU_CTRL_IMPL 0xf000000000000000 /* Implementation */ -#define IOMMU_CTRL_VERS 0x0f00000000000000 /* Version */ -#define IOMMU_CTRL_TSBSZ 0x0000000000070000 /* TSB Size */ -#define IOMMU_TSBSZ_1K 0x0000000000000000 /* TSB Table 1024 8-byte entries */ -#define IOMMU_TSBSZ_2K 0x0000000000010000 /* TSB Table 2048 8-byte entries */ -#define IOMMU_TSBSZ_4K 0x0000000000020000 /* TSB Table 4096 8-byte entries */ -#define IOMMU_TSBSZ_8K 0x0000000000030000 /* TSB Table 8192 8-byte entries */ -#define IOMMU_TSBSZ_16K 0x0000000000040000 /* TSB Table 16k 8-byte entries */ -#define IOMMU_TSBSZ_32K 0x0000000000050000 /* TSB Table 32k 8-byte entries */ -#define IOMMU_TSBSZ_64K 0x0000000000060000 /* TSB Table 64k 8-byte entries */ -#define IOMMU_TSBSZ_128K 0x0000000000070000 /* TSB Table 128k 8-byte entries */ -#define IOMMU_CTRL_TBWSZ 0x0000000000000004 /* Assumed page size, 0=8k 1=64k */ -#define IOMMU_CTRL_DENAB 0x0000000000000002 /* Diagnostic mode enable */ -#define IOMMU_CTRL_ENAB 0x0000000000000001 /* IOMMU Enable */ - -/* The format of an iopte in the page tables, we only use 64k pages. */ +/* The format of an iopte in the page tables. */ #define IOPTE_VALID 0x8000000000000000 /* IOPTE is valid */ #define IOPTE_64K 0x2000000000000000 /* IOPTE is for 64k page */ #define IOPTE_STBUF 0x1000000000000000 /* DVMA can use streaming buffer */ @@ -44,12 +16,4 @@ #define IOPTE_CACHE 0x0000000000000010 /* Cached (in UPA E-cache) */ #define IOPTE_WRITE 0x0000000000000002 /* Writeable */ -struct iommu_struct { - struct sysio_regs *sysio_regs; - iopte_t *page_table; - volatile unsigned int flushflag; - unsigned int strbuf_enabled; - spinlock_t iommu_lock; -}; - #endif /* !(_SPARC_IOMMU_H) */ diff --git a/include/asm-sparc64/ipc.h b/include/asm-sparc64/ipc.h index 3e14f7c9f..87fe443d5 100644 --- a/include/asm-sparc64/ipc.h +++ b/include/asm-sparc64/ipc.h @@ -23,6 +23,9 @@ struct ipc_kludge { #define SHMGET 23 #define SHMCTL 24 +/* Used by the DIPC package, try and avoid reusing it */ +#define DIPC 25 + /* We don't need to maintain backward compatibility on 64bit, we've started fresh */ #define IPCCALL(version,op) (op) diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h index 045ae8bc9..53124b0ea 100644 --- a/include/asm-sparc64/irq.h +++ b/include/asm-sparc64/irq.h @@ -1,4 +1,4 @@ -/* $Id: irq.h,v 1.16 1999/09/06 01:17:52 davem Exp $ +/* $Id: irq.h,v 1.17 1999/09/21 14:39:41 davem Exp $ * irq.h: IRQ registers on the 64-bit Sparc. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -61,13 +61,24 @@ struct ino_bucket { /*0x08*/void *irq_info; /* Sun5 Interrupt Clear Register. */ -/*0x10*/volatile unsigned int *iclr; +/*0x10*/unsigned long iclr; /* Sun5 Interrupt Mapping Register. */ -/*0x18*/volatile unsigned int *imap; +/*0x18*/unsigned long imap; }; +/* IMAP/ICLR register defines */ +#define IMAP_VALID 0x80000000 /* IRQ Enabled */ +#define IMAP_TID 0x7c000000 /* UPA TargetID */ +#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. */ @@ -98,7 +109,7 @@ extern void disable_irq(unsigned int); extern void enable_irq(unsigned int); extern void init_timers(void (*lvl10_irq)(int, void *, struct pt_regs *), unsigned long *); -extern unsigned int build_irq(int pil, int inofixup, volatile unsigned int *iclr, volatile unsigned int *imap); +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 unsigned int psycho_build_irq(void *psycho, int imap_off, int ino, int need_dma_sync); diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h index e19335be7..ae61e47a6 100644 --- a/include/asm-sparc64/mmu_context.h +++ b/include/asm-sparc64/mmu_context.h @@ -1,15 +1,15 @@ -/* $Id: mmu_context.h,v 1.40 1999/09/10 10:44:37 davem Exp $ */ +/* $Id: mmu_context.h,v 1.41 1999/09/10 15:39:03 jj 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> -#ifndef __ASSEMBLY__ - extern spinlock_t ctx_alloc_lock; extern unsigned long tlb_context_cache; extern unsigned long mmu_context_bmap[]; diff --git a/include/asm-sparc64/openpromio.h b/include/asm-sparc64/openpromio.h index 0361c668c..37420b761 100644 --- a/include/asm-sparc64/openpromio.h +++ b/include/asm-sparc64/openpromio.h @@ -29,6 +29,10 @@ struct openpromio #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: diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h index f0ca1df71..7036f6e82 100644 --- a/include/asm-sparc64/oplib.h +++ b/include/asm-sparc64/oplib.h @@ -1,4 +1,4 @@ -/* $Id: oplib.h,v 1.11 1999/08/31 19:25:49 davem Exp $ +/* $Id: oplib.h,v 1.12 1999/11/19 05:53:12 davem Exp $ * oplib.h: Describes the interface and available routines in the * Linux Prom library. * @@ -223,6 +223,24 @@ 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 diff --git a/include/asm-sparc64/page.h b/include/asm-sparc64/page.h index 1e89c16e6..dabfea993 100644 --- a/include/asm-sparc64/page.h +++ b/include/asm-sparc64/page.h @@ -1,4 +1,4 @@ -/* $Id: page.h,v 1.27 1999/07/31 00:07:25 davem Exp $ */ +/* $Id: page.h,v 1.29 1999/12/09 10:32:43 davem Exp $ */ #ifndef _SPARC64_PAGE_H #define _SPARC64_PAGE_H @@ -21,8 +21,8 @@ #define BUG() __builtin_trap() #define PAGE_BUG(page) BUG() -extern void clear_page(unsigned long page); -extern void copy_page(unsigned long to, unsigned long from); +extern void clear_page(void *page); +extern void copy_page(void *to, void *from); /* GROSS, defining this makes gcc pass these types as aggregates, * and thus on the stack, turn this crap off... -DaveM @@ -104,6 +104,9 @@ register unsigned long page_offset asm("g4"); #define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) #define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT) +#define virt_to_phys __pa +#define phys_to_virt __va + #ifndef __ASSEMBLY__ /* The following structure is used to hold the physical diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h index 1f740c845..12f015edb 100644 --- a/include/asm-sparc64/pbm.h +++ b/include/asm-sparc64/pbm.h @@ -1,4 +1,4 @@ -/* $Id: pbm.h,v 1.18 1999/09/10 10:44:40 davem Exp $ +/* $Id: pbm.h,v 1.19 1999/12/17 12:32:13 jj Exp $ * pbm.h: UltraSparc PCI controller software state. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) @@ -25,6 +25,9 @@ * 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 @@ -40,8 +43,8 @@ struct pci_iommu { 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; /* How many pages does it map? */ + 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. @@ -49,7 +52,6 @@ struct pci_iommu { u32 page_table_map_base; /* IOMMU Controller Registers */ - int iommu_has_ctx_flush; /* Feature test. */ unsigned long iommu_control; /* IOMMU control register */ unsigned long iommu_tsbbase; /* IOMMU page table base register */ unsigned long iommu_flush; /* IOMMU page flush register */ @@ -60,12 +62,18 @@ struct pci_iommu { * completion of all previous writes into IOMMU/STC. */ unsigned long write_complete_reg; + + /* 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 + */ + u16 lowest_free[PBM_NCLUSTERS]; }; /* This describes a PCI bus module's streaming buffer. */ struct pci_strbuf { int strbuf_enabled; /* Present and using it? */ - int strbuf_has_ctx_flush; /* Supports context flushing? */ /* Streaming Buffer Control Registers */ unsigned long strbuf_control; /* STC control register */ diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h index 6d1558daf..98f706e01 100644 --- a/include/asm-sparc64/pci.h +++ b/include/asm-sparc64/pci.h @@ -9,35 +9,81 @@ */ #define pcibios_assign_all_busses() 0 -/* Map kernel buffer using consistant mode DMA for PCI device. - * Returns a 32-bit PCI DMA address. +struct pci_dev; + +/* Allocate and map kernel buffer using consistant mode DMA for PCI device. + * Returns non-NULL cpu-view pointer to the buffer if successful and + * sets *dma_addrp to the pci side dma address as well, else *dma_addrp + * is undefined. */ -extern u32 pci_map_consistant(struct pci_dev *, void *, int); +extern void *pci_alloc_consistant(struct pci_dev *pdev, long size, u32 *dma_addrp); -/* Unmap a consistant DMA translation. */ -extern void pci_unmap_consistant(struct pci_dev *, u32, int); +/* Free and unmap a consistant DMA buffer. + * cpu_addr is what was returned from pci_alloc_consistant, + * size must be the same as what as passed into pci_alloc_consistant, + * and likewise dma_addr must be the same as what *dma_addrp was set to. + * + * References to the memory and mappings assosciated with cpu_addr/dma_addr + * past this call are illegal. + */ +extern void pci_free_consistant(struct pci_dev *pdev, long size, void *cpu_addr, u32 dma_addr); -/* Map a single buffer for PCI DMA in streaming mode. */ -extern u32 pci_map_single(struct pci_dev *, void *, int); +/* Map a single buffer of the indicate size for PCI DMA in streaming mode. + * The 32-bit PCI bus mastering 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_sync_single is performed. + */ +extern u32 pci_map_single(struct pci_dev *pdev, void *buffer, long size); -/* Unmap a single streaming mode DMA translation. */ -extern void pci_unmap_single(struct pci_dev *, u32, int); +/* 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 guarenteed to see + * whatever the device wrote there. + */ +extern void pci_unmap_single(struct pci_dev *pdev, u32 dma_addr, long size); /* Map a set of buffers described by scatterlist in streaming - * mode for PCI DMA. + * mode for PCI DMA. This is the scather-gather version of the + * above pci_map_single interface. Here the scatter gather list + * elements are each tagged with the appropriate PCI 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 void pci_map_sg(struct pci_dev *, struct scatterlist *, int); +extern int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents); -/* Unmap a set of streaming mode DMA translations. */ -extern void pci_unmap_sg(struct pci_dev *, struct scatterlist *, int); +/* 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 *pdev, struct scatterlist *sg, int nents); /* Make physical memory consistant 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, the + * device again owns the buffer. */ -extern void pci_dma_sync_single(struct pci_dev *, u32, int); +extern void pci_dma_sync_single(struct pci_dev *, u32, long); /* Make physical memory consistant 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(struct pci_dev *, struct scatterlist *, int); diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h new file mode 100644 index 000000000..c0e4a12a1 --- /dev/null +++ b/include/asm-sparc64/pgalloc.h @@ -0,0 +1,301 @@ +/* $Id */ +#ifndef _SPARC64_PGALLOC_H +#define _SPARC64_PGALLOC_H + +#include <linux/kernel.h> +#include <linux/sched.h> + +#include <asm/page.h> + +/* Cache and TLB 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(mm, start, end) \ + flush_cache_mm(mm) +#define flush_cache_page(vma, page) \ + flush_cache_mm((vma)->vm_mm) + +/* These operations are unnecessary on the SpitFire since D-CACHE is write-through. */ +#define flush_icache_range(start, end) do { } while (0) +#define flush_page_to_ram(page) do { } while (0) + +extern void __flush_dcache_range(unsigned long start, unsigned long end); + +extern void __flush_cache_all(void); + +extern void __flush_tlb_all(void); +extern void __flush_tlb_mm(unsigned long context, unsigned long r); +extern void __flush_tlb_range(unsigned long context, unsigned long start, + unsigned long r, unsigned long end, + unsigned long pgsz, unsigned long size); +extern void __flush_tlb_page(unsigned long context, unsigned long page, unsigned long r); + +#ifndef __SMP__ + +#define flush_cache_all() __flush_cache_all() +#define flush_tlb_all() __flush_tlb_all() + +#define flush_tlb_mm(__mm) \ +do { if(CTX_VALID((__mm)->context)) \ + __flush_tlb_mm(CTX_HWBITS((__mm)->context), SECONDARY_CONTEXT); \ +} while(0) + +#define flush_tlb_range(__mm, start, end) \ +do { if(CTX_VALID((__mm)->context)) { \ + unsigned long __start = (start)&PAGE_MASK; \ + unsigned long __end = (end)&PAGE_MASK; \ + __flush_tlb_range(CTX_HWBITS((__mm)->context), __start, \ + SECONDARY_CONTEXT, __end, PAGE_SIZE, \ + (__end - __start)); \ + } \ +} while(0) + +#define flush_tlb_page(vma, page) \ +do { struct mm_struct *__mm = (vma)->vm_mm; \ + if(CTX_VALID(__mm->context)) \ + __flush_tlb_page(CTX_HWBITS(__mm->context), (page)&PAGE_MASK, \ + SECONDARY_CONTEXT); \ +} while(0) + +#else /* __SMP__ */ + +extern void smp_flush_cache_all(void); +extern void smp_flush_tlb_all(void); +extern void smp_flush_tlb_mm(struct mm_struct *mm); +extern void smp_flush_tlb_range(struct mm_struct *mm, unsigned long start, + unsigned long end); +extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long page); + +#define flush_cache_all() smp_flush_cache_all() +#define flush_tlb_all() smp_flush_tlb_all() + +extern __inline__ void flush_tlb_mm(struct mm_struct *mm) +{ + if (CTX_VALID(mm->context)) + smp_flush_tlb_mm(mm); +} + +extern __inline__ void flush_tlb_range(struct mm_struct *mm, unsigned long start, + unsigned long end) +{ + if (CTX_VALID(mm->context)) + smp_flush_tlb_range(mm, start, end); +} + +extern __inline__ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + struct mm_struct *mm = vma->vm_mm; + + if (CTX_VALID(mm->context)) + smp_flush_tlb_page(mm, page); +} + +#endif /* ! __SMP__ */ + +/* Page table allocation/freeing. */ +#ifdef __SMP__ +/* Sliiiicck */ +#define pgt_quicklists cpu_data[smp_processor_id()] +#else +extern struct pgtable_cache_struct { + unsigned long *pgd_cache; + unsigned long *pte_cache[2]; + unsigned int pgcache_size; + unsigned int pgdcache_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) +#define pgd_cache_size (pgt_quicklists.pgdcache_size) + +#ifndef __SMP__ + +extern __inline__ void free_pgd_fast(pgd_t *pgd) +{ + struct page *page = mem_map + MAP_NR(pgd); + + if (!page->pprev_hash) { + (unsigned long *)page->next_hash = pgd_quicklist; + pgd_quicklist = (unsigned long *)page; + } + (unsigned long)page->pprev_hash |= + (((unsigned long)pgd & (PAGE_SIZE / 2)) ? 2 : 1); + pgd_cache_size++; +} + +extern __inline__ pgd_t *get_pgd_fast(void) +{ + struct page *ret; + + if ((ret = (struct page *)pgd_quicklist) != NULL) { + unsigned long mask = (unsigned long)ret->pprev_hash; + unsigned long off = 0; + + if (mask & 1) + mask &= ~1; + else { + off = PAGE_SIZE / 2; + mask &= ~2; + } + (unsigned long)ret->pprev_hash = mask; + if (!mask) + pgd_quicklist = (unsigned long *)ret->next_hash; + ret = (struct page *)(__page_address(ret) + off); + pgd_cache_size--; + } else { + ret = (struct page *) __get_free_page(GFP_KERNEL); + if(ret) { + struct page *page = mem_map + MAP_NR(ret); + + memset(ret, 0, PAGE_SIZE); + (unsigned long)page->pprev_hash = 2; + (unsigned long *)page->next_hash = pgd_quicklist; + pgd_quicklist = (unsigned long *)page; + pgd_cache_size++; + } + } + return (pgd_t *)ret; +} + +#else /* __SMP__ */ + +extern __inline__ void free_pgd_fast(pgd_t *pgd) +{ + *(unsigned long *)pgd = (unsigned long) pgd_quicklist; + pgd_quicklist = (unsigned long *) pgd; + pgtable_cache_size++; +} + +extern __inline__ pgd_t *get_pgd_fast(void) +{ + unsigned long *ret; + + if((ret = pgd_quicklist) != NULL) { + pgd_quicklist = (unsigned long *)(*ret); + ret[0] = 0; + pgtable_cache_size--; + } else { + ret = (unsigned long *) __get_free_page(GFP_KERNEL); + if(ret) + memset(ret, 0, PAGE_SIZE); + } + return (pgd_t *)ret; +} + +extern __inline__ void free_pgd_slow(pgd_t *pgd) +{ + free_page((unsigned long)pgd); +} + +#endif /* __SMP__ */ + +extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long address_premasked); + +extern __inline__ pmd_t *get_pmd_fast(void) +{ + unsigned long *ret; + int color = 0; + + 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--; + } + return (pmd_t *)ret; +} + +extern __inline__ void free_pmd_fast(pmd_t *pmd) +{ + unsigned long color; + + color = (((unsigned long)pmd >> PAGE_SHIFT) & 0x1UL); + *(unsigned long *)pmd = (unsigned long) pte_quicklist[color]; + pte_quicklist[color] = (unsigned long *) pmd; + pgtable_cache_size++; +} + +extern __inline__ void free_pmd_slow(pmd_t *pmd) +{ + free_page((unsigned long)pmd); +} + +extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted, + unsigned long color); + +extern __inline__ pte_t *get_pte_fast(unsigned long color) +{ + unsigned long *ret; + + if((ret = (unsigned long *)pte_quicklist[color]) != NULL) { + pte_quicklist[color] = (unsigned long *)(*ret); + ret[0] = 0; + pgtable_cache_size--; + } + return (pte_t *)ret; +} + +extern __inline__ void free_pte_fast(pte_t *pte) +{ + unsigned long color = (((unsigned long)pte >> PAGE_SHIFT) & 0x1); + *(unsigned long *)pte = (unsigned long) pte_quicklist[color]; + pte_quicklist[color] = (unsigned long *) pte; + pgtable_cache_size++; +} + +extern __inline__ void free_pte_slow(pte_t *pte) +{ + free_page((unsigned long)pte); +} + +#define pte_free_kernel(pte) free_pte_fast(pte) +#define pte_free(pte) free_pte_fast(pte) +#define pmd_free_kernel(pmd) free_pmd_fast(pmd) +#define pmd_free(pmd) free_pmd_fast(pmd) +#define pgd_free(pgd) free_pgd_fast(pgd) +#define pgd_alloc() get_pgd_fast() + +extern inline pte_t * pte_alloc(pmd_t *pmd, unsigned long address) +{ + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); + if (pmd_none(*pmd)) { + /* Be careful, address can be just about anything... */ + unsigned long color = (((unsigned long)pmd)>>2UL) & 0x1UL; + pte_t *page = get_pte_fast(color); + + if (!page) + return get_pte_slow(pmd, address, color); + pmd_set(pmd, page); + return page + address; + } + return (pte_t *) pmd_page(*pmd) + address; +} + +extern inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address) +{ + address = (address >> PMD_SHIFT) & (REAL_PTRS_PER_PMD - 1); + if (pgd_none(*pgd)) { + pmd_t *page = get_pmd_fast(); + + if (!page) + return get_pmd_slow(pgd, address); + pgd_set(pgd, page); + return page + address; + } + return (pmd_t *) pgd_page(*pgd) + address; +} + +#define pte_alloc_kernel(pmd, addr) pte_alloc(pmd, addr) +#define pmd_alloc_kernel(pgd, addr) pmd_alloc(pgd, addr) + +extern int do_check_pgt_cache(int, int); + +/* Nothing to do on sparc64 :) */ +#define set_pgdir(address, entry) do { } while(0) + +#endif /* _SPARC64_PGALLOC_H */ diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index 5b31257da..3b93b20c1 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -1,4 +1,4 @@ -/* $Id: pgtable.h,v 1.110 1999/08/30 10:14:57 davem Exp $ +/* $Id: pgtable.h,v 1.118 1999/12/21 21:24:35 davem Exp $ * pgtable.h: SpitFire page table operations. * * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu) @@ -12,17 +12,12 @@ * the SpitFire page tables. */ -#ifndef __ASSEMBLY__ -#include <linux/mm.h> -#include <linux/pagemap.h> -#endif #include <asm/spitfire.h> #include <asm/asi.h> #include <asm/mmu_context.h> #include <asm/system.h> #ifndef __ASSEMBLY__ -#include <asm/sbus.h> /* Certain architectures need to do special things when pte's * within a page table are directly modified. Thus, the following @@ -69,6 +64,10 @@ #define VMALLOC_VMADDR(x) ((unsigned long)(x)) #define VMALLOC_END 0x0000000200000000UL +#define pte_ERROR(e) __builtin_trap() +#define pmd_ERROR(e) __builtin_trap() +#define pgd_ERROR(e) __builtin_trap() + #endif /* !(__ASSEMBLY__) */ /* SpitFire TTE bits. */ @@ -157,109 +156,30 @@ extern pte_t __bad_page(void); * hit for all __pa()/__va() operations. */ extern unsigned long phys_base; -#define ZERO_PAGE(vaddr) ((unsigned long)__va(phys_base)) - -/* Allocate a block of RAM which is aligned to its size. - * This procedure can be used until the call to mem_init(). - */ -extern void *sparc_init_alloc(unsigned long *kbrk, unsigned long size); - -/* Cache and TLB 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(mm, start, end) \ - flush_cache_mm(mm) -#define flush_cache_page(vma, page) \ - flush_cache_mm((vma)->vm_mm) - -/* These operations are unnecessary on the SpitFire since D-CACHE is write-through. */ -#define flush_icache_range(start, end) do { } while (0) -#define flush_page_to_ram(page) do { } while (0) - -extern void __flush_dcache_range(unsigned long start, unsigned long end); - -extern void __flush_cache_all(void); - -extern void __flush_tlb_all(void); -extern void __flush_tlb_mm(unsigned long context, unsigned long r); -extern void __flush_tlb_range(unsigned long context, unsigned long start, - unsigned long r, unsigned long end, - unsigned long pgsz, unsigned long size); -extern void __flush_tlb_page(unsigned long context, unsigned long page, unsigned long r); - -#ifndef __SMP__ - -#define flush_cache_all() __flush_cache_all() -#define flush_tlb_all() __flush_tlb_all() - -#define flush_tlb_mm(__mm) \ -do { if(CTX_VALID((__mm)->context)) \ - __flush_tlb_mm(CTX_HWBITS((__mm)->context), SECONDARY_CONTEXT); \ -} while(0) - -#define flush_tlb_range(__mm, start, end) \ -do { if(CTX_VALID((__mm)->context)) { \ - unsigned long __start = (start)&PAGE_MASK; \ - unsigned long __end = (end)&PAGE_MASK; \ - __flush_tlb_range(CTX_HWBITS((__mm)->context), __start, \ - SECONDARY_CONTEXT, __end, PAGE_SIZE, \ - (__end - __start)); \ - } \ -} while(0) - -#define flush_tlb_page(vma, page) \ -do { struct mm_struct *__mm = (vma)->vm_mm; \ - if(CTX_VALID(__mm->context)) \ - __flush_tlb_page(CTX_HWBITS(__mm->context), (page)&PAGE_MASK, \ - SECONDARY_CONTEXT); \ -} while(0) - -#else /* __SMP__ */ - -extern void smp_flush_cache_all(void); -extern void smp_flush_tlb_all(void); -extern void smp_flush_tlb_mm(struct mm_struct *mm); -extern void smp_flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end); -extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long page); +#define ZERO_PAGE(vaddr) (mem_map + (phys_base>>PAGE_SHIFT)) -#define flush_cache_all() smp_flush_cache_all() -#define flush_tlb_all() smp_flush_tlb_all() +/* Warning: These take pointers to page structs now... */ +#define mk_pte(page, pgprot) \ + __pte(((page - mem_map) << PAGE_SHIFT) | pgprot_val(pgprot)) +#define page_pte_prot(page, prot) mk_pte(page, prot) +#define page_pte(page) page_pte_prot(page, __pgprot(0)) -extern __inline__ void flush_tlb_mm(struct mm_struct *mm) -{ - if (CTX_VALID(mm->context)) - smp_flush_tlb_mm(mm); -} +#define mk_pte_phys(physpage, pgprot) (__pte((physpage) | pgprot_val(pgprot))) -extern __inline__ void flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) +extern inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot) { - if (CTX_VALID(mm->context)) - smp_flush_tlb_range(mm, start, end); -} + pte_t __pte; -extern __inline__ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; + pte_val(__pte) = (pte_val(orig_pte) & _PAGE_CHG_MASK) | + pgprot_val(new_prot); - if (CTX_VALID(mm->context)) - smp_flush_tlb_page(mm, page); + return __pte; } - -#endif - -#define mk_pte(page, pgprot) (__pte(__pa(page) | pgprot_val(pgprot))) -#define mk_pte_phys(physpage, pgprot) (__pte((physpage) | pgprot_val(pgprot))) -#define pte_modify(_pte, newprot) \ - (pte_val(_pte) = ((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))) #define pmd_set(pmdp, ptep) \ (pmd_val(*(pmdp)) = (__pa((unsigned long) (ptep)) >> 11UL)) #define pgd_set(pgdp, pmdp) \ (pgd_val(*(pgdp)) = (__pa((unsigned long) (pmdp)) >> 11UL)) -#define pte_page(pte) ((unsigned long) __va(((pte_val(pte)&~PAGE_OFFSET)&~(0xfffUL)))) +#define pte_pagenr(pte) ((unsigned long) ((pte_val(pte)&~PAGE_OFFSET)>>PAGE_SHIFT)) #define pmd_page(pmd) ((unsigned long) __va((pmd_val(pmd)<<11UL))) #define pgd_page(pgd) ((unsigned long) __va((pgd_val(pgd)<<11UL))) #define pte_none(pte) (!pte_val(pte)) @@ -286,6 +206,12 @@ extern __inline__ void flush_tlb_page(struct vm_area_struct *vma, unsigned long #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)->virtual) +#define page_address(page) ({ __page_address(page); }) + +#define pte_page(x) (mem_map+pte_pagenr(x)) + /* Be very careful when you change these three, they are delicate. */ static __inline__ pte_t pte_mkyoung(pte_t _pte) { if(pte_val(_pte) & _PAGE_READ) @@ -322,226 +248,7 @@ static __inline__ pte_t pte_mkdirty(pte_t _pte) #define pte_offset(dir, address) ((pte_t *) pmd_page(*(dir)) + \ ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) -/* Very stupidly, we used to get new pgd's and pmd's, init their contents - * to point to the NULL versions of the next level page table, later on - * completely re-init them the same way, then free them up. This wasted - * a lot of work and caused unnecessary memory traffic. How broken... - * We fix this by caching them. - */ - -#ifdef __SMP__ -/* Sliiiicck */ -#define pgt_quicklists cpu_data[smp_processor_id()] -#else -extern struct pgtable_cache_struct { - unsigned long *pgd_cache; - unsigned long *pte_cache; - unsigned int pgcache_size; - unsigned int pgdcache_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) -#define pgd_cache_size (pgt_quicklists.pgdcache_size) - -#ifndef __SMP__ - -extern __inline__ void free_pgd_fast(pgd_t *pgd) -{ - struct page *page = mem_map + MAP_NR(pgd); - - if (!page->pprev_hash) { - (unsigned long *)page->next_hash = pgd_quicklist; - pgd_quicklist = (unsigned long *)page; - } - (unsigned long)page->pprev_hash |= - (((unsigned long)pgd & (PAGE_SIZE / 2)) ? 2 : 1); - pgd_cache_size++; -} - -extern __inline__ pgd_t *get_pgd_fast(void) -{ - struct page *ret; - - if ((ret = (struct page *)pgd_quicklist) != NULL) { - unsigned long mask = (unsigned long)ret->pprev_hash; - unsigned long off = 0; - - if (mask & 1) - mask &= ~1; - else { - off = PAGE_SIZE / 2; - mask &= ~2; - } - (unsigned long)ret->pprev_hash = mask; - if (!mask) - pgd_quicklist = (unsigned long *)ret->next_hash; - ret = (struct page *)(page_address(ret) + off); - pgd_cache_size--; - } else { - ret = (struct page *) __get_free_page(GFP_KERNEL); - if(ret) { - struct page *page = mem_map + MAP_NR(ret); - - memset(ret, 0, PAGE_SIZE); - (unsigned long)page->pprev_hash = 2; - (unsigned long *)page->next_hash = pgd_quicklist; - pgd_quicklist = (unsigned long *)page; - pgd_cache_size++; - } - } - return (pgd_t *)ret; -} - -#else /* __SMP__ */ - -extern __inline__ void free_pgd_fast(pgd_t *pgd) -{ - *(unsigned long *)pgd = (unsigned long) pgd_quicklist; - pgd_quicklist = (unsigned long *) pgd; - pgtable_cache_size++; -} - -extern __inline__ pgd_t *get_pgd_fast(void) -{ - unsigned long *ret; - - if((ret = pgd_quicklist) != NULL) { - pgd_quicklist = (unsigned long *)(*ret); - ret[0] = 0; - pgtable_cache_size--; - } else { - ret = (unsigned long *) __get_free_page(GFP_KERNEL); - if(ret) - memset(ret, 0, PAGE_SIZE); - } - return (pgd_t *)ret; -} - -extern __inline__ void free_pgd_slow(pgd_t *pgd) -{ - free_page((unsigned long)pgd); -} - -#endif /* __SMP__ */ - -extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long address_premasked); - -extern __inline__ pmd_t *get_pmd_fast(void) -{ - unsigned long *ret; - - if((ret = (unsigned long *)pte_quicklist) != NULL) { - pte_quicklist = (unsigned long *)(*ret); - ret[0] = 0; - pgtable_cache_size--; - } - return (pmd_t *)ret; -} - -extern __inline__ void free_pmd_fast(pgd_t *pmd) -{ - *(unsigned long *)pmd = (unsigned long) pte_quicklist; - pte_quicklist = (unsigned long *) pmd; - pgtable_cache_size++; -} - -extern __inline__ void free_pmd_slow(pmd_t *pmd) -{ - free_page((unsigned long)pmd); -} - -extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted); - -extern __inline__ pte_t *get_pte_fast(void) -{ - unsigned long *ret; - - if((ret = (unsigned long *)pte_quicklist) != NULL) { - pte_quicklist = (unsigned long *)(*ret); - ret[0] = 0; - pgtable_cache_size--; - } - return (pte_t *)ret; -} - -extern __inline__ void free_pte_fast(pte_t *pte) -{ - *(unsigned long *)pte = (unsigned long) pte_quicklist; - pte_quicklist = (unsigned long *) pte; - pgtable_cache_size++; -} - -extern __inline__ void free_pte_slow(pte_t *pte) -{ - free_page((unsigned long)pte); -} - -#define pte_free_kernel(pte) free_pte_fast(pte) -#define pte_free(pte) free_pte_fast(pte) -#define pmd_free_kernel(pmd) free_pmd_fast(pmd) -#define pmd_free(pmd) free_pmd_fast(pmd) -#define pgd_free(pgd) free_pgd_fast(pgd) -#define pgd_alloc() get_pgd_fast() - -extern inline pte_t * pte_alloc(pmd_t *pmd, unsigned long address) -{ - address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); - if (pmd_none(*pmd)) { - pte_t *page = get_pte_fast(); - - if (!page) - return get_pte_slow(pmd, address); - pmd_set(pmd, page); - return page + address; - } - return (pte_t *) pmd_page(*pmd) + address; -} - -extern inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address) -{ - address = (address >> PMD_SHIFT) & (REAL_PTRS_PER_PMD - 1); - if (pgd_none(*pgd)) { - pmd_t *page = get_pmd_fast(); - - if (!page) - return get_pmd_slow(pgd, address); - pgd_set(pgd, page); - return page + address; - } - return (pmd_t *) pgd_page(*pgd) + address; -} - -#define pte_alloc_kernel(pmd, addr) pte_alloc(pmd, addr) -#define pmd_alloc_kernel(pgd, addr) pmd_alloc(pgd, addr) - -extern int do_check_pgt_cache(int, int); - -/* Nothing to do on sparc64 :) */ -#define set_pgdir(address, entry) do { } while(0) - extern pgd_t swapper_pg_dir[1]; -/* Routines for getting a dvma scsi buffer. */ -struct mmu_sglist { - char *addr; - char *__dont_touch; - unsigned int len; - __u32 dvma_addr; - __u32 dvma_len; -}; - -extern __u32 mmu_get_scsi_one(char *, unsigned long, struct linux_sbus *sbus); -extern void mmu_get_scsi_sgl(struct mmu_sglist *, int, struct linux_sbus *sbus); - -extern void mmu_release_scsi_one(u32 vaddr, unsigned long len, - struct linux_sbus *sbus); -extern void mmu_release_scsi_sgl(struct mmu_sglist *sg, int sz, struct linux_sbus *sbus); - -#define NEED_DMA_SYNCHRONIZATION -#define mmu_sync_dma(dma_addr, len, sbus_instance) \ - mmu_release_scsi_one((dma_addr), (len), (sbus_instance)) /* These do nothing with the way I have things setup. */ #define mmu_lockarea(vaddr, len) (vaddr) @@ -579,14 +286,11 @@ do { \ if ((__flags & VM_EXEC) != 0 && \ ((pte_val(_pte) & (_PAGE_PRESENT | _PAGE_WRITE | _PAGE_MODIFIED)) == \ (_PAGE_PRESENT | _PAGE_WRITE | _PAGE_MODIFIED))) { \ - flush_icache_page(pte_page(_pte) - page_offset); \ + flush_icache_page(pte_pagenr(_pte) << PAGE_SHIFT); \ } \ } while(0) /* Make a non-present pseudo-TTE. */ -extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) -{ pte_t pte; pte_val(pte) = (type<<PAGE_SHIFT)|(offset<<(PAGE_SHIFT+8)); return pte; } - extern inline pte_t mk_pte_io(unsigned long page, pgprot_t prot, int space) { pte_t pte; @@ -595,9 +299,16 @@ extern inline pte_t mk_pte_io(unsigned long page, pgprot_t prot, int space) return pte; } -#define SWP_TYPE(entry) (((entry>>PAGE_SHIFT) & 0xff)) -#define SWP_OFFSET(entry) ((entry) >> (PAGE_SHIFT+8)) -#define SWP_ENTRY(type,offset) pte_val(mk_swap_pte((type),(offset))) +/* Encode and de-code a swap entry */ +#define SWP_TYPE(entry) (((entry).val >> PAGE_SHIFT) & 0xff) +#define SWP_OFFSET(entry) ((entry).val >> (PAGE_SHIFT + 8)) +#define SWP_ENTRY(type, offset) \ + ( (swp_entry_t) \ + { \ + ((type << PAGE_SHIFT) | (offset << (PAGE_SHIFT + 8))) \ + } ) +#define pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define swp_entry_to_pte(x) ((pte_t) { (x).val }) extern __inline__ unsigned long sun4u_get_pte (unsigned long addr) @@ -631,8 +342,8 @@ extern void module_unmap (void *addr); extern unsigned long *sparc64_valid_addr_bitmap; /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ -#define PageSkip(page) (test_bit(PG_skip, &(page)->flags)) -#define kern_addr_valid(addr) (test_bit(__pa((unsigned long)(addr))>>22, sparc64_valid_addr_bitmap)) +#define kern_addr_valid(addr) \ + (test_bit(__pa((unsigned long)(addr))>>22, sparc64_valid_addr_bitmap)) extern int io_remap_page_range(unsigned long from, unsigned long offset, unsigned long size, pgprot_t prot, int space); diff --git a/include/asm-sparc64/poll.h b/include/asm-sparc64/poll.h index 9fbd1b44d..9ee63f39c 100644 --- a/include/asm-sparc64/poll.h +++ b/include/asm-sparc64/poll.h @@ -11,6 +11,7 @@ #define POLLWRNORM POLLOUT #define POLLRDBAND 128 #define POLLWRBAND 256 +#define POLLMSG 512 struct pollfd { int fd; diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h index 35c54dd1a..807dd0cf4 100644 --- a/include/asm-sparc64/processor.h +++ b/include/asm-sparc64/processor.h @@ -1,4 +1,4 @@ -/* $Id: processor.h,v 1.57 1999/08/04 03:20:05 davem Exp $ +/* $Id: processor.h,v 1.60 2000/01/07 20:21:45 davem Exp $ * include/asm-sparc64/processor.h * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -109,10 +109,20 @@ struct thread_struct { /* Return saved PC of a blocked thread. */ extern __inline__ unsigned long thread_saved_pc(struct thread_struct *t) { - unsigned long *sp = (unsigned long *)(t->ksp + STACK_BIAS); - unsigned long *fp = (unsigned long *)(sp[14] + STACK_BIAS); - - return fp[15]; + unsigned long ret = 0xdeadbeefUL; + + if (t->ksp) { + unsigned long *sp; + sp = (unsigned long *)(t->ksp + STACK_BIAS); + if (((unsigned long)sp & (sizeof(long) - 1)) == 0UL && + sp[14]) { + unsigned long *fp; + fp = (unsigned long *)(sp[14] + STACK_BIAS); + if (((unsigned long)fp & (sizeof(long) - 1)) == 0UL) + ret = fp[15]; + } + } + return ret; } /* On Uniprocessor, even in RMO processes see TSO semantics */ @@ -209,7 +219,35 @@ extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); #define release_segments(mm) do { } while (0) #define forget_segments() do { } while (0) -unsigned long get_wchan(struct task_struct *p); +#define get_wchan(__TSK) \ +({ extern void scheduling_functions_start_here(void); \ + extern void scheduling_functions_end_here(void); \ + unsigned long pc, fp, bias = 0; \ + unsigned long task_base = (unsigned long) (__TSK); \ + struct reg_window *rw; \ + unsigned long __ret = 0; \ + int count = 0; \ + if (!(__TSK) || (__TSK) == current || \ + (__TSK)->state == TASK_RUNNING) \ + goto __out; \ + bias = STACK_BIAS; \ + fp = (__TSK)->thread.ksp + bias; \ + do { \ + /* Bogus frame pointer? */ \ + if (fp < (task_base + sizeof(struct task_struct)) || \ + fp >= (task_base + (2 * PAGE_SIZE))) \ + break; \ + rw = (struct reg_window *) fp; \ + pc = rw->ins[7]; \ + if (pc < ((unsigned long) scheduling_functions_start_here) || \ + pc >= ((unsigned long) scheduling_functions_end_here)) { \ + __ret = pc; \ + goto __out; \ + } \ + fp = rw->ins[6] + bias; \ + } while (++count < 16); \ +__out: __ret; \ +}) #define KSTK_EIP(tsk) ((tsk)->thread.kregs->tpc) #define KSTK_ESP(tsk) ((tsk)->thread.kregs->u_regs[UREG_FP]) @@ -219,6 +257,7 @@ unsigned long get_wchan(struct task_struct *p); /* Allocation and freeing of task_struct and kernel stack. */ #define alloc_task_struct() ((struct task_struct *)__get_free_pages(GFP_KERNEL, 1)) #define free_task_struct(tsk) free_pages((unsigned long)(tsk),1) +#define get_task_struct(tsk) atomic_inc(&mem_map[MAP_NR(tsk)].count) #define init_task (init_task_union.task) #define init_stack (init_task_union.stack) diff --git a/include/asm-sparc64/resource.h b/include/asm-sparc64/resource.h index 0bd968298..1d2b5eff0 100644 --- a/include/asm-sparc64/resource.h +++ b/include/asm-sparc64/resource.h @@ -1,4 +1,4 @@ -/* $Id: resource.h,v 1.5 1999/07/30 09:31:21 davem Exp $ +/* $Id: resource.h,v 1.7 1999/12/15 17:52:08 jj Exp $ * resource.h: Resource definitions. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -31,13 +31,17 @@ #define RLIM_INFINITY (~0UL) #ifdef __KERNEL__ -#define INIT_RLIMITS \ -{ \ - {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX}, \ - {LONG_MAX, LONG_MAX}, {_STK_LIM, LONG_MAX}, \ - { 0, LONG_MAX}, {LONG_MAX, LONG_MAX}, \ - {INR_OPEN, INR_OPEN}, {0, 0}, \ - {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX} \ +#define INIT_RLIMITS \ +{ \ + {RLIM_INFINITY, RLIM_INFINITY}, \ + {RLIM_INFINITY, RLIM_INFINITY}, \ + {RLIM_INFINITY, RLIM_INFINITY}, \ + {_STK_LIM, RLIM_INFINITY}, \ + { 0, RLIM_INFINITY}, \ + {RLIM_INFINITY, RLIM_INFINITY}, \ + {INR_OPEN, INR_OPEN}, {0, 0}, \ + {RLIM_INFINITY, RLIM_INFINITY}, \ + {RLIM_INFINITY, RLIM_INFINITY} \ } #endif /* __KERNEL__ */ diff --git a/include/asm-sparc64/sbus.h b/include/asm-sparc64/sbus.h index f3169c8ce..1718e234f 100644 --- a/include/asm-sparc64/sbus.h +++ b/include/asm-sparc64/sbus.h @@ -1,16 +1,17 @@ -/* $Id: sbus.h,v 1.10 1998/12/16 04:33:58 davem Exp $ - * sbus.h: Defines for the Sun SBus. +/* $Id: sbus.h,v 1.12 1999/12/20 14:08:25 jj Exp $ + * sbus.h: Defines for the Sun SBus. * - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com) */ -/* XXX This needs to be mostly redone for sun5 SYSIO. */ - #ifndef _SPARC64_SBUS_H #define _SPARC64_SBUS_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 @@ -36,73 +37,75 @@ extern __inline__ int sbus_dev_slot(unsigned long dev_addr) return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>28); } -extern __inline__ unsigned long sbus_dev_offset(unsigned long dev_addr) -{ - return (unsigned long) (((dev_addr)-SUN_SBUS_BVADDR)&SBUS_OFF_MASK); -} - -struct linux_sbus; +struct sbus_bus; /* Linux SBUS device tables */ -struct linux_sbus_device { - struct linux_sbus_device *next; /* next device on this SBus or null */ - struct linux_sbus_device *child; /* For ledma and espdma on sun4m */ - struct linux_sbus *my_bus; /* Back ptr to sbus */ - int prom_node; /* PROM device tree node for this device */ - char prom_name[32]; /* PROM device name */ - - struct linux_prom_registers reg_addrs[PROMREG_MAX]; - int num_registers, ranges_applied; - - unsigned int irqs[4]; - int num_irqs; - - unsigned long sbus_addr; /* Absolute base address for device. */ - unsigned long sbus_vaddrs[PROMVADDR_MAX]; - unsigned long num_vaddrs; - unsigned long offset; /* Offset given by PROM */ - int slot; +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 linux_sbus { - struct linux_sbus *next; /* next SBus, if more than one SBus */ - struct linux_sbus_device *devices; /* Link to devices on this SBus */ - struct iommu_struct *iommu; /* IOMMU for this sbus if applicable */ - int prom_node; /* PROM device tree node for this SBus */ - char prom_name[64]; /* Usually "sbus" or "sbi" */ - int clock_freq; +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 upaid; + + int portid; void *starfire_cookie; }; -extern struct linux_sbus *SBus_chain; +extern struct sbus_bus *sbus_root; /* Device probing routines could find these handy */ #define for_each_sbus(bus) \ - for((bus) = SBus_chain; (bus); (bus)=(bus)->next) + 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_chain, ((device) = (bus) ? (bus)->devices : 0); (bus); (device)=((device)->next ? (device)->next : ((bus) = (bus)->next, (bus) ? (bus)->devices : 0))) - -extern void mmu_set_sbus64(struct linux_sbus_device *, int); - -/* If you did not get the buffer from mmu_get_*() or sparc_alloc_dvma() - * then you must use this to get the 32-bit SBUS dvma address. - * And in this case it is your responsibility to make sure the buffer - * is GFP_DMA, ie. that it is not greater than MAX_DMA_ADDRESS. - */ -extern unsigned long phys_base; -#define sbus_dvma_addr(__addr) ((__u32)(__pa(__addr) - phys_base)) - -/* Apply promlib probed SBUS ranges to registers. */ -extern void prom_apply_sbus_ranges(struct linux_sbus *sbus, - struct linux_prom_registers *sbusregs, int nregs, - struct linux_sbus_device *sdev); + for((bus) = sbus_root, ((device) = (bus) ? (bus)->devices : 0); (bus); (device)=((device)->next ? (device)->next : ((bus) = (bus)->next, (bus) ? (bus)->devices : 0))) + +/* 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 consistant mode. */ +extern void *sbus_alloc_consistant(struct sbus_dev *, long, u32 *dma_addrp); +extern void sbus_free_consistant(struct sbus_dev *, long, void *, u32); + +/* All the rest use streaming mode mappings. */ +extern u32 sbus_map_single(struct sbus_dev *, void *, long); +extern void sbus_unmap_single(struct sbus_dev *, u32, long); +extern int sbus_map_sg(struct sbus_dev *, struct scatterlist *, int); +extern void sbus_unmap_sg(struct sbus_dev *, struct scatterlist *, int); + +/* Finally, allow explicit synchronization of streamable mappings. */ +extern void sbus_dma_sync_single(struct sbus_dev *, u32, long); +extern void sbus_dma_sync_sg(struct sbus_dev *, struct scatterlist *, int); #endif /* !(_SPARC64_SBUS_H) */ diff --git a/include/asm-sparc64/scatterlist.h b/include/asm-sparc64/scatterlist.h index d64162a5a..27ebd548b 100644 --- a/include/asm-sparc64/scatterlist.h +++ b/include/asm-sparc64/scatterlist.h @@ -1,4 +1,4 @@ -/* $Id: scatterlist.h,v 1.7 1999/08/30 10:15:01 davem Exp $ */ +/* $Id: scatterlist.h,v 1.9 1999/12/17 12:32:15 jj Exp $ */ #ifndef _SPARC64_SCATTERLIST_H #define _SPARC64_SCATTERLIST_H @@ -14,7 +14,9 @@ struct scatterlist { __u32 dvma_length; }; -extern unsigned long phys_base; -#define ISA_DMA_THRESHOLD (phys_base + (0xfe000000UL) + PAGE_OFFSET) +#define sg_dma_address(sg) ((sg)->dvma_address) +#define sg_dma_len(sg) ((sg)->dvma_length) + +#define ISA_DMA_THRESHOLD (~0UL) #endif /* !(_SPARC64_SCATTERLIST_H) */ diff --git a/include/asm-sparc64/semaphore.h b/include/asm-sparc64/semaphore.h index e119514c4..046385d3c 100644 --- a/include/asm-sparc64/semaphore.h +++ b/include/asm-sparc64/semaphore.h @@ -5,6 +5,7 @@ #ifdef __KERNEL__ #include <asm/atomic.h> +#include <asm/bitops.h> #include <asm/system.h> struct semaphore { @@ -66,7 +67,7 @@ extern __inline__ void down(struct semaphore * sem) #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - __asm__ __volatile__(" + __asm__ __volatile__(" 1: lduw [%0], %%g5 sub %%g5, 1, %%g7 cas [%0], %%g5, %%g7 @@ -100,7 +101,7 @@ extern __inline__ int down_interruptible(struct semaphore *sem) #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - __asm__ __volatile__(" + __asm__ __volatile__(" 1: lduw [%2], %%g5 sub %%g5, 1, %%g7 cas [%2], %%g5, %%g7 @@ -136,7 +137,7 @@ extern inline int down_trylock(struct semaphore *sem) #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - __asm__ __volatile__(" + __asm__ __volatile__(" 1: lduw [%2], %%g5 sub %%g5, 1, %%g7 cas [%2], %%g5, %%g7 @@ -197,7 +198,262 @@ extern __inline__ void up(struct semaphore * sem) .previous\n" : : "r" (__atomic_fool_gcc(sem)), "i" (__up) : "g5", "g7", "memory", "cc"); -} +} + +/* rw mutexes (should that be mutices? =) -- throw rw + * spinlocks and semaphores together, and this is what we + * end up with... + * + * The lock is initialized to BIAS. This way, a writer + * subtracts BIAS ands gets 0 for the case of an uncontended + * lock. Readers decrement by 1 and see a positive value + * when uncontended, negative if there are writers waiting + * (in which case it goes to sleep). + * + * The value 0x01000000 supports up to 128 processors and + * lots of processes. BIAS must be chosen such that subtracting + * BIAS once per CPU will result in the int remaining + * negative. + * In terms of fairness, this should result in the lock + * flopping back and forth between readers and writers + * under heavy use. + * + * -ben + * + * Once we start supporting machines with more than 128 CPUs, + * we should go for using a 64bit atomic type instead of 32bit + * as counter. We shall probably go for bias 0x80000000 then, + * so that single sethi can set it. + * + * -jj + */ +#define RW_LOCK_BIAS 0x01000000 +#define RW_LOCK_BIAS_STR "0x01000000" + +struct rw_semaphore { + int count; + /* So that this does not have to be 64bit type, + * we'll use le bitops on it which use casa instead of casx. + * bit 0 means read bias granted + * bit 1 means write bias granted + */ + unsigned granted; + wait_queue_head_t wait; + wait_queue_head_t write_bias_wait; +#if WAITQUEUE_DEBUG + long __magic; + atomic_t readers; + atomic_t writers; +#endif +}; + +#if WAITQUEUE_DEBUG +#define __RWSEM_DEBUG_INIT , ATOMIC_INIT(0), ATOMIC_INIT(0) +#else +#define __RWSEM_DEBUG_INIT /* */ +#endif + +#define __RWSEM_INITIALIZER(name) \ +{ RW_LOCK_BIAS, 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \ + __WAIT_QUEUE_HEAD_INITIALIZER((name).write_bias_wait) \ + __SEM_DEBUG_INIT(name) __RWSEM_DEBUG_INIT } + +extern inline void init_rwsem(struct rw_semaphore *sem) +{ + sem->count = RW_LOCK_BIAS; + sem->granted = 0; + init_waitqueue_head(&sem->wait); + init_waitqueue_head(&sem->write_bias_wait); +#if WAITQUEUE_DEBUG + sem->__magic = (long)&sem->__magic; + atomic_set(&sem->readers, 0); + atomic_set(&sem->writers, 0); +#endif +} + +extern void __down_read_failed(/* Special calling convention */ void); +extern void __down_write_failed(/* Special calling convention */ void); +extern void __rwsem_wake(struct rw_semaphore *sem, unsigned long readers); + +extern inline void down_read(struct rw_semaphore *sem) +{ +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + __asm__ __volatile__(" + 1: lduw [%0], %%g5 + subcc %%g5, 1, %%g7 + cas [%0], %%g5, %%g7 + bneg,pn %%icc, 3f + cmp %%g5, %%g7 + bne,pn %%icc, 1b + membar #StoreStore + 2: + .subsection 2 + 3: bne,pn %%icc, 1b + mov %0, %%g7 + save %%sp, -160, %%sp + mov %%g1, %%l1 + mov %%g2, %%l2 + call %1 + mov %%g3, %%l3 + mov %%l1, %%g1 + mov %%l2, %%g2 + ba,pt %%xcc, 2b + restore %%l3, %%g0, %%g3 + .previous\n" + : : "r" (__atomic_fool_gcc(sem)), "i" (__down_read_failed) + : "g5", "g7", "memory", "cc"); +#if WAITQUEUE_DEBUG + if (test_le_bit(1, &sem->granted)) + BUG(); + if (atomic_read(&sem->writers)) + BUG(); + atomic_inc(&sem->readers); +#endif +} + +extern inline void down_write(struct rw_semaphore *sem) +{ +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + __asm__ __volatile__(" + 1: lduw [%0], %%g5 + sethi %%hi(" RW_LOCK_BIAS_STR "), %%g7 + subcc %%g5, %%g7, %%g7 + cas [%0], %%g5, %%g7 + bne,pn %%icc, 3f + cmp %%g5, %%g7 + bne,pn %%icc, 1b + membar #StoreStore + 2: + .subsection 2 + 3: bne,pn %%icc, 1b + mov %0, %%g7 + save %%sp, -160, %%sp + mov %%g1, %%l1 + mov %%g2, %%l2 + call %1 + mov %%g3, %%l3 + mov %%l1, %%g1 + mov %%l2, %%g2 + ba,pt %%xcc, 2b + restore %%l3, %%g0, %%g3 + .previous\n" + : : "r" (__atomic_fool_gcc(sem)), "i" (__down_write_failed) + : "g5", "g7", "memory", "cc"); +#if WAITQUEUE_DEBUG + if (atomic_read(&sem->writers)) + BUG(); + if (atomic_read(&sem->readers)) + BUG(); + if (test_le_bit(0, &sem->granted)) + BUG(); + if (test_le_bit(1, &sem->granted)) + BUG(); + atomic_inc(&sem->writers); +#endif +} + +/* When a reader does a release, the only significant + * case is when there was a writer waiting, and we've + * bumped the count to 0: we must wake the writer up. + */ +extern inline void __up_read(struct rw_semaphore *sem) +{ + __asm__ __volatile__(" + membar #StoreLoad | #LoadLoad + 1: lduw [%0], %%g5 + addcc %%g5, 1, %%g7 + cas [%0], %%g5, %%g7 + be,pn %%icc, 3f + cmp %%g5, %%g7 + bne,pn %%icc, 1b + nop + 2: + .subsection 2 + 3: bne,pn %%icc, 1b + mov %0, %%g7 + save %%sp, -160, %%sp + mov %%g1, %%l1 + mov %%g2, %%l2 + clr %%o1 + mov %%g7, %%o0 + call %1 + mov %%g3, %%l3 + mov %%l1, %%g1 + mov %%l2, %%g2 + ba,pt %%xcc, 2b + restore %%l3, %%g0, %%g3 + .previous\n" + : : "r" (__atomic_fool_gcc(sem)), "i" (__rwsem_wake) + : "g5", "g7", "memory", "cc"); +} + +/* releasing the writer is easy -- just release it and + * wake up any sleepers. + */ +extern inline void __up_write(struct rw_semaphore *sem) +{ + __asm__ __volatile__(" + membar #StoreLoad | #LoadLoad + 1: lduw [%0], %%g5 + sethi %%hi(" RW_LOCK_BIAS_STR "), %%g7 + add %%g5, %%g7, %%g7 + cas [%0], %%g5, %%g7 + cmp %%g5, %%g7 + bne,pn %%icc, 1b + sethi %%hi(" RW_LOCK_BIAS_STR "), %%g7 + addcc %%g5, %%g7, %%g5 + bcs,pn %%icc, 3f + nop + 2: + .subsection 2 + 3: mov %0, %%g7 + save %%sp, -160, %%sp + mov %%g1, %%l1 + mov %%g2, %%l2 + srl %%g5, 0, %%o1 + mov %%g7, %%o0 + call %1 + mov %%g3, %%l3 + mov %%l1, %%g1 + mov %%l2, %%g2 + ba,pt %%xcc, 2b + restore %%l3, %%g0, %%g3 + .previous\n" + : : "r" (__atomic_fool_gcc(sem)), "i" (__rwsem_wake) + : "g5", "g7", "memory", "cc"); +} + +extern inline void up_read(struct rw_semaphore *sem) +{ +#if WAITQUEUE_DEBUG + if (test_le_bit(1, &sem->granted)) + BUG(); + if (atomic_read(&sem->writers)) + BUG(); + atomic_dec(&sem->readers); +#endif + __up_read(sem); +} + +extern inline void up_write(struct rw_semaphore *sem) +{ +#if WAITQUEUE_DEBUG + if (test_le_bit(0, &sem->granted)) + BUG(); + if (test_le_bit(1, &sem->granted)) + BUG(); + if (atomic_read(&sem->readers)) + BUG(); + if (atomic_read(&sem->writers) != 1) + BUG(); + atomic_dec(&sem->writers); +#endif + __up_write(sem); +} #endif /* __KERNEL__ */ diff --git a/include/asm-sparc64/sfp-machine.h b/include/asm-sparc64/sfp-machine.h index edb309873..49c77bd81 100644 --- a/include/asm-sparc64/sfp-machine.h +++ b/include/asm-sparc64/sfp-machine.h @@ -37,7 +37,7 @@ _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(D,R,X,Y) +#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) diff --git a/include/asm-sparc64/shmparam.h b/include/asm-sparc64/shmparam.h index e39a5752c..03ace40fd 100644 --- a/include/asm-sparc64/shmparam.h +++ b/include/asm-sparc64/shmparam.h @@ -1,4 +1,4 @@ -/* $Id: shmparam.h,v 1.3 1998/09/28 07:15:03 jj Exp $ */ +/* $Id: shmparam.h,v 1.4 1999/12/09 10:32:44 davem Exp $ */ #ifndef _ASMSPARC64_SHMPARAM_H #define _ASMSPARC64_SHMPARAM_H diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h index d20d9f1b4..7cd66aa56 100644 --- a/include/asm-sparc64/smp.h +++ b/include/asm-sparc64/smp.h @@ -33,19 +33,19 @@ extern struct prom_cpuinfo linux_cpus[64]; /* Keep this a multiple of 64-bytes for cache reasons. */ struct cpuinfo_sparc { /* Dcache line 1 */ - unsigned long irq_count; - unsigned long bh_count; + unsigned int irq_count; + unsigned int bh_count; unsigned int multiplier; unsigned int counter; + unsigned int idle_volume; + unsigned int __pad; unsigned long udelay_val; /* Dcache line 2 */ unsigned int pgcache_size; unsigned int pgdcache_size; - unsigned long *pte_cache; + unsigned long *pte_cache[2]; unsigned long *pgd_cache; - unsigned int idle_volume; - unsigned int __pad; /* Dcache lines 3 and 4 */ unsigned int irq_worklists[16]; diff --git a/include/asm-sparc64/stat.h b/include/asm-sparc64/stat.h index f726bd5a0..0fd68589b 100644 --- a/include/asm-sparc64/stat.h +++ b/include/asm-sparc64/stat.h @@ -1,4 +1,4 @@ -/* $Id: stat.h,v 1.5 1998/07/26 05:24:41 davem Exp $ */ +/* $Id: stat.h,v 1.6 1999/12/21 14:09:48 jj Exp $ */ #ifndef _SPARC64_STAT_H #define _SPARC64_STAT_H @@ -42,4 +42,45 @@ struct stat { unsigned long __unused4[2]; }; +#ifdef __KERNEL__ +/* This is sparc32 stat64 structure. */ + +struct stat64 { + unsigned char __pad0[6]; + unsigned short st_dev; + unsigned char __pad1[4]; + + unsigned int st_ino; + unsigned int st_mode; + unsigned int st_nlink; + + unsigned int st_uid; + unsigned int st_gid; + + unsigned char __pad2[6]; + unsigned short 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 __unused1; + + unsigned int st_mtime; + unsigned int __unused2; + + unsigned int st_ctime; + unsigned int __unused3; + + unsigned int __unused4; + unsigned int __unused5; +}; + +#endif + #endif diff --git a/include/asm-sparc64/string.h b/include/asm-sparc64/string.h index c1a67071f..f6b69aa53 100644 --- a/include/asm-sparc64/string.h +++ b/include/asm-sparc64/string.h @@ -1,9 +1,9 @@ -/* $Id: string.h,v 1.14 1998/10/20 03:09:18 jj Exp $ +/* $Id: string.h,v 1.15 1999/12/23 17:02:20 jj 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 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * Copyright (C) 1996,1997,1999 Jakub Jelinek (jakub@redhat.com) */ #ifndef __SPARC64_STRING_H__ @@ -21,7 +21,9 @@ extern __kernel_size_t __memcpy_short(void *,const void *,__kernel_size_t,long,l extern __kernel_size_t __memcpy_entry(void *,const void *,__kernel_size_t,long,long); extern __kernel_size_t __memcpy_16plus(void *,const void *,__kernel_size_t,long,long); extern __kernel_size_t __memcpy_384plus(void *,const void *,__kernel_size_t,long,long); -extern __kernel_size_t __memset(void *,int,__kernel_size_t); +extern void *__memset(void *,int,__kernel_size_t); +extern void *__builtin_memcpy(void *,const void *,__kernel_size_t); +extern void *__builtin_memset(void *,int,__kernel_size_t); #ifndef EXPORT_SYMTAB_STROPS @@ -65,28 +67,24 @@ extern inline void *__nonconstant_memcpy(void *to, const void *from, __kernel_si #define __HAVE_ARCH_MEMSET -extern inline void *__constant_memset(void *s, char c, __kernel_size_t count) +extern inline void *__constant_memset(void *s, int c, __kernel_size_t count) { extern __kernel_size_t __bzero(void *, __kernel_size_t); - if(!c) + if(!c) { __bzero(s, count); - else - __memset(s, c, count); - return s; -} - -extern inline void *__nonconstant_memset(void *s, char c, __kernel_size_t count) -{ - __memset(s, c, count); - return s; + return s; + } else + return __memset(s, c, count); } #undef memset #define memset(s, c, count) \ -(__builtin_constant_p(c) ? \ - __constant_memset((s), (c), (count)) : \ - __nonconstant_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 diff --git a/include/asm-sparc64/sysio.h b/include/asm-sparc64/sysio.h deleted file mode 100644 index 5ee5875f2..000000000 --- a/include/asm-sparc64/sysio.h +++ /dev/null @@ -1,441 +0,0 @@ -/* $Id: sysio.h,v 1.9 1999/08/30 10:15:03 davem Exp $ - * sysio.h: UltraSparc sun5 specific SBUS definitions. - * - * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) - */ - -#ifndef __SPARC64_SYSIO_H -#define __SPARC64_SYSIO_H - -#include <linux/types.h> - -/* SUN5 SYSIO Register Set, one per controller probed. */ -struct sysio_regs { -/*0x0000*/ volatile u64 upa_id; /* SYSIO UPA Port ID Register */ -/*0x0008*/ volatile u64 upa_cfg; /* SYSIO UPA Config Register */ -/*0x0010*/ volatile u64 control; /* SYSIO Control Register */ -/*0x0018*/ volatile u64 _unused1; -/*0x0020*/ volatile u64 ecc_control; /* ECC Control Register */ -/*0x0028*/ volatile u64 _unused2; - - /* Uncorrectable Error Fault Registers */ -/*0x0030*/ volatile u64 ue_afsr; /* UE Async Fault Status */ -/*0x0038*/ volatile u64 ue_afar; /* UE Async Fault Address */ - - /* Correctable Error Fault Registers */ -/*0x0040*/ volatile u64 ce_afsr; /* CE Async Fault Status */ -/*0x0048*/ volatile u64 ce_afar; /* CE Async Fault Address */ - - volatile u64 __pad0[0x16]; - - /* Performance Monitoring Registers */ -/*0x0100*/ volatile u64 pmon_control; -/*0x0108*/ volatile u64 pmon_counter; - - volatile u64 __pad1[0x3de]; - - /* SBUS Module Registers */ -/*0x2000*/ volatile u64 sbus_control; /* SBUS Control Register */ -/*0x2008*/ volatile u64 _unused3; -/*0x2010*/ volatile u64 sbus_afsr; /* SBUS Async Fault Status */ -/*0x2018*/ volatile u64 sbus_afar; /* SBUS Async Fault Address */ - - /* SBUS Slot Configuration Registers. - * On Fusion/Electron/Pulsar desktops/servers slots 4-->6 - * are for on-board devices, in particular for Electron/Pulsar - * they are: - * - * slot 4) Audio - * slot 5) MACIO - * slot 6) SLAVIO - * - * On Sunfire/Starfire/Wildfire enterprise boxen these upper slots - * are unused. - */ -/*0x2020*/ volatile u64 sbus_s0cfg; /* SBUS Slot 0 Config */ -/*0x2028*/ volatile u64 sbus_s1cfg; /* SBUS Slot 1 Config */ -/*0x2030*/ volatile u64 sbus_s2cfg; /* SBUS Slot 2 Config */ -/*0x2038*/ volatile u64 sbus_s3cfg; /* SBUS Slot 3 Config */ -/*0x2040*/ volatile u64 sbus_s4cfg; /* SBUS Slot 4 Config */ -/*0x2048*/ volatile u64 sbus_s5cfg; /* SBUS Slot 5 Config */ -/*0x2050*/ volatile u64 sbus_s6cfg; /* SBUS Slot 6 Config */ - - volatile u64 __pad2[0x75]; - - /* SBUS IOMMU lives here */ -/*0x2400*/ volatile u64 iommu_control; /* IOMMU Control */ -/*0x2408*/ volatile u64 iommu_tsbbase; /* IOMMU TSB Base */ -/*0x2410*/ volatile u64 iommu_flush; /* IOMMU Flush Register */ - - volatile u64 __pad3[0x7d]; - - /* SBUS/IOMMU Streaming Buffer Registers */ -/*0x2800*/ volatile u64 sbuf_control; /* StrBuffer Control */ -/*0x2808*/ volatile u64 sbuf_pflush; /* StrBuffer Page Flush */ -/*0x2810*/ volatile u64 sbuf_fsync; /* StrBuffer Flush Synchronization Reg */ - - volatile u64 __pad4[0x7d]; - - /* Interrupt mapping/control registers */ -/*0x2c00*/ volatile u32 _uim0, imap_slot0; /* SBUS Slot 0 Int Mapping */ -/*0x2c08*/ volatile u32 _uim1, imap_slot1; /* SBUS Slot 1 Int Mapping */ -/*0x2c10*/ volatile u32 _uim2, imap_slot2; /* SBUS Slot 2 Int Mapping */ -/*0x2c18*/ volatile u32 _uim3, imap_slot3; /* SBUS Slot 3 Int Mapping */ - - /* Interrupt Retry Timer. */ -/*0x2c20*/ volatile u32 _irpad, irq_retry; - - volatile u64 __pad5[0x7b]; - - /* The following are only used on Fusion/Electron/Pulsar - * desktop systems, they mean nothing on Sunfire/Starfire/Wildfire - */ -/*0x3000*/ volatile u32 _uis, imap_scsi; /* SCSI Int Mapping */ -/*0x3008*/ volatile u32 _uie, imap_eth; /* Ethernet Int Mapping */ -/*0x3010*/ volatile u32 _uip, imap_bpp; /* Parallel Port Int Mapping */ -/*0x3018*/ volatile u32 _uia, imap_audio; /* Audio Int Mapping */ -/*0x3020*/ volatile u32 _uipf, imap_pfail; /* Power Fail Int Mapping */ -/*0x3028*/ volatile u32 _uik, imap_kms; /* Kbd/Ms/Serial Int Mapping */ -/*0x3030*/ volatile u32 _uif, imap_flpy; /* Floppy Int Mapping */ -/*0x3038*/ volatile u32 _uishw, imap_shw; /* Spare HW Int Mapping */ -/*0x3040*/ volatile u32 _uikbd, imap_kbd; /* Kbd Only Int Mapping */ -/*0x3048*/ volatile u32 _uims, imap_ms; /* Mouse Only Int Mapping */ -/*0x3050*/ volatile u32 _uiser, imap_ser; /* Serial Only Int Mapping */ -/*0x3058*/ volatile u64 _imap_unused; -/*0x3060*/ volatile u32 _uit0, imap_tim0; /* Timer 0 Int Mapping */ -/*0x3068*/ volatile u32 _uit1, imap_tim1; /* Timer 1 Int Mapping */ -/*0x3070*/ volatile u32 _uiue, imap_ue; /* UE Int Mapping */ -/*0x3078*/ volatile u32 _uice, imap_ce; /* CE Int Mapping */ -/*0x3080*/ volatile u32 _uisbe, imap_sberr; /* SBUS Err Int Mapping */ -/*0x3088*/ volatile u32 _uipm, imap_pmgmt; /* Power Mgmt Int Mapping */ -/*0x3090*/ volatile u32 _uigfx, imap_gfx; /* OB Graphics Int Mapping */ -/*0x3098*/ volatile u32 _uieupa, imap_eupa; /* UPA Expansion Int Mapping */ - - volatile u64 __pad6[0x6c]; - - /* Interrupt Clear Registers */ -/*0x3400*/ volatile u32 __ucu0, iclr_unused0; -/*0x3408*/ volatile u32 _ucs0, iclr_slot0; - volatile u64 __pad7[0x7]; -/*0x3448*/ volatile u32 _ucs1, iclr_slot1; - volatile u64 __pad8[0x7]; -/*0x3488*/ volatile u32 _ucs2, iclr_slot2; - volatile u64 __pad9[0x7]; -/*0x34c8*/ volatile u32 _ucs3, iclr_slot3; - volatile u64 __pad10[0x66]; -/*0x3800*/ volatile u32 _ucscsi, iclr_scsi; -/*0x3808*/ volatile u32 _uceth, iclr_eth; -/*0x3810*/ volatile u32 _ucbpp, iclr_bpp; -/*0x3818*/ volatile u32 _ucaudio, iclr_audio; -/*0x3820*/ volatile u32 _ucpfail, iclr_pfail; -/*0x3828*/ volatile u32 _uckms, iclr_kms; -/*0x3830*/ volatile u32 _ucflpy, iclr_flpt; -/*0x3838*/ volatile u32 _ucshw, iclr_shw; -/*0x3840*/ volatile u32 _uckbd, iclr_kbd; -/*0x3848*/ volatile u32 _ucms, iclr_ms; -/*0x3850*/ volatile u32 _ucser, iclr_ser; -/*0x3858*/ volatile u64 iclr_unused1; -/*0x3860*/ volatile u32 _uctim0, iclr_tim0; -/*0x3868*/ volatile u32 _uctim1, iclr_tim1; -/*0x3870*/ volatile u32 _ucue, iclr_ue; -/*0x3878*/ volatile u32 _ucce, iclr_ce; -/*0x3880*/ volatile u32 _ucserr, iclr_serr; -/*0x3888*/ volatile u32 _ucpmgmt, iclr_pmgmt; - - volatile u64 __pad11[0x6e]; - - /* Counters/Timers */ -/*0x3c00*/ volatile u64 tim0_cnt; -/*0x3c08*/ volatile u64 tim0_lim; -/*0x3c10*/ volatile u64 tim1_cnt; -/*0x3c18*/ volatile u64 tim1_lim; - - volatile u64 __pad12[0x7c]; - - /* DMA Scoreboard Diagnostic Registers */ -/*0x4000*/ volatile u64 dscore_reg0; /* DMA Scoreboard Diag Reg 0 */ -/*0x4008*/ volatile u64 dscore_reg1; /* DMA Scoreboard Diag Reg 1 */ - - volatile u64 __pad13[0x7e]; - - /* SBUS IOMMU Diagnostic Registers */ -/*0x4400*/ volatile u64 sbus_vdiag; /* SBUS VADDR Diagnostic Register */ -/*0x4408*/ volatile u64 sbus_tcompare; /* SBUS IOMMU TLB Tag Compare */ - - volatile u64 __pad14[0x1e]; - - /* More IOMMU diagnostic things */ -/*0x4500*/ volatile u64 iommu_lru[16]; /* IOMMU LRU Queue Diagnostic Access */ -/*0x4580*/ volatile u64 iommu_tag[16]; /* IOMMU TLB Tag Diagnostic Access */ -/*0x4600*/ volatile u64 iommu_data[32]; /* IOMMU TLB Data RAM Diag Access */ - - volatile u64 __pad15[0x20]; - - /* Interrupt State Diagnostics */ -/*0x4800*/ volatile u64 sbus_istate; -/*0x4808*/ volatile u64 obio_istate; - - volatile u64 __pad16[0xfe]; - - /* Streaming Buffer Diagnostic Area */ -/*0x5000*/ volatile u64 sbuf_data[128]; /* StrBuffer Data Ram Diagnostic */ -/*0x5400*/ volatile u64 sbuf_errs[128]; /* StrBuffer Error Status Diagnostics */ -/*0x5800*/ volatile u64 sbuf_ptag[16]; /* StrBuffer Page Tag Diagnostics */ -/*0x5880*/ volatile u64 _unusedXXX[16]; -/*0x5900*/ volatile u64 sbuf_ltag[16]; /* StrBuffer Line Tag Diagnostics */ -}; - -/* SYSIO UPA Port ID */ -#define SYSIO_UPPID_FESC 0xff00000000000000 /* FCode escape, 0xfc */ -#define SYSIO_UPPID_RESV1 0x00fffff800000000 /* Reserved */ -#define SYSIO_UPPID_ENV 0x0000000400000000 /* Cannot generate ECC */ -#define SYSIO_UPPID_ORD 0x0000000200000000 /* One Outstanding Read */ -#define SYSIO_UPPID_RESV2 0x0000000180000000 /* Reserved */ -#define SYSIO_UPPID_PDQ 0x000000007e000000 /* Data Queue size */ -#define SYSIO_UPPID_PRQ 0x0000000001e00000 /* Request Queue size */ -#define SYSIO_UPPID_UCAP 0x00000000001f0000 /* UPA Capabilities */ -#define SYSIO_UPPID_JEDEC 0x000000000000ffff /* JEDEC ID for SYSIO */ - -/* SYSIO UPA Configuration Register */ -#define SYSIO_UPCFG_RESV 0xffffffffffffff00 /* Reserved */ -#define SYSIO_UPCFG_SCIQ1 0x00000000000000f0 /* Unused, always zero */ -#define SYSIO_UPCFG_SCIQ2 0x000000000000000f /* Requests Queue size (0x2) */ - -/* SYSIO Control Register */ -#define SYSIO_CONTROL_IMPL 0xf000000000000000 /* Implementation of this SYSIO */ -#define SYSIO_CONTROL_VER 0x0f00000000000000 /* Version of this SYSIO */ -#define SYSIO_CONTROL_MID 0x00f8000000000000 /* UPA Module ID of SYSIO */ -#define SYSIO_CONTROL_IGN 0x0007c00000000000 /* Interrupt Group Number */ -#define SYSIO_CONTROL_RESV 0x00003ffffffffff0 /* Reserved */ -#define SYSIO_CONTROL_APCKEN 0x0000000000000008 /* Address Parity Check Enable */ -#define SYSIO_CONTROL_APERR 0x0000000000000004 /* Incoming System Addr Parerr */ -#define SYSIO_CONTROL_IAP 0x0000000000000002 /* Invert UPA Parity */ -#define SYSIO_CONTROL_MODE 0x0000000000000001 /* SYSIO clock mode */ - -/* SYSIO ECC Control Register */ -#define SYSIO_ECNTRL_ECCEN 0x8000000000000000 /* Enable ECC Checking */ -#define SYSIO_ECNTRL_UEEN 0x4000000000000000 /* Enable UE Interrupts */ -#define SYSIO_ECNTRL_CEEN 0x2000000000000000 /* Enable CE Interrupts */ - -/* Uncorrectable Error AFSR, AFAR holds low 40bits of faulting physical address. */ -#define SYSIO_UEAFSR_PPIO 0x8000000000000000 /* Primary PIO is cause */ -#define SYSIO_UEAFSR_PDRD 0x4000000000000000 /* Primary DVMA read is cause */ -#define SYSIO_UEAFSR_PDWR 0x2000000000000000 /* Primary DVMA write is cause */ -#define SYSIO_UEAFSR_SPIO 0x1000000000000000 /* Secondary PIO is cause */ -#define SYSIO_UEAFSR_SDRD 0x0800000000000000 /* Secondary DVMA read is cause */ -#define SYSIO_UEAFSR_SDWR 0x0400000000000000 /* Secondary DVMA write is cause*/ -#define SYSIO_UEAFSR_RESV1 0x03ff000000000000 /* Reserved */ -#define SYSIO_UEAFSR_DOFF 0x0000e00000000000 /* Doubleword Offset */ -#define SYSIO_UEAFSR_SIZE 0x00001c0000000000 /* Bad transfer size is 2**SIZE */ -#define SYSIO_UEAFSR_MID 0x000003e000000000 /* UPA MID causing the fault */ -#define SYSIO_UEAFSR_RESV2 0x0000001fffffffff /* Reserved */ - -/* Correctable Error AFSR, AFAR holds low 40bits of faulting physical address. */ -#define SYSIO_CEAFSR_PPIO 0x8000000000000000 /* Primary PIO is cause */ -#define SYSIO_CEAFSR_PDRD 0x4000000000000000 /* Primary DVMA read is cause */ -#define SYSIO_CEAFSR_PDWR 0x2000000000000000 /* Primary DVMA write is cause */ -#define SYSIO_CEAFSR_SPIO 0x1000000000000000 /* Secondary PIO is cause */ -#define SYSIO_CEAFSR_SDRD 0x0800000000000000 /* Secondary DVMA read is cause */ -#define SYSIO_CEAFSR_SDWR 0x0400000000000000 /* Secondary DVMA write is cause*/ -#define SYSIO_CEAFSR_RESV1 0x0300000000000000 /* Reserved */ -#define SYSIO_CEAFSR_ESYND 0x00ff000000000000 /* Syndrome Bits */ -#define SYSIO_CEAFSR_DOFF 0x0000e00000000000 /* Double Offset */ -#define SYSIO_CEAFSR_SIZE 0x00001c0000000000 /* Bad transfer size is 2**SIZE */ -#define SYSIO_CEAFSR_MID 0x000003e000000000 /* UPA MID causing the fault */ -#define SYSIO_CEAFSR_RESV2 0x0000001fffffffff /* Reserved */ - -/* DMA Scoreboard Diagnostic Register(s) */ -#define SYSIO_DSCORE_VALID 0x0040000000000000 /* Entry is valid */ -#define SYSIO_DSCORE_C 0x0020000000000000 /* Transaction cacheable */ -#define SYSIO_DSCORE_READ 0x0010000000000000 /* Transaction was a read */ -#define SYSIO_DSCORE_TAG 0x000f000000000000 /* Transaction ID */ -#define SYSIO_DSCORE_ADDR 0x0000ffffffffff80 /* Transaction PADDR */ -#define SYSIO_DSCORE_SIZE 0x0000000000000030 /* Transaction size */ -#define SYSIO_DSCORE_SRC 0x000000000000000f /* Transaction source */ - -/* SYSIO SBUS Control Register */ -#define SYSIO_SBCNTRL_IMPL 0xf000000000000000 /* Implementation */ -#define SYSIO_SBCNTRL_REV 0x0f00000000000000 /* Revision */ -#define SYSIO_SBCNTRL_RESV1 0x00c0000000000000 /* Reserved */ -#define SYSIO_SBCNTRL_DPERR 0x003f000000000000 /* DMA Write Parity Error */ -#define SYSIO_SBCNTRL_RESV2 0x0000800000000000 /* Reserved */ -#define SYSIO_SBCNTRL_PPERR 0x00007f0000000000 /* PIO Load Parity Error */ -#define SYSIO_SBCNTRL_RESV 0x000000fffffff800 /* Reserved */ -#define SYSIO_SBCNTRL_FAST 0x0000000000000400 /* Enable Fast-SBUS mode. */ -#define SYSIO_SBCNTRL_WEN 0x0000000000000200 /* Power Mgmt Wake Enable */ -#define SYSIO_SBCNTRL_EEN 0x0000000000000100 /* SBUS Error Interrupt Enable */ -#define SYSIO_SBCNTRL_RESV3 0x00000000000000c0 /* Reserved */ -#define SYSIO_SBCNTRL_AEN 0x000000000000003f /* SBUS DVMA Arbitration Enable */ - -/* SYSIO SBUS AFSR, AFAR holds low 40 bits of physical address causing the fault. */ -#define SYSIO_SBAFSR_PLE 0x8000000000000000 /* Primary Late PIO Error */ -#define SYSIO_SBAFSR_PTO 0x4000000000000000 /* Primary SBUS Timeout */ -#define SYSIO_SBAFSR_PBERR 0x2000000000000000 /* Primary SBUS Error ACK */ -#define SYSIO_SBAFSR_SLE 0x1000000000000000 /* Secondary Late PIO Error */ -#define SYSIO_SBAFSR_STO 0x0800000000000000 /* Secondary SBUS Timeout */ -#define SYSIO_SBAFSR_SBERR 0x0400000000000000 /* Secondary SBUS Error ACK */ -#define SYSIO_SBAFSR_RESV1 0x03ff000000000000 /* Reserved */ -#define SYSIO_SBAFSR_RD 0x0000800000000000 /* Primary was late PIO read */ -#define SYSIO_SBAFSR_RESV2 0x0000600000000000 /* Reserved */ -#define SYSIO_SBAFSR_SIZE 0x00001c0000000000 /* Size of transfer */ -#define SYSIO_SBAFSR_MID 0x000003e000000000 /* MID causing the error */ -#define SYSIO_SBAFSR_RESV3 0x0000001fffffffff /* Reserved */ - -/* SYSIO SBUS Slot Configuration Register(s) */ -#define SYSIO_SBSCFG_RESV1 0xfffffffff8000000 /* Reserved */ -#define SYSIO_SBSCFG_SADDR 0x0000000007ff0000 /* Segment Address (PA[40:30]) */ -#define SYSIO_SBSCFG_CP 0x0000000000008000 /* Bypasses are cacheable */ -#define SYSIO_SBSCFG_ETM 0x0000000000004000 /* Ext Transfer Mode supported */ -#define SYSIO_SBSCFG_PE 0x0000000000002000 /* SBUS Parity Checking Enable */ -#define SYSIO_SBSCFG_RESV2 0x0000000000001fe0 /* Reserved */ -#define SYSIO_SBSCFG_BA64 0x0000000000000010 /* 64-byte bursts supported */ -#define SYSIO_SBSCFG_BA32 0x0000000000000008 /* 32-byte bursts supported */ -#define SYSIO_SBSCFG_BA16 0x0000000000000004 /* 16-byte bursts supported */ -#define SYSIO_SBSCFG_BA8 0x0000000000000002 /* 8-byte bursts supported */ -#define SYSIO_SBSCFG_BY 0x0000000000000001 /* IOMMU Bypass Enable */ - -/* IOMMU things defined fully in asm-sparc64/iommu.h */ - -/* Streaming Buffer Control Register */ -#define SYSIO_SBUFCTRL_IMPL 0xf000000000000000 /* Implementation */ -#define SYSIO_SBUFCTRL_REV 0x0f00000000000000 /* Revision */ -#define SYSIO_SBUFCTRL_DE 0x0000000000000002 /* Diag Mode Enable */ -#define SYSIO_SBUFCTRL_SB_EN 0x0000000000000001 /* Streaming Buffer Enable */ - -/* Streaming Buffer Page Invalidate/Flush Register */ -#define SYSIO_SBUFFLUSH_ADDR 0x00000000ffffe000 /* DVMA Page to be flushed */ -#define SYSIO_SBUFFLUSH_RESV 0x0000000000001fff /* Ignored bits */ - -/* Streaming Buffer Flush Synchronization Register */ -#define SYSIO_SBUFSYNC_ADDR 0x000001fffffffffc /* Physical address to update */ -#define SYSIO_SBUFSYNC_RESV 0x0000000000000003 /* Ignored bits */ - -/* SYSIO Interrupt mapping register(s). */ -#define SYSIO_IMAP_VALID 0x80000000 /* This enables delivery. */ -#define SYSIO_IMAP_TID 0x7c000000 /* Target ID (MID to send it to) */ -#define SYSIO_IMAP_RESV 0x03fff800 /* Reserved. */ -#define SYSIO_IMAP_IGN 0x000007c0 /* Interrupt Group Number. */ -#define SYSIO_IMAP_INO 0x0000003f /* Interrupt Number Offset. */ -#define SYSIO_IMAP_INR 0x000007ff /* Interrupt # (Gfx/UPA_slave only)*/ - -/* SYSIO Interrupt clear pseudo register(s). */ -#define SYSIO_ICLR_IDLE 0x00000000 /* Transition to idle state. */ -#define SYSIO_ICLR_TRANSMIT 0x00000001 /* Transition to transmit state. */ -#define SYSIO_ICLR_RESV 0x00000002 /* Reserved. */ -#define SYSIO_ICLR_PENDING 0x00000003 /* Transition to pending state. */ - -/* SYSIO Interrupt Retry Timer register. */ -#define SYSIO_IRETRY_LIMIT 0x000000ff /* The retry interval. */ - -/* SYSIO Interrupt State registers. */ -#define SYSIO_ISTATE_IDLE 0x0 /* No interrupt received or pending */ -#define SYSIO_ISTATE_TRANSMIT 0x1 /* Received, but IRQ not dispatched */ -#define SYSIO_ISTATE_ILLEGAL 0x2 /* Impossible state */ -#define SYSIO_ISTATE_PENDING 0x3 /* Received and dispatched */ - -/* Two ways to get at the right bits, your choice... note that level - * zero is illegal. For slots 0 --> 3 the formula for the bit range - * in the register is: - * - * LSB ((SBUS_SLOT X 16) + (SBUS_LEVEL X 2)) - * MSB ((SBUS_SLOT X 16) + (SBUS_LEVEL X 2)) + 1 - * - * Thus the following macro. - */ -#define SYSIO_SBUS_ISTATE(regval, slot, level) \ - (((regval) >> (((slot) * 16) + ((level) * 2))) & 0x3) - -#define SYSIO_SBUS_ISTATE_S0L1 0x000000000000000c /* Slot 0, level 1 */ -#define SYSIO_SBUS_ISTATE_S0L2 0x0000000000000030 /* Slot 0, level 2 */ -#define SYSIO_SBUS_ISTATE_S0L3 0x00000000000000c0 /* Slot 0, level 3 */ -#define SYSIO_SBUS_ISTATE_S0L4 0x0000000000000300 /* Slot 0, level 4 */ -#define SYSIO_SBUS_ISTATE_S0L5 0x0000000000000c00 /* Slot 0, level 5 */ -#define SYSIO_SBUS_ISTATE_S0L6 0x0000000000003000 /* Slot 0, level 6 */ -#define SYSIO_SBUS_ISTATE_S0L7 0x000000000000c000 /* Slot 0, level 7 */ -#define SYSIO_SBUS_ISTATE_S1L1 0x00000000000c0000 /* Slot 1, level 1 */ -#define SYSIO_SBUS_ISTATE_S1L2 0x0000000000300000 /* Slot 1, level 2 */ -#define SYSIO_SBUS_ISTATE_S1L3 0x0000000000c00000 /* Slot 1, level 3 */ -#define SYSIO_SBUS_ISTATE_S1L4 0x0000000003000000 /* Slot 1, level 4 */ -#define SYSIO_SBUS_ISTATE_S1L5 0x000000000c000000 /* Slot 1, level 5 */ -#define SYSIO_SBUS_ISTATE_S1L6 0x0000000030000000 /* Slot 1, level 6 */ -#define SYSIO_SBUS_ISTATE_S1L7 0x00000000c0000000 /* Slot 1, level 7 */ -#define SYSIO_SBUS_ISTATE_S2L1 0x0000000c00000000 /* Slot 2, level 1 */ -#define SYSIO_SBUS_ISTATE_S2L2 0x0000003000000000 /* Slot 2, level 2 */ -#define SYSIO_SBUS_ISTATE_S2L3 0x000000c000000000 /* Slot 2, level 3 */ -#define SYSIO_SBUS_ISTATE_S2L4 0x0000030000000000 /* Slot 2, level 4 */ -#define SYSIO_SBUS_ISTATE_S2L5 0x00000c0000000000 /* Slot 2, level 5 */ -#define SYSIO_SBUS_ISTATE_S2L6 0x0000300000000000 /* Slot 2, level 6 */ -#define SYSIO_SBUS_ISTATE_S2L7 0x0000c00000000000 /* Slot 2, level 7 */ -#define SYSIO_SBUS_ISTATE_S3L1 0x000c000000000000 /* Slot 3, level 1 */ -#define SYSIO_SBUS_ISTATE_S3L2 0x0030000000000000 /* Slot 3, level 2 */ -#define SYSIO_SBUS_ISTATE_S3L3 0x00c0000000000000 /* Slot 3, level 3 */ -#define SYSIO_SBUS_ISTATE_S3L4 0x0300000000000000 /* Slot 3, level 4 */ -#define SYSIO_SBUS_ISTATE_S3L5 0x0c00000000000000 /* Slot 3, level 5 */ -#define SYSIO_SBUS_ISTATE_S3L6 0x3000000000000000 /* Slot 3, level 6 */ -#define SYSIO_SBUS_ISTATE_S3L7 0xc000000000000000 /* Slot 3, level 7 */ - -/* For OBIO devices things are a bit different, you just have to know what - * you are looking for. - */ -#define SYSIO_OBIO_ISTATE_SCSI 0x0000000000000003 /* Scsi */ -#define SYSIO_OBIO_ISTATE_ETH 0x000000000000000c /* Ethernet */ -#define SYSIO_OBIO_ISTATE_PP 0x0000000000000030 /* Parallel Port */ -#define SYSIO_OBIO_ISTATE_AUDIO 0x00000000000000c0 /* Sun Audio */ -#define SYSIO_OBIO_ISTATE_PFAIL 0x0000000000000300 /* Power Fail */ -#define SYSIO_OBIO_ISTATE_KBMS 0x0000000000000c00 /* kbd/mouse/serial */ -#define SYSIO_OBIO_ISTATE_FLPY 0x0000000000003000 /* Floppy Controller */ -#define SYSIO_OBIO_ISTATE_SPHW 0x000000000000c000 /* Spare HW */ -#define SYSIO_OBIO_ISTATE_KBD 0x0000000000030000 /* Keyboard */ -#define SYSIO_OBIO_ISTATE_MS 0x00000000000c0000 /* Mouse */ -#define SYSIO_OBIO_ISTATE_SER 0x0000000000300000 /* Serial */ -#define SYSIO_OBIO_ISTATE_TIM0 0x0000000000c00000 /* Timer 0 */ -#define SYSIO_OBIO_ISTATE_TIM1 0x0000000003000000 /* Timer 1 */ -#define SYSIO_OBIO_ISTATE_UE 0x000000000c000000 /* Uncorrectable Err */ -#define SYSIO_OBIO_ISTATE_CE 0x0000000030000000 /* Correctable Err */ -#define SYSIO_OBIO_ISTATE_SERR 0x00000000c0000000 /* SBUS Err */ -#define SYSIO_OBIO_ISTATE_PMGMT 0x0000000300000000 /* Power Management */ -#define SYSIO_OBIO_ISTATE_RSVI 0x0000000400000000 /* Reserved Int */ -#define SYSIO_OBIO_ISTATE_EUPA 0x0000000800000000 /* Expansion UPA (creator) */ -#define SYSIO_OBIO_ISTATE_RESV 0xfffffff000000000 /* Reserved... */ - -/* SYSIO Counter and Limit registers are documented in timer.h as these - * are generic SUN4U things. - */ - -/* SYSIO Performance Monitor Control register. */ -#define SYSIO_PCNTRL_CLR1 0x0000000000008000 /* Clear SEL1 counter */ -#define SYSIO_PCNTRL_SEL1_SDR 0x0000000000000000 /* SEL1: Streaming DVMA reads */ -#define SYSIO_PCNTRL_SEL1_SDW 0x0000000000000100 /* SEL1: Streaming DVMA writes */ -#define SYSIO_PCNTRL_SEL1_CDR 0x0000000000000200 /* SEL1: Consistent DVMA reads */ -#define SYSIO_PCNTRL_SEL1_CDW 0x0000000000000300 /* SEL1: Consistent DVMA writes */ -#define SYSIO_PCNTRL_SEL1_TMISS 0x0000000000000400 /* SEL1: IOMMU TLB misses */ -#define SYSIO_PCNTRL_SEL1_SMISS 0x0000000000000500 /* SEL1: Streaming Buffer misses */ -#define SYSIO_PCNTRL_SEL1_SDC 0x0000000000000600 /* SEL1: SBUS dvma cycles */ -#define SYSIO_PCNTRL_SEL1_DB 0x0000000000000700 /* SEL1: DVMA bytes transferred */ -#define SYSIO_PCNTRL_SEL1_IRQ 0x0000000000000800 /* SEL1: Interrupts */ -#define SYSIO_PCNTRL_SEL1_UIN 0x0000000000000900 /* SEL1: UPA IRQ NACK's */ -#define SYSIO_PCNTRL_SEL1_PRD 0x0000000000000a00 /* SEL1: PIO reads */ -#define SYSIO_PCNTRL_SEL1_PWR 0x0000000000000b00 /* SEL1: PIO writes */ -#define SYSIO_PCNTRL_SEL1_SRR 0x0000000000000c00 /* SEL1: SBUS reruns */ -#define SYSIO_PCNTRL_SEL1_SPIO 0x0000000000000d00 /* SEL1: SYSIO PIO cycles */ -#define SYSIO_PCNTRL_CLR0 0x0000000000000080 /* Clear SEL0 counter */ -#define SYSIO_PCNTRL_SEL0_SDR 0x0000000000000000 /* SEL0: Streaming DVMA reads */ -#define SYSIO_PCNTRL_SEL0_SDW 0x0000000000000001 /* SEL0: Streaming DVMA writes */ -#define SYSIO_PCNTRL_SEL0_CDR 0x0000000000000002 /* SEL0: Consistent DVMA reads */ -#define SYSIO_PCNTRL_SEL0_CDW 0x0000000000000003 /* SEL0: Consistent DVMA writes */ -#define SYSIO_PCNTRL_SEL0_TMISS 0x0000000000000004 /* SEL0: IOMMU TLB misses */ -#define SYSIO_PCNTRL_SEL0_SMISS 0x0000000000000005 /* SEL0: Streaming Buffer misses */ -#define SYSIO_PCNTRL_SEL0_SDC 0x0000000000000006 /* SEL0: SBUS dvma cycles */ -#define SYSIO_PCNTRL_SEL0_DB 0x0000000000000007 /* SEL0: DVMA bytes transferred */ -#define SYSIO_PCNTRL_SEL0_IRQ 0x0000000000000008 /* SEL0: Interrupts */ -#define SYSIO_PCNTRL_SEL0_UIN 0x0000000000000009 /* SEL0: UPA IRQ NACK's */ -#define SYSIO_PCNTRL_SEL0_PRD 0x000000000000000a /* SEL0: PIO reads */ -#define SYSIO_PCNTRL_SEL0_PWR 0x000000000000000b /* SEL0: PIO writes */ -#define SYSIO_PCNTRL_SEL0_SRR 0x000000000000000c /* SEL0: SBUS reruns */ -#define SYSIO_PCNTRL_SEL0_SPIO 0x000000000000000d /* SEL0: SYSIO PIO cycles */ - -/* SYSIO Performance Monitor Counter register. */ -#define SYSIO_PCOUNT_CNT0 0xffffffff00000000 /* Counter zero */ -#define SYSIO_PCOUNT_CNT1 0x00000000ffffffff /* Counter one */ - -#endif /* !(__SPARC64_SYSIO_H) */ diff --git a/include/asm-sparc64/termios.h b/include/asm-sparc64/termios.h index 953b5bdd3..578e07251 100644 --- a/include/asm-sparc64/termios.h +++ b/include/asm-sparc64/termios.h @@ -1,4 +1,4 @@ -/* $Id: termios.h,v 1.8 1999/03/25 09:11:26 davem Exp $ */ +/* $Id: termios.h,v 1.9 1999/12/02 09:57:53 davem Exp $ */ #ifndef _SPARC64_TERMIOS_H #define _SPARC64_TERMIOS_H @@ -69,7 +69,7 @@ struct winsize { #define N_IRDA 11 /* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */ #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 +#define N_SYNC_PPP 14 /* synchronous PPP */ #ifdef __KERNEL__ diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h index 4289e581c..cb03301a4 100644 --- a/include/asm-sparc64/ttable.h +++ b/include/asm-sparc64/ttable.h @@ -1,4 +1,4 @@ -/* $Id: ttable.h,v 1.13 1999/08/31 19:25:50 davem Exp $ */ +/* $Id: ttable.h,v 1.14 1999/10/13 11:48:58 jj Exp $ */ #ifndef _SPARC64_TTABLE_H #define _SPARC64_TTABLE_H @@ -107,7 +107,11 @@ 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 #define LINUX_32BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sys_call_table32) #define LINUX_64BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall, sys_call_table64) #define GETCC_TRAP TRAP(getcc) @@ -159,6 +163,20 @@ /* 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 */ @@ -183,52 +201,67 @@ nop; nop; nop; nop; nop; nop; nop; nop; /* Normal 64bit spill */ -#define SPILL_1_GENERIC(xxx) \ - wr %g0, xxx, %asi; \ - stxa %l0, [%sp + STACK_BIAS + 0x00] %asi; \ - stxa %l1, [%sp + STACK_BIAS + 0x08] %asi; \ - stxa %l2, [%sp + STACK_BIAS + 0x10] %asi; \ - stxa %l3, [%sp + STACK_BIAS + 0x18] %asi; \ - stxa %l4, [%sp + STACK_BIAS + 0x20] %asi; \ - stxa %l5, [%sp + STACK_BIAS + 0x28] %asi; \ - stxa %l6, [%sp + STACK_BIAS + 0x30] %asi; \ - stxa %l7, [%sp + STACK_BIAS + 0x38] %asi; \ - stxa %i0, [%sp + STACK_BIAS + 0x40] %asi; \ - stxa %i1, [%sp + STACK_BIAS + 0x48] %asi; \ - stxa %i2, [%sp + STACK_BIAS + 0x50] %asi; \ - stxa %i3, [%sp + STACK_BIAS + 0x58] %asi; \ - stxa %i4, [%sp + STACK_BIAS + 0x60] %asi; \ - stxa %i5, [%sp + STACK_BIAS + 0x68] %asi; \ - stxa %i6, [%sp + STACK_BIAS + 0x70] %asi; \ - stxa %i7, [%sp + STACK_BIAS + 0x78] %asi; \ - saved; retry; nop; nop; nop; nop; nop; nop; \ - nop; nop; nop; nop; \ +#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(xxx) \ - wr %g0, xxx, %asi; \ +#define SPILL_2_GENERIC(ASI) \ srl %sp, 0, %sp; \ - stwa %l0, [%sp + 0x00] %asi; \ - stwa %l1, [%sp + 0x04] %asi; \ - stwa %l2, [%sp + 0x08] %asi; \ - stwa %l3, [%sp + 0x0c] %asi; \ - stwa %l4, [%sp + 0x10] %asi; \ - stwa %l5, [%sp + 0x14] %asi; \ - stwa %l6, [%sp + 0x18] %asi; \ - stwa %l7, [%sp + 0x1c] %asi; \ - stwa %i0, [%sp + 0x20] %asi; \ - stwa %i1, [%sp + 0x24] %asi; \ - stwa %i2, [%sp + 0x28] %asi; \ - stwa %i3, [%sp + 0x2c] %asi; \ - stwa %i4, [%sp + 0x30] %asi; \ - stwa %i5, [%sp + 0x34] %asi; \ - stwa %i6, [%sp + 0x38] %asi; \ - stwa %i7, [%sp + 0x3c] %asi; \ - saved; retry; nop; nop; nop; nop; \ - nop; nop; nop; nop; nop; \ + 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; @@ -272,52 +305,63 @@ nop; nop; nop; nop; nop; nop; nop; nop; /* Normal 64bit fill */ -#define FILL_1_GENERIC(xxx) \ - wr %g0, xxx, %asi; \ - ldxa [%sp + STACK_BIAS + 0x00] %asi, %l0; \ - ldxa [%sp + STACK_BIAS + 0x08] %asi, %l1; \ - ldxa [%sp + STACK_BIAS + 0x10] %asi, %l2; \ - ldxa [%sp + STACK_BIAS + 0x18] %asi, %l3; \ - ldxa [%sp + STACK_BIAS + 0x20] %asi, %l4; \ - ldxa [%sp + STACK_BIAS + 0x28] %asi, %l5; \ - ldxa [%sp + STACK_BIAS + 0x30] %asi, %l6; \ - ldxa [%sp + STACK_BIAS + 0x38] %asi, %l7; \ - ldxa [%sp + STACK_BIAS + 0x40] %asi, %i0; \ - ldxa [%sp + STACK_BIAS + 0x48] %asi, %i1; \ - ldxa [%sp + STACK_BIAS + 0x50] %asi, %i2; \ - ldxa [%sp + STACK_BIAS + 0x58] %asi, %i3; \ - ldxa [%sp + STACK_BIAS + 0x60] %asi, %i4; \ - ldxa [%sp + STACK_BIAS + 0x68] %asi, %i5; \ - ldxa [%sp + STACK_BIAS + 0x70] %asi, %i6; \ - ldxa [%sp + STACK_BIAS + 0x78] %asi, %i7; \ - restored; retry; nop; nop; nop; nop; nop; nop; \ - nop; nop; nop; nop; \ +#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(xxx) \ - wr %g0, xxx, %asi; \ +#define FILL_2_GENERIC(ASI) \ srl %sp, 0, %sp; \ - lduwa [%sp + 0x00] %asi, %l0; \ - lduwa [%sp + 0x04] %asi, %l1; \ - lduwa [%sp + 0x08] %asi, %l2; \ - lduwa [%sp + 0x0c] %asi, %l3; \ - lduwa [%sp + 0x10] %asi, %l4; \ - lduwa [%sp + 0x14] %asi, %l5; \ - lduwa [%sp + 0x18] %asi, %l6; \ - lduwa [%sp + 0x1c] %asi, %l7; \ - lduwa [%sp + 0x20] %asi, %i0; \ - lduwa [%sp + 0x24] %asi, %i1; \ - lduwa [%sp + 0x28] %asi, %i2; \ - lduwa [%sp + 0x2c] %asi, %i3; \ - lduwa [%sp + 0x30] %asi, %i4; \ - lduwa [%sp + 0x34] %asi, %i5; \ - lduwa [%sp + 0x38] %asi, %i6; \ - lduwa [%sp + 0x3c] %asi, %i7; \ - restored; retry; nop; nop; nop; nop; \ - nop; nop; nop; nop; nop; \ + 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; diff --git a/include/asm-sparc64/uaccess.h b/include/asm-sparc64/uaccess.h index e0dd2e4f3..72c2c6916 100644 --- a/include/asm-sparc64/uaccess.h +++ b/include/asm-sparc64/uaccess.h @@ -1,4 +1,4 @@ -/* $Id: uaccess.h,v 1.31 1999/07/30 09:31:24 davem Exp $ */ +/* $Id: uaccess.h,v 1.32 1999/11/23 08:56:48 davem Exp $ */ #ifndef _ASM_UACCESS_H #define _ASM_UACCESS_H @@ -347,8 +347,10 @@ extern int __strncpy_from_user(unsigned long dest, unsigned long src, int count) __strncpy_from_user((unsigned long)(dest), (unsigned long)(src), (int)(count)) extern int __strlen_user(const char *); +extern int __strnlen_user(const char *, long len); #define strlen_user __strlen_user +#define strnlen_user __strnlen_user #endif /* __ASSEMBLY__ */ diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index 6e364cc7d..8c9b29bc6 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h @@ -1,4 +1,4 @@ -/* $Id: unistd.h,v 1.31 1999/08/04 03:20:06 davem Exp $ */ +/* $Id: unistd.h,v 1.37 2000/01/05 07:37:55 jj Exp $ */ #ifndef _SPARC64_UNISTD_H #define _SPARC64_UNISTD_H @@ -71,14 +71,14 @@ /* #define __NR_mctl 53 SunOS specific */ #define __NR_ioctl 54 /* Common */ #define __NR_reboot 55 /* Common */ -/* #define __NR_ni_syscall 56 ENOSYS under SunOS */ +/* #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_ni_syscall 63 ENOSYS under SunOS */ +/* #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 */ @@ -92,14 +92,14 @@ #define __NR_mprotect 74 /* Common */ /* #define __NR_madvise 75 SunOS Specific */ #define __NR_vhangup 76 /* Common */ -/* #define __NR_ni_syscall 77 ENOSYS under SunOS */ +/* #define __NR_truncate64 77 Linux sparc32 Specific */ /* #define __NR_mincore 78 SunOS Specific */ #define __NR_getgroups 79 /* Common */ #define __NR_setgroups 80 /* Common */ #define __NR_getpgrp 81 /* Common */ /* #define __NR_setpgrp 82 setpgid, same difference... */ #define __NR_setitimer 83 /* Common */ -/* #define __NR_ni_syscall 84 ENOSYS under SunOS */ +/* #define __NR_ftruncate64 84 Linux sparc32 Specific */ #define __NR_swapon 85 /* Common */ #define __NR_getitimer 86 /* Common */ /* #define __NR_gethostname 87 SunOS Specific */ @@ -147,19 +147,19 @@ #define __NR_truncate 129 /* Common */ #define __NR_ftruncate 130 /* Common */ #define __NR_flock 131 /* Common */ -/* #define __NR_ni_syscall 132 ENOSYS under SunOS */ +/* #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_ni_syscall 139 ENOSYS under SunOS */ +/* #define __NR_stat64 139 Linux sparc32 Specific */ /* #define __NR_adjtime 140 SunOS Specific */ #define __NR_getpeername 141 /* Common */ /* #define __NR_gethostid 142 SunOS Specific */ /* #define __NR_ni_syscall 143 ENOSYS under SunOS */ -#define __NR_getrlimit 144 /* Common */ +#define __NR_getrlimit 144 /* Common */ #define __NR_setrlimit 145 /* Common */ /* #define __NR_killpg 146 SunOS Specific */ #define __NR_prctl 147 /* ENOSYS under SunOS */ @@ -276,13 +276,13 @@ type name(void) \ { \ long __res; \ -__asm__ __volatile__ ("mov %0, %%g1\n\t" \ - "t 0x6d\n\t" \ +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)\ - : "0" (__NR_##name) \ - : "g1", "o0", "cc"); \ + : "r" (__g1) \ + : "o0", "cc"); \ if (__res >= 0) \ return (type) __res; \ errno = -__res; \ @@ -293,14 +293,14 @@ return -1; \ type name(type1 arg1) \ { \ long __res; \ -__asm__ __volatile__ ("mov %0, %%g1\n\t" \ - "mov %1, %%o0\n\t" \ - "t 0x6d\n\t" \ +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" ((long)(arg1)) \ - : "0" (__NR_##name),"1" ((long)(arg1)) \ - : "g1", "o0", "cc"); \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__g1) \ + : "cc"); \ if (__res >= 0) \ return (type) __res; \ errno = -__res; \ @@ -311,15 +311,15 @@ return -1; \ type name(type1 arg1,type2 arg2) \ { \ long __res; \ -__asm__ __volatile__ ("mov %0, %%g1\n\t" \ - "mov %1, %%o0\n\t" \ - "mov %2, %%o1\n\t" \ - "t 0x6d\n\t" \ +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" ((long)(arg1)), "=r" ((long)(arg2)) \ - : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)) \ - : "g1", "o0", "o1", "cc"); \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__o1), "r" (__g1) \ + : "cc"); \ if (__res >= 0) \ return (type) __res; \ errno = -__res; \ @@ -330,18 +330,16 @@ return -1; \ type name(type1 arg1,type2 arg2,type3 arg3) \ { \ long __res; \ -__asm__ __volatile__ ("mov %0, %%g1\n\t" \ - "mov %1, %%o0\n\t" \ - "mov %2, %%o1\n\t" \ - "mov %3, %%o2\n\t" \ - "t 0x6d\n\t" \ +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" ((long)(arg1)), "=r" ((long)(arg2)), \ - "=r" ((long)(arg3)) \ - : "0" (__NR_##name), "1" ((long)(arg1)), "2" ((long)(arg2)), \ - "3" ((long)(arg3)) \ - : "g1", "o0", "o1", "o2", "cc"); \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \ + : "cc"); \ if (__res>=0) \ return (type) __res; \ errno = -__res; \ @@ -352,19 +350,17 @@ return -1; \ type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ { \ long __res; \ -__asm__ __volatile__ ("mov %0, %%g1\n\t" \ - "mov %1, %%o0\n\t" \ - "mov %2, %%o1\n\t" \ - "mov %3, %%o2\n\t" \ - "mov %4, %%o3\n\t" \ - "t 0x6d\n\t" \ - "sub %%g0,%%o0, %0\n\t" \ +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" ((long)(arg1)), "=r" ((long)(arg2)), \ - "=r" ((long)(arg3)), "=r" ((long)(arg4)) \ - : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)), \ - "3" ((long)(arg3)),"4" ((long)(arg4)) \ - : "g1", "o0", "o1", "o2", "o3", "cc"); \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \ + : "cc"); \ if (__res>=0) \ return (type) __res; \ errno = -__res; \ @@ -375,22 +371,19 @@ return -1; \ type5,arg5) \ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ { \ - long __res; \ -\ -__asm__ __volatile__ ("mov %1, %%o0\n\t" \ - "mov %2, %%o1\n\t" \ - "mov %3, %%o2\n\t" \ - "mov %4, %%o3\n\t" \ - "mov %5, %%o4\n\t" \ - "mov %6, %%g1\n\t" \ - "t 0x6d\n\t" \ +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" ((long)(arg1)),"r" ((long)(arg2)), \ - "r" ((long)(arg3)),"r" ((long)(arg4)),"r" ((long)(arg5)), \ - "i" (__NR_##name) \ - : "g1", "o0", "o1", "o2", "o3", "o4", "cc"); \ + : "=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; \ diff --git a/include/asm-sparc64/upa.h b/include/asm-sparc64/upa.h index a3885f2c5..fabcf2c51 100644 --- a/include/asm-sparc64/upa.h +++ b/include/asm-sparc64/upa.h @@ -1,7 +1,9 @@ -/* $Id: upa.h,v 1.2 1997/04/04 00:50:30 davem Exp $ */ +/* $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 */ @@ -21,4 +23,88 @@ #define UPA_PORTID_UPACAP 0x00000000001f0000 /* UPA capabilities of mod */ #define UPA_PORTID_ID 0x000000000000ffff /* Module Indentification bits */ +/* UPA I/O space accessors */ +#if defined(__KERNEL__) && !defined(__ASSEMBLY__) +extern __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; +} + +extern __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; +} + +extern __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; +} + +extern __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; +} + +extern __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)); +} + +extern __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)); +} + +extern __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)); +} + +extern __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) */ |