Commit a00736e9 authored by Sam Ravnborg's avatar Sam Ravnborg Committed by David S. Miller

sparc: copy sparc64 specific files to asm-sparc

Used the following script to copy the files:
cd include
set -e
SPARC64=`ls asm-sparc64`
for FILE in ${SPARC64}; do
	if [ -f asm-sparc/$FILE ]; then
		echo $FILE exist in asm-sparc
	else
		git mv asm-sparc64/$FILE asm-sparc/$FILE
		printf "#include <asm-sparc/$FILE>\n" > asm-sparc64/$FILE
		git add asm-sparc64/$FILE
	fi
done
Signed-off-by: default avatarSam Ravnborg <sam@ravnborg.org>
parent bdc3135a
#ifndef AGP_H
#define AGP_H 1
/* dummy for now */
#define map_page_into_agp(page)
#define unmap_page_from_agp(page)
#define flush_agp_cache() mb()
/* Convert a physical address to an address suitable for the GART. */
#define phys_to_gart(x) (x)
#define gart_to_phys(x) (x)
/* GATT allocation. Returns/accepts GATT kernel virtual address. */
#define alloc_gatt_pages(order) \
((char *)__get_free_pages(GFP_KERNEL, (order)))
#define free_gatt_pages(table, order) \
free_pages((unsigned long)(table), (order))
#endif
/*
* apb.h: Advanced PCI Bridge Configuration Registers and Bits
*
* Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
*/
#ifndef _SPARC64_APB_H
#define _SPARC64_APB_H
#define APB_TICK_REGISTER 0xb0
#define APB_INT_ACK 0xb8
#define APB_PRIMARY_MASTER_RETRY_LIMIT 0xc0
#define APB_DMA_ASFR 0xc8
#define APB_DMA_AFAR 0xd0
#define APB_PIO_TARGET_RETRY_LIMIT 0xd8
#define APB_PIO_TARGET_LATENCY_TIMER 0xd9
#define APB_DMA_TARGET_RETRY_LIMIT 0xda
#define APB_DMA_TARGET_LATENCY_TIMER 0xdb
#define APB_SECONDARY_MASTER_RETRY_LIMIT 0xdc
#define APB_SECONDARY_CONTROL 0xdd
#define APB_IO_ADDRESS_MAP 0xde
#define APB_MEM_ADDRESS_MAP 0xdf
#define APB_PCI_CONTROL_LOW 0xe0
# define APB_PCI_CTL_LOW_ARB_PARK (1 << 21)
# define APB_PCI_CTL_LOW_ERRINT_EN (1 << 8)
#define APB_PCI_CONTROL_HIGH 0xe4
# define APB_PCI_CTL_HIGH_SERR (1 << 2)
# define APB_PCI_CTL_HIGH_ARBITER_EN (1 << 0)
#define APB_PIO_ASFR 0xe8
#define APB_PIO_AFAR 0xf0
#define APB_DIAG_REGISTER 0xf8
#endif /* !(_SPARC64_APB_H) */
#ifndef _SPARC64_BACKOFF_H
#define _SPARC64_BACKOFF_H
#define BACKOFF_LIMIT (4 * 1024)
#ifdef CONFIG_SMP
#define BACKOFF_SETUP(reg) \
mov 1, reg
#define BACKOFF_SPIN(reg, tmp, label) \
mov reg, tmp; \
88: brnz,pt tmp, 88b; \
sub tmp, 1, tmp; \
set BACKOFF_LIMIT, tmp; \
cmp reg, tmp; \
bg,pn %xcc, label; \
nop; \
ba,pt %xcc, label; \
sllx reg, 1, reg;
#else
#define BACKOFF_SETUP(reg)
#define BACKOFF_SPIN(reg, tmp, label) \
ba,pt %xcc, label; \
nop;
#endif
#endif /* _SPARC64_BACKOFF_H */
/*
* bbc.h: Defines for BootBus Controller found on UltraSPARC-III
* systems.
*
* Copyright (C) 2000 David S. Miller (davem@redhat.com)
*/
#ifndef _SPARC64_BBC_H
#define _SPARC64_BBC_H
/* Register sizes are indicated by "B" (Byte, 1-byte),
* "H" (Half-word, 2 bytes), "W" (Word, 4 bytes) or
* "Q" (Quad, 8 bytes) inside brackets.
*/
#define BBC_AID 0x00 /* [B] Agent ID */
#define BBC_DEVP 0x01 /* [B] Device Present */
#define BBC_ARB 0x02 /* [B] Arbitration */
#define BBC_QUIESCE 0x03 /* [B] Quiesce */
#define BBC_WDACTION 0x04 /* [B] Watchdog Action */
#define BBC_SPG 0x06 /* [B] Soft POR Gen */
#define BBC_SXG 0x07 /* [B] Soft XIR Gen */
#define BBC_PSRC 0x08 /* [W] POR Source */
#define BBC_XSRC 0x0c /* [B] XIR Source */
#define BBC_CSC 0x0d /* [B] Clock Synthesizers Control*/
#define BBC_ES_CTRL 0x0e /* [H] Energy Star Control */
#define BBC_ES_ACT 0x10 /* [W] E* Assert Change Time */
#define BBC_ES_DACT 0x14 /* [B] E* De-Assert Change Time */
#define BBC_ES_DABT 0x15 /* [B] E* De-Assert Bypass Time */
#define BBC_ES_ABT 0x16 /* [H] E* Assert Bypass Time */
#define BBC_ES_PST 0x18 /* [W] E* PLL Settle Time */
#define BBC_ES_FSL 0x1c /* [W] E* Frequency Switch Latency*/
#define BBC_EBUST 0x20 /* [Q] EBUS Timing */
#define BBC_JTAG_CMD 0x28 /* [W] JTAG+ Command */
#define BBC_JTAG_CTRL 0x2c /* [B] JTAG+ Control */
#define BBC_I2C_SEL 0x2d /* [B] I2C Selection */
#define BBC_I2C_0_S1 0x2e /* [B] I2C ctrlr-0 reg S1 */
#define BBC_I2C_0_S0 0x2f /* [B] I2C ctrlr-0 regs S0,S0',S2,S3*/
#define BBC_I2C_1_S1 0x30 /* [B] I2C ctrlr-1 reg S1 */
#define BBC_I2C_1_S0 0x31 /* [B] I2C ctrlr-1 regs S0,S0',S2,S3*/
#define BBC_KBD_BEEP 0x32 /* [B] Keyboard Beep */
#define BBC_KBD_BCNT 0x34 /* [W] Keyboard Beep Counter */
#define BBC_REGS_SIZE 0x40
/* There is a 2K scratch ram area at offset 0x80000 but I doubt
* we will use it for anything.
*/
/* Agent ID register. This register shows the Safari Agent ID
* for the processors. The value returned depends upon which
* cpu is reading the register.
*/
#define BBC_AID_ID 0x07 /* Safari ID */
#define BBC_AID_RESV 0xf8 /* Reserved */
/* Device Present register. One can determine which cpus are actually
* present in the machine by interrogating this register.
*/
#define BBC_DEVP_CPU0 0x01 /* Processor 0 present */
#define BBC_DEVP_CPU1 0x02 /* Processor 1 present */
#define BBC_DEVP_CPU2 0x04 /* Processor 2 present */
#define BBC_DEVP_CPU3 0x08 /* Processor 3 present */
#define BBC_DEVP_RESV 0xf0 /* Reserved */
/* Arbitration register. This register is used to block access to
* the BBC from a particular cpu.
*/
#define BBC_ARB_CPU0 0x01 /* Enable cpu 0 BBC arbitratrion */
#define BBC_ARB_CPU1 0x02 /* Enable cpu 1 BBC arbitratrion */
#define BBC_ARB_CPU2 0x04 /* Enable cpu 2 BBC arbitratrion */
#define BBC_ARB_CPU3 0x08 /* Enable cpu 3 BBC arbitratrion */
#define BBC_ARB_RESV 0xf0 /* Reserved */
/* Quiesce register. Bus and BBC segments for cpus can be disabled
* with this register, ie. for hot plugging.
*/
#define BBC_QUIESCE_S02 0x01 /* Quiesce Safari segment for cpu 0 and 2 */
#define BBC_QUIESCE_S13 0x02 /* Quiesce Safari segment for cpu 1 and 3 */
#define BBC_QUIESCE_B02 0x04 /* Quiesce BBC segment for cpu 0 and 2 */
#define BBC_QUIESCE_B13 0x08 /* Quiesce BBC segment for cpu 1 and 3 */
#define BBC_QUIESCE_FD0 0x10 /* Disable Fatal_Error[0] reporting */
#define BBC_QUIESCE_FD1 0x20 /* Disable Fatal_Error[1] reporting */
#define BBC_QUIESCE_FD2 0x40 /* Disable Fatal_Error[2] reporting */
#define BBC_QUIESCE_FD3 0x80 /* Disable Fatal_Error[3] reporting */
/* Watchdog Action register. When the watchdog device timer expires
* a line is enabled to the BBC. The action BBC takes when this line
* is asserted can be controlled by this regiser.
*/
#define BBC_WDACTION_RST 0x01 /* When set, watchdog causes system reset.
* When clear, BBC ignores watchdog signal.
*/
#define BBC_WDACTION_RESV 0xfe /* Reserved */
/* Soft_POR_GEN register. The POR (Power On Reset) signal may be asserted
* for specific processors or all processors via this register.
*/
#define BBC_SPG_CPU0 0x01 /* Assert POR for processor 0 */
#define BBC_SPG_CPU1 0x02 /* Assert POR for processor 1 */
#define BBC_SPG_CPU2 0x04 /* Assert POR for processor 2 */
#define BBC_SPG_CPU3 0x08 /* Assert POR for processor 3 */
#define BBC_SPG_CPUALL 0x10 /* Reset all processors and reset
* the entire system.
*/
#define BBC_SPG_RESV 0xe0 /* Reserved */
/* Soft_XIR_GEN register. The XIR (eXternally Initiated Reset) signal
* may be asserted to specific processors via this register.
*/
#define BBC_SXG_CPU0 0x01 /* Assert XIR for processor 0 */
#define BBC_SXG_CPU1 0x02 /* Assert XIR for processor 1 */
#define BBC_SXG_CPU2 0x04 /* Assert XIR for processor 2 */
#define BBC_SXG_CPU3 0x08 /* Assert XIR for processor 3 */
#define BBC_SXG_RESV 0xf0 /* Reserved */
/* POR Source register. One may identify the cause of the most recent
* reset by reading this register.
*/
#define BBC_PSRC_SPG0 0x0001 /* CPU 0 reset via BBC_SPG register */
#define BBC_PSRC_SPG1 0x0002 /* CPU 1 reset via BBC_SPG register */
#define BBC_PSRC_SPG2 0x0004 /* CPU 2 reset via BBC_SPG register */
#define BBC_PSRC_SPG3 0x0008 /* CPU 3 reset via BBC_SPG register */
#define BBC_PSRC_SPGSYS 0x0010 /* System reset via BBC_SPG register */
#define BBC_PSRC_JTAG 0x0020 /* System reset via JTAG+ */
#define BBC_PSRC_BUTTON 0x0040 /* System reset via push-button dongle */
#define BBC_PSRC_PWRUP 0x0080 /* System reset via power-up */
#define BBC_PSRC_FE0 0x0100 /* CPU 0 reported Fatal_Error */
#define BBC_PSRC_FE1 0x0200 /* CPU 1 reported Fatal_Error */
#define BBC_PSRC_FE2 0x0400 /* CPU 2 reported Fatal_Error */
#define BBC_PSRC_FE3 0x0800 /* CPU 3 reported Fatal_Error */
#define BBC_PSRC_FE4 0x1000 /* Schizo reported Fatal_Error */
#define BBC_PSRC_FE5 0x2000 /* Safari device 5 reported Fatal_Error */
#define BBC_PSRC_FE6 0x4000 /* CPMS reported Fatal_Error */
#define BBC_PSRC_SYNTH 0x8000 /* System reset when on-board clock synthesizers
* were updated.
*/
#define BBC_PSRC_WDT 0x10000 /* System reset via Super I/O watchdog */
#define BBC_PSRC_RSC 0x20000 /* System reset via RSC remote monitoring
* device
*/
/* XIR Source register. The source of an XIR event sent to a processor may
* be determined via this register.
*/
#define BBC_XSRC_SXG0 0x01 /* CPU 0 received XIR via Soft_XIR_GEN reg */
#define BBC_XSRC_SXG1 0x02 /* CPU 1 received XIR via Soft_XIR_GEN reg */
#define BBC_XSRC_SXG2 0x04 /* CPU 2 received XIR via Soft_XIR_GEN reg */
#define BBC_XSRC_SXG3 0x08 /* CPU 3 received XIR via Soft_XIR_GEN reg */
#define BBC_XSRC_JTAG 0x10 /* All CPUs received XIR via JTAG+ */
#define BBC_XSRC_W_OR_B 0x20 /* All CPUs received XIR either because:
* a) Super I/O watchdog fired, or
* b) XIR push button was activated
*/
#define BBC_XSRC_RESV 0xc0 /* Reserved */
/* Clock Synthesizers Control register. This register provides the big-bang
* programming interface to the two clock synthesizers of the machine.
*/
#define BBC_CSC_SLOAD 0x01 /* Directly connected to S_LOAD pins */
#define BBC_CSC_SDATA 0x02 /* Directly connected to S_DATA pins */
#define BBC_CSC_SCLOCK 0x04 /* Directly connected to S_CLOCK pins */
#define BBC_CSC_RESV 0x78 /* Reserved */
#define BBC_CSC_RST 0x80 /* Generate system reset when S_LOAD==1 */
/* Energy Star Control register. This register is used to generate the
* clock frequency change trigger to the main system devices (Schizo and
* the processors). The transition occurs when bits in this register
* go from 0 to 1, only one bit must be set at once else no action
* occurs. Basically the sequence of events is:
* a) Choose new frequency: full, 1/2 or 1/32
* b) Program this desired frequency into the cpus and Schizo.
* c) Set the same value in this register.
* d) 16 system clocks later, clear this register.
*/
#define BBC_ES_CTRL_1_1 0x01 /* Full frequency */
#define BBC_ES_CTRL_1_2 0x02 /* 1/2 frequency */
#define BBC_ES_CTRL_1_32 0x20 /* 1/32 frequency */
#define BBC_ES_RESV 0xdc /* Reserved */
/* Energy Star Assert Change Time register. This determines the number
* of BBC clock cycles (which is half the system frequency) between
* the detection of FREEZE_ACK being asserted and the assertion of
* the CLK_CHANGE_L[2:0] signals.
*/
#define BBC_ES_ACT_VAL 0xff
/* Energy Star Assert Bypass Time register. This determines the number
* of BBC clock cycles (which is half the system frequency) between
* the assertion of the CLK_CHANGE_L[2:0] signals and the assertion of
* the ESTAR_PLL_BYPASS signal.
*/
#define BBC_ES_ABT_VAL 0xffff
/* Energy Star PLL Settle Time register. This determines the number of
* BBC clock cycles (which is half the system frequency) between the
* de-assertion of CLK_CHANGE_L[2:0] and the de-assertion of the FREEZE_L
* signal.
*/
#define BBC_ES_PST_VAL 0xffffffff
/* Energy Star Frequency Switch Latency register. This is the number of
* BBC clocks between the de-assertion of CLK_CHANGE_L[2:0] and the first
* edge of the Safari clock at the new frequency.
*/
#define BBC_ES_FSL_VAL 0xffffffff
/* Keyboard Beep control register. This is a simple enabler for the audio
* beep sound.
*/
#define BBC_KBD_BEEP_ENABLE 0x01 /* Enable beep */
#define BBC_KBD_BEEP_RESV 0xfe /* Reserved */
/* Keyboard Beep Counter register. There is a free-running counter inside
* the BBC which runs at half the system clock. The bit set in this register
* determines when the audio sound is generated. So for example if bit
* 10 is set, the audio beep will oscillate at 1/(2**12). The keyboard beep
* generator automatically selects a different bit to use if the system clock
* is changed via Energy Star.
*/
#define BBC_KBD_BCNT_BITS 0x0007fc00
#define BBC_KBC_BCNT_RESV 0xfff803ff
#endif /* _SPARC64_BBC_H */
#ifndef _SPARC64_CHAFSR_H
#define _SPARC64_CHAFSR_H
/* Cheetah Asynchronous Fault Status register, ASI=0x4C VA<63:0>=0x0 */
/* Comments indicate which processor variants on which the bit definition
* is valid. Codes are:
* ch --> cheetah
* ch+ --> cheetah plus
* jp --> jalapeno
*/
/* All bits of this register except M_SYNDROME and E_SYNDROME are
* read, write 1 to clear. M_SYNDROME and E_SYNDROME are read-only.
*/
/* Software bit set by linux trap handlers to indicate that the trap was
* signalled at %tl >= 1.
*/
#define CHAFSR_TL1 (1UL << 63UL) /* n/a */
/* Unmapped error from system bus for prefetch queue or
* store queue read operation
*/
#define CHPAFSR_DTO (1UL << 59UL) /* ch+ */
/* Bus error from system bus for prefetch queue or store queue
* read operation
*/
#define CHPAFSR_DBERR (1UL << 58UL) /* ch+ */
/* Hardware corrected E-cache Tag ECC error */
#define CHPAFSR_THCE (1UL << 57UL) /* ch+ */
/* System interface protocol error, hw timeout caused */
#define JPAFSR_JETO (1UL << 57UL) /* jp */
/* SW handled correctable E-cache Tag ECC error */
#define CHPAFSR_TSCE (1UL << 56UL) /* ch+ */
/* Parity error on system snoop results */
#define JPAFSR_SCE (1UL << 56UL) /* jp */
/* Uncorrectable E-cache Tag ECC error */
#define CHPAFSR_TUE (1UL << 55UL) /* ch+ */
/* System interface protocol error, illegal command detected */
#define JPAFSR_JEIC (1UL << 55UL) /* jp */
/* Uncorrectable system bus data ECC error due to prefetch
* or store fill request
*/
#define CHPAFSR_DUE (1UL << 54UL) /* ch+ */
/* System interface protocol error, illegal ADTYPE detected */
#define JPAFSR_JEIT (1UL << 54UL) /* jp */
/* Multiple errors of the same type have occurred. This bit is set when
* an uncorrectable error or a SW correctable error occurs and the status
* bit to report that error is already set. When multiple errors of
* different types are indicated by setting multiple status bits.
*
* This bit is not set if multiple HW corrected errors with the same
* status bit occur, only uncorrectable and SW correctable ones have
* this behavior.
*
* This bit is not set when multiple ECC errors happen within a single
* 64-byte system bus transaction. Only the first ECC error in a 16-byte
* subunit will be logged. All errors in subsequent 16-byte subunits
* from the same 64-byte transaction are ignored.
*/
#define CHAFSR_ME (1UL << 53UL) /* ch,ch+,jp */
/* Privileged state error has occurred. This is a capture of PSTATE.PRIV
* at the time the error is detected.
*/
#define CHAFSR_PRIV (1UL << 52UL) /* ch,ch+,jp */
/* The following bits 51 (CHAFSR_PERR) to 33 (CHAFSR_CE) are sticky error
* bits and record the most recently detected errors. Bits accumulate
* errors that have been detected since the last write to clear the bit.
*/
/* System interface protocol error. The processor asserts its' ERROR
* pin when this event occurs and it also logs a specific cause code
* into a JTAG scannable flop.
*/
#define CHAFSR_PERR (1UL << 51UL) /* ch,ch+,jp */
/* Internal processor error. The processor asserts its' ERROR
* pin when this event occurs and it also logs a specific cause code
* into a JTAG scannable flop.
*/
#define CHAFSR_IERR (1UL << 50UL) /* ch,ch+,jp */
/* System request parity error on incoming address */
#define CHAFSR_ISAP (1UL << 49UL) /* ch,ch+,jp */
/* HW Corrected system bus MTAG ECC error */
#define CHAFSR_EMC (1UL << 48UL) /* ch,ch+ */
/* Parity error on L2 cache tag SRAM */
#define JPAFSR_ETP (1UL << 48UL) /* jp */
/* Uncorrectable system bus MTAG ECC error */
#define CHAFSR_EMU (1UL << 47UL) /* ch,ch+ */
/* Out of range memory error has occurred */
#define JPAFSR_OM (1UL << 47UL) /* jp */
/* HW Corrected system bus data ECC error for read of interrupt vector */
#define CHAFSR_IVC (1UL << 46UL) /* ch,ch+ */
/* Error due to unsupported store */
#define JPAFSR_UMS (1UL << 46UL) /* jp */
/* Uncorrectable system bus data ECC error for read of interrupt vector */
#define CHAFSR_IVU (1UL << 45UL) /* ch,ch+,jp */
/* Unmapped error from system bus */
#define CHAFSR_TO (1UL << 44UL) /* ch,ch+,jp */
/* Bus error response from system bus */
#define CHAFSR_BERR (1UL << 43UL) /* ch,ch+,jp */
/* SW Correctable E-cache ECC error for instruction fetch or data access
* other than block load.
*/
#define CHAFSR_UCC (1UL << 42UL) /* ch,ch+,jp */
/* Uncorrectable E-cache ECC error for instruction fetch or data access
* other than block load.
*/
#define CHAFSR_UCU (1UL << 41UL) /* ch,ch+,jp */
/* Copyout HW Corrected ECC error */
#define CHAFSR_CPC (1UL << 40UL) /* ch,ch+,jp */
/* Copyout Uncorrectable ECC error */
#define CHAFSR_CPU (1UL << 39UL) /* ch,ch+,jp */
/* HW Corrected ECC error from E-cache for writeback */
#define CHAFSR_WDC (1UL << 38UL) /* ch,ch+,jp */
/* Uncorrectable ECC error from E-cache for writeback */
#define CHAFSR_WDU (1UL << 37UL) /* ch,ch+,jp */
/* HW Corrected ECC error from E-cache for store merge or block load */
#define CHAFSR_EDC (1UL << 36UL) /* ch,ch+,jp */
/* Uncorrectable ECC error from E-cache for store merge or block load */
#define CHAFSR_EDU (1UL << 35UL) /* ch,ch+,jp */
/* Uncorrectable system bus data ECC error for read of memory or I/O */
#define CHAFSR_UE (1UL << 34UL) /* ch,ch+,jp */
/* HW Corrected system bus data ECC error for read of memory or I/O */
#define CHAFSR_CE (1UL << 33UL) /* ch,ch+,jp */
/* Uncorrectable ECC error from remote cache/memory */
#define JPAFSR_RUE (1UL << 32UL) /* jp */
/* Correctable ECC error from remote cache/memory */
#define JPAFSR_RCE (1UL << 31UL) /* jp */
/* JBUS parity error on returned read data */
#define JPAFSR_BP (1UL << 30UL) /* jp */
/* JBUS parity error on data for writeback or block store */
#define JPAFSR_WBP (1UL << 29UL) /* jp */
/* Foreign read to DRAM incurring correctable ECC error */
#define JPAFSR_FRC (1UL << 28UL) /* jp */
/* Foreign read to DRAM incurring uncorrectable ECC error */
#define JPAFSR_FRU (1UL << 27UL) /* jp */
#define CHAFSR_ERRORS (CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP | CHAFSR_EMC | \
CHAFSR_EMU | CHAFSR_IVC | CHAFSR_IVU | CHAFSR_TO | \
CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | CHAFSR_CPC | \
CHAFSR_CPU | CHAFSR_WDC | CHAFSR_WDU | CHAFSR_EDC | \
CHAFSR_EDU | CHAFSR_UE | CHAFSR_CE)
#define CHPAFSR_ERRORS (CHPAFSR_DTO | CHPAFSR_DBERR | CHPAFSR_THCE | \
CHPAFSR_TSCE | CHPAFSR_TUE | CHPAFSR_DUE | \
CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP | CHAFSR_EMC | \
CHAFSR_EMU | CHAFSR_IVC | CHAFSR_IVU | CHAFSR_TO | \
CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | CHAFSR_CPC | \
CHAFSR_CPU | CHAFSR_WDC | CHAFSR_WDU | CHAFSR_EDC | \
CHAFSR_EDU | CHAFSR_UE | CHAFSR_CE)
#define JPAFSR_ERRORS (JPAFSR_JETO | JPAFSR_SCE | JPAFSR_JEIC | \
JPAFSR_JEIT | CHAFSR_PERR | CHAFSR_IERR | \
CHAFSR_ISAP | JPAFSR_ETP | JPAFSR_OM | \
JPAFSR_UMS | CHAFSR_IVU | CHAFSR_TO | \
CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | \
CHAFSR_CPC | CHAFSR_CPU | CHAFSR_WDC | \
CHAFSR_WDU | CHAFSR_EDC | CHAFSR_EDU | \
CHAFSR_UE | CHAFSR_CE | JPAFSR_RUE | \
JPAFSR_RCE | JPAFSR_BP | JPAFSR_WBP | \
JPAFSR_FRC | JPAFSR_FRU)
/* Active JBUS request signal when error occurred */
#define JPAFSR_JBREQ (0x7UL << 24UL) /* jp */
#define JPAFSR_JBREQ_SHIFT 24UL
/* L2 cache way information */
#define JPAFSR_ETW (0x3UL << 22UL) /* jp */
#define JPAFSR_ETW_SHIFT 22UL
/* System bus MTAG ECC syndrome. This field captures the status of the
* first occurrence of the highest-priority error according to the M_SYND
* overwrite policy. After the AFSR sticky bit, corresponding to the error
* for which the M_SYND is reported, is cleared, the contents of the M_SYND
* field will be unchanged by will be unfrozen for further error capture.
*/
#define CHAFSR_M_SYNDROME (0xfUL << 16UL) /* ch,ch+,jp */
#define CHAFSR_M_SYNDROME_SHIFT 16UL
/* Agenid Id of the foreign device causing the UE/CE errors */
#define JPAFSR_AID (0x1fUL << 9UL) /* jp */
#define JPAFSR_AID_SHIFT 9UL
/* System bus or E-cache data ECC syndrome. This field captures the status
* of the first occurrence of the highest-priority error according to the
* E_SYND overwrite policy. After the AFSR sticky bit, corresponding to the
* error for which the E_SYND is reported, is cleare, the contents of the E_SYND
* field will be unchanged but will be unfrozen for further error capture.
*/
#define CHAFSR_E_SYNDROME (0x1ffUL << 0UL) /* ch,ch+,jp */
#define CHAFSR_E_SYNDROME_SHIFT 0UL
/* The AFSR must be explicitly cleared by software, it is not cleared automatically
* by a read. Writes to bits <51:33> with bits set will clear the corresponding
* bits in the AFSR. Bits associated with disrupting traps must be cleared before
* interrupts are re-enabled to prevent multiple traps for the same error. I.e.
* PSTATE.IE and AFSR bits control delivery of disrupting traps.
*
* Since there is only one AFAR, when multiple events have been logged by the
* bits in the AFSR, at most one of these events will have its status captured
* in the AFAR. The highest priority of those event bits will get AFAR logging.
* The AFAR will be unlocked and available to capture the address of another event
* as soon as the one bit in AFSR that corresponds to the event logged in AFAR is
* cleared. For example, if AFSR.CE is detected, then AFSR.UE (which overwrites
* the AFAR), and AFSR.UE is cleared by not AFSR.CE, then the AFAR will be unlocked
* and ready for another event, even though AFSR.CE is still set. The same rules
* also apply to the M_SYNDROME and E_SYNDROME fields of the AFSR.
*/
#endif /* _SPARC64_CHAFSR_H */
#ifndef _SPARC64_CHMCTRL_H
#define _SPARC64_CHMCTRL_H
/* Cheetah memory controller programmable registers. */
#define CHMCTRL_TCTRL1 0x00 /* Memory Timing Control I */
#define CHMCTRL_TCTRL2 0x08 /* Memory Timing Control II */
#define CHMCTRL_TCTRL3 0x38 /* Memory Timing Control III */
#define CHMCTRL_TCTRL4 0x40 /* Memory Timing Control IV */
#define CHMCTRL_DECODE1 0x10 /* Memory Address Decode I */
#define CHMCTRL_DECODE2 0x18 /* Memory Address Decode II */
#define CHMCTRL_DECODE3 0x20 /* Memory Address Decode III */
#define CHMCTRL_DECODE4 0x28 /* Memory Address Decode IV */
#define CHMCTRL_MACTRL 0x30 /* Memory Address Control */
/* Memory Timing Control I */
#define TCTRL1_SDRAMCTL_DLY 0xf000000000000000UL
#define TCTRL1_SDRAMCTL_DLY_SHIFT 60
#define TCTRL1_SDRAMCLK_DLY 0x0e00000000000000UL
#define TCTRL1_SDRAMCLK_DLY_SHIFT 57
#define TCTRL1_R 0x0100000000000000UL
#define TCTRL1_R_SHIFT 56
#define TCTRL1_AUTORFR_CYCLE 0x00fe000000000000UL
#define TCTRL1_AUTORFR_CYCLE_SHIFT 49
#define TCTRL1_RD_WAIT 0x0001f00000000000UL
#define TCTRL1_RD_WAIT_SHIFT 44
#define TCTRL1_PC_CYCLE 0x00000fc000000000UL
#define TCTRL1_PC_CYCLE_SHIFT 38
#define TCTRL1_WR_MORE_RAS_PW 0x0000003f00000000UL
#define TCTRL1_WR_MORE_RAS_PW_SHIFT 32
#define TCTRL1_RD_MORE_RAW_PW 0x00000000fc000000UL
#define TCTRL1_RD_MORE_RAS_PW_SHIFT 26
#define TCTRL1_ACT_WR_DLY 0x0000000003f00000UL
#define TCTRL1_ACT_WR_DLY_SHIFT 20
#define TCTRL1_ACT_RD_DLY 0x00000000000fc000UL
#define TCTRL1_ACT_RD_DLY_SHIFT 14
#define TCTRL1_BANK_PRESENT 0x0000000000003000UL
#define TCTRL1_BANK_PRESENT_SHIFT 12
#define TCTRL1_RFR_INT 0x0000000000000ff8UL
#define TCTRL1_RFR_INT_SHIFT 3
#define TCTRL1_SET_MODE_REG 0x0000000000000004UL
#define TCTRL1_SET_MODE_REG_SHIFT 2
#define TCTRL1_RFR_ENABLE 0x0000000000000002UL
#define TCTRL1_RFR_ENABLE_SHIFT 1
#define TCTRL1_PRECHG_ALL 0x0000000000000001UL
#define TCTRL1_PRECHG_ALL_SHIFT 0
/* Memory Timing Control II */
#define TCTRL2_WR_MSEL_DLY 0xfc00000000000000UL
#define TCTRL2_WR_MSEL_DLY_SHIFT 58
#define TCTRL2_RD_MSEL_DLY 0x03f0000000000000UL
#define TCTRL2_RD_MSEL_DLY_SHIFT 52
#define TCTRL2_WRDATA_THLD 0x000c000000000000UL
#define TCTRL2_WRDATA_THLD_SHIFT 50
#define TCTRL2_RDWR_RD_TI_DLY 0x0003f00000000000UL
#define TCTRL2_RDWR_RD_TI_DLY_SHIFT 44
#define TCTRL2_AUTOPRECHG_ENBL 0x0000080000000000UL
#define TCTRL2_AUTOPRECHG_ENBL_SHIFT 43
#define TCTRL2_RDWR_PI_MORE_DLY 0x000007c000000000UL
#define TCTRL2_RDWR_PI_MORE_DLY_SHIFT 38
#define TCTRL2_RDWR_1_DLY 0x0000003f00000000UL
#define TCTRL2_RDWR_1_DLY_SHIFT 32
#define TCTRL2_WRWR_PI_MORE_DLY 0x00000000f8000000UL
#define TCTRL2_WRWR_PI_MORE_DLY_SHIFT 27
#define TCTRL2_WRWR_1_DLY 0x0000000007e00000UL
#define TCTRL2_WRWR_1_DLY_SHIFT 21
#define TCTRL2_RDWR_RD_PI_MORE_DLY 0x00000000001f0000UL
#define TCTRL2_RDWR_RD_PI_MORE_DLY_SHIFT 16
#define TCTRL2_R 0x0000000000008000UL
#define TCTRL2_R_SHIFT 15
#define TCTRL2_SDRAM_MODE_REG_DATA 0x0000000000007fffUL
#define TCTRL2_SDRAM_MODE_REG_DATA_SHIFT 0
/* Memory Timing Control III */
#define TCTRL3_SDRAM_CTL_DLY 0xf000000000000000UL
#define TCTRL3_SDRAM_CTL_DLY_SHIFT 60
#define TCTRL3_SDRAM_CLK_DLY 0x0e00000000000000UL
#define TCTRL3_SDRAM_CLK_DLY_SHIFT 57
#define TCTRL3_R 0x0100000000000000UL
#define TCTRL3_R_SHIFT 56
#define TCTRL3_AUTO_RFR_CYCLE 0x00fe000000000000UL
#define TCTRL3_AUTO_RFR_CYCLE_SHIFT 49
#define TCTRL3_RD_WAIT 0x0001f00000000000UL
#define TCTRL3_RD_WAIT_SHIFT 44
#define TCTRL3_PC_CYCLE 0x00000fc000000000UL
#define TCTRL3_PC_CYCLE_SHIFT 38
#define TCTRL3_WR_MORE_RAW_PW 0x0000003f00000000UL
#define TCTRL3_WR_MORE_RAW_PW_SHIFT 32
#define TCTRL3_RD_MORE_RAW_PW 0x00000000fc000000UL
#define TCTRL3_RD_MORE_RAW_PW_SHIFT 26
#define TCTRL3_ACT_WR_DLY 0x0000000003f00000UL
#define TCTRL3_ACT_WR_DLY_SHIFT 20
#define TCTRL3_ACT_RD_DLY 0x00000000000fc000UL
#define TCTRL3_ACT_RD_DLY_SHIFT 14
#define TCTRL3_BANK_PRESENT 0x0000000000003000UL
#define TCTRL3_BANK_PRESENT_SHIFT 12
#define TCTRL3_RFR_INT 0x0000000000000ff8UL
#define TCTRL3_RFR_INT_SHIFT 3
#define TCTRL3_SET_MODE_REG 0x0000000000000004UL
#define TCTRL3_SET_MODE_REG_SHIFT 2
#define TCTRL3_RFR_ENABLE 0x0000000000000002UL
#define TCTRL3_RFR_ENABLE_SHIFT 1
#define TCTRL3_PRECHG_ALL 0x0000000000000001UL
#define TCTRL3_PRECHG_ALL_SHIFT 0
/* Memory Timing Control IV */
#define TCTRL4_WR_MSEL_DLY 0xfc00000000000000UL
#define TCTRL4_WR_MSEL_DLY_SHIFT 58
#define TCTRL4_RD_MSEL_DLY 0x03f0000000000000UL
#define TCTRL4_RD_MSEL_DLY_SHIFT 52
#define TCTRL4_WRDATA_THLD 0x000c000000000000UL
#define TCTRL4_WRDATA_THLD_SHIFT 50
#define TCTRL4_RDWR_RD_RI_DLY 0x0003f00000000000UL
#define TCTRL4_RDWR_RD_RI_DLY_SHIFT 44
#define TCTRL4_AUTO_PRECHG_ENBL 0x0000080000000000UL
#define TCTRL4_AUTO_PRECHG_ENBL_SHIFT 43
#define TCTRL4_RD_WR_PI_MORE_DLY 0x000007c000000000UL
#define TCTRL4_RD_WR_PI_MORE_DLY_SHIFT 38
#define TCTRL4_RD_WR_TI_DLY 0x0000003f00000000UL
#define TCTRL4_RD_WR_TI_DLY_SHIFT 32
#define TCTRL4_WR_WR_PI_MORE_DLY 0x00000000f8000000UL
#define TCTRL4_WR_WR_PI_MORE_DLY_SHIFT 27
#define TCTRL4_WR_WR_TI_DLY 0x0000000007e00000UL
#define TCTRL4_WR_WR_TI_DLY_SHIFT 21
#define TCTRL4_RDWR_RD_PI_MORE_DLY 0x00000000001f000UL0
#define TCTRL4_RDWR_RD_PI_MORE_DLY_SHIFT 16
#define TCTRL4_R 0x0000000000008000UL
#define TCTRL4_R_SHIFT 15
#define TCTRL4_SDRAM_MODE_REG_DATA 0x0000000000007fffUL
#define TCTRL4_SDRAM_MODE_REG_DATA_SHIFT 0
/* All 4 memory address decoding registers have the
* same layout.
*/
#define MEM_DECODE_VALID 0x8000000000000000UL /* Valid */
#define MEM_DECODE_VALID_SHIFT 63
#define MEM_DECODE_UK 0x001ffe0000000000UL /* Upper mask */
#define MEM_DECODE_UK_SHIFT 41
#define MEM_DECODE_UM 0x0000001ffff00000UL /* Upper match */
#define MEM_DECODE_UM_SHIFT 20
#define MEM_DECODE_LK 0x000000000003c000UL /* Lower mask */
#define MEM_DECODE_LK_SHIFT 14
#define MEM_DECODE_LM 0x0000000000000f00UL /* Lower match */
#define MEM_DECODE_LM_SHIFT 8
#define PA_UPPER_BITS 0x000007fffc000000UL
#define PA_UPPER_BITS_SHIFT 26
#define PA_LOWER_BITS 0x00000000000003c0UL
#define PA_LOWER_BITS_SHIFT 6
#define MACTRL_R0 0x8000000000000000UL
#define MACTRL_R0_SHIFT 63
#define MACTRL_ADDR_LE_PW 0x7000000000000000UL
#define MACTRL_ADDR_LE_PW_SHIFT 60
#define MACTRL_CMD_PW 0x0f00000000000000UL
#define MACTRL_CMD_PW_SHIFT 56
#define MACTRL_HALF_MODE_WR_MSEL_DLY 0x00fc000000000000UL
#define MACTRL_HALF_MODE_WR_MSEL_DLY_SHIFT 50
#define MACTRL_HALF_MODE_RD_MSEL_DLY 0x0003f00000000000UL
#define MACTRL_HALF_MODE_RD_MSEL_DLY_SHIFT 44
#define MACTRL_HALF_MODE_SDRAM_CTL_DLY 0x00000f0000000000UL
#define MACTRL_HALF_MODE_SDRAM_CTL_DLY_SHIFT 40
#define MACTRL_HALF_MODE_SDRAM_CLK_DLY 0x000000e000000000UL
#define MACTRL_HALF_MODE_SDRAM_CLK_DLY_SHIFT 37
#define MACTRL_R1 0x0000001000000000UL
#define MACTRL_R1_SHIFT 36
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B3 0x0000000f00000000UL
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B3_SHIFT 32
#define MACTRL_ENC_INTLV_B3 0x00000000f8000000UL
#define MACTRL_ENC_INTLV_B3_SHIFT 27
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B2 0x0000000007800000UL
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B2_SHIFT 23
#define MACTRL_ENC_INTLV_B2 0x00000000007c0000UL
#define MACTRL_ENC_INTLV_B2_SHIFT 18
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B1 0x000000000003c000UL
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B1_SHIFT 14
#define MACTRL_ENC_INTLV_B1 0x0000000000003e00UL
#define MACTRL_ENC_INTLV_B1_SHIFT 9
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B0 0x00000000000001e0UL
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B0_SHIFT 5
#define MACTRL_ENC_INTLV_B0 0x000000000000001fUL
#define MACTRL_ENC_INTLV_B0_SHIFT 0
#endif /* _SPARC64_CHMCTRL_H */
#ifndef _SPARC64_CMT_H
#define _SPARC64_CMT_H
/* cmt.h: Chip Multi-Threading register definitions
*
* Copyright (C) 2004 David S. Miller (davem@redhat.com)
*/
/* ASI_CORE_ID - private */
#define LP_ID 0x0000000000000010UL
#define LP_ID_MAX 0x00000000003f0000UL
#define LP_ID_ID 0x000000000000003fUL
/* ASI_INTR_ID - private */
#define LP_INTR_ID 0x0000000000000000UL
#define LP_INTR_ID_ID 0x00000000000003ffUL
/* ASI_CESR_ID - private */
#define CESR_ID 0x0000000000000040UL
#define CESR_ID_ID 0x00000000000000ffUL
/* ASI_CORE_AVAILABLE - shared */
#define LP_AVAIL 0x0000000000000000UL
#define LP_AVAIL_1 0x0000000000000002UL
#define LP_AVAIL_0 0x0000000000000001UL
/* ASI_CORE_ENABLE_STATUS - shared */
#define LP_ENAB_STAT 0x0000000000000010UL
#define LP_ENAB_STAT_1 0x0000000000000002UL
#define LP_ENAB_STAT_0 0x0000000000000001UL
/* ASI_CORE_ENABLE - shared */
#define LP_ENAB 0x0000000000000020UL
#define LP_ENAB_1 0x0000000000000002UL
#define LP_ENAB_0 0x0000000000000001UL
/* ASI_CORE_RUNNING - shared */
#define LP_RUNNING_RW 0x0000000000000050UL
#define LP_RUNNING_W1S 0x0000000000000060UL
#define LP_RUNNING_W1C 0x0000000000000068UL
#define LP_RUNNING_1 0x0000000000000002UL
#define LP_RUNNING_0 0x0000000000000001UL
/* ASI_CORE_RUNNING_STAT - shared */
#define LP_RUN_STAT 0x0000000000000058UL
#define LP_RUN_STAT_1 0x0000000000000002UL
#define LP_RUN_STAT_0 0x0000000000000001UL
/* ASI_XIR_STEERING - shared */
#define LP_XIR_STEER 0x0000000000000030UL
#define LP_XIR_STEER_1 0x0000000000000002UL
#define LP_XIR_STEER_0 0x0000000000000001UL
/* ASI_CMT_ERROR_STEERING - shared */
#define CMT_ER_STEER 0x0000000000000040UL
#define CMT_ER_STEER_1 0x0000000000000002UL
#define CMT_ER_STEER_0 0x0000000000000001UL
#endif /* _SPARC64_CMT_H */
#ifndef _ASM_SPARC64_COMPAT_H
#define _ASM_SPARC64_COMPAT_H
/*
* Architecture specific compatibility types
*/
#include <linux/types.h>
#define COMPAT_USER_HZ 100
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
typedef s32 compat_time_t;
typedef s32 compat_clock_t;
typedef s32 compat_pid_t;
typedef u16 __compat_uid_t;
typedef u16 __compat_gid_t;
typedef u32 __compat_uid32_t;
typedef u32 __compat_gid32_t;
typedef u16 compat_mode_t;
typedef u32 compat_ino_t;
typedef u16 compat_dev_t;
typedef s32 compat_off_t;
typedef s64 compat_loff_t;
typedef s16 compat_nlink_t;
typedef u16 compat_ipc_pid_t;
typedef s32 compat_daddr_t;
typedef u32 compat_caddr_t;
typedef __kernel_fsid_t compat_fsid_t;
typedef s32 compat_key_t;
typedef s32 compat_timer_t;
typedef s32 compat_int_t;
typedef s32 compat_long_t;
typedef s64 compat_s64;
typedef u32 compat_uint_t;
typedef u32 compat_ulong_t;
typedef u64 compat_u64;
struct compat_timespec {
compat_time_t tv_sec;
s32 tv_nsec;
};
struct compat_timeval {
compat_time_t tv_sec;
s32 tv_usec;
};
struct compat_stat {
compat_dev_t st_dev;
compat_ino_t st_ino;
compat_mode_t st_mode;
compat_nlink_t st_nlink;
__compat_uid_t st_uid;
__compat_gid_t st_gid;
compat_dev_t st_rdev;
compat_off_t st_size;
compat_time_t st_atime;
compat_ulong_t st_atime_nsec;
compat_time_t st_mtime;
compat_ulong_t st_mtime_nsec;
compat_time_t st_ctime;
compat_ulong_t st_ctime_nsec;
compat_off_t st_blksize;
compat_off_t st_blocks;
u32 __unused4[2];
};
struct compat_stat64 {
unsigned long long st_dev;
unsigned long long st_ino;
unsigned int st_mode;
unsigned int st_nlink;
unsigned int st_uid;
unsigned int st_gid;
unsigned long long st_rdev;
unsigned char __pad3[8];
long long st_size;
unsigned int st_blksize;
unsigned char __pad4[8];
unsigned int st_blocks;
unsigned int st_atime;
unsigned int st_atime_nsec;
unsigned int st_mtime;
unsigned int st_mtime_nsec;
unsigned int st_ctime;
unsigned int st_ctime_nsec;
unsigned int __unused4;
unsigned int __unused5;
};
struct compat_flock {
short l_type;
short l_whence;
compat_off_t l_start;
compat_off_t l_len;
compat_pid_t l_pid;
short __unused;
};
#define F_GETLK64 12
#define F_SETLK64 13
#define F_SETLKW64 14
struct compat_flock64 {
short l_type;
short l_whence;
compat_loff_t l_start;
compat_loff_t l_len;
compat_pid_t l_pid;
short __unused;
};
struct compat_statfs {
int f_type;
int f_bsize;
int f_blocks;
int f_bfree;
int f_bavail;
int f_files;
int f_ffree;
compat_fsid_t f_fsid;
int f_namelen; /* SunOS ignores this field. */
int f_frsize;
int f_spare[5];
};
#define COMPAT_RLIM_INFINITY 0x7fffffff
typedef u32 compat_old_sigset_t;
#define _COMPAT_NSIG 64
#define _COMPAT_NSIG_BPW 32
typedef u32 compat_sigset_word;
#define COMPAT_OFF_T_MAX 0x7fffffff
#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
/*
* A pointer passed in from user mode. This should not
* be used for syscall parameters, just declare them
* as pointers because the syscall entry code will have
* appropriately converted them already.
*/
typedef u32 compat_uptr_t;
static inline void __user *compat_ptr(compat_uptr_t uptr)
{
return (void __user *)(unsigned long)uptr;
}
static inline compat_uptr_t ptr_to_compat(void __user *uptr)
{
return (u32)(unsigned long)uptr;
}
static inline void __user *compat_alloc_user_space(long len)
{
struct pt_regs *regs = current_thread_info()->kregs;
unsigned long usp = regs->u_regs[UREG_I6];
if (!(test_thread_flag(TIF_32BIT)))
usp += STACK_BIAS;
else
usp &= 0xffffffffUL;
usp -= len;
usp &= ~0x7UL;
return (void __user *) usp;
}
struct compat_ipc64_perm {
compat_key_t key;
__compat_uid32_t uid;
__compat_gid32_t gid;
__compat_uid32_t cuid;
__compat_gid32_t cgid;
unsigned short __pad1;
compat_mode_t mode;
unsigned short __pad2;
unsigned short seq;
unsigned long __unused1; /* yes they really are 64bit pads */
unsigned long __unused2;
};
struct compat_semid64_ds {
struct compat_ipc64_perm sem_perm;
unsigned int __pad1;
compat_time_t sem_otime;
unsigned int __pad2;
compat_time_t sem_ctime;
u32 sem_nsems;
u32 __unused1;
u32 __unused2;
};
struct compat_msqid64_ds {
struct compat_ipc64_perm msg_perm;
unsigned int __pad1;
compat_time_t msg_stime;
unsigned int __pad2;
compat_time_t msg_rtime;
unsigned int __pad3;
compat_time_t msg_ctime;
unsigned int msg_cbytes;
unsigned int msg_qnum;
unsigned int msg_qbytes;
compat_pid_t msg_lspid;
compat_pid_t msg_lrpid;
unsigned int __unused1;
unsigned int __unused2;
};
struct compat_shmid64_ds {
struct compat_ipc64_perm shm_perm;
unsigned int __pad1;
compat_time_t shm_atime;
unsigned int __pad2;
compat_time_t shm_dtime;
unsigned int __pad3;
compat_time_t shm_ctime;
compat_size_t shm_segsz;
compat_pid_t shm_cpid;
compat_pid_t shm_lpid;
unsigned int shm_nattch;
unsigned int __unused1;
unsigned int __unused2;
};
#endif /* _ASM_SPARC64_COMPAT_H */
#ifndef _COMPAT_SIGNAL_H
#define _COMPAT_SIGNAL_H
#include <linux/compat.h>
#include <asm/signal.h>
#ifdef CONFIG_COMPAT
struct __new_sigaction32 {
unsigned sa_handler;
unsigned int sa_flags;
unsigned sa_restorer; /* not used by Linux/SPARC yet */
compat_sigset_t sa_mask;
};
struct __old_sigaction32 {
unsigned sa_handler;
compat_old_sigset_t sa_mask;
unsigned int sa_flags;
unsigned sa_restorer; /* not used by Linux/SPARC yet */
};
typedef struct sigaltstack32 {
u32 ss_sp;
int ss_flags;
compat_size_t ss_size;
} stack_t32;
#endif
#endif /* !(_COMPAT_SIGNAL_H) */
#ifndef _SPARC64_DCR_H
#define _SPARC64_DCR_H
/* UltraSparc-III/III+ Dispatch Control Register, ASR 0x12 */
#define DCR_DPE 0x0000000000001000 /* III+: D$ Parity Error Enable */
#define DCR_OBS 0x0000000000000fc0 /* Observability Bus Controls */
#define DCR_BPE 0x0000000000000020 /* Branch Predict Enable */
#define DCR_RPE 0x0000000000000010 /* Return Address Prediction Enable */
#define DCR_SI 0x0000000000000008 /* Single Instruction Disable */
#define DCR_IPE 0x0000000000000004 /* III+: I$ Parity Error Enable */
#define DCR_IFPOE 0x0000000000000002 /* IRQ FP Operation Enable */
#define DCR_MS 0x0000000000000001 /* Multi-Scalar dispatch */
#endif /* _SPARC64_DCR_H */
#ifndef _SPARC64_DCU_H
#define _SPARC64_DCU_H
#include <linux/const.h>
/* UltraSparc-III Data Cache Unit Control Register */
#define DCU_CP _AC(0x0002000000000000,UL) /* Phys Cache Enable w/o mmu */
#define DCU_CV _AC(0x0001000000000000,UL) /* Virt Cache Enable w/o mmu */
#define DCU_ME _AC(0x0000800000000000,UL) /* NC-store Merging Enable */
#define DCU_RE _AC(0x0000400000000000,UL) /* RAW bypass Enable */
#define DCU_PE _AC(0x0000200000000000,UL) /* PCache Enable */
#define DCU_HPE _AC(0x0000100000000000,UL) /* HW prefetch Enable */
#define DCU_SPE _AC(0x0000080000000000,UL) /* SW prefetch Enable */
#define DCU_SL _AC(0x0000040000000000,UL) /* Secondary ld-steering Enab*/
#define DCU_WE _AC(0x0000020000000000,UL) /* WCache enable */
#define DCU_PM _AC(0x000001fe00000000,UL) /* PA Watchpoint Byte Mask */
#define DCU_VM _AC(0x00000001fe000000,UL) /* VA Watchpoint Byte Mask */
#define DCU_PR _AC(0x0000000001000000,UL) /* PA Watchpoint Read Enable */
#define DCU_PW _AC(0x0000000000800000,UL) /* PA Watchpoint Write Enable*/
#define DCU_VR _AC(0x0000000000400000,UL) /* VA Watchpoint Read Enable */
#define DCU_VW _AC(0x0000000000200000,UL) /* VA Watchpoint Write Enable*/
#define DCU_DM _AC(0x0000000000000008,UL) /* DMMU Enable */
#define DCU_IM _AC(0x0000000000000004,UL) /* IMMU Enable */
#define DCU_DC _AC(0x0000000000000002,UL) /* Data Cache Enable */
#define DCU_IC _AC(0x0000000000000001,UL) /* Instruction Cache Enable */
#endif /* _SPARC64_DCU_H */
#ifndef _SPARC64_ESTATE_H
#define _SPARC64_ESTATE_H
/* UltraSPARC-III E-cache Error Enable */
#define ESTATE_ERROR_FMT 0x0000000000040000 /* Force MTAG ECC */
#define ESTATE_ERROR_FMESS 0x000000000003c000 /* Forced MTAG ECC val */
#define ESTATE_ERROR_FMD 0x0000000000002000 /* Force DATA ECC */
#define ESTATE_ERROR_FDECC 0x0000000000001ff0 /* Forced DATA ECC val */
#define ESTATE_ERROR_UCEEN 0x0000000000000008 /* See below */
#define ESTATE_ERROR_NCEEN 0x0000000000000002 /* See below */
#define ESTATE_ERROR_CEEN 0x0000000000000001 /* See below */
/* UCEEN enables the fast_ECC_error trap for: 1) software correctable E-cache
* errors 2) uncorrectable E-cache errors. Such events only occur on reads
* of the E-cache by the local processor for: 1) data loads 2) instruction
* fetches 3) atomic operations. Such events _cannot_ occur for: 1) merge
* 2) writeback 2) copyout. The AFSR bits associated with these traps are
* UCC and UCU.
*/
/* NCEEN enables instruction_access_error, data_access_error, and ECC_error traps
* for uncorrectable ECC errors and system errors.
*
* Uncorrectable system bus data error or MTAG ECC error, system bus TimeOUT,
* or system bus BusERR:
* 1) As the result of an instruction fetch, will generate instruction_access_error
* 2) As the result of a load etc. will generate data_access_error.
* 3) As the result of store merge completion, writeback, or copyout will
* generate a disrupting ECC_error trap.
* 4) As the result of such errors on instruction vector fetch can generate any
* of the 3 trap types.
*
* The AFSR bits associated with these traps are EMU, EDU, WDU, CPU, IVU, UE,
* BERR, and TO.
*/
/* CEEN enables the ECC_error trap for hardware corrected ECC errors. System bus
* reads resulting in a hardware corrected data or MTAG ECC error will generate an
* ECC_error disrupting trap with this bit enabled.
*
* This same trap will also be generated when a hardware corrected ECC error results
* during store merge, writeback, and copyout operations.
*/
/* In general, if the trap enable bits above are disabled the AFSR bits will still
* log the events even though the trap will not be generated by the processor.
*/
#endif /* _SPARC64_ESTATE_H */
/*
* fhc.h: Structures for central/fhc pseudo driver on Sunfire/Starfire/Wildfire.
*
* Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com)
*/
#ifndef _SPARC64_FHC_H
#define _SPARC64_FHC_H
#include <linux/timer.h>
#include <asm/oplib.h>
#include <asm/prom.h>
#include <asm/upa.h>
struct linux_fhc;
/* Clock board register offsets. */
#define CLOCK_CTRL 0x00UL /* Main control */
#define CLOCK_STAT1 0x10UL /* Status one */
#define CLOCK_STAT2 0x20UL /* Status two */
#define CLOCK_PWRSTAT 0x30UL /* Power status */
#define CLOCK_PWRPRES 0x40UL /* Power presence */
#define CLOCK_TEMP 0x50UL /* Temperature */
#define CLOCK_IRQDIAG 0x60UL /* IRQ diagnostics */
#define CLOCK_PWRSTAT2 0x70UL /* Power status two */
#define CLOCK_CTRL_LLED 0x04 /* Left LED, 0 == on */
#define CLOCK_CTRL_MLED 0x02 /* Mid LED, 1 == on */
#define CLOCK_CTRL_RLED 0x01 /* RIght LED, 1 == on */
struct linux_central {
struct linux_fhc *child;
unsigned long cfreg;
unsigned long clkregs;
unsigned long clkver;
int slots;
struct device_node *prom_node;
struct linux_prom_ranges central_ranges[PROMREG_MAX];
int num_central_ranges;
};
/* Firehose controller register offsets */
struct fhc_regs {
unsigned long pregs; /* FHC internal regs */
#define FHC_PREGS_ID 0x00UL /* FHC ID */
#define FHC_ID_VERS 0xf0000000 /* Version of this FHC */
#define FHC_ID_PARTID 0x0ffff000 /* Part ID code (0x0f9f == FHC) */
#define FHC_ID_MANUF 0x0000007e /* Manufacturer (0x3e == SUN's JEDEC)*/
#define FHC_ID_RESV 0x00000001 /* Read as one */
#define FHC_PREGS_RCS 0x10UL /* FHC Reset Control/Status Register */
#define FHC_RCS_POR 0x80000000 /* Last reset was a power cycle */
#define FHC_RCS_SPOR 0x40000000 /* Last reset was sw power on reset */
#define FHC_RCS_SXIR 0x20000000 /* Last reset was sw XIR reset */
#define FHC_RCS_BPOR 0x10000000 /* Last reset was due to POR button */
#define FHC_RCS_BXIR 0x08000000 /* Last reset was due to XIR button */
#define FHC_RCS_WEVENT 0x04000000 /* CPU reset was due to wakeup event */
#define FHC_RCS_CFATAL 0x02000000 /* Centerplane Fatal Error signalled */
#define FHC_RCS_FENAB 0x01000000 /* Fatal errors elicit system reset */
#define FHC_PREGS_CTRL 0x20UL /* FHC Control Register */
#define FHC_CONTROL_ICS 0x00100000 /* Ignore Centerplane Signals */
#define FHC_CONTROL_FRST 0x00080000 /* Fatal Error Reset Enable */
#define FHC_CONTROL_LFAT 0x00040000 /* AC/DC signalled a local error */
#define FHC_CONTROL_SLINE 0x00010000 /* Firmware Synchronization Line */
#define FHC_CONTROL_DCD 0x00008000 /* DC-->DC Converter Disable */
#define FHC_CONTROL_POFF 0x00004000 /* AC/DC Controller PLL Disable */
#define FHC_CONTROL_FOFF 0x00002000 /* FHC Controller PLL Disable */
#define FHC_CONTROL_AOFF 0x00001000 /* CPU A SRAM/SBD Low Power Mode */
#define FHC_CONTROL_BOFF 0x00000800 /* CPU B SRAM/SBD Low Power Mode */
#define FHC_CONTROL_PSOFF 0x00000400 /* Turns off this FHC's power supply */
#define FHC_CONTROL_IXIST 0x00000200 /* 0=FHC tells clock board it exists */
#define FHC_CONTROL_XMSTR 0x00000100 /* 1=Causes this FHC to be XIR master*/
#define FHC_CONTROL_LLED 0x00000040 /* 0=Left LED ON */
#define FHC_CONTROL_MLED 0x00000020 /* 1=Middle LED ON */
#define FHC_CONTROL_RLED 0x00000010 /* 1=Right LED */
#define FHC_CONTROL_BPINS 0x00000003 /* Spare Bidirectional Pins */
#define FHC_PREGS_BSR 0x30UL /* FHC Board Status Register */
#define FHC_BSR_DA64 0x00040000 /* Port A: 0=128bit 1=64bit data path */
#define FHC_BSR_DB64 0x00020000 /* Port B: 0=128bit 1=64bit data path */
#define FHC_BSR_BID 0x0001e000 /* Board ID */
#define FHC_BSR_SA 0x00001c00 /* Port A UPA Speed (from the pins) */
#define FHC_BSR_SB 0x00000380 /* Port B UPA Speed (from the pins) */
#define FHC_BSR_NDIAG 0x00000040 /* Not in Diag Mode */
#define FHC_BSR_NTBED 0x00000020 /* Not in TestBED Mode */
#define FHC_BSR_NIA 0x0000001c /* Jumper, bit 18 in PROM space */
#define FHC_BSR_SI 0x00000001 /* Spare input pin value */
#define FHC_PREGS_ECC 0x40UL /* FHC ECC Control Register (16 bits) */
#define FHC_PREGS_JCTRL 0xf0UL /* FHC JTAG Control Register */
#define FHC_JTAG_CTRL_MENAB 0x80000000 /* Indicates this is JTAG Master */
#define FHC_JTAG_CTRL_MNONE 0x40000000 /* Indicates no JTAG Master present */
#define FHC_PREGS_JCMD 0x100UL /* FHC JTAG Command Register */
unsigned long ireg; /* FHC IGN reg */
#define FHC_IREG_IGN 0x00UL /* This FHC's IGN */
unsigned long ffregs; /* FHC fanfail regs */
#define FHC_FFREGS_IMAP 0x00UL /* FHC Fanfail IMAP */
#define FHC_FFREGS_ICLR 0x10UL /* FHC Fanfail ICLR */
unsigned long sregs; /* FHC system regs */
#define FHC_SREGS_IMAP 0x00UL /* FHC System IMAP */
#define FHC_SREGS_ICLR 0x10UL /* FHC System ICLR */
unsigned long uregs; /* FHC uart regs */
#define FHC_UREGS_IMAP 0x00UL /* FHC Uart IMAP */
#define FHC_UREGS_ICLR 0x10UL /* FHC Uart ICLR */
unsigned long tregs; /* FHC TOD regs */
#define FHC_TREGS_IMAP 0x00UL /* FHC TOD IMAP */
#define FHC_TREGS_ICLR 0x10UL /* FHC TOD ICLR */
};
struct linux_fhc {
struct linux_fhc *next;
struct linux_central *parent; /* NULL if not central FHC */
struct fhc_regs fhc_regs;
int board;
int jtag_master;
struct device_node *prom_node;
struct linux_prom_ranges fhc_ranges[PROMREG_MAX];
int num_fhc_ranges;
};
#endif /* !(_SPARC64_FHC_H) */
/* fpumacro.h: FPU related macros.
*
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
*/
#ifndef _SPARC64_FPUMACRO_H
#define _SPARC64_FPUMACRO_H
#include <asm/asi.h>
#include <asm/visasm.h>
struct fpustate {
u32 regs[64];
};
#define FPUSTATE (struct fpustate *)(current_thread_info()->fpregs)
static inline unsigned long fprs_read(void)
{
unsigned long retval;
__asm__ __volatile__("rd %%fprs, %0" : "=r" (retval));
return retval;
}
static inline void fprs_write(unsigned long val)
{
__asm__ __volatile__("wr %0, 0x0, %%fprs" : : "r" (val));
}
#endif /* !(_SPARC64_FPUMACRO_H) */
#ifndef _ASM_SPARC64_HUGETLB_H
#define _ASM_SPARC64_HUGETLB_H
#include <asm/page.h>
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte);
pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep);
void hugetlb_prefault_arch_hook(struct mm_struct *mm);
static inline int is_hugepage_only_range(struct mm_struct *mm,
unsigned long addr,
unsigned long len) {
return 0;
}
/*
* If the arch doesn't supply something else, assume that hugepage
* size aligned regions are ok without further preparation.
*/
static inline int prepare_hugepage_range(unsigned long addr, unsigned long len)
{
if (len & ~HPAGE_MASK)
return -EINVAL;
if (addr & ~HPAGE_MASK)
return -EINVAL;
return 0;
}
static inline void hugetlb_free_pgd_range(struct mmu_gather **tlb,
unsigned long addr, unsigned long end,
unsigned long floor,
unsigned long ceiling)
{
free_pgd_range(tlb, addr, end, floor, ceiling);
}
static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep)
{
}
static inline int huge_pte_none(pte_t pte)
{
return pte_none(pte);
}
static inline pte_t huge_pte_wrprotect(pte_t pte)
{
return pte_wrprotect(pte);
}
static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
ptep_set_wrprotect(mm, addr, ptep);
}
static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep,
pte_t pte, int dirty)
{
return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
}
static inline pte_t huge_ptep_get(pte_t *ptep)
{
return *ptep;
}
static inline int arch_prepare_hugepage(struct page *page)
{
return 0;
}
static inline void arch_release_hugepage(struct page *page)
{
}
#endif /* _ASM_SPARC64_HUGETLB_H */
#ifndef _SPARC64_HVTRAP_H
#define _SPARC64_HVTRAP_H
#ifndef __ASSEMBLY__
#include <linux/types.h>
struct hvtramp_mapping {
__u64 vaddr;
__u64 tte;
};
struct hvtramp_descr {
__u32 cpu;
__u32 num_mappings;
__u64 fault_info_va;
__u64 fault_info_pa;
__u64 thread_reg;
struct hvtramp_mapping maps[1];
};
extern void hv_cpu_startup(unsigned long hvdescr_pa);
#endif
#define HVTRAMP_DESCR_CPU 0x00
#define HVTRAMP_DESCR_NUM_MAPPINGS 0x04
#define HVTRAMP_DESCR_FAULT_INFO_VA 0x08
#define HVTRAMP_DESCR_FAULT_INFO_PA 0x10
#define HVTRAMP_DESCR_THREAD_REG 0x18
#define HVTRAMP_DESCR_MAPS 0x20
#define HVTRAMP_MAPPING_VADDR 0x00
#define HVTRAMP_MAPPING_TTE 0x08
#define HVTRAMP_MAPPING_SIZE 0x10
#endif /* _SPARC64_HVTRAP_H */
#ifndef _SPARC64_HYPERVISOR_H
#define _SPARC64_HYPERVISOR_H
/* Sun4v hypervisor interfaces and defines.
*
* Hypervisor calls are made via traps to software traps number 0x80
* and above. Registers %o0 to %o5 serve as argument, status, and
* return value registers.
*
* There are two kinds of these traps. First there are the normal
* "fast traps" which use software trap 0x80 and encode the function
* to invoke by number in register %o5. Argument and return value
* handling is as follows:
*
* -----------------------------------------------
* | %o5 | function number | undefined |
* | %o0 | argument 0 | return status |
* | %o1 | argument 1 | return value 1 |
* | %o2 | argument 2 | return value 2 |
* | %o3 | argument 3 | return value 3 |
* | %o4 | argument 4 | return value 4 |
* -----------------------------------------------
*
* The second type are "hyper-fast traps" which encode the function
* number in the software trap number itself. So these use trap
* numbers > 0x80. The register usage for hyper-fast traps is as
* follows:
*
* -----------------------------------------------
* | %o0 | argument 0 | return status |
* | %o1 | argument 1 | return value 1 |
* | %o2 | argument 2 | return value 2 |
* | %o3 | argument 3 | return value 3 |
* | %o4 | argument 4 | return value 4 |
* -----------------------------------------------
*
* Registers providing explicit arguments to the hypervisor calls
* are volatile across the call. Upon return their values are
* undefined unless explicitly specified as containing a particular
* return value by the specific call. The return status is always
* returned in register %o0, zero indicates a successful execution of
* the hypervisor call and other values indicate an error status as
* defined below. So, for example, if a hyper-fast trap takes
* arguments 0, 1, and 2, then %o0, %o1, and %o2 are volatile across
* the call and %o3, %o4, and %o5 would be preserved.
*
* If the hypervisor trap is invalid, or the fast trap function number
* is invalid, HV_EBADTRAP will be returned in %o0. Also, all 64-bits
* of the argument and return values are significant.
*/
/* Trap numbers. */
#define HV_FAST_TRAP 0x80
#define HV_MMU_MAP_ADDR_TRAP 0x83
#define HV_MMU_UNMAP_ADDR_TRAP 0x84
#define HV_TTRACE_ADDENTRY_TRAP 0x85
#define HV_CORE_TRAP 0xff
/* Error codes. */
#define HV_EOK 0 /* Successful return */
#define HV_ENOCPU 1 /* Invalid CPU id */
#define HV_ENORADDR 2 /* Invalid real address */
#define HV_ENOINTR 3 /* Invalid interrupt id */
#define HV_EBADPGSZ 4 /* Invalid pagesize encoding */
#define HV_EBADTSB 5 /* Invalid TSB description */
#define HV_EINVAL 6 /* Invalid argument */
#define HV_EBADTRAP 7 /* Invalid function number */
#define HV_EBADALIGN 8 /* Invalid address alignment */
#define HV_EWOULDBLOCK 9 /* Cannot complete w/o blocking */
#define HV_ENOACCESS 10 /* No access to resource */
#define HV_EIO 11 /* I/O error */
#define HV_ECPUERROR 12 /* CPU in error state */
#define HV_ENOTSUPPORTED 13 /* Function not supported */
#define HV_ENOMAP 14 /* No mapping found */
#define HV_ETOOMANY 15 /* Too many items specified */
#define HV_ECHANNEL 16 /* Invalid LDC channel */
#define HV_EBUSY 17 /* Resource busy */
/* mach_exit()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MACH_EXIT
* ARG0: exit code
* ERRORS: This service does not return.
*
* Stop all CPUs in the virtual domain and place them into the stopped
* state. The 64-bit exit code may be passed to a service entity as
* the domain's exit status. On systems without a service entity, the
* domain will undergo a reset, and the boot firmware will be
* reloaded.
*
* This function will never return to the guest that invokes it.
*
* Note: By convention an exit code of zero denotes a successful exit by
* the guest code. A non-zero exit code denotes a guest specific
* error indication.
*
*/
#define HV_FAST_MACH_EXIT 0x00
#ifndef __ASSEMBLY__
extern void sun4v_mach_exit(unsigned long exit_code);
#endif
/* Domain services. */
/* mach_desc()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MACH_DESC
* ARG0: buffer
* ARG1: length
* RET0: status
* RET1: length
* ERRORS: HV_EBADALIGN Buffer is badly aligned
* HV_ENORADDR Buffer is to an illegal real address.
* HV_EINVAL Buffer length is too small for complete
* machine description.
*
* Copy the most current machine description into the buffer indicated
* by the real address in ARG0. The buffer provided must be 16 byte
* aligned. Upon success or HV_EINVAL, this service returns the
* actual size of the machine description in the RET1 return value.
*
* Note: A method of determining the appropriate buffer size for the
* machine description is to first call this service with a buffer
* length of 0 bytes.
*/
#define HV_FAST_MACH_DESC 0x01
#ifndef __ASSEMBLY__
extern unsigned long sun4v_mach_desc(unsigned long buffer_pa,
unsigned long buf_len,
unsigned long *real_buf_len);
#endif
/* mach_sir()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MACH_SIR
* ERRORS: This service does not return.
*
* Perform a software initiated reset of the virtual machine domain.
* All CPUs are captured as soon as possible, all hardware devices are
* returned to the entry default state, and the domain is restarted at
* the SIR (trap type 0x04) real trap table (RTBA) entry point on one
* of the CPUs. The single CPU restarted is selected as determined by
* platform specific policy. Memory is preserved across this
* operation.
*/
#define HV_FAST_MACH_SIR 0x02
#ifndef __ASSEMBLY__
extern void sun4v_mach_sir(void);
#endif
/* mach_set_watchdog()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MACH_SET_WATCHDOG
* ARG0: timeout in milliseconds
* RET0: status
* RET1: time remaining in milliseconds
*
* A guest uses this API to set a watchdog timer. Once the gues has set
* the timer, it must call the timer service again either to disable or
* postpone the expiration. If the timer expires before being reset or
* disabled, then the hypervisor take a platform specific action leading
* to guest termination within a bounded time period. The platform action
* may include recovery actions such as reporting the expiration to a
* Service Processor, and/or automatically restarting the gues.
*
* The 'timeout' parameter is specified in milliseconds, however the
* implementated granularity is given by the 'watchdog-resolution'
* property in the 'platform' node of the guest's machine description.
* The largest allowed timeout value is specified by the
* 'watchdog-max-timeout' property of the 'platform' node.
*
* If the 'timeout' argument is not zero, the watchdog timer is set to
* expire after a minimum of 'timeout' milliseconds.
*
* If the 'timeout' argument is zero, the watchdog timer is disabled.
*
* If the 'timeout' value exceeds the value of the 'max-watchdog-timeout'
* property, the hypervisor leaves the watchdog timer state unchanged,
* and returns a status of EINVAL.
*
* The 'time remaining' return value is valid regardless of whether the
* return status is EOK or EINVAL. A non-zero return value indicates the
* number of milliseconds that were remaining until the timer was to expire.
* If less than one millisecond remains, the return value is '1'. If the
* watchdog timer was disabled at the time of the call, the return value is
* zero.
*
* If the hypervisor cannot support the exact timeout value requested, but
* can support a larger timeout value, the hypervisor may round the actual
* timeout to a value larger than the requested timeout, consequently the
* 'time remaining' return value may be larger than the previously requested
* timeout value.
*
* Any guest OS debugger should be aware that the watchdog service may be in
* use. Consequently, it is recommended that the watchdog service is
* disabled upon debugger entry (e.g. reaching a breakpoint), and then
* re-enabled upon returning to normal execution. The API has been designed
* with this in mind, and the 'time remaining' result of the disable call may
* be used directly as the timeout argument of the re-enable call.
*/
#define HV_FAST_MACH_SET_WATCHDOG 0x05
#ifndef __ASSEMBLY__
extern unsigned long sun4v_mach_set_watchdog(unsigned long timeout,
unsigned long *orig_timeout);
#endif
/* CPU services.
*
* CPUs represent devices that can execute software threads. A single
* chip that contains multiple cores or strands is represented as
* multiple CPUs with unique CPU identifiers. CPUs are exported to
* OBP via the machine description (and to the OS via the OBP device
* tree). CPUs are always in one of three states: stopped, running,
* or error.
*
* A CPU ID is a pre-assigned 16-bit value that uniquely identifies a
* CPU within a logical domain. Operations that are to be performed
* on multiple CPUs specify them via a CPU list. A CPU list is an
* array in real memory, of which each 16-bit word is a CPU ID. CPU
* lists are passed through the API as two arguments. The first is
* the number of entries (16-bit words) in the CPU list, and the
* second is the (real address) pointer to the CPU ID list.
*/
/* cpu_start()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_START
* ARG0: CPU ID
* ARG1: PC
* ARG2: RTBA
* ARG3: target ARG0
* RET0: status
* ERRORS: ENOCPU Invalid CPU ID
* EINVAL Target CPU ID is not in the stopped state
* ENORADDR Invalid PC or RTBA real address
* EBADALIGN Unaligned PC or unaligned RTBA
* EWOULDBLOCK Starting resources are not available
*
* Start CPU with given CPU ID with PC in %pc and with a real trap
* base address value of RTBA. The indicated CPU must be in the
* stopped state. The supplied RTBA must be aligned on a 256 byte
* boundary. On successful completion, the specified CPU will be in
* the running state and will be supplied with "target ARG0" in %o0
* and RTBA in %tba.
*/
#define HV_FAST_CPU_START 0x10
#ifndef __ASSEMBLY__
extern unsigned long sun4v_cpu_start(unsigned long cpuid,
unsigned long pc,
unsigned long rtba,
unsigned long arg0);
#endif
/* cpu_stop()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_STOP
* ARG0: CPU ID
* RET0: status
* ERRORS: ENOCPU Invalid CPU ID
* EINVAL Target CPU ID is the current cpu
* EINVAL Target CPU ID is not in the running state
* EWOULDBLOCK Stopping resources are not available
* ENOTSUPPORTED Not supported on this platform
*
* The specified CPU is stopped. The indicated CPU must be in the
* running state. On completion, it will be in the stopped state. It
* is not legal to stop the current CPU.
*
* Note: As this service cannot be used to stop the current cpu, this service
* may not be used to stop the last running CPU in a domain. To stop
* and exit a running domain, a guest must use the mach_exit() service.
*/
#define HV_FAST_CPU_STOP 0x11
#ifndef __ASSEMBLY__
extern unsigned long sun4v_cpu_stop(unsigned long cpuid);
#endif
/* cpu_yield()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_YIELD
* RET0: status
* ERRORS: No possible error.
*
* Suspend execution on the current CPU. Execution will resume when
* an interrupt (device, %stick_compare, or cross-call) is targeted to
* the CPU. On some CPUs, this API may be used by the hypervisor to
* save power by disabling hardware strands.
*/
#define HV_FAST_CPU_YIELD 0x12
#ifndef __ASSEMBLY__
extern unsigned long sun4v_cpu_yield(void);
#endif
/* cpu_qconf()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_QCONF
* ARG0: queue
* ARG1: base real address
* ARG2: number of entries
* RET0: status
* ERRORS: ENORADDR Invalid base real address
* EINVAL Invalid queue or number of entries is less
* than 2 or too large.
* EBADALIGN Base real address is not correctly aligned
* for size.
*
* Configure the given queue to be placed at the given base real
* address, with the given number of entries. The number of entries
* must be a power of 2. The base real address must be aligned
* exactly to match the queue size. Each queue entry is 64 bytes
* long, so for example a 32 entry queue must be aligned on a 2048
* byte real address boundary.
*
* The specified queue is unconfigured if the number of entries is given
* as zero.
*
* For the current version of this API service, the argument queue is defined
* as follows:
*
* queue description
* ----- -------------------------
* 0x3c cpu mondo queue
* 0x3d device mondo queue
* 0x3e resumable error queue
* 0x3f non-resumable error queue
*
* Note: The maximum number of entries for each queue for a specific cpu may
* be determined from the machine description.
*/
#define HV_FAST_CPU_QCONF 0x14
#define HV_CPU_QUEUE_CPU_MONDO 0x3c
#define HV_CPU_QUEUE_DEVICE_MONDO 0x3d
#define HV_CPU_QUEUE_RES_ERROR 0x3e
#define HV_CPU_QUEUE_NONRES_ERROR 0x3f
#ifndef __ASSEMBLY__
extern unsigned long sun4v_cpu_qconf(unsigned long type,
unsigned long queue_paddr,
unsigned long num_queue_entries);
#endif
/* cpu_qinfo()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_QINFO
* ARG0: queue
* RET0: status
* RET1: base real address
* RET1: number of entries
* ERRORS: EINVAL Invalid queue
*
* Return the configuration info for the given queue. The base real
* address and number of entries of the defined queue are returned.
* The queue argument values are the same as for cpu_qconf() above.
*
* If the specified queue is a valid queue number, but no queue has
* been defined, the number of entries will be set to zero and the
* base real address returned is undefined.
*/
#define HV_FAST_CPU_QINFO 0x15
/* cpu_mondo_send()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_MONDO_SEND
* ARG0-1: CPU list
* ARG2: data real address
* RET0: status
* ERRORS: EBADALIGN Mondo data is not 64-byte aligned or CPU list
* is not 2-byte aligned.
* ENORADDR Invalid data mondo address, or invalid cpu list
* address.
* ENOCPU Invalid cpu in CPU list
* EWOULDBLOCK Some or all of the listed CPUs did not receive
* the mondo
* ECPUERROR One or more of the listed CPUs are in error
* state, use HV_FAST_CPU_STATE to see which ones
* EINVAL CPU list includes caller's CPU ID
*
* Send a mondo interrupt to the CPUs in the given CPU list with the
* 64-bytes at the given data real address. The data must be 64-byte
* aligned. The mondo data will be delivered to the cpu_mondo queues
* of the recipient CPUs.
*
* In all cases, error or not, the CPUs in the CPU list to which the
* mondo has been successfully delivered will be indicated by having
* their entry in CPU list updated with the value 0xffff.
*/
#define HV_FAST_CPU_MONDO_SEND 0x42
#ifndef __ASSEMBLY__
extern unsigned long sun4v_cpu_mondo_send(unsigned long cpu_count, unsigned long cpu_list_pa, unsigned long mondo_block_pa);
#endif
/* cpu_myid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_MYID
* RET0: status
* RET1: CPU ID
* ERRORS: No errors defined.
*
* Return the hypervisor ID handle for the current CPU. Use by a
* virtual CPU to discover it's own identity.
*/
#define HV_FAST_CPU_MYID 0x16
/* cpu_state()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_STATE
* ARG0: CPU ID
* RET0: status
* RET1: state
* ERRORS: ENOCPU Invalid CPU ID
*
* Retrieve the current state of the CPU with the given CPU ID.
*/
#define HV_FAST_CPU_STATE 0x17
#define HV_CPU_STATE_STOPPED 0x01
#define HV_CPU_STATE_RUNNING 0x02
#define HV_CPU_STATE_ERROR 0x03
#ifndef __ASSEMBLY__
extern long sun4v_cpu_state(unsigned long cpuid);
#endif
/* cpu_set_rtba()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_SET_RTBA
* ARG0: RTBA
* RET0: status
* RET1: previous RTBA
* ERRORS: ENORADDR Invalid RTBA real address
* EBADALIGN RTBA is incorrectly aligned for a trap table
*
* Set the real trap base address of the local cpu to the given RTBA.
* The supplied RTBA must be aligned on a 256 byte boundary. Upon
* success the previous value of the RTBA is returned in RET1.
*
* Note: This service does not affect %tba
*/
#define HV_FAST_CPU_SET_RTBA 0x18
/* cpu_set_rtba()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_GET_RTBA
* RET0: status
* RET1: previous RTBA
* ERRORS: No possible error.
*
* Returns the current value of RTBA in RET1.
*/
#define HV_FAST_CPU_GET_RTBA 0x19
/* MMU services.
*
* Layout of a TSB description for mmu_tsb_ctx{,non}0() calls.
*/
#ifndef __ASSEMBLY__
struct hv_tsb_descr {
unsigned short pgsz_idx;
unsigned short assoc;
unsigned int num_ttes; /* in TTEs */
unsigned int ctx_idx;
unsigned int pgsz_mask;
unsigned long tsb_base;
unsigned long resv;
};
#endif
#define HV_TSB_DESCR_PGSZ_IDX_OFFSET 0x00
#define HV_TSB_DESCR_ASSOC_OFFSET 0x02
#define HV_TSB_DESCR_NUM_TTES_OFFSET 0x04
#define HV_TSB_DESCR_CTX_IDX_OFFSET 0x08
#define HV_TSB_DESCR_PGSZ_MASK_OFFSET 0x0c
#define HV_TSB_DESCR_TSB_BASE_OFFSET 0x10
#define HV_TSB_DESCR_RESV_OFFSET 0x18
/* Page size bitmask. */
#define HV_PGSZ_MASK_8K (1 << 0)
#define HV_PGSZ_MASK_64K (1 << 1)
#define HV_PGSZ_MASK_512K (1 << 2)
#define HV_PGSZ_MASK_4MB (1 << 3)
#define HV_PGSZ_MASK_32MB (1 << 4)
#define HV_PGSZ_MASK_256MB (1 << 5)
#define HV_PGSZ_MASK_2GB (1 << 6)
#define HV_PGSZ_MASK_16GB (1 << 7)
/* Page size index. The value given in the TSB descriptor must correspond
* to the smallest page size specified in the pgsz_mask page size bitmask.
*/
#define HV_PGSZ_IDX_8K 0
#define HV_PGSZ_IDX_64K 1
#define HV_PGSZ_IDX_512K 2
#define HV_PGSZ_IDX_4MB 3
#define HV_PGSZ_IDX_32MB 4
#define HV_PGSZ_IDX_256MB 5
#define HV_PGSZ_IDX_2GB 6
#define HV_PGSZ_IDX_16GB 7
/* MMU fault status area.
*
* MMU related faults have their status and fault address information
* placed into a memory region made available by privileged code. Each
* virtual processor must make a mmu_fault_area_conf() call to tell the
* hypervisor where that processor's fault status should be stored.
*
* The fault status block is a multiple of 64-bytes and must be aligned
* on a 64-byte boundary.
*/
#ifndef __ASSEMBLY__
struct hv_fault_status {
unsigned long i_fault_type;
unsigned long i_fault_addr;
unsigned long i_fault_ctx;
unsigned long i_reserved[5];
unsigned long d_fault_type;
unsigned long d_fault_addr;
unsigned long d_fault_ctx;
unsigned long d_reserved[5];
};
#endif
#define HV_FAULT_I_TYPE_OFFSET 0x00
#define HV_FAULT_I_ADDR_OFFSET 0x08
#define HV_FAULT_I_CTX_OFFSET 0x10
#define HV_FAULT_D_TYPE_OFFSET 0x40
#define HV_FAULT_D_ADDR_OFFSET 0x48
#define HV_FAULT_D_CTX_OFFSET 0x50
#define HV_FAULT_TYPE_FAST_MISS 1
#define HV_FAULT_TYPE_FAST_PROT 2
#define HV_FAULT_TYPE_MMU_MISS 3
#define HV_FAULT_TYPE_INV_RA 4
#define HV_FAULT_TYPE_PRIV_VIOL 5
#define HV_FAULT_TYPE_PROT_VIOL 6
#define HV_FAULT_TYPE_NFO 7
#define HV_FAULT_TYPE_NFO_SEFF 8
#define HV_FAULT_TYPE_INV_VA 9
#define HV_FAULT_TYPE_INV_ASI 10
#define HV_FAULT_TYPE_NC_ATOMIC 11
#define HV_FAULT_TYPE_PRIV_ACT 12
#define HV_FAULT_TYPE_RESV1 13
#define HV_FAULT_TYPE_UNALIGNED 14
#define HV_FAULT_TYPE_INV_PGSZ 15
/* Values 16 --> -2 are reserved. */
#define HV_FAULT_TYPE_MULTIPLE -1
/* Flags argument for mmu_{map,unmap}_addr(), mmu_demap_{page,context,all}(),
* and mmu_{map,unmap}_perm_addr().
*/
#define HV_MMU_DMMU 0x01
#define HV_MMU_IMMU 0x02
#define HV_MMU_ALL (HV_MMU_DMMU | HV_MMU_IMMU)
/* mmu_map_addr()
* TRAP: HV_MMU_MAP_ADDR_TRAP
* ARG0: virtual address
* ARG1: mmu context
* ARG2: TTE
* ARG3: flags (HV_MMU_{IMMU,DMMU})
* ERRORS: EINVAL Invalid virtual address, mmu context, or flags
* EBADPGSZ Invalid page size value
* ENORADDR Invalid real address in TTE
*
* Create a non-permanent mapping using the given TTE, virtual
* address, and mmu context. The flags argument determines which
* (data, or instruction, or both) TLB the mapping gets loaded into.
*
* The behavior is undefined if the valid bit is clear in the TTE.
*
* Note: This API call is for privileged code to specify temporary translation
* mappings without the need to create and manage a TSB.
*/
/* mmu_unmap_addr()
* TRAP: HV_MMU_UNMAP_ADDR_TRAP
* ARG0: virtual address
* ARG1: mmu context
* ARG2: flags (HV_MMU_{IMMU,DMMU})
* ERRORS: EINVAL Invalid virtual address, mmu context, or flags
*
* Demaps the given virtual address in the given mmu context on this
* CPU. This function is intended to be used to demap pages mapped
* with mmu_map_addr. This service is equivalent to invoking
* mmu_demap_page() with only the current CPU in the CPU list. The
* flags argument determines which (data, or instruction, or both) TLB
* the mapping gets unmapped from.
*
* Attempting to perform an unmap operation for a previously defined
* permanent mapping will have undefined results.
*/
/* mmu_tsb_ctx0()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_TSB_CTX0
* ARG0: number of TSB descriptions
* ARG1: TSB descriptions pointer
* RET0: status
* ERRORS: ENORADDR Invalid TSB descriptions pointer or
* TSB base within a descriptor
* EBADALIGN TSB descriptions pointer is not aligned
* to an 8-byte boundary, or TSB base
* within a descriptor is not aligned for
* the given TSB size
* EBADPGSZ Invalid page size in a TSB descriptor
* EBADTSB Invalid associativity or size in a TSB
* descriptor
* EINVAL Invalid number of TSB descriptions, or
* invalid context index in a TSB
* descriptor, or index page size not
* equal to smallest page size in page
* size bitmask field.
*
* Configures the TSBs for the current CPU for virtual addresses with
* context zero. The TSB descriptions pointer is a pointer to an
* array of the given number of TSB descriptions.
*
* Note: The maximum number of TSBs available to a virtual CPU is given by the
* mmu-max-#tsbs property of the cpu's corresponding "cpu" node in the
* machine description.
*/
#define HV_FAST_MMU_TSB_CTX0 0x20
#ifndef __ASSEMBLY__
extern unsigned long sun4v_mmu_tsb_ctx0(unsigned long num_descriptions,
unsigned long tsb_desc_ra);
#endif
/* mmu_tsb_ctxnon0()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_TSB_CTXNON0
* ARG0: number of TSB descriptions
* ARG1: TSB descriptions pointer
* RET0: status
* ERRORS: Same as for mmu_tsb_ctx0() above.
*
* Configures the TSBs for the current CPU for virtual addresses with
* non-zero contexts. The TSB descriptions pointer is a pointer to an
* array of the given number of TSB descriptions.
*
* Note: A maximum of 16 TSBs may be specified in the TSB description list.
*/
#define HV_FAST_MMU_TSB_CTXNON0 0x21
/* mmu_demap_page()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_DEMAP_PAGE
* ARG0: reserved, must be zero
* ARG1: reserved, must be zero
* ARG2: virtual address
* ARG3: mmu context
* ARG4: flags (HV_MMU_{IMMU,DMMU})
* RET0: status
* ERRORS: EINVAL Invalid virutal address, context, or
* flags value
* ENOTSUPPORTED ARG0 or ARG1 is non-zero
*
* Demaps any page mapping of the given virtual address in the given
* mmu context for the current virtual CPU. Any virtually tagged
* caches are guaranteed to be kept consistent. The flags argument
* determines which TLB (instruction, or data, or both) participate in
* the operation.
*
* ARG0 and ARG1 are both reserved and must be set to zero.
*/
#define HV_FAST_MMU_DEMAP_PAGE 0x22
/* mmu_demap_ctx()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_DEMAP_CTX
* ARG0: reserved, must be zero
* ARG1: reserved, must be zero
* ARG2: mmu context
* ARG3: flags (HV_MMU_{IMMU,DMMU})
* RET0: status
* ERRORS: EINVAL Invalid context or flags value
* ENOTSUPPORTED ARG0 or ARG1 is non-zero
*
* Demaps all non-permanent virtual page mappings previously specified
* for the given context for the current virtual CPU. Any virtual
* tagged caches are guaranteed to be kept consistent. The flags
* argument determines which TLB (instruction, or data, or both)
* participate in the operation.
*
* ARG0 and ARG1 are both reserved and must be set to zero.
*/
#define HV_FAST_MMU_DEMAP_CTX 0x23
/* mmu_demap_all()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_DEMAP_ALL
* ARG0: reserved, must be zero
* ARG1: reserved, must be zero
* ARG2: flags (HV_MMU_{IMMU,DMMU})
* RET0: status
* ERRORS: EINVAL Invalid flags value
* ENOTSUPPORTED ARG0 or ARG1 is non-zero
*
* Demaps all non-permanent virtual page mappings previously specified
* for the current virtual CPU. Any virtual tagged caches are
* guaranteed to be kept consistent. The flags argument determines
* which TLB (instruction, or data, or both) participate in the
* operation.
*
* ARG0 and ARG1 are both reserved and must be set to zero.
*/
#define HV_FAST_MMU_DEMAP_ALL 0x24
#ifndef __ASSEMBLY__
extern void sun4v_mmu_demap_all(void);
#endif
/* mmu_map_perm_addr()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_MAP_PERM_ADDR
* ARG0: virtual address
* ARG1: reserved, must be zero
* ARG2: TTE
* ARG3: flags (HV_MMU_{IMMU,DMMU})
* RET0: status
* ERRORS: EINVAL Invalid virutal address or flags value
* EBADPGSZ Invalid page size value
* ENORADDR Invalid real address in TTE
* ETOOMANY Too many mappings (max of 8 reached)
*
* Create a permanent mapping using the given TTE and virtual address
* for context 0 on the calling virtual CPU. A maximum of 8 such
* permanent mappings may be specified by privileged code. Mappings
* may be removed with mmu_unmap_perm_addr().
*
* The behavior is undefined if a TTE with the valid bit clear is given.
*
* Note: This call is used to specify address space mappings for which
* privileged code does not expect to receive misses. For example,
* this mechanism can be used to map kernel nucleus code and data.
*/
#define HV_FAST_MMU_MAP_PERM_ADDR 0x25
#ifndef __ASSEMBLY__
extern unsigned long sun4v_mmu_map_perm_addr(unsigned long vaddr,
unsigned long set_to_zero,
unsigned long tte,
unsigned long flags);
#endif
/* mmu_fault_area_conf()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_FAULT_AREA_CONF
* ARG0: real address
* RET0: status
* RET1: previous mmu fault area real address
* ERRORS: ENORADDR Invalid real address
* EBADALIGN Invalid alignment for fault area
*
* Configure the MMU fault status area for the calling CPU. A 64-byte
* aligned real address specifies where MMU fault status information
* is placed. The return value is the previously specified area, or 0
* for the first invocation. Specifying a fault area at real address
* 0 is not allowed.
*/
#define HV_FAST_MMU_FAULT_AREA_CONF 0x26
/* mmu_enable()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_ENABLE
* ARG0: enable flag
* ARG1: return target address
* RET0: status
* ERRORS: ENORADDR Invalid real address when disabling
* translation.
* EBADALIGN The return target address is not
* aligned to an instruction.
* EINVAL The enable flag request the current
* operating mode (e.g. disable if already
* disabled)
*
* Enable or disable virtual address translation for the calling CPU
* within the virtual machine domain. If the enable flag is zero,
* translation is disabled, any non-zero value will enable
* translation.
*
* When this function returns, the newly selected translation mode
* will be active. If the mmu is being enabled, then the return
* target address is a virtual address else it is a real address.
*
* Upon successful completion, control will be returned to the given
* return target address (ie. the cpu will jump to that address). On
* failure, the previous mmu mode remains and the trap simply returns
* as normal with the appropriate error code in RET0.
*/
#define HV_FAST_MMU_ENABLE 0x27
/* mmu_unmap_perm_addr()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_UNMAP_PERM_ADDR
* ARG0: virtual address
* ARG1: reserved, must be zero
* ARG2: flags (HV_MMU_{IMMU,DMMU})
* RET0: status
* ERRORS: EINVAL Invalid virutal address or flags value
* ENOMAP Specified mapping was not found
*
* Demaps any permanent page mapping (established via
* mmu_map_perm_addr()) at the given virtual address for context 0 on
* the current virtual CPU. Any virtual tagged caches are guaranteed
* to be kept consistent.
*/
#define HV_FAST_MMU_UNMAP_PERM_ADDR 0x28
/* mmu_tsb_ctx0_info()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_TSB_CTX0_INFO
* ARG0: max TSBs
* ARG1: buffer pointer
* RET0: status
* RET1: number of TSBs
* ERRORS: EINVAL Supplied buffer is too small
* EBADALIGN The buffer pointer is badly aligned
* ENORADDR Invalid real address for buffer pointer
*
* Return the TSB configuration as previous defined by mmu_tsb_ctx0()
* into the provided buffer. The size of the buffer is given in ARG1
* in terms of the number of TSB description entries.
*
* Upon return, RET1 always contains the number of TSB descriptions
* previously configured. If zero TSBs were configured, EOK is
* returned with RET1 containing 0.
*/
#define HV_FAST_MMU_TSB_CTX0_INFO 0x29
/* mmu_tsb_ctxnon0_info()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_TSB_CTXNON0_INFO
* ARG0: max TSBs
* ARG1: buffer pointer
* RET0: status
* RET1: number of TSBs
* ERRORS: EINVAL Supplied buffer is too small
* EBADALIGN The buffer pointer is badly aligned
* ENORADDR Invalid real address for buffer pointer
*
* Return the TSB configuration as previous defined by
* mmu_tsb_ctxnon0() into the provided buffer. The size of the buffer
* is given in ARG1 in terms of the number of TSB description entries.
*
* Upon return, RET1 always contains the number of TSB descriptions
* previously configured. If zero TSBs were configured, EOK is
* returned with RET1 containing 0.
*/
#define HV_FAST_MMU_TSB_CTXNON0_INFO 0x2a
/* mmu_fault_area_info()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_FAULT_AREA_INFO
* RET0: status
* RET1: fault area real address
* ERRORS: No errors defined.
*
* Return the currently defined MMU fault status area for the current
* CPU. The real address of the fault status area is returned in
* RET1, or 0 is returned in RET1 if no fault status area is defined.
*
* Note: mmu_fault_area_conf() may be called with the return value (RET1)
* from this service if there is a need to save and restore the fault
* area for a cpu.
*/
#define HV_FAST_MMU_FAULT_AREA_INFO 0x2b
/* Cache and Memory services. */
/* mem_scrub()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MEM_SCRUB
* ARG0: real address
* ARG1: length
* RET0: status
* RET1: length scrubbed
* ERRORS: ENORADDR Invalid real address
* EBADALIGN Start address or length are not correctly
* aligned
* EINVAL Length is zero
*
* Zero the memory contents in the range real address to real address
* plus length minus 1. Also, valid ECC will be generated for that
* memory address range. Scrubbing is started at the given real
* address, but may not scrub the entire given length. The actual
* length scrubbed will be returned in RET1.
*
* The real address and length must be aligned on an 8K boundary, or
* contain the start address and length from a sun4v error report.
*
* Note: There are two uses for this function. The first use is to block clear
* and initialize memory and the second is to scrub an u ncorrectable
* error reported via a resumable or non-resumable trap. The second
* use requires the arguments to be equal to the real address and length
* provided in a sun4v memory error report.
*/
#define HV_FAST_MEM_SCRUB 0x31
/* mem_sync()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MEM_SYNC
* ARG0: real address
* ARG1: length
* RET0: status
* RET1: length synced
* ERRORS: ENORADDR Invalid real address
* EBADALIGN Start address or length are not correctly
* aligned
* EINVAL Length is zero
*
* Force the next access within the real address to real address plus
* length minus 1 to be fetches from main system memory. Less than
* the given length may be synced, the actual amount synced is
* returned in RET1. The real address and length must be aligned on
* an 8K boundary.
*/
#define HV_FAST_MEM_SYNC 0x32
/* Time of day services.
*
* The hypervisor maintains the time of day on a per-domain basis.
* Changing the time of day in one domain does not affect the time of
* day on any other domain.
*
* Time is described by a single unsigned 64-bit word which is the
* number of seconds since the UNIX Epoch (00:00:00 UTC, January 1,
* 1970).
*/
/* tod_get()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_TOD_GET
* RET0: status
* RET1: TOD
* ERRORS: EWOULDBLOCK TOD resource is temporarily unavailable
* ENOTSUPPORTED If TOD not supported on this platform
*
* Return the current time of day. May block if TOD access is
* temporarily not possible.
*/
#define HV_FAST_TOD_GET 0x50
#ifndef __ASSEMBLY__
extern unsigned long sun4v_tod_get(unsigned long *time);
#endif
/* tod_set()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_TOD_SET
* ARG0: TOD
* RET0: status
* ERRORS: EWOULDBLOCK TOD resource is temporarily unavailable
* ENOTSUPPORTED If TOD not supported on this platform
*
* The current time of day is set to the value specified in ARG0. May
* block if TOD access is temporarily not possible.
*/
#define HV_FAST_TOD_SET 0x51
#ifndef __ASSEMBLY__
extern unsigned long sun4v_tod_set(unsigned long time);
#endif
/* Console services */
/* con_getchar()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CONS_GETCHAR
* RET0: status
* RET1: character
* ERRORS: EWOULDBLOCK No character available.
*
* Returns a character from the console device. If no character is
* available then an EWOULDBLOCK error is returned. If a character is
* available, then the returned status is EOK and the character value
* is in RET1.
*
* A virtual BREAK is represented by the 64-bit value -1.
*
* A virtual HUP signal is represented by the 64-bit value -2.
*/
#define HV_FAST_CONS_GETCHAR 0x60
/* con_putchar()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CONS_PUTCHAR
* ARG0: character
* RET0: status
* ERRORS: EINVAL Illegal character
* EWOULDBLOCK Output buffer currently full, would block
*
* Send a character to the console device. Only character values
* between 0 and 255 may be used. Values outside this range are
* invalid except for the 64-bit value -1 which is used to send a
* virtual BREAK.
*/
#define HV_FAST_CONS_PUTCHAR 0x61
/* con_read()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CONS_READ
* ARG0: buffer real address
* ARG1: buffer size in bytes
* RET0: status
* RET1: bytes read or BREAK or HUP
* ERRORS: EWOULDBLOCK No character available.
*
* Reads characters into a buffer from the console device. If no
* character is available then an EWOULDBLOCK error is returned.
* If a character is available, then the returned status is EOK
* and the number of bytes read into the given buffer is provided
* in RET1.
*
* A virtual BREAK is represented by the 64-bit RET1 value -1.
*
* A virtual HUP signal is represented by the 64-bit RET1 value -2.
*
* If BREAK or HUP are indicated, no bytes were read into buffer.
*/
#define HV_FAST_CONS_READ 0x62
/* con_write()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CONS_WRITE
* ARG0: buffer real address
* ARG1: buffer size in bytes
* RET0: status
* RET1: bytes written
* ERRORS: EWOULDBLOCK Output buffer currently full, would block
*
* Send a characters in buffer to the console device. Breaks must be
* sent using con_putchar().
*/
#define HV_FAST_CONS_WRITE 0x63
#ifndef __ASSEMBLY__
extern long sun4v_con_getchar(long *status);
extern long sun4v_con_putchar(long c);
extern long sun4v_con_read(unsigned long buffer,
unsigned long size,
unsigned long *bytes_read);
extern unsigned long sun4v_con_write(unsigned long buffer,
unsigned long size,
unsigned long *bytes_written);
#endif
/* mach_set_soft_state()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MACH_SET_SOFT_STATE
* ARG0: software state
* ARG1: software state description pointer
* RET0: status
* ERRORS: EINVAL software state not valid or software state
* description is not NULL terminated
* ENORADDR software state description pointer is not a
* valid real address
* EBADALIGNED software state description is not correctly
* aligned
*
* This allows the guest to report it's soft state to the hypervisor. There
* are two primary components to this state. The first part states whether
* the guest software is running or not. The second containts optional
* details specific to the software.
*
* The software state argument is defined below in HV_SOFT_STATE_*, and
* indicates whether the guest is operating normally or in a transitional
* state.
*
* The software state description argument is a real address of a data buffer
* of size 32-bytes aligned on a 32-byte boundary. It is treated as a NULL
* terminated 7-bit ASCII string of up to 31 characters not including the
* NULL termination.
*/
#define HV_FAST_MACH_SET_SOFT_STATE 0x70
#define HV_SOFT_STATE_NORMAL 0x01
#define HV_SOFT_STATE_TRANSITION 0x02
#ifndef __ASSEMBLY__
extern unsigned long sun4v_mach_set_soft_state(unsigned long soft_state,
unsigned long msg_string_ra);
#endif
/* mach_get_soft_state()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MACH_GET_SOFT_STATE
* ARG0: software state description pointer
* RET0: status
* RET1: software state
* ERRORS: ENORADDR software state description pointer is not a
* valid real address
* EBADALIGNED software state description is not correctly
* aligned
*
* Retrieve the current value of the guest's software state. The rules
* for the software state pointer are the same as for mach_set_soft_state()
* above.
*/
#define HV_FAST_MACH_GET_SOFT_STATE 0x71
/* svc_send()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_SVC_SEND
* ARG0: service ID
* ARG1: buffer real address
* ARG2: buffer size
* RET0: STATUS
* RET1: sent_bytes
*
* Be careful, all output registers are clobbered by this operation,
* so for example it is not possible to save away a value in %o4
* across the trap.
*/
#define HV_FAST_SVC_SEND 0x80
/* svc_recv()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_SVC_RECV
* ARG0: service ID
* ARG1: buffer real address
* ARG2: buffer size
* RET0: STATUS
* RET1: recv_bytes
*
* Be careful, all output registers are clobbered by this operation,
* so for example it is not possible to save away a value in %o4
* across the trap.
*/
#define HV_FAST_SVC_RECV 0x81
/* svc_getstatus()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_SVC_GETSTATUS
* ARG0: service ID
* RET0: STATUS
* RET1: status bits
*/
#define HV_FAST_SVC_GETSTATUS 0x82
/* svc_setstatus()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_SVC_SETSTATUS
* ARG0: service ID
* ARG1: bits to set
* RET0: STATUS
*/
#define HV_FAST_SVC_SETSTATUS 0x83
/* svc_clrstatus()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_SVC_CLRSTATUS
* ARG0: service ID
* ARG1: bits to clear
* RET0: STATUS
*/
#define HV_FAST_SVC_CLRSTATUS 0x84
#ifndef __ASSEMBLY__
extern unsigned long sun4v_svc_send(unsigned long svc_id,
unsigned long buffer,
unsigned long buffer_size,
unsigned long *sent_bytes);
extern unsigned long sun4v_svc_recv(unsigned long svc_id,
unsigned long buffer,
unsigned long buffer_size,
unsigned long *recv_bytes);
extern unsigned long sun4v_svc_getstatus(unsigned long svc_id,
unsigned long *status_bits);
extern unsigned long sun4v_svc_setstatus(unsigned long svc_id,
unsigned long status_bits);
extern unsigned long sun4v_svc_clrstatus(unsigned long svc_id,
unsigned long status_bits);
#endif
/* Trap trace services.
*
* The hypervisor provides a trap tracing capability for privileged
* code running on each virtual CPU. Privileged code provides a
* round-robin trap trace queue within which the hypervisor writes
* 64-byte entries detailing hyperprivileged traps taken n behalf of
* privileged code. This is provided as a debugging capability for
* privileged code.
*
* The trap trace control structure is 64-bytes long and placed at the
* start (offset 0) of the trap trace buffer, and is described as
* follows:
*/
#ifndef __ASSEMBLY__
struct hv_trap_trace_control {
unsigned long head_offset;
unsigned long tail_offset;
unsigned long __reserved[0x30 / sizeof(unsigned long)];
};
#endif
#define HV_TRAP_TRACE_CTRL_HEAD_OFFSET 0x00
#define HV_TRAP_TRACE_CTRL_TAIL_OFFSET 0x08
/* The head offset is the offset of the most recently completed entry
* in the trap-trace buffer. The tail offset is the offset of the
* next entry to be written. The control structure is owned and
* modified by the hypervisor. A guest may not modify the control
* structure contents. Attempts to do so will result in undefined
* behavior for the guest.
*
* Each trap trace buffer entry is layed out as follows:
*/
#ifndef __ASSEMBLY__
struct hv_trap_trace_entry {
unsigned char type; /* Hypervisor or guest entry? */
unsigned char hpstate; /* Hyper-privileged state */
unsigned char tl; /* Trap level */
unsigned char gl; /* Global register level */
unsigned short tt; /* Trap type */
unsigned short tag; /* Extended trap identifier */
unsigned long tstate; /* Trap state */
unsigned long tick; /* Tick */
unsigned long tpc; /* Trap PC */
unsigned long f1; /* Entry specific */
unsigned long f2; /* Entry specific */
unsigned long f3; /* Entry specific */
unsigned long f4; /* Entry specific */
};
#endif
#define HV_TRAP_TRACE_ENTRY_TYPE 0x00
#define HV_TRAP_TRACE_ENTRY_HPSTATE 0x01
#define HV_TRAP_TRACE_ENTRY_TL 0x02
#define HV_TRAP_TRACE_ENTRY_GL 0x03
#define HV_TRAP_TRACE_ENTRY_TT 0x04
#define HV_TRAP_TRACE_ENTRY_TAG 0x06
#define HV_TRAP_TRACE_ENTRY_TSTATE 0x08
#define HV_TRAP_TRACE_ENTRY_TICK 0x10
#define HV_TRAP_TRACE_ENTRY_TPC 0x18
#define HV_TRAP_TRACE_ENTRY_F1 0x20
#define HV_TRAP_TRACE_ENTRY_F2 0x28
#define HV_TRAP_TRACE_ENTRY_F3 0x30
#define HV_TRAP_TRACE_ENTRY_F4 0x38
/* The type field is encoded as follows. */
#define HV_TRAP_TYPE_UNDEF 0x00 /* Entry content undefined */
#define HV_TRAP_TYPE_HV 0x01 /* Hypervisor trap entry */
#define HV_TRAP_TYPE_GUEST 0xff /* Added via ttrace_addentry() */
/* ttrace_buf_conf()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_TTRACE_BUF_CONF
* ARG0: real address
* ARG1: number of entries
* RET0: status
* RET1: number of entries
* ERRORS: ENORADDR Invalid real address
* EINVAL Size is too small
* EBADALIGN Real address not aligned on 64-byte boundary
*
* Requests hypervisor trap tracing and declares a virtual CPU's trap
* trace buffer to the hypervisor. The real address supplies the real
* base address of the trap trace queue and must be 64-byte aligned.
* Specifying a value of 0 for the number of entries disables trap
* tracing for the calling virtual CPU. The buffer allocated must be
* sized for a power of two number of 64-byte trap trace entries plus
* an initial 64-byte control structure.
*
* This may be invoked any number of times so that a virtual CPU may
* relocate a trap trace buffer or create "snapshots" of information.
*
* If the real address is illegal or badly aligned, then trap tracing
* is disabled and an error is returned.
*
* Upon failure with EINVAL, this service call returns in RET1 the
* minimum number of buffer entries required. Upon other failures
* RET1 is undefined.
*/
#define HV_FAST_TTRACE_BUF_CONF 0x90
/* ttrace_buf_info()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_TTRACE_BUF_INFO
* RET0: status
* RET1: real address
* RET2: size
* ERRORS: None defined.
*
* Returns the size and location of the previously declared trap-trace
* buffer. In the event that no buffer was previously defined, or the
* buffer is disabled, this call will return a size of zero bytes.
*/
#define HV_FAST_TTRACE_BUF_INFO 0x91
/* ttrace_enable()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_TTRACE_ENABLE
* ARG0: enable
* RET0: status
* RET1: previous enable state
* ERRORS: EINVAL No trap trace buffer currently defined
*
* Enable or disable trap tracing, and return the previous enabled
* state in RET1. Future systems may define various flags for the
* enable argument (ARG0), for the moment a guest should pass
* "(uint64_t) -1" to enable, and "(uint64_t) 0" to disable all
* tracing - which will ensure future compatability.
*/
#define HV_FAST_TTRACE_ENABLE 0x92
/* ttrace_freeze()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_TTRACE_FREEZE
* ARG0: freeze
* RET0: status
* RET1: previous freeze state
* ERRORS: EINVAL No trap trace buffer currently defined
*
* Freeze or unfreeze trap tracing, returning the previous freeze
* state in RET1. A guest should pass a non-zero value to freeze and
* a zero value to unfreeze all tracing. The returned previous state
* is 0 for not frozen and 1 for frozen.
*/
#define HV_FAST_TTRACE_FREEZE 0x93
/* ttrace_addentry()
* TRAP: HV_TTRACE_ADDENTRY_TRAP
* ARG0: tag (16-bits)
* ARG1: data word 0
* ARG2: data word 1
* ARG3: data word 2
* ARG4: data word 3
* RET0: status
* ERRORS: EINVAL No trap trace buffer currently defined
*
* Add an entry to the trap trace buffer. Upon return only ARG0/RET0
* is modified - none of the other registers holding arguments are
* volatile across this hypervisor service.
*/
/* Core dump services.
*
* Since the hypervisor viraulizes and thus obscures a lot of the
* physical machine layout and state, traditional OS crash dumps can
* be difficult to diagnose especially when the problem is a
* configuration error of some sort.
*
* The dump services provide an opaque buffer into which the
* hypervisor can place it's internal state in order to assist in
* debugging such situations. The contents are opaque and extremely
* platform and hypervisor implementation specific. The guest, during
* a core dump, requests that the hypervisor update any information in
* the dump buffer in preparation to being dumped as part of the
* domain's memory image.
*/
/* dump_buf_update()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_DUMP_BUF_UPDATE
* ARG0: real address
* ARG1: size
* RET0: status
* RET1: required size of dump buffer
* ERRORS: ENORADDR Invalid real address
* EBADALIGN Real address is not aligned on a 64-byte
* boundary
* EINVAL Size is non-zero but less than minimum size
* required
* ENOTSUPPORTED Operation not supported on current logical
* domain
*
* Declare a domain dump buffer to the hypervisor. The real address
* provided for the domain dump buffer must be 64-byte aligned. The
* size specifies the size of the dump buffer and may be larger than
* the minimum size specified in the machine description. The
* hypervisor will fill the dump buffer with opaque data.
*
* Note: A guest may elect to include dump buffer contents as part of a crash
* dump to assist with debugging. This function may be called any number
* of times so that a guest may relocate a dump buffer, or create
* "snapshots" of any dump-buffer information. Each call to
* dump_buf_update() atomically declares the new dump buffer to the
* hypervisor.
*
* A specified size of 0 unconfigures the dump buffer. If the real
* address is illegal or badly aligned, then any currently active dump
* buffer is disabled and an error is returned.
*
* In the event that the call fails with EINVAL, RET1 contains the
* minimum size requires by the hypervisor for a valid dump buffer.
*/
#define HV_FAST_DUMP_BUF_UPDATE 0x94
/* dump_buf_info()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_DUMP_BUF_INFO
* RET0: status
* RET1: real address of current dump buffer
* RET2: size of current dump buffer
* ERRORS: No errors defined.
*
* Return the currently configures dump buffer description. A
* returned size of 0 bytes indicates an undefined dump buffer. In
* this case the return address in RET1 is undefined.
*/
#define HV_FAST_DUMP_BUF_INFO 0x95
/* Device interrupt services.
*
* Device interrupts are allocated to system bus bridges by the hypervisor,
* and described to OBP in the machine description. OBP then describes
* these interrupts to the OS via properties in the device tree.
*
* Terminology:
*
* cpuid Unique opaque value which represents a target cpu.
*
* devhandle Device handle. It uniquely identifies a device, and
* consistes of the lower 28-bits of the hi-cell of the
* first entry of the device's "reg" property in the
* OBP device tree.
*
* devino Device interrupt number. Specifies the relative
* interrupt number within the device. The unique
* combination of devhandle and devino are used to
* identify a specific device interrupt.
*
* Note: The devino value is the same as the values in the
* "interrupts" property or "interrupt-map" property
* in the OBP device tree for that device.
*
* sysino System interrupt number. A 64-bit unsigned interger
* representing a unique interrupt within a virtual
* machine.
*
* intr_state A flag representing the interrupt state for a given
* sysino. The state values are defined below.
*
* intr_enabled A flag representing the 'enabled' state for a given
* sysino. The enable values are defined below.
*/
#define HV_INTR_STATE_IDLE 0 /* Nothing pending */
#define HV_INTR_STATE_RECEIVED 1 /* Interrupt received by hardware */
#define HV_INTR_STATE_DELIVERED 2 /* Interrupt delivered to queue */
#define HV_INTR_DISABLED 0 /* sysino not enabled */
#define HV_INTR_ENABLED 1 /* sysino enabled */
/* intr_devino_to_sysino()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_INTR_DEVINO2SYSINO
* ARG0: devhandle
* ARG1: devino
* RET0: status
* RET1: sysino
* ERRORS: EINVAL Invalid devhandle/devino
*
* Converts a device specific interrupt number of the given
* devhandle/devino into a system specific ino (sysino).
*/
#define HV_FAST_INTR_DEVINO2SYSINO 0xa0
#ifndef __ASSEMBLY__
extern unsigned long sun4v_devino_to_sysino(unsigned long devhandle,
unsigned long devino);
#endif
/* intr_getenabled()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_INTR_GETENABLED
* ARG0: sysino
* RET0: status
* RET1: intr_enabled (HV_INTR_{DISABLED,ENABLED})
* ERRORS: EINVAL Invalid sysino
*
* Returns interrupt enabled state in RET1 for the interrupt defined
* by the given sysino.
*/
#define HV_FAST_INTR_GETENABLED 0xa1
#ifndef __ASSEMBLY__
extern unsigned long sun4v_intr_getenabled(unsigned long sysino);
#endif
/* intr_setenabled()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_INTR_SETENABLED
* ARG0: sysino
* ARG1: intr_enabled (HV_INTR_{DISABLED,ENABLED})
* RET0: status
* ERRORS: EINVAL Invalid sysino or intr_enabled value
*
* Set the 'enabled' state of the interrupt sysino.
*/
#define HV_FAST_INTR_SETENABLED 0xa2
#ifndef __ASSEMBLY__
extern unsigned long sun4v_intr_setenabled(unsigned long sysino, unsigned long intr_enabled);
#endif
/* intr_getstate()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_INTR_GETSTATE
* ARG0: sysino
* RET0: status
* RET1: intr_state (HV_INTR_STATE_*)
* ERRORS: EINVAL Invalid sysino
*
* Returns current state of the interrupt defined by the given sysino.
*/
#define HV_FAST_INTR_GETSTATE 0xa3
#ifndef __ASSEMBLY__
extern unsigned long sun4v_intr_getstate(unsigned long sysino);
#endif
/* intr_setstate()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_INTR_SETSTATE
* ARG0: sysino
* ARG1: intr_state (HV_INTR_STATE_*)
* RET0: status
* ERRORS: EINVAL Invalid sysino or intr_state value
*
* Sets the current state of the interrupt described by the given sysino
* value.
*
* Note: Setting the state to HV_INTR_STATE_IDLE clears any pending
* interrupt for sysino.
*/
#define HV_FAST_INTR_SETSTATE 0xa4
#ifndef __ASSEMBLY__
extern unsigned long sun4v_intr_setstate(unsigned long sysino, unsigned long intr_state);
#endif
/* intr_gettarget()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_INTR_GETTARGET
* ARG0: sysino
* RET0: status
* RET1: cpuid
* ERRORS: EINVAL Invalid sysino
*
* Returns CPU that is the current target of the interrupt defined by
* the given sysino. The CPU value returned is undefined if the target
* has not been set via intr_settarget().
*/
#define HV_FAST_INTR_GETTARGET 0xa5
#ifndef __ASSEMBLY__
extern unsigned long sun4v_intr_gettarget(unsigned long sysino);
#endif
/* intr_settarget()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_INTR_SETTARGET
* ARG0: sysino
* ARG1: cpuid
* RET0: status
* ERRORS: EINVAL Invalid sysino
* ENOCPU Invalid cpuid
*
* Set the target CPU for the interrupt defined by the given sysino.
*/
#define HV_FAST_INTR_SETTARGET 0xa6
#ifndef __ASSEMBLY__
extern unsigned long sun4v_intr_settarget(unsigned long sysino, unsigned long cpuid);
#endif
/* vintr_get_cookie()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_VINTR_GET_COOKIE
* ARG0: device handle
* ARG1: device ino
* RET0: status
* RET1: cookie
*/
#define HV_FAST_VINTR_GET_COOKIE 0xa7
/* vintr_set_cookie()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_VINTR_SET_COOKIE
* ARG0: device handle
* ARG1: device ino
* ARG2: cookie
* RET0: status
*/
#define HV_FAST_VINTR_SET_COOKIE 0xa8
/* vintr_get_valid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_VINTR_GET_VALID
* ARG0: device handle
* ARG1: device ino
* RET0: status
* RET1: valid state
*/
#define HV_FAST_VINTR_GET_VALID 0xa9
/* vintr_set_valid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_VINTR_SET_VALID
* ARG0: device handle
* ARG1: device ino
* ARG2: valid state
* RET0: status
*/
#define HV_FAST_VINTR_SET_VALID 0xaa
/* vintr_get_state()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_VINTR_GET_STATE
* ARG0: device handle
* ARG1: device ino
* RET0: status
* RET1: state
*/
#define HV_FAST_VINTR_GET_STATE 0xab
/* vintr_set_state()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_VINTR_SET_STATE
* ARG0: device handle
* ARG1: device ino
* ARG2: state
* RET0: status
*/
#define HV_FAST_VINTR_SET_STATE 0xac
/* vintr_get_target()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_VINTR_GET_TARGET
* ARG0: device handle
* ARG1: device ino
* RET0: status
* RET1: cpuid
*/
#define HV_FAST_VINTR_GET_TARGET 0xad
/* vintr_set_target()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_VINTR_SET_TARGET
* ARG0: device handle
* ARG1: device ino
* ARG2: cpuid
* RET0: status
*/
#define HV_FAST_VINTR_SET_TARGET 0xae
#ifndef __ASSEMBLY__
extern unsigned long sun4v_vintr_get_cookie(unsigned long dev_handle,
unsigned long dev_ino,
unsigned long *cookie);
extern unsigned long sun4v_vintr_set_cookie(unsigned long dev_handle,
unsigned long dev_ino,
unsigned long cookie);
extern unsigned long sun4v_vintr_get_valid(unsigned long dev_handle,
unsigned long dev_ino,
unsigned long *valid);
extern unsigned long sun4v_vintr_set_valid(unsigned long dev_handle,
unsigned long dev_ino,
unsigned long valid);
extern unsigned long sun4v_vintr_get_state(unsigned long dev_handle,
unsigned long dev_ino,
unsigned long *state);
extern unsigned long sun4v_vintr_set_state(unsigned long dev_handle,
unsigned long dev_ino,
unsigned long state);
extern unsigned long sun4v_vintr_get_target(unsigned long dev_handle,
unsigned long dev_ino,
unsigned long *cpuid);
extern unsigned long sun4v_vintr_set_target(unsigned long dev_handle,
unsigned long dev_ino,
unsigned long cpuid);
#endif
/* PCI IO services.
*
* See the terminology descriptions in the device interrupt services
* section above as those apply here too. Here are terminology
* definitions specific to these PCI IO services:
*
* tsbnum TSB number. Indentifies which io-tsb is used.
* For this version of the specification, tsbnum
* must be zero.
*
* tsbindex TSB index. Identifies which entry in the TSB
* is used. The first entry is zero.
*
* tsbid A 64-bit aligned data structure which contains
* a tsbnum and a tsbindex. Bits 63:32 contain the
* tsbnum and bits 31:00 contain the tsbindex.
*
* Use the HV_PCI_TSBID() macro to construct such
* values.
*
* io_attributes IO attributes for IOMMU mappings. One of more
* of the attritbute bits are stores in a 64-bit
* value. The values are defined below.
*
* r_addr 64-bit real address
*
* pci_device PCI device address. A PCI device address identifies
* a specific device on a specific PCI bus segment.
* A PCI device address ia a 32-bit unsigned integer
* with the following format:
*
* 00000000.bbbbbbbb.dddddfff.00000000
*
* Use the HV_PCI_DEVICE_BUILD() macro to construct
* such values.
*
* pci_config_offset
* PCI configureation space offset. For conventional
* PCI a value between 0 and 255. For extended
* configuration space, a value between 0 and 4095.
*
* Note: For PCI configuration space accesses, the offset
* must be aligned to the access size.
*
* error_flag A return value which specifies if the action succeeded
* or failed. 0 means no error, non-0 means some error
* occurred while performing the service.
*
* io_sync_direction
* Direction definition for pci_dma_sync(), defined
* below in HV_PCI_SYNC_*.
*
* io_page_list A list of io_page_addresses, an io_page_address is
* a real address.
*
* io_page_list_p A pointer to an io_page_list.
*
* "size based byte swap" - Some functions do size based byte swapping
* which allows sw to access pointers and
* counters in native form when the processor
* operates in a different endianness than the
* IO bus. Size-based byte swapping converts a
* multi-byte field between big-endian and
* little-endian format.
*/
#define HV_PCI_MAP_ATTR_READ 0x01
#define HV_PCI_MAP_ATTR_WRITE 0x02
#define HV_PCI_DEVICE_BUILD(b,d,f) \
((((b) & 0xff) << 16) | \
(((d) & 0x1f) << 11) | \
(((f) & 0x07) << 8))
#define HV_PCI_TSBID(__tsb_num, __tsb_index) \
((((u64)(__tsb_num)) << 32UL) | ((u64)(__tsb_index)))
#define HV_PCI_SYNC_FOR_DEVICE 0x01
#define HV_PCI_SYNC_FOR_CPU 0x02
/* pci_iommu_map()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_IOMMU_MAP
* ARG0: devhandle
* ARG1: tsbid
* ARG2: #ttes
* ARG3: io_attributes
* ARG4: io_page_list_p
* RET0: status
* RET1: #ttes mapped
* ERRORS: EINVAL Invalid devhandle/tsbnum/tsbindex/io_attributes
* EBADALIGN Improperly aligned real address
* ENORADDR Invalid real address
*
* Create IOMMU mappings in the sun4v device defined by the given
* devhandle. The mappings are created in the TSB defined by the
* tsbnum component of the given tsbid. The first mapping is created
* in the TSB i ndex defined by the tsbindex component of the given tsbid.
* The call creates up to #ttes mappings, the first one at tsbnum, tsbindex,
* the second at tsbnum, tsbindex + 1, etc.
*
* All mappings are created with the attributes defined by the io_attributes
* argument. The page mapping addresses are described in the io_page_list
* defined by the given io_page_list_p, which is a pointer to the io_page_list.
* The first entry in the io_page_list is the address for the first iotte, the
* 2nd for the 2nd iotte, and so on.
*
* Each io_page_address in the io_page_list must be appropriately aligned.
* #ttes must be greater than zero. For this version of the spec, the tsbnum
* component of the given tsbid must be zero.
*
* Returns the actual number of mappings creates, which may be less than
* or equal to the argument #ttes. If the function returns a value which
* is less than the #ttes, the caller may continus to call the function with
* an updated tsbid, #ttes, io_page_list_p arguments until all pages are
* mapped.
*
* Note: This function does not imply an iotte cache flush. The guest must
* demap an entry before re-mapping it.
*/
#define HV_FAST_PCI_IOMMU_MAP 0xb0
/* pci_iommu_demap()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_IOMMU_DEMAP
* ARG0: devhandle
* ARG1: tsbid
* ARG2: #ttes
* RET0: status
* RET1: #ttes demapped
* ERRORS: EINVAL Invalid devhandle/tsbnum/tsbindex
*
* Demap and flush IOMMU mappings in the device defined by the given
* devhandle. Demaps up to #ttes entries in the TSB defined by the tsbnum
* component of the given tsbid, starting at the TSB index defined by the
* tsbindex component of the given tsbid.
*
* For this version of the spec, the tsbnum of the given tsbid must be zero.
* #ttes must be greater than zero.
*
* Returns the actual number of ttes demapped, which may be less than or equal
* to the argument #ttes. If #ttes demapped is less than #ttes, the caller
* may continue to call this function with updated tsbid and #ttes arguments
* until all pages are demapped.
*
* Note: Entries do not have to be mapped to be demapped. A demap of an
* unmapped page will flush the entry from the tte cache.
*/
#define HV_FAST_PCI_IOMMU_DEMAP 0xb1
/* pci_iommu_getmap()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_IOMMU_GETMAP
* ARG0: devhandle
* ARG1: tsbid
* RET0: status
* RET1: io_attributes
* RET2: real address
* ERRORS: EINVAL Invalid devhandle/tsbnum/tsbindex
* ENOMAP Mapping is not valid, no translation exists
*
* Read and return the mapping in the device described by the given devhandle
* and tsbid. If successful, the io_attributes shall be returned in RET1
* and the page address of the mapping shall be returned in RET2.
*
* For this version of the spec, the tsbnum component of the given tsbid
* must be zero.
*/
#define HV_FAST_PCI_IOMMU_GETMAP 0xb2
/* pci_iommu_getbypass()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_IOMMU_GETBYPASS
* ARG0: devhandle
* ARG1: real address
* ARG2: io_attributes
* RET0: status
* RET1: io_addr
* ERRORS: EINVAL Invalid devhandle/io_attributes
* ENORADDR Invalid real address
* ENOTSUPPORTED Function not supported in this implementation.
*
* Create a "special" mapping in the device described by the given devhandle,
* for the given real address and attributes. Return the IO address in RET1
* if successful.
*/
#define HV_FAST_PCI_IOMMU_GETBYPASS 0xb3
/* pci_config_get()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_CONFIG_GET
* ARG0: devhandle
* ARG1: pci_device
* ARG2: pci_config_offset
* ARG3: size
* RET0: status
* RET1: error_flag
* RET2: data
* ERRORS: EINVAL Invalid devhandle/pci_device/offset/size
* EBADALIGN pci_config_offset not size aligned
* ENOACCESS Access to this offset is not permitted
*
* Read PCI configuration space for the adapter described by the given
* devhandle. Read size (1, 2, or 4) bytes of data from the given
* pci_device, at pci_config_offset from the beginning of the device's
* configuration space. If there was no error, RET1 is set to zero and
* RET2 is set to the data read. Insignificant bits in RET2 are not
* guarenteed to have any specific value and therefore must be ignored.
*
* The data returned in RET2 is size based byte swapped.
*
* If an error occurs during the read, set RET1 to a non-zero value. The
* given pci_config_offset must be 'size' aligned.
*/
#define HV_FAST_PCI_CONFIG_GET 0xb4
/* pci_config_put()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_CONFIG_PUT
* ARG0: devhandle
* ARG1: pci_device
* ARG2: pci_config_offset
* ARG3: size
* ARG4: data
* RET0: status
* RET1: error_flag
* ERRORS: EINVAL Invalid devhandle/pci_device/offset/size
* EBADALIGN pci_config_offset not size aligned
* ENOACCESS Access to this offset is not permitted
*
* Write PCI configuration space for the adapter described by the given
* devhandle. Write size (1, 2, or 4) bytes of data in a single operation,
* at pci_config_offset from the beginning of the device's configuration
* space. The data argument contains the data to be written to configuration
* space. Prior to writing, the data is size based byte swapped.
*
* If an error occurs during the write access, do not generate an error
* report, do set RET1 to a non-zero value. Otherwise RET1 is zero.
* The given pci_config_offset must be 'size' aligned.
*
* This function is permitted to read from offset zero in the configuration
* space described by the given pci_device if necessary to ensure that the
* write access to config space completes.
*/
#define HV_FAST_PCI_CONFIG_PUT 0xb5
/* pci_peek()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_PEEK
* ARG0: devhandle
* ARG1: real address
* ARG2: size
* RET0: status
* RET1: error_flag
* RET2: data
* ERRORS: EINVAL Invalid devhandle or size
* EBADALIGN Improperly aligned real address
* ENORADDR Bad real address
* ENOACCESS Guest access prohibited
*
* Attempt to read the IO address given by the given devhandle, real address,
* and size. Size must be 1, 2, 4, or 8. The read is performed as a single
* access operation using the given size. If an error occurs when reading
* from the given location, do not generate an error report, but return a
* non-zero value in RET1. If the read was successful, return zero in RET1
* and return the actual data read in RET2. The data returned is size based
* byte swapped.
*
* Non-significant bits in RET2 are not guarenteed to have any specific value
* and therefore must be ignored. If RET1 is returned as non-zero, the data
* value is not guarenteed to have any specific value and should be ignored.
*
* The caller must have permission to read from the given devhandle, real
* address, which must be an IO address. The argument real address must be a
* size aligned address.
*
* The hypervisor implementation of this function must block access to any
* IO address that the guest does not have explicit permission to access.
*/
#define HV_FAST_PCI_PEEK 0xb6
/* pci_poke()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_POKE
* ARG0: devhandle
* ARG1: real address
* ARG2: size
* ARG3: data
* ARG4: pci_device
* RET0: status
* RET1: error_flag
* ERRORS: EINVAL Invalid devhandle, size, or pci_device
* EBADALIGN Improperly aligned real address
* ENORADDR Bad real address
* ENOACCESS Guest access prohibited
* ENOTSUPPORTED Function is not supported by implementation
*
* Attempt to write data to the IO address given by the given devhandle,
* real address, and size. Size must be 1, 2, 4, or 8. The write is
* performed as a single access operation using the given size. Prior to
* writing the data is size based swapped.
*
* If an error occurs when writing to the given location, do not generate an
* error report, but return a non-zero value in RET1. If the write was
* successful, return zero in RET1.
*
* pci_device describes the configuration address of the device being
* written to. The implementation may safely read from offset 0 with
* the configuration space of the device described by devhandle and
* pci_device in order to guarantee that the write portion of the operation
* completes
*
* Any error that occurs due to the read shall be reported using the normal
* error reporting mechanisms .. the read error is not suppressed.
*
* The caller must have permission to write to the given devhandle, real
* address, which must be an IO address. The argument real address must be a
* size aligned address. The caller must have permission to read from
* the given devhandle, pci_device cofiguration space offset 0.
*
* The hypervisor implementation of this function must block access to any
* IO address that the guest does not have explicit permission to access.
*/
#define HV_FAST_PCI_POKE 0xb7
/* pci_dma_sync()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_DMA_SYNC
* ARG0: devhandle
* ARG1: real address
* ARG2: size
* ARG3: io_sync_direction
* RET0: status
* RET1: #synced
* ERRORS: EINVAL Invalid devhandle or io_sync_direction
* ENORADDR Bad real address
*
* Synchronize a memory region described by the given real address and size,
* for the device defined by the given devhandle using the direction(s)
* defined by the given io_sync_direction. The argument size is the size of
* the memory region in bytes.
*
* Return the actual number of bytes synchronized in the return value #synced,
* which may be less than or equal to the argument size. If the return
* value #synced is less than size, the caller must continue to call this
* function with updated real address and size arguments until the entire
* memory region is synchronized.
*/
#define HV_FAST_PCI_DMA_SYNC 0xb8
/* PCI MSI services. */
#define HV_MSITYPE_MSI32 0x00
#define HV_MSITYPE_MSI64 0x01
#define HV_MSIQSTATE_IDLE 0x00
#define HV_MSIQSTATE_ERROR 0x01
#define HV_MSIQ_INVALID 0x00
#define HV_MSIQ_VALID 0x01
#define HV_MSISTATE_IDLE 0x00
#define HV_MSISTATE_DELIVERED 0x01
#define HV_MSIVALID_INVALID 0x00
#define HV_MSIVALID_VALID 0x01
#define HV_PCIE_MSGTYPE_PME_MSG 0x18
#define HV_PCIE_MSGTYPE_PME_ACK_MSG 0x1b
#define HV_PCIE_MSGTYPE_CORR_MSG 0x30
#define HV_PCIE_MSGTYPE_NONFATAL_MSG 0x31
#define HV_PCIE_MSGTYPE_FATAL_MSG 0x33
#define HV_MSG_INVALID 0x00
#define HV_MSG_VALID 0x01
/* pci_msiq_conf()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_CONF
* ARG0: devhandle
* ARG1: msiqid
* ARG2: real address
* ARG3: number of entries
* RET0: status
* ERRORS: EINVAL Invalid devhandle, msiqid or nentries
* EBADALIGN Improperly aligned real address
* ENORADDR Bad real address
*
* Configure the MSI queue given by the devhandle and msiqid arguments,
* and to be placed at the given real address and be of the given
* number of entries. The real address must be aligned exactly to match
* the queue size. Each queue entry is 64-bytes long, so f.e. a 32 entry
* queue must be aligned on a 2048 byte real address boundary. The MSI-EQ
* Head and Tail are initialized so that the MSI-EQ is 'empty'.
*
* Implementation Note: Certain implementations have fixed sized queues. In
* that case, number of entries must contain the correct
* value.
*/
#define HV_FAST_PCI_MSIQ_CONF 0xc0
/* pci_msiq_info()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_INFO
* ARG0: devhandle
* ARG1: msiqid
* RET0: status
* RET1: real address
* RET2: number of entries
* ERRORS: EINVAL Invalid devhandle or msiqid
*
* Return the configuration information for the MSI queue described
* by the given devhandle and msiqid. The base address of the queue
* is returned in ARG1 and the number of entries is returned in ARG2.
* If the queue is unconfigured, the real address is undefined and the
* number of entries will be returned as zero.
*/
#define HV_FAST_PCI_MSIQ_INFO 0xc1
/* pci_msiq_getvalid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_GETVALID
* ARG0: devhandle
* ARG1: msiqid
* RET0: status
* RET1: msiqvalid (HV_MSIQ_VALID or HV_MSIQ_INVALID)
* ERRORS: EINVAL Invalid devhandle or msiqid
*
* Get the valid state of the MSI-EQ described by the given devhandle and
* msiqid.
*/
#define HV_FAST_PCI_MSIQ_GETVALID 0xc2
/* pci_msiq_setvalid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_SETVALID
* ARG0: devhandle
* ARG1: msiqid
* ARG2: msiqvalid (HV_MSIQ_VALID or HV_MSIQ_INVALID)
* RET0: status
* ERRORS: EINVAL Invalid devhandle or msiqid or msiqvalid
* value or MSI EQ is uninitialized
*
* Set the valid state of the MSI-EQ described by the given devhandle and
* msiqid to the given msiqvalid.
*/
#define HV_FAST_PCI_MSIQ_SETVALID 0xc3
/* pci_msiq_getstate()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_GETSTATE
* ARG0: devhandle
* ARG1: msiqid
* RET0: status
* RET1: msiqstate (HV_MSIQSTATE_IDLE or HV_MSIQSTATE_ERROR)
* ERRORS: EINVAL Invalid devhandle or msiqid
*
* Get the state of the MSI-EQ described by the given devhandle and
* msiqid.
*/
#define HV_FAST_PCI_MSIQ_GETSTATE 0xc4
/* pci_msiq_getvalid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_GETVALID
* ARG0: devhandle
* ARG1: msiqid
* ARG2: msiqstate (HV_MSIQSTATE_IDLE or HV_MSIQSTATE_ERROR)
* RET0: status
* ERRORS: EINVAL Invalid devhandle or msiqid or msiqstate
* value or MSI EQ is uninitialized
*
* Set the state of the MSI-EQ described by the given devhandle and
* msiqid to the given msiqvalid.
*/
#define HV_FAST_PCI_MSIQ_SETSTATE 0xc5
/* pci_msiq_gethead()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_GETHEAD
* ARG0: devhandle
* ARG1: msiqid
* RET0: status
* RET1: msiqhead
* ERRORS: EINVAL Invalid devhandle or msiqid
*
* Get the current MSI EQ queue head for the MSI-EQ described by the
* given devhandle and msiqid.
*/
#define HV_FAST_PCI_MSIQ_GETHEAD 0xc6
/* pci_msiq_sethead()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_SETHEAD
* ARG0: devhandle
* ARG1: msiqid
* ARG2: msiqhead
* RET0: status
* ERRORS: EINVAL Invalid devhandle or msiqid or msiqhead,
* or MSI EQ is uninitialized
*
* Set the current MSI EQ queue head for the MSI-EQ described by the
* given devhandle and msiqid.
*/
#define HV_FAST_PCI_MSIQ_SETHEAD 0xc7
/* pci_msiq_gettail()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_GETTAIL
* ARG0: devhandle
* ARG1: msiqid
* RET0: status
* RET1: msiqtail
* ERRORS: EINVAL Invalid devhandle or msiqid
*
* Get the current MSI EQ queue tail for the MSI-EQ described by the
* given devhandle and msiqid.
*/
#define HV_FAST_PCI_MSIQ_GETTAIL 0xc8
/* pci_msi_getvalid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSI_GETVALID
* ARG0: devhandle
* ARG1: msinum
* RET0: status
* RET1: msivalidstate
* ERRORS: EINVAL Invalid devhandle or msinum
*
* Get the current valid/enabled state for the MSI defined by the
* given devhandle and msinum.
*/
#define HV_FAST_PCI_MSI_GETVALID 0xc9
/* pci_msi_setvalid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSI_SETVALID
* ARG0: devhandle
* ARG1: msinum
* ARG2: msivalidstate
* RET0: status
* ERRORS: EINVAL Invalid devhandle or msinum or msivalidstate
*
* Set the current valid/enabled state for the MSI defined by the
* given devhandle and msinum.
*/
#define HV_FAST_PCI_MSI_SETVALID 0xca
/* pci_msi_getmsiq()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSI_GETMSIQ
* ARG0: devhandle
* ARG1: msinum
* RET0: status
* RET1: msiqid
* ERRORS: EINVAL Invalid devhandle or msinum or MSI is unbound
*
* Get the MSI EQ that the MSI defined by the given devhandle and
* msinum is bound to.
*/
#define HV_FAST_PCI_MSI_GETMSIQ 0xcb
/* pci_msi_setmsiq()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSI_SETMSIQ
* ARG0: devhandle
* ARG1: msinum
* ARG2: msitype
* ARG3: msiqid
* RET0: status
* ERRORS: EINVAL Invalid devhandle or msinum or msiqid
*
* Set the MSI EQ that the MSI defined by the given devhandle and
* msinum is bound to.
*/
#define HV_FAST_PCI_MSI_SETMSIQ 0xcc
/* pci_msi_getstate()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSI_GETSTATE
* ARG0: devhandle
* ARG1: msinum
* RET0: status
* RET1: msistate
* ERRORS: EINVAL Invalid devhandle or msinum
*
* Get the state of the MSI defined by the given devhandle and msinum.
* If not initialized, return HV_MSISTATE_IDLE.
*/
#define HV_FAST_PCI_MSI_GETSTATE 0xcd
/* pci_msi_setstate()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSI_SETSTATE
* ARG0: devhandle
* ARG1: msinum
* ARG2: msistate
* RET0: status
* ERRORS: EINVAL Invalid devhandle or msinum or msistate
*
* Set the state of the MSI defined by the given devhandle and msinum.
*/
#define HV_FAST_PCI_MSI_SETSTATE 0xce
/* pci_msg_getmsiq()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSG_GETMSIQ
* ARG0: devhandle
* ARG1: msgtype
* RET0: status
* RET1: msiqid
* ERRORS: EINVAL Invalid devhandle or msgtype
*
* Get the MSI EQ of the MSG defined by the given devhandle and msgtype.
*/
#define HV_FAST_PCI_MSG_GETMSIQ 0xd0
/* pci_msg_setmsiq()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSG_SETMSIQ
* ARG0: devhandle
* ARG1: msgtype
* ARG2: msiqid
* RET0: status
* ERRORS: EINVAL Invalid devhandle, msgtype, or msiqid
*
* Set the MSI EQ of the MSG defined by the given devhandle and msgtype.
*/
#define HV_FAST_PCI_MSG_SETMSIQ 0xd1
/* pci_msg_getvalid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSG_GETVALID
* ARG0: devhandle
* ARG1: msgtype
* RET0: status
* RET1: msgvalidstate
* ERRORS: EINVAL Invalid devhandle or msgtype
*
* Get the valid/enabled state of the MSG defined by the given
* devhandle and msgtype.
*/
#define HV_FAST_PCI_MSG_GETVALID 0xd2
/* pci_msg_setvalid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSG_SETVALID
* ARG0: devhandle
* ARG1: msgtype
* ARG2: msgvalidstate
* RET0: status
* ERRORS: EINVAL Invalid devhandle or msgtype or msgvalidstate
*
* Set the valid/enabled state of the MSG defined by the given
* devhandle and msgtype.
*/
#define HV_FAST_PCI_MSG_SETVALID 0xd3
/* Logical Domain Channel services. */
#define LDC_CHANNEL_DOWN 0
#define LDC_CHANNEL_UP 1
#define LDC_CHANNEL_RESETTING 2
/* ldc_tx_qconf()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_TX_QCONF
* ARG0: channel ID
* ARG1: real address base of queue
* ARG2: num entries in queue
* RET0: status
*
* Configure transmit queue for the LDC endpoint specified by the
* given channel ID, to be placed at the given real address, and
* be of the given num entries. Num entries must be a power of two.
* The real address base of the queue must be aligned on the queue
* size. Each queue entry is 64-bytes, so for example, a 32 entry
* queue must be aligned on a 2048 byte real address boundary.
*
* Upon configuration of a valid transmit queue the head and tail
* pointers are set to a hypervisor specific identical value indicating
* that the queue initially is empty.
*
* The endpoint's transmit queue is un-configured if num entries is zero.
*
* The maximum number of entries for each queue for a specific cpu may be
* determined from the machine description. A transmit queue may be
* specified even in the event that the LDC is down (peer endpoint has no
* receive queue specified). Transmission will begin as soon as the peer
* endpoint defines a receive queue.
*
* It is recommended that a guest wait for a transmit queue to empty prior
* to reconfiguring it, or un-configuring it. Re or un-configuring of a
* non-empty transmit queue behaves exactly as defined above, however it
* is undefined as to how many of the pending entries in the original queue
* will be delivered prior to the re-configuration taking effect.
* Furthermore, as the queue configuration causes a reset of the head and
* tail pointers there is no way for a guest to determine how many entries
* have been sent after the configuration operation.
*/
#define HV_FAST_LDC_TX_QCONF 0xe0
/* ldc_tx_qinfo()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_TX_QINFO
* ARG0: channel ID
* RET0: status
* RET1: real address base of queue
* RET2: num entries in queue
*
* Return the configuration info for the transmit queue of LDC endpoint
* defined by the given channel ID. The real address is the currently
* defined real address base of the defined queue, and num entries is the
* size of the queue in terms of number of entries.
*
* If the specified channel ID is a valid endpoint number, but no transmit
* queue has been defined this service will return success, but with num
* entries set to zero and the real address will have an undefined value.
*/
#define HV_FAST_LDC_TX_QINFO 0xe1
/* ldc_tx_get_state()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_TX_GET_STATE
* ARG0: channel ID
* RET0: status
* RET1: head offset
* RET2: tail offset
* RET3: channel state
*
* Return the transmit state, and the head and tail queue pointers, for
* the transmit queue of the LDC endpoint defined by the given channel ID.
* The head and tail values are the byte offset of the head and tail
* positions of the transmit queue for the specified endpoint.
*/
#define HV_FAST_LDC_TX_GET_STATE 0xe2
/* ldc_tx_set_qtail()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_TX_SET_QTAIL
* ARG0: channel ID
* ARG1: tail offset
* RET0: status
*
* Update the tail pointer for the transmit queue associated with the LDC
* endpoint defined by the given channel ID. The tail offset specified
* must be aligned on a 64 byte boundary, and calculated so as to increase
* the number of pending entries on the transmit queue. Any attempt to
* decrease the number of pending transmit queue entires is considered
* an invalid tail offset and will result in an EINVAL error.
*
* Since the tail of the transmit queue may not be moved backwards, the
* transmit queue may be flushed by configuring a new transmit queue,
* whereupon the hypervisor will configure the initial transmit head and
* tail pointers to be equal.
*/
#define HV_FAST_LDC_TX_SET_QTAIL 0xe3
/* ldc_rx_qconf()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_RX_QCONF
* ARG0: channel ID
* ARG1: real address base of queue
* ARG2: num entries in queue
* RET0: status
*
* Configure receive queue for the LDC endpoint specified by the
* given channel ID, to be placed at the given real address, and
* be of the given num entries. Num entries must be a power of two.
* The real address base of the queue must be aligned on the queue
* size. Each queue entry is 64-bytes, so for example, a 32 entry
* queue must be aligned on a 2048 byte real address boundary.
*
* The endpoint's transmit queue is un-configured if num entries is zero.
*
* If a valid receive queue is specified for a local endpoint the LDC is
* in the up state for the purpose of transmission to this endpoint.
*
* The maximum number of entries for each queue for a specific cpu may be
* determined from the machine description.
*
* As receive queue configuration causes a reset of the queue's head and
* tail pointers there is no way for a gues to determine how many entries
* have been received between a preceeding ldc_get_rx_state() API call
* and the completion of the configuration operation. It should be noted
* that datagram delivery is not guarenteed via domain channels anyway,
* and therefore any higher protocol should be resilient to datagram
* loss if necessary. However, to overcome this specific race potential
* it is recommended, for example, that a higher level protocol be employed
* to ensure either retransmission, or ensure that no datagrams are pending
* on the peer endpoint's transmit queue prior to the configuration process.
*/
#define HV_FAST_LDC_RX_QCONF 0xe4
/* ldc_rx_qinfo()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_RX_QINFO
* ARG0: channel ID
* RET0: status
* RET1: real address base of queue
* RET2: num entries in queue
*
* Return the configuration info for the receive queue of LDC endpoint
* defined by the given channel ID. The real address is the currently
* defined real address base of the defined queue, and num entries is the
* size of the queue in terms of number of entries.
*
* If the specified channel ID is a valid endpoint number, but no receive
* queue has been defined this service will return success, but with num
* entries set to zero and the real address will have an undefined value.
*/
#define HV_FAST_LDC_RX_QINFO 0xe5
/* ldc_rx_get_state()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_RX_GET_STATE
* ARG0: channel ID
* RET0: status
* RET1: head offset
* RET2: tail offset
* RET3: channel state
*
* Return the receive state, and the head and tail queue pointers, for
* the receive queue of the LDC endpoint defined by the given channel ID.
* The head and tail values are the byte offset of the head and tail
* positions of the receive queue for the specified endpoint.
*/
#define HV_FAST_LDC_RX_GET_STATE 0xe6
/* ldc_rx_set_qhead()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_RX_SET_QHEAD
* ARG0: channel ID
* ARG1: head offset
* RET0: status
*
* Update the head pointer for the receive queue associated with the LDC
* endpoint defined by the given channel ID. The head offset specified
* must be aligned on a 64 byte boundary, and calculated so as to decrease
* the number of pending entries on the receive queue. Any attempt to
* increase the number of pending receive queue entires is considered
* an invalid head offset and will result in an EINVAL error.
*
* The receive queue may be flushed by setting the head offset equal
* to the current tail offset.
*/
#define HV_FAST_LDC_RX_SET_QHEAD 0xe7
/* LDC Map Table Entry. Each slot is defined by a translation table
* entry, as specified by the LDC_MTE_* bits below, and a 64-bit
* hypervisor invalidation cookie.
*/
#define LDC_MTE_PADDR 0x0fffffffffffe000 /* pa[55:13] */
#define LDC_MTE_COPY_W 0x0000000000000400 /* copy write access */
#define LDC_MTE_COPY_R 0x0000000000000200 /* copy read access */
#define LDC_MTE_IOMMU_W 0x0000000000000100 /* IOMMU write access */
#define LDC_MTE_IOMMU_R 0x0000000000000080 /* IOMMU read access */
#define LDC_MTE_EXEC 0x0000000000000040 /* execute */
#define LDC_MTE_WRITE 0x0000000000000020 /* read */
#define LDC_MTE_READ 0x0000000000000010 /* write */
#define LDC_MTE_SZALL 0x000000000000000f /* page size bits */
#define LDC_MTE_SZ16GB 0x0000000000000007 /* 16GB page */
#define LDC_MTE_SZ2GB 0x0000000000000006 /* 2GB page */
#define LDC_MTE_SZ256MB 0x0000000000000005 /* 256MB page */
#define LDC_MTE_SZ32MB 0x0000000000000004 /* 32MB page */
#define LDC_MTE_SZ4MB 0x0000000000000003 /* 4MB page */
#define LDC_MTE_SZ512K 0x0000000000000002 /* 512K page */
#define LDC_MTE_SZ64K 0x0000000000000001 /* 64K page */
#define LDC_MTE_SZ8K 0x0000000000000000 /* 8K page */
#ifndef __ASSEMBLY__
struct ldc_mtable_entry {
unsigned long mte;
unsigned long cookie;
};
#endif
/* ldc_set_map_table()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_SET_MAP_TABLE
* ARG0: channel ID
* ARG1: table real address
* ARG2: num entries
* RET0: status
*
* Register the MTE table at the given table real address, with the
* specified num entries, for the LDC indicated by the given channel
* ID.
*/
#define HV_FAST_LDC_SET_MAP_TABLE 0xea
/* ldc_get_map_table()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_GET_MAP_TABLE
* ARG0: channel ID
* RET0: status
* RET1: table real address
* RET2: num entries
*
* Return the configuration of the current mapping table registered
* for the given channel ID.
*/
#define HV_FAST_LDC_GET_MAP_TABLE 0xeb
#define LDC_COPY_IN 0
#define LDC_COPY_OUT 1
/* ldc_copy()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_COPY
* ARG0: channel ID
* ARG1: LDC_COPY_* direction code
* ARG2: target real address
* ARG3: local real address
* ARG4: length in bytes
* RET0: status
* RET1: actual length in bytes
*/
#define HV_FAST_LDC_COPY 0xec
#define LDC_MEM_READ 1
#define LDC_MEM_WRITE 2
#define LDC_MEM_EXEC 4
/* ldc_mapin()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_MAPIN
* ARG0: channel ID
* ARG1: cookie
* RET0: status
* RET1: real address
* RET2: LDC_MEM_* permissions
*/
#define HV_FAST_LDC_MAPIN 0xed
/* ldc_unmap()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_UNMAP
* ARG0: real address
* RET0: status
*/
#define HV_FAST_LDC_UNMAP 0xee
/* ldc_revoke()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_REVOKE
* ARG0: channel ID
* ARG1: cookie
* ARG2: ldc_mtable_entry cookie
* RET0: status
*/
#define HV_FAST_LDC_REVOKE 0xef
#ifndef __ASSEMBLY__
extern unsigned long sun4v_ldc_tx_qconf(unsigned long channel,
unsigned long ra,
unsigned long num_entries);
extern unsigned long sun4v_ldc_tx_qinfo(unsigned long channel,
unsigned long *ra,
unsigned long *num_entries);
extern unsigned long sun4v_ldc_tx_get_state(unsigned long channel,
unsigned long *head_off,
unsigned long *tail_off,
unsigned long *chan_state);
extern unsigned long sun4v_ldc_tx_set_qtail(unsigned long channel,
unsigned long tail_off);
extern unsigned long sun4v_ldc_rx_qconf(unsigned long channel,
unsigned long ra,
unsigned long num_entries);
extern unsigned long sun4v_ldc_rx_qinfo(unsigned long channel,
unsigned long *ra,
unsigned long *num_entries);
extern unsigned long sun4v_ldc_rx_get_state(unsigned long channel,
unsigned long *head_off,
unsigned long *tail_off,
unsigned long *chan_state);
extern unsigned long sun4v_ldc_rx_set_qhead(unsigned long channel,
unsigned long head_off);
extern unsigned long sun4v_ldc_set_map_table(unsigned long channel,
unsigned long ra,
unsigned long num_entries);
extern unsigned long sun4v_ldc_get_map_table(unsigned long channel,
unsigned long *ra,
unsigned long *num_entries);
extern unsigned long sun4v_ldc_copy(unsigned long channel,
unsigned long dir_code,
unsigned long tgt_raddr,
unsigned long lcl_raddr,
unsigned long len,
unsigned long *actual_len);
extern unsigned long sun4v_ldc_mapin(unsigned long channel,
unsigned long cookie,
unsigned long *ra,
unsigned long *perm);
extern unsigned long sun4v_ldc_unmap(unsigned long ra);
extern unsigned long sun4v_ldc_revoke(unsigned long channel,
unsigned long cookie,
unsigned long mte_cookie);
#endif
/* Performance counter services. */
#define HV_PERF_JBUS_PERF_CTRL_REG 0x00
#define HV_PERF_JBUS_PERF_CNT_REG 0x01
#define HV_PERF_DRAM_PERF_CTRL_REG_0 0x02
#define HV_PERF_DRAM_PERF_CNT_REG_0 0x03
#define HV_PERF_DRAM_PERF_CTRL_REG_1 0x04
#define HV_PERF_DRAM_PERF_CNT_REG_1 0x05
#define HV_PERF_DRAM_PERF_CTRL_REG_2 0x06
#define HV_PERF_DRAM_PERF_CNT_REG_2 0x07
#define HV_PERF_DRAM_PERF_CTRL_REG_3 0x08
#define HV_PERF_DRAM_PERF_CNT_REG_3 0x09
/* get_perfreg()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_GET_PERFREG
* ARG0: performance reg number
* RET0: status
* RET1: performance reg value
* ERRORS: EINVAL Invalid performance register number
* ENOACCESS No access allowed to performance counters
*
* Read the value of the given DRAM/JBUS performance counter/control register.
*/
#define HV_FAST_GET_PERFREG 0x100
/* set_perfreg()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_SET_PERFREG
* ARG0: performance reg number
* ARG1: performance reg value
* RET0: status
* ERRORS: EINVAL Invalid performance register number
* ENOACCESS No access allowed to performance counters
*
* Write the given performance reg value to the given DRAM/JBUS
* performance counter/control register.
*/
#define HV_FAST_SET_PERFREG 0x101
/* MMU statistics services.
*
* The hypervisor maintains MMU statistics and privileged code provides
* a buffer where these statistics can be collected. It is continually
* updated once configured. The layout is as follows:
*/
#ifndef __ASSEMBLY__
struct hv_mmu_statistics {
unsigned long immu_tsb_hits_ctx0_8k_tte;
unsigned long immu_tsb_ticks_ctx0_8k_tte;
unsigned long immu_tsb_hits_ctx0_64k_tte;
unsigned long immu_tsb_ticks_ctx0_64k_tte;
unsigned long __reserved1[2];
unsigned long immu_tsb_hits_ctx0_4mb_tte;
unsigned long immu_tsb_ticks_ctx0_4mb_tte;
unsigned long __reserved2[2];
unsigned long immu_tsb_hits_ctx0_256mb_tte;
unsigned long immu_tsb_ticks_ctx0_256mb_tte;
unsigned long __reserved3[4];
unsigned long immu_tsb_hits_ctxnon0_8k_tte;
unsigned long immu_tsb_ticks_ctxnon0_8k_tte;
unsigned long immu_tsb_hits_ctxnon0_64k_tte;
unsigned long immu_tsb_ticks_ctxnon0_64k_tte;
unsigned long __reserved4[2];
unsigned long immu_tsb_hits_ctxnon0_4mb_tte;
unsigned long immu_tsb_ticks_ctxnon0_4mb_tte;
unsigned long __reserved5[2];
unsigned long immu_tsb_hits_ctxnon0_256mb_tte;
unsigned long immu_tsb_ticks_ctxnon0_256mb_tte;
unsigned long __reserved6[4];
unsigned long dmmu_tsb_hits_ctx0_8k_tte;
unsigned long dmmu_tsb_ticks_ctx0_8k_tte;
unsigned long dmmu_tsb_hits_ctx0_64k_tte;
unsigned long dmmu_tsb_ticks_ctx0_64k_tte;
unsigned long __reserved7[2];
unsigned long dmmu_tsb_hits_ctx0_4mb_tte;
unsigned long dmmu_tsb_ticks_ctx0_4mb_tte;
unsigned long __reserved8[2];
unsigned long dmmu_tsb_hits_ctx0_256mb_tte;
unsigned long dmmu_tsb_ticks_ctx0_256mb_tte;
unsigned long __reserved9[4];
unsigned long dmmu_tsb_hits_ctxnon0_8k_tte;
unsigned long dmmu_tsb_ticks_ctxnon0_8k_tte;
unsigned long dmmu_tsb_hits_ctxnon0_64k_tte;
unsigned long dmmu_tsb_ticks_ctxnon0_64k_tte;
unsigned long __reserved10[2];
unsigned long dmmu_tsb_hits_ctxnon0_4mb_tte;
unsigned long dmmu_tsb_ticks_ctxnon0_4mb_tte;
unsigned long __reserved11[2];
unsigned long dmmu_tsb_hits_ctxnon0_256mb_tte;
unsigned long dmmu_tsb_ticks_ctxnon0_256mb_tte;
unsigned long __reserved12[4];
};
#endif
/* mmustat_conf()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMUSTAT_CONF
* ARG0: real address
* RET0: status
* RET1: real address
* ERRORS: ENORADDR Invalid real address
* EBADALIGN Real address not aligned on 64-byte boundary
* EBADTRAP API not supported on this processor
*
* Enable MMU statistic gathering using the buffer at the given real
* address on the current virtual CPU. The new buffer real address
* is given in ARG1, and the previously specified buffer real address
* is returned in RET1, or is returned as zero for the first invocation.
*
* If the passed in real address argument is zero, this will disable
* MMU statistic collection on the current virtual CPU. If an error is
* returned then no statistics are collected.
*
* The buffer contents should be initialized to all zeros before being
* given to the hypervisor or else the statistics will be meaningless.
*/
#define HV_FAST_MMUSTAT_CONF 0x102
/* mmustat_info()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMUSTAT_INFO
* RET0: status
* RET1: real address
* ERRORS: EBADTRAP API not supported on this processor
*
* Return the current state and real address of the currently configured
* MMU statistics buffer on the current virtual CPU.
*/
#define HV_FAST_MMUSTAT_INFO 0x103
#ifndef __ASSEMBLY__
extern unsigned long sun4v_mmustat_conf(unsigned long ra, unsigned long *orig_ra);
extern unsigned long sun4v_mmustat_info(unsigned long *ra);
#endif
/* NCS crypto services */
/* ncs_request() sub-function numbers */
#define HV_NCS_QCONF 0x01
#define HV_NCS_QTAIL_UPDATE 0x02
#ifndef __ASSEMBLY__
struct hv_ncs_queue_entry {
/* MAU Control Register */
unsigned long mau_control;
#define MAU_CONTROL_INV_PARITY 0x0000000000002000
#define MAU_CONTROL_STRAND 0x0000000000001800
#define MAU_CONTROL_BUSY 0x0000000000000400
#define MAU_CONTROL_INT 0x0000000000000200
#define MAU_CONTROL_OP 0x00000000000001c0
#define MAU_CONTROL_OP_SHIFT 6
#define MAU_OP_LOAD_MA_MEMORY 0x0
#define MAU_OP_STORE_MA_MEMORY 0x1
#define MAU_OP_MODULAR_MULT 0x2
#define MAU_OP_MODULAR_REDUCE 0x3
#define MAU_OP_MODULAR_EXP_LOOP 0x4
#define MAU_CONTROL_LEN 0x000000000000003f
#define MAU_CONTROL_LEN_SHIFT 0
/* Real address of bytes to load or store bytes
* into/out-of the MAU.
*/
unsigned long mau_mpa;
/* Modular Arithmetic MA Offset Register. */
unsigned long mau_ma;
/* Modular Arithmetic N Prime Register. */
unsigned long mau_np;
};
struct hv_ncs_qconf_arg {
unsigned long mid; /* MAU ID, 1 per core on Niagara */
unsigned long base; /* Real address base of queue */
unsigned long end; /* Real address end of queue */
unsigned long num_ents; /* Number of entries in queue */
};
struct hv_ncs_qtail_update_arg {
unsigned long mid; /* MAU ID, 1 per core on Niagara */
unsigned long tail; /* New tail index to use */
unsigned long syncflag; /* only SYNCFLAG_SYNC is implemented */
#define HV_NCS_SYNCFLAG_SYNC 0x00
#define HV_NCS_SYNCFLAG_ASYNC 0x01
};
#endif
/* ncs_request()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_NCS_REQUEST
* ARG0: NCS sub-function
* ARG1: sub-function argument real address
* ARG2: size in bytes of sub-function argument
* RET0: status
*
* The MAU chip of the Niagara processor is not directly accessible
* to privileged code, instead it is programmed indirectly via this
* hypervisor API.
*
* The interfaces defines a queue of MAU operations to perform.
* Privileged code registers a queue with the hypervisor by invoking
* this HVAPI with the HV_NCS_QCONF sub-function, which defines the
* base, end, and number of entries of the queue. Each queue entry
* contains a MAU register struct block.
*
* The privileged code then proceeds to add entries to the queue and
* then invoke the HV_NCS_QTAIL_UPDATE sub-function. Since only
* synchronous operations are supported by the current hypervisor,
* HV_NCS_QTAIL_UPDATE will run all the pending queue entries to
* completion and return HV_EOK, or return an error code.
*
* The real address of the sub-function argument must be aligned on at
* least an 8-byte boundary.
*
* The tail argument of HV_NCS_QTAIL_UPDATE is an index, not a byte
* offset, into the queue and must be less than or equal the 'num_ents'
* argument given in the HV_NCS_QCONF call.
*/
#define HV_FAST_NCS_REQUEST 0x110
#ifndef __ASSEMBLY__
extern unsigned long sun4v_ncs_request(unsigned long request,
unsigned long arg_ra,
unsigned long arg_size);
#endif
#define HV_FAST_FIRE_GET_PERFREG 0x120
#define HV_FAST_FIRE_SET_PERFREG 0x121
/* Function numbers for HV_CORE_TRAP. */
#define HV_CORE_SET_VER 0x00
#define HV_CORE_PUTCHAR 0x01
#define HV_CORE_EXIT 0x02
#define HV_CORE_GET_VER 0x03
/* Hypervisor API groups for use with HV_CORE_SET_VER and
* HV_CORE_GET_VER.
*/
#define HV_GRP_SUN4V 0x0000
#define HV_GRP_CORE 0x0001
#define HV_GRP_INTR 0x0002
#define HV_GRP_SOFT_STATE 0x0003
#define HV_GRP_PCI 0x0100
#define HV_GRP_LDOM 0x0101
#define HV_GRP_SVC_CHAN 0x0102
#define HV_GRP_NCS 0x0103
#define HV_GRP_NIAG_PERF 0x0200
#define HV_GRP_FIRE_PERF 0x0201
#define HV_GRP_DIAG 0x0300
#ifndef __ASSEMBLY__
extern unsigned long sun4v_get_version(unsigned long group,
unsigned long *major,
unsigned long *minor);
extern unsigned long sun4v_set_version(unsigned long group,
unsigned long major,
unsigned long minor,
unsigned long *actual_minor);
extern int sun4v_hvapi_register(unsigned long group, unsigned long major,
unsigned long *minor);
extern void sun4v_hvapi_unregister(unsigned long group);
extern int sun4v_hvapi_get(unsigned long group,
unsigned long *major,
unsigned long *minor);
extern void sun4v_hvapi_init(void);
#endif
#endif /* !(_SPARC64_HYPERVISOR_H) */
#ifndef _SPARC64_INTR_QUEUE_H
#define _SPARC64_INTR_QUEUE_H
/* Sun4v interrupt queue registers, accessed via ASI_QUEUE. */
#define INTRQ_CPU_MONDO_HEAD 0x3c0 /* CPU mondo head */
#define INTRQ_CPU_MONDO_TAIL 0x3c8 /* CPU mondo tail */
#define INTRQ_DEVICE_MONDO_HEAD 0x3d0 /* Device mondo head */
#define INTRQ_DEVICE_MONDO_TAIL 0x3d8 /* Device mondo tail */
#define INTRQ_RESUM_MONDO_HEAD 0x3e0 /* Resumable error mondo head */
#define INTRQ_RESUM_MONDO_TAIL 0x3e8 /* Resumable error mondo tail */
#define INTRQ_NONRESUM_MONDO_HEAD 0x3f0 /* Non-resumable error mondo head */
#define INTRQ_NONRESUM_MONDO_TAIL 0x3f8 /* Non-resumable error mondo head */
#endif /* !(_SPARC64_INTR_QUEUE_H) */
#ifndef _SPARC64_KPROBES_H
#define _SPARC64_KPROBES_H
#include <linux/types.h>
#include <linux/percpu.h>
typedef u32 kprobe_opcode_t;
#define BREAKPOINT_INSTRUCTION 0x91d02070 /* ta 0x70 */
#define BREAKPOINT_INSTRUCTION_2 0x91d02071 /* ta 0x71 */
#define MAX_INSN_SIZE 2
#define kretprobe_blacklist_size 0
#define arch_remove_kprobe(p) do {} while (0)
#define flush_insn_slot(p) \
do { flushi(&(p)->ainsn.insn[0]); \
flushi(&(p)->ainsn.insn[1]); \
} while (0)
void kretprobe_trampoline(void);
/* Architecture specific copy of original instruction*/
struct arch_specific_insn {
/* copy of the original instruction */
kprobe_opcode_t insn[MAX_INSN_SIZE];
};
struct prev_kprobe {
struct kprobe *kp;
unsigned long status;
unsigned long orig_tnpc;
unsigned long orig_tstate_pil;
};
/* per-cpu kprobe control block */
struct kprobe_ctlblk {
unsigned long kprobe_status;
unsigned long kprobe_orig_tnpc;
unsigned long kprobe_orig_tstate_pil;
struct pt_regs jprobe_saved_regs;
struct prev_kprobe prev_kprobe;
};
extern int kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data);
extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
#endif /* _SPARC64_KPROBES_H */
#ifndef _SPARC64_LDC_H
#define _SPARC64_LDC_H
#include <asm/hypervisor.h>
extern int ldom_domaining_enabled;
extern void ldom_set_var(const char *var, const char *value);
extern void ldom_reboot(const char *boot_command);
extern void ldom_power_off(void);
/* The event handler will be evoked when link state changes
* or data becomes available on the receive side.
*
* For non-RAW links, if the LDC_EVENT_RESET event arrives the
* driver should reset all of it's internal state and reinvoke
* ldc_connect() to try and bring the link up again.
*
* For RAW links, ldc_connect() is not used. Instead the driver
* just waits for the LDC_EVENT_UP event.
*/
struct ldc_channel_config {
void (*event)(void *arg, int event);
u32 mtu;
unsigned int rx_irq;
unsigned int tx_irq;
u8 mode;
#define LDC_MODE_RAW 0x00
#define LDC_MODE_UNRELIABLE 0x01
#define LDC_MODE_RESERVED 0x02
#define LDC_MODE_STREAM 0x03
u8 debug;
#define LDC_DEBUG_HS 0x01
#define LDC_DEBUG_STATE 0x02
#define LDC_DEBUG_RX 0x04
#define LDC_DEBUG_TX 0x08
#define LDC_DEBUG_DATA 0x10
};
#define LDC_EVENT_RESET 0x01
#define LDC_EVENT_UP 0x02
#define LDC_EVENT_DATA_READY 0x04
#define LDC_STATE_INVALID 0x00
#define LDC_STATE_INIT 0x01
#define LDC_STATE_BOUND 0x02
#define LDC_STATE_READY 0x03
#define LDC_STATE_CONNECTED 0x04
struct ldc_channel;
/* Allocate state for a channel. */
extern struct ldc_channel *ldc_alloc(unsigned long id,
const struct ldc_channel_config *cfgp,
void *event_arg);
/* Shut down and free state for a channel. */
extern void ldc_free(struct ldc_channel *lp);
/* Register TX and RX queues of the link with the hypervisor. */
extern int ldc_bind(struct ldc_channel *lp, const char *name);
/* For non-RAW protocols we need to complete a handshake before
* communication can proceed. ldc_connect() does that, if the
* handshake completes successfully, an LDC_EVENT_UP event will
* be sent up to the driver.
*/
extern int ldc_connect(struct ldc_channel *lp);
extern int ldc_disconnect(struct ldc_channel *lp);
extern int ldc_state(struct ldc_channel *lp);
/* Read and write operations. Only valid when the link is up. */
extern int ldc_write(struct ldc_channel *lp, const void *buf,
unsigned int size);
extern int ldc_read(struct ldc_channel *lp, void *buf, unsigned int size);
#define LDC_MAP_SHADOW 0x01
#define LDC_MAP_DIRECT 0x02
#define LDC_MAP_IO 0x04
#define LDC_MAP_R 0x08
#define LDC_MAP_W 0x10
#define LDC_MAP_X 0x20
#define LDC_MAP_RW (LDC_MAP_R | LDC_MAP_W)
#define LDC_MAP_RWX (LDC_MAP_R | LDC_MAP_W | LDC_MAP_X)
#define LDC_MAP_ALL 0x03f
struct ldc_trans_cookie {
u64 cookie_addr;
u64 cookie_size;
};
struct scatterlist;
extern int ldc_map_sg(struct ldc_channel *lp,
struct scatterlist *sg, int num_sg,
struct ldc_trans_cookie *cookies, int ncookies,
unsigned int map_perm);
extern int ldc_map_single(struct ldc_channel *lp,
void *buf, unsigned int len,
struct ldc_trans_cookie *cookies, int ncookies,
unsigned int map_perm);
extern void ldc_unmap(struct ldc_channel *lp, struct ldc_trans_cookie *cookies,
int ncookies);
extern int ldc_copy(struct ldc_channel *lp, int copy_dir,
void *buf, unsigned int len, unsigned long offset,
struct ldc_trans_cookie *cookies, int ncookies);
static inline int ldc_get_dring_entry(struct ldc_channel *lp,
void *buf, unsigned int len,
unsigned long offset,
struct ldc_trans_cookie *cookies,
int ncookies)
{
return ldc_copy(lp, LDC_COPY_IN, buf, len, offset, cookies, ncookies);
}
static inline int ldc_put_dring_entry(struct ldc_channel *lp,
void *buf, unsigned int len,
unsigned long offset,
struct ldc_trans_cookie *cookies,
int ncookies)
{
return ldc_copy(lp, LDC_COPY_OUT, buf, len, offset, cookies, ncookies);
}
extern void *ldc_alloc_exp_dring(struct ldc_channel *lp, unsigned int len,
struct ldc_trans_cookie *cookies,
int *ncookies, unsigned int map_perm);
extern void ldc_free_exp_dring(struct ldc_channel *lp, void *buf,
unsigned int len,
struct ldc_trans_cookie *cookies, int ncookies);
#endif /* _SPARC64_LDC_H */
#ifndef _SPARC64_LMB_H
#define _SPARC64_LMB_H
#include <asm/oplib.h>
#define LMB_DBG(fmt...) prom_printf(fmt)
#define LMB_REAL_LIMIT 0
#endif /* !(_SPARC64_LMB_H) */
#ifndef _SPARC64_LSU_H
#define _SPARC64_LSU_H
#include <linux/const.h>
/* LSU Control Register */
#define LSU_CONTROL_PM _AC(0x000001fe00000000,UL) /* Phys-watchpoint byte mask*/
#define LSU_CONTROL_VM _AC(0x00000001fe000000,UL) /* Virt-watchpoint byte mask*/
#define LSU_CONTROL_PR _AC(0x0000000001000000,UL) /* Phys-rd watchpoint enable*/
#define LSU_CONTROL_PW _AC(0x0000000000800000,UL) /* Phys-wr watchpoint enable*/
#define LSU_CONTROL_VR _AC(0x0000000000400000,UL) /* Virt-rd watchpoint enable*/
#define LSU_CONTROL_VW _AC(0x0000000000200000,UL) /* Virt-wr watchpoint enable*/
#define LSU_CONTROL_FM _AC(0x00000000000ffff0,UL) /* Parity mask enables. */
#define LSU_CONTROL_DM _AC(0x0000000000000008,UL) /* Data MMU enable. */
#define LSU_CONTROL_IM _AC(0x0000000000000004,UL) /* Instruction MMU enable. */
#define LSU_CONTROL_DC _AC(0x0000000000000002,UL) /* Data cache enable. */
#define LSU_CONTROL_IC _AC(0x0000000000000001,UL) /* Instruction cache enable.*/
#endif /* !(_SPARC64_LSU_H) */
#ifndef _SPARC64_MDESC_H
#define _SPARC64_MDESC_H
#include <linux/types.h>
#include <linux/cpumask.h>
#include <asm/prom.h>
struct mdesc_handle;
/* Machine description operations are to be surrounded by grab and
* release calls. The mdesc_handle returned from the grab is
* the first argument to all of the operational calls that work
* on mdescs.
*/
extern struct mdesc_handle *mdesc_grab(void);
extern void mdesc_release(struct mdesc_handle *);
#define MDESC_NODE_NULL (~(u64)0)
extern u64 mdesc_node_by_name(struct mdesc_handle *handle,
u64 from_node, const char *name);
#define mdesc_for_each_node_by_name(__hdl, __node, __name) \
for (__node = mdesc_node_by_name(__hdl, MDESC_NODE_NULL, __name); \
(__node) != MDESC_NODE_NULL; \
__node = mdesc_node_by_name(__hdl, __node, __name))
/* Access to property values returned from mdesc_get_property() are
* only valid inside of a mdesc_grab()/mdesc_release() sequence.
* Once mdesc_release() is called, the memory backed up by these
* pointers may reference freed up memory.
*
* Therefore callers must make copies of any property values
* they need.
*
* These same rules apply to mdesc_node_name().
*/
extern const void *mdesc_get_property(struct mdesc_handle *handle,
u64 node, const char *name, int *lenp);
extern const char *mdesc_node_name(struct mdesc_handle *hp, u64 node);
/* MD arc iteration, the standard sequence is:
*
* unsigned long arc;
* mdesc_for_each_arc(arc, handle, node, MDESC_ARC_TYPE_{FWD,BACK}) {
* unsigned long target = mdesc_arc_target(handle, arc);
* ...
* }
*/
#define MDESC_ARC_TYPE_FWD "fwd"
#define MDESC_ARC_TYPE_BACK "back"
extern u64 mdesc_next_arc(struct mdesc_handle *handle, u64 from,
const char *arc_type);
#define mdesc_for_each_arc(__arc, __hdl, __node, __type) \
for (__arc = mdesc_next_arc(__hdl, __node, __type); \
(__arc) != MDESC_NODE_NULL; \
__arc = mdesc_next_arc(__hdl, __arc, __type))
extern u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc);
extern void mdesc_update(void);
struct mdesc_notifier_client {
void (*add)(struct mdesc_handle *handle, u64 node);
void (*remove)(struct mdesc_handle *handle, u64 node);
const char *node_name;
struct mdesc_notifier_client *next;
};
extern void mdesc_register_notifier(struct mdesc_notifier_client *client);
extern void mdesc_fill_in_cpu_data(cpumask_t mask);
extern void sun4v_mdesc_init(void);
#endif
#ifndef _SPARC64_MMZONE_H
#define _SPARC64_MMZONE_H
#ifdef CONFIG_NEED_MULTIPLE_NODES
extern struct pglist_data *node_data[];
#define NODE_DATA(nid) (node_data[nid])
#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
#define node_end_pfn(nid) (NODE_DATA(nid)->node_end_pfn)
extern int numa_cpu_lookup_table[];
extern cpumask_t numa_cpumask_lookup_table[];
#endif /* CONFIG_NEED_MULTIPLE_NODES */
#endif /* _SPARC64_MMZONE_H */
/* ns87303.h: Configuration Register Description for the
* National Semiconductor PC87303 (SuperIO).
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
*/
#ifndef _SPARC_NS87303_H
#define _SPARC_NS87303_H 1
/*
* Control Register Index Values
*/
#define FER 0x00
#define FAR 0x01
#define PTR 0x02
#define FCR 0x03
#define PCR 0x04
#define KRR 0x05
#define PMC 0x06
#define TUP 0x07
#define SID 0x08
#define ASC 0x09
#define CS0CF0 0x0a
#define CS0CF1 0x0b
#define CS1CF0 0x0c
#define CS1CF1 0x0d
/* Function Enable Register (FER) bits */
#define FER_EDM 0x10 /* Encoded Drive and Motor pin information */
/* Function Address Register (FAR) bits */
#define FAR_LPT_MASK 0x03
#define FAR_LPTB 0x00
#define FAR_LPTA 0x01
#define FAR_LPTC 0x02
/* Power and Test Register (PTR) bits */
#define PTR_LPTB_IRQ7 0x08
#define PTR_LEVEL_IRQ 0x80 /* When not ECP/EPP: Use level IRQ */
#define PTR_LPT_REG_DIR 0x80 /* When ECP/EPP: LPT CTR controlls direction */
/* of the parallel port */
/* Function Control Register (FCR) bits */
#define FCR_LDE 0x10 /* Logical Drive Exchange */
#define FCR_ZWS_ENA 0x20 /* Enable short host read/write in ECP/EPP */
/* Printer Control Register (PCR) bits */
#define PCR_EPP_ENABLE 0x01
#define PCR_EPP_IEEE 0x02 /* Enable EPP Version 1.9 (IEEE 1284) */
#define PCR_ECP_ENABLE 0x04
#define PCR_ECP_CLK_ENA 0x08 /* If 0 ECP Clock is stopped on Power down */
#define PCR_IRQ_POLAR 0x20 /* If 0 IRQ is level high or negative pulse, */
/* if 1 polarity is inverted */
#define PCR_IRQ_ODRAIN 0x40 /* If 1, IRQ is open drain */
/* Tape UARTs and Parallel Port Config Register (TUP) bits */
#define TUP_EPP_TIMO 0x02 /* Enable EPP timeout IRQ */
/* Advanced SuperIO Config Register (ASC) bits */
#define ASC_LPT_IRQ7 0x01 /* Always use IRQ7 for LPT */
#define ASC_DRV2_SEL 0x02 /* Logical Drive Exchange controlled by TDR */
#define FER_RESERVED 0x00
#define FAR_RESERVED 0x00
#define PTR_RESERVED 0x73
#define FCR_RESERVED 0xc4
#define PCR_RESERVED 0x10
#define KRR_RESERVED 0x00
#define PMC_RESERVED 0x98
#define TUP_RESERVED 0xfb
#define SIP_RESERVED 0x00
#define ASC_RESERVED 0x18
#define CS0CF0_RESERVED 0x00
#define CS0CF1_RESERVED 0x08
#define CS1CF0_RESERVED 0x00
#define CS1CF1_RESERVED 0x08
#ifdef __KERNEL__
#include <linux/spinlock.h>
#include <asm/system.h>
#include <asm/io.h>
extern spinlock_t ns87303_lock;
static inline int ns87303_modify(unsigned long port, unsigned int index,
unsigned char clr, unsigned char set)
{
static unsigned char reserved[] = {
FER_RESERVED, FAR_RESERVED, PTR_RESERVED, FCR_RESERVED,
PCR_RESERVED, KRR_RESERVED, PMC_RESERVED, TUP_RESERVED,
SIP_RESERVED, ASC_RESERVED, CS0CF0_RESERVED, CS0CF1_RESERVED,
CS1CF0_RESERVED, CS1CF1_RESERVED
};
unsigned long flags;
unsigned char value;
if (index > 0x0d)
return -EINVAL;
spin_lock_irqsave(&ns87303_lock, flags);
outb(index, port);
value = inb(port + 1);
value &= ~(reserved[index] | clr);
value |= set;
outb(value, port + 1);
outb(value, port + 1);
spin_unlock_irqrestore(&ns87303_lock, flags);
return 0;
}
#endif /* __KERNEL__ */
#endif /* !(_SPARC_NS87303_H) */
/* parport.h: sparc64 specific parport initialization and dma.
*
* Copyright (C) 1999 Eddie C. Dost (ecd@skynet.be)
*/
#ifndef _ASM_SPARC64_PARPORT_H
#define _ASM_SPARC64_PARPORT_H 1
#include <asm/ebus.h>
#include <asm/ns87303.h>
#include <asm/of_device.h>
#include <asm/prom.h>
#define PARPORT_PC_MAX_PORTS PARPORT_MAX
/*
* While sparc64 doesn't have an ISA DMA API, we provide something that looks
* close enough to make parport_pc happy
*/
#define HAS_DMA
static DEFINE_SPINLOCK(dma_spin_lock);
#define claim_dma_lock() \
({ unsigned long flags; \
spin_lock_irqsave(&dma_spin_lock, flags); \
flags; \
})
#define release_dma_lock(__flags) \
spin_unlock_irqrestore(&dma_spin_lock, __flags);
static struct sparc_ebus_info {
struct ebus_dma_info info;
unsigned int addr;
unsigned int count;
int lock;
struct parport *port;
} sparc_ebus_dmas[PARPORT_PC_MAX_PORTS];
static DECLARE_BITMAP(dma_slot_map, PARPORT_PC_MAX_PORTS);
static inline int request_dma(unsigned int dmanr, const char *device_id)
{
if (dmanr >= PARPORT_PC_MAX_PORTS)
return -EINVAL;
if (xchg(&sparc_ebus_dmas[dmanr].lock, 1) != 0)
return -EBUSY;
return 0;
}
static inline void free_dma(unsigned int dmanr)
{
if (dmanr >= PARPORT_PC_MAX_PORTS) {
printk(KERN_WARNING "Trying to free DMA%d\n", dmanr);
return;
}
if (xchg(&sparc_ebus_dmas[dmanr].lock, 0) == 0) {
printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr);
return;
}
}
static inline void enable_dma(unsigned int dmanr)
{
ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1);
if (ebus_dma_request(&sparc_ebus_dmas[dmanr].info,
sparc_ebus_dmas[dmanr].addr,
sparc_ebus_dmas[dmanr].count))
BUG();
}
static inline void disable_dma(unsigned int dmanr)
{
ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 0);
}
static inline void clear_dma_ff(unsigned int dmanr)
{
/* nothing */
}
static inline void set_dma_mode(unsigned int dmanr, char mode)
{
ebus_dma_prepare(&sparc_ebus_dmas[dmanr].info, (mode != DMA_MODE_WRITE));
}
static inline void set_dma_addr(unsigned int dmanr, unsigned int addr)
{
sparc_ebus_dmas[dmanr].addr = addr;
}
static inline void set_dma_count(unsigned int dmanr, unsigned int count)
{
sparc_ebus_dmas[dmanr].count = count;
}
static inline unsigned int get_dma_residue(unsigned int dmanr)
{
return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info);
}
static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id *match)
{
unsigned long base = op->resource[0].start;
unsigned long config = op->resource[1].start;
unsigned long d_base = op->resource[2].start;
unsigned long d_len;
struct device_node *parent;
struct parport *p;
int slot, err;
parent = op->node->parent;
if (!strcmp(parent->name, "dma")) {
p = parport_pc_probe_port(base, base + 0x400,
op->irqs[0], PARPORT_DMA_NOFIFO,
op->dev.parent->parent);
if (!p)
return -ENOMEM;
dev_set_drvdata(&op->dev, p);
return 0;
}
for (slot = 0; slot < PARPORT_PC_MAX_PORTS; slot++) {
if (!test_and_set_bit(slot, dma_slot_map))
break;
}
err = -ENODEV;
if (slot >= PARPORT_PC_MAX_PORTS)
goto out_err;
spin_lock_init(&sparc_ebus_dmas[slot].info.lock);
d_len = (op->resource[2].end - d_base) + 1UL;
sparc_ebus_dmas[slot].info.regs =
of_ioremap(&op->resource[2], 0, d_len, "ECPP DMA");
if (!sparc_ebus_dmas[slot].info.regs)
goto out_clear_map;
sparc_ebus_dmas[slot].info.flags = 0;
sparc_ebus_dmas[slot].info.callback = NULL;
sparc_ebus_dmas[slot].info.client_cookie = NULL;
sparc_ebus_dmas[slot].info.irq = 0xdeadbeef;
strcpy(sparc_ebus_dmas[slot].info.name, "parport");
if (ebus_dma_register(&sparc_ebus_dmas[slot].info))
goto out_unmap_regs;
ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 1);
/* Configure IRQ to Push Pull, Level Low */
/* Enable ECP, set bit 2 of the CTR first */
outb(0x04, base + 0x02);
ns87303_modify(config, PCR,
PCR_EPP_ENABLE |
PCR_IRQ_ODRAIN,
PCR_ECP_ENABLE |
PCR_ECP_CLK_ENA |
PCR_IRQ_POLAR);
/* CTR bit 5 controls direction of port */
ns87303_modify(config, PTR,
0, PTR_LPT_REG_DIR);
p = parport_pc_probe_port(base, base + 0x400,
op->irqs[0],
slot,
op->dev.parent);
err = -ENOMEM;
if (!p)
goto out_disable_irq;
dev_set_drvdata(&op->dev, p);
return 0;
out_disable_irq:
ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
out_unmap_regs:
of_iounmap(&op->resource[2], sparc_ebus_dmas[slot].info.regs, d_len);
out_clear_map:
clear_bit(slot, dma_slot_map);
out_err:
return err;
}
static int __devexit ecpp_remove(struct of_device *op)
{
struct parport *p = dev_get_drvdata(&op->dev);
int slot = p->dma;
parport_pc_unregister_port(p);
if (slot != PARPORT_DMA_NOFIFO) {
unsigned long d_base = op->resource[2].start;
unsigned long d_len;
d_len = (op->resource[2].end - d_base) + 1UL;
ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
of_iounmap(&op->resource[2],
sparc_ebus_dmas[slot].info.regs,
d_len);
clear_bit(slot, dma_slot_map);
}
return 0;
}
static struct of_device_id ecpp_match[] = {
{
.name = "ecpp",
},
{
.name = "parallel",
.compatible = "ecpp",
},
{
.name = "parallel",
.compatible = "ns87317-ecpp",
},
{},
};
static struct of_platform_driver ecpp_driver = {
.name = "ecpp",
.match_table = ecpp_match,
.probe = ecpp_probe,
.remove = __devexit_p(ecpp_remove),
};
static int parport_pc_find_nonpci_ports(int autoirq, int autodma)
{
of_register_driver(&ecpp_driver, &of_bus_type);
return 0;
}
#endif /* !(_ASM_SPARC64_PARPORT_H */
#ifndef _SPARC64_PIL_H
#define _SPARC64_PIL_H
/* To avoid some locking problems, we hard allocate certain PILs
* for SMP cross call messages that must do a etrap/rtrap.
*
* A local_irq_disable() does not block the cross call delivery, so
* when SMP locking is an issue we reschedule the event into a PIL
* interrupt which is blocked by local_irq_disable().
*
* In fact any XCALL which has to etrap/rtrap has a problem because
* it is difficult to prevent rtrap from running BH's, and that would
* need to be done if the XCALL arrived while %pil==15.
*/
#define PIL_SMP_CALL_FUNC 1
#define PIL_SMP_RECEIVE_SIGNAL 2
#define PIL_SMP_CAPTURE 3
#define PIL_SMP_CTX_NEW_VERSION 4
#define PIL_DEVICE_IRQ 5
#endif /* !(_SPARC64_PIL_H) */
#ifndef _SPARC64_REBOOT_H
#define _SPARC64_REBOOT_H
extern void machine_alt_power_off(void);
#endif /* _SPARC64_REBOOT_H */
/* rwsem-const.h: RW semaphore counter constants. */
#ifndef _SPARC64_RWSEM_CONST_H
#define _SPARC64_RWSEM_CONST_H
#define RWSEM_UNLOCKED_VALUE 0x00000000
#define RWSEM_ACTIVE_BIAS 0x00000001
#define RWSEM_ACTIVE_MASK 0x0000ffff
#define RWSEM_WAITING_BIAS 0xffff0000
#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
#endif /* _SPARC64_RWSEM_CONST_H */
/*
* rwsem.h: R/W semaphores implemented using CAS
*
* Written by David S. Miller (davem@redhat.com), 2001.
* Derived from asm-i386/rwsem.h
*/
#ifndef _SPARC64_RWSEM_H
#define _SPARC64_RWSEM_H
#ifndef _LINUX_RWSEM_H
#error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead"
#endif
#ifdef __KERNEL__
#include <linux/list.h>
#include <linux/spinlock.h>
#include <asm/rwsem-const.h>
struct rwsem_waiter;
struct rw_semaphore {
signed int count;
spinlock_t wait_lock;
struct list_head wait_list;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
};
#ifdef CONFIG_DEBUG_LOCK_ALLOC
# define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname }
#else
# define __RWSEM_DEP_MAP_INIT(lockname)
#endif
#define __RWSEM_INITIALIZER(name) \
{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) \
__RWSEM_DEP_MAP_INIT(name) }
#define DECLARE_RWSEM(name) \
struct rw_semaphore name = __RWSEM_INITIALIZER(name)
extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
struct lock_class_key *key);
#define init_rwsem(sem) \
do { \
static struct lock_class_key __key; \
\
__init_rwsem((sem), #sem, &__key); \
} while (0)
extern void __down_read(struct rw_semaphore *sem);
extern int __down_read_trylock(struct rw_semaphore *sem);
extern void __down_write(struct rw_semaphore *sem);
extern int __down_write_trylock(struct rw_semaphore *sem);
extern void __up_read(struct rw_semaphore *sem);
extern void __up_write(struct rw_semaphore *sem);
extern void __downgrade_write(struct rw_semaphore *sem);
static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
{
__down_write(sem);
}
static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
{
return atomic_add_return(delta, (atomic_t *)(&sem->count));
}
static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
{
atomic_add(delta, (atomic_t *)(&sem->count));
}
static inline int rwsem_is_locked(struct rw_semaphore *sem)
{
return (sem->count != 0);
}
#endif /* __KERNEL__ */
#endif /* _SPARC64_RWSEM_H */
#ifndef _SPARC64_SCRATCHPAD_H
#define _SPARC64_SCRATCHPAD_H
/* Sun4v scratchpad registers, accessed via ASI_SCRATCHPAD. */
#define SCRATCHPAD_MMU_MISS 0x00 /* Shared with OBP - set by OBP */
#define SCRATCHPAD_CPUID 0x08 /* Shared with OBP - set by hypervisor */
#define SCRATCHPAD_UTSBREG1 0x10
#define SCRATCHPAD_UTSBREG2 0x18
/* 0x20 and 0x28, hypervisor only... */
#define SCRATCHPAD_UNUSED1 0x30
#define SCRATCHPAD_UNUSED2 0x38 /* Reserved for OBP */
#endif /* !(_SPARC64_SCRATCHPAD_H) */
#ifndef _ASM_SECCOMP_H
#include <linux/thread_info.h> /* already defines TIF_32BIT */
#ifndef TIF_32BIT
#error "unexpected TIF_32BIT on sparc64"
#endif
#include <linux/unistd.h>
#define __NR_seccomp_read __NR_read
#define __NR_seccomp_write __NR_write
#define __NR_seccomp_exit __NR_exit
#define __NR_seccomp_sigreturn __NR_rt_sigreturn
#define __NR_seccomp_read_32 __NR_read
#define __NR_seccomp_write_32 __NR_write
#define __NR_seccomp_exit_32 __NR_exit
#define __NR_seccomp_sigreturn_32 __NR_sigreturn
#endif /* _ASM_SECCOMP_H */
#ifndef _SPARC64_SFAFSR_H
#define _SPARC64_SFAFSR_H
#include <linux/const.h>
/* Spitfire Asynchronous Fault Status register, ASI=0x4C VA<63:0>=0x0 */
#define SFAFSR_ME (_AC(1,UL) << SFAFSR_ME_SHIFT)
#define SFAFSR_ME_SHIFT 32
#define SFAFSR_PRIV (_AC(1,UL) << SFAFSR_PRIV_SHIFT)
#define SFAFSR_PRIV_SHIFT 31
#define SFAFSR_ISAP (_AC(1,UL) << SFAFSR_ISAP_SHIFT)
#define SFAFSR_ISAP_SHIFT 30
#define SFAFSR_ETP (_AC(1,UL) << SFAFSR_ETP_SHIFT)
#define SFAFSR_ETP_SHIFT 29
#define SFAFSR_IVUE (_AC(1,UL) << SFAFSR_IVUE_SHIFT)
#define SFAFSR_IVUE_SHIFT 28
#define SFAFSR_TO (_AC(1,UL) << SFAFSR_TO_SHIFT)
#define SFAFSR_TO_SHIFT 27
#define SFAFSR_BERR (_AC(1,UL) << SFAFSR_BERR_SHIFT)
#define SFAFSR_BERR_SHIFT 26
#define SFAFSR_LDP (_AC(1,UL) << SFAFSR_LDP_SHIFT)
#define SFAFSR_LDP_SHIFT 25
#define SFAFSR_CP (_AC(1,UL) << SFAFSR_CP_SHIFT)
#define SFAFSR_CP_SHIFT 24
#define SFAFSR_WP (_AC(1,UL) << SFAFSR_WP_SHIFT)
#define SFAFSR_WP_SHIFT 23
#define SFAFSR_EDP (_AC(1,UL) << SFAFSR_EDP_SHIFT)
#define SFAFSR_EDP_SHIFT 22
#define SFAFSR_UE (_AC(1,UL) << SFAFSR_UE_SHIFT)
#define SFAFSR_UE_SHIFT 21
#define SFAFSR_CE (_AC(1,UL) << SFAFSR_CE_SHIFT)
#define SFAFSR_CE_SHIFT 20
#define SFAFSR_ETS (_AC(0xf,UL) << SFAFSR_ETS_SHIFT)
#define SFAFSR_ETS_SHIFT 16
#define SFAFSR_PSYND (_AC(0xffff,UL) << SFAFSR_PSYND_SHIFT)
#define SFAFSR_PSYND_SHIFT 0
/* UDB Error Register, ASI=0x7f VA<63:0>=0x0(High),0x18(Low) for read
* ASI=0x77 VA<63:0>=0x0(High),0x18(Low) for write
*/
#define UDBE_UE (_AC(1,UL) << 9)
#define UDBE_CE (_AC(1,UL) << 8)
#define UDBE_E_SYNDR (_AC(0xff,UL) << 0)
/* The trap handlers for asynchronous errors encode the AFSR and
* other pieces of information into a 64-bit argument for C code
* encoded as follows:
*
* -----------------------------------------------
* | UDB_H | UDB_L | TL>1 | TT | AFSR |
* -----------------------------------------------
* 63 54 53 44 42 41 33 32 0
*
* The AFAR is passed in unchanged.
*/
#define SFSTAT_UDBH_MASK (_AC(0x3ff,UL) << SFSTAT_UDBH_SHIFT)
#define SFSTAT_UDBH_SHIFT 54
#define SFSTAT_UDBL_MASK (_AC(0x3ff,UL) << SFSTAT_UDBH_SHIFT)
#define SFSTAT_UDBL_SHIFT 44
#define SFSTAT_TL_GT_ONE (_AC(1,UL) << SFSTAT_TL_GT_ONE_SHIFT)
#define SFSTAT_TL_GT_ONE_SHIFT 42
#define SFSTAT_TRAP_TYPE (_AC(0x1FF,UL) << SFSTAT_TRAP_TYPE_SHIFT)
#define SFSTAT_TRAP_TYPE_SHIFT 33
#define SFSTAT_AFSR_MASK (_AC(0x1ffffffff,UL) << SFSTAT_AFSR_SHIFT)
#define SFSTAT_AFSR_SHIFT 0
/* ESTATE Error Enable Register, ASI=0x4b VA<63:0>=0x0 */
#define ESTATE_ERR_CE 0x1 /* Correctable errors */
#define ESTATE_ERR_NCE 0x2 /* TO, BERR, LDP, ETP, EDP, WP, UE, IVUE */
#define ESTATE_ERR_ISAP 0x4 /* System address parity error */
#define ESTATE_ERR_ALL (ESTATE_ERR_CE | \
ESTATE_ERR_NCE | \
ESTATE_ERR_ISAP)
/* The various trap types that report using the above state. */
#define TRAP_TYPE_IAE 0x09 /* Instruction Access Error */
#define TRAP_TYPE_DAE 0x32 /* Data Access Error */
#define TRAP_TYPE_CEE 0x63 /* Correctable ECC Error */
#endif /* _SPARC64_SFAFSR_H */
#ifndef _SPARC64_SPARSEMEM_H
#define _SPARC64_SPARSEMEM_H
#ifdef __KERNEL__
#define SECTION_SIZE_BITS 30
#define MAX_PHYSADDR_BITS 42
#define MAX_PHYSMEM_BITS 42
#endif /* !(__KERNEL__) */
#endif /* !(_SPARC64_SPARSEMEM_H) */
/* spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations.
*
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
*/
#ifndef _SPARC64_SPITFIRE_H
#define _SPARC64_SPITFIRE_H
#include <asm/asi.h>
/* The following register addresses are accessible via ASI_DMMU
* and ASI_IMMU, that is there is a distinct and unique copy of
* each these registers for each TLB.
*/
#define TSB_TAG_TARGET 0x0000000000000000 /* All chips */
#define TLB_SFSR 0x0000000000000018 /* All chips */
#define TSB_REG 0x0000000000000028 /* All chips */
#define TLB_TAG_ACCESS 0x0000000000000030 /* All chips */
#define VIRT_WATCHPOINT 0x0000000000000038 /* All chips */
#define PHYS_WATCHPOINT 0x0000000000000040 /* All chips */
#define TSB_EXTENSION_P 0x0000000000000048 /* Ultra-III and later */
#define TSB_EXTENSION_S 0x0000000000000050 /* Ultra-III and later, D-TLB only */
#define TSB_EXTENSION_N 0x0000000000000058 /* Ultra-III and later */
#define TLB_TAG_ACCESS_EXT 0x0000000000000060 /* Ultra-III+ and later */
/* These registers only exist as one entity, and are accessed
* via ASI_DMMU only.
*/
#define PRIMARY_CONTEXT 0x0000000000000008
#define SECONDARY_CONTEXT 0x0000000000000010
#define DMMU_SFAR 0x0000000000000020
#define VIRT_WATCHPOINT 0x0000000000000038
#define PHYS_WATCHPOINT 0x0000000000000040
#define SPITFIRE_HIGHEST_LOCKED_TLBENT (64 - 1)
#define CHEETAH_HIGHEST_LOCKED_TLBENT (16 - 1)
#define L1DCACHE_SIZE 0x4000
#define SUN4V_CHIP_INVALID 0x00
#define SUN4V_CHIP_NIAGARA1 0x01
#define SUN4V_CHIP_NIAGARA2 0x02
#define SUN4V_CHIP_UNKNOWN 0xff
#ifndef __ASSEMBLY__
enum ultra_tlb_layout {
spitfire = 0,
cheetah = 1,
cheetah_plus = 2,
hypervisor = 3,
};
extern enum ultra_tlb_layout tlb_type;
extern int sun4v_chip_type;
extern int cheetah_pcache_forced_on;
extern void cheetah_enable_pcache(void);
#define sparc64_highest_locked_tlbent() \
(tlb_type == spitfire ? \
SPITFIRE_HIGHEST_LOCKED_TLBENT : \
CHEETAH_HIGHEST_LOCKED_TLBENT)
extern int num_kernel_image_mappings;
/* The data cache is write through, so this just invalidates the
* specified line.
*/
static inline void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag)
{
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* No outputs */
: "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG));
}
/* The instruction cache lines are flushed with this, but note that
* this does not flush the pipeline. It is possible for a line to
* get flushed but stale instructions to still be in the pipeline,
* a flush instruction (to any address) is sufficient to handle
* this issue after the line is invalidated.
*/
static inline void spitfire_put_icache_tag(unsigned long addr, unsigned long tag)
{
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* No outputs */
: "r" (tag), "r" (addr), "i" (ASI_IC_TAG));
}
static inline unsigned long spitfire_get_dtlb_data(int entry)
{
unsigned long data;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (data)
: "r" (entry << 3), "i" (ASI_DTLB_DATA_ACCESS));
/* Clear TTE diag bits. */
data &= ~0x0003fe0000000000UL;
return data;
}
static inline unsigned long spitfire_get_dtlb_tag(int entry)
{
unsigned long tag;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (tag)
: "r" (entry << 3), "i" (ASI_DTLB_TAG_READ));
return tag;
}
static inline void spitfire_put_dtlb_data(int entry, unsigned long data)
{
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* No outputs */
: "r" (data), "r" (entry << 3),
"i" (ASI_DTLB_DATA_ACCESS));
}
static inline unsigned long spitfire_get_itlb_data(int entry)
{
unsigned long data;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (data)
: "r" (entry << 3), "i" (ASI_ITLB_DATA_ACCESS));
/* Clear TTE diag bits. */
data &= ~0x0003fe0000000000UL;
return data;
}
static inline unsigned long spitfire_get_itlb_tag(int entry)
{
unsigned long tag;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (tag)
: "r" (entry << 3), "i" (ASI_ITLB_TAG_READ));
return tag;
}
static inline void spitfire_put_itlb_data(int entry, unsigned long data)
{
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* No outputs */
: "r" (data), "r" (entry << 3),
"i" (ASI_ITLB_DATA_ACCESS));
}
static inline void spitfire_flush_dtlb_nucleus_page(unsigned long page)
{
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* No outputs */
: "r" (page | 0x20), "i" (ASI_DMMU_DEMAP));
}
static inline void spitfire_flush_itlb_nucleus_page(unsigned long page)
{
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* No outputs */
: "r" (page | 0x20), "i" (ASI_IMMU_DEMAP));
}
/* Cheetah has "all non-locked" tlb flushes. */
static inline void cheetah_flush_dtlb_all(void)
{
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* No outputs */
: "r" (0x80), "i" (ASI_DMMU_DEMAP));
}
static inline void cheetah_flush_itlb_all(void)
{
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* No outputs */
: "r" (0x80), "i" (ASI_IMMU_DEMAP));
}
/* Cheetah has a 4-tlb layout so direct access is a bit different.
* The first two TLBs are fully assosciative, hold 16 entries, and are
* used only for locked and >8K sized translations. One exists for
* data accesses and one for instruction accesses.
*
* The third TLB is for data accesses to 8K non-locked translations, is
* 2 way assosciative, and holds 512 entries. The fourth TLB is for
* instruction accesses to 8K non-locked translations, is 2 way
* assosciative, and holds 128 entries.
*
* Cheetah has some bug where bogus data can be returned from
* ASI_{D,I}TLB_DATA_ACCESS loads, doing the load twice fixes
* the problem for me. -DaveM
*/
static inline unsigned long cheetah_get_ldtlb_data(int entry)
{
unsigned long data;
__asm__ __volatile__("ldxa [%1] %2, %%g0\n\t"
"ldxa [%1] %2, %0"
: "=r" (data)
: "r" ((0 << 16) | (entry << 3)),
"i" (ASI_DTLB_DATA_ACCESS));
return data;
}
static inline unsigned long cheetah_get_litlb_data(int entry)
{
unsigned long data;
__asm__ __volatile__("ldxa [%1] %2, %%g0\n\t"
"ldxa [%1] %2, %0"
: "=r" (data)
: "r" ((0 << 16) | (entry << 3)),
"i" (ASI_ITLB_DATA_ACCESS));
return data;
}
static inline unsigned long cheetah_get_ldtlb_tag(int entry)
{
unsigned long tag;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (tag)
: "r" ((0 << 16) | (entry << 3)),
"i" (ASI_DTLB_TAG_READ));
return tag;
}
static inline unsigned long cheetah_get_litlb_tag(int entry)
{
unsigned long tag;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (tag)
: "r" ((0 << 16) | (entry << 3)),
"i" (ASI_ITLB_TAG_READ));
return tag;
}
static inline void cheetah_put_ldtlb_data(int entry, unsigned long data)
{
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* No outputs */
: "r" (data),
"r" ((0 << 16) | (entry << 3)),
"i" (ASI_DTLB_DATA_ACCESS));
}
static inline void cheetah_put_litlb_data(int entry, unsigned long data)
{
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* No outputs */
: "r" (data),
"r" ((0 << 16) | (entry << 3)),
"i" (ASI_ITLB_DATA_ACCESS));
}
static inline unsigned long cheetah_get_dtlb_data(int entry, int tlb)
{
unsigned long data;
__asm__ __volatile__("ldxa [%1] %2, %%g0\n\t"
"ldxa [%1] %2, %0"
: "=r" (data)
: "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_DATA_ACCESS));
return data;
}
static inline unsigned long cheetah_get_dtlb_tag(int entry, int tlb)
{
unsigned long tag;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (tag)
: "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_TAG_READ));
return tag;
}
static inline void cheetah_put_dtlb_data(int entry, unsigned long data, int tlb)
{
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* No outputs */
: "r" (data),
"r" ((tlb << 16) | (entry << 3)),
"i" (ASI_DTLB_DATA_ACCESS));
}
static inline unsigned long cheetah_get_itlb_data(int entry)
{
unsigned long data;
__asm__ __volatile__("ldxa [%1] %2, %%g0\n\t"
"ldxa [%1] %2, %0"
: "=r" (data)
: "r" ((2 << 16) | (entry << 3)),
"i" (ASI_ITLB_DATA_ACCESS));
return data;
}
static inline unsigned long cheetah_get_itlb_tag(int entry)
{
unsigned long tag;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (tag)
: "r" ((2 << 16) | (entry << 3)), "i" (ASI_ITLB_TAG_READ));
return tag;
}
static inline void cheetah_put_itlb_data(int entry, unsigned long data)
{
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* No outputs */
: "r" (data), "r" ((2 << 16) | (entry << 3)),
"i" (ASI_ITLB_DATA_ACCESS));
}
#endif /* !(__ASSEMBLY__) */
#endif /* !(_SPARC64_SPITFIRE_H) */
#ifndef _SPARC64_SSTATE_H
#define _SPARC64_SSTATE_H
extern void sstate_booting(void);
extern void sstate_running(void);
extern void sstate_halt(void);
extern void sstate_poweroff(void);
extern void sstate_panic(void);
extern void sstate_reboot(void);
extern void sun4v_sstate_init(void);
#endif /* _SPARC64_SSTATE_H */
#ifndef _SPARC64_STACKTRACE_H
#define _SPARC64_STACKTRACE_H
extern void stack_trace_flush(void);
#endif /* _SPARC64_STACKTRACE_H */
/*
* starfire.h: Group all starfire specific code together.
*
* Copyright (C) 2000 Anton Blanchard (anton@samba.org)
*/
#ifndef _SPARC64_STARFIRE_H
#define _SPARC64_STARFIRE_H
#ifndef __ASSEMBLY__
extern int this_is_starfire;
extern void check_if_starfire(void);
extern void starfire_cpu_setup(void);
extern int starfire_hard_smp_processor_id(void);
extern void starfire_hookup(int);
extern unsigned int starfire_translate(unsigned long imap, unsigned int upaid);
#endif
#endif
#ifndef _SPARC64_SYSCALLS_H
#define _SPARC64_SYSCALLS_H
struct pt_regs;
extern asmlinkage long sparc_do_fork(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size);
extern asmlinkage int sparc_execve(struct pt_regs *regs);
#endif /* _SPARC64_SYSCALLS_H */
#ifndef _SPARC64_TSB_H
#define _SPARC64_TSB_H
/* The sparc64 TSB is similar to the powerpc hashtables. It's a
* power-of-2 sized table of TAG/PTE pairs. The cpu precomputes
* pointers into this table for 8K and 64K page sizes, and also a
* comparison TAG based upon the virtual address and context which
* faults.
*
* TLB miss trap handler software does the actual lookup via something
* of the form:
*
* ldxa [%g0] ASI_{D,I}MMU_TSB_8KB_PTR, %g1
* ldxa [%g0] ASI_{D,I}MMU, %g6
* sllx %g6, 22, %g6
* srlx %g6, 22, %g6
* ldda [%g1] ASI_NUCLEUS_QUAD_LDD, %g4
* cmp %g4, %g6
* bne,pn %xcc, tsb_miss_{d,i}tlb
* mov FAULT_CODE_{D,I}TLB, %g3
* stxa %g5, [%g0] ASI_{D,I}TLB_DATA_IN
* retry
*
*
* Each 16-byte slot of the TSB is the 8-byte tag and then the 8-byte
* PTE. The TAG is of the same layout as the TLB TAG TARGET mmu
* register which is:
*
* -------------------------------------------------
* | - | CONTEXT | - | VADDR bits 63:22 |
* -------------------------------------------------
* 63 61 60 48 47 42 41 0
*
* But actually, since we use per-mm TSB's, we zero out the CONTEXT
* field.
*
* Like the powerpc hashtables we need to use locking in order to
* synchronize while we update the entries. PTE updates need locking
* as well.
*
* We need to carefully choose a lock bits for the TSB entry. We
* choose to use bit 47 in the tag. Also, since we never map anything
* at page zero in context zero, we use zero as an invalid tag entry.
* When the lock bit is set, this forces a tag comparison failure.
*/
#define TSB_TAG_LOCK_BIT 47
#define TSB_TAG_LOCK_HIGH (1 << (TSB_TAG_LOCK_BIT - 32))
#define TSB_TAG_INVALID_BIT 46
#define TSB_TAG_INVALID_HIGH (1 << (TSB_TAG_INVALID_BIT - 32))
#define TSB_MEMBAR membar #StoreStore
/* Some cpus support physical address quad loads. We want to use
* those if possible so we don't need to hard-lock the TSB mapping
* into the TLB. We encode some instruction patching in order to
* support this.
*
* The kernel TSB is locked into the TLB by virtue of being in the
* kernel image, so we don't play these games for swapper_tsb access.
*/
#ifndef __ASSEMBLY__
struct tsb_ldquad_phys_patch_entry {
unsigned int addr;
unsigned int sun4u_insn;
unsigned int sun4v_insn;
};
extern struct tsb_ldquad_phys_patch_entry __tsb_ldquad_phys_patch,
__tsb_ldquad_phys_patch_end;
struct tsb_phys_patch_entry {
unsigned int addr;
unsigned int insn;
};
extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
#endif
#define TSB_LOAD_QUAD(TSB, REG) \
661: ldda [TSB] ASI_NUCLEUS_QUAD_LDD, REG; \
.section .tsb_ldquad_phys_patch, "ax"; \
.word 661b; \
ldda [TSB] ASI_QUAD_LDD_PHYS, REG; \
ldda [TSB] ASI_QUAD_LDD_PHYS_4V, REG; \
.previous
#define TSB_LOAD_TAG_HIGH(TSB, REG) \
661: lduwa [TSB] ASI_N, REG; \
.section .tsb_phys_patch, "ax"; \
.word 661b; \
lduwa [TSB] ASI_PHYS_USE_EC, REG; \
.previous
#define TSB_LOAD_TAG(TSB, REG) \
661: ldxa [TSB] ASI_N, REG; \
.section .tsb_phys_patch, "ax"; \
.word 661b; \
ldxa [TSB] ASI_PHYS_USE_EC, REG; \
.previous
#define TSB_CAS_TAG_HIGH(TSB, REG1, REG2) \
661: casa [TSB] ASI_N, REG1, REG2; \
.section .tsb_phys_patch, "ax"; \
.word 661b; \
casa [TSB] ASI_PHYS_USE_EC, REG1, REG2; \
.previous
#define TSB_CAS_TAG(TSB, REG1, REG2) \
661: casxa [TSB] ASI_N, REG1, REG2; \
.section .tsb_phys_patch, "ax"; \
.word 661b; \
casxa [TSB] ASI_PHYS_USE_EC, REG1, REG2; \
.previous
#define TSB_STORE(ADDR, VAL) \
661: stxa VAL, [ADDR] ASI_N; \
.section .tsb_phys_patch, "ax"; \
.word 661b; \
stxa VAL, [ADDR] ASI_PHYS_USE_EC; \
.previous
#define TSB_LOCK_TAG(TSB, REG1, REG2) \
99: TSB_LOAD_TAG_HIGH(TSB, REG1); \
sethi %hi(TSB_TAG_LOCK_HIGH), REG2;\
andcc REG1, REG2, %g0; \
bne,pn %icc, 99b; \
nop; \
TSB_CAS_TAG_HIGH(TSB, REG1, REG2); \
cmp REG1, REG2; \
bne,pn %icc, 99b; \
nop; \
TSB_MEMBAR
#define TSB_WRITE(TSB, TTE, TAG) \
add TSB, 0x8, TSB; \
TSB_STORE(TSB, TTE); \
sub TSB, 0x8, TSB; \
TSB_MEMBAR; \
TSB_STORE(TSB, TAG);
#define KTSB_LOAD_QUAD(TSB, REG) \
ldda [TSB] ASI_NUCLEUS_QUAD_LDD, REG;
#define KTSB_STORE(ADDR, VAL) \
stxa VAL, [ADDR] ASI_N;
#define KTSB_LOCK_TAG(TSB, REG1, REG2) \
99: lduwa [TSB] ASI_N, REG1; \
sethi %hi(TSB_TAG_LOCK_HIGH), REG2;\
andcc REG1, REG2, %g0; \
bne,pn %icc, 99b; \
nop; \
casa [TSB] ASI_N, REG1, REG2;\
cmp REG1, REG2; \
bne,pn %icc, 99b; \
nop; \
TSB_MEMBAR
#define KTSB_WRITE(TSB, TTE, TAG) \
add TSB, 0x8, TSB; \
stxa TTE, [TSB] ASI_N; \
sub TSB, 0x8, TSB; \
TSB_MEMBAR; \
stxa TAG, [TSB] ASI_N;
/* Do a kernel page table walk. Leaves physical PTE pointer in
* REG1. Jumps to FAIL_LABEL on early page table walk termination.
* VADDR will not be clobbered, but REG2 will.
*/
#define KERN_PGTABLE_WALK(VADDR, REG1, REG2, FAIL_LABEL) \
sethi %hi(swapper_pg_dir), REG1; \
or REG1, %lo(swapper_pg_dir), REG1; \
sllx VADDR, 64 - (PGDIR_SHIFT + PGDIR_BITS), REG2; \
srlx REG2, 64 - PAGE_SHIFT, REG2; \
andn REG2, 0x3, REG2; \
lduw [REG1 + REG2], REG1; \
brz,pn REG1, FAIL_LABEL; \
sllx VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \
srlx REG2, 64 - PAGE_SHIFT, REG2; \
sllx REG1, 11, REG1; \
andn REG2, 0x3, REG2; \
lduwa [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \
brz,pn REG1, FAIL_LABEL; \
sllx VADDR, 64 - PMD_SHIFT, REG2; \
srlx REG2, 64 - PAGE_SHIFT, REG2; \
sllx REG1, 11, REG1; \
andn REG2, 0x7, REG2; \
add REG1, REG2, REG1;
/* Do a user page table walk in MMU globals. Leaves physical PTE
* pointer in REG1. Jumps to FAIL_LABEL on early page table walk
* termination. Physical base of page tables is in PHYS_PGD which
* will not be modified.
*
* VADDR will not be clobbered, but REG1 and REG2 will.
*/
#define USER_PGTABLE_WALK_TL1(VADDR, PHYS_PGD, REG1, REG2, FAIL_LABEL) \
sllx VADDR, 64 - (PGDIR_SHIFT + PGDIR_BITS), REG2; \
srlx REG2, 64 - PAGE_SHIFT, REG2; \
andn REG2, 0x3, REG2; \
lduwa [PHYS_PGD + REG2] ASI_PHYS_USE_EC, REG1; \
brz,pn REG1, FAIL_LABEL; \
sllx VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \
srlx REG2, 64 - PAGE_SHIFT, REG2; \
sllx REG1, 11, REG1; \
andn REG2, 0x3, REG2; \
lduwa [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \
brz,pn REG1, FAIL_LABEL; \
sllx VADDR, 64 - PMD_SHIFT, REG2; \
srlx REG2, 64 - PAGE_SHIFT, REG2; \
sllx REG1, 11, REG1; \
andn REG2, 0x7, REG2; \
add REG1, REG2, REG1;
/* Lookup a OBP mapping on VADDR in the prom_trans[] table at TL>0.
* If no entry is found, FAIL_LABEL will be branched to. On success
* the resulting PTE value will be left in REG1. VADDR is preserved
* by this routine.
*/
#define OBP_TRANS_LOOKUP(VADDR, REG1, REG2, REG3, FAIL_LABEL) \
sethi %hi(prom_trans), REG1; \
or REG1, %lo(prom_trans), REG1; \
97: ldx [REG1 + 0x00], REG2; \
brz,pn REG2, FAIL_LABEL; \
nop; \
ldx [REG1 + 0x08], REG3; \
add REG2, REG3, REG3; \
cmp REG2, VADDR; \
bgu,pt %xcc, 98f; \
cmp VADDR, REG3; \
bgeu,pt %xcc, 98f; \
ldx [REG1 + 0x10], REG3; \
sub VADDR, REG2, REG2; \
ba,pt %xcc, 99f; \
add REG3, REG2, REG1; \
98: ba,pt %xcc, 97b; \
add REG1, (3 * 8), REG1; \
99:
/* We use a 32K TSB for the whole kernel, this allows to
* handle about 16MB of modules and vmalloc mappings without
* incurring many hash conflicts.
*/
#define KERNEL_TSB_SIZE_BYTES (32 * 1024)
#define KERNEL_TSB_NENTRIES \
(KERNEL_TSB_SIZE_BYTES / 16)
#define KERNEL_TSB4M_NENTRIES 4096
/* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL
* on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries
* and the found TTE will be left in REG1. REG3 and REG4 must
* be an even/odd pair of registers.
*
* VADDR and TAG will be preserved and not clobbered by this macro.
*/
#define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
sethi %hi(swapper_tsb), REG1; \
or REG1, %lo(swapper_tsb), REG1; \
srlx VADDR, PAGE_SHIFT, REG2; \
and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \
sllx REG2, 4, REG2; \
add REG1, REG2, REG2; \
KTSB_LOAD_QUAD(REG2, REG3); \
cmp REG3, TAG; \
be,a,pt %xcc, OK_LABEL; \
mov REG4, REG1;
#ifndef CONFIG_DEBUG_PAGEALLOC
/* This version uses a trick, the TAG is already (VADDR >> 22) so
* we can make use of that for the index computation.
*/
#define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
sethi %hi(swapper_4m_tsb), REG1; \
or REG1, %lo(swapper_4m_tsb), REG1; \
and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \
sllx REG2, 4, REG2; \
add REG1, REG2, REG2; \
KTSB_LOAD_QUAD(REG2, REG3); \
cmp REG3, TAG; \
be,a,pt %xcc, OK_LABEL; \
mov REG4, REG1;
#endif
#endif /* !(_SPARC64_TSB_H) */
#ifndef _SPARC64_TTABLE_H
#define _SPARC64_TTABLE_H
#include <asm/utrap.h>
#ifdef __ASSEMBLY__
#include <asm/thread_info.h>
#endif
#define BOOT_KERNEL b sparc64_boot; nop; nop; nop; nop; nop; nop; nop;
/* We need a "cleaned" instruction... */
#define CLEAN_WINDOW \
rdpr %cleanwin, %l0; add %l0, 1, %l0; \
wrpr %l0, 0x0, %cleanwin; \
clr %o0; clr %o1; clr %o2; clr %o3; \
clr %o4; clr %o5; clr %o6; clr %o7; \
clr %l0; clr %l1; clr %l2; clr %l3; \
clr %l4; clr %l5; clr %l6; clr %l7; \
retry; \
nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
#define TRAP(routine) \
sethi %hi(109f), %g7; \
ba,pt %xcc, etrap; \
109: or %g7, %lo(109b), %g7; \
call routine; \
add %sp, PTREGS_OFF, %o0; \
ba,pt %xcc, rtrap; \
nop; \
nop;
#define TRAP_7INSNS(routine) \
sethi %hi(109f), %g7; \
ba,pt %xcc, etrap; \
109: or %g7, %lo(109b), %g7; \
call routine; \
add %sp, PTREGS_OFF, %o0; \
ba,pt %xcc, rtrap; \
nop;
#define TRAP_SAVEFPU(routine) \
sethi %hi(109f), %g7; \
ba,pt %xcc, do_fptrap; \
109: or %g7, %lo(109b), %g7; \
call routine; \
add %sp, PTREGS_OFF, %o0; \
ba,pt %xcc, rtrap; \
nop; \
nop;
#define TRAP_NOSAVE(routine) \
ba,pt %xcc, routine; \
nop; \
nop; nop; nop; nop; nop; nop;
#define TRAP_NOSAVE_7INSNS(routine) \
ba,pt %xcc, routine; \
nop; \
nop; nop; nop; nop; nop;
#define TRAPTL1(routine) \
sethi %hi(109f), %g7; \
ba,pt %xcc, etraptl1; \
109: or %g7, %lo(109b), %g7; \
call routine; \
add %sp, PTREGS_OFF, %o0; \
ba,pt %xcc, rtrap; \
nop; \
nop;
#define TRAP_ARG(routine, arg) \
sethi %hi(109f), %g7; \
ba,pt %xcc, etrap; \
109: or %g7, %lo(109b), %g7; \
add %sp, PTREGS_OFF, %o0; \
call routine; \
mov arg, %o1; \
ba,pt %xcc, rtrap; \
nop;
#define TRAPTL1_ARG(routine, arg) \
sethi %hi(109f), %g7; \
ba,pt %xcc, etraptl1; \
109: or %g7, %lo(109b), %g7; \
add %sp, PTREGS_OFF, %o0; \
call routine; \
mov arg, %o1; \
ba,pt %xcc, rtrap; \
nop;
#define SYSCALL_TRAP(routine, systbl) \
rdpr %pil, %g2; \
mov TSTATE_SYSCALL, %g3; \
sethi %hi(109f), %g7; \
ba,pt %xcc, etrap_syscall; \
109: or %g7, %lo(109b), %g7; \
sethi %hi(systbl), %l7; \
ba,pt %xcc, routine; \
or %l7, %lo(systbl), %l7;
#define TRAP_UTRAP(handler,lvl) \
mov handler, %g3; \
ba,pt %xcc, utrap_trap; \
mov lvl, %g4; \
nop; \
nop; \
nop; \
nop; \
nop;
#ifdef CONFIG_COMPAT
#define LINUX_32BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sys_call_table32)
#else
#define LINUX_32BIT_SYSCALL_TRAP BTRAP(0x110)
#endif
#define LINUX_64BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall, sys_call_table64)
#define GETCC_TRAP TRAP(getcc)
#define SETCC_TRAP TRAP(setcc)
#define BREAKPOINT_TRAP TRAP(breakpoint_trap)
#ifdef CONFIG_TRACE_IRQFLAGS
#define TRAP_IRQ(routine, level) \
rdpr %pil, %g2; \
wrpr %g0, 15, %pil; \
sethi %hi(1f-4), %g7; \
ba,pt %xcc, etrap_irq; \
or %g7, %lo(1f-4), %g7; \
nop; \
nop; \
nop; \
.subsection 2; \
1: call trace_hardirqs_off; \
nop; \
mov level, %o0; \
call routine; \
add %sp, PTREGS_OFF, %o1; \
ba,a,pt %xcc, rtrap_irq; \
.previous;
#else
#define TRAP_IRQ(routine, level) \
rdpr %pil, %g2; \
wrpr %g0, 15, %pil; \
ba,pt %xcc, etrap_irq; \
rd %pc, %g7; \
mov level, %o0; \
call routine; \
add %sp, PTREGS_OFF, %o1; \
ba,a,pt %xcc, rtrap_irq;
#endif
#define TRAP_IVEC TRAP_NOSAVE(do_ivec)
#define BTRAP(lvl) TRAP_ARG(bad_trap, lvl)
#define BTRAPTL1(lvl) TRAPTL1_ARG(bad_trap_tl1, lvl)
#define FLUSH_WINDOW_TRAP \
ba,pt %xcc, etrap; \
rd %pc, %g7; \
flushw; \
ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1; \
add %l1, 4, %l2; \
stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]; \
ba,pt %xcc, rtrap; \
stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC];
#ifdef CONFIG_KPROBES
#define KPROBES_TRAP(lvl) TRAP_IRQ(kprobe_trap, lvl)
#else
#define KPROBES_TRAP(lvl) TRAP_ARG(bad_trap, lvl)
#endif
#ifdef CONFIG_KGDB
#define KGDB_TRAP(lvl) TRAP_IRQ(kgdb_trap, lvl)
#else
#define KGDB_TRAP(lvl) TRAP_ARG(bad_trap, lvl)
#endif
#define SUN4V_ITSB_MISS \
ldxa [%g0] ASI_SCRATCHPAD, %g2; \
ldx [%g2 + HV_FAULT_I_ADDR_OFFSET], %g4; \
ldx [%g2 + HV_FAULT_I_CTX_OFFSET], %g5; \
srlx %g4, 22, %g6; \
ba,pt %xcc, sun4v_itsb_miss; \
nop; \
nop; \
nop;
#define SUN4V_DTSB_MISS \
ldxa [%g0] ASI_SCRATCHPAD, %g2; \
ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4; \
ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5; \
srlx %g4, 22, %g6; \
ba,pt %xcc, sun4v_dtsb_miss; \
nop; \
nop; \
nop;
/* Before touching these macros, you owe it to yourself to go and
* see how arch/sparc64/kernel/winfixup.S works... -DaveM
*
* For the user cases we used to use the %asi register, but
* it turns out that the "wr xxx, %asi" costs ~5 cycles, so
* now we use immediate ASI loads and stores instead. Kudos
* to Greg Onufer for pointing out this performance anomaly.
*
* Further note that we cannot use the g2, g4, g5, and g7 alternate
* globals in the spill routines, check out the save instruction in
* arch/sparc64/kernel/etrap.S to see what I mean about g2, and
* g4/g5 are the globals which are preserved by etrap processing
* for the caller of it. The g7 register is the return pc for
* etrap. Finally, g6 is the current thread register so we cannot
* us it in the spill handlers either. Most of these rules do not
* apply to fill processing, only g6 is not usable.
*/
/* Normal kernel spill */
#define SPILL_0_NORMAL \
stx %l0, [%sp + STACK_BIAS + 0x00]; \
stx %l1, [%sp + STACK_BIAS + 0x08]; \
stx %l2, [%sp + STACK_BIAS + 0x10]; \
stx %l3, [%sp + STACK_BIAS + 0x18]; \
stx %l4, [%sp + STACK_BIAS + 0x20]; \
stx %l5, [%sp + STACK_BIAS + 0x28]; \
stx %l6, [%sp + STACK_BIAS + 0x30]; \
stx %l7, [%sp + STACK_BIAS + 0x38]; \
stx %i0, [%sp + STACK_BIAS + 0x40]; \
stx %i1, [%sp + STACK_BIAS + 0x48]; \
stx %i2, [%sp + STACK_BIAS + 0x50]; \
stx %i3, [%sp + STACK_BIAS + 0x58]; \
stx %i4, [%sp + STACK_BIAS + 0x60]; \
stx %i5, [%sp + STACK_BIAS + 0x68]; \
stx %i6, [%sp + STACK_BIAS + 0x70]; \
stx %i7, [%sp + STACK_BIAS + 0x78]; \
saved; retry; nop; nop; nop; nop; nop; nop; \
nop; nop; nop; nop; nop; nop; nop; nop;
#define SPILL_0_NORMAL_ETRAP \
etrap_kernel_spill: \
stx %l0, [%sp + STACK_BIAS + 0x00]; \
stx %l1, [%sp + STACK_BIAS + 0x08]; \
stx %l2, [%sp + STACK_BIAS + 0x10]; \
stx %l3, [%sp + STACK_BIAS + 0x18]; \
stx %l4, [%sp + STACK_BIAS + 0x20]; \
stx %l5, [%sp + STACK_BIAS + 0x28]; \
stx %l6, [%sp + STACK_BIAS + 0x30]; \
stx %l7, [%sp + STACK_BIAS + 0x38]; \
stx %i0, [%sp + STACK_BIAS + 0x40]; \
stx %i1, [%sp + STACK_BIAS + 0x48]; \
stx %i2, [%sp + STACK_BIAS + 0x50]; \
stx %i3, [%sp + STACK_BIAS + 0x58]; \
stx %i4, [%sp + STACK_BIAS + 0x60]; \
stx %i5, [%sp + STACK_BIAS + 0x68]; \
stx %i6, [%sp + STACK_BIAS + 0x70]; \
stx %i7, [%sp + STACK_BIAS + 0x78]; \
saved; \
sub %g1, 2, %g1; \
ba,pt %xcc, etrap_save; \
wrpr %g1, %cwp; \
nop; nop; nop; nop; nop; nop; nop; nop; \
nop; nop; nop; nop;
/* Normal 64bit spill */
#define SPILL_1_GENERIC(ASI) \
add %sp, STACK_BIAS + 0x00, %g1; \
stxa %l0, [%g1 + %g0] ASI; \
mov 0x08, %g3; \
stxa %l1, [%g1 + %g3] ASI; \
add %g1, 0x10, %g1; \
stxa %l2, [%g1 + %g0] ASI; \
stxa %l3, [%g1 + %g3] ASI; \
add %g1, 0x10, %g1; \
stxa %l4, [%g1 + %g0] ASI; \
stxa %l5, [%g1 + %g3] ASI; \
add %g1, 0x10, %g1; \
stxa %l6, [%g1 + %g0] ASI; \
stxa %l7, [%g1 + %g3] ASI; \
add %g1, 0x10, %g1; \
stxa %i0, [%g1 + %g0] ASI; \
stxa %i1, [%g1 + %g3] ASI; \
add %g1, 0x10, %g1; \
stxa %i2, [%g1 + %g0] ASI; \
stxa %i3, [%g1 + %g3] ASI; \
add %g1, 0x10, %g1; \
stxa %i4, [%g1 + %g0] ASI; \
stxa %i5, [%g1 + %g3] ASI; \
add %g1, 0x10, %g1; \
stxa %i6, [%g1 + %g0] ASI; \
stxa %i7, [%g1 + %g3] ASI; \
saved; \
retry; nop; nop; \
b,a,pt %xcc, spill_fixup_dax; \
b,a,pt %xcc, spill_fixup_mna; \
b,a,pt %xcc, spill_fixup;
#define SPILL_1_GENERIC_ETRAP \
etrap_user_spill_64bit: \
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; \
sub %g1, 2, %g1; \
ba,pt %xcc, etrap_save; \
wrpr %g1, %cwp; \
nop; nop; nop; nop; nop; \
nop; nop; nop; nop; \
ba,a,pt %xcc, etrap_spill_fixup_64bit; \
ba,a,pt %xcc, etrap_spill_fixup_64bit; \
ba,a,pt %xcc, etrap_spill_fixup_64bit;
#define SPILL_1_GENERIC_ETRAP_FIXUP \
etrap_spill_fixup_64bit: \
ldub [%g6 + TI_WSAVED], %g1; \
sll %g1, 3, %g3; \
add %g6, %g3, %g3; \
stx %sp, [%g3 + TI_RWIN_SPTRS]; \
sll %g1, 7, %g3; \
add %g6, %g3, %g3; \
stx %l0, [%g3 + TI_REG_WINDOW + 0x00]; \
stx %l1, [%g3 + TI_REG_WINDOW + 0x08]; \
stx %l2, [%g3 + TI_REG_WINDOW + 0x10]; \
stx %l3, [%g3 + TI_REG_WINDOW + 0x18]; \
stx %l4, [%g3 + TI_REG_WINDOW + 0x20]; \
stx %l5, [%g3 + TI_REG_WINDOW + 0x28]; \
stx %l6, [%g3 + TI_REG_WINDOW + 0x30]; \
stx %l7, [%g3 + TI_REG_WINDOW + 0x38]; \
stx %i0, [%g3 + TI_REG_WINDOW + 0x40]; \
stx %i1, [%g3 + TI_REG_WINDOW + 0x48]; \
stx %i2, [%g3 + TI_REG_WINDOW + 0x50]; \
stx %i3, [%g3 + TI_REG_WINDOW + 0x58]; \
stx %i4, [%g3 + TI_REG_WINDOW + 0x60]; \
stx %i5, [%g3 + TI_REG_WINDOW + 0x68]; \
stx %i6, [%g3 + TI_REG_WINDOW + 0x70]; \
stx %i7, [%g3 + TI_REG_WINDOW + 0x78]; \
add %g1, 1, %g1; \
stb %g1, [%g6 + TI_WSAVED]; \
saved; \
rdpr %cwp, %g1; \
sub %g1, 2, %g1; \
ba,pt %xcc, etrap_save; \
wrpr %g1, %cwp; \
nop; nop; nop
/* Normal 32bit spill */
#define SPILL_2_GENERIC(ASI) \
srl %sp, 0, %sp; \
stwa %l0, [%sp + %g0] ASI; \
mov 0x04, %g3; \
stwa %l1, [%sp + %g3] ASI; \
add %sp, 0x08, %g1; \
stwa %l2, [%g1 + %g0] ASI; \
stwa %l3, [%g1 + %g3] ASI; \
add %g1, 0x08, %g1; \
stwa %l4, [%g1 + %g0] ASI; \
stwa %l5, [%g1 + %g3] ASI; \
add %g1, 0x08, %g1; \
stwa %l6, [%g1 + %g0] ASI; \
stwa %l7, [%g1 + %g3] ASI; \
add %g1, 0x08, %g1; \
stwa %i0, [%g1 + %g0] ASI; \
stwa %i1, [%g1 + %g3] ASI; \
add %g1, 0x08, %g1; \
stwa %i2, [%g1 + %g0] ASI; \
stwa %i3, [%g1 + %g3] ASI; \
add %g1, 0x08, %g1; \
stwa %i4, [%g1 + %g0] ASI; \
stwa %i5, [%g1 + %g3] ASI; \
add %g1, 0x08, %g1; \
stwa %i6, [%g1 + %g0] ASI; \
stwa %i7, [%g1 + %g3] ASI; \
saved; \
retry; nop; nop; \
b,a,pt %xcc, spill_fixup_dax; \
b,a,pt %xcc, spill_fixup_mna; \
b,a,pt %xcc, spill_fixup;
#define SPILL_2_GENERIC_ETRAP \
etrap_user_spill_32bit: \
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; \
sub %g1, 2, %g1; \
ba,pt %xcc, etrap_save; \
wrpr %g1, %cwp; \
nop; nop; nop; nop; \
nop; nop; nop; nop; \
ba,a,pt %xcc, etrap_spill_fixup_32bit; \
ba,a,pt %xcc, etrap_spill_fixup_32bit; \
ba,a,pt %xcc, etrap_spill_fixup_32bit;
#define SPILL_2_GENERIC_ETRAP_FIXUP \
etrap_spill_fixup_32bit: \
ldub [%g6 + TI_WSAVED], %g1; \
sll %g1, 3, %g3; \
add %g6, %g3, %g3; \
stx %sp, [%g3 + TI_RWIN_SPTRS]; \
sll %g1, 7, %g3; \
add %g6, %g3, %g3; \
stw %l0, [%g3 + TI_REG_WINDOW + 0x00]; \
stw %l1, [%g3 + TI_REG_WINDOW + 0x04]; \
stw %l2, [%g3 + TI_REG_WINDOW + 0x08]; \
stw %l3, [%g3 + TI_REG_WINDOW + 0x0c]; \
stw %l4, [%g3 + TI_REG_WINDOW + 0x10]; \
stw %l5, [%g3 + TI_REG_WINDOW + 0x14]; \
stw %l6, [%g3 + TI_REG_WINDOW + 0x18]; \
stw %l7, [%g3 + TI_REG_WINDOW + 0x1c]; \
stw %i0, [%g3 + TI_REG_WINDOW + 0x20]; \
stw %i1, [%g3 + TI_REG_WINDOW + 0x24]; \
stw %i2, [%g3 + TI_REG_WINDOW + 0x28]; \
stw %i3, [%g3 + TI_REG_WINDOW + 0x2c]; \
stw %i4, [%g3 + TI_REG_WINDOW + 0x30]; \
stw %i5, [%g3 + TI_REG_WINDOW + 0x34]; \
stw %i6, [%g3 + TI_REG_WINDOW + 0x38]; \
stw %i7, [%g3 + TI_REG_WINDOW + 0x3c]; \
add %g1, 1, %g1; \
stb %g1, [%g6 + TI_WSAVED]; \
saved; \
rdpr %cwp, %g1; \
sub %g1, 2, %g1; \
ba,pt %xcc, etrap_save; \
wrpr %g1, %cwp; \
nop; nop; nop
#define SPILL_1_NORMAL SPILL_1_GENERIC(ASI_AIUP)
#define SPILL_2_NORMAL SPILL_2_GENERIC(ASI_AIUP)
#define SPILL_3_NORMAL SPILL_0_NORMAL
#define SPILL_4_NORMAL SPILL_0_NORMAL
#define SPILL_5_NORMAL SPILL_0_NORMAL
#define SPILL_6_NORMAL SPILL_0_NORMAL
#define SPILL_7_NORMAL SPILL_0_NORMAL
#define SPILL_0_OTHER SPILL_0_NORMAL
#define SPILL_1_OTHER SPILL_1_GENERIC(ASI_AIUS)
#define SPILL_2_OTHER SPILL_2_GENERIC(ASI_AIUS)
#define SPILL_3_OTHER SPILL_3_NORMAL
#define SPILL_4_OTHER SPILL_4_NORMAL
#define SPILL_5_OTHER SPILL_5_NORMAL
#define SPILL_6_OTHER SPILL_6_NORMAL
#define SPILL_7_OTHER SPILL_7_NORMAL
/* Normal kernel fill */
#define FILL_0_NORMAL \
ldx [%sp + STACK_BIAS + 0x00], %l0; \
ldx [%sp + STACK_BIAS + 0x08], %l1; \
ldx [%sp + STACK_BIAS + 0x10], %l2; \
ldx [%sp + STACK_BIAS + 0x18], %l3; \
ldx [%sp + STACK_BIAS + 0x20], %l4; \
ldx [%sp + STACK_BIAS + 0x28], %l5; \
ldx [%sp + STACK_BIAS + 0x30], %l6; \
ldx [%sp + STACK_BIAS + 0x38], %l7; \
ldx [%sp + STACK_BIAS + 0x40], %i0; \
ldx [%sp + STACK_BIAS + 0x48], %i1; \
ldx [%sp + STACK_BIAS + 0x50], %i2; \
ldx [%sp + STACK_BIAS + 0x58], %i3; \
ldx [%sp + STACK_BIAS + 0x60], %i4; \
ldx [%sp + STACK_BIAS + 0x68], %i5; \
ldx [%sp + STACK_BIAS + 0x70], %i6; \
ldx [%sp + STACK_BIAS + 0x78], %i7; \
restored; retry; nop; nop; nop; nop; nop; nop; \
nop; nop; nop; nop; nop; nop; nop; nop;
#define FILL_0_NORMAL_RTRAP \
kern_rtt_fill: \
rdpr %cwp, %g1; \
sub %g1, 1, %g1; \
wrpr %g1, %cwp; \
ldx [%sp + STACK_BIAS + 0x00], %l0; \
ldx [%sp + STACK_BIAS + 0x08], %l1; \
ldx [%sp + STACK_BIAS + 0x10], %l2; \
ldx [%sp + STACK_BIAS + 0x18], %l3; \
ldx [%sp + STACK_BIAS + 0x20], %l4; \
ldx [%sp + STACK_BIAS + 0x28], %l5; \
ldx [%sp + STACK_BIAS + 0x30], %l6; \
ldx [%sp + STACK_BIAS + 0x38], %l7; \
ldx [%sp + STACK_BIAS + 0x40], %i0; \
ldx [%sp + STACK_BIAS + 0x48], %i1; \
ldx [%sp + STACK_BIAS + 0x50], %i2; \
ldx [%sp + STACK_BIAS + 0x58], %i3; \
ldx [%sp + STACK_BIAS + 0x60], %i4; \
ldx [%sp + STACK_BIAS + 0x68], %i5; \
ldx [%sp + STACK_BIAS + 0x70], %i6; \
ldx [%sp + STACK_BIAS + 0x78], %i7; \
restored; \
add %g1, 1, %g1; \
ba,pt %xcc, kern_rtt_restore; \
wrpr %g1, %cwp; \
nop; nop; nop; nop; nop; \
nop; nop; nop; nop;
/* Normal 64bit fill */
#define FILL_1_GENERIC(ASI) \
add %sp, STACK_BIAS + 0x00, %g1; \
ldxa [%g1 + %g0] ASI, %l0; \
mov 0x08, %g2; \
mov 0x10, %g3; \
ldxa [%g1 + %g2] ASI, %l1; \
mov 0x18, %g5; \
ldxa [%g1 + %g3] ASI, %l2; \
ldxa [%g1 + %g5] ASI, %l3; \
add %g1, 0x20, %g1; \
ldxa [%g1 + %g0] ASI, %l4; \
ldxa [%g1 + %g2] ASI, %l5; \
ldxa [%g1 + %g3] ASI, %l6; \
ldxa [%g1 + %g5] ASI, %l7; \
add %g1, 0x20, %g1; \
ldxa [%g1 + %g0] ASI, %i0; \
ldxa [%g1 + %g2] ASI, %i1; \
ldxa [%g1 + %g3] ASI, %i2; \
ldxa [%g1 + %g5] ASI, %i3; \
add %g1, 0x20, %g1; \
ldxa [%g1 + %g0] ASI, %i4; \
ldxa [%g1 + %g2] ASI, %i5; \
ldxa [%g1 + %g3] ASI, %i6; \
ldxa [%g1 + %g5] ASI, %i7; \
restored; \
retry; nop; nop; nop; nop; \
b,a,pt %xcc, fill_fixup_dax; \
b,a,pt %xcc, fill_fixup_mna; \
b,a,pt %xcc, fill_fixup;
#define FILL_1_GENERIC_RTRAP \
user_rtt_fill_64bit: \
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; \
ba,pt %xcc, user_rtt_pre_restore; \
restored; \
nop; nop; nop; nop; nop; nop; \
nop; nop; nop; nop; nop; \
ba,a,pt %xcc, user_rtt_fill_fixup; \
ba,a,pt %xcc, user_rtt_fill_fixup; \
ba,a,pt %xcc, user_rtt_fill_fixup;
/* Normal 32bit fill */
#define FILL_2_GENERIC(ASI) \
srl %sp, 0, %sp; \
lduwa [%sp + %g0] ASI, %l0; \
mov 0x04, %g2; \
mov 0x08, %g3; \
lduwa [%sp + %g2] ASI, %l1; \
mov 0x0c, %g5; \
lduwa [%sp + %g3] ASI, %l2; \
lduwa [%sp + %g5] ASI, %l3; \
add %sp, 0x10, %g1; \
lduwa [%g1 + %g0] ASI, %l4; \
lduwa [%g1 + %g2] ASI, %l5; \
lduwa [%g1 + %g3] ASI, %l6; \
lduwa [%g1 + %g5] ASI, %l7; \
add %g1, 0x10, %g1; \
lduwa [%g1 + %g0] ASI, %i0; \
lduwa [%g1 + %g2] ASI, %i1; \
lduwa [%g1 + %g3] ASI, %i2; \
lduwa [%g1 + %g5] ASI, %i3; \
add %g1, 0x10, %g1; \
lduwa [%g1 + %g0] ASI, %i4; \
lduwa [%g1 + %g2] ASI, %i5; \
lduwa [%g1 + %g3] ASI, %i6; \
lduwa [%g1 + %g5] ASI, %i7; \
restored; \
retry; nop; nop; nop; nop; \
b,a,pt %xcc, fill_fixup_dax; \
b,a,pt %xcc, fill_fixup_mna; \
b,a,pt %xcc, fill_fixup;
#define FILL_2_GENERIC_RTRAP \
user_rtt_fill_32bit: \
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; \
ba,pt %xcc, user_rtt_pre_restore; \
restored; \
nop; nop; nop; nop; nop; \
nop; nop; nop; nop; nop; \
ba,a,pt %xcc, user_rtt_fill_fixup; \
ba,a,pt %xcc, user_rtt_fill_fixup; \
ba,a,pt %xcc, user_rtt_fill_fixup;
#define FILL_1_NORMAL FILL_1_GENERIC(ASI_AIUP)
#define FILL_2_NORMAL FILL_2_GENERIC(ASI_AIUP)
#define FILL_3_NORMAL FILL_0_NORMAL
#define FILL_4_NORMAL FILL_0_NORMAL
#define FILL_5_NORMAL FILL_0_NORMAL
#define FILL_6_NORMAL FILL_0_NORMAL
#define FILL_7_NORMAL FILL_0_NORMAL
#define FILL_0_OTHER FILL_0_NORMAL
#define FILL_1_OTHER FILL_1_GENERIC(ASI_AIUS)
#define FILL_2_OTHER FILL_2_GENERIC(ASI_AIUS)
#define FILL_3_OTHER FILL_3_NORMAL
#define FILL_4_OTHER FILL_4_NORMAL
#define FILL_5_OTHER FILL_5_NORMAL
#define FILL_6_OTHER FILL_6_NORMAL
#define FILL_7_OTHER FILL_7_NORMAL
#endif /* !(_SPARC64_TTABLE_H) */
#ifndef _SPARC64_UPA_H
#define _SPARC64_UPA_H
#include <asm/asi.h>
/* UPA level registers and defines. */
/* UPA Config Register */
#define UPA_CONFIG_RESV 0xffffffffc0000000 /* Reserved. */
#define UPA_CONFIG_PCON 0x000000003fc00000 /* Depth of various sys queues. */
#define UPA_CONFIG_MID 0x00000000003e0000 /* Module ID. */
#define UPA_CONFIG_PCAP 0x000000000001ffff /* Port Capabilities. */
/* UPA Port ID Register */
#define UPA_PORTID_FNP 0xff00000000000000 /* Hardcoded to 0xfc on ultra. */
#define UPA_PORTID_RESV 0x00fffff800000000 /* Reserved. */
#define UPA_PORTID_ECCVALID 0x0000000400000000 /* Zero if mod can generate ECC */
#define UPA_PORTID_ONEREAD 0x0000000200000000 /* Set if mod generates P_RASB */
#define UPA_PORTID_PINTRDQ 0x0000000180000000 /* # outstanding P_INT_REQ's */
#define UPA_PORTID_PREQDQ 0x000000007e000000 /* slave-wr's to mod supported */
#define UPA_PORTID_PREQRD 0x0000000001e00000 /* # incoming P_REQ's supported */
#define UPA_PORTID_UPACAP 0x00000000001f0000 /* UPA capabilities of mod */
#define UPA_PORTID_ID 0x000000000000ffff /* Module Identification bits */
/* UPA I/O space accessors */
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
static inline unsigned char _upa_readb(unsigned long addr)
{
unsigned char ret;
__asm__ __volatile__("lduba\t[%1] %2, %0\t/* upa_readb */"
: "=r" (ret)
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
return ret;
}
static inline unsigned short _upa_readw(unsigned long addr)
{
unsigned short ret;
__asm__ __volatile__("lduha\t[%1] %2, %0\t/* upa_readw */"
: "=r" (ret)
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
return ret;
}
static inline unsigned int _upa_readl(unsigned long addr)
{
unsigned int ret;
__asm__ __volatile__("lduwa\t[%1] %2, %0\t/* upa_readl */"
: "=r" (ret)
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
return ret;
}
static inline unsigned long _upa_readq(unsigned long addr)
{
unsigned long ret;
__asm__ __volatile__("ldxa\t[%1] %2, %0\t/* upa_readq */"
: "=r" (ret)
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
return ret;
}
static inline void _upa_writeb(unsigned char b, unsigned long addr)
{
__asm__ __volatile__("stba\t%0, [%1] %2\t/* upa_writeb */"
: /* no outputs */
: "r" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
}
static inline void _upa_writew(unsigned short w, unsigned long addr)
{
__asm__ __volatile__("stha\t%0, [%1] %2\t/* upa_writew */"
: /* no outputs */
: "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
}
static inline void _upa_writel(unsigned int l, unsigned long addr)
{
__asm__ __volatile__("stwa\t%0, [%1] %2\t/* upa_writel */"
: /* no outputs */
: "r" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
}
static inline void _upa_writeq(unsigned long q, unsigned long addr)
{
__asm__ __volatile__("stxa\t%0, [%1] %2\t/* upa_writeq */"
: /* no outputs */
: "r" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
}
#define upa_readb(__addr) (_upa_readb((unsigned long)(__addr)))
#define upa_readw(__addr) (_upa_readw((unsigned long)(__addr)))
#define upa_readl(__addr) (_upa_readl((unsigned long)(__addr)))
#define upa_readq(__addr) (_upa_readq((unsigned long)(__addr)))
#define upa_writeb(__b, __addr) (_upa_writeb((__b), (unsigned long)(__addr)))
#define upa_writew(__w, __addr) (_upa_writew((__w), (unsigned long)(__addr)))
#define upa_writel(__l, __addr) (_upa_writel((__l), (unsigned long)(__addr)))
#define upa_writeq(__q, __addr) (_upa_writeq((__q), (unsigned long)(__addr)))
#endif /* __KERNEL__ && !__ASSEMBLY__ */
#endif /* !(_SPARC64_UPA_H) */
#ifndef _SPARC64_VIO_H
#define _SPARC64_VIO_H
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/mod_devicetable.h>
#include <linux/timer.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/list.h>
#include <linux/log2.h>
#include <asm/ldc.h>
#include <asm/mdesc.h>
struct vio_msg_tag {
u8 type;
#define VIO_TYPE_CTRL 0x01
#define VIO_TYPE_DATA 0x02
#define VIO_TYPE_ERR 0x04
u8 stype;
#define VIO_SUBTYPE_INFO 0x01
#define VIO_SUBTYPE_ACK 0x02
#define VIO_SUBTYPE_NACK 0x04
u16 stype_env;
#define VIO_VER_INFO 0x0001
#define VIO_ATTR_INFO 0x0002
#define VIO_DRING_REG 0x0003
#define VIO_DRING_UNREG 0x0004
#define VIO_RDX 0x0005
#define VIO_PKT_DATA 0x0040
#define VIO_DESC_DATA 0x0041
#define VIO_DRING_DATA 0x0042
#define VNET_MCAST_INFO 0x0101
u32 sid;
};
struct vio_rdx {
struct vio_msg_tag tag;
u64 resv[6];
};
struct vio_ver_info {
struct vio_msg_tag tag;
u16 major;
u16 minor;
u8 dev_class;
#define VDEV_NETWORK 0x01
#define VDEV_NETWORK_SWITCH 0x02
#define VDEV_DISK 0x03
#define VDEV_DISK_SERVER 0x04
u8 resv1[3];
u64 resv2[5];
};
struct vio_dring_register {
struct vio_msg_tag tag;
u64 dring_ident;
u32 num_descr;
u32 descr_size;
u16 options;
#define VIO_TX_DRING 0x0001
#define VIO_RX_DRING 0x0002
u16 resv;
u32 num_cookies;
struct ldc_trans_cookie cookies[0];
};
struct vio_dring_unregister {
struct vio_msg_tag tag;
u64 dring_ident;
u64 resv[5];
};
/* Data transfer modes */
#define VIO_PKT_MODE 0x01 /* Packet based transfer */
#define VIO_DESC_MODE 0x02 /* In-band descriptors */
#define VIO_DRING_MODE 0x03 /* Descriptor rings */
struct vio_dring_data {
struct vio_msg_tag tag;
u64 seq;
u64 dring_ident;
u32 start_idx;
u32 end_idx;
u8 state;
#define VIO_DRING_ACTIVE 0x01
#define VIO_DRING_STOPPED 0x02
u8 __pad1;
u16 __pad2;
u32 __pad3;
u64 __par4[2];
};
struct vio_dring_hdr {
u8 state;
#define VIO_DESC_FREE 0x01
#define VIO_DESC_READY 0x02
#define VIO_DESC_ACCEPTED 0x03
#define VIO_DESC_DONE 0x04
u8 ack;
#define VIO_ACK_ENABLE 0x01
#define VIO_ACK_DISABLE 0x00
u16 __pad1;
u32 __pad2;
};
/* VIO disk specific structures and defines */
struct vio_disk_attr_info {
struct vio_msg_tag tag;
u8 xfer_mode;
u8 vdisk_type;
#define VD_DISK_TYPE_SLICE 0x01 /* Slice in block device */
#define VD_DISK_TYPE_DISK 0x02 /* Entire block device */
u16 resv1;
u32 vdisk_block_size;
u64 operations;
u64 vdisk_size;
u64 max_xfer_size;
u64 resv2[2];
};
struct vio_disk_desc {
struct vio_dring_hdr hdr;
u64 req_id;
u8 operation;
#define VD_OP_BREAD 0x01 /* Block read */
#define VD_OP_BWRITE 0x02 /* Block write */
#define VD_OP_FLUSH 0x03 /* Flush disk contents */
#define VD_OP_GET_WCE 0x04 /* Get write-cache status */
#define VD_OP_SET_WCE 0x05 /* Enable/disable write-cache */
#define VD_OP_GET_VTOC 0x06 /* Get VTOC */
#define VD_OP_SET_VTOC 0x07 /* Set VTOC */
#define VD_OP_GET_DISKGEOM 0x08 /* Get disk geometry */
#define VD_OP_SET_DISKGEOM 0x09 /* Set disk geometry */
#define VD_OP_SCSICMD 0x0a /* SCSI control command */
#define VD_OP_GET_DEVID 0x0b /* Get device ID */
#define VD_OP_GET_EFI 0x0c /* Get EFI */
#define VD_OP_SET_EFI 0x0d /* Set EFI */
u8 slice;
u16 resv1;
u32 status;
u64 offset;
u64 size;
u32 ncookies;
u32 resv2;
struct ldc_trans_cookie cookies[0];
};
#define VIO_DISK_VNAME_LEN 8
#define VIO_DISK_ALABEL_LEN 128
#define VIO_DISK_NUM_PART 8
struct vio_disk_vtoc {
u8 volume_name[VIO_DISK_VNAME_LEN];
u16 sector_size;
u16 num_partitions;
u8 ascii_label[VIO_DISK_ALABEL_LEN];
struct {
u16 id;
u16 perm_flags;
u32 resv;
u64 start_block;
u64 num_blocks;
} partitions[VIO_DISK_NUM_PART];
};
struct vio_disk_geom {
u16 num_cyl; /* Num data cylinders */
u16 alt_cyl; /* Num alternate cylinders */
u16 beg_cyl; /* Cyl off of fixed head area */
u16 num_hd; /* Num heads */
u16 num_sec; /* Num sectors */
u16 ifact; /* Interleave factor */
u16 apc; /* Alts per cylinder (SCSI) */
u16 rpm; /* Revolutions per minute */
u16 phy_cyl; /* Num physical cylinders */
u16 wr_skip; /* Num sects to skip, writes */
u16 rd_skip; /* Num sects to skip, writes */
};
struct vio_disk_devid {
u16 resv;
u16 type;
u32 len;
char id[0];
};
struct vio_disk_efi {
u64 lba;
u64 len;
char data[0];
};
/* VIO net specific structures and defines */
struct vio_net_attr_info {
struct vio_msg_tag tag;
u8 xfer_mode;
u8 addr_type;
#define VNET_ADDR_ETHERMAC 0x01
u16 ack_freq;
u32 resv1;
u64 addr;
u64 mtu;
u64 resv2[3];
};
#define VNET_NUM_MCAST 7
struct vio_net_mcast_info {
struct vio_msg_tag tag;
u8 set;
u8 count;
u8 mcast_addr[VNET_NUM_MCAST * 6];
u32 resv;
};
struct vio_net_desc {
struct vio_dring_hdr hdr;
u32 size;
u32 ncookies;
struct ldc_trans_cookie cookies[0];
};
#define VIO_MAX_RING_COOKIES 24
struct vio_dring_state {
u64 ident;
void *base;
u64 snd_nxt;
u64 rcv_nxt;
u32 entry_size;
u32 num_entries;
u32 prod;
u32 cons;
u32 pending;
int ncookies;
struct ldc_trans_cookie cookies[VIO_MAX_RING_COOKIES];
};
static inline void *vio_dring_cur(struct vio_dring_state *dr)
{
return dr->base + (dr->entry_size * dr->prod);
}
static inline void *vio_dring_entry(struct vio_dring_state *dr,
unsigned int index)
{
return dr->base + (dr->entry_size * index);
}
static inline u32 vio_dring_avail(struct vio_dring_state *dr,
unsigned int ring_size)
{
BUILD_BUG_ON(!is_power_of_2(ring_size));
return (dr->pending -
((dr->prod - dr->cons) & (ring_size - 1)));
}
#define VIO_MAX_TYPE_LEN 32
#define VIO_MAX_COMPAT_LEN 64
struct vio_dev {
u64 mp;
struct device_node *dp;
char type[VIO_MAX_TYPE_LEN];
char compat[VIO_MAX_COMPAT_LEN];
int compat_len;
u64 dev_no;
unsigned long channel_id;
unsigned int tx_irq;
unsigned int rx_irq;
struct device dev;
};
struct vio_driver {
struct list_head node;
const struct vio_device_id *id_table;
int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
int (*remove)(struct vio_dev *dev);
void (*shutdown)(struct vio_dev *dev);
unsigned long driver_data;
struct device_driver driver;
};
struct vio_version {
u16 major;
u16 minor;
};
struct vio_driver_state;
struct vio_driver_ops {
int (*send_attr)(struct vio_driver_state *vio);
int (*handle_attr)(struct vio_driver_state *vio, void *pkt);
void (*handshake_complete)(struct vio_driver_state *vio);
};
struct vio_completion {
struct completion com;
int err;
int waiting_for;
};
struct vio_driver_state {
/* Protects VIO handshake and, optionally, driver private state. */
spinlock_t lock;
struct ldc_channel *lp;
u32 _peer_sid;
u32 _local_sid;
struct vio_dring_state drings[2];
#define VIO_DRIVER_TX_RING 0
#define VIO_DRIVER_RX_RING 1
u8 hs_state;
#define VIO_HS_INVALID 0x00
#define VIO_HS_GOTVERS 0x01
#define VIO_HS_GOT_ATTR 0x04
#define VIO_HS_SENT_DREG 0x08
#define VIO_HS_SENT_RDX 0x10
#define VIO_HS_GOT_RDX_ACK 0x20
#define VIO_HS_GOT_RDX 0x40
#define VIO_HS_SENT_RDX_ACK 0x80
#define VIO_HS_COMPLETE (VIO_HS_GOT_RDX_ACK | VIO_HS_SENT_RDX_ACK)
u8 dev_class;
u8 dr_state;
#define VIO_DR_STATE_TXREG 0x01
#define VIO_DR_STATE_RXREG 0x02
#define VIO_DR_STATE_TXREQ 0x10
#define VIO_DR_STATE_RXREQ 0x20
u8 debug;
#define VIO_DEBUG_HS 0x01
#define VIO_DEBUG_DATA 0x02
void *desc_buf;
unsigned int desc_buf_len;
struct vio_completion *cmp;
struct vio_dev *vdev;
struct timer_list timer;
struct vio_version ver;
struct vio_version *ver_table;
int ver_table_entries;
char *name;
struct vio_driver_ops *ops;
};
#define viodbg(TYPE, f, a...) \
do { if (vio->debug & VIO_DEBUG_##TYPE) \
printk(KERN_INFO "vio: ID[%lu] " f, \
vio->vdev->channel_id, ## a); \
} while (0)
extern int vio_register_driver(struct vio_driver *drv);
extern void vio_unregister_driver(struct vio_driver *drv);
static inline struct vio_driver *to_vio_driver(struct device_driver *drv)
{
return container_of(drv, struct vio_driver, driver);
}
static inline struct vio_dev *to_vio_dev(struct device *dev)
{
return container_of(dev, struct vio_dev, dev);
}
extern int vio_ldc_send(struct vio_driver_state *vio, void *data, int len);
extern void vio_link_state_change(struct vio_driver_state *vio, int event);
extern void vio_conn_reset(struct vio_driver_state *vio);
extern int vio_control_pkt_engine(struct vio_driver_state *vio, void *pkt);
extern int vio_validate_sid(struct vio_driver_state *vio,
struct vio_msg_tag *tp);
extern u32 vio_send_sid(struct vio_driver_state *vio);
extern int vio_ldc_alloc(struct vio_driver_state *vio,
struct ldc_channel_config *base_cfg, void *event_arg);
extern void vio_ldc_free(struct vio_driver_state *vio);
extern int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev,
u8 dev_class, struct vio_version *ver_table,
int ver_table_size, struct vio_driver_ops *ops,
char *name);
extern void vio_port_up(struct vio_driver_state *vio);
#endif /* _SPARC64_VIO_H */
#ifndef _SPARC64_VISASM_H
#define _SPARC64_VISASM_H
/* visasm.h: FPU saving macros for VIS routines
*
* Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
*/
#include <asm/pstate.h>
#include <asm/ptrace.h>
/* Clobbers %o5, %g1, %g2, %g3, %g7, %icc, %xcc */
#define VISEntry \
rd %fprs, %o5; \
andcc %o5, (FPRS_FEF|FPRS_DU), %g0; \
be,pt %icc, 297f; \
sethi %hi(297f), %g7; \
sethi %hi(VISenter), %g1; \
jmpl %g1 + %lo(VISenter), %g0; \
or %g7, %lo(297f), %g7; \
297: wr %g0, FPRS_FEF, %fprs; \
#define VISExit \
wr %g0, 0, %fprs;
/* Clobbers %o5, %g1, %g2, %g3, %g7, %icc, %xcc.
* Must preserve %o5 between VISEntryHalf and VISExitHalf */
#define VISEntryHalf \
rd %fprs, %o5; \
andcc %o5, FPRS_FEF, %g0; \
be,pt %icc, 297f; \
sethi %hi(298f), %g7; \
sethi %hi(VISenterhalf), %g1; \
jmpl %g1 + %lo(VISenterhalf), %g0; \
or %g7, %lo(298f), %g7; \
clr %o5; \
297: wr %o5, FPRS_FEF, %fprs; \
298:
#define VISExitHalf \
wr %o5, 0, %fprs;
#ifndef __ASSEMBLY__
static inline void save_and_clear_fpu(void) {
__asm__ __volatile__ (
" rd %%fprs, %%o5\n"
" andcc %%o5, %0, %%g0\n"
" be,pt %%icc, 299f\n"
" sethi %%hi(298f), %%g7\n"
" sethi %%hi(VISenter), %%g1\n"
" jmpl %%g1 + %%lo(VISenter), %%g0\n"
" or %%g7, %%lo(298f), %%g7\n"
" 298: wr %%g0, 0, %%fprs\n"
" 299:\n"
" " : : "i" (FPRS_FEF|FPRS_DU) :
"o5", "g1", "g2", "g3", "g7", "cc");
}
#endif
#endif /* _SPARC64_ASI_H */
#ifndef AGP_H
#define AGP_H 1
/* dummy for now */
#define map_page_into_agp(page)
#define unmap_page_from_agp(page)
#define flush_agp_cache() mb()
/* Convert a physical address to an address suitable for the GART. */
#define phys_to_gart(x) (x)
#define gart_to_phys(x) (x)
/* GATT allocation. Returns/accepts GATT kernel virtual address. */
#define alloc_gatt_pages(order) \
((char *)__get_free_pages(GFP_KERNEL, (order)))
#define free_gatt_pages(table, order) \
free_pages((unsigned long)(table), (order))
#endif
#include <asm-sparc/agp.h>
/*
* apb.h: Advanced PCI Bridge Configuration Registers and Bits
*
* Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
*/
#ifndef _SPARC64_APB_H
#define _SPARC64_APB_H
#define APB_TICK_REGISTER 0xb0
#define APB_INT_ACK 0xb8
#define APB_PRIMARY_MASTER_RETRY_LIMIT 0xc0
#define APB_DMA_ASFR 0xc8
#define APB_DMA_AFAR 0xd0
#define APB_PIO_TARGET_RETRY_LIMIT 0xd8
#define APB_PIO_TARGET_LATENCY_TIMER 0xd9
#define APB_DMA_TARGET_RETRY_LIMIT 0xda
#define APB_DMA_TARGET_LATENCY_TIMER 0xdb
#define APB_SECONDARY_MASTER_RETRY_LIMIT 0xdc
#define APB_SECONDARY_CONTROL 0xdd
#define APB_IO_ADDRESS_MAP 0xde
#define APB_MEM_ADDRESS_MAP 0xdf
#define APB_PCI_CONTROL_LOW 0xe0
# define APB_PCI_CTL_LOW_ARB_PARK (1 << 21)
# define APB_PCI_CTL_LOW_ERRINT_EN (1 << 8)
#define APB_PCI_CONTROL_HIGH 0xe4
# define APB_PCI_CTL_HIGH_SERR (1 << 2)
# define APB_PCI_CTL_HIGH_ARBITER_EN (1 << 0)
#define APB_PIO_ASFR 0xe8
#define APB_PIO_AFAR 0xf0
#define APB_DIAG_REGISTER 0xf8
#endif /* !(_SPARC64_APB_H) */
#include <asm-sparc/apb.h>
#ifndef _SPARC64_BACKOFF_H
#define _SPARC64_BACKOFF_H
#define BACKOFF_LIMIT (4 * 1024)
#ifdef CONFIG_SMP
#define BACKOFF_SETUP(reg) \
mov 1, reg
#define BACKOFF_SPIN(reg, tmp, label) \
mov reg, tmp; \
88: brnz,pt tmp, 88b; \
sub tmp, 1, tmp; \
set BACKOFF_LIMIT, tmp; \
cmp reg, tmp; \
bg,pn %xcc, label; \
nop; \
ba,pt %xcc, label; \
sllx reg, 1, reg;
#else
#define BACKOFF_SETUP(reg)
#define BACKOFF_SPIN(reg, tmp, label) \
ba,pt %xcc, label; \
nop;
#endif
#endif /* _SPARC64_BACKOFF_H */
#include <asm-sparc/backoff.h>
/*
* bbc.h: Defines for BootBus Controller found on UltraSPARC-III
* systems.
*
* Copyright (C) 2000 David S. Miller (davem@redhat.com)
*/
#ifndef _SPARC64_BBC_H
#define _SPARC64_BBC_H
/* Register sizes are indicated by "B" (Byte, 1-byte),
* "H" (Half-word, 2 bytes), "W" (Word, 4 bytes) or
* "Q" (Quad, 8 bytes) inside brackets.
*/
#define BBC_AID 0x00 /* [B] Agent ID */
#define BBC_DEVP 0x01 /* [B] Device Present */
#define BBC_ARB 0x02 /* [B] Arbitration */
#define BBC_QUIESCE 0x03 /* [B] Quiesce */
#define BBC_WDACTION 0x04 /* [B] Watchdog Action */
#define BBC_SPG 0x06 /* [B] Soft POR Gen */
#define BBC_SXG 0x07 /* [B] Soft XIR Gen */
#define BBC_PSRC 0x08 /* [W] POR Source */
#define BBC_XSRC 0x0c /* [B] XIR Source */
#define BBC_CSC 0x0d /* [B] Clock Synthesizers Control*/
#define BBC_ES_CTRL 0x0e /* [H] Energy Star Control */
#define BBC_ES_ACT 0x10 /* [W] E* Assert Change Time */
#define BBC_ES_DACT 0x14 /* [B] E* De-Assert Change Time */
#define BBC_ES_DABT 0x15 /* [B] E* De-Assert Bypass Time */
#define BBC_ES_ABT 0x16 /* [H] E* Assert Bypass Time */
#define BBC_ES_PST 0x18 /* [W] E* PLL Settle Time */
#define BBC_ES_FSL 0x1c /* [W] E* Frequency Switch Latency*/
#define BBC_EBUST 0x20 /* [Q] EBUS Timing */
#define BBC_JTAG_CMD 0x28 /* [W] JTAG+ Command */
#define BBC_JTAG_CTRL 0x2c /* [B] JTAG+ Control */
#define BBC_I2C_SEL 0x2d /* [B] I2C Selection */
#define BBC_I2C_0_S1 0x2e /* [B] I2C ctrlr-0 reg S1 */
#define BBC_I2C_0_S0 0x2f /* [B] I2C ctrlr-0 regs S0,S0',S2,S3*/
#define BBC_I2C_1_S1 0x30 /* [B] I2C ctrlr-1 reg S1 */
#define BBC_I2C_1_S0 0x31 /* [B] I2C ctrlr-1 regs S0,S0',S2,S3*/
#define BBC_KBD_BEEP 0x32 /* [B] Keyboard Beep */
#define BBC_KBD_BCNT 0x34 /* [W] Keyboard Beep Counter */
#define BBC_REGS_SIZE 0x40
/* There is a 2K scratch ram area at offset 0x80000 but I doubt
* we will use it for anything.
*/
/* Agent ID register. This register shows the Safari Agent ID
* for the processors. The value returned depends upon which
* cpu is reading the register.
*/
#define BBC_AID_ID 0x07 /* Safari ID */
#define BBC_AID_RESV 0xf8 /* Reserved */
/* Device Present register. One can determine which cpus are actually
* present in the machine by interrogating this register.
*/
#define BBC_DEVP_CPU0 0x01 /* Processor 0 present */
#define BBC_DEVP_CPU1 0x02 /* Processor 1 present */
#define BBC_DEVP_CPU2 0x04 /* Processor 2 present */
#define BBC_DEVP_CPU3 0x08 /* Processor 3 present */
#define BBC_DEVP_RESV 0xf0 /* Reserved */
/* Arbitration register. This register is used to block access to
* the BBC from a particular cpu.
*/
#define BBC_ARB_CPU0 0x01 /* Enable cpu 0 BBC arbitratrion */
#define BBC_ARB_CPU1 0x02 /* Enable cpu 1 BBC arbitratrion */
#define BBC_ARB_CPU2 0x04 /* Enable cpu 2 BBC arbitratrion */
#define BBC_ARB_CPU3 0x08 /* Enable cpu 3 BBC arbitratrion */
#define BBC_ARB_RESV 0xf0 /* Reserved */
/* Quiesce register. Bus and BBC segments for cpus can be disabled
* with this register, ie. for hot plugging.
*/
#define BBC_QUIESCE_S02 0x01 /* Quiesce Safari segment for cpu 0 and 2 */
#define BBC_QUIESCE_S13 0x02 /* Quiesce Safari segment for cpu 1 and 3 */
#define BBC_QUIESCE_B02 0x04 /* Quiesce BBC segment for cpu 0 and 2 */
#define BBC_QUIESCE_B13 0x08 /* Quiesce BBC segment for cpu 1 and 3 */
#define BBC_QUIESCE_FD0 0x10 /* Disable Fatal_Error[0] reporting */
#define BBC_QUIESCE_FD1 0x20 /* Disable Fatal_Error[1] reporting */
#define BBC_QUIESCE_FD2 0x40 /* Disable Fatal_Error[2] reporting */
#define BBC_QUIESCE_FD3 0x80 /* Disable Fatal_Error[3] reporting */
/* Watchdog Action register. When the watchdog device timer expires
* a line is enabled to the BBC. The action BBC takes when this line
* is asserted can be controlled by this regiser.
*/
#define BBC_WDACTION_RST 0x01 /* When set, watchdog causes system reset.
* When clear, BBC ignores watchdog signal.
*/
#define BBC_WDACTION_RESV 0xfe /* Reserved */
/* Soft_POR_GEN register. The POR (Power On Reset) signal may be asserted
* for specific processors or all processors via this register.
*/
#define BBC_SPG_CPU0 0x01 /* Assert POR for processor 0 */
#define BBC_SPG_CPU1 0x02 /* Assert POR for processor 1 */
#define BBC_SPG_CPU2 0x04 /* Assert POR for processor 2 */
#define BBC_SPG_CPU3 0x08 /* Assert POR for processor 3 */
#define BBC_SPG_CPUALL 0x10 /* Reset all processors and reset
* the entire system.
*/
#define BBC_SPG_RESV 0xe0 /* Reserved */
/* Soft_XIR_GEN register. The XIR (eXternally Initiated Reset) signal
* may be asserted to specific processors via this register.
*/
#define BBC_SXG_CPU0 0x01 /* Assert XIR for processor 0 */
#define BBC_SXG_CPU1 0x02 /* Assert XIR for processor 1 */
#define BBC_SXG_CPU2 0x04 /* Assert XIR for processor 2 */
#define BBC_SXG_CPU3 0x08 /* Assert XIR for processor 3 */
#define BBC_SXG_RESV 0xf0 /* Reserved */
/* POR Source register. One may identify the cause of the most recent
* reset by reading this register.
*/
#define BBC_PSRC_SPG0 0x0001 /* CPU 0 reset via BBC_SPG register */
#define BBC_PSRC_SPG1 0x0002 /* CPU 1 reset via BBC_SPG register */
#define BBC_PSRC_SPG2 0x0004 /* CPU 2 reset via BBC_SPG register */
#define BBC_PSRC_SPG3 0x0008 /* CPU 3 reset via BBC_SPG register */
#define BBC_PSRC_SPGSYS 0x0010 /* System reset via BBC_SPG register */
#define BBC_PSRC_JTAG 0x0020 /* System reset via JTAG+ */
#define BBC_PSRC_BUTTON 0x0040 /* System reset via push-button dongle */
#define BBC_PSRC_PWRUP 0x0080 /* System reset via power-up */
#define BBC_PSRC_FE0 0x0100 /* CPU 0 reported Fatal_Error */
#define BBC_PSRC_FE1 0x0200 /* CPU 1 reported Fatal_Error */
#define BBC_PSRC_FE2 0x0400 /* CPU 2 reported Fatal_Error */
#define BBC_PSRC_FE3 0x0800 /* CPU 3 reported Fatal_Error */
#define BBC_PSRC_FE4 0x1000 /* Schizo reported Fatal_Error */
#define BBC_PSRC_FE5 0x2000 /* Safari device 5 reported Fatal_Error */
#define BBC_PSRC_FE6 0x4000 /* CPMS reported Fatal_Error */
#define BBC_PSRC_SYNTH 0x8000 /* System reset when on-board clock synthesizers
* were updated.
*/
#define BBC_PSRC_WDT 0x10000 /* System reset via Super I/O watchdog */
#define BBC_PSRC_RSC 0x20000 /* System reset via RSC remote monitoring
* device
*/
/* XIR Source register. The source of an XIR event sent to a processor may
* be determined via this register.
*/
#define BBC_XSRC_SXG0 0x01 /* CPU 0 received XIR via Soft_XIR_GEN reg */
#define BBC_XSRC_SXG1 0x02 /* CPU 1 received XIR via Soft_XIR_GEN reg */
#define BBC_XSRC_SXG2 0x04 /* CPU 2 received XIR via Soft_XIR_GEN reg */
#define BBC_XSRC_SXG3 0x08 /* CPU 3 received XIR via Soft_XIR_GEN reg */
#define BBC_XSRC_JTAG 0x10 /* All CPUs received XIR via JTAG+ */
#define BBC_XSRC_W_OR_B 0x20 /* All CPUs received XIR either because:
* a) Super I/O watchdog fired, or
* b) XIR push button was activated
*/
#define BBC_XSRC_RESV 0xc0 /* Reserved */
/* Clock Synthesizers Control register. This register provides the big-bang
* programming interface to the two clock synthesizers of the machine.
*/
#define BBC_CSC_SLOAD 0x01 /* Directly connected to S_LOAD pins */
#define BBC_CSC_SDATA 0x02 /* Directly connected to S_DATA pins */
#define BBC_CSC_SCLOCK 0x04 /* Directly connected to S_CLOCK pins */
#define BBC_CSC_RESV 0x78 /* Reserved */
#define BBC_CSC_RST 0x80 /* Generate system reset when S_LOAD==1 */
/* Energy Star Control register. This register is used to generate the
* clock frequency change trigger to the main system devices (Schizo and
* the processors). The transition occurs when bits in this register
* go from 0 to 1, only one bit must be set at once else no action
* occurs. Basically the sequence of events is:
* a) Choose new frequency: full, 1/2 or 1/32
* b) Program this desired frequency into the cpus and Schizo.
* c) Set the same value in this register.
* d) 16 system clocks later, clear this register.
*/
#define BBC_ES_CTRL_1_1 0x01 /* Full frequency */
#define BBC_ES_CTRL_1_2 0x02 /* 1/2 frequency */
#define BBC_ES_CTRL_1_32 0x20 /* 1/32 frequency */
#define BBC_ES_RESV 0xdc /* Reserved */
/* Energy Star Assert Change Time register. This determines the number
* of BBC clock cycles (which is half the system frequency) between
* the detection of FREEZE_ACK being asserted and the assertion of
* the CLK_CHANGE_L[2:0] signals.
*/
#define BBC_ES_ACT_VAL 0xff
/* Energy Star Assert Bypass Time register. This determines the number
* of BBC clock cycles (which is half the system frequency) between
* the assertion of the CLK_CHANGE_L[2:0] signals and the assertion of
* the ESTAR_PLL_BYPASS signal.
*/
#define BBC_ES_ABT_VAL 0xffff
/* Energy Star PLL Settle Time register. This determines the number of
* BBC clock cycles (which is half the system frequency) between the
* de-assertion of CLK_CHANGE_L[2:0] and the de-assertion of the FREEZE_L
* signal.
*/
#define BBC_ES_PST_VAL 0xffffffff
/* Energy Star Frequency Switch Latency register. This is the number of
* BBC clocks between the de-assertion of CLK_CHANGE_L[2:0] and the first
* edge of the Safari clock at the new frequency.
*/
#define BBC_ES_FSL_VAL 0xffffffff
/* Keyboard Beep control register. This is a simple enabler for the audio
* beep sound.
*/
#define BBC_KBD_BEEP_ENABLE 0x01 /* Enable beep */
#define BBC_KBD_BEEP_RESV 0xfe /* Reserved */
/* Keyboard Beep Counter register. There is a free-running counter inside
* the BBC which runs at half the system clock. The bit set in this register
* determines when the audio sound is generated. So for example if bit
* 10 is set, the audio beep will oscillate at 1/(2**12). The keyboard beep
* generator automatically selects a different bit to use if the system clock
* is changed via Energy Star.
*/
#define BBC_KBD_BCNT_BITS 0x0007fc00
#define BBC_KBC_BCNT_RESV 0xfff803ff
#endif /* _SPARC64_BBC_H */
#include <asm-sparc/bbc.h>
#ifndef _SPARC64_CHAFSR_H
#define _SPARC64_CHAFSR_H
/* Cheetah Asynchronous Fault Status register, ASI=0x4C VA<63:0>=0x0 */
/* Comments indicate which processor variants on which the bit definition
* is valid. Codes are:
* ch --> cheetah
* ch+ --> cheetah plus
* jp --> jalapeno
*/
/* All bits of this register except M_SYNDROME and E_SYNDROME are
* read, write 1 to clear. M_SYNDROME and E_SYNDROME are read-only.
*/
/* Software bit set by linux trap handlers to indicate that the trap was
* signalled at %tl >= 1.
*/
#define CHAFSR_TL1 (1UL << 63UL) /* n/a */
/* Unmapped error from system bus for prefetch queue or
* store queue read operation
*/
#define CHPAFSR_DTO (1UL << 59UL) /* ch+ */
/* Bus error from system bus for prefetch queue or store queue
* read operation
*/
#define CHPAFSR_DBERR (1UL << 58UL) /* ch+ */
/* Hardware corrected E-cache Tag ECC error */
#define CHPAFSR_THCE (1UL << 57UL) /* ch+ */
/* System interface protocol error, hw timeout caused */
#define JPAFSR_JETO (1UL << 57UL) /* jp */
/* SW handled correctable E-cache Tag ECC error */
#define CHPAFSR_TSCE (1UL << 56UL) /* ch+ */
/* Parity error on system snoop results */
#define JPAFSR_SCE (1UL << 56UL) /* jp */
/* Uncorrectable E-cache Tag ECC error */
#define CHPAFSR_TUE (1UL << 55UL) /* ch+ */
/* System interface protocol error, illegal command detected */
#define JPAFSR_JEIC (1UL << 55UL) /* jp */
/* Uncorrectable system bus data ECC error due to prefetch
* or store fill request
*/
#define CHPAFSR_DUE (1UL << 54UL) /* ch+ */
/* System interface protocol error, illegal ADTYPE detected */
#define JPAFSR_JEIT (1UL << 54UL) /* jp */
/* Multiple errors of the same type have occurred. This bit is set when
* an uncorrectable error or a SW correctable error occurs and the status
* bit to report that error is already set. When multiple errors of
* different types are indicated by setting multiple status bits.
*
* This bit is not set if multiple HW corrected errors with the same
* status bit occur, only uncorrectable and SW correctable ones have
* this behavior.
*
* This bit is not set when multiple ECC errors happen within a single
* 64-byte system bus transaction. Only the first ECC error in a 16-byte
* subunit will be logged. All errors in subsequent 16-byte subunits
* from the same 64-byte transaction are ignored.
*/
#define CHAFSR_ME (1UL << 53UL) /* ch,ch+,jp */
/* Privileged state error has occurred. This is a capture of PSTATE.PRIV
* at the time the error is detected.
*/
#define CHAFSR_PRIV (1UL << 52UL) /* ch,ch+,jp */
/* The following bits 51 (CHAFSR_PERR) to 33 (CHAFSR_CE) are sticky error
* bits and record the most recently detected errors. Bits accumulate
* errors that have been detected since the last write to clear the bit.
*/
/* System interface protocol error. The processor asserts its' ERROR
* pin when this event occurs and it also logs a specific cause code
* into a JTAG scannable flop.
*/
#define CHAFSR_PERR (1UL << 51UL) /* ch,ch+,jp */
/* Internal processor error. The processor asserts its' ERROR
* pin when this event occurs and it also logs a specific cause code
* into a JTAG scannable flop.
*/
#define CHAFSR_IERR (1UL << 50UL) /* ch,ch+,jp */
/* System request parity error on incoming address */
#define CHAFSR_ISAP (1UL << 49UL) /* ch,ch+,jp */
/* HW Corrected system bus MTAG ECC error */
#define CHAFSR_EMC (1UL << 48UL) /* ch,ch+ */
/* Parity error on L2 cache tag SRAM */
#define JPAFSR_ETP (1UL << 48UL) /* jp */
/* Uncorrectable system bus MTAG ECC error */
#define CHAFSR_EMU (1UL << 47UL) /* ch,ch+ */
/* Out of range memory error has occurred */
#define JPAFSR_OM (1UL << 47UL) /* jp */
/* HW Corrected system bus data ECC error for read of interrupt vector */
#define CHAFSR_IVC (1UL << 46UL) /* ch,ch+ */
/* Error due to unsupported store */
#define JPAFSR_UMS (1UL << 46UL) /* jp */
/* Uncorrectable system bus data ECC error for read of interrupt vector */
#define CHAFSR_IVU (1UL << 45UL) /* ch,ch+,jp */
/* Unmapped error from system bus */
#define CHAFSR_TO (1UL << 44UL) /* ch,ch+,jp */
/* Bus error response from system bus */
#define CHAFSR_BERR (1UL << 43UL) /* ch,ch+,jp */
/* SW Correctable E-cache ECC error for instruction fetch or data access
* other than block load.
*/
#define CHAFSR_UCC (1UL << 42UL) /* ch,ch+,jp */
/* Uncorrectable E-cache ECC error for instruction fetch or data access
* other than block load.
*/
#define CHAFSR_UCU (1UL << 41UL) /* ch,ch+,jp */
/* Copyout HW Corrected ECC error */
#define CHAFSR_CPC (1UL << 40UL) /* ch,ch+,jp */
/* Copyout Uncorrectable ECC error */
#define CHAFSR_CPU (1UL << 39UL) /* ch,ch+,jp */
/* HW Corrected ECC error from E-cache for writeback */
#define CHAFSR_WDC (1UL << 38UL) /* ch,ch+,jp */
/* Uncorrectable ECC error from E-cache for writeback */
#define CHAFSR_WDU (1UL << 37UL) /* ch,ch+,jp */
/* HW Corrected ECC error from E-cache for store merge or block load */
#define CHAFSR_EDC (1UL << 36UL) /* ch,ch+,jp */
/* Uncorrectable ECC error from E-cache for store merge or block load */
#define CHAFSR_EDU (1UL << 35UL) /* ch,ch+,jp */
/* Uncorrectable system bus data ECC error for read of memory or I/O */
#define CHAFSR_UE (1UL << 34UL) /* ch,ch+,jp */
/* HW Corrected system bus data ECC error for read of memory or I/O */
#define CHAFSR_CE (1UL << 33UL) /* ch,ch+,jp */
/* Uncorrectable ECC error from remote cache/memory */
#define JPAFSR_RUE (1UL << 32UL) /* jp */
/* Correctable ECC error from remote cache/memory */
#define JPAFSR_RCE (1UL << 31UL) /* jp */
/* JBUS parity error on returned read data */
#define JPAFSR_BP (1UL << 30UL) /* jp */
/* JBUS parity error on data for writeback or block store */
#define JPAFSR_WBP (1UL << 29UL) /* jp */
/* Foreign read to DRAM incurring correctable ECC error */
#define JPAFSR_FRC (1UL << 28UL) /* jp */
/* Foreign read to DRAM incurring uncorrectable ECC error */
#define JPAFSR_FRU (1UL << 27UL) /* jp */
#define CHAFSR_ERRORS (CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP | CHAFSR_EMC | \
CHAFSR_EMU | CHAFSR_IVC | CHAFSR_IVU | CHAFSR_TO | \
CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | CHAFSR_CPC | \
CHAFSR_CPU | CHAFSR_WDC | CHAFSR_WDU | CHAFSR_EDC | \
CHAFSR_EDU | CHAFSR_UE | CHAFSR_CE)
#define CHPAFSR_ERRORS (CHPAFSR_DTO | CHPAFSR_DBERR | CHPAFSR_THCE | \
CHPAFSR_TSCE | CHPAFSR_TUE | CHPAFSR_DUE | \
CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP | CHAFSR_EMC | \
CHAFSR_EMU | CHAFSR_IVC | CHAFSR_IVU | CHAFSR_TO | \
CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | CHAFSR_CPC | \
CHAFSR_CPU | CHAFSR_WDC | CHAFSR_WDU | CHAFSR_EDC | \
CHAFSR_EDU | CHAFSR_UE | CHAFSR_CE)
#define JPAFSR_ERRORS (JPAFSR_JETO | JPAFSR_SCE | JPAFSR_JEIC | \
JPAFSR_JEIT | CHAFSR_PERR | CHAFSR_IERR | \
CHAFSR_ISAP | JPAFSR_ETP | JPAFSR_OM | \
JPAFSR_UMS | CHAFSR_IVU | CHAFSR_TO | \
CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | \
CHAFSR_CPC | CHAFSR_CPU | CHAFSR_WDC | \
CHAFSR_WDU | CHAFSR_EDC | CHAFSR_EDU | \
CHAFSR_UE | CHAFSR_CE | JPAFSR_RUE | \
JPAFSR_RCE | JPAFSR_BP | JPAFSR_WBP | \
JPAFSR_FRC | JPAFSR_FRU)
/* Active JBUS request signal when error occurred */
#define JPAFSR_JBREQ (0x7UL << 24UL) /* jp */
#define JPAFSR_JBREQ_SHIFT 24UL
/* L2 cache way information */
#define JPAFSR_ETW (0x3UL << 22UL) /* jp */
#define JPAFSR_ETW_SHIFT 22UL
/* System bus MTAG ECC syndrome. This field captures the status of the
* first occurrence of the highest-priority error according to the M_SYND
* overwrite policy. After the AFSR sticky bit, corresponding to the error
* for which the M_SYND is reported, is cleared, the contents of the M_SYND
* field will be unchanged by will be unfrozen for further error capture.
*/
#define CHAFSR_M_SYNDROME (0xfUL << 16UL) /* ch,ch+,jp */
#define CHAFSR_M_SYNDROME_SHIFT 16UL
/* Agenid Id of the foreign device causing the UE/CE errors */
#define JPAFSR_AID (0x1fUL << 9UL) /* jp */
#define JPAFSR_AID_SHIFT 9UL
/* System bus or E-cache data ECC syndrome. This field captures the status
* of the first occurrence of the highest-priority error according to the
* E_SYND overwrite policy. After the AFSR sticky bit, corresponding to the
* error for which the E_SYND is reported, is cleare, the contents of the E_SYND
* field will be unchanged but will be unfrozen for further error capture.
*/
#define CHAFSR_E_SYNDROME (0x1ffUL << 0UL) /* ch,ch+,jp */
#define CHAFSR_E_SYNDROME_SHIFT 0UL
/* The AFSR must be explicitly cleared by software, it is not cleared automatically
* by a read. Writes to bits <51:33> with bits set will clear the corresponding
* bits in the AFSR. Bits associated with disrupting traps must be cleared before
* interrupts are re-enabled to prevent multiple traps for the same error. I.e.
* PSTATE.IE and AFSR bits control delivery of disrupting traps.
*
* Since there is only one AFAR, when multiple events have been logged by the
* bits in the AFSR, at most one of these events will have its status captured
* in the AFAR. The highest priority of those event bits will get AFAR logging.
* The AFAR will be unlocked and available to capture the address of another event
* as soon as the one bit in AFSR that corresponds to the event logged in AFAR is
* cleared. For example, if AFSR.CE is detected, then AFSR.UE (which overwrites
* the AFAR), and AFSR.UE is cleared by not AFSR.CE, then the AFAR will be unlocked
* and ready for another event, even though AFSR.CE is still set. The same rules
* also apply to the M_SYNDROME and E_SYNDROME fields of the AFSR.
*/
#endif /* _SPARC64_CHAFSR_H */
#include <asm-sparc/chafsr.h>
#ifndef _SPARC64_CHMCTRL_H
#define _SPARC64_CHMCTRL_H
/* Cheetah memory controller programmable registers. */
#define CHMCTRL_TCTRL1 0x00 /* Memory Timing Control I */
#define CHMCTRL_TCTRL2 0x08 /* Memory Timing Control II */
#define CHMCTRL_TCTRL3 0x38 /* Memory Timing Control III */
#define CHMCTRL_TCTRL4 0x40 /* Memory Timing Control IV */
#define CHMCTRL_DECODE1 0x10 /* Memory Address Decode I */
#define CHMCTRL_DECODE2 0x18 /* Memory Address Decode II */
#define CHMCTRL_DECODE3 0x20 /* Memory Address Decode III */
#define CHMCTRL_DECODE4 0x28 /* Memory Address Decode IV */
#define CHMCTRL_MACTRL 0x30 /* Memory Address Control */
/* Memory Timing Control I */
#define TCTRL1_SDRAMCTL_DLY 0xf000000000000000UL
#define TCTRL1_SDRAMCTL_DLY_SHIFT 60
#define TCTRL1_SDRAMCLK_DLY 0x0e00000000000000UL
#define TCTRL1_SDRAMCLK_DLY_SHIFT 57
#define TCTRL1_R 0x0100000000000000UL
#define TCTRL1_R_SHIFT 56
#define TCTRL1_AUTORFR_CYCLE 0x00fe000000000000UL
#define TCTRL1_AUTORFR_CYCLE_SHIFT 49
#define TCTRL1_RD_WAIT 0x0001f00000000000UL
#define TCTRL1_RD_WAIT_SHIFT 44
#define TCTRL1_PC_CYCLE 0x00000fc000000000UL
#define TCTRL1_PC_CYCLE_SHIFT 38
#define TCTRL1_WR_MORE_RAS_PW 0x0000003f00000000UL
#define TCTRL1_WR_MORE_RAS_PW_SHIFT 32
#define TCTRL1_RD_MORE_RAW_PW 0x00000000fc000000UL
#define TCTRL1_RD_MORE_RAS_PW_SHIFT 26
#define TCTRL1_ACT_WR_DLY 0x0000000003f00000UL
#define TCTRL1_ACT_WR_DLY_SHIFT 20
#define TCTRL1_ACT_RD_DLY 0x00000000000fc000UL
#define TCTRL1_ACT_RD_DLY_SHIFT 14
#define TCTRL1_BANK_PRESENT 0x0000000000003000UL
#define TCTRL1_BANK_PRESENT_SHIFT 12
#define TCTRL1_RFR_INT 0x0000000000000ff8UL
#define TCTRL1_RFR_INT_SHIFT 3
#define TCTRL1_SET_MODE_REG 0x0000000000000004UL
#define TCTRL1_SET_MODE_REG_SHIFT 2
#define TCTRL1_RFR_ENABLE 0x0000000000000002UL
#define TCTRL1_RFR_ENABLE_SHIFT 1
#define TCTRL1_PRECHG_ALL 0x0000000000000001UL
#define TCTRL1_PRECHG_ALL_SHIFT 0
/* Memory Timing Control II */
#define TCTRL2_WR_MSEL_DLY 0xfc00000000000000UL
#define TCTRL2_WR_MSEL_DLY_SHIFT 58
#define TCTRL2_RD_MSEL_DLY 0x03f0000000000000UL
#define TCTRL2_RD_MSEL_DLY_SHIFT 52
#define TCTRL2_WRDATA_THLD 0x000c000000000000UL
#define TCTRL2_WRDATA_THLD_SHIFT 50
#define TCTRL2_RDWR_RD_TI_DLY 0x0003f00000000000UL
#define TCTRL2_RDWR_RD_TI_DLY_SHIFT 44
#define TCTRL2_AUTOPRECHG_ENBL 0x0000080000000000UL
#define TCTRL2_AUTOPRECHG_ENBL_SHIFT 43
#define TCTRL2_RDWR_PI_MORE_DLY 0x000007c000000000UL
#define TCTRL2_RDWR_PI_MORE_DLY_SHIFT 38
#define TCTRL2_RDWR_1_DLY 0x0000003f00000000UL
#define TCTRL2_RDWR_1_DLY_SHIFT 32
#define TCTRL2_WRWR_PI_MORE_DLY 0x00000000f8000000UL
#define TCTRL2_WRWR_PI_MORE_DLY_SHIFT 27
#define TCTRL2_WRWR_1_DLY 0x0000000007e00000UL
#define TCTRL2_WRWR_1_DLY_SHIFT 21
#define TCTRL2_RDWR_RD_PI_MORE_DLY 0x00000000001f0000UL
#define TCTRL2_RDWR_RD_PI_MORE_DLY_SHIFT 16
#define TCTRL2_R 0x0000000000008000UL
#define TCTRL2_R_SHIFT 15
#define TCTRL2_SDRAM_MODE_REG_DATA 0x0000000000007fffUL
#define TCTRL2_SDRAM_MODE_REG_DATA_SHIFT 0
/* Memory Timing Control III */
#define TCTRL3_SDRAM_CTL_DLY 0xf000000000000000UL
#define TCTRL3_SDRAM_CTL_DLY_SHIFT 60
#define TCTRL3_SDRAM_CLK_DLY 0x0e00000000000000UL
#define TCTRL3_SDRAM_CLK_DLY_SHIFT 57
#define TCTRL3_R 0x0100000000000000UL
#define TCTRL3_R_SHIFT 56
#define TCTRL3_AUTO_RFR_CYCLE 0x00fe000000000000UL
#define TCTRL3_AUTO_RFR_CYCLE_SHIFT 49
#define TCTRL3_RD_WAIT 0x0001f00000000000UL
#define TCTRL3_RD_WAIT_SHIFT 44
#define TCTRL3_PC_CYCLE 0x00000fc000000000UL
#define TCTRL3_PC_CYCLE_SHIFT 38
#define TCTRL3_WR_MORE_RAW_PW 0x0000003f00000000UL
#define TCTRL3_WR_MORE_RAW_PW_SHIFT 32
#define TCTRL3_RD_MORE_RAW_PW 0x00000000fc000000UL
#define TCTRL3_RD_MORE_RAW_PW_SHIFT 26
#define TCTRL3_ACT_WR_DLY 0x0000000003f00000UL
#define TCTRL3_ACT_WR_DLY_SHIFT 20
#define TCTRL3_ACT_RD_DLY 0x00000000000fc000UL
#define TCTRL3_ACT_RD_DLY_SHIFT 14
#define TCTRL3_BANK_PRESENT 0x0000000000003000UL
#define TCTRL3_BANK_PRESENT_SHIFT 12
#define TCTRL3_RFR_INT 0x0000000000000ff8UL
#define TCTRL3_RFR_INT_SHIFT 3
#define TCTRL3_SET_MODE_REG 0x0000000000000004UL
#define TCTRL3_SET_MODE_REG_SHIFT 2
#define TCTRL3_RFR_ENABLE 0x0000000000000002UL
#define TCTRL3_RFR_ENABLE_SHIFT 1
#define TCTRL3_PRECHG_ALL 0x0000000000000001UL
#define TCTRL3_PRECHG_ALL_SHIFT 0
/* Memory Timing Control IV */
#define TCTRL4_WR_MSEL_DLY 0xfc00000000000000UL
#define TCTRL4_WR_MSEL_DLY_SHIFT 58
#define TCTRL4_RD_MSEL_DLY 0x03f0000000000000UL
#define TCTRL4_RD_MSEL_DLY_SHIFT 52
#define TCTRL4_WRDATA_THLD 0x000c000000000000UL
#define TCTRL4_WRDATA_THLD_SHIFT 50
#define TCTRL4_RDWR_RD_RI_DLY 0x0003f00000000000UL
#define TCTRL4_RDWR_RD_RI_DLY_SHIFT 44
#define TCTRL4_AUTO_PRECHG_ENBL 0x0000080000000000UL
#define TCTRL4_AUTO_PRECHG_ENBL_SHIFT 43
#define TCTRL4_RD_WR_PI_MORE_DLY 0x000007c000000000UL
#define TCTRL4_RD_WR_PI_MORE_DLY_SHIFT 38
#define TCTRL4_RD_WR_TI_DLY 0x0000003f00000000UL
#define TCTRL4_RD_WR_TI_DLY_SHIFT 32
#define TCTRL4_WR_WR_PI_MORE_DLY 0x00000000f8000000UL
#define TCTRL4_WR_WR_PI_MORE_DLY_SHIFT 27
#define TCTRL4_WR_WR_TI_DLY 0x0000000007e00000UL
#define TCTRL4_WR_WR_TI_DLY_SHIFT 21
#define TCTRL4_RDWR_RD_PI_MORE_DLY 0x00000000001f000UL0
#define TCTRL4_RDWR_RD_PI_MORE_DLY_SHIFT 16
#define TCTRL4_R 0x0000000000008000UL
#define TCTRL4_R_SHIFT 15
#define TCTRL4_SDRAM_MODE_REG_DATA 0x0000000000007fffUL
#define TCTRL4_SDRAM_MODE_REG_DATA_SHIFT 0
/* All 4 memory address decoding registers have the
* same layout.
*/
#define MEM_DECODE_VALID 0x8000000000000000UL /* Valid */
#define MEM_DECODE_VALID_SHIFT 63
#define MEM_DECODE_UK 0x001ffe0000000000UL /* Upper mask */
#define MEM_DECODE_UK_SHIFT 41
#define MEM_DECODE_UM 0x0000001ffff00000UL /* Upper match */
#define MEM_DECODE_UM_SHIFT 20
#define MEM_DECODE_LK 0x000000000003c000UL /* Lower mask */
#define MEM_DECODE_LK_SHIFT 14
#define MEM_DECODE_LM 0x0000000000000f00UL /* Lower match */
#define MEM_DECODE_LM_SHIFT 8
#define PA_UPPER_BITS 0x000007fffc000000UL
#define PA_UPPER_BITS_SHIFT 26
#define PA_LOWER_BITS 0x00000000000003c0UL
#define PA_LOWER_BITS_SHIFT 6
#define MACTRL_R0 0x8000000000000000UL
#define MACTRL_R0_SHIFT 63
#define MACTRL_ADDR_LE_PW 0x7000000000000000UL
#define MACTRL_ADDR_LE_PW_SHIFT 60
#define MACTRL_CMD_PW 0x0f00000000000000UL
#define MACTRL_CMD_PW_SHIFT 56
#define MACTRL_HALF_MODE_WR_MSEL_DLY 0x00fc000000000000UL
#define MACTRL_HALF_MODE_WR_MSEL_DLY_SHIFT 50
#define MACTRL_HALF_MODE_RD_MSEL_DLY 0x0003f00000000000UL
#define MACTRL_HALF_MODE_RD_MSEL_DLY_SHIFT 44
#define MACTRL_HALF_MODE_SDRAM_CTL_DLY 0x00000f0000000000UL
#define MACTRL_HALF_MODE_SDRAM_CTL_DLY_SHIFT 40
#define MACTRL_HALF_MODE_SDRAM_CLK_DLY 0x000000e000000000UL
#define MACTRL_HALF_MODE_SDRAM_CLK_DLY_SHIFT 37
#define MACTRL_R1 0x0000001000000000UL
#define MACTRL_R1_SHIFT 36
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B3 0x0000000f00000000UL
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B3_SHIFT 32
#define MACTRL_ENC_INTLV_B3 0x00000000f8000000UL
#define MACTRL_ENC_INTLV_B3_SHIFT 27
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B2 0x0000000007800000UL
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B2_SHIFT 23
#define MACTRL_ENC_INTLV_B2 0x00000000007c0000UL
#define MACTRL_ENC_INTLV_B2_SHIFT 18
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B1 0x000000000003c000UL
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B1_SHIFT 14
#define MACTRL_ENC_INTLV_B1 0x0000000000003e00UL
#define MACTRL_ENC_INTLV_B1_SHIFT 9
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B0 0x00000000000001e0UL
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B0_SHIFT 5
#define MACTRL_ENC_INTLV_B0 0x000000000000001fUL
#define MACTRL_ENC_INTLV_B0_SHIFT 0
#endif /* _SPARC64_CHMCTRL_H */
#include <asm-sparc/chmctrl.h>
#ifndef _SPARC64_CMT_H
#define _SPARC64_CMT_H
/* cmt.h: Chip Multi-Threading register definitions
*
* Copyright (C) 2004 David S. Miller (davem@redhat.com)
*/
/* ASI_CORE_ID - private */
#define LP_ID 0x0000000000000010UL
#define LP_ID_MAX 0x00000000003f0000UL
#define LP_ID_ID 0x000000000000003fUL
/* ASI_INTR_ID - private */
#define LP_INTR_ID 0x0000000000000000UL
#define LP_INTR_ID_ID 0x00000000000003ffUL
/* ASI_CESR_ID - private */
#define CESR_ID 0x0000000000000040UL
#define CESR_ID_ID 0x00000000000000ffUL
/* ASI_CORE_AVAILABLE - shared */
#define LP_AVAIL 0x0000000000000000UL
#define LP_AVAIL_1 0x0000000000000002UL
#define LP_AVAIL_0 0x0000000000000001UL
/* ASI_CORE_ENABLE_STATUS - shared */
#define LP_ENAB_STAT 0x0000000000000010UL
#define LP_ENAB_STAT_1 0x0000000000000002UL
#define LP_ENAB_STAT_0 0x0000000000000001UL
/* ASI_CORE_ENABLE - shared */
#define LP_ENAB 0x0000000000000020UL
#define LP_ENAB_1 0x0000000000000002UL
#define LP_ENAB_0 0x0000000000000001UL
/* ASI_CORE_RUNNING - shared */
#define LP_RUNNING_RW 0x0000000000000050UL
#define LP_RUNNING_W1S 0x0000000000000060UL
#define LP_RUNNING_W1C 0x0000000000000068UL
#define LP_RUNNING_1 0x0000000000000002UL
#define LP_RUNNING_0 0x0000000000000001UL
/* ASI_CORE_RUNNING_STAT - shared */
#define LP_RUN_STAT 0x0000000000000058UL
#define LP_RUN_STAT_1 0x0000000000000002UL
#define LP_RUN_STAT_0 0x0000000000000001UL
/* ASI_XIR_STEERING - shared */
#define LP_XIR_STEER 0x0000000000000030UL
#define LP_XIR_STEER_1 0x0000000000000002UL
#define LP_XIR_STEER_0 0x0000000000000001UL
/* ASI_CMT_ERROR_STEERING - shared */
#define CMT_ER_STEER 0x0000000000000040UL
#define CMT_ER_STEER_1 0x0000000000000002UL
#define CMT_ER_STEER_0 0x0000000000000001UL
#endif /* _SPARC64_CMT_H */
#include <asm-sparc/cmt.h>
#ifndef _ASM_SPARC64_COMPAT_H
#define _ASM_SPARC64_COMPAT_H
/*
* Architecture specific compatibility types
*/
#include <linux/types.h>
#define COMPAT_USER_HZ 100
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
typedef s32 compat_time_t;
typedef s32 compat_clock_t;
typedef s32 compat_pid_t;
typedef u16 __compat_uid_t;
typedef u16 __compat_gid_t;
typedef u32 __compat_uid32_t;
typedef u32 __compat_gid32_t;
typedef u16 compat_mode_t;
typedef u32 compat_ino_t;
typedef u16 compat_dev_t;
typedef s32 compat_off_t;
typedef s64 compat_loff_t;
typedef s16 compat_nlink_t;
typedef u16 compat_ipc_pid_t;
typedef s32 compat_daddr_t;
typedef u32 compat_caddr_t;
typedef __kernel_fsid_t compat_fsid_t;
typedef s32 compat_key_t;
typedef s32 compat_timer_t;
typedef s32 compat_int_t;
typedef s32 compat_long_t;
typedef s64 compat_s64;
typedef u32 compat_uint_t;
typedef u32 compat_ulong_t;
typedef u64 compat_u64;
struct compat_timespec {
compat_time_t tv_sec;
s32 tv_nsec;
};
struct compat_timeval {
compat_time_t tv_sec;
s32 tv_usec;
};
struct compat_stat {
compat_dev_t st_dev;
compat_ino_t st_ino;
compat_mode_t st_mode;
compat_nlink_t st_nlink;
__compat_uid_t st_uid;
__compat_gid_t st_gid;
compat_dev_t st_rdev;
compat_off_t st_size;
compat_time_t st_atime;
compat_ulong_t st_atime_nsec;
compat_time_t st_mtime;
compat_ulong_t st_mtime_nsec;
compat_time_t st_ctime;
compat_ulong_t st_ctime_nsec;
compat_off_t st_blksize;
compat_off_t st_blocks;
u32 __unused4[2];
};
struct compat_stat64 {
unsigned long long st_dev;
unsigned long long st_ino;
unsigned int st_mode;
unsigned int st_nlink;
unsigned int st_uid;
unsigned int st_gid;
unsigned long long st_rdev;
unsigned char __pad3[8];
long long st_size;
unsigned int st_blksize;
unsigned char __pad4[8];
unsigned int st_blocks;
unsigned int st_atime;
unsigned int st_atime_nsec;
unsigned int st_mtime;
unsigned int st_mtime_nsec;
unsigned int st_ctime;
unsigned int st_ctime_nsec;
unsigned int __unused4;
unsigned int __unused5;
};
struct compat_flock {
short l_type;
short l_whence;
compat_off_t l_start;
compat_off_t l_len;
compat_pid_t l_pid;
short __unused;
};
#define F_GETLK64 12
#define F_SETLK64 13
#define F_SETLKW64 14
struct compat_flock64 {
short l_type;
short l_whence;
compat_loff_t l_start;
compat_loff_t l_len;
compat_pid_t l_pid;
short __unused;
};
struct compat_statfs {
int f_type;
int f_bsize;
int f_blocks;
int f_bfree;
int f_bavail;
int f_files;
int f_ffree;
compat_fsid_t f_fsid;
int f_namelen; /* SunOS ignores this field. */
int f_frsize;
int f_spare[5];
};
#define COMPAT_RLIM_INFINITY 0x7fffffff
typedef u32 compat_old_sigset_t;
#define _COMPAT_NSIG 64
#define _COMPAT_NSIG_BPW 32
typedef u32 compat_sigset_word;
#define COMPAT_OFF_T_MAX 0x7fffffff
#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
/*
* A pointer passed in from user mode. This should not
* be used for syscall parameters, just declare them
* as pointers because the syscall entry code will have
* appropriately converted them already.
*/
typedef u32 compat_uptr_t;
static inline void __user *compat_ptr(compat_uptr_t uptr)
{
return (void __user *)(unsigned long)uptr;
}
static inline compat_uptr_t ptr_to_compat(void __user *uptr)
{
return (u32)(unsigned long)uptr;
}
static inline void __user *compat_alloc_user_space(long len)
{
struct pt_regs *regs = current_thread_info()->kregs;
unsigned long usp = regs->u_regs[UREG_I6];
if (!(test_thread_flag(TIF_32BIT)))
usp += STACK_BIAS;
else
usp &= 0xffffffffUL;
usp -= len;
usp &= ~0x7UL;
return (void __user *) usp;
}
struct compat_ipc64_perm {
compat_key_t key;
__compat_uid32_t uid;
__compat_gid32_t gid;
__compat_uid32_t cuid;
__compat_gid32_t cgid;
unsigned short __pad1;
compat_mode_t mode;
unsigned short __pad2;
unsigned short seq;
unsigned long __unused1; /* yes they really are 64bit pads */
unsigned long __unused2;
};
struct compat_semid64_ds {
struct compat_ipc64_perm sem_perm;
unsigned int __pad1;
compat_time_t sem_otime;
unsigned int __pad2;
compat_time_t sem_ctime;
u32 sem_nsems;
u32 __unused1;
u32 __unused2;
};
struct compat_msqid64_ds {
struct compat_ipc64_perm msg_perm;
unsigned int __pad1;
compat_time_t msg_stime;
unsigned int __pad2;
compat_time_t msg_rtime;
unsigned int __pad3;
compat_time_t msg_ctime;
unsigned int msg_cbytes;
unsigned int msg_qnum;
unsigned int msg_qbytes;
compat_pid_t msg_lspid;
compat_pid_t msg_lrpid;
unsigned int __unused1;
unsigned int __unused2;
};
struct compat_shmid64_ds {
struct compat_ipc64_perm shm_perm;
unsigned int __pad1;
compat_time_t shm_atime;
unsigned int __pad2;
compat_time_t shm_dtime;
unsigned int __pad3;
compat_time_t shm_ctime;
compat_size_t shm_segsz;
compat_pid_t shm_cpid;
compat_pid_t shm_lpid;
unsigned int shm_nattch;
unsigned int __unused1;
unsigned int __unused2;
};
#endif /* _ASM_SPARC64_COMPAT_H */
#include <asm-sparc/compat.h>
#ifndef _COMPAT_SIGNAL_H
#define _COMPAT_SIGNAL_H
#include <linux/compat.h>
#include <asm/signal.h>
#ifdef CONFIG_COMPAT
struct __new_sigaction32 {
unsigned sa_handler;
unsigned int sa_flags;
unsigned sa_restorer; /* not used by Linux/SPARC yet */
compat_sigset_t sa_mask;
};
struct __old_sigaction32 {
unsigned sa_handler;
compat_old_sigset_t sa_mask;
unsigned int sa_flags;
unsigned sa_restorer; /* not used by Linux/SPARC yet */
};
typedef struct sigaltstack32 {
u32 ss_sp;
int ss_flags;
compat_size_t ss_size;
} stack_t32;
#endif
#endif /* !(_COMPAT_SIGNAL_H) */
#include <asm-sparc/compat_signal.h>
#ifndef _SPARC64_DCR_H
#define _SPARC64_DCR_H
/* UltraSparc-III/III+ Dispatch Control Register, ASR 0x12 */
#define DCR_DPE 0x0000000000001000 /* III+: D$ Parity Error Enable */
#define DCR_OBS 0x0000000000000fc0 /* Observability Bus Controls */
#define DCR_BPE 0x0000000000000020 /* Branch Predict Enable */
#define DCR_RPE 0x0000000000000010 /* Return Address Prediction Enable */
#define DCR_SI 0x0000000000000008 /* Single Instruction Disable */
#define DCR_IPE 0x0000000000000004 /* III+: I$ Parity Error Enable */
#define DCR_IFPOE 0x0000000000000002 /* IRQ FP Operation Enable */
#define DCR_MS 0x0000000000000001 /* Multi-Scalar dispatch */
#endif /* _SPARC64_DCR_H */
#include <asm-sparc/dcr.h>
#ifndef _SPARC64_DCU_H
#define _SPARC64_DCU_H
#include <linux/const.h>
/* UltraSparc-III Data Cache Unit Control Register */
#define DCU_CP _AC(0x0002000000000000,UL) /* Phys Cache Enable w/o mmu */
#define DCU_CV _AC(0x0001000000000000,UL) /* Virt Cache Enable w/o mmu */
#define DCU_ME _AC(0x0000800000000000,UL) /* NC-store Merging Enable */
#define DCU_RE _AC(0x0000400000000000,UL) /* RAW bypass Enable */
#define DCU_PE _AC(0x0000200000000000,UL) /* PCache Enable */
#define DCU_HPE _AC(0x0000100000000000,UL) /* HW prefetch Enable */
#define DCU_SPE _AC(0x0000080000000000,UL) /* SW prefetch Enable */
#define DCU_SL _AC(0x0000040000000000,UL) /* Secondary ld-steering Enab*/
#define DCU_WE _AC(0x0000020000000000,UL) /* WCache enable */
#define DCU_PM _AC(0x000001fe00000000,UL) /* PA Watchpoint Byte Mask */
#define DCU_VM _AC(0x00000001fe000000,UL) /* VA Watchpoint Byte Mask */
#define DCU_PR _AC(0x0000000001000000,UL) /* PA Watchpoint Read Enable */
#define DCU_PW _AC(0x0000000000800000,UL) /* PA Watchpoint Write Enable*/
#define DCU_VR _AC(0x0000000000400000,UL) /* VA Watchpoint Read Enable */
#define DCU_VW _AC(0x0000000000200000,UL) /* VA Watchpoint Write Enable*/
#define DCU_DM _AC(0x0000000000000008,UL) /* DMMU Enable */
#define DCU_IM _AC(0x0000000000000004,UL) /* IMMU Enable */
#define DCU_DC _AC(0x0000000000000002,UL) /* Data Cache Enable */
#define DCU_IC _AC(0x0000000000000001,UL) /* Instruction Cache Enable */
#endif /* _SPARC64_DCU_H */
#include <asm-sparc/dcu.h>
#ifndef _SPARC64_ESTATE_H
#define _SPARC64_ESTATE_H
/* UltraSPARC-III E-cache Error Enable */
#define ESTATE_ERROR_FMT 0x0000000000040000 /* Force MTAG ECC */
#define ESTATE_ERROR_FMESS 0x000000000003c000 /* Forced MTAG ECC val */
#define ESTATE_ERROR_FMD 0x0000000000002000 /* Force DATA ECC */
#define ESTATE_ERROR_FDECC 0x0000000000001ff0 /* Forced DATA ECC val */
#define ESTATE_ERROR_UCEEN 0x0000000000000008 /* See below */
#define ESTATE_ERROR_NCEEN 0x0000000000000002 /* See below */
#define ESTATE_ERROR_CEEN 0x0000000000000001 /* See below */
/* UCEEN enables the fast_ECC_error trap for: 1) software correctable E-cache
* errors 2) uncorrectable E-cache errors. Such events only occur on reads
* of the E-cache by the local processor for: 1) data loads 2) instruction
* fetches 3) atomic operations. Such events _cannot_ occur for: 1) merge
* 2) writeback 2) copyout. The AFSR bits associated with these traps are
* UCC and UCU.
*/
/* NCEEN enables instruction_access_error, data_access_error, and ECC_error traps
* for uncorrectable ECC errors and system errors.
*
* Uncorrectable system bus data error or MTAG ECC error, system bus TimeOUT,
* or system bus BusERR:
* 1) As the result of an instruction fetch, will generate instruction_access_error
* 2) As the result of a load etc. will generate data_access_error.
* 3) As the result of store merge completion, writeback, or copyout will
* generate a disrupting ECC_error trap.
* 4) As the result of such errors on instruction vector fetch can generate any
* of the 3 trap types.
*
* The AFSR bits associated with these traps are EMU, EDU, WDU, CPU, IVU, UE,
* BERR, and TO.
*/
/* CEEN enables the ECC_error trap for hardware corrected ECC errors. System bus
* reads resulting in a hardware corrected data or MTAG ECC error will generate an
* ECC_error disrupting trap with this bit enabled.
*
* This same trap will also be generated when a hardware corrected ECC error results
* during store merge, writeback, and copyout operations.
*/
/* In general, if the trap enable bits above are disabled the AFSR bits will still
* log the events even though the trap will not be generated by the processor.
*/
#endif /* _SPARC64_ESTATE_H */
#include <asm-sparc/estate.h>
/*
* fhc.h: Structures for central/fhc pseudo driver on Sunfire/Starfire/Wildfire.
*
* Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com)
*/
#ifndef _SPARC64_FHC_H
#define _SPARC64_FHC_H
#include <linux/timer.h>
#include <asm/oplib.h>
#include <asm/prom.h>
#include <asm/upa.h>
struct linux_fhc;
/* Clock board register offsets. */
#define CLOCK_CTRL 0x00UL /* Main control */
#define CLOCK_STAT1 0x10UL /* Status one */
#define CLOCK_STAT2 0x20UL /* Status two */
#define CLOCK_PWRSTAT 0x30UL /* Power status */
#define CLOCK_PWRPRES 0x40UL /* Power presence */
#define CLOCK_TEMP 0x50UL /* Temperature */
#define CLOCK_IRQDIAG 0x60UL /* IRQ diagnostics */
#define CLOCK_PWRSTAT2 0x70UL /* Power status two */
#define CLOCK_CTRL_LLED 0x04 /* Left LED, 0 == on */
#define CLOCK_CTRL_MLED 0x02 /* Mid LED, 1 == on */
#define CLOCK_CTRL_RLED 0x01 /* RIght LED, 1 == on */
struct linux_central {
struct linux_fhc *child;
unsigned long cfreg;
unsigned long clkregs;
unsigned long clkver;
int slots;
struct device_node *prom_node;
struct linux_prom_ranges central_ranges[PROMREG_MAX];
int num_central_ranges;
};
/* Firehose controller register offsets */
struct fhc_regs {
unsigned long pregs; /* FHC internal regs */
#define FHC_PREGS_ID 0x00UL /* FHC ID */
#define FHC_ID_VERS 0xf0000000 /* Version of this FHC */
#define FHC_ID_PARTID 0x0ffff000 /* Part ID code (0x0f9f == FHC) */
#define FHC_ID_MANUF 0x0000007e /* Manufacturer (0x3e == SUN's JEDEC)*/
#define FHC_ID_RESV 0x00000001 /* Read as one */
#define FHC_PREGS_RCS 0x10UL /* FHC Reset Control/Status Register */
#define FHC_RCS_POR 0x80000000 /* Last reset was a power cycle */
#define FHC_RCS_SPOR 0x40000000 /* Last reset was sw power on reset */
#define FHC_RCS_SXIR 0x20000000 /* Last reset was sw XIR reset */
#define FHC_RCS_BPOR 0x10000000 /* Last reset was due to POR button */
#define FHC_RCS_BXIR 0x08000000 /* Last reset was due to XIR button */
#define FHC_RCS_WEVENT 0x04000000 /* CPU reset was due to wakeup event */
#define FHC_RCS_CFATAL 0x02000000 /* Centerplane Fatal Error signalled */
#define FHC_RCS_FENAB 0x01000000 /* Fatal errors elicit system reset */
#define FHC_PREGS_CTRL 0x20UL /* FHC Control Register */
#define FHC_CONTROL_ICS 0x00100000 /* Ignore Centerplane Signals */
#define FHC_CONTROL_FRST 0x00080000 /* Fatal Error Reset Enable */
#define FHC_CONTROL_LFAT 0x00040000 /* AC/DC signalled a local error */
#define FHC_CONTROL_SLINE 0x00010000 /* Firmware Synchronization Line */
#define FHC_CONTROL_DCD 0x00008000 /* DC-->DC Converter Disable */
#define FHC_CONTROL_POFF 0x00004000 /* AC/DC Controller PLL Disable */
#define FHC_CONTROL_FOFF 0x00002000 /* FHC Controller PLL Disable */
#define FHC_CONTROL_AOFF 0x00001000 /* CPU A SRAM/SBD Low Power Mode */
#define FHC_CONTROL_BOFF 0x00000800 /* CPU B SRAM/SBD Low Power Mode */
#define FHC_CONTROL_PSOFF 0x00000400 /* Turns off this FHC's power supply */
#define FHC_CONTROL_IXIST 0x00000200 /* 0=FHC tells clock board it exists */
#define FHC_CONTROL_XMSTR 0x00000100 /* 1=Causes this FHC to be XIR master*/
#define FHC_CONTROL_LLED 0x00000040 /* 0=Left LED ON */
#define FHC_CONTROL_MLED 0x00000020 /* 1=Middle LED ON */
#define FHC_CONTROL_RLED 0x00000010 /* 1=Right LED */
#define FHC_CONTROL_BPINS 0x00000003 /* Spare Bidirectional Pins */
#define FHC_PREGS_BSR 0x30UL /* FHC Board Status Register */
#define FHC_BSR_DA64 0x00040000 /* Port A: 0=128bit 1=64bit data path */
#define FHC_BSR_DB64 0x00020000 /* Port B: 0=128bit 1=64bit data path */
#define FHC_BSR_BID 0x0001e000 /* Board ID */
#define FHC_BSR_SA 0x00001c00 /* Port A UPA Speed (from the pins) */
#define FHC_BSR_SB 0x00000380 /* Port B UPA Speed (from the pins) */
#define FHC_BSR_NDIAG 0x00000040 /* Not in Diag Mode */
#define FHC_BSR_NTBED 0x00000020 /* Not in TestBED Mode */
#define FHC_BSR_NIA 0x0000001c /* Jumper, bit 18 in PROM space */
#define FHC_BSR_SI 0x00000001 /* Spare input pin value */
#define FHC_PREGS_ECC 0x40UL /* FHC ECC Control Register (16 bits) */
#define FHC_PREGS_JCTRL 0xf0UL /* FHC JTAG Control Register */
#define FHC_JTAG_CTRL_MENAB 0x80000000 /* Indicates this is JTAG Master */
#define FHC_JTAG_CTRL_MNONE 0x40000000 /* Indicates no JTAG Master present */
#define FHC_PREGS_JCMD 0x100UL /* FHC JTAG Command Register */
unsigned long ireg; /* FHC IGN reg */
#define FHC_IREG_IGN 0x00UL /* This FHC's IGN */
unsigned long ffregs; /* FHC fanfail regs */
#define FHC_FFREGS_IMAP 0x00UL /* FHC Fanfail IMAP */
#define FHC_FFREGS_ICLR 0x10UL /* FHC Fanfail ICLR */
unsigned long sregs; /* FHC system regs */
#define FHC_SREGS_IMAP 0x00UL /* FHC System IMAP */
#define FHC_SREGS_ICLR 0x10UL /* FHC System ICLR */
unsigned long uregs; /* FHC uart regs */
#define FHC_UREGS_IMAP 0x00UL /* FHC Uart IMAP */
#define FHC_UREGS_ICLR 0x10UL /* FHC Uart ICLR */
unsigned long tregs; /* FHC TOD regs */
#define FHC_TREGS_IMAP 0x00UL /* FHC TOD IMAP */
#define FHC_TREGS_ICLR 0x10UL /* FHC TOD ICLR */
};
struct linux_fhc {
struct linux_fhc *next;
struct linux_central *parent; /* NULL if not central FHC */
struct fhc_regs fhc_regs;
int board;
int jtag_master;
struct device_node *prom_node;
struct linux_prom_ranges fhc_ranges[PROMREG_MAX];
int num_fhc_ranges;
};
#endif /* !(_SPARC64_FHC_H) */
#include <asm-sparc/fhc.h>
/* fpumacro.h: FPU related macros.
*
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
*/
#ifndef _SPARC64_FPUMACRO_H
#define _SPARC64_FPUMACRO_H
#include <asm/asi.h>
#include <asm/visasm.h>
struct fpustate {
u32 regs[64];
};
#define FPUSTATE (struct fpustate *)(current_thread_info()->fpregs)
static inline unsigned long fprs_read(void)
{
unsigned long retval;
__asm__ __volatile__("rd %%fprs, %0" : "=r" (retval));
return retval;
}
static inline void fprs_write(unsigned long val)
{
__asm__ __volatile__("wr %0, 0x0, %%fprs" : : "r" (val));
}
#endif /* !(_SPARC64_FPUMACRO_H) */
#include <asm-sparc/fpumacro.h>
#ifndef _ASM_SPARC64_HUGETLB_H
#define _ASM_SPARC64_HUGETLB_H
#include <asm/page.h>
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte);
pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep);
void hugetlb_prefault_arch_hook(struct mm_struct *mm);
static inline int is_hugepage_only_range(struct mm_struct *mm,
unsigned long addr,
unsigned long len) {
return 0;
}
/*
* If the arch doesn't supply something else, assume that hugepage
* size aligned regions are ok without further preparation.
*/
static inline int prepare_hugepage_range(unsigned long addr, unsigned long len)
{
if (len & ~HPAGE_MASK)
return -EINVAL;
if (addr & ~HPAGE_MASK)
return -EINVAL;
return 0;
}
static inline void hugetlb_free_pgd_range(struct mmu_gather **tlb,
unsigned long addr, unsigned long end,
unsigned long floor,
unsigned long ceiling)
{
free_pgd_range(tlb, addr, end, floor, ceiling);
}
static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep)
{
}
static inline int huge_pte_none(pte_t pte)
{
return pte_none(pte);
}
static inline pte_t huge_pte_wrprotect(pte_t pte)
{
return pte_wrprotect(pte);
}
static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
ptep_set_wrprotect(mm, addr, ptep);
}
static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep,
pte_t pte, int dirty)
{
return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
}
static inline pte_t huge_ptep_get(pte_t *ptep)
{
return *ptep;
}
static inline int arch_prepare_hugepage(struct page *page)
{
return 0;
}
static inline void arch_release_hugepage(struct page *page)
{
}
#endif /* _ASM_SPARC64_HUGETLB_H */
#include <asm-sparc/hugetlb.h>
#ifndef _SPARC64_HVTRAP_H
#define _SPARC64_HVTRAP_H
#ifndef __ASSEMBLY__
#include <linux/types.h>
struct hvtramp_mapping {
__u64 vaddr;
__u64 tte;
};
struct hvtramp_descr {
__u32 cpu;
__u32 num_mappings;
__u64 fault_info_va;
__u64 fault_info_pa;
__u64 thread_reg;
struct hvtramp_mapping maps[1];
};
extern void hv_cpu_startup(unsigned long hvdescr_pa);
#endif
#define HVTRAMP_DESCR_CPU 0x00
#define HVTRAMP_DESCR_NUM_MAPPINGS 0x04
#define HVTRAMP_DESCR_FAULT_INFO_VA 0x08
#define HVTRAMP_DESCR_FAULT_INFO_PA 0x10
#define HVTRAMP_DESCR_THREAD_REG 0x18
#define HVTRAMP_DESCR_MAPS 0x20
#define HVTRAMP_MAPPING_VADDR 0x00
#define HVTRAMP_MAPPING_TTE 0x08
#define HVTRAMP_MAPPING_SIZE 0x10
#endif /* _SPARC64_HVTRAP_H */
#include <asm-sparc/hvtramp.h>
#ifndef _SPARC64_HYPERVISOR_H
#define _SPARC64_HYPERVISOR_H
/* Sun4v hypervisor interfaces and defines.
*
* Hypervisor calls are made via traps to software traps number 0x80
* and above. Registers %o0 to %o5 serve as argument, status, and
* return value registers.
*
* There are two kinds of these traps. First there are the normal
* "fast traps" which use software trap 0x80 and encode the function
* to invoke by number in register %o5. Argument and return value
* handling is as follows:
*
* -----------------------------------------------
* | %o5 | function number | undefined |
* | %o0 | argument 0 | return status |
* | %o1 | argument 1 | return value 1 |
* | %o2 | argument 2 | return value 2 |
* | %o3 | argument 3 | return value 3 |
* | %o4 | argument 4 | return value 4 |
* -----------------------------------------------
*
* The second type are "hyper-fast traps" which encode the function
* number in the software trap number itself. So these use trap
* numbers > 0x80. The register usage for hyper-fast traps is as
* follows:
*
* -----------------------------------------------
* | %o0 | argument 0 | return status |
* | %o1 | argument 1 | return value 1 |
* | %o2 | argument 2 | return value 2 |
* | %o3 | argument 3 | return value 3 |
* | %o4 | argument 4 | return value 4 |
* -----------------------------------------------
*
* Registers providing explicit arguments to the hypervisor calls
* are volatile across the call. Upon return their values are
* undefined unless explicitly specified as containing a particular
* return value by the specific call. The return status is always
* returned in register %o0, zero indicates a successful execution of
* the hypervisor call and other values indicate an error status as
* defined below. So, for example, if a hyper-fast trap takes
* arguments 0, 1, and 2, then %o0, %o1, and %o2 are volatile across
* the call and %o3, %o4, and %o5 would be preserved.
*
* If the hypervisor trap is invalid, or the fast trap function number
* is invalid, HV_EBADTRAP will be returned in %o0. Also, all 64-bits
* of the argument and return values are significant.
*/
/* Trap numbers. */
#define HV_FAST_TRAP 0x80
#define HV_MMU_MAP_ADDR_TRAP 0x83
#define HV_MMU_UNMAP_ADDR_TRAP 0x84
#define HV_TTRACE_ADDENTRY_TRAP 0x85
#define HV_CORE_TRAP 0xff
/* Error codes. */
#define HV_EOK 0 /* Successful return */
#define HV_ENOCPU 1 /* Invalid CPU id */
#define HV_ENORADDR 2 /* Invalid real address */
#define HV_ENOINTR 3 /* Invalid interrupt id */
#define HV_EBADPGSZ 4 /* Invalid pagesize encoding */
#define HV_EBADTSB 5 /* Invalid TSB description */
#define HV_EINVAL 6 /* Invalid argument */
#define HV_EBADTRAP 7 /* Invalid function number */
#define HV_EBADALIGN 8 /* Invalid address alignment */
#define HV_EWOULDBLOCK 9 /* Cannot complete w/o blocking */
#define HV_ENOACCESS 10 /* No access to resource */
#define HV_EIO 11 /* I/O error */
#define HV_ECPUERROR 12 /* CPU in error state */
#define HV_ENOTSUPPORTED 13 /* Function not supported */
#define HV_ENOMAP 14 /* No mapping found */
#define HV_ETOOMANY 15 /* Too many items specified */
#define HV_ECHANNEL 16 /* Invalid LDC channel */
#define HV_EBUSY 17 /* Resource busy */
/* mach_exit()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MACH_EXIT
* ARG0: exit code
* ERRORS: This service does not return.
*
* Stop all CPUs in the virtual domain and place them into the stopped
* state. The 64-bit exit code may be passed to a service entity as
* the domain's exit status. On systems without a service entity, the
* domain will undergo a reset, and the boot firmware will be
* reloaded.
*
* This function will never return to the guest that invokes it.
*
* Note: By convention an exit code of zero denotes a successful exit by
* the guest code. A non-zero exit code denotes a guest specific
* error indication.
*
*/
#define HV_FAST_MACH_EXIT 0x00
#ifndef __ASSEMBLY__
extern void sun4v_mach_exit(unsigned long exit_code);
#endif
/* Domain services. */
/* mach_desc()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MACH_DESC
* ARG0: buffer
* ARG1: length
* RET0: status
* RET1: length
* ERRORS: HV_EBADALIGN Buffer is badly aligned
* HV_ENORADDR Buffer is to an illegal real address.
* HV_EINVAL Buffer length is too small for complete
* machine description.
*
* Copy the most current machine description into the buffer indicated
* by the real address in ARG0. The buffer provided must be 16 byte
* aligned. Upon success or HV_EINVAL, this service returns the
* actual size of the machine description in the RET1 return value.
*
* Note: A method of determining the appropriate buffer size for the
* machine description is to first call this service with a buffer
* length of 0 bytes.
*/
#define HV_FAST_MACH_DESC 0x01
#ifndef __ASSEMBLY__
extern unsigned long sun4v_mach_desc(unsigned long buffer_pa,
unsigned long buf_len,
unsigned long *real_buf_len);
#endif
/* mach_sir()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MACH_SIR
* ERRORS: This service does not return.
*
* Perform a software initiated reset of the virtual machine domain.
* All CPUs are captured as soon as possible, all hardware devices are
* returned to the entry default state, and the domain is restarted at
* the SIR (trap type 0x04) real trap table (RTBA) entry point on one
* of the CPUs. The single CPU restarted is selected as determined by
* platform specific policy. Memory is preserved across this
* operation.
*/
#define HV_FAST_MACH_SIR 0x02
#ifndef __ASSEMBLY__
extern void sun4v_mach_sir(void);
#endif
/* mach_set_watchdog()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MACH_SET_WATCHDOG
* ARG0: timeout in milliseconds
* RET0: status
* RET1: time remaining in milliseconds
*
* A guest uses this API to set a watchdog timer. Once the gues has set
* the timer, it must call the timer service again either to disable or
* postpone the expiration. If the timer expires before being reset or
* disabled, then the hypervisor take a platform specific action leading
* to guest termination within a bounded time period. The platform action
* may include recovery actions such as reporting the expiration to a
* Service Processor, and/or automatically restarting the gues.
*
* The 'timeout' parameter is specified in milliseconds, however the
* implementated granularity is given by the 'watchdog-resolution'
* property in the 'platform' node of the guest's machine description.
* The largest allowed timeout value is specified by the
* 'watchdog-max-timeout' property of the 'platform' node.
*
* If the 'timeout' argument is not zero, the watchdog timer is set to
* expire after a minimum of 'timeout' milliseconds.
*
* If the 'timeout' argument is zero, the watchdog timer is disabled.
*
* If the 'timeout' value exceeds the value of the 'max-watchdog-timeout'
* property, the hypervisor leaves the watchdog timer state unchanged,
* and returns a status of EINVAL.
*
* The 'time remaining' return value is valid regardless of whether the
* return status is EOK or EINVAL. A non-zero return value indicates the
* number of milliseconds that were remaining until the timer was to expire.
* If less than one millisecond remains, the return value is '1'. If the
* watchdog timer was disabled at the time of the call, the return value is
* zero.
*
* If the hypervisor cannot support the exact timeout value requested, but
* can support a larger timeout value, the hypervisor may round the actual
* timeout to a value larger than the requested timeout, consequently the
* 'time remaining' return value may be larger than the previously requested
* timeout value.
*
* Any guest OS debugger should be aware that the watchdog service may be in
* use. Consequently, it is recommended that the watchdog service is
* disabled upon debugger entry (e.g. reaching a breakpoint), and then
* re-enabled upon returning to normal execution. The API has been designed
* with this in mind, and the 'time remaining' result of the disable call may
* be used directly as the timeout argument of the re-enable call.
*/
#define HV_FAST_MACH_SET_WATCHDOG 0x05
#ifndef __ASSEMBLY__
extern unsigned long sun4v_mach_set_watchdog(unsigned long timeout,
unsigned long *orig_timeout);
#endif
/* CPU services.
*
* CPUs represent devices that can execute software threads. A single
* chip that contains multiple cores or strands is represented as
* multiple CPUs with unique CPU identifiers. CPUs are exported to
* OBP via the machine description (and to the OS via the OBP device
* tree). CPUs are always in one of three states: stopped, running,
* or error.
*
* A CPU ID is a pre-assigned 16-bit value that uniquely identifies a
* CPU within a logical domain. Operations that are to be performed
* on multiple CPUs specify them via a CPU list. A CPU list is an
* array in real memory, of which each 16-bit word is a CPU ID. CPU
* lists are passed through the API as two arguments. The first is
* the number of entries (16-bit words) in the CPU list, and the
* second is the (real address) pointer to the CPU ID list.
*/
/* cpu_start()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_START
* ARG0: CPU ID
* ARG1: PC
* ARG2: RTBA
* ARG3: target ARG0
* RET0: status
* ERRORS: ENOCPU Invalid CPU ID
* EINVAL Target CPU ID is not in the stopped state
* ENORADDR Invalid PC or RTBA real address
* EBADALIGN Unaligned PC or unaligned RTBA
* EWOULDBLOCK Starting resources are not available
*
* Start CPU with given CPU ID with PC in %pc and with a real trap
* base address value of RTBA. The indicated CPU must be in the
* stopped state. The supplied RTBA must be aligned on a 256 byte
* boundary. On successful completion, the specified CPU will be in
* the running state and will be supplied with "target ARG0" in %o0
* and RTBA in %tba.
*/
#define HV_FAST_CPU_START 0x10
#ifndef __ASSEMBLY__
extern unsigned long sun4v_cpu_start(unsigned long cpuid,
unsigned long pc,
unsigned long rtba,
unsigned long arg0);
#endif
/* cpu_stop()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_STOP
* ARG0: CPU ID
* RET0: status
* ERRORS: ENOCPU Invalid CPU ID
* EINVAL Target CPU ID is the current cpu
* EINVAL Target CPU ID is not in the running state
* EWOULDBLOCK Stopping resources are not available
* ENOTSUPPORTED Not supported on this platform
*
* The specified CPU is stopped. The indicated CPU must be in the
* running state. On completion, it will be in the stopped state. It
* is not legal to stop the current CPU.
*
* Note: As this service cannot be used to stop the current cpu, this service
* may not be used to stop the last running CPU in a domain. To stop
* and exit a running domain, a guest must use the mach_exit() service.
*/
#define HV_FAST_CPU_STOP 0x11
#ifndef __ASSEMBLY__
extern unsigned long sun4v_cpu_stop(unsigned long cpuid);
#endif
/* cpu_yield()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_YIELD
* RET0: status
* ERRORS: No possible error.
*
* Suspend execution on the current CPU. Execution will resume when
* an interrupt (device, %stick_compare, or cross-call) is targeted to
* the CPU. On some CPUs, this API may be used by the hypervisor to
* save power by disabling hardware strands.
*/
#define HV_FAST_CPU_YIELD 0x12
#ifndef __ASSEMBLY__
extern unsigned long sun4v_cpu_yield(void);
#endif
/* cpu_qconf()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_QCONF
* ARG0: queue
* ARG1: base real address
* ARG2: number of entries
* RET0: status
* ERRORS: ENORADDR Invalid base real address
* EINVAL Invalid queue or number of entries is less
* than 2 or too large.
* EBADALIGN Base real address is not correctly aligned
* for size.
*
* Configure the given queue to be placed at the given base real
* address, with the given number of entries. The number of entries
* must be a power of 2. The base real address must be aligned
* exactly to match the queue size. Each queue entry is 64 bytes
* long, so for example a 32 entry queue must be aligned on a 2048
* byte real address boundary.
*
* The specified queue is unconfigured if the number of entries is given
* as zero.
*
* For the current version of this API service, the argument queue is defined
* as follows:
*
* queue description
* ----- -------------------------
* 0x3c cpu mondo queue
* 0x3d device mondo queue
* 0x3e resumable error queue
* 0x3f non-resumable error queue
*
* Note: The maximum number of entries for each queue for a specific cpu may
* be determined from the machine description.
*/
#define HV_FAST_CPU_QCONF 0x14
#define HV_CPU_QUEUE_CPU_MONDO 0x3c
#define HV_CPU_QUEUE_DEVICE_MONDO 0x3d
#define HV_CPU_QUEUE_RES_ERROR 0x3e
#define HV_CPU_QUEUE_NONRES_ERROR 0x3f
#ifndef __ASSEMBLY__
extern unsigned long sun4v_cpu_qconf(unsigned long type,
unsigned long queue_paddr,
unsigned long num_queue_entries);
#endif
/* cpu_qinfo()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_QINFO
* ARG0: queue
* RET0: status
* RET1: base real address
* RET1: number of entries
* ERRORS: EINVAL Invalid queue
*
* Return the configuration info for the given queue. The base real
* address and number of entries of the defined queue are returned.
* The queue argument values are the same as for cpu_qconf() above.
*
* If the specified queue is a valid queue number, but no queue has
* been defined, the number of entries will be set to zero and the
* base real address returned is undefined.
*/
#define HV_FAST_CPU_QINFO 0x15
/* cpu_mondo_send()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_MONDO_SEND
* ARG0-1: CPU list
* ARG2: data real address
* RET0: status
* ERRORS: EBADALIGN Mondo data is not 64-byte aligned or CPU list
* is not 2-byte aligned.
* ENORADDR Invalid data mondo address, or invalid cpu list
* address.
* ENOCPU Invalid cpu in CPU list
* EWOULDBLOCK Some or all of the listed CPUs did not receive
* the mondo
* ECPUERROR One or more of the listed CPUs are in error
* state, use HV_FAST_CPU_STATE to see which ones
* EINVAL CPU list includes caller's CPU ID
*
* Send a mondo interrupt to the CPUs in the given CPU list with the
* 64-bytes at the given data real address. The data must be 64-byte
* aligned. The mondo data will be delivered to the cpu_mondo queues
* of the recipient CPUs.
*
* In all cases, error or not, the CPUs in the CPU list to which the
* mondo has been successfully delivered will be indicated by having
* their entry in CPU list updated with the value 0xffff.
*/
#define HV_FAST_CPU_MONDO_SEND 0x42
#ifndef __ASSEMBLY__
extern unsigned long sun4v_cpu_mondo_send(unsigned long cpu_count, unsigned long cpu_list_pa, unsigned long mondo_block_pa);
#endif
/* cpu_myid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_MYID
* RET0: status
* RET1: CPU ID
* ERRORS: No errors defined.
*
* Return the hypervisor ID handle for the current CPU. Use by a
* virtual CPU to discover it's own identity.
*/
#define HV_FAST_CPU_MYID 0x16
/* cpu_state()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_STATE
* ARG0: CPU ID
* RET0: status
* RET1: state
* ERRORS: ENOCPU Invalid CPU ID
*
* Retrieve the current state of the CPU with the given CPU ID.
*/
#define HV_FAST_CPU_STATE 0x17
#define HV_CPU_STATE_STOPPED 0x01
#define HV_CPU_STATE_RUNNING 0x02
#define HV_CPU_STATE_ERROR 0x03
#ifndef __ASSEMBLY__
extern long sun4v_cpu_state(unsigned long cpuid);
#endif
/* cpu_set_rtba()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_SET_RTBA
* ARG0: RTBA
* RET0: status
* RET1: previous RTBA
* ERRORS: ENORADDR Invalid RTBA real address
* EBADALIGN RTBA is incorrectly aligned for a trap table
*
* Set the real trap base address of the local cpu to the given RTBA.
* The supplied RTBA must be aligned on a 256 byte boundary. Upon
* success the previous value of the RTBA is returned in RET1.
*
* Note: This service does not affect %tba
*/
#define HV_FAST_CPU_SET_RTBA 0x18
/* cpu_set_rtba()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CPU_GET_RTBA
* RET0: status
* RET1: previous RTBA
* ERRORS: No possible error.
*
* Returns the current value of RTBA in RET1.
*/
#define HV_FAST_CPU_GET_RTBA 0x19
/* MMU services.
*
* Layout of a TSB description for mmu_tsb_ctx{,non}0() calls.
*/
#ifndef __ASSEMBLY__
struct hv_tsb_descr {
unsigned short pgsz_idx;
unsigned short assoc;
unsigned int num_ttes; /* in TTEs */
unsigned int ctx_idx;
unsigned int pgsz_mask;
unsigned long tsb_base;
unsigned long resv;
};
#endif
#define HV_TSB_DESCR_PGSZ_IDX_OFFSET 0x00
#define HV_TSB_DESCR_ASSOC_OFFSET 0x02
#define HV_TSB_DESCR_NUM_TTES_OFFSET 0x04
#define HV_TSB_DESCR_CTX_IDX_OFFSET 0x08
#define HV_TSB_DESCR_PGSZ_MASK_OFFSET 0x0c
#define HV_TSB_DESCR_TSB_BASE_OFFSET 0x10
#define HV_TSB_DESCR_RESV_OFFSET 0x18
/* Page size bitmask. */
#define HV_PGSZ_MASK_8K (1 << 0)
#define HV_PGSZ_MASK_64K (1 << 1)
#define HV_PGSZ_MASK_512K (1 << 2)
#define HV_PGSZ_MASK_4MB (1 << 3)
#define HV_PGSZ_MASK_32MB (1 << 4)
#define HV_PGSZ_MASK_256MB (1 << 5)
#define HV_PGSZ_MASK_2GB (1 << 6)
#define HV_PGSZ_MASK_16GB (1 << 7)
/* Page size index. The value given in the TSB descriptor must correspond
* to the smallest page size specified in the pgsz_mask page size bitmask.
*/
#define HV_PGSZ_IDX_8K 0
#define HV_PGSZ_IDX_64K 1
#define HV_PGSZ_IDX_512K 2
#define HV_PGSZ_IDX_4MB 3
#define HV_PGSZ_IDX_32MB 4
#define HV_PGSZ_IDX_256MB 5
#define HV_PGSZ_IDX_2GB 6
#define HV_PGSZ_IDX_16GB 7
/* MMU fault status area.
*
* MMU related faults have their status and fault address information
* placed into a memory region made available by privileged code. Each
* virtual processor must make a mmu_fault_area_conf() call to tell the
* hypervisor where that processor's fault status should be stored.
*
* The fault status block is a multiple of 64-bytes and must be aligned
* on a 64-byte boundary.
*/
#ifndef __ASSEMBLY__
struct hv_fault_status {
unsigned long i_fault_type;
unsigned long i_fault_addr;
unsigned long i_fault_ctx;
unsigned long i_reserved[5];
unsigned long d_fault_type;
unsigned long d_fault_addr;
unsigned long d_fault_ctx;
unsigned long d_reserved[5];
};
#endif
#define HV_FAULT_I_TYPE_OFFSET 0x00
#define HV_FAULT_I_ADDR_OFFSET 0x08
#define HV_FAULT_I_CTX_OFFSET 0x10
#define HV_FAULT_D_TYPE_OFFSET 0x40
#define HV_FAULT_D_ADDR_OFFSET 0x48
#define HV_FAULT_D_CTX_OFFSET 0x50
#define HV_FAULT_TYPE_FAST_MISS 1
#define HV_FAULT_TYPE_FAST_PROT 2
#define HV_FAULT_TYPE_MMU_MISS 3
#define HV_FAULT_TYPE_INV_RA 4
#define HV_FAULT_TYPE_PRIV_VIOL 5
#define HV_FAULT_TYPE_PROT_VIOL 6
#define HV_FAULT_TYPE_NFO 7
#define HV_FAULT_TYPE_NFO_SEFF 8
#define HV_FAULT_TYPE_INV_VA 9
#define HV_FAULT_TYPE_INV_ASI 10
#define HV_FAULT_TYPE_NC_ATOMIC 11
#define HV_FAULT_TYPE_PRIV_ACT 12
#define HV_FAULT_TYPE_RESV1 13
#define HV_FAULT_TYPE_UNALIGNED 14
#define HV_FAULT_TYPE_INV_PGSZ 15
/* Values 16 --> -2 are reserved. */
#define HV_FAULT_TYPE_MULTIPLE -1
/* Flags argument for mmu_{map,unmap}_addr(), mmu_demap_{page,context,all}(),
* and mmu_{map,unmap}_perm_addr().
*/
#define HV_MMU_DMMU 0x01
#define HV_MMU_IMMU 0x02
#define HV_MMU_ALL (HV_MMU_DMMU | HV_MMU_IMMU)
/* mmu_map_addr()
* TRAP: HV_MMU_MAP_ADDR_TRAP
* ARG0: virtual address
* ARG1: mmu context
* ARG2: TTE
* ARG3: flags (HV_MMU_{IMMU,DMMU})
* ERRORS: EINVAL Invalid virtual address, mmu context, or flags
* EBADPGSZ Invalid page size value
* ENORADDR Invalid real address in TTE
*
* Create a non-permanent mapping using the given TTE, virtual
* address, and mmu context. The flags argument determines which
* (data, or instruction, or both) TLB the mapping gets loaded into.
*
* The behavior is undefined if the valid bit is clear in the TTE.
*
* Note: This API call is for privileged code to specify temporary translation
* mappings without the need to create and manage a TSB.
*/
/* mmu_unmap_addr()
* TRAP: HV_MMU_UNMAP_ADDR_TRAP
* ARG0: virtual address
* ARG1: mmu context
* ARG2: flags (HV_MMU_{IMMU,DMMU})
* ERRORS: EINVAL Invalid virtual address, mmu context, or flags
*
* Demaps the given virtual address in the given mmu context on this
* CPU. This function is intended to be used to demap pages mapped
* with mmu_map_addr. This service is equivalent to invoking
* mmu_demap_page() with only the current CPU in the CPU list. The
* flags argument determines which (data, or instruction, or both) TLB
* the mapping gets unmapped from.
*
* Attempting to perform an unmap operation for a previously defined
* permanent mapping will have undefined results.
*/
/* mmu_tsb_ctx0()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_TSB_CTX0
* ARG0: number of TSB descriptions
* ARG1: TSB descriptions pointer
* RET0: status
* ERRORS: ENORADDR Invalid TSB descriptions pointer or
* TSB base within a descriptor
* EBADALIGN TSB descriptions pointer is not aligned
* to an 8-byte boundary, or TSB base
* within a descriptor is not aligned for
* the given TSB size
* EBADPGSZ Invalid page size in a TSB descriptor
* EBADTSB Invalid associativity or size in a TSB
* descriptor
* EINVAL Invalid number of TSB descriptions, or
* invalid context index in a TSB
* descriptor, or index page size not
* equal to smallest page size in page
* size bitmask field.
*
* Configures the TSBs for the current CPU for virtual addresses with
* context zero. The TSB descriptions pointer is a pointer to an
* array of the given number of TSB descriptions.
*
* Note: The maximum number of TSBs available to a virtual CPU is given by the
* mmu-max-#tsbs property of the cpu's corresponding "cpu" node in the
* machine description.
*/
#define HV_FAST_MMU_TSB_CTX0 0x20
#ifndef __ASSEMBLY__
extern unsigned long sun4v_mmu_tsb_ctx0(unsigned long num_descriptions,
unsigned long tsb_desc_ra);
#endif
/* mmu_tsb_ctxnon0()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_TSB_CTXNON0
* ARG0: number of TSB descriptions
* ARG1: TSB descriptions pointer
* RET0: status
* ERRORS: Same as for mmu_tsb_ctx0() above.
*
* Configures the TSBs for the current CPU for virtual addresses with
* non-zero contexts. The TSB descriptions pointer is a pointer to an
* array of the given number of TSB descriptions.
*
* Note: A maximum of 16 TSBs may be specified in the TSB description list.
*/
#define HV_FAST_MMU_TSB_CTXNON0 0x21
/* mmu_demap_page()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_DEMAP_PAGE
* ARG0: reserved, must be zero
* ARG1: reserved, must be zero
* ARG2: virtual address
* ARG3: mmu context
* ARG4: flags (HV_MMU_{IMMU,DMMU})
* RET0: status
* ERRORS: EINVAL Invalid virutal address, context, or
* flags value
* ENOTSUPPORTED ARG0 or ARG1 is non-zero
*
* Demaps any page mapping of the given virtual address in the given
* mmu context for the current virtual CPU. Any virtually tagged
* caches are guaranteed to be kept consistent. The flags argument
* determines which TLB (instruction, or data, or both) participate in
* the operation.
*
* ARG0 and ARG1 are both reserved and must be set to zero.
*/
#define HV_FAST_MMU_DEMAP_PAGE 0x22
/* mmu_demap_ctx()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_DEMAP_CTX
* ARG0: reserved, must be zero
* ARG1: reserved, must be zero
* ARG2: mmu context
* ARG3: flags (HV_MMU_{IMMU,DMMU})
* RET0: status
* ERRORS: EINVAL Invalid context or flags value
* ENOTSUPPORTED ARG0 or ARG1 is non-zero
*
* Demaps all non-permanent virtual page mappings previously specified
* for the given context for the current virtual CPU. Any virtual
* tagged caches are guaranteed to be kept consistent. The flags
* argument determines which TLB (instruction, or data, or both)
* participate in the operation.
*
* ARG0 and ARG1 are both reserved and must be set to zero.
*/
#define HV_FAST_MMU_DEMAP_CTX 0x23
/* mmu_demap_all()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_DEMAP_ALL
* ARG0: reserved, must be zero
* ARG1: reserved, must be zero
* ARG2: flags (HV_MMU_{IMMU,DMMU})
* RET0: status
* ERRORS: EINVAL Invalid flags value
* ENOTSUPPORTED ARG0 or ARG1 is non-zero
*
* Demaps all non-permanent virtual page mappings previously specified
* for the current virtual CPU. Any virtual tagged caches are
* guaranteed to be kept consistent. The flags argument determines
* which TLB (instruction, or data, or both) participate in the
* operation.
*
* ARG0 and ARG1 are both reserved and must be set to zero.
*/
#define HV_FAST_MMU_DEMAP_ALL 0x24
#ifndef __ASSEMBLY__
extern void sun4v_mmu_demap_all(void);
#endif
/* mmu_map_perm_addr()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_MAP_PERM_ADDR
* ARG0: virtual address
* ARG1: reserved, must be zero
* ARG2: TTE
* ARG3: flags (HV_MMU_{IMMU,DMMU})
* RET0: status
* ERRORS: EINVAL Invalid virutal address or flags value
* EBADPGSZ Invalid page size value
* ENORADDR Invalid real address in TTE
* ETOOMANY Too many mappings (max of 8 reached)
*
* Create a permanent mapping using the given TTE and virtual address
* for context 0 on the calling virtual CPU. A maximum of 8 such
* permanent mappings may be specified by privileged code. Mappings
* may be removed with mmu_unmap_perm_addr().
*
* The behavior is undefined if a TTE with the valid bit clear is given.
*
* Note: This call is used to specify address space mappings for which
* privileged code does not expect to receive misses. For example,
* this mechanism can be used to map kernel nucleus code and data.
*/
#define HV_FAST_MMU_MAP_PERM_ADDR 0x25
#ifndef __ASSEMBLY__
extern unsigned long sun4v_mmu_map_perm_addr(unsigned long vaddr,
unsigned long set_to_zero,
unsigned long tte,
unsigned long flags);
#endif
/* mmu_fault_area_conf()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_FAULT_AREA_CONF
* ARG0: real address
* RET0: status
* RET1: previous mmu fault area real address
* ERRORS: ENORADDR Invalid real address
* EBADALIGN Invalid alignment for fault area
*
* Configure the MMU fault status area for the calling CPU. A 64-byte
* aligned real address specifies where MMU fault status information
* is placed. The return value is the previously specified area, or 0
* for the first invocation. Specifying a fault area at real address
* 0 is not allowed.
*/
#define HV_FAST_MMU_FAULT_AREA_CONF 0x26
/* mmu_enable()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_ENABLE
* ARG0: enable flag
* ARG1: return target address
* RET0: status
* ERRORS: ENORADDR Invalid real address when disabling
* translation.
* EBADALIGN The return target address is not
* aligned to an instruction.
* EINVAL The enable flag request the current
* operating mode (e.g. disable if already
* disabled)
*
* Enable or disable virtual address translation for the calling CPU
* within the virtual machine domain. If the enable flag is zero,
* translation is disabled, any non-zero value will enable
* translation.
*
* When this function returns, the newly selected translation mode
* will be active. If the mmu is being enabled, then the return
* target address is a virtual address else it is a real address.
*
* Upon successful completion, control will be returned to the given
* return target address (ie. the cpu will jump to that address). On
* failure, the previous mmu mode remains and the trap simply returns
* as normal with the appropriate error code in RET0.
*/
#define HV_FAST_MMU_ENABLE 0x27
/* mmu_unmap_perm_addr()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_UNMAP_PERM_ADDR
* ARG0: virtual address
* ARG1: reserved, must be zero
* ARG2: flags (HV_MMU_{IMMU,DMMU})
* RET0: status
* ERRORS: EINVAL Invalid virutal address or flags value
* ENOMAP Specified mapping was not found
*
* Demaps any permanent page mapping (established via
* mmu_map_perm_addr()) at the given virtual address for context 0 on
* the current virtual CPU. Any virtual tagged caches are guaranteed
* to be kept consistent.
*/
#define HV_FAST_MMU_UNMAP_PERM_ADDR 0x28
/* mmu_tsb_ctx0_info()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_TSB_CTX0_INFO
* ARG0: max TSBs
* ARG1: buffer pointer
* RET0: status
* RET1: number of TSBs
* ERRORS: EINVAL Supplied buffer is too small
* EBADALIGN The buffer pointer is badly aligned
* ENORADDR Invalid real address for buffer pointer
*
* Return the TSB configuration as previous defined by mmu_tsb_ctx0()
* into the provided buffer. The size of the buffer is given in ARG1
* in terms of the number of TSB description entries.
*
* Upon return, RET1 always contains the number of TSB descriptions
* previously configured. If zero TSBs were configured, EOK is
* returned with RET1 containing 0.
*/
#define HV_FAST_MMU_TSB_CTX0_INFO 0x29
/* mmu_tsb_ctxnon0_info()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_TSB_CTXNON0_INFO
* ARG0: max TSBs
* ARG1: buffer pointer
* RET0: status
* RET1: number of TSBs
* ERRORS: EINVAL Supplied buffer is too small
* EBADALIGN The buffer pointer is badly aligned
* ENORADDR Invalid real address for buffer pointer
*
* Return the TSB configuration as previous defined by
* mmu_tsb_ctxnon0() into the provided buffer. The size of the buffer
* is given in ARG1 in terms of the number of TSB description entries.
*
* Upon return, RET1 always contains the number of TSB descriptions
* previously configured. If zero TSBs were configured, EOK is
* returned with RET1 containing 0.
*/
#define HV_FAST_MMU_TSB_CTXNON0_INFO 0x2a
/* mmu_fault_area_info()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMU_FAULT_AREA_INFO
* RET0: status
* RET1: fault area real address
* ERRORS: No errors defined.
*
* Return the currently defined MMU fault status area for the current
* CPU. The real address of the fault status area is returned in
* RET1, or 0 is returned in RET1 if no fault status area is defined.
*
* Note: mmu_fault_area_conf() may be called with the return value (RET1)
* from this service if there is a need to save and restore the fault
* area for a cpu.
*/
#define HV_FAST_MMU_FAULT_AREA_INFO 0x2b
/* Cache and Memory services. */
/* mem_scrub()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MEM_SCRUB
* ARG0: real address
* ARG1: length
* RET0: status
* RET1: length scrubbed
* ERRORS: ENORADDR Invalid real address
* EBADALIGN Start address or length are not correctly
* aligned
* EINVAL Length is zero
*
* Zero the memory contents in the range real address to real address
* plus length minus 1. Also, valid ECC will be generated for that
* memory address range. Scrubbing is started at the given real
* address, but may not scrub the entire given length. The actual
* length scrubbed will be returned in RET1.
*
* The real address and length must be aligned on an 8K boundary, or
* contain the start address and length from a sun4v error report.
*
* Note: There are two uses for this function. The first use is to block clear
* and initialize memory and the second is to scrub an u ncorrectable
* error reported via a resumable or non-resumable trap. The second
* use requires the arguments to be equal to the real address and length
* provided in a sun4v memory error report.
*/
#define HV_FAST_MEM_SCRUB 0x31
/* mem_sync()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MEM_SYNC
* ARG0: real address
* ARG1: length
* RET0: status
* RET1: length synced
* ERRORS: ENORADDR Invalid real address
* EBADALIGN Start address or length are not correctly
* aligned
* EINVAL Length is zero
*
* Force the next access within the real address to real address plus
* length minus 1 to be fetches from main system memory. Less than
* the given length may be synced, the actual amount synced is
* returned in RET1. The real address and length must be aligned on
* an 8K boundary.
*/
#define HV_FAST_MEM_SYNC 0x32
/* Time of day services.
*
* The hypervisor maintains the time of day on a per-domain basis.
* Changing the time of day in one domain does not affect the time of
* day on any other domain.
*
* Time is described by a single unsigned 64-bit word which is the
* number of seconds since the UNIX Epoch (00:00:00 UTC, January 1,
* 1970).
*/
/* tod_get()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_TOD_GET
* RET0: status
* RET1: TOD
* ERRORS: EWOULDBLOCK TOD resource is temporarily unavailable
* ENOTSUPPORTED If TOD not supported on this platform
*
* Return the current time of day. May block if TOD access is
* temporarily not possible.
*/
#define HV_FAST_TOD_GET 0x50
#ifndef __ASSEMBLY__
extern unsigned long sun4v_tod_get(unsigned long *time);
#endif
/* tod_set()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_TOD_SET
* ARG0: TOD
* RET0: status
* ERRORS: EWOULDBLOCK TOD resource is temporarily unavailable
* ENOTSUPPORTED If TOD not supported on this platform
*
* The current time of day is set to the value specified in ARG0. May
* block if TOD access is temporarily not possible.
*/
#define HV_FAST_TOD_SET 0x51
#ifndef __ASSEMBLY__
extern unsigned long sun4v_tod_set(unsigned long time);
#endif
/* Console services */
/* con_getchar()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CONS_GETCHAR
* RET0: status
* RET1: character
* ERRORS: EWOULDBLOCK No character available.
*
* Returns a character from the console device. If no character is
* available then an EWOULDBLOCK error is returned. If a character is
* available, then the returned status is EOK and the character value
* is in RET1.
*
* A virtual BREAK is represented by the 64-bit value -1.
*
* A virtual HUP signal is represented by the 64-bit value -2.
*/
#define HV_FAST_CONS_GETCHAR 0x60
/* con_putchar()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CONS_PUTCHAR
* ARG0: character
* RET0: status
* ERRORS: EINVAL Illegal character
* EWOULDBLOCK Output buffer currently full, would block
*
* Send a character to the console device. Only character values
* between 0 and 255 may be used. Values outside this range are
* invalid except for the 64-bit value -1 which is used to send a
* virtual BREAK.
*/
#define HV_FAST_CONS_PUTCHAR 0x61
/* con_read()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CONS_READ
* ARG0: buffer real address
* ARG1: buffer size in bytes
* RET0: status
* RET1: bytes read or BREAK or HUP
* ERRORS: EWOULDBLOCK No character available.
*
* Reads characters into a buffer from the console device. If no
* character is available then an EWOULDBLOCK error is returned.
* If a character is available, then the returned status is EOK
* and the number of bytes read into the given buffer is provided
* in RET1.
*
* A virtual BREAK is represented by the 64-bit RET1 value -1.
*
* A virtual HUP signal is represented by the 64-bit RET1 value -2.
*
* If BREAK or HUP are indicated, no bytes were read into buffer.
*/
#define HV_FAST_CONS_READ 0x62
/* con_write()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_CONS_WRITE
* ARG0: buffer real address
* ARG1: buffer size in bytes
* RET0: status
* RET1: bytes written
* ERRORS: EWOULDBLOCK Output buffer currently full, would block
*
* Send a characters in buffer to the console device. Breaks must be
* sent using con_putchar().
*/
#define HV_FAST_CONS_WRITE 0x63
#ifndef __ASSEMBLY__
extern long sun4v_con_getchar(long *status);
extern long sun4v_con_putchar(long c);
extern long sun4v_con_read(unsigned long buffer,
unsigned long size,
unsigned long *bytes_read);
extern unsigned long sun4v_con_write(unsigned long buffer,
unsigned long size,
unsigned long *bytes_written);
#endif
/* mach_set_soft_state()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MACH_SET_SOFT_STATE
* ARG0: software state
* ARG1: software state description pointer
* RET0: status
* ERRORS: EINVAL software state not valid or software state
* description is not NULL terminated
* ENORADDR software state description pointer is not a
* valid real address
* EBADALIGNED software state description is not correctly
* aligned
*
* This allows the guest to report it's soft state to the hypervisor. There
* are two primary components to this state. The first part states whether
* the guest software is running or not. The second containts optional
* details specific to the software.
*
* The software state argument is defined below in HV_SOFT_STATE_*, and
* indicates whether the guest is operating normally or in a transitional
* state.
*
* The software state description argument is a real address of a data buffer
* of size 32-bytes aligned on a 32-byte boundary. It is treated as a NULL
* terminated 7-bit ASCII string of up to 31 characters not including the
* NULL termination.
*/
#define HV_FAST_MACH_SET_SOFT_STATE 0x70
#define HV_SOFT_STATE_NORMAL 0x01
#define HV_SOFT_STATE_TRANSITION 0x02
#ifndef __ASSEMBLY__
extern unsigned long sun4v_mach_set_soft_state(unsigned long soft_state,
unsigned long msg_string_ra);
#endif
/* mach_get_soft_state()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MACH_GET_SOFT_STATE
* ARG0: software state description pointer
* RET0: status
* RET1: software state
* ERRORS: ENORADDR software state description pointer is not a
* valid real address
* EBADALIGNED software state description is not correctly
* aligned
*
* Retrieve the current value of the guest's software state. The rules
* for the software state pointer are the same as for mach_set_soft_state()
* above.
*/
#define HV_FAST_MACH_GET_SOFT_STATE 0x71
/* svc_send()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_SVC_SEND
* ARG0: service ID
* ARG1: buffer real address
* ARG2: buffer size
* RET0: STATUS
* RET1: sent_bytes
*
* Be careful, all output registers are clobbered by this operation,
* so for example it is not possible to save away a value in %o4
* across the trap.
*/
#define HV_FAST_SVC_SEND 0x80
/* svc_recv()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_SVC_RECV
* ARG0: service ID
* ARG1: buffer real address
* ARG2: buffer size
* RET0: STATUS
* RET1: recv_bytes
*
* Be careful, all output registers are clobbered by this operation,
* so for example it is not possible to save away a value in %o4
* across the trap.
*/
#define HV_FAST_SVC_RECV 0x81
/* svc_getstatus()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_SVC_GETSTATUS
* ARG0: service ID
* RET0: STATUS
* RET1: status bits
*/
#define HV_FAST_SVC_GETSTATUS 0x82
/* svc_setstatus()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_SVC_SETSTATUS
* ARG0: service ID
* ARG1: bits to set
* RET0: STATUS
*/
#define HV_FAST_SVC_SETSTATUS 0x83
/* svc_clrstatus()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_SVC_CLRSTATUS
* ARG0: service ID
* ARG1: bits to clear
* RET0: STATUS
*/
#define HV_FAST_SVC_CLRSTATUS 0x84
#ifndef __ASSEMBLY__
extern unsigned long sun4v_svc_send(unsigned long svc_id,
unsigned long buffer,
unsigned long buffer_size,
unsigned long *sent_bytes);
extern unsigned long sun4v_svc_recv(unsigned long svc_id,
unsigned long buffer,
unsigned long buffer_size,
unsigned long *recv_bytes);
extern unsigned long sun4v_svc_getstatus(unsigned long svc_id,
unsigned long *status_bits);
extern unsigned long sun4v_svc_setstatus(unsigned long svc_id,
unsigned long status_bits);
extern unsigned long sun4v_svc_clrstatus(unsigned long svc_id,
unsigned long status_bits);
#endif
/* Trap trace services.
*
* The hypervisor provides a trap tracing capability for privileged
* code running on each virtual CPU. Privileged code provides a
* round-robin trap trace queue within which the hypervisor writes
* 64-byte entries detailing hyperprivileged traps taken n behalf of
* privileged code. This is provided as a debugging capability for
* privileged code.
*
* The trap trace control structure is 64-bytes long and placed at the
* start (offset 0) of the trap trace buffer, and is described as
* follows:
*/
#ifndef __ASSEMBLY__
struct hv_trap_trace_control {
unsigned long head_offset;
unsigned long tail_offset;
unsigned long __reserved[0x30 / sizeof(unsigned long)];
};
#endif
#define HV_TRAP_TRACE_CTRL_HEAD_OFFSET 0x00
#define HV_TRAP_TRACE_CTRL_TAIL_OFFSET 0x08
/* The head offset is the offset of the most recently completed entry
* in the trap-trace buffer. The tail offset is the offset of the
* next entry to be written. The control structure is owned and
* modified by the hypervisor. A guest may not modify the control
* structure contents. Attempts to do so will result in undefined
* behavior for the guest.
*
* Each trap trace buffer entry is layed out as follows:
*/
#ifndef __ASSEMBLY__
struct hv_trap_trace_entry {
unsigned char type; /* Hypervisor or guest entry? */
unsigned char hpstate; /* Hyper-privileged state */
unsigned char tl; /* Trap level */
unsigned char gl; /* Global register level */
unsigned short tt; /* Trap type */
unsigned short tag; /* Extended trap identifier */
unsigned long tstate; /* Trap state */
unsigned long tick; /* Tick */
unsigned long tpc; /* Trap PC */
unsigned long f1; /* Entry specific */
unsigned long f2; /* Entry specific */
unsigned long f3; /* Entry specific */
unsigned long f4; /* Entry specific */
};
#endif
#define HV_TRAP_TRACE_ENTRY_TYPE 0x00
#define HV_TRAP_TRACE_ENTRY_HPSTATE 0x01
#define HV_TRAP_TRACE_ENTRY_TL 0x02
#define HV_TRAP_TRACE_ENTRY_GL 0x03
#define HV_TRAP_TRACE_ENTRY_TT 0x04
#define HV_TRAP_TRACE_ENTRY_TAG 0x06
#define HV_TRAP_TRACE_ENTRY_TSTATE 0x08
#define HV_TRAP_TRACE_ENTRY_TICK 0x10
#define HV_TRAP_TRACE_ENTRY_TPC 0x18
#define HV_TRAP_TRACE_ENTRY_F1 0x20
#define HV_TRAP_TRACE_ENTRY_F2 0x28
#define HV_TRAP_TRACE_ENTRY_F3 0x30
#define HV_TRAP_TRACE_ENTRY_F4 0x38
/* The type field is encoded as follows. */
#define HV_TRAP_TYPE_UNDEF 0x00 /* Entry content undefined */
#define HV_TRAP_TYPE_HV 0x01 /* Hypervisor trap entry */
#define HV_TRAP_TYPE_GUEST 0xff /* Added via ttrace_addentry() */
/* ttrace_buf_conf()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_TTRACE_BUF_CONF
* ARG0: real address
* ARG1: number of entries
* RET0: status
* RET1: number of entries
* ERRORS: ENORADDR Invalid real address
* EINVAL Size is too small
* EBADALIGN Real address not aligned on 64-byte boundary
*
* Requests hypervisor trap tracing and declares a virtual CPU's trap
* trace buffer to the hypervisor. The real address supplies the real
* base address of the trap trace queue and must be 64-byte aligned.
* Specifying a value of 0 for the number of entries disables trap
* tracing for the calling virtual CPU. The buffer allocated must be
* sized for a power of two number of 64-byte trap trace entries plus
* an initial 64-byte control structure.
*
* This may be invoked any number of times so that a virtual CPU may
* relocate a trap trace buffer or create "snapshots" of information.
*
* If the real address is illegal or badly aligned, then trap tracing
* is disabled and an error is returned.
*
* Upon failure with EINVAL, this service call returns in RET1 the
* minimum number of buffer entries required. Upon other failures
* RET1 is undefined.
*/
#define HV_FAST_TTRACE_BUF_CONF 0x90
/* ttrace_buf_info()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_TTRACE_BUF_INFO
* RET0: status
* RET1: real address
* RET2: size
* ERRORS: None defined.
*
* Returns the size and location of the previously declared trap-trace
* buffer. In the event that no buffer was previously defined, or the
* buffer is disabled, this call will return a size of zero bytes.
*/
#define HV_FAST_TTRACE_BUF_INFO 0x91
/* ttrace_enable()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_TTRACE_ENABLE
* ARG0: enable
* RET0: status
* RET1: previous enable state
* ERRORS: EINVAL No trap trace buffer currently defined
*
* Enable or disable trap tracing, and return the previous enabled
* state in RET1. Future systems may define various flags for the
* enable argument (ARG0), for the moment a guest should pass
* "(uint64_t) -1" to enable, and "(uint64_t) 0" to disable all
* tracing - which will ensure future compatability.
*/
#define HV_FAST_TTRACE_ENABLE 0x92
/* ttrace_freeze()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_TTRACE_FREEZE
* ARG0: freeze
* RET0: status
* RET1: previous freeze state
* ERRORS: EINVAL No trap trace buffer currently defined
*
* Freeze or unfreeze trap tracing, returning the previous freeze
* state in RET1. A guest should pass a non-zero value to freeze and
* a zero value to unfreeze all tracing. The returned previous state
* is 0 for not frozen and 1 for frozen.
*/
#define HV_FAST_TTRACE_FREEZE 0x93
/* ttrace_addentry()
* TRAP: HV_TTRACE_ADDENTRY_TRAP
* ARG0: tag (16-bits)
* ARG1: data word 0
* ARG2: data word 1
* ARG3: data word 2
* ARG4: data word 3
* RET0: status
* ERRORS: EINVAL No trap trace buffer currently defined
*
* Add an entry to the trap trace buffer. Upon return only ARG0/RET0
* is modified - none of the other registers holding arguments are
* volatile across this hypervisor service.
*/
/* Core dump services.
*
* Since the hypervisor viraulizes and thus obscures a lot of the
* physical machine layout and state, traditional OS crash dumps can
* be difficult to diagnose especially when the problem is a
* configuration error of some sort.
*
* The dump services provide an opaque buffer into which the
* hypervisor can place it's internal state in order to assist in
* debugging such situations. The contents are opaque and extremely
* platform and hypervisor implementation specific. The guest, during
* a core dump, requests that the hypervisor update any information in
* the dump buffer in preparation to being dumped as part of the
* domain's memory image.
*/
/* dump_buf_update()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_DUMP_BUF_UPDATE
* ARG0: real address
* ARG1: size
* RET0: status
* RET1: required size of dump buffer
* ERRORS: ENORADDR Invalid real address
* EBADALIGN Real address is not aligned on a 64-byte
* boundary
* EINVAL Size is non-zero but less than minimum size
* required
* ENOTSUPPORTED Operation not supported on current logical
* domain
*
* Declare a domain dump buffer to the hypervisor. The real address
* provided for the domain dump buffer must be 64-byte aligned. The
* size specifies the size of the dump buffer and may be larger than
* the minimum size specified in the machine description. The
* hypervisor will fill the dump buffer with opaque data.
*
* Note: A guest may elect to include dump buffer contents as part of a crash
* dump to assist with debugging. This function may be called any number
* of times so that a guest may relocate a dump buffer, or create
* "snapshots" of any dump-buffer information. Each call to
* dump_buf_update() atomically declares the new dump buffer to the
* hypervisor.
*
* A specified size of 0 unconfigures the dump buffer. If the real
* address is illegal or badly aligned, then any currently active dump
* buffer is disabled and an error is returned.
*
* In the event that the call fails with EINVAL, RET1 contains the
* minimum size requires by the hypervisor for a valid dump buffer.
*/
#define HV_FAST_DUMP_BUF_UPDATE 0x94
/* dump_buf_info()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_DUMP_BUF_INFO
* RET0: status
* RET1: real address of current dump buffer
* RET2: size of current dump buffer
* ERRORS: No errors defined.
*
* Return the currently configures dump buffer description. A
* returned size of 0 bytes indicates an undefined dump buffer. In
* this case the return address in RET1 is undefined.
*/
#define HV_FAST_DUMP_BUF_INFO 0x95
/* Device interrupt services.
*
* Device interrupts are allocated to system bus bridges by the hypervisor,
* and described to OBP in the machine description. OBP then describes
* these interrupts to the OS via properties in the device tree.
*
* Terminology:
*
* cpuid Unique opaque value which represents a target cpu.
*
* devhandle Device handle. It uniquely identifies a device, and
* consistes of the lower 28-bits of the hi-cell of the
* first entry of the device's "reg" property in the
* OBP device tree.
*
* devino Device interrupt number. Specifies the relative
* interrupt number within the device. The unique
* combination of devhandle and devino are used to
* identify a specific device interrupt.
*
* Note: The devino value is the same as the values in the
* "interrupts" property or "interrupt-map" property
* in the OBP device tree for that device.
*
* sysino System interrupt number. A 64-bit unsigned interger
* representing a unique interrupt within a virtual
* machine.
*
* intr_state A flag representing the interrupt state for a given
* sysino. The state values are defined below.
*
* intr_enabled A flag representing the 'enabled' state for a given
* sysino. The enable values are defined below.
*/
#define HV_INTR_STATE_IDLE 0 /* Nothing pending */
#define HV_INTR_STATE_RECEIVED 1 /* Interrupt received by hardware */
#define HV_INTR_STATE_DELIVERED 2 /* Interrupt delivered to queue */
#define HV_INTR_DISABLED 0 /* sysino not enabled */
#define HV_INTR_ENABLED 1 /* sysino enabled */
/* intr_devino_to_sysino()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_INTR_DEVINO2SYSINO
* ARG0: devhandle
* ARG1: devino
* RET0: status
* RET1: sysino
* ERRORS: EINVAL Invalid devhandle/devino
*
* Converts a device specific interrupt number of the given
* devhandle/devino into a system specific ino (sysino).
*/
#define HV_FAST_INTR_DEVINO2SYSINO 0xa0
#ifndef __ASSEMBLY__
extern unsigned long sun4v_devino_to_sysino(unsigned long devhandle,
unsigned long devino);
#endif
/* intr_getenabled()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_INTR_GETENABLED
* ARG0: sysino
* RET0: status
* RET1: intr_enabled (HV_INTR_{DISABLED,ENABLED})
* ERRORS: EINVAL Invalid sysino
*
* Returns interrupt enabled state in RET1 for the interrupt defined
* by the given sysino.
*/
#define HV_FAST_INTR_GETENABLED 0xa1
#ifndef __ASSEMBLY__
extern unsigned long sun4v_intr_getenabled(unsigned long sysino);
#endif
/* intr_setenabled()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_INTR_SETENABLED
* ARG0: sysino
* ARG1: intr_enabled (HV_INTR_{DISABLED,ENABLED})
* RET0: status
* ERRORS: EINVAL Invalid sysino or intr_enabled value
*
* Set the 'enabled' state of the interrupt sysino.
*/
#define HV_FAST_INTR_SETENABLED 0xa2
#ifndef __ASSEMBLY__
extern unsigned long sun4v_intr_setenabled(unsigned long sysino, unsigned long intr_enabled);
#endif
/* intr_getstate()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_INTR_GETSTATE
* ARG0: sysino
* RET0: status
* RET1: intr_state (HV_INTR_STATE_*)
* ERRORS: EINVAL Invalid sysino
*
* Returns current state of the interrupt defined by the given sysino.
*/
#define HV_FAST_INTR_GETSTATE 0xa3
#ifndef __ASSEMBLY__
extern unsigned long sun4v_intr_getstate(unsigned long sysino);
#endif
/* intr_setstate()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_INTR_SETSTATE
* ARG0: sysino
* ARG1: intr_state (HV_INTR_STATE_*)
* RET0: status
* ERRORS: EINVAL Invalid sysino or intr_state value
*
* Sets the current state of the interrupt described by the given sysino
* value.
*
* Note: Setting the state to HV_INTR_STATE_IDLE clears any pending
* interrupt for sysino.
*/
#define HV_FAST_INTR_SETSTATE 0xa4
#ifndef __ASSEMBLY__
extern unsigned long sun4v_intr_setstate(unsigned long sysino, unsigned long intr_state);
#endif
/* intr_gettarget()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_INTR_GETTARGET
* ARG0: sysino
* RET0: status
* RET1: cpuid
* ERRORS: EINVAL Invalid sysino
*
* Returns CPU that is the current target of the interrupt defined by
* the given sysino. The CPU value returned is undefined if the target
* has not been set via intr_settarget().
*/
#define HV_FAST_INTR_GETTARGET 0xa5
#ifndef __ASSEMBLY__
extern unsigned long sun4v_intr_gettarget(unsigned long sysino);
#endif
/* intr_settarget()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_INTR_SETTARGET
* ARG0: sysino
* ARG1: cpuid
* RET0: status
* ERRORS: EINVAL Invalid sysino
* ENOCPU Invalid cpuid
*
* Set the target CPU for the interrupt defined by the given sysino.
*/
#define HV_FAST_INTR_SETTARGET 0xa6
#ifndef __ASSEMBLY__
extern unsigned long sun4v_intr_settarget(unsigned long sysino, unsigned long cpuid);
#endif
/* vintr_get_cookie()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_VINTR_GET_COOKIE
* ARG0: device handle
* ARG1: device ino
* RET0: status
* RET1: cookie
*/
#define HV_FAST_VINTR_GET_COOKIE 0xa7
/* vintr_set_cookie()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_VINTR_SET_COOKIE
* ARG0: device handle
* ARG1: device ino
* ARG2: cookie
* RET0: status
*/
#define HV_FAST_VINTR_SET_COOKIE 0xa8
/* vintr_get_valid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_VINTR_GET_VALID
* ARG0: device handle
* ARG1: device ino
* RET0: status
* RET1: valid state
*/
#define HV_FAST_VINTR_GET_VALID 0xa9
/* vintr_set_valid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_VINTR_SET_VALID
* ARG0: device handle
* ARG1: device ino
* ARG2: valid state
* RET0: status
*/
#define HV_FAST_VINTR_SET_VALID 0xaa
/* vintr_get_state()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_VINTR_GET_STATE
* ARG0: device handle
* ARG1: device ino
* RET0: status
* RET1: state
*/
#define HV_FAST_VINTR_GET_STATE 0xab
/* vintr_set_state()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_VINTR_SET_STATE
* ARG0: device handle
* ARG1: device ino
* ARG2: state
* RET0: status
*/
#define HV_FAST_VINTR_SET_STATE 0xac
/* vintr_get_target()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_VINTR_GET_TARGET
* ARG0: device handle
* ARG1: device ino
* RET0: status
* RET1: cpuid
*/
#define HV_FAST_VINTR_GET_TARGET 0xad
/* vintr_set_target()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_VINTR_SET_TARGET
* ARG0: device handle
* ARG1: device ino
* ARG2: cpuid
* RET0: status
*/
#define HV_FAST_VINTR_SET_TARGET 0xae
#ifndef __ASSEMBLY__
extern unsigned long sun4v_vintr_get_cookie(unsigned long dev_handle,
unsigned long dev_ino,
unsigned long *cookie);
extern unsigned long sun4v_vintr_set_cookie(unsigned long dev_handle,
unsigned long dev_ino,
unsigned long cookie);
extern unsigned long sun4v_vintr_get_valid(unsigned long dev_handle,
unsigned long dev_ino,
unsigned long *valid);
extern unsigned long sun4v_vintr_set_valid(unsigned long dev_handle,
unsigned long dev_ino,
unsigned long valid);
extern unsigned long sun4v_vintr_get_state(unsigned long dev_handle,
unsigned long dev_ino,
unsigned long *state);
extern unsigned long sun4v_vintr_set_state(unsigned long dev_handle,
unsigned long dev_ino,
unsigned long state);
extern unsigned long sun4v_vintr_get_target(unsigned long dev_handle,
unsigned long dev_ino,
unsigned long *cpuid);
extern unsigned long sun4v_vintr_set_target(unsigned long dev_handle,
unsigned long dev_ino,
unsigned long cpuid);
#endif
/* PCI IO services.
*
* See the terminology descriptions in the device interrupt services
* section above as those apply here too. Here are terminology
* definitions specific to these PCI IO services:
*
* tsbnum TSB number. Indentifies which io-tsb is used.
* For this version of the specification, tsbnum
* must be zero.
*
* tsbindex TSB index. Identifies which entry in the TSB
* is used. The first entry is zero.
*
* tsbid A 64-bit aligned data structure which contains
* a tsbnum and a tsbindex. Bits 63:32 contain the
* tsbnum and bits 31:00 contain the tsbindex.
*
* Use the HV_PCI_TSBID() macro to construct such
* values.
*
* io_attributes IO attributes for IOMMU mappings. One of more
* of the attritbute bits are stores in a 64-bit
* value. The values are defined below.
*
* r_addr 64-bit real address
*
* pci_device PCI device address. A PCI device address identifies
* a specific device on a specific PCI bus segment.
* A PCI device address ia a 32-bit unsigned integer
* with the following format:
*
* 00000000.bbbbbbbb.dddddfff.00000000
*
* Use the HV_PCI_DEVICE_BUILD() macro to construct
* such values.
*
* pci_config_offset
* PCI configureation space offset. For conventional
* PCI a value between 0 and 255. For extended
* configuration space, a value between 0 and 4095.
*
* Note: For PCI configuration space accesses, the offset
* must be aligned to the access size.
*
* error_flag A return value which specifies if the action succeeded
* or failed. 0 means no error, non-0 means some error
* occurred while performing the service.
*
* io_sync_direction
* Direction definition for pci_dma_sync(), defined
* below in HV_PCI_SYNC_*.
*
* io_page_list A list of io_page_addresses, an io_page_address is
* a real address.
*
* io_page_list_p A pointer to an io_page_list.
*
* "size based byte swap" - Some functions do size based byte swapping
* which allows sw to access pointers and
* counters in native form when the processor
* operates in a different endianness than the
* IO bus. Size-based byte swapping converts a
* multi-byte field between big-endian and
* little-endian format.
*/
#define HV_PCI_MAP_ATTR_READ 0x01
#define HV_PCI_MAP_ATTR_WRITE 0x02
#define HV_PCI_DEVICE_BUILD(b,d,f) \
((((b) & 0xff) << 16) | \
(((d) & 0x1f) << 11) | \
(((f) & 0x07) << 8))
#define HV_PCI_TSBID(__tsb_num, __tsb_index) \
((((u64)(__tsb_num)) << 32UL) | ((u64)(__tsb_index)))
#define HV_PCI_SYNC_FOR_DEVICE 0x01
#define HV_PCI_SYNC_FOR_CPU 0x02
/* pci_iommu_map()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_IOMMU_MAP
* ARG0: devhandle
* ARG1: tsbid
* ARG2: #ttes
* ARG3: io_attributes
* ARG4: io_page_list_p
* RET0: status
* RET1: #ttes mapped
* ERRORS: EINVAL Invalid devhandle/tsbnum/tsbindex/io_attributes
* EBADALIGN Improperly aligned real address
* ENORADDR Invalid real address
*
* Create IOMMU mappings in the sun4v device defined by the given
* devhandle. The mappings are created in the TSB defined by the
* tsbnum component of the given tsbid. The first mapping is created
* in the TSB i ndex defined by the tsbindex component of the given tsbid.
* The call creates up to #ttes mappings, the first one at tsbnum, tsbindex,
* the second at tsbnum, tsbindex + 1, etc.
*
* All mappings are created with the attributes defined by the io_attributes
* argument. The page mapping addresses are described in the io_page_list
* defined by the given io_page_list_p, which is a pointer to the io_page_list.
* The first entry in the io_page_list is the address for the first iotte, the
* 2nd for the 2nd iotte, and so on.
*
* Each io_page_address in the io_page_list must be appropriately aligned.
* #ttes must be greater than zero. For this version of the spec, the tsbnum
* component of the given tsbid must be zero.
*
* Returns the actual number of mappings creates, which may be less than
* or equal to the argument #ttes. If the function returns a value which
* is less than the #ttes, the caller may continus to call the function with
* an updated tsbid, #ttes, io_page_list_p arguments until all pages are
* mapped.
*
* Note: This function does not imply an iotte cache flush. The guest must
* demap an entry before re-mapping it.
*/
#define HV_FAST_PCI_IOMMU_MAP 0xb0
/* pci_iommu_demap()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_IOMMU_DEMAP
* ARG0: devhandle
* ARG1: tsbid
* ARG2: #ttes
* RET0: status
* RET1: #ttes demapped
* ERRORS: EINVAL Invalid devhandle/tsbnum/tsbindex
*
* Demap and flush IOMMU mappings in the device defined by the given
* devhandle. Demaps up to #ttes entries in the TSB defined by the tsbnum
* component of the given tsbid, starting at the TSB index defined by the
* tsbindex component of the given tsbid.
*
* For this version of the spec, the tsbnum of the given tsbid must be zero.
* #ttes must be greater than zero.
*
* Returns the actual number of ttes demapped, which may be less than or equal
* to the argument #ttes. If #ttes demapped is less than #ttes, the caller
* may continue to call this function with updated tsbid and #ttes arguments
* until all pages are demapped.
*
* Note: Entries do not have to be mapped to be demapped. A demap of an
* unmapped page will flush the entry from the tte cache.
*/
#define HV_FAST_PCI_IOMMU_DEMAP 0xb1
/* pci_iommu_getmap()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_IOMMU_GETMAP
* ARG0: devhandle
* ARG1: tsbid
* RET0: status
* RET1: io_attributes
* RET2: real address
* ERRORS: EINVAL Invalid devhandle/tsbnum/tsbindex
* ENOMAP Mapping is not valid, no translation exists
*
* Read and return the mapping in the device described by the given devhandle
* and tsbid. If successful, the io_attributes shall be returned in RET1
* and the page address of the mapping shall be returned in RET2.
*
* For this version of the spec, the tsbnum component of the given tsbid
* must be zero.
*/
#define HV_FAST_PCI_IOMMU_GETMAP 0xb2
/* pci_iommu_getbypass()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_IOMMU_GETBYPASS
* ARG0: devhandle
* ARG1: real address
* ARG2: io_attributes
* RET0: status
* RET1: io_addr
* ERRORS: EINVAL Invalid devhandle/io_attributes
* ENORADDR Invalid real address
* ENOTSUPPORTED Function not supported in this implementation.
*
* Create a "special" mapping in the device described by the given devhandle,
* for the given real address and attributes. Return the IO address in RET1
* if successful.
*/
#define HV_FAST_PCI_IOMMU_GETBYPASS 0xb3
/* pci_config_get()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_CONFIG_GET
* ARG0: devhandle
* ARG1: pci_device
* ARG2: pci_config_offset
* ARG3: size
* RET0: status
* RET1: error_flag
* RET2: data
* ERRORS: EINVAL Invalid devhandle/pci_device/offset/size
* EBADALIGN pci_config_offset not size aligned
* ENOACCESS Access to this offset is not permitted
*
* Read PCI configuration space for the adapter described by the given
* devhandle. Read size (1, 2, or 4) bytes of data from the given
* pci_device, at pci_config_offset from the beginning of the device's
* configuration space. If there was no error, RET1 is set to zero and
* RET2 is set to the data read. Insignificant bits in RET2 are not
* guarenteed to have any specific value and therefore must be ignored.
*
* The data returned in RET2 is size based byte swapped.
*
* If an error occurs during the read, set RET1 to a non-zero value. The
* given pci_config_offset must be 'size' aligned.
*/
#define HV_FAST_PCI_CONFIG_GET 0xb4
/* pci_config_put()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_CONFIG_PUT
* ARG0: devhandle
* ARG1: pci_device
* ARG2: pci_config_offset
* ARG3: size
* ARG4: data
* RET0: status
* RET1: error_flag
* ERRORS: EINVAL Invalid devhandle/pci_device/offset/size
* EBADALIGN pci_config_offset not size aligned
* ENOACCESS Access to this offset is not permitted
*
* Write PCI configuration space for the adapter described by the given
* devhandle. Write size (1, 2, or 4) bytes of data in a single operation,
* at pci_config_offset from the beginning of the device's configuration
* space. The data argument contains the data to be written to configuration
* space. Prior to writing, the data is size based byte swapped.
*
* If an error occurs during the write access, do not generate an error
* report, do set RET1 to a non-zero value. Otherwise RET1 is zero.
* The given pci_config_offset must be 'size' aligned.
*
* This function is permitted to read from offset zero in the configuration
* space described by the given pci_device if necessary to ensure that the
* write access to config space completes.
*/
#define HV_FAST_PCI_CONFIG_PUT 0xb5
/* pci_peek()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_PEEK
* ARG0: devhandle
* ARG1: real address
* ARG2: size
* RET0: status
* RET1: error_flag
* RET2: data
* ERRORS: EINVAL Invalid devhandle or size
* EBADALIGN Improperly aligned real address
* ENORADDR Bad real address
* ENOACCESS Guest access prohibited
*
* Attempt to read the IO address given by the given devhandle, real address,
* and size. Size must be 1, 2, 4, or 8. The read is performed as a single
* access operation using the given size. If an error occurs when reading
* from the given location, do not generate an error report, but return a
* non-zero value in RET1. If the read was successful, return zero in RET1
* and return the actual data read in RET2. The data returned is size based
* byte swapped.
*
* Non-significant bits in RET2 are not guarenteed to have any specific value
* and therefore must be ignored. If RET1 is returned as non-zero, the data
* value is not guarenteed to have any specific value and should be ignored.
*
* The caller must have permission to read from the given devhandle, real
* address, which must be an IO address. The argument real address must be a
* size aligned address.
*
* The hypervisor implementation of this function must block access to any
* IO address that the guest does not have explicit permission to access.
*/
#define HV_FAST_PCI_PEEK 0xb6
/* pci_poke()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_POKE
* ARG0: devhandle
* ARG1: real address
* ARG2: size
* ARG3: data
* ARG4: pci_device
* RET0: status
* RET1: error_flag
* ERRORS: EINVAL Invalid devhandle, size, or pci_device
* EBADALIGN Improperly aligned real address
* ENORADDR Bad real address
* ENOACCESS Guest access prohibited
* ENOTSUPPORTED Function is not supported by implementation
*
* Attempt to write data to the IO address given by the given devhandle,
* real address, and size. Size must be 1, 2, 4, or 8. The write is
* performed as a single access operation using the given size. Prior to
* writing the data is size based swapped.
*
* If an error occurs when writing to the given location, do not generate an
* error report, but return a non-zero value in RET1. If the write was
* successful, return zero in RET1.
*
* pci_device describes the configuration address of the device being
* written to. The implementation may safely read from offset 0 with
* the configuration space of the device described by devhandle and
* pci_device in order to guarantee that the write portion of the operation
* completes
*
* Any error that occurs due to the read shall be reported using the normal
* error reporting mechanisms .. the read error is not suppressed.
*
* The caller must have permission to write to the given devhandle, real
* address, which must be an IO address. The argument real address must be a
* size aligned address. The caller must have permission to read from
* the given devhandle, pci_device cofiguration space offset 0.
*
* The hypervisor implementation of this function must block access to any
* IO address that the guest does not have explicit permission to access.
*/
#define HV_FAST_PCI_POKE 0xb7
/* pci_dma_sync()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_DMA_SYNC
* ARG0: devhandle
* ARG1: real address
* ARG2: size
* ARG3: io_sync_direction
* RET0: status
* RET1: #synced
* ERRORS: EINVAL Invalid devhandle or io_sync_direction
* ENORADDR Bad real address
*
* Synchronize a memory region described by the given real address and size,
* for the device defined by the given devhandle using the direction(s)
* defined by the given io_sync_direction. The argument size is the size of
* the memory region in bytes.
*
* Return the actual number of bytes synchronized in the return value #synced,
* which may be less than or equal to the argument size. If the return
* value #synced is less than size, the caller must continue to call this
* function with updated real address and size arguments until the entire
* memory region is synchronized.
*/
#define HV_FAST_PCI_DMA_SYNC 0xb8
/* PCI MSI services. */
#define HV_MSITYPE_MSI32 0x00
#define HV_MSITYPE_MSI64 0x01
#define HV_MSIQSTATE_IDLE 0x00
#define HV_MSIQSTATE_ERROR 0x01
#define HV_MSIQ_INVALID 0x00
#define HV_MSIQ_VALID 0x01
#define HV_MSISTATE_IDLE 0x00
#define HV_MSISTATE_DELIVERED 0x01
#define HV_MSIVALID_INVALID 0x00
#define HV_MSIVALID_VALID 0x01
#define HV_PCIE_MSGTYPE_PME_MSG 0x18
#define HV_PCIE_MSGTYPE_PME_ACK_MSG 0x1b
#define HV_PCIE_MSGTYPE_CORR_MSG 0x30
#define HV_PCIE_MSGTYPE_NONFATAL_MSG 0x31
#define HV_PCIE_MSGTYPE_FATAL_MSG 0x33
#define HV_MSG_INVALID 0x00
#define HV_MSG_VALID 0x01
/* pci_msiq_conf()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_CONF
* ARG0: devhandle
* ARG1: msiqid
* ARG2: real address
* ARG3: number of entries
* RET0: status
* ERRORS: EINVAL Invalid devhandle, msiqid or nentries
* EBADALIGN Improperly aligned real address
* ENORADDR Bad real address
*
* Configure the MSI queue given by the devhandle and msiqid arguments,
* and to be placed at the given real address and be of the given
* number of entries. The real address must be aligned exactly to match
* the queue size. Each queue entry is 64-bytes long, so f.e. a 32 entry
* queue must be aligned on a 2048 byte real address boundary. The MSI-EQ
* Head and Tail are initialized so that the MSI-EQ is 'empty'.
*
* Implementation Note: Certain implementations have fixed sized queues. In
* that case, number of entries must contain the correct
* value.
*/
#define HV_FAST_PCI_MSIQ_CONF 0xc0
/* pci_msiq_info()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_INFO
* ARG0: devhandle
* ARG1: msiqid
* RET0: status
* RET1: real address
* RET2: number of entries
* ERRORS: EINVAL Invalid devhandle or msiqid
*
* Return the configuration information for the MSI queue described
* by the given devhandle and msiqid. The base address of the queue
* is returned in ARG1 and the number of entries is returned in ARG2.
* If the queue is unconfigured, the real address is undefined and the
* number of entries will be returned as zero.
*/
#define HV_FAST_PCI_MSIQ_INFO 0xc1
/* pci_msiq_getvalid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_GETVALID
* ARG0: devhandle
* ARG1: msiqid
* RET0: status
* RET1: msiqvalid (HV_MSIQ_VALID or HV_MSIQ_INVALID)
* ERRORS: EINVAL Invalid devhandle or msiqid
*
* Get the valid state of the MSI-EQ described by the given devhandle and
* msiqid.
*/
#define HV_FAST_PCI_MSIQ_GETVALID 0xc2
/* pci_msiq_setvalid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_SETVALID
* ARG0: devhandle
* ARG1: msiqid
* ARG2: msiqvalid (HV_MSIQ_VALID or HV_MSIQ_INVALID)
* RET0: status
* ERRORS: EINVAL Invalid devhandle or msiqid or msiqvalid
* value or MSI EQ is uninitialized
*
* Set the valid state of the MSI-EQ described by the given devhandle and
* msiqid to the given msiqvalid.
*/
#define HV_FAST_PCI_MSIQ_SETVALID 0xc3
/* pci_msiq_getstate()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_GETSTATE
* ARG0: devhandle
* ARG1: msiqid
* RET0: status
* RET1: msiqstate (HV_MSIQSTATE_IDLE or HV_MSIQSTATE_ERROR)
* ERRORS: EINVAL Invalid devhandle or msiqid
*
* Get the state of the MSI-EQ described by the given devhandle and
* msiqid.
*/
#define HV_FAST_PCI_MSIQ_GETSTATE 0xc4
/* pci_msiq_getvalid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_GETVALID
* ARG0: devhandle
* ARG1: msiqid
* ARG2: msiqstate (HV_MSIQSTATE_IDLE or HV_MSIQSTATE_ERROR)
* RET0: status
* ERRORS: EINVAL Invalid devhandle or msiqid or msiqstate
* value or MSI EQ is uninitialized
*
* Set the state of the MSI-EQ described by the given devhandle and
* msiqid to the given msiqvalid.
*/
#define HV_FAST_PCI_MSIQ_SETSTATE 0xc5
/* pci_msiq_gethead()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_GETHEAD
* ARG0: devhandle
* ARG1: msiqid
* RET0: status
* RET1: msiqhead
* ERRORS: EINVAL Invalid devhandle or msiqid
*
* Get the current MSI EQ queue head for the MSI-EQ described by the
* given devhandle and msiqid.
*/
#define HV_FAST_PCI_MSIQ_GETHEAD 0xc6
/* pci_msiq_sethead()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_SETHEAD
* ARG0: devhandle
* ARG1: msiqid
* ARG2: msiqhead
* RET0: status
* ERRORS: EINVAL Invalid devhandle or msiqid or msiqhead,
* or MSI EQ is uninitialized
*
* Set the current MSI EQ queue head for the MSI-EQ described by the
* given devhandle and msiqid.
*/
#define HV_FAST_PCI_MSIQ_SETHEAD 0xc7
/* pci_msiq_gettail()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSIQ_GETTAIL
* ARG0: devhandle
* ARG1: msiqid
* RET0: status
* RET1: msiqtail
* ERRORS: EINVAL Invalid devhandle or msiqid
*
* Get the current MSI EQ queue tail for the MSI-EQ described by the
* given devhandle and msiqid.
*/
#define HV_FAST_PCI_MSIQ_GETTAIL 0xc8
/* pci_msi_getvalid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSI_GETVALID
* ARG0: devhandle
* ARG1: msinum
* RET0: status
* RET1: msivalidstate
* ERRORS: EINVAL Invalid devhandle or msinum
*
* Get the current valid/enabled state for the MSI defined by the
* given devhandle and msinum.
*/
#define HV_FAST_PCI_MSI_GETVALID 0xc9
/* pci_msi_setvalid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSI_SETVALID
* ARG0: devhandle
* ARG1: msinum
* ARG2: msivalidstate
* RET0: status
* ERRORS: EINVAL Invalid devhandle or msinum or msivalidstate
*
* Set the current valid/enabled state for the MSI defined by the
* given devhandle and msinum.
*/
#define HV_FAST_PCI_MSI_SETVALID 0xca
/* pci_msi_getmsiq()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSI_GETMSIQ
* ARG0: devhandle
* ARG1: msinum
* RET0: status
* RET1: msiqid
* ERRORS: EINVAL Invalid devhandle or msinum or MSI is unbound
*
* Get the MSI EQ that the MSI defined by the given devhandle and
* msinum is bound to.
*/
#define HV_FAST_PCI_MSI_GETMSIQ 0xcb
/* pci_msi_setmsiq()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSI_SETMSIQ
* ARG0: devhandle
* ARG1: msinum
* ARG2: msitype
* ARG3: msiqid
* RET0: status
* ERRORS: EINVAL Invalid devhandle or msinum or msiqid
*
* Set the MSI EQ that the MSI defined by the given devhandle and
* msinum is bound to.
*/
#define HV_FAST_PCI_MSI_SETMSIQ 0xcc
/* pci_msi_getstate()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSI_GETSTATE
* ARG0: devhandle
* ARG1: msinum
* RET0: status
* RET1: msistate
* ERRORS: EINVAL Invalid devhandle or msinum
*
* Get the state of the MSI defined by the given devhandle and msinum.
* If not initialized, return HV_MSISTATE_IDLE.
*/
#define HV_FAST_PCI_MSI_GETSTATE 0xcd
/* pci_msi_setstate()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSI_SETSTATE
* ARG0: devhandle
* ARG1: msinum
* ARG2: msistate
* RET0: status
* ERRORS: EINVAL Invalid devhandle or msinum or msistate
*
* Set the state of the MSI defined by the given devhandle and msinum.
*/
#define HV_FAST_PCI_MSI_SETSTATE 0xce
/* pci_msg_getmsiq()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSG_GETMSIQ
* ARG0: devhandle
* ARG1: msgtype
* RET0: status
* RET1: msiqid
* ERRORS: EINVAL Invalid devhandle or msgtype
*
* Get the MSI EQ of the MSG defined by the given devhandle and msgtype.
*/
#define HV_FAST_PCI_MSG_GETMSIQ 0xd0
/* pci_msg_setmsiq()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSG_SETMSIQ
* ARG0: devhandle
* ARG1: msgtype
* ARG2: msiqid
* RET0: status
* ERRORS: EINVAL Invalid devhandle, msgtype, or msiqid
*
* Set the MSI EQ of the MSG defined by the given devhandle and msgtype.
*/
#define HV_FAST_PCI_MSG_SETMSIQ 0xd1
/* pci_msg_getvalid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSG_GETVALID
* ARG0: devhandle
* ARG1: msgtype
* RET0: status
* RET1: msgvalidstate
* ERRORS: EINVAL Invalid devhandle or msgtype
*
* Get the valid/enabled state of the MSG defined by the given
* devhandle and msgtype.
*/
#define HV_FAST_PCI_MSG_GETVALID 0xd2
/* pci_msg_setvalid()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_PCI_MSG_SETVALID
* ARG0: devhandle
* ARG1: msgtype
* ARG2: msgvalidstate
* RET0: status
* ERRORS: EINVAL Invalid devhandle or msgtype or msgvalidstate
*
* Set the valid/enabled state of the MSG defined by the given
* devhandle and msgtype.
*/
#define HV_FAST_PCI_MSG_SETVALID 0xd3
/* Logical Domain Channel services. */
#define LDC_CHANNEL_DOWN 0
#define LDC_CHANNEL_UP 1
#define LDC_CHANNEL_RESETTING 2
/* ldc_tx_qconf()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_TX_QCONF
* ARG0: channel ID
* ARG1: real address base of queue
* ARG2: num entries in queue
* RET0: status
*
* Configure transmit queue for the LDC endpoint specified by the
* given channel ID, to be placed at the given real address, and
* be of the given num entries. Num entries must be a power of two.
* The real address base of the queue must be aligned on the queue
* size. Each queue entry is 64-bytes, so for example, a 32 entry
* queue must be aligned on a 2048 byte real address boundary.
*
* Upon configuration of a valid transmit queue the head and tail
* pointers are set to a hypervisor specific identical value indicating
* that the queue initially is empty.
*
* The endpoint's transmit queue is un-configured if num entries is zero.
*
* The maximum number of entries for each queue for a specific cpu may be
* determined from the machine description. A transmit queue may be
* specified even in the event that the LDC is down (peer endpoint has no
* receive queue specified). Transmission will begin as soon as the peer
* endpoint defines a receive queue.
*
* It is recommended that a guest wait for a transmit queue to empty prior
* to reconfiguring it, or un-configuring it. Re or un-configuring of a
* non-empty transmit queue behaves exactly as defined above, however it
* is undefined as to how many of the pending entries in the original queue
* will be delivered prior to the re-configuration taking effect.
* Furthermore, as the queue configuration causes a reset of the head and
* tail pointers there is no way for a guest to determine how many entries
* have been sent after the configuration operation.
*/
#define HV_FAST_LDC_TX_QCONF 0xe0
/* ldc_tx_qinfo()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_TX_QINFO
* ARG0: channel ID
* RET0: status
* RET1: real address base of queue
* RET2: num entries in queue
*
* Return the configuration info for the transmit queue of LDC endpoint
* defined by the given channel ID. The real address is the currently
* defined real address base of the defined queue, and num entries is the
* size of the queue in terms of number of entries.
*
* If the specified channel ID is a valid endpoint number, but no transmit
* queue has been defined this service will return success, but with num
* entries set to zero and the real address will have an undefined value.
*/
#define HV_FAST_LDC_TX_QINFO 0xe1
/* ldc_tx_get_state()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_TX_GET_STATE
* ARG0: channel ID
* RET0: status
* RET1: head offset
* RET2: tail offset
* RET3: channel state
*
* Return the transmit state, and the head and tail queue pointers, for
* the transmit queue of the LDC endpoint defined by the given channel ID.
* The head and tail values are the byte offset of the head and tail
* positions of the transmit queue for the specified endpoint.
*/
#define HV_FAST_LDC_TX_GET_STATE 0xe2
/* ldc_tx_set_qtail()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_TX_SET_QTAIL
* ARG0: channel ID
* ARG1: tail offset
* RET0: status
*
* Update the tail pointer for the transmit queue associated with the LDC
* endpoint defined by the given channel ID. The tail offset specified
* must be aligned on a 64 byte boundary, and calculated so as to increase
* the number of pending entries on the transmit queue. Any attempt to
* decrease the number of pending transmit queue entires is considered
* an invalid tail offset and will result in an EINVAL error.
*
* Since the tail of the transmit queue may not be moved backwards, the
* transmit queue may be flushed by configuring a new transmit queue,
* whereupon the hypervisor will configure the initial transmit head and
* tail pointers to be equal.
*/
#define HV_FAST_LDC_TX_SET_QTAIL 0xe3
/* ldc_rx_qconf()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_RX_QCONF
* ARG0: channel ID
* ARG1: real address base of queue
* ARG2: num entries in queue
* RET0: status
*
* Configure receive queue for the LDC endpoint specified by the
* given channel ID, to be placed at the given real address, and
* be of the given num entries. Num entries must be a power of two.
* The real address base of the queue must be aligned on the queue
* size. Each queue entry is 64-bytes, so for example, a 32 entry
* queue must be aligned on a 2048 byte real address boundary.
*
* The endpoint's transmit queue is un-configured if num entries is zero.
*
* If a valid receive queue is specified for a local endpoint the LDC is
* in the up state for the purpose of transmission to this endpoint.
*
* The maximum number of entries for each queue for a specific cpu may be
* determined from the machine description.
*
* As receive queue configuration causes a reset of the queue's head and
* tail pointers there is no way for a gues to determine how many entries
* have been received between a preceeding ldc_get_rx_state() API call
* and the completion of the configuration operation. It should be noted
* that datagram delivery is not guarenteed via domain channels anyway,
* and therefore any higher protocol should be resilient to datagram
* loss if necessary. However, to overcome this specific race potential
* it is recommended, for example, that a higher level protocol be employed
* to ensure either retransmission, or ensure that no datagrams are pending
* on the peer endpoint's transmit queue prior to the configuration process.
*/
#define HV_FAST_LDC_RX_QCONF 0xe4
/* ldc_rx_qinfo()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_RX_QINFO
* ARG0: channel ID
* RET0: status
* RET1: real address base of queue
* RET2: num entries in queue
*
* Return the configuration info for the receive queue of LDC endpoint
* defined by the given channel ID. The real address is the currently
* defined real address base of the defined queue, and num entries is the
* size of the queue in terms of number of entries.
*
* If the specified channel ID is a valid endpoint number, but no receive
* queue has been defined this service will return success, but with num
* entries set to zero and the real address will have an undefined value.
*/
#define HV_FAST_LDC_RX_QINFO 0xe5
/* ldc_rx_get_state()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_RX_GET_STATE
* ARG0: channel ID
* RET0: status
* RET1: head offset
* RET2: tail offset
* RET3: channel state
*
* Return the receive state, and the head and tail queue pointers, for
* the receive queue of the LDC endpoint defined by the given channel ID.
* The head and tail values are the byte offset of the head and tail
* positions of the receive queue for the specified endpoint.
*/
#define HV_FAST_LDC_RX_GET_STATE 0xe6
/* ldc_rx_set_qhead()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_RX_SET_QHEAD
* ARG0: channel ID
* ARG1: head offset
* RET0: status
*
* Update the head pointer for the receive queue associated with the LDC
* endpoint defined by the given channel ID. The head offset specified
* must be aligned on a 64 byte boundary, and calculated so as to decrease
* the number of pending entries on the receive queue. Any attempt to
* increase the number of pending receive queue entires is considered
* an invalid head offset and will result in an EINVAL error.
*
* The receive queue may be flushed by setting the head offset equal
* to the current tail offset.
*/
#define HV_FAST_LDC_RX_SET_QHEAD 0xe7
/* LDC Map Table Entry. Each slot is defined by a translation table
* entry, as specified by the LDC_MTE_* bits below, and a 64-bit
* hypervisor invalidation cookie.
*/
#define LDC_MTE_PADDR 0x0fffffffffffe000 /* pa[55:13] */
#define LDC_MTE_COPY_W 0x0000000000000400 /* copy write access */
#define LDC_MTE_COPY_R 0x0000000000000200 /* copy read access */
#define LDC_MTE_IOMMU_W 0x0000000000000100 /* IOMMU write access */
#define LDC_MTE_IOMMU_R 0x0000000000000080 /* IOMMU read access */
#define LDC_MTE_EXEC 0x0000000000000040 /* execute */
#define LDC_MTE_WRITE 0x0000000000000020 /* read */
#define LDC_MTE_READ 0x0000000000000010 /* write */
#define LDC_MTE_SZALL 0x000000000000000f /* page size bits */
#define LDC_MTE_SZ16GB 0x0000000000000007 /* 16GB page */
#define LDC_MTE_SZ2GB 0x0000000000000006 /* 2GB page */
#define LDC_MTE_SZ256MB 0x0000000000000005 /* 256MB page */
#define LDC_MTE_SZ32MB 0x0000000000000004 /* 32MB page */
#define LDC_MTE_SZ4MB 0x0000000000000003 /* 4MB page */
#define LDC_MTE_SZ512K 0x0000000000000002 /* 512K page */
#define LDC_MTE_SZ64K 0x0000000000000001 /* 64K page */
#define LDC_MTE_SZ8K 0x0000000000000000 /* 8K page */
#ifndef __ASSEMBLY__
struct ldc_mtable_entry {
unsigned long mte;
unsigned long cookie;
};
#endif
/* ldc_set_map_table()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_SET_MAP_TABLE
* ARG0: channel ID
* ARG1: table real address
* ARG2: num entries
* RET0: status
*
* Register the MTE table at the given table real address, with the
* specified num entries, for the LDC indicated by the given channel
* ID.
*/
#define HV_FAST_LDC_SET_MAP_TABLE 0xea
/* ldc_get_map_table()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_GET_MAP_TABLE
* ARG0: channel ID
* RET0: status
* RET1: table real address
* RET2: num entries
*
* Return the configuration of the current mapping table registered
* for the given channel ID.
*/
#define HV_FAST_LDC_GET_MAP_TABLE 0xeb
#define LDC_COPY_IN 0
#define LDC_COPY_OUT 1
/* ldc_copy()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_COPY
* ARG0: channel ID
* ARG1: LDC_COPY_* direction code
* ARG2: target real address
* ARG3: local real address
* ARG4: length in bytes
* RET0: status
* RET1: actual length in bytes
*/
#define HV_FAST_LDC_COPY 0xec
#define LDC_MEM_READ 1
#define LDC_MEM_WRITE 2
#define LDC_MEM_EXEC 4
/* ldc_mapin()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_MAPIN
* ARG0: channel ID
* ARG1: cookie
* RET0: status
* RET1: real address
* RET2: LDC_MEM_* permissions
*/
#define HV_FAST_LDC_MAPIN 0xed
/* ldc_unmap()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_UNMAP
* ARG0: real address
* RET0: status
*/
#define HV_FAST_LDC_UNMAP 0xee
/* ldc_revoke()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_LDC_REVOKE
* ARG0: channel ID
* ARG1: cookie
* ARG2: ldc_mtable_entry cookie
* RET0: status
*/
#define HV_FAST_LDC_REVOKE 0xef
#ifndef __ASSEMBLY__
extern unsigned long sun4v_ldc_tx_qconf(unsigned long channel,
unsigned long ra,
unsigned long num_entries);
extern unsigned long sun4v_ldc_tx_qinfo(unsigned long channel,
unsigned long *ra,
unsigned long *num_entries);
extern unsigned long sun4v_ldc_tx_get_state(unsigned long channel,
unsigned long *head_off,
unsigned long *tail_off,
unsigned long *chan_state);
extern unsigned long sun4v_ldc_tx_set_qtail(unsigned long channel,
unsigned long tail_off);
extern unsigned long sun4v_ldc_rx_qconf(unsigned long channel,
unsigned long ra,
unsigned long num_entries);
extern unsigned long sun4v_ldc_rx_qinfo(unsigned long channel,
unsigned long *ra,
unsigned long *num_entries);
extern unsigned long sun4v_ldc_rx_get_state(unsigned long channel,
unsigned long *head_off,
unsigned long *tail_off,
unsigned long *chan_state);
extern unsigned long sun4v_ldc_rx_set_qhead(unsigned long channel,
unsigned long head_off);
extern unsigned long sun4v_ldc_set_map_table(unsigned long channel,
unsigned long ra,
unsigned long num_entries);
extern unsigned long sun4v_ldc_get_map_table(unsigned long channel,
unsigned long *ra,
unsigned long *num_entries);
extern unsigned long sun4v_ldc_copy(unsigned long channel,
unsigned long dir_code,
unsigned long tgt_raddr,
unsigned long lcl_raddr,
unsigned long len,
unsigned long *actual_len);
extern unsigned long sun4v_ldc_mapin(unsigned long channel,
unsigned long cookie,
unsigned long *ra,
unsigned long *perm);
extern unsigned long sun4v_ldc_unmap(unsigned long ra);
extern unsigned long sun4v_ldc_revoke(unsigned long channel,
unsigned long cookie,
unsigned long mte_cookie);
#endif
/* Performance counter services. */
#define HV_PERF_JBUS_PERF_CTRL_REG 0x00
#define HV_PERF_JBUS_PERF_CNT_REG 0x01
#define HV_PERF_DRAM_PERF_CTRL_REG_0 0x02
#define HV_PERF_DRAM_PERF_CNT_REG_0 0x03
#define HV_PERF_DRAM_PERF_CTRL_REG_1 0x04
#define HV_PERF_DRAM_PERF_CNT_REG_1 0x05
#define HV_PERF_DRAM_PERF_CTRL_REG_2 0x06
#define HV_PERF_DRAM_PERF_CNT_REG_2 0x07
#define HV_PERF_DRAM_PERF_CTRL_REG_3 0x08
#define HV_PERF_DRAM_PERF_CNT_REG_3 0x09
/* get_perfreg()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_GET_PERFREG
* ARG0: performance reg number
* RET0: status
* RET1: performance reg value
* ERRORS: EINVAL Invalid performance register number
* ENOACCESS No access allowed to performance counters
*
* Read the value of the given DRAM/JBUS performance counter/control register.
*/
#define HV_FAST_GET_PERFREG 0x100
/* set_perfreg()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_SET_PERFREG
* ARG0: performance reg number
* ARG1: performance reg value
* RET0: status
* ERRORS: EINVAL Invalid performance register number
* ENOACCESS No access allowed to performance counters
*
* Write the given performance reg value to the given DRAM/JBUS
* performance counter/control register.
*/
#define HV_FAST_SET_PERFREG 0x101
/* MMU statistics services.
*
* The hypervisor maintains MMU statistics and privileged code provides
* a buffer where these statistics can be collected. It is continually
* updated once configured. The layout is as follows:
*/
#ifndef __ASSEMBLY__
struct hv_mmu_statistics {
unsigned long immu_tsb_hits_ctx0_8k_tte;
unsigned long immu_tsb_ticks_ctx0_8k_tte;
unsigned long immu_tsb_hits_ctx0_64k_tte;
unsigned long immu_tsb_ticks_ctx0_64k_tte;
unsigned long __reserved1[2];
unsigned long immu_tsb_hits_ctx0_4mb_tte;
unsigned long immu_tsb_ticks_ctx0_4mb_tte;
unsigned long __reserved2[2];
unsigned long immu_tsb_hits_ctx0_256mb_tte;
unsigned long immu_tsb_ticks_ctx0_256mb_tte;
unsigned long __reserved3[4];
unsigned long immu_tsb_hits_ctxnon0_8k_tte;
unsigned long immu_tsb_ticks_ctxnon0_8k_tte;
unsigned long immu_tsb_hits_ctxnon0_64k_tte;
unsigned long immu_tsb_ticks_ctxnon0_64k_tte;
unsigned long __reserved4[2];
unsigned long immu_tsb_hits_ctxnon0_4mb_tte;
unsigned long immu_tsb_ticks_ctxnon0_4mb_tte;
unsigned long __reserved5[2];
unsigned long immu_tsb_hits_ctxnon0_256mb_tte;
unsigned long immu_tsb_ticks_ctxnon0_256mb_tte;
unsigned long __reserved6[4];
unsigned long dmmu_tsb_hits_ctx0_8k_tte;
unsigned long dmmu_tsb_ticks_ctx0_8k_tte;
unsigned long dmmu_tsb_hits_ctx0_64k_tte;
unsigned long dmmu_tsb_ticks_ctx0_64k_tte;
unsigned long __reserved7[2];
unsigned long dmmu_tsb_hits_ctx0_4mb_tte;
unsigned long dmmu_tsb_ticks_ctx0_4mb_tte;
unsigned long __reserved8[2];
unsigned long dmmu_tsb_hits_ctx0_256mb_tte;
unsigned long dmmu_tsb_ticks_ctx0_256mb_tte;
unsigned long __reserved9[4];
unsigned long dmmu_tsb_hits_ctxnon0_8k_tte;
unsigned long dmmu_tsb_ticks_ctxnon0_8k_tte;
unsigned long dmmu_tsb_hits_ctxnon0_64k_tte;
unsigned long dmmu_tsb_ticks_ctxnon0_64k_tte;
unsigned long __reserved10[2];
unsigned long dmmu_tsb_hits_ctxnon0_4mb_tte;
unsigned long dmmu_tsb_ticks_ctxnon0_4mb_tte;
unsigned long __reserved11[2];
unsigned long dmmu_tsb_hits_ctxnon0_256mb_tte;
unsigned long dmmu_tsb_ticks_ctxnon0_256mb_tte;
unsigned long __reserved12[4];
};
#endif
/* mmustat_conf()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMUSTAT_CONF
* ARG0: real address
* RET0: status
* RET1: real address
* ERRORS: ENORADDR Invalid real address
* EBADALIGN Real address not aligned on 64-byte boundary
* EBADTRAP API not supported on this processor
*
* Enable MMU statistic gathering using the buffer at the given real
* address on the current virtual CPU. The new buffer real address
* is given in ARG1, and the previously specified buffer real address
* is returned in RET1, or is returned as zero for the first invocation.
*
* If the passed in real address argument is zero, this will disable
* MMU statistic collection on the current virtual CPU. If an error is
* returned then no statistics are collected.
*
* The buffer contents should be initialized to all zeros before being
* given to the hypervisor or else the statistics will be meaningless.
*/
#define HV_FAST_MMUSTAT_CONF 0x102
/* mmustat_info()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_MMUSTAT_INFO
* RET0: status
* RET1: real address
* ERRORS: EBADTRAP API not supported on this processor
*
* Return the current state and real address of the currently configured
* MMU statistics buffer on the current virtual CPU.
*/
#define HV_FAST_MMUSTAT_INFO 0x103
#ifndef __ASSEMBLY__
extern unsigned long sun4v_mmustat_conf(unsigned long ra, unsigned long *orig_ra);
extern unsigned long sun4v_mmustat_info(unsigned long *ra);
#endif
/* NCS crypto services */
/* ncs_request() sub-function numbers */
#define HV_NCS_QCONF 0x01
#define HV_NCS_QTAIL_UPDATE 0x02
#ifndef __ASSEMBLY__
struct hv_ncs_queue_entry {
/* MAU Control Register */
unsigned long mau_control;
#define MAU_CONTROL_INV_PARITY 0x0000000000002000
#define MAU_CONTROL_STRAND 0x0000000000001800
#define MAU_CONTROL_BUSY 0x0000000000000400
#define MAU_CONTROL_INT 0x0000000000000200
#define MAU_CONTROL_OP 0x00000000000001c0
#define MAU_CONTROL_OP_SHIFT 6
#define MAU_OP_LOAD_MA_MEMORY 0x0
#define MAU_OP_STORE_MA_MEMORY 0x1
#define MAU_OP_MODULAR_MULT 0x2
#define MAU_OP_MODULAR_REDUCE 0x3
#define MAU_OP_MODULAR_EXP_LOOP 0x4
#define MAU_CONTROL_LEN 0x000000000000003f
#define MAU_CONTROL_LEN_SHIFT 0
/* Real address of bytes to load or store bytes
* into/out-of the MAU.
*/
unsigned long mau_mpa;
/* Modular Arithmetic MA Offset Register. */
unsigned long mau_ma;
/* Modular Arithmetic N Prime Register. */
unsigned long mau_np;
};
struct hv_ncs_qconf_arg {
unsigned long mid; /* MAU ID, 1 per core on Niagara */
unsigned long base; /* Real address base of queue */
unsigned long end; /* Real address end of queue */
unsigned long num_ents; /* Number of entries in queue */
};
struct hv_ncs_qtail_update_arg {
unsigned long mid; /* MAU ID, 1 per core on Niagara */
unsigned long tail; /* New tail index to use */
unsigned long syncflag; /* only SYNCFLAG_SYNC is implemented */
#define HV_NCS_SYNCFLAG_SYNC 0x00
#define HV_NCS_SYNCFLAG_ASYNC 0x01
};
#endif
/* ncs_request()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_FAST_NCS_REQUEST
* ARG0: NCS sub-function
* ARG1: sub-function argument real address
* ARG2: size in bytes of sub-function argument
* RET0: status
*
* The MAU chip of the Niagara processor is not directly accessible
* to privileged code, instead it is programmed indirectly via this
* hypervisor API.
*
* The interfaces defines a queue of MAU operations to perform.
* Privileged code registers a queue with the hypervisor by invoking
* this HVAPI with the HV_NCS_QCONF sub-function, which defines the
* base, end, and number of entries of the queue. Each queue entry
* contains a MAU register struct block.
*
* The privileged code then proceeds to add entries to the queue and
* then invoke the HV_NCS_QTAIL_UPDATE sub-function. Since only
* synchronous operations are supported by the current hypervisor,
* HV_NCS_QTAIL_UPDATE will run all the pending queue entries to
* completion and return HV_EOK, or return an error code.
*
* The real address of the sub-function argument must be aligned on at
* least an 8-byte boundary.
*
* The tail argument of HV_NCS_QTAIL_UPDATE is an index, not a byte
* offset, into the queue and must be less than or equal the 'num_ents'
* argument given in the HV_NCS_QCONF call.
*/
#define HV_FAST_NCS_REQUEST 0x110
#ifndef __ASSEMBLY__
extern unsigned long sun4v_ncs_request(unsigned long request,
unsigned long arg_ra,
unsigned long arg_size);
#endif
#define HV_FAST_FIRE_GET_PERFREG 0x120
#define HV_FAST_FIRE_SET_PERFREG 0x121
/* Function numbers for HV_CORE_TRAP. */
#define HV_CORE_SET_VER 0x00
#define HV_CORE_PUTCHAR 0x01
#define HV_CORE_EXIT 0x02
#define HV_CORE_GET_VER 0x03
/* Hypervisor API groups for use with HV_CORE_SET_VER and
* HV_CORE_GET_VER.
*/
#define HV_GRP_SUN4V 0x0000
#define HV_GRP_CORE 0x0001
#define HV_GRP_INTR 0x0002
#define HV_GRP_SOFT_STATE 0x0003
#define HV_GRP_PCI 0x0100
#define HV_GRP_LDOM 0x0101
#define HV_GRP_SVC_CHAN 0x0102
#define HV_GRP_NCS 0x0103
#define HV_GRP_NIAG_PERF 0x0200
#define HV_GRP_FIRE_PERF 0x0201
#define HV_GRP_DIAG 0x0300
#ifndef __ASSEMBLY__
extern unsigned long sun4v_get_version(unsigned long group,
unsigned long *major,
unsigned long *minor);
extern unsigned long sun4v_set_version(unsigned long group,
unsigned long major,
unsigned long minor,
unsigned long *actual_minor);
extern int sun4v_hvapi_register(unsigned long group, unsigned long major,
unsigned long *minor);
extern void sun4v_hvapi_unregister(unsigned long group);
extern int sun4v_hvapi_get(unsigned long group,
unsigned long *major,
unsigned long *minor);
extern void sun4v_hvapi_init(void);
#endif
#endif /* !(_SPARC64_HYPERVISOR_H) */
#include <asm-sparc/hypervisor.h>
#ifndef _SPARC64_INTR_QUEUE_H
#define _SPARC64_INTR_QUEUE_H
/* Sun4v interrupt queue registers, accessed via ASI_QUEUE. */
#define INTRQ_CPU_MONDO_HEAD 0x3c0 /* CPU mondo head */
#define INTRQ_CPU_MONDO_TAIL 0x3c8 /* CPU mondo tail */
#define INTRQ_DEVICE_MONDO_HEAD 0x3d0 /* Device mondo head */
#define INTRQ_DEVICE_MONDO_TAIL 0x3d8 /* Device mondo tail */
#define INTRQ_RESUM_MONDO_HEAD 0x3e0 /* Resumable error mondo head */
#define INTRQ_RESUM_MONDO_TAIL 0x3e8 /* Resumable error mondo tail */
#define INTRQ_NONRESUM_MONDO_HEAD 0x3f0 /* Non-resumable error mondo head */
#define INTRQ_NONRESUM_MONDO_TAIL 0x3f8 /* Non-resumable error mondo head */
#endif /* !(_SPARC64_INTR_QUEUE_H) */
#include <asm-sparc/intr_queue.h>
#ifndef _SPARC64_KPROBES_H
#define _SPARC64_KPROBES_H
#include <linux/types.h>
#include <linux/percpu.h>
typedef u32 kprobe_opcode_t;
#define BREAKPOINT_INSTRUCTION 0x91d02070 /* ta 0x70 */
#define BREAKPOINT_INSTRUCTION_2 0x91d02071 /* ta 0x71 */
#define MAX_INSN_SIZE 2
#define kretprobe_blacklist_size 0
#define arch_remove_kprobe(p) do {} while (0)
#define flush_insn_slot(p) \
do { flushi(&(p)->ainsn.insn[0]); \
flushi(&(p)->ainsn.insn[1]); \
} while (0)
void kretprobe_trampoline(void);
/* Architecture specific copy of original instruction*/
struct arch_specific_insn {
/* copy of the original instruction */
kprobe_opcode_t insn[MAX_INSN_SIZE];
};
struct prev_kprobe {
struct kprobe *kp;
unsigned long status;
unsigned long orig_tnpc;
unsigned long orig_tstate_pil;
};
/* per-cpu kprobe control block */
struct kprobe_ctlblk {
unsigned long kprobe_status;
unsigned long kprobe_orig_tnpc;
unsigned long kprobe_orig_tstate_pil;
struct pt_regs jprobe_saved_regs;
struct prev_kprobe prev_kprobe;
};
extern int kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data);
extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
#endif /* _SPARC64_KPROBES_H */
#include <asm-sparc/kprobes.h>
#ifndef _SPARC64_LDC_H
#define _SPARC64_LDC_H
#include <asm/hypervisor.h>
extern int ldom_domaining_enabled;
extern void ldom_set_var(const char *var, const char *value);
extern void ldom_reboot(const char *boot_command);
extern void ldom_power_off(void);
/* The event handler will be evoked when link state changes
* or data becomes available on the receive side.
*
* For non-RAW links, if the LDC_EVENT_RESET event arrives the
* driver should reset all of it's internal state and reinvoke
* ldc_connect() to try and bring the link up again.
*
* For RAW links, ldc_connect() is not used. Instead the driver
* just waits for the LDC_EVENT_UP event.
*/
struct ldc_channel_config {
void (*event)(void *arg, int event);
u32 mtu;
unsigned int rx_irq;
unsigned int tx_irq;
u8 mode;
#define LDC_MODE_RAW 0x00
#define LDC_MODE_UNRELIABLE 0x01
#define LDC_MODE_RESERVED 0x02
#define LDC_MODE_STREAM 0x03
u8 debug;
#define LDC_DEBUG_HS 0x01
#define LDC_DEBUG_STATE 0x02
#define LDC_DEBUG_RX 0x04
#define LDC_DEBUG_TX 0x08
#define LDC_DEBUG_DATA 0x10
};
#define LDC_EVENT_RESET 0x01
#define LDC_EVENT_UP 0x02
#define LDC_EVENT_DATA_READY 0x04
#define LDC_STATE_INVALID 0x00
#define LDC_STATE_INIT 0x01
#define LDC_STATE_BOUND 0x02
#define LDC_STATE_READY 0x03
#define LDC_STATE_CONNECTED 0x04
struct ldc_channel;
/* Allocate state for a channel. */
extern struct ldc_channel *ldc_alloc(unsigned long id,
const struct ldc_channel_config *cfgp,
void *event_arg);
/* Shut down and free state for a channel. */
extern void ldc_free(struct ldc_channel *lp);
/* Register TX and RX queues of the link with the hypervisor. */
extern int ldc_bind(struct ldc_channel *lp, const char *name);
/* For non-RAW protocols we need to complete a handshake before
* communication can proceed. ldc_connect() does that, if the
* handshake completes successfully, an LDC_EVENT_UP event will
* be sent up to the driver.
*/
extern int ldc_connect(struct ldc_channel *lp);
extern int ldc_disconnect(struct ldc_channel *lp);
extern int ldc_state(struct ldc_channel *lp);
/* Read and write operations. Only valid when the link is up. */
extern int ldc_write(struct ldc_channel *lp, const void *buf,
unsigned int size);
extern int ldc_read(struct ldc_channel *lp, void *buf, unsigned int size);
#define LDC_MAP_SHADOW 0x01
#define LDC_MAP_DIRECT 0x02
#define LDC_MAP_IO 0x04
#define LDC_MAP_R 0x08
#define LDC_MAP_W 0x10
#define LDC_MAP_X 0x20
#define LDC_MAP_RW (LDC_MAP_R | LDC_MAP_W)
#define LDC_MAP_RWX (LDC_MAP_R | LDC_MAP_W | LDC_MAP_X)
#define LDC_MAP_ALL 0x03f
struct ldc_trans_cookie {
u64 cookie_addr;
u64 cookie_size;
};
struct scatterlist;
extern int ldc_map_sg(struct ldc_channel *lp,
struct scatterlist *sg, int num_sg,
struct ldc_trans_cookie *cookies, int ncookies,
unsigned int map_perm);
extern int ldc_map_single(struct ldc_channel *lp,
void *buf, unsigned int len,
struct ldc_trans_cookie *cookies, int ncookies,
unsigned int map_perm);
extern void ldc_unmap(struct ldc_channel *lp, struct ldc_trans_cookie *cookies,
int ncookies);
extern int ldc_copy(struct ldc_channel *lp, int copy_dir,
void *buf, unsigned int len, unsigned long offset,
struct ldc_trans_cookie *cookies, int ncookies);
static inline int ldc_get_dring_entry(struct ldc_channel *lp,
void *buf, unsigned int len,
unsigned long offset,
struct ldc_trans_cookie *cookies,
int ncookies)
{
return ldc_copy(lp, LDC_COPY_IN, buf, len, offset, cookies, ncookies);
}
static inline int ldc_put_dring_entry(struct ldc_channel *lp,
void *buf, unsigned int len,
unsigned long offset,
struct ldc_trans_cookie *cookies,
int ncookies)
{
return ldc_copy(lp, LDC_COPY_OUT, buf, len, offset, cookies, ncookies);
}
extern void *ldc_alloc_exp_dring(struct ldc_channel *lp, unsigned int len,
struct ldc_trans_cookie *cookies,
int *ncookies, unsigned int map_perm);
extern void ldc_free_exp_dring(struct ldc_channel *lp, void *buf,
unsigned int len,
struct ldc_trans_cookie *cookies, int ncookies);
#endif /* _SPARC64_LDC_H */
#include <asm-sparc/ldc.h>
#ifndef _SPARC64_LMB_H
#define _SPARC64_LMB_H
#include <asm/oplib.h>
#define LMB_DBG(fmt...) prom_printf(fmt)
#define LMB_REAL_LIMIT 0
#endif /* !(_SPARC64_LMB_H) */
#include <asm-sparc/lmb.h>
#ifndef _SPARC64_LSU_H
#define _SPARC64_LSU_H
#include <linux/const.h>
/* LSU Control Register */
#define LSU_CONTROL_PM _AC(0x000001fe00000000,UL) /* Phys-watchpoint byte mask*/
#define LSU_CONTROL_VM _AC(0x00000001fe000000,UL) /* Virt-watchpoint byte mask*/
#define LSU_CONTROL_PR _AC(0x0000000001000000,UL) /* Phys-rd watchpoint enable*/
#define LSU_CONTROL_PW _AC(0x0000000000800000,UL) /* Phys-wr watchpoint enable*/
#define LSU_CONTROL_VR _AC(0x0000000000400000,UL) /* Virt-rd watchpoint enable*/
#define LSU_CONTROL_VW _AC(0x0000000000200000,UL) /* Virt-wr watchpoint enable*/
#define LSU_CONTROL_FM _AC(0x00000000000ffff0,UL) /* Parity mask enables. */
#define LSU_CONTROL_DM _AC(0x0000000000000008,UL) /* Data MMU enable. */
#define LSU_CONTROL_IM _AC(0x0000000000000004,UL) /* Instruction MMU enable. */
#define LSU_CONTROL_DC _AC(0x0000000000000002,UL) /* Data cache enable. */
#define LSU_CONTROL_IC _AC(0x0000000000000001,UL) /* Instruction cache enable.*/
#endif /* !(_SPARC64_LSU_H) */
#include <asm-sparc/lsu.h>
#ifndef _SPARC64_MDESC_H
#define _SPARC64_MDESC_H
#include <linux/types.h>
#include <linux/cpumask.h>
#include <asm/prom.h>
struct mdesc_handle;
/* Machine description operations are to be surrounded by grab and
* release calls. The mdesc_handle returned from the grab is
* the first argument to all of the operational calls that work
* on mdescs.
*/
extern struct mdesc_handle *mdesc_grab(void);
extern void mdesc_release(struct mdesc_handle *);
#define MDESC_NODE_NULL (~(u64)0)
extern u64 mdesc_node_by_name(struct mdesc_handle *handle,
u64 from_node, const char *name);
#define mdesc_for_each_node_by_name(__hdl, __node, __name) \
for (__node = mdesc_node_by_name(__hdl, MDESC_NODE_NULL, __name); \
(__node) != MDESC_NODE_NULL; \
__node = mdesc_node_by_name(__hdl, __node, __name))
/* Access to property values returned from mdesc_get_property() are
* only valid inside of a mdesc_grab()/mdesc_release() sequence.
* Once mdesc_release() is called, the memory backed up by these
* pointers may reference freed up memory.
*
* Therefore callers must make copies of any property values
* they need.
*
* These same rules apply to mdesc_node_name().
*/
extern const void *mdesc_get_property(struct mdesc_handle *handle,
u64 node, const char *name, int *lenp);
extern const char *mdesc_node_name(struct mdesc_handle *hp, u64 node);
/* MD arc iteration, the standard sequence is:
*
* unsigned long arc;
* mdesc_for_each_arc(arc, handle, node, MDESC_ARC_TYPE_{FWD,BACK}) {
* unsigned long target = mdesc_arc_target(handle, arc);
* ...
* }
*/
#define MDESC_ARC_TYPE_FWD "fwd"
#define MDESC_ARC_TYPE_BACK "back"
extern u64 mdesc_next_arc(struct mdesc_handle *handle, u64 from,
const char *arc_type);
#define mdesc_for_each_arc(__arc, __hdl, __node, __type) \
for (__arc = mdesc_next_arc(__hdl, __node, __type); \
(__arc) != MDESC_NODE_NULL; \
__arc = mdesc_next_arc(__hdl, __arc, __type))
extern u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc);
extern void mdesc_update(void);
struct mdesc_notifier_client {
void (*add)(struct mdesc_handle *handle, u64 node);
void (*remove)(struct mdesc_handle *handle, u64 node);
const char *node_name;
struct mdesc_notifier_client *next;
};
extern void mdesc_register_notifier(struct mdesc_notifier_client *client);
extern void mdesc_fill_in_cpu_data(cpumask_t mask);
extern void sun4v_mdesc_init(void);
#endif
#include <asm-sparc/mdesc.h>
#ifndef _SPARC64_MMZONE_H
#define _SPARC64_MMZONE_H
#ifdef CONFIG_NEED_MULTIPLE_NODES
extern struct pglist_data *node_data[];
#define NODE_DATA(nid) (node_data[nid])
#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
#define node_end_pfn(nid) (NODE_DATA(nid)->node_end_pfn)
extern int numa_cpu_lookup_table[];
extern cpumask_t numa_cpumask_lookup_table[];
#endif /* CONFIG_NEED_MULTIPLE_NODES */
#endif /* _SPARC64_MMZONE_H */
#include <asm-sparc/mmzone.h>
/* ns87303.h: Configuration Register Description for the
* National Semiconductor PC87303 (SuperIO).
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
*/
#ifndef _SPARC_NS87303_H
#define _SPARC_NS87303_H 1
/*
* Control Register Index Values
*/
#define FER 0x00
#define FAR 0x01
#define PTR 0x02
#define FCR 0x03
#define PCR 0x04
#define KRR 0x05
#define PMC 0x06
#define TUP 0x07
#define SID 0x08
#define ASC 0x09
#define CS0CF0 0x0a
#define CS0CF1 0x0b
#define CS1CF0 0x0c
#define CS1CF1 0x0d
/* Function Enable Register (FER) bits */
#define FER_EDM 0x10 /* Encoded Drive and Motor pin information */
/* Function Address Register (FAR) bits */
#define FAR_LPT_MASK 0x03
#define FAR_LPTB 0x00
#define FAR_LPTA 0x01
#define FAR_LPTC 0x02
/* Power and Test Register (PTR) bits */
#define PTR_LPTB_IRQ7 0x08
#define PTR_LEVEL_IRQ 0x80 /* When not ECP/EPP: Use level IRQ */
#define PTR_LPT_REG_DIR 0x80 /* When ECP/EPP: LPT CTR controlls direction */
/* of the parallel port */
/* Function Control Register (FCR) bits */
#define FCR_LDE 0x10 /* Logical Drive Exchange */
#define FCR_ZWS_ENA 0x20 /* Enable short host read/write in ECP/EPP */
/* Printer Control Register (PCR) bits */
#define PCR_EPP_ENABLE 0x01
#define PCR_EPP_IEEE 0x02 /* Enable EPP Version 1.9 (IEEE 1284) */
#define PCR_ECP_ENABLE 0x04
#define PCR_ECP_CLK_ENA 0x08 /* If 0 ECP Clock is stopped on Power down */
#define PCR_IRQ_POLAR 0x20 /* If 0 IRQ is level high or negative pulse, */
/* if 1 polarity is inverted */
#define PCR_IRQ_ODRAIN 0x40 /* If 1, IRQ is open drain */
/* Tape UARTs and Parallel Port Config Register (TUP) bits */
#define TUP_EPP_TIMO 0x02 /* Enable EPP timeout IRQ */
/* Advanced SuperIO Config Register (ASC) bits */
#define ASC_LPT_IRQ7 0x01 /* Always use IRQ7 for LPT */
#define ASC_DRV2_SEL 0x02 /* Logical Drive Exchange controlled by TDR */
#define FER_RESERVED 0x00
#define FAR_RESERVED 0x00
#define PTR_RESERVED 0x73
#define FCR_RESERVED 0xc4
#define PCR_RESERVED 0x10
#define KRR_RESERVED 0x00
#define PMC_RESERVED 0x98
#define TUP_RESERVED 0xfb
#define SIP_RESERVED 0x00
#define ASC_RESERVED 0x18
#define CS0CF0_RESERVED 0x00
#define CS0CF1_RESERVED 0x08
#define CS1CF0_RESERVED 0x00
#define CS1CF1_RESERVED 0x08
#ifdef __KERNEL__
#include <linux/spinlock.h>
#include <asm/system.h>
#include <asm/io.h>
extern spinlock_t ns87303_lock;
static inline int ns87303_modify(unsigned long port, unsigned int index,
unsigned char clr, unsigned char set)
{
static unsigned char reserved[] = {
FER_RESERVED, FAR_RESERVED, PTR_RESERVED, FCR_RESERVED,
PCR_RESERVED, KRR_RESERVED, PMC_RESERVED, TUP_RESERVED,
SIP_RESERVED, ASC_RESERVED, CS0CF0_RESERVED, CS0CF1_RESERVED,
CS1CF0_RESERVED, CS1CF1_RESERVED
};
unsigned long flags;
unsigned char value;
if (index > 0x0d)
return -EINVAL;
spin_lock_irqsave(&ns87303_lock, flags);
outb(index, port);
value = inb(port + 1);
value &= ~(reserved[index] | clr);
value |= set;
outb(value, port + 1);
outb(value, port + 1);
spin_unlock_irqrestore(&ns87303_lock, flags);
return 0;
}
#endif /* __KERNEL__ */
#endif /* !(_SPARC_NS87303_H) */
#include <asm-sparc/ns87303.h>
/* parport.h: sparc64 specific parport initialization and dma.
*
* Copyright (C) 1999 Eddie C. Dost (ecd@skynet.be)
*/
#ifndef _ASM_SPARC64_PARPORT_H
#define _ASM_SPARC64_PARPORT_H 1
#include <asm/ebus.h>
#include <asm/ns87303.h>
#include <asm/of_device.h>
#include <asm/prom.h>
#define PARPORT_PC_MAX_PORTS PARPORT_MAX
/*
* While sparc64 doesn't have an ISA DMA API, we provide something that looks
* close enough to make parport_pc happy
*/
#define HAS_DMA
static DEFINE_SPINLOCK(dma_spin_lock);
#define claim_dma_lock() \
({ unsigned long flags; \
spin_lock_irqsave(&dma_spin_lock, flags); \
flags; \
})
#define release_dma_lock(__flags) \
spin_unlock_irqrestore(&dma_spin_lock, __flags);
static struct sparc_ebus_info {
struct ebus_dma_info info;
unsigned int addr;
unsigned int count;
int lock;
struct parport *port;
} sparc_ebus_dmas[PARPORT_PC_MAX_PORTS];
static DECLARE_BITMAP(dma_slot_map, PARPORT_PC_MAX_PORTS);
static inline int request_dma(unsigned int dmanr, const char *device_id)
{
if (dmanr >= PARPORT_PC_MAX_PORTS)
return -EINVAL;
if (xchg(&sparc_ebus_dmas[dmanr].lock, 1) != 0)
return -EBUSY;
return 0;
}
static inline void free_dma(unsigned int dmanr)
{
if (dmanr >= PARPORT_PC_MAX_PORTS) {
printk(KERN_WARNING "Trying to free DMA%d\n", dmanr);
return;
}
if (xchg(&sparc_ebus_dmas[dmanr].lock, 0) == 0) {
printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr);
return;
}
}
static inline void enable_dma(unsigned int dmanr)
{
ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1);
if (ebus_dma_request(&sparc_ebus_dmas[dmanr].info,
sparc_ebus_dmas[dmanr].addr,
sparc_ebus_dmas[dmanr].count))
BUG();
}
static inline void disable_dma(unsigned int dmanr)
{
ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 0);
}
static inline void clear_dma_ff(unsigned int dmanr)
{
/* nothing */
}
static inline void set_dma_mode(unsigned int dmanr, char mode)
{
ebus_dma_prepare(&sparc_ebus_dmas[dmanr].info, (mode != DMA_MODE_WRITE));
}
static inline void set_dma_addr(unsigned int dmanr, unsigned int addr)
{
sparc_ebus_dmas[dmanr].addr = addr;
}
static inline void set_dma_count(unsigned int dmanr, unsigned int count)
{
sparc_ebus_dmas[dmanr].count = count;
}
static inline unsigned int get_dma_residue(unsigned int dmanr)
{
return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info);
}
static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id *match)
{
unsigned long base = op->resource[0].start;
unsigned long config = op->resource[1].start;
unsigned long d_base = op->resource[2].start;
unsigned long d_len;
struct device_node *parent;
struct parport *p;
int slot, err;
parent = op->node->parent;
if (!strcmp(parent->name, "dma")) {
p = parport_pc_probe_port(base, base + 0x400,
op->irqs[0], PARPORT_DMA_NOFIFO,
op->dev.parent->parent);
if (!p)
return -ENOMEM;
dev_set_drvdata(&op->dev, p);
return 0;
}
for (slot = 0; slot < PARPORT_PC_MAX_PORTS; slot++) {
if (!test_and_set_bit(slot, dma_slot_map))
break;
}
err = -ENODEV;
if (slot >= PARPORT_PC_MAX_PORTS)
goto out_err;
spin_lock_init(&sparc_ebus_dmas[slot].info.lock);
d_len = (op->resource[2].end - d_base) + 1UL;
sparc_ebus_dmas[slot].info.regs =
of_ioremap(&op->resource[2], 0, d_len, "ECPP DMA");
if (!sparc_ebus_dmas[slot].info.regs)
goto out_clear_map;
sparc_ebus_dmas[slot].info.flags = 0;
sparc_ebus_dmas[slot].info.callback = NULL;
sparc_ebus_dmas[slot].info.client_cookie = NULL;
sparc_ebus_dmas[slot].info.irq = 0xdeadbeef;
strcpy(sparc_ebus_dmas[slot].info.name, "parport");
if (ebus_dma_register(&sparc_ebus_dmas[slot].info))
goto out_unmap_regs;
ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 1);
/* Configure IRQ to Push Pull, Level Low */
/* Enable ECP, set bit 2 of the CTR first */
outb(0x04, base + 0x02);
ns87303_modify(config, PCR,
PCR_EPP_ENABLE |
PCR_IRQ_ODRAIN,
PCR_ECP_ENABLE |
PCR_ECP_CLK_ENA |
PCR_IRQ_POLAR);
/* CTR bit 5 controls direction of port */
ns87303_modify(config, PTR,
0, PTR_LPT_REG_DIR);
p = parport_pc_probe_port(base, base + 0x400,
op->irqs[0],
slot,
op->dev.parent);
err = -ENOMEM;
if (!p)
goto out_disable_irq;
dev_set_drvdata(&op->dev, p);
return 0;
out_disable_irq:
ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
out_unmap_regs:
of_iounmap(&op->resource[2], sparc_ebus_dmas[slot].info.regs, d_len);
out_clear_map:
clear_bit(slot, dma_slot_map);
out_err:
return err;
}
static int __devexit ecpp_remove(struct of_device *op)
{
struct parport *p = dev_get_drvdata(&op->dev);
int slot = p->dma;
parport_pc_unregister_port(p);
if (slot != PARPORT_DMA_NOFIFO) {
unsigned long d_base = op->resource[2].start;
unsigned long d_len;
d_len = (op->resource[2].end - d_base) + 1UL;
ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
of_iounmap(&op->resource[2],
sparc_ebus_dmas[slot].info.regs,
d_len);
clear_bit(slot, dma_slot_map);
}
return 0;
}
static struct of_device_id ecpp_match[] = {
{
.name = "ecpp",
},
{
.name = "parallel",
.compatible = "ecpp",
},
{
.name = "parallel",
.compatible = "ns87317-ecpp",
},
{},
};
static struct of_platform_driver ecpp_driver = {
.name = "ecpp",
.match_table = ecpp_match,
.probe = ecpp_probe,
.remove = __devexit_p(ecpp_remove),
};
static int parport_pc_find_nonpci_ports(int autoirq, int autodma)
{
of_register_driver(&ecpp_driver, &of_bus_type);
return 0;
}
#endif /* !(_ASM_SPARC64_PARPORT_H */
#include <asm-sparc/parport.h>
#ifndef _SPARC64_PIL_H
#define _SPARC64_PIL_H
/* To avoid some locking problems, we hard allocate certain PILs
* for SMP cross call messages that must do a etrap/rtrap.
*
* A local_irq_disable() does not block the cross call delivery, so
* when SMP locking is an issue we reschedule the event into a PIL
* interrupt which is blocked by local_irq_disable().
*
* In fact any XCALL which has to etrap/rtrap has a problem because
* it is difficult to prevent rtrap from running BH's, and that would
* need to be done if the XCALL arrived while %pil==15.
*/
#define PIL_SMP_CALL_FUNC 1
#define PIL_SMP_RECEIVE_SIGNAL 2
#define PIL_SMP_CAPTURE 3
#define PIL_SMP_CTX_NEW_VERSION 4
#define PIL_DEVICE_IRQ 5
#endif /* !(_SPARC64_PIL_H) */
#include <asm-sparc/pil.h>
#ifndef _SPARC64_REBOOT_H
#define _SPARC64_REBOOT_H
extern void machine_alt_power_off(void);
#endif /* _SPARC64_REBOOT_H */
#include <asm-sparc/reboot.h>
/* rwsem-const.h: RW semaphore counter constants. */
#ifndef _SPARC64_RWSEM_CONST_H
#define _SPARC64_RWSEM_CONST_H
#define RWSEM_UNLOCKED_VALUE 0x00000000
#define RWSEM_ACTIVE_BIAS 0x00000001
#define RWSEM_ACTIVE_MASK 0x0000ffff
#define RWSEM_WAITING_BIAS 0xffff0000
#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
#endif /* _SPARC64_RWSEM_CONST_H */
#include <asm-sparc/rwsem-const.h>
/*
* rwsem.h: R/W semaphores implemented using CAS
*
* Written by David S. Miller (davem@redhat.com), 2001.
* Derived from asm-i386/rwsem.h
*/
#ifndef _SPARC64_RWSEM_H
#define _SPARC64_RWSEM_H
#ifndef _LINUX_RWSEM_H
#error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead"
#endif
#ifdef __KERNEL__
#include <linux/list.h>
#include <linux/spinlock.h>
#include <asm/rwsem-const.h>
struct rwsem_waiter;
struct rw_semaphore {
signed int count;
spinlock_t wait_lock;
struct list_head wait_list;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
};
#ifdef CONFIG_DEBUG_LOCK_ALLOC
# define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname }
#else
# define __RWSEM_DEP_MAP_INIT(lockname)
#endif
#define __RWSEM_INITIALIZER(name) \
{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) \
__RWSEM_DEP_MAP_INIT(name) }
#define DECLARE_RWSEM(name) \
struct rw_semaphore name = __RWSEM_INITIALIZER(name)
extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
struct lock_class_key *key);
#define init_rwsem(sem) \
do { \
static struct lock_class_key __key; \
\
__init_rwsem((sem), #sem, &__key); \
} while (0)
extern void __down_read(struct rw_semaphore *sem);
extern int __down_read_trylock(struct rw_semaphore *sem);
extern void __down_write(struct rw_semaphore *sem);
extern int __down_write_trylock(struct rw_semaphore *sem);
extern void __up_read(struct rw_semaphore *sem);
extern void __up_write(struct rw_semaphore *sem);
extern void __downgrade_write(struct rw_semaphore *sem);
static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
{
__down_write(sem);
}
static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
{
return atomic_add_return(delta, (atomic_t *)(&sem->count));
}
static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
{
atomic_add(delta, (atomic_t *)(&sem->count));
}
static inline int rwsem_is_locked(struct rw_semaphore *sem)
{
return (sem->count != 0);
}
#endif /* __KERNEL__ */
#endif /* _SPARC64_RWSEM_H */
#include <asm-sparc/rwsem.h>
#ifndef _SPARC64_SCRATCHPAD_H
#define _SPARC64_SCRATCHPAD_H
/* Sun4v scratchpad registers, accessed via ASI_SCRATCHPAD. */
#define SCRATCHPAD_MMU_MISS 0x00 /* Shared with OBP - set by OBP */
#define SCRATCHPAD_CPUID 0x08 /* Shared with OBP - set by hypervisor */
#define SCRATCHPAD_UTSBREG1 0x10
#define SCRATCHPAD_UTSBREG2 0x18
/* 0x20 and 0x28, hypervisor only... */
#define SCRATCHPAD_UNUSED1 0x30
#define SCRATCHPAD_UNUSED2 0x38 /* Reserved for OBP */
#endif /* !(_SPARC64_SCRATCHPAD_H) */
#include <asm-sparc/scratchpad.h>
#ifndef _ASM_SECCOMP_H
#include <linux/thread_info.h> /* already defines TIF_32BIT */
#ifndef TIF_32BIT
#error "unexpected TIF_32BIT on sparc64"
#endif
#include <linux/unistd.h>
#define __NR_seccomp_read __NR_read
#define __NR_seccomp_write __NR_write
#define __NR_seccomp_exit __NR_exit
#define __NR_seccomp_sigreturn __NR_rt_sigreturn
#define __NR_seccomp_read_32 __NR_read
#define __NR_seccomp_write_32 __NR_write
#define __NR_seccomp_exit_32 __NR_exit
#define __NR_seccomp_sigreturn_32 __NR_sigreturn
#endif /* _ASM_SECCOMP_H */
#include <asm-sparc/seccomp.h>
#ifndef _SPARC64_SFAFSR_H
#define _SPARC64_SFAFSR_H
#include <linux/const.h>
/* Spitfire Asynchronous Fault Status register, ASI=0x4C VA<63:0>=0x0 */
#define SFAFSR_ME (_AC(1,UL) << SFAFSR_ME_SHIFT)
#define SFAFSR_ME_SHIFT 32
#define SFAFSR_PRIV (_AC(1,UL) << SFAFSR_PRIV_SHIFT)
#define SFAFSR_PRIV_SHIFT 31
#define SFAFSR_ISAP (_AC(1,UL) << SFAFSR_ISAP_SHIFT)
#define SFAFSR_ISAP_SHIFT 30
#define SFAFSR_ETP (_AC(1,UL) << SFAFSR_ETP_SHIFT)
#define SFAFSR_ETP_SHIFT 29
#define SFAFSR_IVUE (_AC(1,UL) << SFAFSR_IVUE_SHIFT)
#define SFAFSR_IVUE_SHIFT 28
#define SFAFSR_TO (_AC(1,UL) << SFAFSR_TO_SHIFT)
#define SFAFSR_TO_SHIFT 27
#define SFAFSR_BERR (_AC(1,UL) << SFAFSR_BERR_SHIFT)
#define SFAFSR_BERR_SHIFT 26
#define SFAFSR_LDP (_AC(1,UL) << SFAFSR_LDP_SHIFT)
#define SFAFSR_LDP_SHIFT 25
#define SFAFSR_CP (_AC(1,UL) << SFAFSR_CP_SHIFT)
#define SFAFSR_CP_SHIFT 24
#define SFAFSR_WP (_AC(1,UL) << SFAFSR_WP_SHIFT)
#define SFAFSR_WP_SHIFT 23
#define SFAFSR_EDP (_AC(1,UL) << SFAFSR_EDP_SHIFT)
#define SFAFSR_EDP_SHIFT 22
#define SFAFSR_UE (_AC(1,UL) << SFAFSR_UE_SHIFT)
#define SFAFSR_UE_SHIFT 21
#define SFAFSR_CE (_AC(1,UL) << SFAFSR_CE_SHIFT)
#define SFAFSR_CE_SHIFT 20
#define SFAFSR_ETS (_AC(0xf,UL) << SFAFSR_ETS_SHIFT)
#define SFAFSR_ETS_SHIFT 16
#define SFAFSR_PSYND (_AC(0xffff,UL) << SFAFSR_PSYND_SHIFT)
#define SFAFSR_PSYND_SHIFT 0
/* UDB Error Register, ASI=0x7f VA<63:0>=0x0(High),0x18(Low) for read
* ASI=0x77 VA<63:0>=0x0(High),0x18(Low) for write
*/
#define UDBE_UE (_AC(1,UL) << 9)
#define UDBE_CE (_AC(1,UL) << 8)
#define UDBE_E_SYNDR (_AC(0xff,UL) << 0)
/* The trap handlers for asynchronous errors encode the AFSR and
* other pieces of information into a 64-bit argument for C code
* encoded as follows:
*
* -----------------------------------------------
* | UDB_H | UDB_L | TL>1 | TT | AFSR |
* -----------------------------------------------
* 63 54 53 44 42 41 33 32 0
*
* The AFAR is passed in unchanged.
*/
#define SFSTAT_UDBH_MASK (_AC(0x3ff,UL) << SFSTAT_UDBH_SHIFT)
#define SFSTAT_UDBH_SHIFT 54
#define SFSTAT_UDBL_MASK (_AC(0x3ff,UL) << SFSTAT_UDBH_SHIFT)
#define SFSTAT_UDBL_SHIFT 44
#define SFSTAT_TL_GT_ONE (_AC(1,UL) << SFSTAT_TL_GT_ONE_SHIFT)
#define SFSTAT_TL_GT_ONE_SHIFT 42
#define SFSTAT_TRAP_TYPE (_AC(0x1FF,UL) << SFSTAT_TRAP_TYPE_SHIFT)
#define SFSTAT_TRAP_TYPE_SHIFT 33
#define SFSTAT_AFSR_MASK (_AC(0x1ffffffff,UL) << SFSTAT_AFSR_SHIFT)
#define SFSTAT_AFSR_SHIFT 0
/* ESTATE Error Enable Register, ASI=0x4b VA<63:0>=0x0 */
#define ESTATE_ERR_CE 0x1 /* Correctable errors */
#define ESTATE_ERR_NCE 0x2 /* TO, BERR, LDP, ETP, EDP, WP, UE, IVUE */
#define ESTATE_ERR_ISAP 0x4 /* System address parity error */
#define ESTATE_ERR_ALL (ESTATE_ERR_CE | \
ESTATE_ERR_NCE | \
ESTATE_ERR_ISAP)
/* The various trap types that report using the above state. */
#define TRAP_TYPE_IAE 0x09 /* Instruction Access Error */
#define TRAP_TYPE_DAE 0x32 /* Data Access Error */
#define TRAP_TYPE_CEE 0x63 /* Correctable ECC Error */
#endif /* _SPARC64_SFAFSR_H */
#include <asm-sparc/sfafsr.h>
#ifndef _SPARC64_SPARSEMEM_H
#define _SPARC64_SPARSEMEM_H
#ifdef __KERNEL__
#define SECTION_SIZE_BITS 30
#define MAX_PHYSADDR_BITS 42
#define MAX_PHYSMEM_BITS 42
#endif /* !(__KERNEL__) */
#endif /* !(_SPARC64_SPARSEMEM_H) */
#include <asm-sparc/sparsemem.h>
/* spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations.
*
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
*/
#ifndef _SPARC64_SPITFIRE_H
#define _SPARC64_SPITFIRE_H
#include <asm/asi.h>
/* The following register addresses are accessible via ASI_DMMU
* and ASI_IMMU, that is there is a distinct and unique copy of
* each these registers for each TLB.
*/
#define TSB_TAG_TARGET 0x0000000000000000 /* All chips */
#define TLB_SFSR 0x0000000000000018 /* All chips */
#define TSB_REG 0x0000000000000028 /* All chips */
#define TLB_TAG_ACCESS 0x0000000000000030 /* All chips */
#define VIRT_WATCHPOINT 0x0000000000000038 /* All chips */
#define PHYS_WATCHPOINT 0x0000000000000040 /* All chips */
#define TSB_EXTENSION_P 0x0000000000000048 /* Ultra-III and later */
#define TSB_EXTENSION_S 0x0000000000000050 /* Ultra-III and later, D-TLB only */
#define TSB_EXTENSION_N 0x0000000000000058 /* Ultra-III and later */
#define TLB_TAG_ACCESS_EXT 0x0000000000000060 /* Ultra-III+ and later */
/* These registers only exist as one entity, and are accessed
* via ASI_DMMU only.
*/
#define PRIMARY_CONTEXT 0x0000000000000008
#define SECONDARY_CONTEXT 0x0000000000000010
#define DMMU_SFAR 0x0000000000000020
#define VIRT_WATCHPOINT 0x0000000000000038
#define PHYS_WATCHPOINT 0x0000000000000040
#define SPITFIRE_HIGHEST_LOCKED_TLBENT (64 - 1)
#define CHEETAH_HIGHEST_LOCKED_TLBENT (16 - 1)
#define L1DCACHE_SIZE 0x4000
#define SUN4V_CHIP_INVALID 0x00
#define SUN4V_CHIP_NIAGARA1 0x01
#define SUN4V_CHIP_NIAGARA2 0x02
#define SUN4V_CHIP_UNKNOWN 0xff
#ifndef __ASSEMBLY__
enum ultra_tlb_layout {
spitfire = 0,
cheetah = 1,
cheetah_plus = 2,
hypervisor = 3,
};
extern enum ultra_tlb_layout tlb_type;
extern int sun4v_chip_type;
extern int cheetah_pcache_forced_on;
extern void cheetah_enable_pcache(void);
#define sparc64_highest_locked_tlbent() \
(tlb_type == spitfire ? \
SPITFIRE_HIGHEST_LOCKED_TLBENT : \
CHEETAH_HIGHEST_LOCKED_TLBENT)
extern int num_kernel_image_mappings;
/* The data cache is write through, so this just invalidates the
* specified line.
*/
static inline void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag)
{
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* No outputs */
: "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG));
}
/* The instruction cache lines are flushed with this, but note that
* this does not flush the pipeline. It is possible for a line to
* get flushed but stale instructions to still be in the pipeline,
* a flush instruction (to any address) is sufficient to handle
* this issue after the line is invalidated.
*/
static inline void spitfire_put_icache_tag(unsigned long addr, unsigned long tag)
{
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* No outputs */
: "r" (tag), "r" (addr), "i" (ASI_IC_TAG));
}
static inline unsigned long spitfire_get_dtlb_data(int entry)
{
unsigned long data;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (data)
: "r" (entry << 3), "i" (ASI_DTLB_DATA_ACCESS));
/* Clear TTE diag bits. */
data &= ~0x0003fe0000000000UL;
return data;
}
static inline unsigned long spitfire_get_dtlb_tag(int entry)
{
unsigned long tag;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (tag)
: "r" (entry << 3), "i" (ASI_DTLB_TAG_READ));
return tag;
}
static inline void spitfire_put_dtlb_data(int entry, unsigned long data)
{
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* No outputs */
: "r" (data), "r" (entry << 3),
"i" (ASI_DTLB_DATA_ACCESS));
}
static inline unsigned long spitfire_get_itlb_data(int entry)
{
unsigned long data;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (data)
: "r" (entry << 3), "i" (ASI_ITLB_DATA_ACCESS));
/* Clear TTE diag bits. */
data &= ~0x0003fe0000000000UL;
return data;
}
static inline unsigned long spitfire_get_itlb_tag(int entry)
{
unsigned long tag;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (tag)
: "r" (entry << 3), "i" (ASI_ITLB_TAG_READ));
return tag;
}
static inline void spitfire_put_itlb_data(int entry, unsigned long data)
{
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* No outputs */
: "r" (data), "r" (entry << 3),
"i" (ASI_ITLB_DATA_ACCESS));
}
static inline void spitfire_flush_dtlb_nucleus_page(unsigned long page)
{
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* No outputs */
: "r" (page | 0x20), "i" (ASI_DMMU_DEMAP));
}
static inline void spitfire_flush_itlb_nucleus_page(unsigned long page)
{
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* No outputs */
: "r" (page | 0x20), "i" (ASI_IMMU_DEMAP));
}
/* Cheetah has "all non-locked" tlb flushes. */
static inline void cheetah_flush_dtlb_all(void)
{
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* No outputs */
: "r" (0x80), "i" (ASI_DMMU_DEMAP));
}
static inline void cheetah_flush_itlb_all(void)
{
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* No outputs */
: "r" (0x80), "i" (ASI_IMMU_DEMAP));
}
/* Cheetah has a 4-tlb layout so direct access is a bit different.
* The first two TLBs are fully assosciative, hold 16 entries, and are
* used only for locked and >8K sized translations. One exists for
* data accesses and one for instruction accesses.
*
* The third TLB is for data accesses to 8K non-locked translations, is
* 2 way assosciative, and holds 512 entries. The fourth TLB is for
* instruction accesses to 8K non-locked translations, is 2 way
* assosciative, and holds 128 entries.
*
* Cheetah has some bug where bogus data can be returned from
* ASI_{D,I}TLB_DATA_ACCESS loads, doing the load twice fixes
* the problem for me. -DaveM
*/
static inline unsigned long cheetah_get_ldtlb_data(int entry)
{
unsigned long data;
__asm__ __volatile__("ldxa [%1] %2, %%g0\n\t"
"ldxa [%1] %2, %0"
: "=r" (data)
: "r" ((0 << 16) | (entry << 3)),
"i" (ASI_DTLB_DATA_ACCESS));
return data;
}
static inline unsigned long cheetah_get_litlb_data(int entry)
{
unsigned long data;
__asm__ __volatile__("ldxa [%1] %2, %%g0\n\t"
"ldxa [%1] %2, %0"
: "=r" (data)
: "r" ((0 << 16) | (entry << 3)),
"i" (ASI_ITLB_DATA_ACCESS));
return data;
}
static inline unsigned long cheetah_get_ldtlb_tag(int entry)
{
unsigned long tag;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (tag)
: "r" ((0 << 16) | (entry << 3)),
"i" (ASI_DTLB_TAG_READ));
return tag;
}
static inline unsigned long cheetah_get_litlb_tag(int entry)
{
unsigned long tag;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (tag)
: "r" ((0 << 16) | (entry << 3)),
"i" (ASI_ITLB_TAG_READ));
return tag;
}
static inline void cheetah_put_ldtlb_data(int entry, unsigned long data)
{
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* No outputs */
: "r" (data),
"r" ((0 << 16) | (entry << 3)),
"i" (ASI_DTLB_DATA_ACCESS));
}
static inline void cheetah_put_litlb_data(int entry, unsigned long data)
{
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* No outputs */
: "r" (data),
"r" ((0 << 16) | (entry << 3)),
"i" (ASI_ITLB_DATA_ACCESS));
}
static inline unsigned long cheetah_get_dtlb_data(int entry, int tlb)
{
unsigned long data;
__asm__ __volatile__("ldxa [%1] %2, %%g0\n\t"
"ldxa [%1] %2, %0"
: "=r" (data)
: "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_DATA_ACCESS));
return data;
}
static inline unsigned long cheetah_get_dtlb_tag(int entry, int tlb)
{
unsigned long tag;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (tag)
: "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_TAG_READ));
return tag;
}
static inline void cheetah_put_dtlb_data(int entry, unsigned long data, int tlb)
{
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* No outputs */
: "r" (data),
"r" ((tlb << 16) | (entry << 3)),
"i" (ASI_DTLB_DATA_ACCESS));
}
static inline unsigned long cheetah_get_itlb_data(int entry)
{
unsigned long data;
__asm__ __volatile__("ldxa [%1] %2, %%g0\n\t"
"ldxa [%1] %2, %0"
: "=r" (data)
: "r" ((2 << 16) | (entry << 3)),
"i" (ASI_ITLB_DATA_ACCESS));
return data;
}
static inline unsigned long cheetah_get_itlb_tag(int entry)
{
unsigned long tag;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (tag)
: "r" ((2 << 16) | (entry << 3)), "i" (ASI_ITLB_TAG_READ));
return tag;
}
static inline void cheetah_put_itlb_data(int entry, unsigned long data)
{
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* No outputs */
: "r" (data), "r" ((2 << 16) | (entry << 3)),
"i" (ASI_ITLB_DATA_ACCESS));
}
#endif /* !(__ASSEMBLY__) */
#endif /* !(_SPARC64_SPITFIRE_H) */
#include <asm-sparc/spitfire.h>
#ifndef _SPARC64_SSTATE_H
#define _SPARC64_SSTATE_H
extern void sstate_booting(void);
extern void sstate_running(void);
extern void sstate_halt(void);
extern void sstate_poweroff(void);
extern void sstate_panic(void);
extern void sstate_reboot(void);
extern void sun4v_sstate_init(void);
#endif /* _SPARC64_SSTATE_H */
#include <asm-sparc/sstate.h>
#ifndef _SPARC64_STACKTRACE_H
#define _SPARC64_STACKTRACE_H
extern void stack_trace_flush(void);
#endif /* _SPARC64_STACKTRACE_H */
#include <asm-sparc/stacktrace.h>
/*
* starfire.h: Group all starfire specific code together.
*
* Copyright (C) 2000 Anton Blanchard (anton@samba.org)
*/
#ifndef _SPARC64_STARFIRE_H
#define _SPARC64_STARFIRE_H
#ifndef __ASSEMBLY__
extern int this_is_starfire;
extern void check_if_starfire(void);
extern void starfire_cpu_setup(void);
extern int starfire_hard_smp_processor_id(void);
extern void starfire_hookup(int);
extern unsigned int starfire_translate(unsigned long imap, unsigned int upaid);
#endif
#endif
#include <asm-sparc/starfire.h>
#ifndef _SPARC64_SYSCALLS_H
#define _SPARC64_SYSCALLS_H
struct pt_regs;
extern asmlinkage long sparc_do_fork(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size);
extern asmlinkage int sparc_execve(struct pt_regs *regs);
#endif /* _SPARC64_SYSCALLS_H */
#include <asm-sparc/syscalls.h>
#ifndef _SPARC64_TSB_H
#define _SPARC64_TSB_H
/* The sparc64 TSB is similar to the powerpc hashtables. It's a
* power-of-2 sized table of TAG/PTE pairs. The cpu precomputes
* pointers into this table for 8K and 64K page sizes, and also a
* comparison TAG based upon the virtual address and context which
* faults.
*
* TLB miss trap handler software does the actual lookup via something
* of the form:
*
* ldxa [%g0] ASI_{D,I}MMU_TSB_8KB_PTR, %g1
* ldxa [%g0] ASI_{D,I}MMU, %g6
* sllx %g6, 22, %g6
* srlx %g6, 22, %g6
* ldda [%g1] ASI_NUCLEUS_QUAD_LDD, %g4
* cmp %g4, %g6
* bne,pn %xcc, tsb_miss_{d,i}tlb
* mov FAULT_CODE_{D,I}TLB, %g3
* stxa %g5, [%g0] ASI_{D,I}TLB_DATA_IN
* retry
*
*
* Each 16-byte slot of the TSB is the 8-byte tag and then the 8-byte
* PTE. The TAG is of the same layout as the TLB TAG TARGET mmu
* register which is:
*
* -------------------------------------------------
* | - | CONTEXT | - | VADDR bits 63:22 |
* -------------------------------------------------
* 63 61 60 48 47 42 41 0
*
* But actually, since we use per-mm TSB's, we zero out the CONTEXT
* field.
*
* Like the powerpc hashtables we need to use locking in order to
* synchronize while we update the entries. PTE updates need locking
* as well.
*
* We need to carefully choose a lock bits for the TSB entry. We
* choose to use bit 47 in the tag. Also, since we never map anything
* at page zero in context zero, we use zero as an invalid tag entry.
* When the lock bit is set, this forces a tag comparison failure.
*/
#define TSB_TAG_LOCK_BIT 47
#define TSB_TAG_LOCK_HIGH (1 << (TSB_TAG_LOCK_BIT - 32))
#define TSB_TAG_INVALID_BIT 46
#define TSB_TAG_INVALID_HIGH (1 << (TSB_TAG_INVALID_BIT - 32))
#define TSB_MEMBAR membar #StoreStore
/* Some cpus support physical address quad loads. We want to use
* those if possible so we don't need to hard-lock the TSB mapping
* into the TLB. We encode some instruction patching in order to
* support this.
*
* The kernel TSB is locked into the TLB by virtue of being in the
* kernel image, so we don't play these games for swapper_tsb access.
*/
#ifndef __ASSEMBLY__
struct tsb_ldquad_phys_patch_entry {
unsigned int addr;
unsigned int sun4u_insn;
unsigned int sun4v_insn;
};
extern struct tsb_ldquad_phys_patch_entry __tsb_ldquad_phys_patch,
__tsb_ldquad_phys_patch_end;
struct tsb_phys_patch_entry {
unsigned int addr;
unsigned int insn;
};
extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
#endif
#define TSB_LOAD_QUAD(TSB, REG) \
661: ldda [TSB] ASI_NUCLEUS_QUAD_LDD, REG; \
.section .tsb_ldquad_phys_patch, "ax"; \
.word 661b; \
ldda [TSB] ASI_QUAD_LDD_PHYS, REG; \
ldda [TSB] ASI_QUAD_LDD_PHYS_4V, REG; \
.previous
#define TSB_LOAD_TAG_HIGH(TSB, REG) \
661: lduwa [TSB] ASI_N, REG; \
.section .tsb_phys_patch, "ax"; \
.word 661b; \
lduwa [TSB] ASI_PHYS_USE_EC, REG; \
.previous
#define TSB_LOAD_TAG(TSB, REG) \
661: ldxa [TSB] ASI_N, REG; \
.section .tsb_phys_patch, "ax"; \
.word 661b; \
ldxa [TSB] ASI_PHYS_USE_EC, REG; \
.previous
#define TSB_CAS_TAG_HIGH(TSB, REG1, REG2) \
661: casa [TSB] ASI_N, REG1, REG2; \
.section .tsb_phys_patch, "ax"; \
.word 661b; \
casa [TSB] ASI_PHYS_USE_EC, REG1, REG2; \
.previous
#define TSB_CAS_TAG(TSB, REG1, REG2) \
661: casxa [TSB] ASI_N, REG1, REG2; \
.section .tsb_phys_patch, "ax"; \
.word 661b; \
casxa [TSB] ASI_PHYS_USE_EC, REG1, REG2; \
.previous
#define TSB_STORE(ADDR, VAL) \
661: stxa VAL, [ADDR] ASI_N; \
.section .tsb_phys_patch, "ax"; \
.word 661b; \
stxa VAL, [ADDR] ASI_PHYS_USE_EC; \
.previous
#define TSB_LOCK_TAG(TSB, REG1, REG2) \
99: TSB_LOAD_TAG_HIGH(TSB, REG1); \
sethi %hi(TSB_TAG_LOCK_HIGH), REG2;\
andcc REG1, REG2, %g0; \
bne,pn %icc, 99b; \
nop; \
TSB_CAS_TAG_HIGH(TSB, REG1, REG2); \
cmp REG1, REG2; \
bne,pn %icc, 99b; \
nop; \
TSB_MEMBAR
#define TSB_WRITE(TSB, TTE, TAG) \
add TSB, 0x8, TSB; \
TSB_STORE(TSB, TTE); \
sub TSB, 0x8, TSB; \
TSB_MEMBAR; \
TSB_STORE(TSB, TAG);
#define KTSB_LOAD_QUAD(TSB, REG) \
ldda [TSB] ASI_NUCLEUS_QUAD_LDD, REG;
#define KTSB_STORE(ADDR, VAL) \
stxa VAL, [ADDR] ASI_N;
#define KTSB_LOCK_TAG(TSB, REG1, REG2) \
99: lduwa [TSB] ASI_N, REG1; \
sethi %hi(TSB_TAG_LOCK_HIGH), REG2;\
andcc REG1, REG2, %g0; \
bne,pn %icc, 99b; \
nop; \
casa [TSB] ASI_N, REG1, REG2;\
cmp REG1, REG2; \
bne,pn %icc, 99b; \
nop; \
TSB_MEMBAR
#define KTSB_WRITE(TSB, TTE, TAG) \
add TSB, 0x8, TSB; \
stxa TTE, [TSB] ASI_N; \
sub TSB, 0x8, TSB; \
TSB_MEMBAR; \
stxa TAG, [TSB] ASI_N;
/* Do a kernel page table walk. Leaves physical PTE pointer in
* REG1. Jumps to FAIL_LABEL on early page table walk termination.
* VADDR will not be clobbered, but REG2 will.
*/
#define KERN_PGTABLE_WALK(VADDR, REG1, REG2, FAIL_LABEL) \
sethi %hi(swapper_pg_dir), REG1; \
or REG1, %lo(swapper_pg_dir), REG1; \
sllx VADDR, 64 - (PGDIR_SHIFT + PGDIR_BITS), REG2; \
srlx REG2, 64 - PAGE_SHIFT, REG2; \
andn REG2, 0x3, REG2; \
lduw [REG1 + REG2], REG1; \
brz,pn REG1, FAIL_LABEL; \
sllx VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \
srlx REG2, 64 - PAGE_SHIFT, REG2; \
sllx REG1, 11, REG1; \
andn REG2, 0x3, REG2; \
lduwa [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \
brz,pn REG1, FAIL_LABEL; \
sllx VADDR, 64 - PMD_SHIFT, REG2; \
srlx REG2, 64 - PAGE_SHIFT, REG2; \
sllx REG1, 11, REG1; \
andn REG2, 0x7, REG2; \
add REG1, REG2, REG1;
/* Do a user page table walk in MMU globals. Leaves physical PTE
* pointer in REG1. Jumps to FAIL_LABEL on early page table walk
* termination. Physical base of page tables is in PHYS_PGD which
* will not be modified.
*
* VADDR will not be clobbered, but REG1 and REG2 will.
*/
#define USER_PGTABLE_WALK_TL1(VADDR, PHYS_PGD, REG1, REG2, FAIL_LABEL) \
sllx VADDR, 64 - (PGDIR_SHIFT + PGDIR_BITS), REG2; \
srlx REG2, 64 - PAGE_SHIFT, REG2; \
andn REG2, 0x3, REG2; \
lduwa [PHYS_PGD + REG2] ASI_PHYS_USE_EC, REG1; \
brz,pn REG1, FAIL_LABEL; \
sllx VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \
srlx REG2, 64 - PAGE_SHIFT, REG2; \
sllx REG1, 11, REG1; \
andn REG2, 0x3, REG2; \
lduwa [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \
brz,pn REG1, FAIL_LABEL; \
sllx VADDR, 64 - PMD_SHIFT, REG2; \
srlx REG2, 64 - PAGE_SHIFT, REG2; \
sllx REG1, 11, REG1; \
andn REG2, 0x7, REG2; \
add REG1, REG2, REG1;
/* Lookup a OBP mapping on VADDR in the prom_trans[] table at TL>0.
* If no entry is found, FAIL_LABEL will be branched to. On success
* the resulting PTE value will be left in REG1. VADDR is preserved
* by this routine.
*/
#define OBP_TRANS_LOOKUP(VADDR, REG1, REG2, REG3, FAIL_LABEL) \
sethi %hi(prom_trans), REG1; \
or REG1, %lo(prom_trans), REG1; \
97: ldx [REG1 + 0x00], REG2; \
brz,pn REG2, FAIL_LABEL; \
nop; \
ldx [REG1 + 0x08], REG3; \
add REG2, REG3, REG3; \
cmp REG2, VADDR; \
bgu,pt %xcc, 98f; \
cmp VADDR, REG3; \
bgeu,pt %xcc, 98f; \
ldx [REG1 + 0x10], REG3; \
sub VADDR, REG2, REG2; \
ba,pt %xcc, 99f; \
add REG3, REG2, REG1; \
98: ba,pt %xcc, 97b; \
add REG1, (3 * 8), REG1; \
99:
/* We use a 32K TSB for the whole kernel, this allows to
* handle about 16MB of modules and vmalloc mappings without
* incurring many hash conflicts.
*/
#define KERNEL_TSB_SIZE_BYTES (32 * 1024)
#define KERNEL_TSB_NENTRIES \
(KERNEL_TSB_SIZE_BYTES / 16)
#define KERNEL_TSB4M_NENTRIES 4096
/* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL
* on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries
* and the found TTE will be left in REG1. REG3 and REG4 must
* be an even/odd pair of registers.
*
* VADDR and TAG will be preserved and not clobbered by this macro.
*/
#define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
sethi %hi(swapper_tsb), REG1; \
or REG1, %lo(swapper_tsb), REG1; \
srlx VADDR, PAGE_SHIFT, REG2; \
and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \
sllx REG2, 4, REG2; \
add REG1, REG2, REG2; \
KTSB_LOAD_QUAD(REG2, REG3); \
cmp REG3, TAG; \
be,a,pt %xcc, OK_LABEL; \
mov REG4, REG1;
#ifndef CONFIG_DEBUG_PAGEALLOC
/* This version uses a trick, the TAG is already (VADDR >> 22) so
* we can make use of that for the index computation.
*/
#define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
sethi %hi(swapper_4m_tsb), REG1; \
or REG1, %lo(swapper_4m_tsb), REG1; \
and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \
sllx REG2, 4, REG2; \
add REG1, REG2, REG2; \
KTSB_LOAD_QUAD(REG2, REG3); \
cmp REG3, TAG; \
be,a,pt %xcc, OK_LABEL; \
mov REG4, REG1;
#endif
#endif /* !(_SPARC64_TSB_H) */
#include <asm-sparc/tsb.h>
#ifndef _SPARC64_TTABLE_H
#define _SPARC64_TTABLE_H
#include <asm/utrap.h>
#ifdef __ASSEMBLY__
#include <asm/thread_info.h>
#endif
#define BOOT_KERNEL b sparc64_boot; nop; nop; nop; nop; nop; nop; nop;
/* We need a "cleaned" instruction... */
#define CLEAN_WINDOW \
rdpr %cleanwin, %l0; add %l0, 1, %l0; \
wrpr %l0, 0x0, %cleanwin; \
clr %o0; clr %o1; clr %o2; clr %o3; \
clr %o4; clr %o5; clr %o6; clr %o7; \
clr %l0; clr %l1; clr %l2; clr %l3; \
clr %l4; clr %l5; clr %l6; clr %l7; \
retry; \
nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
#define TRAP(routine) \
sethi %hi(109f), %g7; \
ba,pt %xcc, etrap; \
109: or %g7, %lo(109b), %g7; \
call routine; \
add %sp, PTREGS_OFF, %o0; \
ba,pt %xcc, rtrap; \
nop; \
nop;
#define TRAP_7INSNS(routine) \
sethi %hi(109f), %g7; \
ba,pt %xcc, etrap; \
109: or %g7, %lo(109b), %g7; \
call routine; \
add %sp, PTREGS_OFF, %o0; \
ba,pt %xcc, rtrap; \
nop;
#define TRAP_SAVEFPU(routine) \
sethi %hi(109f), %g7; \
ba,pt %xcc, do_fptrap; \
109: or %g7, %lo(109b), %g7; \
call routine; \
add %sp, PTREGS_OFF, %o0; \
ba,pt %xcc, rtrap; \
nop; \
nop;
#define TRAP_NOSAVE(routine) \
ba,pt %xcc, routine; \
nop; \
nop; nop; nop; nop; nop; nop;
#define TRAP_NOSAVE_7INSNS(routine) \
ba,pt %xcc, routine; \
nop; \
nop; nop; nop; nop; nop;
#define TRAPTL1(routine) \
sethi %hi(109f), %g7; \
ba,pt %xcc, etraptl1; \
109: or %g7, %lo(109b), %g7; \
call routine; \
add %sp, PTREGS_OFF, %o0; \
ba,pt %xcc, rtrap; \
nop; \
nop;
#define TRAP_ARG(routine, arg) \
sethi %hi(109f), %g7; \
ba,pt %xcc, etrap; \
109: or %g7, %lo(109b), %g7; \
add %sp, PTREGS_OFF, %o0; \
call routine; \
mov arg, %o1; \
ba,pt %xcc, rtrap; \
nop;
#define TRAPTL1_ARG(routine, arg) \
sethi %hi(109f), %g7; \
ba,pt %xcc, etraptl1; \
109: or %g7, %lo(109b), %g7; \
add %sp, PTREGS_OFF, %o0; \
call routine; \
mov arg, %o1; \
ba,pt %xcc, rtrap; \
nop;
#define SYSCALL_TRAP(routine, systbl) \
rdpr %pil, %g2; \
mov TSTATE_SYSCALL, %g3; \
sethi %hi(109f), %g7; \
ba,pt %xcc, etrap_syscall; \
109: or %g7, %lo(109b), %g7; \
sethi %hi(systbl), %l7; \
ba,pt %xcc, routine; \
or %l7, %lo(systbl), %l7;
#define TRAP_UTRAP(handler,lvl) \
mov handler, %g3; \
ba,pt %xcc, utrap_trap; \
mov lvl, %g4; \
nop; \
nop; \
nop; \
nop; \
nop;
#ifdef CONFIG_COMPAT
#define LINUX_32BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sys_call_table32)
#else
#define LINUX_32BIT_SYSCALL_TRAP BTRAP(0x110)
#endif
#define LINUX_64BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall, sys_call_table64)
#define GETCC_TRAP TRAP(getcc)
#define SETCC_TRAP TRAP(setcc)
#define BREAKPOINT_TRAP TRAP(breakpoint_trap)
#ifdef CONFIG_TRACE_IRQFLAGS
#define TRAP_IRQ(routine, level) \
rdpr %pil, %g2; \
wrpr %g0, 15, %pil; \
sethi %hi(1f-4), %g7; \
ba,pt %xcc, etrap_irq; \
or %g7, %lo(1f-4), %g7; \
nop; \
nop; \
nop; \
.subsection 2; \
1: call trace_hardirqs_off; \
nop; \
mov level, %o0; \
call routine; \
add %sp, PTREGS_OFF, %o1; \
ba,a,pt %xcc, rtrap_irq; \
.previous;
#else
#define TRAP_IRQ(routine, level) \
rdpr %pil, %g2; \
wrpr %g0, 15, %pil; \
ba,pt %xcc, etrap_irq; \
rd %pc, %g7; \
mov level, %o0; \
call routine; \
add %sp, PTREGS_OFF, %o1; \
ba,a,pt %xcc, rtrap_irq;
#endif
#define TRAP_IVEC TRAP_NOSAVE(do_ivec)
#define BTRAP(lvl) TRAP_ARG(bad_trap, lvl)
#define BTRAPTL1(lvl) TRAPTL1_ARG(bad_trap_tl1, lvl)
#define FLUSH_WINDOW_TRAP \
ba,pt %xcc, etrap; \
rd %pc, %g7; \
flushw; \
ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1; \
add %l1, 4, %l2; \
stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]; \
ba,pt %xcc, rtrap; \
stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC];
#ifdef CONFIG_KPROBES
#define KPROBES_TRAP(lvl) TRAP_IRQ(kprobe_trap, lvl)
#else
#define KPROBES_TRAP(lvl) TRAP_ARG(bad_trap, lvl)
#endif
#ifdef CONFIG_KGDB
#define KGDB_TRAP(lvl) TRAP_IRQ(kgdb_trap, lvl)
#else
#define KGDB_TRAP(lvl) TRAP_ARG(bad_trap, lvl)
#endif
#define SUN4V_ITSB_MISS \
ldxa [%g0] ASI_SCRATCHPAD, %g2; \
ldx [%g2 + HV_FAULT_I_ADDR_OFFSET], %g4; \
ldx [%g2 + HV_FAULT_I_CTX_OFFSET], %g5; \
srlx %g4, 22, %g6; \
ba,pt %xcc, sun4v_itsb_miss; \
nop; \
nop; \
nop;
#define SUN4V_DTSB_MISS \
ldxa [%g0] ASI_SCRATCHPAD, %g2; \
ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4; \
ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5; \
srlx %g4, 22, %g6; \
ba,pt %xcc, sun4v_dtsb_miss; \
nop; \
nop; \
nop;
/* Before touching these macros, you owe it to yourself to go and
* see how arch/sparc64/kernel/winfixup.S works... -DaveM
*
* For the user cases we used to use the %asi register, but
* it turns out that the "wr xxx, %asi" costs ~5 cycles, so
* now we use immediate ASI loads and stores instead. Kudos
* to Greg Onufer for pointing out this performance anomaly.
*
* Further note that we cannot use the g2, g4, g5, and g7 alternate
* globals in the spill routines, check out the save instruction in
* arch/sparc64/kernel/etrap.S to see what I mean about g2, and
* g4/g5 are the globals which are preserved by etrap processing
* for the caller of it. The g7 register is the return pc for
* etrap. Finally, g6 is the current thread register so we cannot
* us it in the spill handlers either. Most of these rules do not
* apply to fill processing, only g6 is not usable.
*/
/* Normal kernel spill */
#define SPILL_0_NORMAL \
stx %l0, [%sp + STACK_BIAS + 0x00]; \
stx %l1, [%sp + STACK_BIAS + 0x08]; \
stx %l2, [%sp + STACK_BIAS + 0x10]; \
stx %l3, [%sp + STACK_BIAS + 0x18]; \
stx %l4, [%sp + STACK_BIAS + 0x20]; \
stx %l5, [%sp + STACK_BIAS + 0x28]; \
stx %l6, [%sp + STACK_BIAS + 0x30]; \
stx %l7, [%sp + STACK_BIAS + 0x38]; \
stx %i0, [%sp + STACK_BIAS + 0x40]; \
stx %i1, [%sp + STACK_BIAS + 0x48]; \
stx %i2, [%sp + STACK_BIAS + 0x50]; \
stx %i3, [%sp + STACK_BIAS + 0x58]; \
stx %i4, [%sp + STACK_BIAS + 0x60]; \
stx %i5, [%sp + STACK_BIAS + 0x68]; \
stx %i6, [%sp + STACK_BIAS + 0x70]; \
stx %i7, [%sp + STACK_BIAS + 0x78]; \
saved; retry; nop; nop; nop; nop; nop; nop; \
nop; nop; nop; nop; nop; nop; nop; nop;
#define SPILL_0_NORMAL_ETRAP \
etrap_kernel_spill: \
stx %l0, [%sp + STACK_BIAS + 0x00]; \
stx %l1, [%sp + STACK_BIAS + 0x08]; \
stx %l2, [%sp + STACK_BIAS + 0x10]; \
stx %l3, [%sp + STACK_BIAS + 0x18]; \
stx %l4, [%sp + STACK_BIAS + 0x20]; \
stx %l5, [%sp + STACK_BIAS + 0x28]; \
stx %l6, [%sp + STACK_BIAS + 0x30]; \
stx %l7, [%sp + STACK_BIAS + 0x38]; \
stx %i0, [%sp + STACK_BIAS + 0x40]; \
stx %i1, [%sp + STACK_BIAS + 0x48]; \
stx %i2, [%sp + STACK_BIAS + 0x50]; \
stx %i3, [%sp + STACK_BIAS + 0x58]; \
stx %i4, [%sp + STACK_BIAS + 0x60]; \
stx %i5, [%sp + STACK_BIAS + 0x68]; \
stx %i6, [%sp + STACK_BIAS + 0x70]; \
stx %i7, [%sp + STACK_BIAS + 0x78]; \
saved; \
sub %g1, 2, %g1; \
ba,pt %xcc, etrap_save; \
wrpr %g1, %cwp; \
nop; nop; nop; nop; nop; nop; nop; nop; \
nop; nop; nop; nop;
/* Normal 64bit spill */
#define SPILL_1_GENERIC(ASI) \
add %sp, STACK_BIAS + 0x00, %g1; \
stxa %l0, [%g1 + %g0] ASI; \
mov 0x08, %g3; \
stxa %l1, [%g1 + %g3] ASI; \
add %g1, 0x10, %g1; \
stxa %l2, [%g1 + %g0] ASI; \
stxa %l3, [%g1 + %g3] ASI; \
add %g1, 0x10, %g1; \
stxa %l4, [%g1 + %g0] ASI; \
stxa %l5, [%g1 + %g3] ASI; \
add %g1, 0x10, %g1; \
stxa %l6, [%g1 + %g0] ASI; \
stxa %l7, [%g1 + %g3] ASI; \
add %g1, 0x10, %g1; \
stxa %i0, [%g1 + %g0] ASI; \
stxa %i1, [%g1 + %g3] ASI; \
add %g1, 0x10, %g1; \
stxa %i2, [%g1 + %g0] ASI; \
stxa %i3, [%g1 + %g3] ASI; \
add %g1, 0x10, %g1; \
stxa %i4, [%g1 + %g0] ASI; \
stxa %i5, [%g1 + %g3] ASI; \
add %g1, 0x10, %g1; \
stxa %i6, [%g1 + %g0] ASI; \
stxa %i7, [%g1 + %g3] ASI; \
saved; \
retry; nop; nop; \
b,a,pt %xcc, spill_fixup_dax; \
b,a,pt %xcc, spill_fixup_mna; \
b,a,pt %xcc, spill_fixup;
#define SPILL_1_GENERIC_ETRAP \
etrap_user_spill_64bit: \
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; \
sub %g1, 2, %g1; \
ba,pt %xcc, etrap_save; \
wrpr %g1, %cwp; \
nop; nop; nop; nop; nop; \
nop; nop; nop; nop; \
ba,a,pt %xcc, etrap_spill_fixup_64bit; \
ba,a,pt %xcc, etrap_spill_fixup_64bit; \
ba,a,pt %xcc, etrap_spill_fixup_64bit;
#define SPILL_1_GENERIC_ETRAP_FIXUP \
etrap_spill_fixup_64bit: \
ldub [%g6 + TI_WSAVED], %g1; \
sll %g1, 3, %g3; \
add %g6, %g3, %g3; \
stx %sp, [%g3 + TI_RWIN_SPTRS]; \
sll %g1, 7, %g3; \
add %g6, %g3, %g3; \
stx %l0, [%g3 + TI_REG_WINDOW + 0x00]; \
stx %l1, [%g3 + TI_REG_WINDOW + 0x08]; \
stx %l2, [%g3 + TI_REG_WINDOW + 0x10]; \
stx %l3, [%g3 + TI_REG_WINDOW + 0x18]; \
stx %l4, [%g3 + TI_REG_WINDOW + 0x20]; \
stx %l5, [%g3 + TI_REG_WINDOW + 0x28]; \
stx %l6, [%g3 + TI_REG_WINDOW + 0x30]; \
stx %l7, [%g3 + TI_REG_WINDOW + 0x38]; \
stx %i0, [%g3 + TI_REG_WINDOW + 0x40]; \
stx %i1, [%g3 + TI_REG_WINDOW + 0x48]; \
stx %i2, [%g3 + TI_REG_WINDOW + 0x50]; \
stx %i3, [%g3 + TI_REG_WINDOW + 0x58]; \
stx %i4, [%g3 + TI_REG_WINDOW + 0x60]; \
stx %i5, [%g3 + TI_REG_WINDOW + 0x68]; \
stx %i6, [%g3 + TI_REG_WINDOW + 0x70]; \
stx %i7, [%g3 + TI_REG_WINDOW + 0x78]; \
add %g1, 1, %g1; \
stb %g1, [%g6 + TI_WSAVED]; \
saved; \
rdpr %cwp, %g1; \
sub %g1, 2, %g1; \
ba,pt %xcc, etrap_save; \
wrpr %g1, %cwp; \
nop; nop; nop
/* Normal 32bit spill */
#define SPILL_2_GENERIC(ASI) \
srl %sp, 0, %sp; \
stwa %l0, [%sp + %g0] ASI; \
mov 0x04, %g3; \
stwa %l1, [%sp + %g3] ASI; \
add %sp, 0x08, %g1; \
stwa %l2, [%g1 + %g0] ASI; \
stwa %l3, [%g1 + %g3] ASI; \
add %g1, 0x08, %g1; \
stwa %l4, [%g1 + %g0] ASI; \
stwa %l5, [%g1 + %g3] ASI; \
add %g1, 0x08, %g1; \
stwa %l6, [%g1 + %g0] ASI; \
stwa %l7, [%g1 + %g3] ASI; \
add %g1, 0x08, %g1; \
stwa %i0, [%g1 + %g0] ASI; \
stwa %i1, [%g1 + %g3] ASI; \
add %g1, 0x08, %g1; \
stwa %i2, [%g1 + %g0] ASI; \
stwa %i3, [%g1 + %g3] ASI; \
add %g1, 0x08, %g1; \
stwa %i4, [%g1 + %g0] ASI; \
stwa %i5, [%g1 + %g3] ASI; \
add %g1, 0x08, %g1; \
stwa %i6, [%g1 + %g0] ASI; \
stwa %i7, [%g1 + %g3] ASI; \
saved; \
retry; nop; nop; \
b,a,pt %xcc, spill_fixup_dax; \
b,a,pt %xcc, spill_fixup_mna; \
b,a,pt %xcc, spill_fixup;
#define SPILL_2_GENERIC_ETRAP \
etrap_user_spill_32bit: \
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; \
sub %g1, 2, %g1; \
ba,pt %xcc, etrap_save; \
wrpr %g1, %cwp; \
nop; nop; nop; nop; \
nop; nop; nop; nop; \
ba,a,pt %xcc, etrap_spill_fixup_32bit; \
ba,a,pt %xcc, etrap_spill_fixup_32bit; \
ba,a,pt %xcc, etrap_spill_fixup_32bit;
#define SPILL_2_GENERIC_ETRAP_FIXUP \
etrap_spill_fixup_32bit: \
ldub [%g6 + TI_WSAVED], %g1; \
sll %g1, 3, %g3; \
add %g6, %g3, %g3; \
stx %sp, [%g3 + TI_RWIN_SPTRS]; \
sll %g1, 7, %g3; \
add %g6, %g3, %g3; \
stw %l0, [%g3 + TI_REG_WINDOW + 0x00]; \
stw %l1, [%g3 + TI_REG_WINDOW + 0x04]; \
stw %l2, [%g3 + TI_REG_WINDOW + 0x08]; \
stw %l3, [%g3 + TI_REG_WINDOW + 0x0c]; \
stw %l4, [%g3 + TI_REG_WINDOW + 0x10]; \
stw %l5, [%g3 + TI_REG_WINDOW + 0x14]; \
stw %l6, [%g3 + TI_REG_WINDOW + 0x18]; \
stw %l7, [%g3 + TI_REG_WINDOW + 0x1c]; \
stw %i0, [%g3 + TI_REG_WINDOW + 0x20]; \
stw %i1, [%g3 + TI_REG_WINDOW + 0x24]; \
stw %i2, [%g3 + TI_REG_WINDOW + 0x28]; \
stw %i3, [%g3 + TI_REG_WINDOW + 0x2c]; \
stw %i4, [%g3 + TI_REG_WINDOW + 0x30]; \
stw %i5, [%g3 + TI_REG_WINDOW + 0x34]; \
stw %i6, [%g3 + TI_REG_WINDOW + 0x38]; \
stw %i7, [%g3 + TI_REG_WINDOW + 0x3c]; \
add %g1, 1, %g1; \
stb %g1, [%g6 + TI_WSAVED]; \
saved; \
rdpr %cwp, %g1; \
sub %g1, 2, %g1; \
ba,pt %xcc, etrap_save; \
wrpr %g1, %cwp; \
nop; nop; nop
#define SPILL_1_NORMAL SPILL_1_GENERIC(ASI_AIUP)
#define SPILL_2_NORMAL SPILL_2_GENERIC(ASI_AIUP)
#define SPILL_3_NORMAL SPILL_0_NORMAL
#define SPILL_4_NORMAL SPILL_0_NORMAL
#define SPILL_5_NORMAL SPILL_0_NORMAL
#define SPILL_6_NORMAL SPILL_0_NORMAL
#define SPILL_7_NORMAL SPILL_0_NORMAL
#define SPILL_0_OTHER SPILL_0_NORMAL
#define SPILL_1_OTHER SPILL_1_GENERIC(ASI_AIUS)
#define SPILL_2_OTHER SPILL_2_GENERIC(ASI_AIUS)
#define SPILL_3_OTHER SPILL_3_NORMAL
#define SPILL_4_OTHER SPILL_4_NORMAL
#define SPILL_5_OTHER SPILL_5_NORMAL
#define SPILL_6_OTHER SPILL_6_NORMAL
#define SPILL_7_OTHER SPILL_7_NORMAL
/* Normal kernel fill */
#define FILL_0_NORMAL \
ldx [%sp + STACK_BIAS + 0x00], %l0; \
ldx [%sp + STACK_BIAS + 0x08], %l1; \
ldx [%sp + STACK_BIAS + 0x10], %l2; \
ldx [%sp + STACK_BIAS + 0x18], %l3; \
ldx [%sp + STACK_BIAS + 0x20], %l4; \
ldx [%sp + STACK_BIAS + 0x28], %l5; \
ldx [%sp + STACK_BIAS + 0x30], %l6; \
ldx [%sp + STACK_BIAS + 0x38], %l7; \
ldx [%sp + STACK_BIAS + 0x40], %i0; \
ldx [%sp + STACK_BIAS + 0x48], %i1; \
ldx [%sp + STACK_BIAS + 0x50], %i2; \
ldx [%sp + STACK_BIAS + 0x58], %i3; \
ldx [%sp + STACK_BIAS + 0x60], %i4; \
ldx [%sp + STACK_BIAS + 0x68], %i5; \
ldx [%sp + STACK_BIAS + 0x70], %i6; \
ldx [%sp + STACK_BIAS + 0x78], %i7; \
restored; retry; nop; nop; nop; nop; nop; nop; \
nop; nop; nop; nop; nop; nop; nop; nop;
#define FILL_0_NORMAL_RTRAP \
kern_rtt_fill: \
rdpr %cwp, %g1; \
sub %g1, 1, %g1; \
wrpr %g1, %cwp; \
ldx [%sp + STACK_BIAS + 0x00], %l0; \
ldx [%sp + STACK_BIAS + 0x08], %l1; \
ldx [%sp + STACK_BIAS + 0x10], %l2; \
ldx [%sp + STACK_BIAS + 0x18], %l3; \
ldx [%sp + STACK_BIAS + 0x20], %l4; \
ldx [%sp + STACK_BIAS + 0x28], %l5; \
ldx [%sp + STACK_BIAS + 0x30], %l6; \
ldx [%sp + STACK_BIAS + 0x38], %l7; \
ldx [%sp + STACK_BIAS + 0x40], %i0; \
ldx [%sp + STACK_BIAS + 0x48], %i1; \
ldx [%sp + STACK_BIAS + 0x50], %i2; \
ldx [%sp + STACK_BIAS + 0x58], %i3; \
ldx [%sp + STACK_BIAS + 0x60], %i4; \
ldx [%sp + STACK_BIAS + 0x68], %i5; \
ldx [%sp + STACK_BIAS + 0x70], %i6; \
ldx [%sp + STACK_BIAS + 0x78], %i7; \
restored; \
add %g1, 1, %g1; \
ba,pt %xcc, kern_rtt_restore; \
wrpr %g1, %cwp; \
nop; nop; nop; nop; nop; \
nop; nop; nop; nop;
/* Normal 64bit fill */
#define FILL_1_GENERIC(ASI) \
add %sp, STACK_BIAS + 0x00, %g1; \
ldxa [%g1 + %g0] ASI, %l0; \
mov 0x08, %g2; \
mov 0x10, %g3; \
ldxa [%g1 + %g2] ASI, %l1; \
mov 0x18, %g5; \
ldxa [%g1 + %g3] ASI, %l2; \
ldxa [%g1 + %g5] ASI, %l3; \
add %g1, 0x20, %g1; \
ldxa [%g1 + %g0] ASI, %l4; \
ldxa [%g1 + %g2] ASI, %l5; \
ldxa [%g1 + %g3] ASI, %l6; \
ldxa [%g1 + %g5] ASI, %l7; \
add %g1, 0x20, %g1; \
ldxa [%g1 + %g0] ASI, %i0; \
ldxa [%g1 + %g2] ASI, %i1; \
ldxa [%g1 + %g3] ASI, %i2; \
ldxa [%g1 + %g5] ASI, %i3; \
add %g1, 0x20, %g1; \
ldxa [%g1 + %g0] ASI, %i4; \
ldxa [%g1 + %g2] ASI, %i5; \
ldxa [%g1 + %g3] ASI, %i6; \
ldxa [%g1 + %g5] ASI, %i7; \
restored; \
retry; nop; nop; nop; nop; \
b,a,pt %xcc, fill_fixup_dax; \
b,a,pt %xcc, fill_fixup_mna; \
b,a,pt %xcc, fill_fixup;
#define FILL_1_GENERIC_RTRAP \
user_rtt_fill_64bit: \
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; \
ba,pt %xcc, user_rtt_pre_restore; \
restored; \
nop; nop; nop; nop; nop; nop; \
nop; nop; nop; nop; nop; \
ba,a,pt %xcc, user_rtt_fill_fixup; \
ba,a,pt %xcc, user_rtt_fill_fixup; \
ba,a,pt %xcc, user_rtt_fill_fixup;
/* Normal 32bit fill */
#define FILL_2_GENERIC(ASI) \
srl %sp, 0, %sp; \
lduwa [%sp + %g0] ASI, %l0; \
mov 0x04, %g2; \
mov 0x08, %g3; \
lduwa [%sp + %g2] ASI, %l1; \
mov 0x0c, %g5; \
lduwa [%sp + %g3] ASI, %l2; \
lduwa [%sp + %g5] ASI, %l3; \
add %sp, 0x10, %g1; \
lduwa [%g1 + %g0] ASI, %l4; \
lduwa [%g1 + %g2] ASI, %l5; \
lduwa [%g1 + %g3] ASI, %l6; \
lduwa [%g1 + %g5] ASI, %l7; \
add %g1, 0x10, %g1; \
lduwa [%g1 + %g0] ASI, %i0; \
lduwa [%g1 + %g2] ASI, %i1; \
lduwa [%g1 + %g3] ASI, %i2; \
lduwa [%g1 + %g5] ASI, %i3; \
add %g1, 0x10, %g1; \
lduwa [%g1 + %g0] ASI, %i4; \
lduwa [%g1 + %g2] ASI, %i5; \
lduwa [%g1 + %g3] ASI, %i6; \
lduwa [%g1 + %g5] ASI, %i7; \
restored; \
retry; nop; nop; nop; nop; \
b,a,pt %xcc, fill_fixup_dax; \
b,a,pt %xcc, fill_fixup_mna; \
b,a,pt %xcc, fill_fixup;
#define FILL_2_GENERIC_RTRAP \
user_rtt_fill_32bit: \
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; \
ba,pt %xcc, user_rtt_pre_restore; \
restored; \
nop; nop; nop; nop; nop; \
nop; nop; nop; nop; nop; \
ba,a,pt %xcc, user_rtt_fill_fixup; \
ba,a,pt %xcc, user_rtt_fill_fixup; \
ba,a,pt %xcc, user_rtt_fill_fixup;
#define FILL_1_NORMAL FILL_1_GENERIC(ASI_AIUP)
#define FILL_2_NORMAL FILL_2_GENERIC(ASI_AIUP)
#define FILL_3_NORMAL FILL_0_NORMAL
#define FILL_4_NORMAL FILL_0_NORMAL
#define FILL_5_NORMAL FILL_0_NORMAL
#define FILL_6_NORMAL FILL_0_NORMAL
#define FILL_7_NORMAL FILL_0_NORMAL
#define FILL_0_OTHER FILL_0_NORMAL
#define FILL_1_OTHER FILL_1_GENERIC(ASI_AIUS)
#define FILL_2_OTHER FILL_2_GENERIC(ASI_AIUS)
#define FILL_3_OTHER FILL_3_NORMAL
#define FILL_4_OTHER FILL_4_NORMAL
#define FILL_5_OTHER FILL_5_NORMAL
#define FILL_6_OTHER FILL_6_NORMAL
#define FILL_7_OTHER FILL_7_NORMAL
#endif /* !(_SPARC64_TTABLE_H) */
#include <asm-sparc/ttable.h>
#ifndef _SPARC64_UPA_H
#define _SPARC64_UPA_H
#include <asm/asi.h>
/* UPA level registers and defines. */
/* UPA Config Register */
#define UPA_CONFIG_RESV 0xffffffffc0000000 /* Reserved. */
#define UPA_CONFIG_PCON 0x000000003fc00000 /* Depth of various sys queues. */
#define UPA_CONFIG_MID 0x00000000003e0000 /* Module ID. */
#define UPA_CONFIG_PCAP 0x000000000001ffff /* Port Capabilities. */
/* UPA Port ID Register */
#define UPA_PORTID_FNP 0xff00000000000000 /* Hardcoded to 0xfc on ultra. */
#define UPA_PORTID_RESV 0x00fffff800000000 /* Reserved. */
#define UPA_PORTID_ECCVALID 0x0000000400000000 /* Zero if mod can generate ECC */
#define UPA_PORTID_ONEREAD 0x0000000200000000 /* Set if mod generates P_RASB */
#define UPA_PORTID_PINTRDQ 0x0000000180000000 /* # outstanding P_INT_REQ's */
#define UPA_PORTID_PREQDQ 0x000000007e000000 /* slave-wr's to mod supported */
#define UPA_PORTID_PREQRD 0x0000000001e00000 /* # incoming P_REQ's supported */
#define UPA_PORTID_UPACAP 0x00000000001f0000 /* UPA capabilities of mod */
#define UPA_PORTID_ID 0x000000000000ffff /* Module Identification bits */
/* UPA I/O space accessors */
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
static inline unsigned char _upa_readb(unsigned long addr)
{
unsigned char ret;
__asm__ __volatile__("lduba\t[%1] %2, %0\t/* upa_readb */"
: "=r" (ret)
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
return ret;
}
static inline unsigned short _upa_readw(unsigned long addr)
{
unsigned short ret;
__asm__ __volatile__("lduha\t[%1] %2, %0\t/* upa_readw */"
: "=r" (ret)
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
return ret;
}
static inline unsigned int _upa_readl(unsigned long addr)
{
unsigned int ret;
__asm__ __volatile__("lduwa\t[%1] %2, %0\t/* upa_readl */"
: "=r" (ret)
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
return ret;
}
static inline unsigned long _upa_readq(unsigned long addr)
{
unsigned long ret;
__asm__ __volatile__("ldxa\t[%1] %2, %0\t/* upa_readq */"
: "=r" (ret)
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
return ret;
}
static inline void _upa_writeb(unsigned char b, unsigned long addr)
{
__asm__ __volatile__("stba\t%0, [%1] %2\t/* upa_writeb */"
: /* no outputs */
: "r" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
}
static inline void _upa_writew(unsigned short w, unsigned long addr)
{
__asm__ __volatile__("stha\t%0, [%1] %2\t/* upa_writew */"
: /* no outputs */
: "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
}
static inline void _upa_writel(unsigned int l, unsigned long addr)
{
__asm__ __volatile__("stwa\t%0, [%1] %2\t/* upa_writel */"
: /* no outputs */
: "r" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
}
static inline void _upa_writeq(unsigned long q, unsigned long addr)
{
__asm__ __volatile__("stxa\t%0, [%1] %2\t/* upa_writeq */"
: /* no outputs */
: "r" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
}
#define upa_readb(__addr) (_upa_readb((unsigned long)(__addr)))
#define upa_readw(__addr) (_upa_readw((unsigned long)(__addr)))
#define upa_readl(__addr) (_upa_readl((unsigned long)(__addr)))
#define upa_readq(__addr) (_upa_readq((unsigned long)(__addr)))
#define upa_writeb(__b, __addr) (_upa_writeb((__b), (unsigned long)(__addr)))
#define upa_writew(__w, __addr) (_upa_writew((__w), (unsigned long)(__addr)))
#define upa_writel(__l, __addr) (_upa_writel((__l), (unsigned long)(__addr)))
#define upa_writeq(__q, __addr) (_upa_writeq((__q), (unsigned long)(__addr)))
#endif /* __KERNEL__ && !__ASSEMBLY__ */
#endif /* !(_SPARC64_UPA_H) */
#include <asm-sparc/upa.h>
#ifndef _SPARC64_VIO_H
#define _SPARC64_VIO_H
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/mod_devicetable.h>
#include <linux/timer.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/list.h>
#include <linux/log2.h>
#include <asm/ldc.h>
#include <asm/mdesc.h>
struct vio_msg_tag {
u8 type;
#define VIO_TYPE_CTRL 0x01
#define VIO_TYPE_DATA 0x02
#define VIO_TYPE_ERR 0x04
u8 stype;
#define VIO_SUBTYPE_INFO 0x01
#define VIO_SUBTYPE_ACK 0x02
#define VIO_SUBTYPE_NACK 0x04
u16 stype_env;
#define VIO_VER_INFO 0x0001
#define VIO_ATTR_INFO 0x0002
#define VIO_DRING_REG 0x0003
#define VIO_DRING_UNREG 0x0004
#define VIO_RDX 0x0005
#define VIO_PKT_DATA 0x0040
#define VIO_DESC_DATA 0x0041
#define VIO_DRING_DATA 0x0042
#define VNET_MCAST_INFO 0x0101
u32 sid;
};
struct vio_rdx {
struct vio_msg_tag tag;
u64 resv[6];
};
struct vio_ver_info {
struct vio_msg_tag tag;
u16 major;
u16 minor;
u8 dev_class;
#define VDEV_NETWORK 0x01
#define VDEV_NETWORK_SWITCH 0x02
#define VDEV_DISK 0x03
#define VDEV_DISK_SERVER 0x04
u8 resv1[3];
u64 resv2[5];
};
struct vio_dring_register {
struct vio_msg_tag tag;
u64 dring_ident;
u32 num_descr;
u32 descr_size;
u16 options;
#define VIO_TX_DRING 0x0001
#define VIO_RX_DRING 0x0002
u16 resv;
u32 num_cookies;
struct ldc_trans_cookie cookies[0];
};
struct vio_dring_unregister {
struct vio_msg_tag tag;
u64 dring_ident;
u64 resv[5];
};
/* Data transfer modes */
#define VIO_PKT_MODE 0x01 /* Packet based transfer */
#define VIO_DESC_MODE 0x02 /* In-band descriptors */
#define VIO_DRING_MODE 0x03 /* Descriptor rings */
struct vio_dring_data {
struct vio_msg_tag tag;
u64 seq;
u64 dring_ident;
u32 start_idx;
u32 end_idx;
u8 state;
#define VIO_DRING_ACTIVE 0x01
#define VIO_DRING_STOPPED 0x02
u8 __pad1;
u16 __pad2;
u32 __pad3;
u64 __par4[2];
};
struct vio_dring_hdr {
u8 state;
#define VIO_DESC_FREE 0x01
#define VIO_DESC_READY 0x02
#define VIO_DESC_ACCEPTED 0x03
#define VIO_DESC_DONE 0x04
u8 ack;
#define VIO_ACK_ENABLE 0x01
#define VIO_ACK_DISABLE 0x00
u16 __pad1;
u32 __pad2;
};
/* VIO disk specific structures and defines */
struct vio_disk_attr_info {
struct vio_msg_tag tag;
u8 xfer_mode;
u8 vdisk_type;
#define VD_DISK_TYPE_SLICE 0x01 /* Slice in block device */
#define VD_DISK_TYPE_DISK 0x02 /* Entire block device */
u16 resv1;
u32 vdisk_block_size;
u64 operations;
u64 vdisk_size;
u64 max_xfer_size;
u64 resv2[2];
};
struct vio_disk_desc {
struct vio_dring_hdr hdr;
u64 req_id;
u8 operation;
#define VD_OP_BREAD 0x01 /* Block read */
#define VD_OP_BWRITE 0x02 /* Block write */
#define VD_OP_FLUSH 0x03 /* Flush disk contents */
#define VD_OP_GET_WCE 0x04 /* Get write-cache status */
#define VD_OP_SET_WCE 0x05 /* Enable/disable write-cache */
#define VD_OP_GET_VTOC 0x06 /* Get VTOC */
#define VD_OP_SET_VTOC 0x07 /* Set VTOC */
#define VD_OP_GET_DISKGEOM 0x08 /* Get disk geometry */
#define VD_OP_SET_DISKGEOM 0x09 /* Set disk geometry */
#define VD_OP_SCSICMD 0x0a /* SCSI control command */
#define VD_OP_GET_DEVID 0x0b /* Get device ID */
#define VD_OP_GET_EFI 0x0c /* Get EFI */
#define VD_OP_SET_EFI 0x0d /* Set EFI */
u8 slice;
u16 resv1;
u32 status;
u64 offset;
u64 size;
u32 ncookies;
u32 resv2;
struct ldc_trans_cookie cookies[0];
};
#define VIO_DISK_VNAME_LEN 8
#define VIO_DISK_ALABEL_LEN 128
#define VIO_DISK_NUM_PART 8
struct vio_disk_vtoc {
u8 volume_name[VIO_DISK_VNAME_LEN];
u16 sector_size;
u16 num_partitions;
u8 ascii_label[VIO_DISK_ALABEL_LEN];
struct {
u16 id;
u16 perm_flags;
u32 resv;
u64 start_block;
u64 num_blocks;
} partitions[VIO_DISK_NUM_PART];
};
struct vio_disk_geom {
u16 num_cyl; /* Num data cylinders */
u16 alt_cyl; /* Num alternate cylinders */
u16 beg_cyl; /* Cyl off of fixed head area */
u16 num_hd; /* Num heads */
u16 num_sec; /* Num sectors */
u16 ifact; /* Interleave factor */
u16 apc; /* Alts per cylinder (SCSI) */
u16 rpm; /* Revolutions per minute */
u16 phy_cyl; /* Num physical cylinders */
u16 wr_skip; /* Num sects to skip, writes */
u16 rd_skip; /* Num sects to skip, writes */
};
struct vio_disk_devid {
u16 resv;
u16 type;
u32 len;
char id[0];
};
struct vio_disk_efi {
u64 lba;
u64 len;
char data[0];
};
/* VIO net specific structures and defines */
struct vio_net_attr_info {
struct vio_msg_tag tag;
u8 xfer_mode;
u8 addr_type;
#define VNET_ADDR_ETHERMAC 0x01
u16 ack_freq;
u32 resv1;
u64 addr;
u64 mtu;
u64 resv2[3];
};
#define VNET_NUM_MCAST 7
struct vio_net_mcast_info {
struct vio_msg_tag tag;
u8 set;
u8 count;
u8 mcast_addr[VNET_NUM_MCAST * 6];
u32 resv;
};
struct vio_net_desc {
struct vio_dring_hdr hdr;
u32 size;
u32 ncookies;
struct ldc_trans_cookie cookies[0];
};
#define VIO_MAX_RING_COOKIES 24
struct vio_dring_state {
u64 ident;
void *base;
u64 snd_nxt;
u64 rcv_nxt;
u32 entry_size;
u32 num_entries;
u32 prod;
u32 cons;
u32 pending;
int ncookies;
struct ldc_trans_cookie cookies[VIO_MAX_RING_COOKIES];
};
static inline void *vio_dring_cur(struct vio_dring_state *dr)
{
return dr->base + (dr->entry_size * dr->prod);
}
static inline void *vio_dring_entry(struct vio_dring_state *dr,
unsigned int index)
{
return dr->base + (dr->entry_size * index);
}
static inline u32 vio_dring_avail(struct vio_dring_state *dr,
unsigned int ring_size)
{
BUILD_BUG_ON(!is_power_of_2(ring_size));
return (dr->pending -
((dr->prod - dr->cons) & (ring_size - 1)));
}
#define VIO_MAX_TYPE_LEN 32
#define VIO_MAX_COMPAT_LEN 64
struct vio_dev {
u64 mp;
struct device_node *dp;
char type[VIO_MAX_TYPE_LEN];
char compat[VIO_MAX_COMPAT_LEN];
int compat_len;
u64 dev_no;
unsigned long channel_id;
unsigned int tx_irq;
unsigned int rx_irq;
struct device dev;
};
struct vio_driver {
struct list_head node;
const struct vio_device_id *id_table;
int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
int (*remove)(struct vio_dev *dev);
void (*shutdown)(struct vio_dev *dev);
unsigned long driver_data;
struct device_driver driver;
};
struct vio_version {
u16 major;
u16 minor;
};
struct vio_driver_state;
struct vio_driver_ops {
int (*send_attr)(struct vio_driver_state *vio);
int (*handle_attr)(struct vio_driver_state *vio, void *pkt);
void (*handshake_complete)(struct vio_driver_state *vio);
};
struct vio_completion {
struct completion com;
int err;
int waiting_for;
};
struct vio_driver_state {
/* Protects VIO handshake and, optionally, driver private state. */
spinlock_t lock;
struct ldc_channel *lp;
u32 _peer_sid;
u32 _local_sid;
struct vio_dring_state drings[2];
#define VIO_DRIVER_TX_RING 0
#define VIO_DRIVER_RX_RING 1
u8 hs_state;
#define VIO_HS_INVALID 0x00
#define VIO_HS_GOTVERS 0x01
#define VIO_HS_GOT_ATTR 0x04
#define VIO_HS_SENT_DREG 0x08
#define VIO_HS_SENT_RDX 0x10
#define VIO_HS_GOT_RDX_ACK 0x20
#define VIO_HS_GOT_RDX 0x40
#define VIO_HS_SENT_RDX_ACK 0x80
#define VIO_HS_COMPLETE (VIO_HS_GOT_RDX_ACK | VIO_HS_SENT_RDX_ACK)
u8 dev_class;
u8 dr_state;
#define VIO_DR_STATE_TXREG 0x01
#define VIO_DR_STATE_RXREG 0x02
#define VIO_DR_STATE_TXREQ 0x10
#define VIO_DR_STATE_RXREQ 0x20
u8 debug;
#define VIO_DEBUG_HS 0x01
#define VIO_DEBUG_DATA 0x02
void *desc_buf;
unsigned int desc_buf_len;
struct vio_completion *cmp;
struct vio_dev *vdev;
struct timer_list timer;
struct vio_version ver;
struct vio_version *ver_table;
int ver_table_entries;
char *name;
struct vio_driver_ops *ops;
};
#define viodbg(TYPE, f, a...) \
do { if (vio->debug & VIO_DEBUG_##TYPE) \
printk(KERN_INFO "vio: ID[%lu] " f, \
vio->vdev->channel_id, ## a); \
} while (0)
extern int vio_register_driver(struct vio_driver *drv);
extern void vio_unregister_driver(struct vio_driver *drv);
static inline struct vio_driver *to_vio_driver(struct device_driver *drv)
{
return container_of(drv, struct vio_driver, driver);
}
static inline struct vio_dev *to_vio_dev(struct device *dev)
{
return container_of(dev, struct vio_dev, dev);
}
extern int vio_ldc_send(struct vio_driver_state *vio, void *data, int len);
extern void vio_link_state_change(struct vio_driver_state *vio, int event);
extern void vio_conn_reset(struct vio_driver_state *vio);
extern int vio_control_pkt_engine(struct vio_driver_state *vio, void *pkt);
extern int vio_validate_sid(struct vio_driver_state *vio,
struct vio_msg_tag *tp);
extern u32 vio_send_sid(struct vio_driver_state *vio);
extern int vio_ldc_alloc(struct vio_driver_state *vio,
struct ldc_channel_config *base_cfg, void *event_arg);
extern void vio_ldc_free(struct vio_driver_state *vio);
extern int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev,
u8 dev_class, struct vio_version *ver_table,
int ver_table_size, struct vio_driver_ops *ops,
char *name);
extern void vio_port_up(struct vio_driver_state *vio);
#endif /* _SPARC64_VIO_H */
#include <asm-sparc/vio.h>
#ifndef _SPARC64_VISASM_H
#define _SPARC64_VISASM_H
/* visasm.h: FPU saving macros for VIS routines
*
* Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
*/
#include <asm/pstate.h>
#include <asm/ptrace.h>
/* Clobbers %o5, %g1, %g2, %g3, %g7, %icc, %xcc */
#define VISEntry \
rd %fprs, %o5; \
andcc %o5, (FPRS_FEF|FPRS_DU), %g0; \
be,pt %icc, 297f; \
sethi %hi(297f), %g7; \
sethi %hi(VISenter), %g1; \
jmpl %g1 + %lo(VISenter), %g0; \
or %g7, %lo(297f), %g7; \
297: wr %g0, FPRS_FEF, %fprs; \
#define VISExit \
wr %g0, 0, %fprs;
/* Clobbers %o5, %g1, %g2, %g3, %g7, %icc, %xcc.
* Must preserve %o5 between VISEntryHalf and VISExitHalf */
#define VISEntryHalf \
rd %fprs, %o5; \
andcc %o5, FPRS_FEF, %g0; \
be,pt %icc, 297f; \
sethi %hi(298f), %g7; \
sethi %hi(VISenterhalf), %g1; \
jmpl %g1 + %lo(VISenterhalf), %g0; \
or %g7, %lo(298f), %g7; \
clr %o5; \
297: wr %o5, FPRS_FEF, %fprs; \
298:
#define VISExitHalf \
wr %o5, 0, %fprs;
#ifndef __ASSEMBLY__
static inline void save_and_clear_fpu(void) {
__asm__ __volatile__ (
" rd %%fprs, %%o5\n"
" andcc %%o5, %0, %%g0\n"
" be,pt %%icc, 299f\n"
" sethi %%hi(298f), %%g7\n"
" sethi %%hi(VISenter), %%g1\n"
" jmpl %%g1 + %%lo(VISenter), %%g0\n"
" or %%g7, %%lo(298f), %%g7\n"
" 298: wr %%g0, 0, %%fprs\n"
" 299:\n"
" " : : "i" (FPRS_FEF|FPRS_DU) :
"o5", "g1", "g2", "g3", "g7", "cc");
}
#endif
#endif /* _SPARC64_ASI_H */
#include <asm-sparc/visasm.h>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment