forked from Qortal/Brooklyn
cleaning up the git
This commit is contained in:
parent
7ae6aaac6f
commit
f55982be23
3
arch/.gitignore
vendored
Normal file
3
arch/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
/i386/
|
||||
/x86_64/
|
1329
arch/Kconfig
Normal file
1329
arch/Kconfig
Normal file
File diff suppressed because it is too large
Load Diff
6
arch/alpha/Kbuild
Normal file
6
arch/alpha/Kbuild
Normal file
@ -0,0 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-y += kernel/ mm/
|
||||
obj-$(CONFIG_MATHEMU) += math-emu/
|
||||
|
||||
# for cleaning
|
||||
subdir- += boot
|
678
arch/alpha/Kconfig
Normal file
678
arch/alpha/Kconfig
Normal file
@ -0,0 +1,678 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
config ALPHA
|
||||
bool
|
||||
default y
|
||||
select ARCH_32BIT_USTAT_F_TINODE
|
||||
select ARCH_MIGHT_HAVE_PC_PARPORT
|
||||
select ARCH_MIGHT_HAVE_PC_SERIO
|
||||
select ARCH_NO_PREEMPT
|
||||
select ARCH_NO_SG_CHAIN
|
||||
select ARCH_USE_CMPXCHG_LOCKREF
|
||||
select DMA_OPS if PCI
|
||||
select FORCE_PCI if !ALPHA_JENSEN
|
||||
select PCI_DOMAINS if PCI
|
||||
select PCI_SYSCALL if PCI
|
||||
select HAVE_AOUT
|
||||
select HAVE_ASM_MODVERSIONS
|
||||
select HAVE_PCSPKR_PLATFORM
|
||||
select HAVE_PERF_EVENTS
|
||||
select NEED_DMA_MAP_STATE
|
||||
select NEED_SG_DMA_LENGTH
|
||||
select VIRT_TO_BUS
|
||||
select GENERIC_IRQ_PROBE
|
||||
select GENERIC_PCI_IOMAP
|
||||
select AUTO_IRQ_AFFINITY if SMP
|
||||
select GENERIC_IRQ_SHOW
|
||||
select ARCH_WANT_IPC_PARSE_VERSION
|
||||
select ARCH_HAVE_NMI_SAFE_CMPXCHG
|
||||
select AUDIT_ARCH
|
||||
select GENERIC_CPU_VULNERABILITIES
|
||||
select GENERIC_SMP_IDLE_THREAD
|
||||
select HAVE_ARCH_AUDITSYSCALL
|
||||
select HAVE_MOD_ARCH_SPECIFIC
|
||||
select MODULES_USE_ELF_RELA
|
||||
select ODD_RT_SIGACTION
|
||||
select OLD_SIGSUSPEND
|
||||
select CPU_NO_EFFICIENT_FFS if !ALPHA_EV67
|
||||
select MMU_GATHER_NO_RANGE
|
||||
select SET_FS
|
||||
select SPARSEMEM_EXTREME if SPARSEMEM
|
||||
select ZONE_DMA
|
||||
help
|
||||
The Alpha is a 64-bit general-purpose processor designed and
|
||||
marketed by the Digital Equipment Corporation of blessed memory,
|
||||
now Hewlett-Packard. The Alpha Linux project has a home page at
|
||||
<http://www.alphalinux.org/>.
|
||||
|
||||
config 64BIT
|
||||
def_bool y
|
||||
|
||||
config MMU
|
||||
bool
|
||||
default y
|
||||
|
||||
config ARCH_HAS_ILOG2_U32
|
||||
bool
|
||||
default n
|
||||
|
||||
config ARCH_HAS_ILOG2_U64
|
||||
bool
|
||||
default n
|
||||
|
||||
config GENERIC_CALIBRATE_DELAY
|
||||
bool
|
||||
default y
|
||||
|
||||
config GENERIC_ISA_DMA
|
||||
bool
|
||||
default y
|
||||
|
||||
config PGTABLE_LEVELS
|
||||
int
|
||||
default 3
|
||||
|
||||
config AUDIT_ARCH
|
||||
bool
|
||||
|
||||
menu "System setup"
|
||||
|
||||
choice
|
||||
prompt "Alpha system type"
|
||||
default ALPHA_GENERIC
|
||||
help
|
||||
This is the system type of your hardware. A "generic" kernel will
|
||||
run on any supported Alpha system. However, if you configure a
|
||||
kernel for your specific system, it will be faster and smaller.
|
||||
|
||||
To find out what type of Alpha system you have, you may want to
|
||||
check out the Linux/Alpha FAQ, accessible on the WWW from
|
||||
<http://www.alphalinux.org/>. In summary:
|
||||
|
||||
Alcor/Alpha-XLT AS 600, AS 500, XL-300, XL-366
|
||||
Alpha-XL XL-233, XL-266
|
||||
AlphaBook1 Alpha laptop
|
||||
Avanti AS 200, AS 205, AS 250, AS 255, AS 300, AS 400
|
||||
Cabriolet AlphaPC64, AlphaPCI64
|
||||
DP264 DP264 / DS20 / ES40 / DS10 / DS10L
|
||||
EB164 EB164 21164 evaluation board
|
||||
EB64+ EB64+ 21064 evaluation board
|
||||
EB66 EB66 21066 evaluation board
|
||||
EB66+ EB66+ 21066 evaluation board
|
||||
Jensen DECpc 150, DEC 2000 models 300, 500
|
||||
LX164 AlphaPC164-LX
|
||||
Lynx AS 2100A
|
||||
Miata Personal Workstation 433/500/600 a/au
|
||||
Marvel AlphaServer ES47 / ES80 / GS1280
|
||||
Mikasa AS 1000
|
||||
Noname AXPpci33, UDB (Multia)
|
||||
Noritake AS 1000A, AS 600A, AS 800
|
||||
PC164 AlphaPC164
|
||||
Rawhide AS 1200, AS 4000, AS 4100
|
||||
Ruffian RPX164-2, AlphaPC164-UX, AlphaPC164-BX
|
||||
SX164 AlphaPC164-SX
|
||||
Sable AS 2000, AS 2100
|
||||
Shark DS 20L
|
||||
Takara Takara (OEM)
|
||||
Titan AlphaServer ES45 / DS25 / DS15
|
||||
Wildfire AlphaServer GS 40/80/160/320
|
||||
|
||||
If you don't know what to do, choose "generic".
|
||||
|
||||
config ALPHA_GENERIC
|
||||
bool "Generic"
|
||||
depends on TTY
|
||||
select HAVE_EISA
|
||||
help
|
||||
A generic kernel will run on all supported Alpha hardware.
|
||||
|
||||
config ALPHA_ALCOR
|
||||
bool "Alcor/Alpha-XLT"
|
||||
select HAVE_EISA
|
||||
help
|
||||
For systems using the Digital ALCOR chipset: 5 chips (4, 64-bit data
|
||||
slices (Data Switch, DSW) - 208-pin PQFP and 1 control (Control, I/O
|
||||
Address, CIA) - a 383 pin plastic PGA). It provides a DRAM
|
||||
controller (256-bit memory bus) and a PCI interface. It also does
|
||||
all the work required to support an external Bcache and to maintain
|
||||
memory coherence when a PCI device DMAs into (or out of) memory.
|
||||
|
||||
config ALPHA_XL
|
||||
bool "Alpha-XL"
|
||||
help
|
||||
XL-233 and XL-266-based Alpha systems.
|
||||
|
||||
config ALPHA_BOOK1
|
||||
bool "AlphaBook1"
|
||||
help
|
||||
Dec AlphaBook1/Burns Alpha-based laptops.
|
||||
|
||||
config ALPHA_AVANTI_CH
|
||||
bool "Avanti"
|
||||
|
||||
config ALPHA_CABRIOLET
|
||||
bool "Cabriolet"
|
||||
help
|
||||
Cabriolet AlphaPC64, AlphaPCI64 systems. Derived from EB64+ but now
|
||||
baby-AT with Flash boot ROM, no on-board SCSI or Ethernet. 3 ISA
|
||||
slots, 4 PCI slots (one pair are on a shared slot), uses plug-in
|
||||
Bcache SIMMs. Requires power supply with 3.3V output.
|
||||
|
||||
config ALPHA_DP264
|
||||
bool "DP264"
|
||||
help
|
||||
Various 21264 systems with the tsunami core logic chipset.
|
||||
API Networks: 264DP, UP2000(+), CS20;
|
||||
Compaq: DS10(E,L), XP900, XP1000, DS20(E), ES40.
|
||||
|
||||
config ALPHA_EB164
|
||||
bool "EB164"
|
||||
help
|
||||
EB164 21164 evaluation board from DEC. Uses 21164 and ALCOR. Has
|
||||
ISA and PCI expansion (3 ISA slots, 2 64-bit PCI slots (one is
|
||||
shared with an ISA slot) and 2 32-bit PCI slots. Uses plus-in
|
||||
Bcache SIMMs. I/O sub-system provides SuperI/O (2S, 1P, FD), KBD,
|
||||
MOUSE (PS2 style), RTC/NVRAM. Boot ROM is Flash. PC-AT-sized
|
||||
motherboard. Requires power supply with 3.3V output.
|
||||
|
||||
config ALPHA_EB64P_CH
|
||||
bool "EB64+"
|
||||
|
||||
config ALPHA_EB66
|
||||
bool "EB66"
|
||||
help
|
||||
A Digital DS group board. Uses 21066 or 21066A. I/O sub-system is
|
||||
identical to EB64+. Baby PC-AT size. Runs from standard PC power
|
||||
supply. The EB66 schematic was published as a marketing poster
|
||||
advertising the 21066 as "the first microprocessor in the world with
|
||||
embedded PCI".
|
||||
|
||||
config ALPHA_EB66P
|
||||
bool "EB66+"
|
||||
help
|
||||
Later variant of the EB66 board.
|
||||
|
||||
config ALPHA_EIGER
|
||||
bool "Eiger"
|
||||
help
|
||||
Apparently an obscure OEM single-board computer based on the
|
||||
Typhoon/Tsunami chipset family. Information on it is scanty.
|
||||
|
||||
config ALPHA_JENSEN
|
||||
bool "Jensen"
|
||||
select HAVE_EISA
|
||||
help
|
||||
DEC PC 150 AXP (aka Jensen): This is a very old Digital system - one
|
||||
of the first-generation Alpha systems. A number of these systems
|
||||
seem to be available on the second- hand market. The Jensen is a
|
||||
floor-standing tower system which originally used a 150MHz 21064 It
|
||||
used programmable logic to interface a 486 EISA I/O bridge to the
|
||||
CPU.
|
||||
|
||||
config ALPHA_LX164
|
||||
bool "LX164"
|
||||
help
|
||||
A technical overview of this board is available at
|
||||
<http://www.unix-ag.org/Linux-Alpha/Architectures/LX164.html>.
|
||||
|
||||
config ALPHA_LYNX
|
||||
bool "Lynx"
|
||||
select HAVE_EISA
|
||||
help
|
||||
AlphaServer 2100A-based systems.
|
||||
|
||||
config ALPHA_MARVEL
|
||||
bool "Marvel"
|
||||
help
|
||||
AlphaServer ES47 / ES80 / GS1280 based on EV7.
|
||||
|
||||
config ALPHA_MIATA
|
||||
bool "Miata"
|
||||
select HAVE_EISA
|
||||
help
|
||||
The Digital PersonalWorkStation (PWS 433a, 433au, 500a, 500au, 600a,
|
||||
or 600au).
|
||||
|
||||
config ALPHA_MIKASA
|
||||
bool "Mikasa"
|
||||
help
|
||||
AlphaServer 1000-based Alpha systems.
|
||||
|
||||
config ALPHA_NAUTILUS
|
||||
bool "Nautilus"
|
||||
help
|
||||
Alpha systems based on the AMD 751 & ALI 1543C chipsets.
|
||||
|
||||
config ALPHA_NONAME_CH
|
||||
bool "Noname"
|
||||
|
||||
config ALPHA_NORITAKE
|
||||
bool "Noritake"
|
||||
select HAVE_EISA
|
||||
help
|
||||
AlphaServer 1000A, AlphaServer 600A, and AlphaServer 800-based
|
||||
systems.
|
||||
|
||||
config ALPHA_PC164
|
||||
bool "PC164"
|
||||
|
||||
config ALPHA_P2K
|
||||
bool "Platform2000"
|
||||
|
||||
config ALPHA_RAWHIDE
|
||||
bool "Rawhide"
|
||||
select HAVE_EISA
|
||||
help
|
||||
AlphaServer 1200, AlphaServer 4000 and AlphaServer 4100 machines.
|
||||
See HOWTO at
|
||||
<http://www.alphalinux.org/docs/rawhide/4100_install.shtml>.
|
||||
|
||||
config ALPHA_RUFFIAN
|
||||
bool "Ruffian"
|
||||
help
|
||||
Samsung APC164UX. There is a page on known problems and workarounds
|
||||
at <http://www.alphalinux.org/faq/FAQ-11.html>.
|
||||
|
||||
config ALPHA_RX164
|
||||
bool "RX164"
|
||||
|
||||
config ALPHA_SX164
|
||||
bool "SX164"
|
||||
|
||||
config ALPHA_SABLE
|
||||
bool "Sable"
|
||||
select HAVE_EISA
|
||||
help
|
||||
Digital AlphaServer 2000 and 2100-based systems.
|
||||
|
||||
config ALPHA_SHARK
|
||||
bool "Shark"
|
||||
|
||||
config ALPHA_TAKARA
|
||||
bool "Takara"
|
||||
help
|
||||
Alpha 11164-based OEM single-board computer.
|
||||
|
||||
config ALPHA_TITAN
|
||||
bool "Titan"
|
||||
help
|
||||
AlphaServer ES45/DS25 SMP based on EV68 and Titan chipset.
|
||||
|
||||
config ALPHA_WILDFIRE
|
||||
bool "Wildfire"
|
||||
help
|
||||
AlphaServer GS 40/80/160/320 SMP based on the EV67 core.
|
||||
|
||||
endchoice
|
||||
|
||||
# clear all implied options (don't want default values for those):
|
||||
# Most of these machines have ISA slots; not exactly sure which don't,
|
||||
# and this doesn't activate hordes of code, so do it always.
|
||||
config ISA
|
||||
bool
|
||||
default y
|
||||
help
|
||||
Find out whether you have ISA slots on your motherboard. ISA is the
|
||||
name of a bus system, i.e. the way the CPU talks to the other stuff
|
||||
inside your box. Other bus systems are PCI, EISA, MicroChannel
|
||||
(MCA) or VESA. ISA is an older system, now being displaced by PCI;
|
||||
newer boards don't support it. If you have ISA, say Y, otherwise N.
|
||||
|
||||
config ISA_DMA_API
|
||||
bool
|
||||
default y
|
||||
|
||||
config ALPHA_NONAME
|
||||
bool
|
||||
depends on ALPHA_BOOK1 || ALPHA_NONAME_CH
|
||||
default y
|
||||
help
|
||||
The AXPpci33 (aka NoName), is based on the EB66 (includes the Multia
|
||||
UDB). This design was produced by Digital's Technical OEM (TOEM)
|
||||
group. It uses the 21066 processor running at 166MHz or 233MHz. It
|
||||
is a baby-AT size, and runs from a standard PC power supply. It has
|
||||
5 ISA slots and 3 PCI slots (one pair are a shared slot). There are
|
||||
2 versions, with either PS/2 or large DIN connectors for the
|
||||
keyboard.
|
||||
|
||||
config ALPHA_EV4
|
||||
bool
|
||||
depends on ALPHA_JENSEN || (ALPHA_SABLE && !ALPHA_GAMMA) || ALPHA_LYNX || ALPHA_NORITAKE && !ALPHA_PRIMO || ALPHA_MIKASA && !ALPHA_PRIMO || ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P_CH || ALPHA_XL || ALPHA_NONAME || ALPHA_EB66 || ALPHA_EB66P || ALPHA_P2K
|
||||
default y if !ALPHA_LYNX
|
||||
|
||||
config ALPHA_LCA
|
||||
bool
|
||||
depends on ALPHA_NONAME || ALPHA_EB66 || ALPHA_EB66P || ALPHA_P2K
|
||||
default y
|
||||
|
||||
config ALPHA_APECS
|
||||
bool
|
||||
depends on !ALPHA_PRIMO && (ALPHA_NORITAKE || ALPHA_MIKASA) || ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P_CH || ALPHA_XL
|
||||
default y
|
||||
|
||||
config ALPHA_EB64P
|
||||
bool
|
||||
depends on ALPHA_CABRIOLET || ALPHA_EB64P_CH
|
||||
default y
|
||||
help
|
||||
Uses 21064 or 21064A and APECs. Has ISA and PCI expansion (3 ISA,
|
||||
2 PCI, one pair are on a shared slot). Supports 36-bit DRAM SIMs.
|
||||
ISA bus generated by Intel SaturnI/O PCI-ISA bridge. On-board SCSI
|
||||
(NCR 810 on PCI) Ethernet (Digital 21040), KBD, MOUSE (PS2 style),
|
||||
SuperI/O (2S, 1P, FD), RTC/NVRAM. Boot ROM is EPROM. PC-AT size.
|
||||
Runs from standard PC power supply.
|
||||
|
||||
config ALPHA_EV5
|
||||
bool "EV5 CPU(s) (model 5/xxx)?" if ALPHA_LYNX
|
||||
default y if ALPHA_RX164 || ALPHA_RAWHIDE || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_SABLE && ALPHA_GAMMA || ALPHA_NORITAKE && ALPHA_PRIMO || ALPHA_MIKASA && ALPHA_PRIMO || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR
|
||||
|
||||
config ALPHA_EV4
|
||||
bool
|
||||
default y if ALPHA_LYNX && !ALPHA_EV5
|
||||
|
||||
config ALPHA_CIA
|
||||
bool
|
||||
depends on ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_NORITAKE && ALPHA_PRIMO || ALPHA_MIKASA && ALPHA_PRIMO || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR
|
||||
default y
|
||||
|
||||
config ALPHA_EV56
|
||||
bool "EV56 CPU (speed >= 366MHz)?" if ALPHA_ALCOR
|
||||
default y if ALPHA_RX164 || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_PC164 || ALPHA_TAKARA
|
||||
|
||||
config ALPHA_EV56
|
||||
prompt "EV56 CPU (speed >= 333MHz)?"
|
||||
depends on ALPHA_NORITAKE || ALPHA_PRIMO
|
||||
|
||||
config ALPHA_EV56
|
||||
prompt "EV56 CPU (speed >= 400MHz)?"
|
||||
depends on ALPHA_RAWHIDE
|
||||
|
||||
config ALPHA_PRIMO
|
||||
bool "EV5 CPU daughtercard (model 5/xxx)?"
|
||||
depends on ALPHA_NORITAKE || ALPHA_MIKASA
|
||||
help
|
||||
Say Y if you have an AS 1000 5/xxx or an AS 1000A 5/xxx.
|
||||
|
||||
config ALPHA_GAMMA
|
||||
bool "EV5 CPU(s) (model 5/xxx)?"
|
||||
depends on ALPHA_SABLE
|
||||
help
|
||||
Say Y if you have an AS 2000 5/xxx or an AS 2100 5/xxx.
|
||||
|
||||
config ALPHA_GAMMA
|
||||
bool
|
||||
depends on ALPHA_LYNX
|
||||
default y
|
||||
|
||||
config ALPHA_T2
|
||||
bool
|
||||
depends on ALPHA_SABLE || ALPHA_LYNX
|
||||
default y
|
||||
|
||||
config ALPHA_PYXIS
|
||||
bool
|
||||
depends on ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN
|
||||
default y
|
||||
|
||||
config ALPHA_EV6
|
||||
bool
|
||||
depends on ALPHA_NAUTILUS || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_DP264 || ALPHA_EIGER || ALPHA_MARVEL
|
||||
default y
|
||||
|
||||
config ALPHA_TSUNAMI
|
||||
bool
|
||||
depends on ALPHA_SHARK || ALPHA_DP264 || ALPHA_EIGER
|
||||
default y
|
||||
|
||||
config ALPHA_EV67
|
||||
bool "EV67 (or later) CPU (speed > 600MHz)?" if ALPHA_DP264 || ALPHA_EIGER
|
||||
default y if ALPHA_NAUTILUS || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL
|
||||
help
|
||||
Is this a machine based on the EV67 core? If in doubt, select N here
|
||||
and the machine will be treated as an EV6.
|
||||
|
||||
config ALPHA_MCPCIA
|
||||
bool
|
||||
depends on ALPHA_RAWHIDE
|
||||
default y
|
||||
|
||||
config ALPHA_POLARIS
|
||||
bool
|
||||
depends on ALPHA_RX164
|
||||
default y
|
||||
|
||||
config ALPHA_IRONGATE
|
||||
bool
|
||||
depends on ALPHA_NAUTILUS
|
||||
default y
|
||||
|
||||
config GENERIC_HWEIGHT
|
||||
bool
|
||||
default y if !ALPHA_EV67
|
||||
|
||||
config ALPHA_AVANTI
|
||||
bool
|
||||
depends on ALPHA_XL || ALPHA_AVANTI_CH
|
||||
default y
|
||||
help
|
||||
Avanti AS 200, AS 205, AS 250, AS 255, AS 300, and AS 400-based
|
||||
Alphas. Info at
|
||||
<http://www.unix-ag.org/Linux-Alpha/Architectures/Avanti.html>.
|
||||
|
||||
config ALPHA_BROKEN_IRQ_MASK
|
||||
bool
|
||||
depends on ALPHA_GENERIC || ALPHA_PC164
|
||||
default y
|
||||
|
||||
config VGA_HOSE
|
||||
bool
|
||||
depends on VGA_CONSOLE && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL || ALPHA_TSUNAMI)
|
||||
default y
|
||||
help
|
||||
Support VGA on an arbitrary hose; needed for several platforms
|
||||
which always have multiple hoses, and whose consoles support it.
|
||||
|
||||
|
||||
config ALPHA_QEMU
|
||||
bool "Run under QEMU emulation"
|
||||
depends on !ALPHA_GENERIC
|
||||
help
|
||||
Assume the presence of special features supported by QEMU PALcode
|
||||
that reduce the overhead of system emulation.
|
||||
|
||||
Generic kernels will auto-detect QEMU. But when building a
|
||||
system-specific kernel, the assumption is that we want to
|
||||
eliminate as many runtime tests as possible.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
|
||||
config ALPHA_SRM
|
||||
bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME
|
||||
depends on TTY
|
||||
default y if ALPHA_JENSEN || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_LYNX || ALPHA_NORITAKE || ALPHA_DP264 || ALPHA_RAWHIDE || ALPHA_EIGER || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL
|
||||
help
|
||||
There are two different types of booting firmware on Alphas: SRM,
|
||||
which is command line driven, and ARC, which uses menus and arrow
|
||||
keys. Details about the Linux/Alpha booting process are contained in
|
||||
the Linux/Alpha FAQ, accessible on the WWW from
|
||||
<http://www.alphalinux.org/>.
|
||||
|
||||
The usual way to load Linux on an Alpha machine is to use MILO
|
||||
(a bootloader that lets you pass command line parameters to the
|
||||
kernel just like lilo does for the x86 architecture) which can be
|
||||
loaded either from ARC or can be installed directly as a permanent
|
||||
firmware replacement from floppy (which requires changing a certain
|
||||
jumper on the motherboard). If you want to do either of these, say N
|
||||
here. If MILO doesn't work on your system (true for Jensen
|
||||
motherboards), you can bypass it altogether and boot Linux directly
|
||||
from an SRM console; say Y here in order to do that. Note that you
|
||||
won't be able to boot from an IDE disk using SRM.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config ARCH_MAY_HAVE_PC_FDC
|
||||
def_bool y
|
||||
|
||||
config SMP
|
||||
bool "Symmetric multi-processing support"
|
||||
depends on ALPHA_SABLE || ALPHA_LYNX || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL
|
||||
help
|
||||
This enables support for systems with more than one CPU. If you have
|
||||
a system with only one CPU, say N. If you have a system with more
|
||||
than one CPU, say Y.
|
||||
|
||||
If you say N here, the kernel will run on uni- and multiprocessor
|
||||
machines, but will use only one CPU of a multiprocessor machine. If
|
||||
you say Y here, the kernel will run on many, but not all,
|
||||
uniprocessor machines. On a uniprocessor machine, the kernel
|
||||
will run faster if you say N here.
|
||||
|
||||
See also the SMP-HOWTO available at
|
||||
<https://www.tldp.org/docs.html#howto>.
|
||||
|
||||
If you don't know what to do here, say N.
|
||||
|
||||
config NR_CPUS
|
||||
int "Maximum number of CPUs (2-32)"
|
||||
range 2 32
|
||||
depends on SMP
|
||||
default "32" if ALPHA_GENERIC || ALPHA_MARVEL
|
||||
default "4" if !ALPHA_GENERIC && !ALPHA_MARVEL
|
||||
help
|
||||
MARVEL support can handle a maximum of 32 CPUs, all the others
|
||||
with working support have a maximum of 4 CPUs.
|
||||
|
||||
config ARCH_SPARSEMEM_ENABLE
|
||||
bool "Sparse Memory Support"
|
||||
help
|
||||
Say Y to support efficient handling of discontiguous physical memory,
|
||||
for systems that have huge holes in the physical address space.
|
||||
|
||||
config ALPHA_WTINT
|
||||
bool "Use WTINT" if ALPHA_SRM || ALPHA_GENERIC
|
||||
default y if ALPHA_QEMU
|
||||
default n if ALPHA_EV5 || ALPHA_EV56 || (ALPHA_EV4 && !ALPHA_LCA)
|
||||
default n if !ALPHA_SRM && !ALPHA_GENERIC
|
||||
default y if SMP
|
||||
help
|
||||
The Wait for Interrupt (WTINT) PALcall attempts to place the CPU
|
||||
to sleep until the next interrupt. This may reduce the power
|
||||
consumed, and the heat produced by the computer. However, it has
|
||||
the side effect of making the cycle counter unreliable as a timing
|
||||
device across the sleep.
|
||||
|
||||
For emulation under QEMU, definitely say Y here, as we have other
|
||||
mechanisms for measuring time than the cycle counter.
|
||||
|
||||
For EV4 (but not LCA), EV5 and EV56 systems, or for systems running
|
||||
MILO, sleep mode is not supported so you might as well say N here.
|
||||
|
||||
For SMP systems we cannot use the cycle counter for timing anyway,
|
||||
so you might as well say Y here.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
# LARGE_VMALLOC is racy, if you *really* need it then fix it first
|
||||
config ALPHA_LARGE_VMALLOC
|
||||
bool
|
||||
help
|
||||
Process creation and other aspects of virtual memory management can
|
||||
be streamlined if we restrict the kernel to one PGD for all vmalloc
|
||||
allocations. This equates to about 8GB.
|
||||
|
||||
Under normal circumstances, this is so far and above what is needed
|
||||
as to be laughable. However, there are certain applications (such
|
||||
as benchmark-grade in-kernel web serving) that can make use of as
|
||||
much vmalloc space as is available.
|
||||
|
||||
Say N unless you know you need gobs and gobs of vmalloc space.
|
||||
|
||||
config VERBOSE_MCHECK
|
||||
bool "Verbose Machine Checks"
|
||||
|
||||
config VERBOSE_MCHECK_ON
|
||||
int "Verbose Printing Mode (0=off, 1=on, 2=all)"
|
||||
depends on VERBOSE_MCHECK
|
||||
default 1
|
||||
help
|
||||
This option allows the default printing mode to be set, and then
|
||||
possibly overridden by a boot command argument.
|
||||
|
||||
For example, if one wanted the option of printing verbose
|
||||
machine checks, but wanted the default to be as if verbose
|
||||
machine check printing was turned off, then one would choose
|
||||
the printing mode to be 0. Then, upon reboot, one could add
|
||||
the boot command line "verbose_mcheck=1" to get the normal
|
||||
verbose machine check printing, or "verbose_mcheck=2" to get
|
||||
the maximum information available.
|
||||
|
||||
Take the default (1) unless you want more control or more info.
|
||||
|
||||
choice
|
||||
prompt "Timer interrupt frequency (HZ)?"
|
||||
default HZ_128 if ALPHA_QEMU
|
||||
default HZ_1200 if ALPHA_RAWHIDE
|
||||
default HZ_1024
|
||||
help
|
||||
The frequency at which timer interrupts occur. A high frequency
|
||||
minimizes latency, whereas a low frequency minimizes overhead of
|
||||
process accounting. The later effect is especially significant
|
||||
when being run under QEMU.
|
||||
|
||||
Note that some Alpha hardware cannot change the interrupt frequency
|
||||
of the timer. If unsure, say 1024 (or 1200 for Rawhide).
|
||||
|
||||
config HZ_32
|
||||
bool "32 Hz"
|
||||
config HZ_64
|
||||
bool "64 Hz"
|
||||
config HZ_128
|
||||
bool "128 Hz"
|
||||
config HZ_256
|
||||
bool "256 Hz"
|
||||
config HZ_1024
|
||||
bool "1024 Hz"
|
||||
config HZ_1200
|
||||
bool "1200 Hz"
|
||||
endchoice
|
||||
|
||||
config HZ
|
||||
int
|
||||
default 32 if HZ_32
|
||||
default 64 if HZ_64
|
||||
default 128 if HZ_128
|
||||
default 256 if HZ_256
|
||||
default 1200 if HZ_1200
|
||||
default 1024
|
||||
|
||||
config SRM_ENV
|
||||
tristate "SRM environment through procfs"
|
||||
depends on PROC_FS
|
||||
help
|
||||
If you enable this option, a subdirectory inside /proc called
|
||||
/proc/srm_environment will give you access to the all important
|
||||
SRM environment variables (those which have a name) and also
|
||||
to all others (by their internal number).
|
||||
|
||||
SRM is something like a BIOS for Alpha machines. There are some
|
||||
other such BIOSes, like AlphaBIOS, which this driver cannot
|
||||
support (hey, that's not SRM!).
|
||||
|
||||
Despite the fact that this driver doesn't work on all Alphas (but
|
||||
only on those which have SRM as their firmware), it's save to
|
||||
build it even if your particular machine doesn't know about SRM
|
||||
(or if you intend to compile a generic kernel). It will simply
|
||||
not create those subdirectory in /proc (and give you some warning,
|
||||
of course).
|
||||
|
||||
This driver is also available as a module and will be called
|
||||
srm_env then.
|
||||
|
||||
endmenu
|
||||
|
||||
# DUMMY_CONSOLE may be defined in drivers/video/console/Kconfig
|
||||
# but we also need it if VGA_HOSE is set
|
||||
config DUMMY_CONSOLE
|
||||
bool
|
||||
depends on VGA_HOSE
|
||||
default y
|
38
arch/alpha/Kconfig.debug
Normal file
38
arch/alpha/Kconfig.debug
Normal file
@ -0,0 +1,38 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
config EARLY_PRINTK
|
||||
bool
|
||||
depends on ALPHA_GENERIC || ALPHA_SRM
|
||||
default y
|
||||
|
||||
config ALPHA_LEGACY_START_ADDRESS
|
||||
bool "Legacy kernel start address"
|
||||
depends on ALPHA_GENERIC
|
||||
default n
|
||||
help
|
||||
The 2.4 kernel changed the kernel start address from 0x310000
|
||||
to 0x810000 to make room for the Wildfire's larger SRM console.
|
||||
Recent consoles on Titan and Marvel machines also require the
|
||||
extra room.
|
||||
|
||||
If you're using aboot 0.7 or later, the bootloader will examine the
|
||||
ELF headers to determine where to transfer control. Unfortunately,
|
||||
most older bootloaders -- APB or MILO -- hardcoded the kernel start
|
||||
address rather than examining the ELF headers, and the result is a
|
||||
hard lockup.
|
||||
|
||||
Say Y if you have a broken bootloader. Say N if you do not, or if
|
||||
you wish to run on Wildfire, Titan, or Marvel.
|
||||
|
||||
config ALPHA_LEGACY_START_ADDRESS
|
||||
bool
|
||||
depends on !ALPHA_GENERIC && !ALPHA_TITAN && !ALPHA_MARVEL && !ALPHA_WILDFIRE
|
||||
default y
|
||||
|
||||
config MATHEMU
|
||||
tristate "Kernel FP software completion" if DEBUG_KERNEL && !SMP
|
||||
default y if !DEBUG_KERNEL || SMP
|
||||
help
|
||||
This option is required for IEEE compliant floating point arithmetic
|
||||
on the Alpha. The only time you would ever not say Y is to say M in
|
||||
order to debug the code. Say Y unless you know what you are doing.
|
66
arch/alpha/Makefile
Normal file
66
arch/alpha/Makefile
Normal file
@ -0,0 +1,66 @@
|
||||
#
|
||||
# alpha/Makefile
|
||||
#
|
||||
# This file is subject to the terms and conditions of the GNU General Public
|
||||
# License. See the file "COPYING" in the main directory of this archive
|
||||
# for more details.
|
||||
#
|
||||
# Copyright (C) 1994 by Linus Torvalds
|
||||
#
|
||||
|
||||
NM := $(NM) -B
|
||||
|
||||
LDFLAGS_vmlinux := -static -N #-relax
|
||||
CHECKFLAGS += -D__alpha__
|
||||
cflags-y := -pipe -mno-fp-regs -ffixed-8
|
||||
cflags-y += $(call cc-option, -fno-jump-tables)
|
||||
|
||||
cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4
|
||||
cpuflags-$(CONFIG_ALPHA_EV5) := -mcpu=ev5
|
||||
cpuflags-$(CONFIG_ALPHA_EV56) := -mcpu=ev56
|
||||
cpuflags-$(CONFIG_ALPHA_POLARIS) := -mcpu=pca56
|
||||
cpuflags-$(CONFIG_ALPHA_SX164) := -mcpu=pca56
|
||||
cpuflags-$(CONFIG_ALPHA_EV6) := -mcpu=ev6
|
||||
cpuflags-$(CONFIG_ALPHA_EV67) := -mcpu=ev67
|
||||
# If GENERIC, make sure to turn off any instruction set extensions that
|
||||
# the host compiler might have on by default. Given that EV4 and EV5
|
||||
# have the same instruction set, prefer EV5 because an EV5 schedule is
|
||||
# more likely to keep an EV4 processor busy than vice-versa.
|
||||
cpuflags-$(CONFIG_ALPHA_GENERIC) := -mcpu=ev5
|
||||
|
||||
cflags-y += $(cpuflags-y)
|
||||
|
||||
|
||||
# For TSUNAMI, we must have the assembler not emulate our instructions.
|
||||
# The same is true for IRONGATE, POLARIS, PYXIS.
|
||||
# BWX is most important, but we don't really want any emulation ever.
|
||||
KBUILD_CFLAGS += $(cflags-y) -Wa,-mev6
|
||||
|
||||
head-y := arch/alpha/kernel/head.o
|
||||
|
||||
libs-y += arch/alpha/lib/
|
||||
|
||||
# export what is needed by arch/alpha/boot/Makefile
|
||||
LIBS_Y := $(patsubst %/, %/lib.a, $(libs-y))
|
||||
export LIBS_Y
|
||||
|
||||
boot := arch/alpha/boot
|
||||
|
||||
#Default target when executing make with no arguments
|
||||
all boot: $(boot)/vmlinux.gz
|
||||
|
||||
$(boot)/vmlinux.gz: vmlinux
|
||||
$(Q)$(MAKE) $(build)=$(boot) $@
|
||||
|
||||
bootimage bootpfile bootpzfile: vmlinux
|
||||
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
|
||||
|
||||
archheaders:
|
||||
$(Q)$(MAKE) $(build)=arch/alpha/kernel/syscalls all
|
||||
|
||||
define archhelp
|
||||
echo '* boot - Compressed kernel image (arch/alpha/boot/vmlinux.gz)'
|
||||
echo ' bootimage - SRM bootable image (arch/alpha/boot/bootimage)'
|
||||
echo ' bootpfile - BOOTP bootable image (arch/alpha/boot/bootpfile)'
|
||||
echo ' bootpzfile - compressed kernel BOOTP image (arch/alpha/boot/bootpzfile)'
|
||||
endef
|
120
arch/alpha/boot/Makefile
Normal file
120
arch/alpha/boot/Makefile
Normal file
@ -0,0 +1,120 @@
|
||||
#
|
||||
# arch/alpha/boot/Makefile
|
||||
#
|
||||
# This file is subject to the terms and conditions of the GNU General Public
|
||||
# License. See the file "COPYING" in the main directory of this archive
|
||||
# for more details.
|
||||
#
|
||||
# Copyright (C) 1994 by Linus Torvalds
|
||||
#
|
||||
|
||||
hostprogs := tools/mkbb tools/objstrip
|
||||
targets := vmlinux.gz vmlinux \
|
||||
vmlinux.nh tools/lxboot tools/bootlx tools/bootph \
|
||||
tools/bootpzh bootloader bootpheader bootpzheader
|
||||
OBJSTRIP := $(obj)/tools/objstrip
|
||||
|
||||
KBUILD_HOSTCFLAGS := -Wall -I$(objtree)/usr/include
|
||||
BOOTCFLAGS += -I$(objtree)/$(obj) -I$(srctree)/$(obj)
|
||||
|
||||
# SRM bootable image. Copy to offset 512 of a partition.
|
||||
$(obj)/bootimage: $(addprefix $(obj)/tools/,mkbb lxboot bootlx) $(obj)/vmlinux.nh
|
||||
( cat $(obj)/tools/lxboot $(obj)/tools/bootlx $(obj)/vmlinux.nh ) > $@
|
||||
$(obj)/tools/mkbb $@ $(obj)/tools/lxboot
|
||||
@echo ' Bootimage $@ is ready'
|
||||
|
||||
# BOOTP bootable image. Define INITRD during make to append initrd image.
|
||||
$(obj)/bootpfile: $(obj)/tools/bootph $(obj)/vmlinux.nh
|
||||
cat $(obj)/tools/bootph $(obj)/vmlinux.nh > $@
|
||||
ifdef INITRD
|
||||
cat $(INITRD) >> $@
|
||||
endif
|
||||
|
||||
# Compressed kernel BOOTP bootable image.
|
||||
# Define INITRD during make to append initrd image.
|
||||
$(obj)/bootpzfile: $(obj)/tools/bootpzh $(obj)/vmlinux.nh.gz
|
||||
cat $(obj)/tools/bootpzh $(obj)/vmlinux.nh.gz > $@
|
||||
ifdef INITRD
|
||||
cat $(INITRD) >> $@
|
||||
endif
|
||||
|
||||
# Compressed kernel image
|
||||
$(obj)/vmlinux.gz: $(obj)/vmlinux FORCE
|
||||
$(call if_changed,gzip)
|
||||
@echo ' Kernel $@ is ready'
|
||||
|
||||
$(obj)/main.o: $(obj)/ksize.h
|
||||
$(obj)/bootp.o: $(obj)/ksize.h
|
||||
$(obj)/bootpz.o: $(obj)/kzsize.h
|
||||
|
||||
$(obj)/ksize.h: $(obj)/vmlinux.nh FORCE
|
||||
echo "#define KERNEL_SIZE `ls -l $(obj)/vmlinux.nh | awk '{print $$5}'`" > $@T
|
||||
ifdef INITRD
|
||||
[ -f $(INITRD) ] || exit 1
|
||||
echo "#define INITRD_IMAGE_SIZE `ls -l $(INITRD) | awk '{print $$5}'`" >> $@T
|
||||
endif
|
||||
cmp -s $@T $@ || mv -f $@T $@
|
||||
rm -f $@T
|
||||
|
||||
$(obj)/kzsize.h: $(obj)/vmlinux.nh.gz FORCE
|
||||
echo "#define KERNEL_SIZE `ls -l $(obj)/vmlinux.nh | awk '{print $$5}'`" > $@T
|
||||
echo "#define KERNEL_Z_SIZE `ls -l $(obj)/vmlinux.nh.gz | awk '{print $$5}'`" >> $@T
|
||||
ifdef INITRD
|
||||
[ -f $(INITRD) ] || exit 1
|
||||
echo "#define INITRD_IMAGE_SIZE `ls -l $(INITRD) | awk '{print $$5}'`" >> $@T
|
||||
endif
|
||||
cmp -s $@T $@ || mv -f $@T $@
|
||||
rm -f $@T
|
||||
|
||||
quiet_cmd_strip = STRIP $@
|
||||
cmd_strip = $(STRIP) -o $@ $<
|
||||
|
||||
$(obj)/vmlinux: vmlinux FORCE
|
||||
$(call if_changed,strip)
|
||||
|
||||
quiet_cmd_objstrip = OBJSTRIP $@
|
||||
cmd_objstrip = $(OBJSTRIP) $(OSFLAGS_$(@F)) $< $@
|
||||
|
||||
OSFLAGS_vmlinux.nh := -v
|
||||
OSFLAGS_lxboot := -p
|
||||
OSFLAGS_bootlx := -vb
|
||||
OSFLAGS_bootph := -vb
|
||||
OSFLAGS_bootpzh := -vb
|
||||
|
||||
$(obj)/vmlinux.nh: vmlinux $(OBJSTRIP) FORCE
|
||||
$(call if_changed,objstrip)
|
||||
|
||||
$(obj)/vmlinux.nh.gz: $(obj)/vmlinux.nh FORCE
|
||||
$(call if_changed,gzip)
|
||||
|
||||
$(obj)/tools/lxboot: $(obj)/bootloader $(OBJSTRIP) FORCE
|
||||
$(call if_changed,objstrip)
|
||||
|
||||
$(obj)/tools/bootlx: $(obj)/bootloader $(OBJSTRIP) FORCE
|
||||
$(call if_changed,objstrip)
|
||||
|
||||
$(obj)/tools/bootph: $(obj)/bootpheader $(OBJSTRIP) FORCE
|
||||
$(call if_changed,objstrip)
|
||||
|
||||
$(obj)/tools/bootpzh: $(obj)/bootpzheader $(OBJSTRIP) FORCE
|
||||
$(call if_changed,objstrip)
|
||||
|
||||
LDFLAGS_bootloader := -static -T # -N -relax
|
||||
LDFLAGS_bootloader := -static -T # -N -relax
|
||||
LDFLAGS_bootpheader := -static -T # -N -relax
|
||||
LDFLAGS_bootpzheader := -static -T # -N -relax
|
||||
|
||||
OBJ_bootlx := $(obj)/head.o $(obj)/stdio.o $(obj)/main.o
|
||||
OBJ_bootph := $(obj)/head.o $(obj)/stdio.o $(obj)/bootp.o
|
||||
OBJ_bootpzh := $(obj)/head.o $(obj)/stdio.o $(obj)/bootpz.o $(obj)/misc.o
|
||||
|
||||
$(obj)/bootloader: $(obj)/bootloader.lds $(OBJ_bootlx) $(LIBS_Y) FORCE
|
||||
$(call if_changed,ld)
|
||||
|
||||
$(obj)/bootpheader: $(obj)/bootloader.lds $(OBJ_bootph) $(LIBS_Y) FORCE
|
||||
$(call if_changed,ld)
|
||||
|
||||
$(obj)/bootpzheader: $(obj)/bootloader.lds $(OBJ_bootpzh) $(LIBS_Y) FORCE
|
||||
$(call if_changed,ld)
|
||||
|
||||
$(obj)/misc.o: lib/inflate.c
|
25
arch/alpha/boot/bootloader.lds
Normal file
25
arch/alpha/boot/bootloader.lds
Normal file
@ -0,0 +1,25 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
OUTPUT_FORMAT("elf64-alpha")
|
||||
ENTRY(__start)
|
||||
printk = srm_printk;
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x20000000;
|
||||
.text : { *(.text) }
|
||||
_etext = .;
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata) *(.rodata.*) }
|
||||
.data : { *(.data) CONSTRUCTORS }
|
||||
.got : { *(.got) }
|
||||
.sdata : { *(.sdata) }
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
.sbss : { *(.sbss) *(.scommon) }
|
||||
.bss : { *(.bss) *(COMMON) }
|
||||
_end = . ;
|
||||
PROVIDE (end = .);
|
||||
|
||||
.mdebug 0 : { *(.mdebug) }
|
||||
.note 0 : { *(.note) }
|
||||
.comment 0 : { *(.comment) }
|
||||
}
|
214
arch/alpha/boot/bootp.c
Normal file
214
arch/alpha/boot/bootp.c
Normal file
@ -0,0 +1,214 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* arch/alpha/boot/bootp.c
|
||||
*
|
||||
* Copyright (C) 1997 Jay Estabrook
|
||||
*
|
||||
* This file is used for creating a bootp file for the Linux/AXP kernel
|
||||
*
|
||||
* based significantly on the arch/alpha/boot/main.c of Linus Torvalds
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <generated/utsrelease.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/console.h>
|
||||
#include <asm/hwrpb.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "ksize.h"
|
||||
|
||||
extern unsigned long switch_to_osf_pal(unsigned long nr,
|
||||
struct pcb_struct *pcb_va, struct pcb_struct *pcb_pa,
|
||||
unsigned long *vptb);
|
||||
|
||||
extern void move_stack(unsigned long new_stack);
|
||||
|
||||
struct hwrpb_struct *hwrpb = INIT_HWRPB;
|
||||
static struct pcb_struct pcb_va[1];
|
||||
|
||||
/*
|
||||
* Find a physical address of a virtual object..
|
||||
*
|
||||
* This is easy using the virtual page table address.
|
||||
*/
|
||||
|
||||
static inline void *
|
||||
find_pa(unsigned long *vptb, void *ptr)
|
||||
{
|
||||
unsigned long address = (unsigned long) ptr;
|
||||
unsigned long result;
|
||||
|
||||
result = vptb[address >> 13];
|
||||
result >>= 32;
|
||||
result <<= 13;
|
||||
result |= address & 0x1fff;
|
||||
return (void *) result;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function moves into OSF/1 pal-code, and has a temporary
|
||||
* PCB for that. The kernel proper should replace this PCB with
|
||||
* the real one as soon as possible.
|
||||
*
|
||||
* The page table muckery in here depends on the fact that the boot
|
||||
* code has the L1 page table identity-map itself in the second PTE
|
||||
* in the L1 page table. Thus the L1-page is virtually addressable
|
||||
* itself (through three levels) at virtual address 0x200802000.
|
||||
*/
|
||||
|
||||
#define VPTB ((unsigned long *) 0x200000000)
|
||||
#define L1 ((unsigned long *) 0x200802000)
|
||||
|
||||
void
|
||||
pal_init(void)
|
||||
{
|
||||
unsigned long i, rev;
|
||||
struct percpu_struct * percpu;
|
||||
struct pcb_struct * pcb_pa;
|
||||
|
||||
/* Create the dummy PCB. */
|
||||
pcb_va->ksp = 0;
|
||||
pcb_va->usp = 0;
|
||||
pcb_va->ptbr = L1[1] >> 32;
|
||||
pcb_va->asn = 0;
|
||||
pcb_va->pcc = 0;
|
||||
pcb_va->unique = 0;
|
||||
pcb_va->flags = 1;
|
||||
pcb_va->res1 = 0;
|
||||
pcb_va->res2 = 0;
|
||||
pcb_pa = find_pa(VPTB, pcb_va);
|
||||
|
||||
/*
|
||||
* a0 = 2 (OSF)
|
||||
* a1 = return address, but we give the asm the vaddr of the PCB
|
||||
* a2 = physical addr of PCB
|
||||
* a3 = new virtual page table pointer
|
||||
* a4 = KSP (but the asm sets it)
|
||||
*/
|
||||
srm_printk("Switching to OSF PAL-code .. ");
|
||||
|
||||
i = switch_to_osf_pal(2, pcb_va, pcb_pa, VPTB);
|
||||
if (i) {
|
||||
srm_printk("failed, code %ld\n", i);
|
||||
__halt();
|
||||
}
|
||||
|
||||
percpu = (struct percpu_struct *)
|
||||
(INIT_HWRPB->processor_offset + (unsigned long) INIT_HWRPB);
|
||||
rev = percpu->pal_revision = percpu->palcode_avail[2];
|
||||
|
||||
srm_printk("Ok (rev %lx)\n", rev);
|
||||
|
||||
tbia(); /* do it directly in case we are SMP */
|
||||
}
|
||||
|
||||
static inline void
|
||||
load(unsigned long dst, unsigned long src, unsigned long count)
|
||||
{
|
||||
memcpy((void *)dst, (void *)src, count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start the kernel.
|
||||
*/
|
||||
static inline void
|
||||
runkernel(void)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"bis %0,%0,$27\n\t"
|
||||
"jmp ($27)"
|
||||
: /* no outputs: it doesn't even return */
|
||||
: "r" (START_ADDR));
|
||||
}
|
||||
|
||||
extern char _end;
|
||||
#define KERNEL_ORIGIN \
|
||||
((((unsigned long)&_end) + 511) & ~511)
|
||||
|
||||
void
|
||||
start_kernel(void)
|
||||
{
|
||||
/*
|
||||
* Note that this crufty stuff with static and envval
|
||||
* and envbuf is because:
|
||||
*
|
||||
* 1. Frequently, the stack is short, and we don't want to overrun;
|
||||
* 2. Frequently the stack is where we are going to copy the kernel to;
|
||||
* 3. A certain SRM console required the GET_ENV output to stack.
|
||||
* ??? A comment in the aboot sources indicates that the GET_ENV
|
||||
* destination must be quadword aligned. Might this explain the
|
||||
* behaviour, rather than requiring output to the stack, which
|
||||
* seems rather far-fetched.
|
||||
*/
|
||||
static long nbytes;
|
||||
static char envval[256] __attribute__((aligned(8)));
|
||||
static unsigned long initrd_start;
|
||||
|
||||
srm_printk("Linux/AXP bootp loader for Linux " UTS_RELEASE "\n");
|
||||
if (INIT_HWRPB->pagesize != 8192) {
|
||||
srm_printk("Expected 8kB pages, got %ldkB\n",
|
||||
INIT_HWRPB->pagesize >> 10);
|
||||
return;
|
||||
}
|
||||
if (INIT_HWRPB->vptb != (unsigned long) VPTB) {
|
||||
srm_printk("Expected vptb at %p, got %p\n",
|
||||
VPTB, (void *)INIT_HWRPB->vptb);
|
||||
return;
|
||||
}
|
||||
pal_init();
|
||||
|
||||
/* The initrd must be page-aligned. See below for the
|
||||
cause of the magic number 5. */
|
||||
initrd_start = ((START_ADDR + 5*KERNEL_SIZE + PAGE_SIZE) |
|
||||
(PAGE_SIZE-1)) + 1;
|
||||
#ifdef INITRD_IMAGE_SIZE
|
||||
srm_printk("Initrd positioned at %#lx\n", initrd_start);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Move the stack to a safe place to ensure it won't be
|
||||
* overwritten by kernel image.
|
||||
*/
|
||||
move_stack(initrd_start - PAGE_SIZE);
|
||||
|
||||
nbytes = callback_getenv(ENV_BOOTED_OSFLAGS, envval, sizeof(envval));
|
||||
if (nbytes < 0 || nbytes >= sizeof(envval)) {
|
||||
nbytes = 0;
|
||||
}
|
||||
envval[nbytes] = '\0';
|
||||
srm_printk("Loading the kernel...'%s'\n", envval);
|
||||
|
||||
/* NOTE: *no* callbacks or printouts from here on out!!! */
|
||||
|
||||
/* This is a hack, as some consoles seem to get virtual 20000000 (ie
|
||||
* where the SRM console puts the kernel bootp image) memory
|
||||
* overlapping physical memory where the kernel wants to be put,
|
||||
* which causes real problems when attempting to copy the former to
|
||||
* the latter... :-(
|
||||
*
|
||||
* So, we first move the kernel virtual-to-physical way above where
|
||||
* we physically want the kernel to end up, then copy it from there
|
||||
* to its final resting place... ;-}
|
||||
*
|
||||
* Sigh... */
|
||||
|
||||
#ifdef INITRD_IMAGE_SIZE
|
||||
load(initrd_start, KERNEL_ORIGIN+KERNEL_SIZE, INITRD_IMAGE_SIZE);
|
||||
#endif
|
||||
load(START_ADDR+(4*KERNEL_SIZE), KERNEL_ORIGIN, KERNEL_SIZE);
|
||||
load(START_ADDR, START_ADDR+(4*KERNEL_SIZE), KERNEL_SIZE);
|
||||
|
||||
memset((char*)ZERO_PGE, 0, PAGE_SIZE);
|
||||
strcpy((char*)ZERO_PGE, envval);
|
||||
#ifdef INITRD_IMAGE_SIZE
|
||||
((long *)(ZERO_PGE+256))[0] = initrd_start;
|
||||
((long *)(ZERO_PGE+256))[1] = INITRD_IMAGE_SIZE;
|
||||
#endif
|
||||
|
||||
runkernel();
|
||||
}
|
475
arch/alpha/boot/bootpz.c
Normal file
475
arch/alpha/boot/bootpz.c
Normal file
@ -0,0 +1,475 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* arch/alpha/boot/bootpz.c
|
||||
*
|
||||
* Copyright (C) 1997 Jay Estabrook
|
||||
*
|
||||
* This file is used for creating a compressed BOOTP file for the
|
||||
* Linux/AXP kernel
|
||||
*
|
||||
* based significantly on the arch/alpha/boot/main.c of Linus Torvalds
|
||||
* and the decompression code from MILO.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <generated/utsrelease.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/console.h>
|
||||
#include <asm/hwrpb.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "kzsize.h"
|
||||
|
||||
/* FIXME FIXME FIXME */
|
||||
#define MALLOC_AREA_SIZE 0x200000 /* 2MB for now */
|
||||
/* FIXME FIXME FIXME */
|
||||
|
||||
|
||||
/*
|
||||
WARNING NOTE
|
||||
|
||||
It is very possible that turning on additional messages may cause
|
||||
kernel image corruption due to stack usage to do the printing.
|
||||
|
||||
*/
|
||||
|
||||
#undef DEBUG_CHECK_RANGE
|
||||
#undef DEBUG_ADDRESSES
|
||||
#undef DEBUG_LAST_STEPS
|
||||
|
||||
extern unsigned long switch_to_osf_pal(unsigned long nr,
|
||||
struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
|
||||
unsigned long *vptb);
|
||||
|
||||
extern int decompress_kernel(void* destination, void *source,
|
||||
size_t ksize, size_t kzsize);
|
||||
|
||||
extern void move_stack(unsigned long new_stack);
|
||||
|
||||
struct hwrpb_struct *hwrpb = INIT_HWRPB;
|
||||
static struct pcb_struct pcb_va[1];
|
||||
|
||||
/*
|
||||
* Find a physical address of a virtual object..
|
||||
*
|
||||
* This is easy using the virtual page table address.
|
||||
*/
|
||||
#define VPTB ((unsigned long *) 0x200000000)
|
||||
|
||||
static inline unsigned long
|
||||
find_pa(unsigned long address)
|
||||
{
|
||||
unsigned long result;
|
||||
|
||||
result = VPTB[address >> 13];
|
||||
result >>= 32;
|
||||
result <<= 13;
|
||||
result |= address & 0x1fff;
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
check_range(unsigned long vstart, unsigned long vend,
|
||||
unsigned long kstart, unsigned long kend)
|
||||
{
|
||||
unsigned long vaddr, kaddr;
|
||||
|
||||
#ifdef DEBUG_CHECK_RANGE
|
||||
srm_printk("check_range: V[0x%lx:0x%lx] K[0x%lx:0x%lx]\n",
|
||||
vstart, vend, kstart, kend);
|
||||
#endif
|
||||
/* do some range checking for detecting an overlap... */
|
||||
for (vaddr = vstart; vaddr <= vend; vaddr += PAGE_SIZE)
|
||||
{
|
||||
kaddr = (find_pa(vaddr) | PAGE_OFFSET);
|
||||
if (kaddr >= kstart && kaddr <= kend)
|
||||
{
|
||||
#ifdef DEBUG_CHECK_RANGE
|
||||
srm_printk("OVERLAP: vaddr 0x%lx kaddr 0x%lx"
|
||||
" [0x%lx:0x%lx]\n",
|
||||
vaddr, kaddr, kstart, kend);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function moves into OSF/1 pal-code, and has a temporary
|
||||
* PCB for that. The kernel proper should replace this PCB with
|
||||
* the real one as soon as possible.
|
||||
*
|
||||
* The page table muckery in here depends on the fact that the boot
|
||||
* code has the L1 page table identity-map itself in the second PTE
|
||||
* in the L1 page table. Thus the L1-page is virtually addressable
|
||||
* itself (through three levels) at virtual address 0x200802000.
|
||||
*/
|
||||
|
||||
#define L1 ((unsigned long *) 0x200802000)
|
||||
|
||||
void
|
||||
pal_init(void)
|
||||
{
|
||||
unsigned long i, rev;
|
||||
struct percpu_struct * percpu;
|
||||
struct pcb_struct * pcb_pa;
|
||||
|
||||
/* Create the dummy PCB. */
|
||||
pcb_va->ksp = 0;
|
||||
pcb_va->usp = 0;
|
||||
pcb_va->ptbr = L1[1] >> 32;
|
||||
pcb_va->asn = 0;
|
||||
pcb_va->pcc = 0;
|
||||
pcb_va->unique = 0;
|
||||
pcb_va->flags = 1;
|
||||
pcb_va->res1 = 0;
|
||||
pcb_va->res2 = 0;
|
||||
pcb_pa = (struct pcb_struct *)find_pa((unsigned long)pcb_va);
|
||||
|
||||
/*
|
||||
* a0 = 2 (OSF)
|
||||
* a1 = return address, but we give the asm the vaddr of the PCB
|
||||
* a2 = physical addr of PCB
|
||||
* a3 = new virtual page table pointer
|
||||
* a4 = KSP (but the asm sets it)
|
||||
*/
|
||||
srm_printk("Switching to OSF PAL-code... ");
|
||||
|
||||
i = switch_to_osf_pal(2, pcb_va, pcb_pa, VPTB);
|
||||
if (i) {
|
||||
srm_printk("failed, code %ld\n", i);
|
||||
__halt();
|
||||
}
|
||||
|
||||
percpu = (struct percpu_struct *)
|
||||
(INIT_HWRPB->processor_offset + (unsigned long) INIT_HWRPB);
|
||||
rev = percpu->pal_revision = percpu->palcode_avail[2];
|
||||
|
||||
srm_printk("OK (rev %lx)\n", rev);
|
||||
|
||||
tbia(); /* do it directly in case we are SMP */
|
||||
}
|
||||
|
||||
/*
|
||||
* Start the kernel.
|
||||
*/
|
||||
static inline void
|
||||
runkernel(void)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"bis %0,%0,$27\n\t"
|
||||
"jmp ($27)"
|
||||
: /* no outputs: it doesn't even return */
|
||||
: "r" (START_ADDR));
|
||||
}
|
||||
|
||||
/* Must record the SP (it is virtual) on entry, so we can make sure
|
||||
not to overwrite it during movement or decompression. */
|
||||
unsigned long SP_on_entry;
|
||||
|
||||
/* Calculate the kernel image address based on the end of the BOOTP
|
||||
bootstrapper (ie this program).
|
||||
*/
|
||||
extern char _end;
|
||||
#define KERNEL_ORIGIN \
|
||||
((((unsigned long)&_end) + 511) & ~511)
|
||||
|
||||
/* Round address to next higher page boundary. */
|
||||
#define NEXT_PAGE(a) (((a) | (PAGE_SIZE - 1)) + 1)
|
||||
|
||||
#ifdef INITRD_IMAGE_SIZE
|
||||
# define REAL_INITRD_SIZE INITRD_IMAGE_SIZE
|
||||
#else
|
||||
# define REAL_INITRD_SIZE 0
|
||||
#endif
|
||||
|
||||
/* Defines from include/asm-alpha/system.h
|
||||
|
||||
BOOT_ADDR Virtual address at which the consoles loads
|
||||
the BOOTP image.
|
||||
|
||||
KERNEL_START KSEG address at which the kernel is built to run,
|
||||
which includes some initial data pages before the
|
||||
code.
|
||||
|
||||
START_ADDR KSEG address of the entry point of kernel code.
|
||||
|
||||
ZERO_PGE KSEG address of page full of zeroes, but
|
||||
upon entry to kernel, it can be expected
|
||||
to hold the parameter list and possible
|
||||
INTRD information.
|
||||
|
||||
These are used in the local defines below.
|
||||
*/
|
||||
|
||||
|
||||
/* Virtual addresses for the BOOTP image. Note that this includes the
|
||||
bootstrapper code as well as the compressed kernel image, and
|
||||
possibly the INITRD image.
|
||||
|
||||
Oh, and do NOT forget the STACK, which appears to be placed virtually
|
||||
beyond the end of the loaded image.
|
||||
*/
|
||||
#define V_BOOT_IMAGE_START BOOT_ADDR
|
||||
#define V_BOOT_IMAGE_END SP_on_entry
|
||||
|
||||
/* Virtual addresses for just the bootstrapper part of the BOOTP image. */
|
||||
#define V_BOOTSTRAPPER_START BOOT_ADDR
|
||||
#define V_BOOTSTRAPPER_END KERNEL_ORIGIN
|
||||
|
||||
/* Virtual addresses for just the data part of the BOOTP
|
||||
image. This may also include the INITRD image, but always
|
||||
includes the STACK.
|
||||
*/
|
||||
#define V_DATA_START KERNEL_ORIGIN
|
||||
#define V_INITRD_START (KERNEL_ORIGIN + KERNEL_Z_SIZE)
|
||||
#define V_INTRD_END (V_INITRD_START + REAL_INITRD_SIZE)
|
||||
#define V_DATA_END V_BOOT_IMAGE_END
|
||||
|
||||
/* KSEG addresses for the uncompressed kernel.
|
||||
|
||||
Note that the end address includes workspace for the decompression.
|
||||
Note also that the DATA_START address is ZERO_PGE, to which we write
|
||||
just before jumping to the kernel image at START_ADDR.
|
||||
*/
|
||||
#define K_KERNEL_DATA_START ZERO_PGE
|
||||
#define K_KERNEL_IMAGE_START START_ADDR
|
||||
#define K_KERNEL_IMAGE_END (START_ADDR + KERNEL_SIZE)
|
||||
|
||||
/* Define to where we may have to decompress the kernel image, before
|
||||
we move it to the final position, in case of overlap. This will be
|
||||
above the final position of the kernel.
|
||||
|
||||
Regardless of overlap, we move the INITRD image to the end of this
|
||||
copy area, because there needs to be a buffer area after the kernel
|
||||
for "bootmem" anyway.
|
||||
*/
|
||||
#define K_COPY_IMAGE_START NEXT_PAGE(K_KERNEL_IMAGE_END)
|
||||
/* Reserve one page below INITRD for the new stack. */
|
||||
#define K_INITRD_START \
|
||||
NEXT_PAGE(K_COPY_IMAGE_START + KERNEL_SIZE + PAGE_SIZE)
|
||||
#define K_COPY_IMAGE_END \
|
||||
(K_INITRD_START + REAL_INITRD_SIZE + MALLOC_AREA_SIZE)
|
||||
#define K_COPY_IMAGE_SIZE \
|
||||
NEXT_PAGE(K_COPY_IMAGE_END - K_COPY_IMAGE_START)
|
||||
|
||||
void
|
||||
start_kernel(void)
|
||||
{
|
||||
int must_move = 0;
|
||||
|
||||
/* Initialize these for the decompression-in-place situation,
|
||||
which is the smallest amount of work and most likely to
|
||||
occur when using the normal START_ADDR of the kernel
|
||||
(currently set to 16MB, to clear all console code.
|
||||
*/
|
||||
unsigned long uncompressed_image_start = K_KERNEL_IMAGE_START;
|
||||
unsigned long uncompressed_image_end = K_KERNEL_IMAGE_END;
|
||||
|
||||
unsigned long initrd_image_start = K_INITRD_START;
|
||||
|
||||
/*
|
||||
* Note that this crufty stuff with static and envval
|
||||
* and envbuf is because:
|
||||
*
|
||||
* 1. Frequently, the stack is short, and we don't want to overrun;
|
||||
* 2. Frequently the stack is where we are going to copy the kernel to;
|
||||
* 3. A certain SRM console required the GET_ENV output to stack.
|
||||
* ??? A comment in the aboot sources indicates that the GET_ENV
|
||||
* destination must be quadword aligned. Might this explain the
|
||||
* behaviour, rather than requiring output to the stack, which
|
||||
* seems rather far-fetched.
|
||||
*/
|
||||
static long nbytes;
|
||||
static char envval[256] __attribute__((aligned(8)));
|
||||
register unsigned long asm_sp asm("30");
|
||||
|
||||
SP_on_entry = asm_sp;
|
||||
|
||||
srm_printk("Linux/Alpha BOOTPZ Loader for Linux " UTS_RELEASE "\n");
|
||||
|
||||
/* Validity check the HWRPB. */
|
||||
if (INIT_HWRPB->pagesize != 8192) {
|
||||
srm_printk("Expected 8kB pages, got %ldkB\n",
|
||||
INIT_HWRPB->pagesize >> 10);
|
||||
return;
|
||||
}
|
||||
if (INIT_HWRPB->vptb != (unsigned long) VPTB) {
|
||||
srm_printk("Expected vptb at %p, got %p\n",
|
||||
VPTB, (void *)INIT_HWRPB->vptb);
|
||||
return;
|
||||
}
|
||||
|
||||
/* PALcode (re)initialization. */
|
||||
pal_init();
|
||||
|
||||
/* Get the parameter list from the console environment variable. */
|
||||
nbytes = callback_getenv(ENV_BOOTED_OSFLAGS, envval, sizeof(envval));
|
||||
if (nbytes < 0 || nbytes >= sizeof(envval)) {
|
||||
nbytes = 0;
|
||||
}
|
||||
envval[nbytes] = '\0';
|
||||
|
||||
#ifdef DEBUG_ADDRESSES
|
||||
srm_printk("START_ADDR 0x%lx\n", START_ADDR);
|
||||
srm_printk("KERNEL_ORIGIN 0x%lx\n", KERNEL_ORIGIN);
|
||||
srm_printk("KERNEL_SIZE 0x%x\n", KERNEL_SIZE);
|
||||
srm_printk("KERNEL_Z_SIZE 0x%x\n", KERNEL_Z_SIZE);
|
||||
#endif
|
||||
|
||||
/* Since all the SRM consoles load the BOOTP image at virtual
|
||||
* 0x20000000, we have to ensure that the physical memory
|
||||
* pages occupied by that image do NOT overlap the physical
|
||||
* address range where the kernel wants to be run. This
|
||||
* causes real problems when attempting to cdecompress the
|
||||
* former into the latter... :-(
|
||||
*
|
||||
* So, we may have to decompress/move the kernel/INITRD image
|
||||
* virtual-to-physical someplace else first before moving
|
||||
* kernel /INITRD to their final resting places... ;-}
|
||||
*
|
||||
* Sigh...
|
||||
*/
|
||||
|
||||
/* First, check to see if the range of addresses occupied by
|
||||
the bootstrapper part of the BOOTP image include any of the
|
||||
physical pages into which the kernel will be placed for
|
||||
execution.
|
||||
|
||||
We only need check on the final kernel image range, since we
|
||||
will put the INITRD someplace that we can be sure is not
|
||||
in conflict.
|
||||
*/
|
||||
if (check_range(V_BOOTSTRAPPER_START, V_BOOTSTRAPPER_END,
|
||||
K_KERNEL_DATA_START, K_KERNEL_IMAGE_END))
|
||||
{
|
||||
srm_printk("FATAL ERROR: overlap of bootstrapper code\n");
|
||||
__halt();
|
||||
}
|
||||
|
||||
/* Next, check to see if the range of addresses occupied by
|
||||
the compressed kernel/INITRD/stack portion of the BOOTP
|
||||
image include any of the physical pages into which the
|
||||
decompressed kernel or the INITRD will be placed for
|
||||
execution.
|
||||
*/
|
||||
if (check_range(V_DATA_START, V_DATA_END,
|
||||
K_KERNEL_IMAGE_START, K_COPY_IMAGE_END))
|
||||
{
|
||||
#ifdef DEBUG_ADDRESSES
|
||||
srm_printk("OVERLAP: cannot decompress in place\n");
|
||||
#endif
|
||||
uncompressed_image_start = K_COPY_IMAGE_START;
|
||||
uncompressed_image_end = K_COPY_IMAGE_END;
|
||||
must_move = 1;
|
||||
|
||||
/* Finally, check to see if the range of addresses
|
||||
occupied by the compressed kernel/INITRD part of
|
||||
the BOOTP image include any of the physical pages
|
||||
into which that part is to be copied for
|
||||
decompression.
|
||||
*/
|
||||
while (check_range(V_DATA_START, V_DATA_END,
|
||||
uncompressed_image_start,
|
||||
uncompressed_image_end))
|
||||
{
|
||||
#if 0
|
||||
uncompressed_image_start += K_COPY_IMAGE_SIZE;
|
||||
uncompressed_image_end += K_COPY_IMAGE_SIZE;
|
||||
initrd_image_start += K_COPY_IMAGE_SIZE;
|
||||
#else
|
||||
/* Keep as close as possible to end of BOOTP image. */
|
||||
uncompressed_image_start += PAGE_SIZE;
|
||||
uncompressed_image_end += PAGE_SIZE;
|
||||
initrd_image_start += PAGE_SIZE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
srm_printk("Starting to load the kernel with args '%s'\n", envval);
|
||||
|
||||
#ifdef DEBUG_ADDRESSES
|
||||
srm_printk("Decompressing the kernel...\n"
|
||||
"...from 0x%lx to 0x%lx size 0x%x\n",
|
||||
V_DATA_START,
|
||||
uncompressed_image_start,
|
||||
KERNEL_SIZE);
|
||||
#endif
|
||||
decompress_kernel((void *)uncompressed_image_start,
|
||||
(void *)V_DATA_START,
|
||||
KERNEL_SIZE, KERNEL_Z_SIZE);
|
||||
|
||||
/*
|
||||
* Now, move things to their final positions, if/as required.
|
||||
*/
|
||||
|
||||
#ifdef INITRD_IMAGE_SIZE
|
||||
|
||||
/* First, we always move the INITRD image, if present. */
|
||||
#ifdef DEBUG_ADDRESSES
|
||||
srm_printk("Moving the INITRD image...\n"
|
||||
" from 0x%lx to 0x%lx size 0x%x\n",
|
||||
V_INITRD_START,
|
||||
initrd_image_start,
|
||||
INITRD_IMAGE_SIZE);
|
||||
#endif
|
||||
memcpy((void *)initrd_image_start, (void *)V_INITRD_START,
|
||||
INITRD_IMAGE_SIZE);
|
||||
|
||||
#endif /* INITRD_IMAGE_SIZE */
|
||||
|
||||
/* Next, we may have to move the uncompressed kernel to the
|
||||
final destination.
|
||||
*/
|
||||
if (must_move) {
|
||||
#ifdef DEBUG_ADDRESSES
|
||||
srm_printk("Moving the uncompressed kernel...\n"
|
||||
"...from 0x%lx to 0x%lx size 0x%x\n",
|
||||
uncompressed_image_start,
|
||||
K_KERNEL_IMAGE_START,
|
||||
(unsigned)KERNEL_SIZE);
|
||||
#endif
|
||||
/*
|
||||
* Move the stack to a safe place to ensure it won't be
|
||||
* overwritten by kernel image.
|
||||
*/
|
||||
move_stack(initrd_image_start - PAGE_SIZE);
|
||||
|
||||
memcpy((void *)K_KERNEL_IMAGE_START,
|
||||
(void *)uncompressed_image_start, KERNEL_SIZE);
|
||||
}
|
||||
|
||||
/* Clear the zero page, then move the argument list in. */
|
||||
#ifdef DEBUG_LAST_STEPS
|
||||
srm_printk("Preparing ZERO_PGE...\n");
|
||||
#endif
|
||||
memset((char*)ZERO_PGE, 0, PAGE_SIZE);
|
||||
strcpy((char*)ZERO_PGE, envval);
|
||||
|
||||
#ifdef INITRD_IMAGE_SIZE
|
||||
|
||||
#ifdef DEBUG_LAST_STEPS
|
||||
srm_printk("Preparing INITRD info...\n");
|
||||
#endif
|
||||
/* Finally, set the INITRD paramenters for the kernel. */
|
||||
((long *)(ZERO_PGE+256))[0] = initrd_image_start;
|
||||
((long *)(ZERO_PGE+256))[1] = INITRD_IMAGE_SIZE;
|
||||
|
||||
#endif /* INITRD_IMAGE_SIZE */
|
||||
|
||||
#ifdef DEBUG_LAST_STEPS
|
||||
srm_printk("Doing 'runkernel()'...\n");
|
||||
#endif
|
||||
runkernel();
|
||||
}
|
||||
|
||||
/* dummy function, should never be called. */
|
||||
void *__kmalloc(size_t size, gfp_t flags)
|
||||
{
|
||||
return (void *)NULL;
|
||||
}
|
124
arch/alpha/boot/head.S
Normal file
124
arch/alpha/boot/head.S
Normal file
@ -0,0 +1,124 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* arch/alpha/boot/head.S
|
||||
*
|
||||
* initial bootloader stuff..
|
||||
*/
|
||||
|
||||
#include <asm/pal.h>
|
||||
|
||||
.set noreorder
|
||||
.globl __start
|
||||
.ent __start
|
||||
__start:
|
||||
br $29,2f
|
||||
2: ldgp $29,0($29)
|
||||
jsr $26,start_kernel
|
||||
call_pal PAL_halt
|
||||
.end __start
|
||||
|
||||
.align 5
|
||||
.globl wrent
|
||||
.ent wrent
|
||||
wrent:
|
||||
.prologue 0
|
||||
call_pal PAL_wrent
|
||||
ret ($26)
|
||||
.end wrent
|
||||
|
||||
.align 5
|
||||
.globl wrkgp
|
||||
.ent wrkgp
|
||||
wrkgp:
|
||||
.prologue 0
|
||||
call_pal PAL_wrkgp
|
||||
ret ($26)
|
||||
.end wrkgp
|
||||
|
||||
.align 5
|
||||
.globl switch_to_osf_pal
|
||||
.ent switch_to_osf_pal
|
||||
switch_to_osf_pal:
|
||||
subq $30,128,$30
|
||||
.frame $30,128,$26
|
||||
stq $26,0($30)
|
||||
stq $1,8($30)
|
||||
stq $2,16($30)
|
||||
stq $3,24($30)
|
||||
stq $4,32($30)
|
||||
stq $5,40($30)
|
||||
stq $6,48($30)
|
||||
stq $7,56($30)
|
||||
stq $8,64($30)
|
||||
stq $9,72($30)
|
||||
stq $10,80($30)
|
||||
stq $11,88($30)
|
||||
stq $12,96($30)
|
||||
stq $13,104($30)
|
||||
stq $14,112($30)
|
||||
stq $15,120($30)
|
||||
.prologue 0
|
||||
|
||||
stq $30,0($17) /* save KSP in PCB */
|
||||
|
||||
bis $30,$30,$20 /* a4 = KSP */
|
||||
br $17,1f
|
||||
|
||||
ldq $26,0($30)
|
||||
ldq $1,8($30)
|
||||
ldq $2,16($30)
|
||||
ldq $3,24($30)
|
||||
ldq $4,32($30)
|
||||
ldq $5,40($30)
|
||||
ldq $6,48($30)
|
||||
ldq $7,56($30)
|
||||
ldq $8,64($30)
|
||||
ldq $9,72($30)
|
||||
ldq $10,80($30)
|
||||
ldq $11,88($30)
|
||||
ldq $12,96($30)
|
||||
ldq $13,104($30)
|
||||
ldq $14,112($30)
|
||||
ldq $15,120($30)
|
||||
addq $30,128,$30
|
||||
ret ($26)
|
||||
1: call_pal PAL_swppal
|
||||
.end switch_to_osf_pal
|
||||
|
||||
.align 3
|
||||
.globl tbi
|
||||
.ent tbi
|
||||
tbi:
|
||||
.prologue 0
|
||||
call_pal PAL_tbi
|
||||
ret ($26)
|
||||
.end tbi
|
||||
|
||||
.align 3
|
||||
.globl halt
|
||||
.ent halt
|
||||
halt:
|
||||
.prologue 0
|
||||
call_pal PAL_halt
|
||||
.end halt
|
||||
|
||||
/* $16 - new stack page */
|
||||
.align 3
|
||||
.globl move_stack
|
||||
.ent move_stack
|
||||
move_stack:
|
||||
.prologue 0
|
||||
lda $0, 0x1fff($31)
|
||||
and $0, $30, $1 /* Stack offset */
|
||||
or $1, $16, $16 /* New stack pointer */
|
||||
mov $30, $1
|
||||
mov $16, $2
|
||||
1: ldq $3, 0($1) /* Move the stack */
|
||||
addq $1, 8, $1
|
||||
stq $3, 0($2)
|
||||
and $0, $1, $4
|
||||
addq $2, 8, $2
|
||||
bne $4, 1b
|
||||
mov $16, $30
|
||||
ret ($26)
|
||||
.end move_stack
|
190
arch/alpha/boot/main.c
Normal file
190
arch/alpha/boot/main.c
Normal file
@ -0,0 +1,190 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* arch/alpha/boot/main.c
|
||||
*
|
||||
* Copyright (C) 1994, 1995 Linus Torvalds
|
||||
*
|
||||
* This file is the bootloader for the Linux/AXP kernel
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <generated/utsrelease.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/console.h>
|
||||
#include <asm/hwrpb.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "ksize.h"
|
||||
|
||||
extern unsigned long switch_to_osf_pal(unsigned long nr,
|
||||
struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
|
||||
unsigned long *vptb);
|
||||
struct hwrpb_struct *hwrpb = INIT_HWRPB;
|
||||
static struct pcb_struct pcb_va[1];
|
||||
|
||||
/*
|
||||
* Find a physical address of a virtual object..
|
||||
*
|
||||
* This is easy using the virtual page table address.
|
||||
*/
|
||||
|
||||
static inline void *
|
||||
find_pa(unsigned long *vptb, void *ptr)
|
||||
{
|
||||
unsigned long address = (unsigned long) ptr;
|
||||
unsigned long result;
|
||||
|
||||
result = vptb[address >> 13];
|
||||
result >>= 32;
|
||||
result <<= 13;
|
||||
result |= address & 0x1fff;
|
||||
return (void *) result;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function moves into OSF/1 pal-code, and has a temporary
|
||||
* PCB for that. The kernel proper should replace this PCB with
|
||||
* the real one as soon as possible.
|
||||
*
|
||||
* The page table muckery in here depends on the fact that the boot
|
||||
* code has the L1 page table identity-map itself in the second PTE
|
||||
* in the L1 page table. Thus the L1-page is virtually addressable
|
||||
* itself (through three levels) at virtual address 0x200802000.
|
||||
*/
|
||||
|
||||
#define VPTB ((unsigned long *) 0x200000000)
|
||||
#define L1 ((unsigned long *) 0x200802000)
|
||||
|
||||
void
|
||||
pal_init(void)
|
||||
{
|
||||
unsigned long i, rev;
|
||||
struct percpu_struct * percpu;
|
||||
struct pcb_struct * pcb_pa;
|
||||
|
||||
/* Create the dummy PCB. */
|
||||
pcb_va->ksp = 0;
|
||||
pcb_va->usp = 0;
|
||||
pcb_va->ptbr = L1[1] >> 32;
|
||||
pcb_va->asn = 0;
|
||||
pcb_va->pcc = 0;
|
||||
pcb_va->unique = 0;
|
||||
pcb_va->flags = 1;
|
||||
pcb_va->res1 = 0;
|
||||
pcb_va->res2 = 0;
|
||||
pcb_pa = find_pa(VPTB, pcb_va);
|
||||
|
||||
/*
|
||||
* a0 = 2 (OSF)
|
||||
* a1 = return address, but we give the asm the vaddr of the PCB
|
||||
* a2 = physical addr of PCB
|
||||
* a3 = new virtual page table pointer
|
||||
* a4 = KSP (but the asm sets it)
|
||||
*/
|
||||
srm_printk("Switching to OSF PAL-code .. ");
|
||||
|
||||
i = switch_to_osf_pal(2, pcb_va, pcb_pa, VPTB);
|
||||
if (i) {
|
||||
srm_printk("failed, code %ld\n", i);
|
||||
__halt();
|
||||
}
|
||||
|
||||
percpu = (struct percpu_struct *)
|
||||
(INIT_HWRPB->processor_offset + (unsigned long) INIT_HWRPB);
|
||||
rev = percpu->pal_revision = percpu->palcode_avail[2];
|
||||
|
||||
srm_printk("Ok (rev %lx)\n", rev);
|
||||
|
||||
tbia(); /* do it directly in case we are SMP */
|
||||
}
|
||||
|
||||
static inline long openboot(void)
|
||||
{
|
||||
char bootdev[256];
|
||||
long result;
|
||||
|
||||
result = callback_getenv(ENV_BOOTED_DEV, bootdev, 255);
|
||||
if (result < 0)
|
||||
return result;
|
||||
return callback_open(bootdev, result & 255);
|
||||
}
|
||||
|
||||
static inline long close(long dev)
|
||||
{
|
||||
return callback_close(dev);
|
||||
}
|
||||
|
||||
static inline long load(long dev, unsigned long addr, unsigned long count)
|
||||
{
|
||||
char bootfile[256];
|
||||
extern char _end;
|
||||
long result, boot_size = &_end - (char *) BOOT_ADDR;
|
||||
|
||||
result = callback_getenv(ENV_BOOTED_FILE, bootfile, 255);
|
||||
if (result < 0)
|
||||
return result;
|
||||
result &= 255;
|
||||
bootfile[result] = '\0';
|
||||
if (result)
|
||||
srm_printk("Boot file specification (%s) not implemented\n",
|
||||
bootfile);
|
||||
return callback_read(dev, count, (void *)addr, boot_size/512 + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start the kernel.
|
||||
*/
|
||||
static void runkernel(void)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"bis %1,%1,$30\n\t"
|
||||
"bis %0,%0,$26\n\t"
|
||||
"ret ($26)"
|
||||
: /* no outputs: it doesn't even return */
|
||||
: "r" (START_ADDR),
|
||||
"r" (PAGE_SIZE + INIT_STACK));
|
||||
}
|
||||
|
||||
void start_kernel(void)
|
||||
{
|
||||
long i;
|
||||
long dev;
|
||||
int nbytes;
|
||||
char envval[256];
|
||||
|
||||
srm_printk("Linux/AXP bootloader for Linux " UTS_RELEASE "\n");
|
||||
if (INIT_HWRPB->pagesize != 8192) {
|
||||
srm_printk("Expected 8kB pages, got %ldkB\n", INIT_HWRPB->pagesize >> 10);
|
||||
return;
|
||||
}
|
||||
pal_init();
|
||||
dev = openboot();
|
||||
if (dev < 0) {
|
||||
srm_printk("Unable to open boot device: %016lx\n", dev);
|
||||
return;
|
||||
}
|
||||
dev &= 0xffffffff;
|
||||
srm_printk("Loading vmlinux ...");
|
||||
i = load(dev, START_ADDR, KERNEL_SIZE);
|
||||
close(dev);
|
||||
if (i != KERNEL_SIZE) {
|
||||
srm_printk("Failed (%lx)\n", i);
|
||||
return;
|
||||
}
|
||||
|
||||
nbytes = callback_getenv(ENV_BOOTED_OSFLAGS, envval, sizeof(envval));
|
||||
if (nbytes < 0) {
|
||||
nbytes = 0;
|
||||
}
|
||||
envval[nbytes] = '\0';
|
||||
strcpy((char*)ZERO_PGE, envval);
|
||||
|
||||
srm_printk(" Ok\nNow booting the kernel\n");
|
||||
runkernel();
|
||||
for (i = 0 ; i < 0x100000000 ; i++)
|
||||
/* nothing */;
|
||||
__halt();
|
||||
}
|
174
arch/alpha/boot/misc.c
Normal file
174
arch/alpha/boot/misc.c
Normal file
@ -0,0 +1,174 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* misc.c
|
||||
*
|
||||
* This is a collection of several routines from gzip-1.0.3
|
||||
* adapted for Linux.
|
||||
*
|
||||
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
|
||||
*
|
||||
* Modified for ARM Linux by Russell King
|
||||
*
|
||||
* Nicolas Pitre <nico@visuaide.com> 1999/04/14 :
|
||||
* For this code to run directly from Flash, all constant variables must
|
||||
* be marked with 'const' and all other variables initialized at run-time
|
||||
* only. This way all non constant variables will end up in the bss segment,
|
||||
* which should point to addresses in RAM and cleared to 0 on start.
|
||||
* This allows for a much quicker boot time.
|
||||
*
|
||||
* Modified for Alpha, from the ARM version, by Jay Estabrook 2003.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#define memzero(s,n) memset ((s),0,(n))
|
||||
#define puts srm_printk
|
||||
extern long srm_printk(const char *, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
|
||||
/*
|
||||
* gzip declarations
|
||||
*/
|
||||
#define OF(args) args
|
||||
#define STATIC static
|
||||
|
||||
typedef unsigned char uch;
|
||||
typedef unsigned short ush;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
#define WSIZE 0x8000 /* Window size must be at least 32k, */
|
||||
/* and a power of two */
|
||||
|
||||
static uch *inbuf; /* input buffer */
|
||||
static uch *window; /* Sliding window buffer */
|
||||
|
||||
static unsigned insize; /* valid bytes in inbuf */
|
||||
static unsigned inptr; /* index of next byte to be processed in inbuf */
|
||||
static unsigned outcnt; /* bytes in output buffer */
|
||||
|
||||
/* gzip flag byte */
|
||||
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
|
||||
#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
|
||||
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
|
||||
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
|
||||
#define COMMENT 0x10 /* bit 4 set: file comment present */
|
||||
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
|
||||
#define RESERVED 0xC0 /* bit 6,7: reserved */
|
||||
|
||||
#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
|
||||
|
||||
/* Diagnostic functions */
|
||||
#ifdef DEBUG
|
||||
# define Assert(cond,msg) {if(!(cond)) error(msg);}
|
||||
# define Trace(x) fprintf x
|
||||
# define Tracev(x) {if (verbose) fprintf x ;}
|
||||
# define Tracevv(x) {if (verbose>1) fprintf x ;}
|
||||
# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
|
||||
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
|
||||
#else
|
||||
# define Assert(cond,msg)
|
||||
# define Trace(x)
|
||||
# define Tracev(x)
|
||||
# define Tracevv(x)
|
||||
# define Tracec(c,x)
|
||||
# define Tracecv(c,x)
|
||||
#endif
|
||||
|
||||
static int fill_inbuf(void);
|
||||
static void flush_window(void);
|
||||
static void error(char *m);
|
||||
|
||||
static char *input_data;
|
||||
static int input_data_size;
|
||||
|
||||
static uch *output_data;
|
||||
static ulg output_ptr;
|
||||
static ulg bytes_out;
|
||||
|
||||
static void error(char *m);
|
||||
static void gzip_mark(void **);
|
||||
static void gzip_release(void **);
|
||||
|
||||
extern int end;
|
||||
static ulg free_mem_ptr;
|
||||
static ulg free_mem_end_ptr;
|
||||
|
||||
#define HEAP_SIZE 0x3000
|
||||
|
||||
#include "../../../lib/inflate.c"
|
||||
|
||||
/* ===========================================================================
|
||||
* Fill the input buffer. This is called only when the buffer is empty
|
||||
* and at least one byte is really needed.
|
||||
*/
|
||||
int fill_inbuf(void)
|
||||
{
|
||||
if (insize != 0)
|
||||
error("ran out of input data");
|
||||
|
||||
inbuf = input_data;
|
||||
insize = input_data_size;
|
||||
|
||||
inptr = 1;
|
||||
return inbuf[0];
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Write the output window window[0..outcnt-1] and update crc and bytes_out.
|
||||
* (Used for the decompressed data only.)
|
||||
*/
|
||||
void flush_window(void)
|
||||
{
|
||||
ulg c = crc;
|
||||
unsigned n;
|
||||
uch *in, *out, ch;
|
||||
|
||||
in = window;
|
||||
out = &output_data[output_ptr];
|
||||
for (n = 0; n < outcnt; n++) {
|
||||
ch = *out++ = *in++;
|
||||
c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
|
||||
}
|
||||
crc = c;
|
||||
bytes_out += (ulg)outcnt;
|
||||
output_ptr += (ulg)outcnt;
|
||||
outcnt = 0;
|
||||
/* puts("."); */
|
||||
}
|
||||
|
||||
static void error(char *x)
|
||||
{
|
||||
puts("\n\n");
|
||||
puts(x);
|
||||
puts("\n\n -- System halted");
|
||||
|
||||
while(1); /* Halt */
|
||||
}
|
||||
|
||||
unsigned int
|
||||
decompress_kernel(void *output_start,
|
||||
void *input_start,
|
||||
size_t ksize,
|
||||
size_t kzsize)
|
||||
{
|
||||
output_data = (uch *)output_start;
|
||||
input_data = (uch *)input_start;
|
||||
input_data_size = kzsize; /* use compressed size */
|
||||
|
||||
/* FIXME FIXME FIXME */
|
||||
free_mem_ptr = (ulg)output_start + ksize;
|
||||
free_mem_end_ptr = (ulg)output_start + ksize + 0x200000;
|
||||
/* FIXME FIXME FIXME */
|
||||
|
||||
/* put in temp area to reduce initial footprint */
|
||||
window = malloc(WSIZE);
|
||||
|
||||
makecrc();
|
||||
/* puts("Uncompressing Linux..."); */
|
||||
gunzip();
|
||||
/* puts(" done, booting the kernel.\n"); */
|
||||
return output_ptr;
|
||||
}
|
302
arch/alpha/boot/stdio.c
Normal file
302
arch/alpha/boot/stdio.c
Normal file
@ -0,0 +1,302 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) Paul Mackerras 1997.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
size_t strnlen(const char * s, size_t count)
|
||||
{
|
||||
const char *sc;
|
||||
|
||||
for (sc = s; count-- && *sc != '\0'; ++sc)
|
||||
/* nothing */;
|
||||
return sc - s;
|
||||
}
|
||||
|
||||
# define do_div(n, base) ({ \
|
||||
unsigned int __base = (base); \
|
||||
unsigned int __rem; \
|
||||
__rem = ((unsigned long long)(n)) % __base; \
|
||||
(n) = ((unsigned long long)(n)) / __base; \
|
||||
__rem; \
|
||||
})
|
||||
|
||||
|
||||
static int skip_atoi(const char **s)
|
||||
{
|
||||
int i, c;
|
||||
|
||||
for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s)
|
||||
i = i*10 + c - '0';
|
||||
return i;
|
||||
}
|
||||
|
||||
#define ZEROPAD 1 /* pad with zero */
|
||||
#define SIGN 2 /* unsigned/signed long */
|
||||
#define PLUS 4 /* show plus */
|
||||
#define SPACE 8 /* space if plus */
|
||||
#define LEFT 16 /* left justified */
|
||||
#define SPECIAL 32 /* 0x */
|
||||
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
|
||||
|
||||
static char * number(char * str, unsigned long long num, int base, int size, int precision, int type)
|
||||
{
|
||||
char c,sign,tmp[66];
|
||||
const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
int i;
|
||||
|
||||
if (type & LARGE)
|
||||
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
if (type & LEFT)
|
||||
type &= ~ZEROPAD;
|
||||
if (base < 2 || base > 36)
|
||||
return 0;
|
||||
c = (type & ZEROPAD) ? '0' : ' ';
|
||||
sign = 0;
|
||||
if (type & SIGN) {
|
||||
if ((signed long long)num < 0) {
|
||||
sign = '-';
|
||||
num = - (signed long long)num;
|
||||
size--;
|
||||
} else if (type & PLUS) {
|
||||
sign = '+';
|
||||
size--;
|
||||
} else if (type & SPACE) {
|
||||
sign = ' ';
|
||||
size--;
|
||||
}
|
||||
}
|
||||
if (type & SPECIAL) {
|
||||
if (base == 16)
|
||||
size -= 2;
|
||||
else if (base == 8)
|
||||
size--;
|
||||
}
|
||||
i = 0;
|
||||
if (num == 0)
|
||||
tmp[i++]='0';
|
||||
else while (num != 0) {
|
||||
tmp[i++] = digits[do_div(num, base)];
|
||||
}
|
||||
if (i > precision)
|
||||
precision = i;
|
||||
size -= precision;
|
||||
if (!(type&(ZEROPAD+LEFT)))
|
||||
while(size-->0)
|
||||
*str++ = ' ';
|
||||
if (sign)
|
||||
*str++ = sign;
|
||||
if (type & SPECIAL) {
|
||||
if (base==8)
|
||||
*str++ = '0';
|
||||
else if (base==16) {
|
||||
*str++ = '0';
|
||||
*str++ = digits[33];
|
||||
}
|
||||
}
|
||||
if (!(type & LEFT))
|
||||
while (size-- > 0)
|
||||
*str++ = c;
|
||||
while (i < precision--)
|
||||
*str++ = '0';
|
||||
while (i-- > 0)
|
||||
*str++ = tmp[i];
|
||||
while (size-- > 0)
|
||||
*str++ = ' ';
|
||||
return str;
|
||||
}
|
||||
|
||||
int vsprintf(char *buf, const char *fmt, va_list args)
|
||||
{
|
||||
int len;
|
||||
unsigned long long num;
|
||||
int i, base;
|
||||
char * str;
|
||||
const char *s;
|
||||
|
||||
int flags; /* flags to number() */
|
||||
|
||||
int field_width; /* width of output field */
|
||||
int precision; /* min. # of digits for integers; max
|
||||
number of chars for from string */
|
||||
int qualifier; /* 'h', 'l', or 'L' for integer fields */
|
||||
/* 'z' support added 23/7/1999 S.H. */
|
||||
/* 'z' changed to 'Z' --davidm 1/25/99 */
|
||||
|
||||
|
||||
for (str=buf ; *fmt ; ++fmt) {
|
||||
if (*fmt != '%') {
|
||||
*str++ = *fmt;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* process flags */
|
||||
flags = 0;
|
||||
repeat:
|
||||
++fmt; /* this also skips first '%' */
|
||||
switch (*fmt) {
|
||||
case '-': flags |= LEFT; goto repeat;
|
||||
case '+': flags |= PLUS; goto repeat;
|
||||
case ' ': flags |= SPACE; goto repeat;
|
||||
case '#': flags |= SPECIAL; goto repeat;
|
||||
case '0': flags |= ZEROPAD; goto repeat;
|
||||
}
|
||||
|
||||
/* get field width */
|
||||
field_width = -1;
|
||||
if ('0' <= *fmt && *fmt <= '9')
|
||||
field_width = skip_atoi(&fmt);
|
||||
else if (*fmt == '*') {
|
||||
++fmt;
|
||||
/* it's the next argument */
|
||||
field_width = va_arg(args, int);
|
||||
if (field_width < 0) {
|
||||
field_width = -field_width;
|
||||
flags |= LEFT;
|
||||
}
|
||||
}
|
||||
|
||||
/* get the precision */
|
||||
precision = -1;
|
||||
if (*fmt == '.') {
|
||||
++fmt;
|
||||
if ('0' <= *fmt && *fmt <= '9')
|
||||
precision = skip_atoi(&fmt);
|
||||
else if (*fmt == '*') {
|
||||
++fmt;
|
||||
/* it's the next argument */
|
||||
precision = va_arg(args, int);
|
||||
}
|
||||
if (precision < 0)
|
||||
precision = 0;
|
||||
}
|
||||
|
||||
/* get the conversion qualifier */
|
||||
qualifier = -1;
|
||||
if (*fmt == 'l' && *(fmt + 1) == 'l') {
|
||||
qualifier = 'q';
|
||||
fmt += 2;
|
||||
} else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L'
|
||||
|| *fmt == 'Z') {
|
||||
qualifier = *fmt;
|
||||
++fmt;
|
||||
}
|
||||
|
||||
/* default base */
|
||||
base = 10;
|
||||
|
||||
switch (*fmt) {
|
||||
case 'c':
|
||||
if (!(flags & LEFT))
|
||||
while (--field_width > 0)
|
||||
*str++ = ' ';
|
||||
*str++ = (unsigned char) va_arg(args, int);
|
||||
while (--field_width > 0)
|
||||
*str++ = ' ';
|
||||
continue;
|
||||
|
||||
case 's':
|
||||
s = va_arg(args, char *);
|
||||
if (!s)
|
||||
s = "<NULL>";
|
||||
|
||||
len = strnlen(s, precision);
|
||||
|
||||
if (!(flags & LEFT))
|
||||
while (len < field_width--)
|
||||
*str++ = ' ';
|
||||
for (i = 0; i < len; ++i)
|
||||
*str++ = *s++;
|
||||
while (len < field_width--)
|
||||
*str++ = ' ';
|
||||
continue;
|
||||
|
||||
case 'p':
|
||||
if (field_width == -1) {
|
||||
field_width = 2*sizeof(void *);
|
||||
flags |= ZEROPAD;
|
||||
}
|
||||
str = number(str,
|
||||
(unsigned long) va_arg(args, void *), 16,
|
||||
field_width, precision, flags);
|
||||
continue;
|
||||
|
||||
|
||||
case 'n':
|
||||
if (qualifier == 'l') {
|
||||
long * ip = va_arg(args, long *);
|
||||
*ip = (str - buf);
|
||||
} else if (qualifier == 'Z') {
|
||||
size_t * ip = va_arg(args, size_t *);
|
||||
*ip = (str - buf);
|
||||
} else {
|
||||
int * ip = va_arg(args, int *);
|
||||
*ip = (str - buf);
|
||||
}
|
||||
continue;
|
||||
|
||||
case '%':
|
||||
*str++ = '%';
|
||||
continue;
|
||||
|
||||
/* integer number formats - set up the flags and "break" */
|
||||
case 'o':
|
||||
base = 8;
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
flags |= LARGE;
|
||||
case 'x':
|
||||
base = 16;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'i':
|
||||
flags |= SIGN;
|
||||
case 'u':
|
||||
break;
|
||||
|
||||
default:
|
||||
*str++ = '%';
|
||||
if (*fmt)
|
||||
*str++ = *fmt;
|
||||
else
|
||||
--fmt;
|
||||
continue;
|
||||
}
|
||||
if (qualifier == 'l') {
|
||||
num = va_arg(args, unsigned long);
|
||||
if (flags & SIGN)
|
||||
num = (signed long) num;
|
||||
} else if (qualifier == 'q') {
|
||||
num = va_arg(args, unsigned long long);
|
||||
if (flags & SIGN)
|
||||
num = (signed long long) num;
|
||||
} else if (qualifier == 'Z') {
|
||||
num = va_arg(args, size_t);
|
||||
} else if (qualifier == 'h') {
|
||||
num = (unsigned short) va_arg(args, int);
|
||||
if (flags & SIGN)
|
||||
num = (signed short) num;
|
||||
} else {
|
||||
num = va_arg(args, unsigned int);
|
||||
if (flags & SIGN)
|
||||
num = (signed int) num;
|
||||
}
|
||||
str = number(str, num, base, field_width, precision, flags);
|
||||
}
|
||||
*str = '\0';
|
||||
return str-buf;
|
||||
}
|
||||
|
||||
int sprintf(char * buf, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int i;
|
||||
|
||||
va_start(args, fmt);
|
||||
i=vsprintf(buf,fmt,args);
|
||||
va_end(args);
|
||||
return i;
|
||||
}
|
153
arch/alpha/boot/tools/mkbb.c
Normal file
153
arch/alpha/boot/tools/mkbb.c
Normal file
@ -0,0 +1,153 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* This utility makes a bootblock suitable for the SRM console/miniloader */
|
||||
|
||||
/* Usage:
|
||||
* mkbb <device> <lxboot>
|
||||
*
|
||||
* Where <device> is the name of the device to install the bootblock on,
|
||||
* and <lxboot> is the name of a bootblock to merge in. This bootblock
|
||||
* contains the offset and size of the bootloader. It must be exactly
|
||||
* 512 bytes long.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Minimal definition of disklabel, so we don't have to include
|
||||
* asm/disklabel.h (confuses make)
|
||||
*/
|
||||
#ifndef MAXPARTITIONS
|
||||
#define MAXPARTITIONS 8 /* max. # of partitions */
|
||||
#endif
|
||||
|
||||
#ifndef u8
|
||||
#define u8 unsigned char
|
||||
#endif
|
||||
|
||||
#ifndef u16
|
||||
#define u16 unsigned short
|
||||
#endif
|
||||
|
||||
#ifndef u32
|
||||
#define u32 unsigned int
|
||||
#endif
|
||||
|
||||
struct disklabel {
|
||||
u32 d_magic; /* must be DISKLABELMAGIC */
|
||||
u16 d_type, d_subtype;
|
||||
u8 d_typename[16];
|
||||
u8 d_packname[16];
|
||||
u32 d_secsize;
|
||||
u32 d_nsectors;
|
||||
u32 d_ntracks;
|
||||
u32 d_ncylinders;
|
||||
u32 d_secpercyl;
|
||||
u32 d_secprtunit;
|
||||
u16 d_sparespertrack;
|
||||
u16 d_sparespercyl;
|
||||
u32 d_acylinders;
|
||||
u16 d_rpm, d_interleave, d_trackskew, d_cylskew;
|
||||
u32 d_headswitch, d_trkseek, d_flags;
|
||||
u32 d_drivedata[5];
|
||||
u32 d_spare[5];
|
||||
u32 d_magic2; /* must be DISKLABELMAGIC */
|
||||
u16 d_checksum;
|
||||
u16 d_npartitions;
|
||||
u32 d_bbsize, d_sbsize;
|
||||
struct d_partition {
|
||||
u32 p_size;
|
||||
u32 p_offset;
|
||||
u32 p_fsize;
|
||||
u8 p_fstype;
|
||||
u8 p_frag;
|
||||
u16 p_cpg;
|
||||
} d_partitions[MAXPARTITIONS];
|
||||
};
|
||||
|
||||
|
||||
typedef union __bootblock {
|
||||
struct {
|
||||
char __pad1[64];
|
||||
struct disklabel __label;
|
||||
} __u1;
|
||||
struct {
|
||||
unsigned long __pad2[63];
|
||||
unsigned long __checksum;
|
||||
} __u2;
|
||||
char bootblock_bytes[512];
|
||||
unsigned long bootblock_quadwords[64];
|
||||
} bootblock;
|
||||
|
||||
#define bootblock_label __u1.__label
|
||||
#define bootblock_checksum __u2.__checksum
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
bootblock bootblock_from_disk;
|
||||
bootblock bootloader_image;
|
||||
int dev, fd;
|
||||
int i;
|
||||
int nread;
|
||||
|
||||
/* Make sure of the arg count */
|
||||
if(argc != 3) {
|
||||
fprintf(stderr, "Usage: %s device lxboot\n", argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* First, open the device and make sure it's accessible */
|
||||
dev = open(argv[1], O_RDWR);
|
||||
if(dev < 0) {
|
||||
perror(argv[1]);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Now open the lxboot and make sure it's reasonable */
|
||||
fd = open(argv[2], O_RDONLY);
|
||||
if(fd < 0) {
|
||||
perror(argv[2]);
|
||||
close(dev);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Read in the lxboot */
|
||||
nread = read(fd, &bootloader_image, sizeof(bootblock));
|
||||
if(nread != sizeof(bootblock)) {
|
||||
perror("lxboot read");
|
||||
fprintf(stderr, "expected %zd, got %d\n", sizeof(bootblock), nread);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Read in the bootblock from disk. */
|
||||
nread = read(dev, &bootblock_from_disk, sizeof(bootblock));
|
||||
if(nread != sizeof(bootblock)) {
|
||||
perror("bootblock read");
|
||||
fprintf(stderr, "expected %zd, got %d\n", sizeof(bootblock), nread);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Swap the bootblock's disklabel into the bootloader */
|
||||
bootloader_image.bootblock_label = bootblock_from_disk.bootblock_label;
|
||||
|
||||
/* Calculate the bootblock checksum */
|
||||
bootloader_image.bootblock_checksum = 0;
|
||||
for(i = 0; i < 63; i++) {
|
||||
bootloader_image.bootblock_checksum +=
|
||||
bootloader_image.bootblock_quadwords[i];
|
||||
}
|
||||
|
||||
/* Write the whole thing out! */
|
||||
lseek(dev, 0L, SEEK_SET);
|
||||
if(write(dev, &bootloader_image, sizeof(bootblock)) != sizeof(bootblock)) {
|
||||
perror("bootblock write");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
close(dev);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
284
arch/alpha/boot/tools/objstrip.c
Normal file
284
arch/alpha/boot/tools/objstrip.c
Normal file
@ -0,0 +1,284 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* arch/alpha/boot/tools/objstrip.c
|
||||
*
|
||||
* Strip the object file headers/trailers from an executable (ELF or ECOFF).
|
||||
*
|
||||
* Copyright (C) 1996 David Mosberger-Tang.
|
||||
*/
|
||||
/*
|
||||
* Converts an ECOFF or ELF object file into a bootable file. The
|
||||
* object file must be a OMAGIC file (i.e., data and bss follow immediately
|
||||
* behind the text). See DEC "Assembly Language Programmer's Guide"
|
||||
* documentation for details. The SRM boot process is documented in
|
||||
* the Alpha AXP Architecture Reference Manual, Second Edition by
|
||||
* Richard L. Sites and Richard T. Witek.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <linux/a.out.h>
|
||||
#include <linux/coff.h>
|
||||
#include <linux/param.h>
|
||||
#ifdef __ELF__
|
||||
# include <linux/elf.h>
|
||||
# define elfhdr elf64_hdr
|
||||
# define elf_phdr elf64_phdr
|
||||
# define elf_check_arch(x) ((x)->e_machine == EM_ALPHA)
|
||||
#endif
|
||||
|
||||
/* bootfile size must be multiple of BLOCK_SIZE: */
|
||||
#define BLOCK_SIZE 512
|
||||
|
||||
const char * prog_name;
|
||||
|
||||
|
||||
static void
|
||||
usage (void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: %s [-v] -p file primary\n"
|
||||
" %s [-vb] file [secondary]\n", prog_name, prog_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
size_t nwritten, tocopy, n, mem_size, fil_size, pad = 0;
|
||||
int fd, ofd, i, j, verbose = 0, primary = 0;
|
||||
char buf[8192], *inname;
|
||||
struct exec * aout; /* includes file & aout header */
|
||||
long offset;
|
||||
#ifdef __ELF__
|
||||
struct elfhdr *elf;
|
||||
struct elf_phdr *elf_phdr; /* program header */
|
||||
unsigned long long e_entry;
|
||||
#endif
|
||||
|
||||
prog_name = argv[0];
|
||||
|
||||
for (i = 1; i < argc && argv[i][0] == '-'; ++i) {
|
||||
for (j = 1; argv[i][j]; ++j) {
|
||||
switch (argv[i][j]) {
|
||||
case 'v':
|
||||
verbose = ~verbose;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
pad = BLOCK_SIZE;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
primary = 1; /* make primary bootblock */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= argc) {
|
||||
usage();
|
||||
}
|
||||
inname = argv[i++];
|
||||
|
||||
fd = open(inname, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ofd = 1;
|
||||
if (i < argc) {
|
||||
ofd = open(argv[i++], O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (ofd == -1) {
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (primary) {
|
||||
/* generate bootblock for primary loader */
|
||||
|
||||
unsigned long bb[64], sum = 0;
|
||||
struct stat st;
|
||||
off_t size;
|
||||
int i;
|
||||
|
||||
if (ofd == 1) {
|
||||
usage();
|
||||
}
|
||||
|
||||
if (fstat(fd, &st) == -1) {
|
||||
perror("fstat");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
size = (st.st_size + BLOCK_SIZE - 1) & ~(BLOCK_SIZE - 1);
|
||||
memset(bb, 0, sizeof(bb));
|
||||
strcpy((char *) bb, "Linux SRM bootblock");
|
||||
bb[60] = size / BLOCK_SIZE; /* count */
|
||||
bb[61] = 1; /* starting sector # */
|
||||
bb[62] = 0; /* flags---must be 0 */
|
||||
for (i = 0; i < 63; ++i) {
|
||||
sum += bb[i];
|
||||
}
|
||||
bb[63] = sum;
|
||||
if (write(ofd, bb, sizeof(bb)) != sizeof(bb)) {
|
||||
perror("boot-block write");
|
||||
exit(1);
|
||||
}
|
||||
printf("%lu\n", size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* read and inspect exec header: */
|
||||
|
||||
if (read(fd, buf, sizeof(buf)) < 0) {
|
||||
perror("read");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef __ELF__
|
||||
elf = (struct elfhdr *) buf;
|
||||
|
||||
if (elf->e_ident[0] == 0x7f && str_has_prefix((char *)elf->e_ident + 1, "ELF")) {
|
||||
if (elf->e_type != ET_EXEC) {
|
||||
fprintf(stderr, "%s: %s is not an ELF executable\n",
|
||||
prog_name, inname);
|
||||
exit(1);
|
||||
}
|
||||
if (!elf_check_arch(elf)) {
|
||||
fprintf(stderr, "%s: is not for this processor (e_machine=%d)\n",
|
||||
prog_name, elf->e_machine);
|
||||
exit(1);
|
||||
}
|
||||
if (elf->e_phnum != 1) {
|
||||
fprintf(stderr,
|
||||
"%s: %d program headers (forgot to link with -N?)\n",
|
||||
prog_name, elf->e_phnum);
|
||||
}
|
||||
|
||||
e_entry = elf->e_entry;
|
||||
|
||||
lseek(fd, elf->e_phoff, SEEK_SET);
|
||||
if (read(fd, buf, sizeof(*elf_phdr)) != sizeof(*elf_phdr)) {
|
||||
perror("read");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
elf_phdr = (struct elf_phdr *) buf;
|
||||
offset = elf_phdr->p_offset;
|
||||
mem_size = elf_phdr->p_memsz;
|
||||
fil_size = elf_phdr->p_filesz;
|
||||
|
||||
/* work around ELF bug: */
|
||||
if (elf_phdr->p_vaddr < e_entry) {
|
||||
unsigned long delta = e_entry - elf_phdr->p_vaddr;
|
||||
offset += delta;
|
||||
mem_size -= delta;
|
||||
fil_size -= delta;
|
||||
elf_phdr->p_vaddr += delta;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
fprintf(stderr, "%s: extracting %#016lx-%#016lx (at %lx)\n",
|
||||
prog_name, (long) elf_phdr->p_vaddr,
|
||||
elf_phdr->p_vaddr + fil_size, offset);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
aout = (struct exec *) buf;
|
||||
|
||||
if (!(aout->fh.f_flags & COFF_F_EXEC)) {
|
||||
fprintf(stderr, "%s: %s is not in executable format\n",
|
||||
prog_name, inname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (aout->fh.f_opthdr != sizeof(aout->ah)) {
|
||||
fprintf(stderr, "%s: %s has unexpected optional header size\n",
|
||||
prog_name, inname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (N_MAGIC(*aout) != OMAGIC) {
|
||||
fprintf(stderr, "%s: %s is not an OMAGIC file\n",
|
||||
prog_name, inname);
|
||||
exit(1);
|
||||
}
|
||||
offset = N_TXTOFF(*aout);
|
||||
fil_size = aout->ah.tsize + aout->ah.dsize;
|
||||
mem_size = fil_size + aout->ah.bsize;
|
||||
|
||||
if (verbose) {
|
||||
fprintf(stderr, "%s: extracting %#016lx-%#016lx (at %lx)\n",
|
||||
prog_name, aout->ah.text_start,
|
||||
aout->ah.text_start + fil_size, offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (lseek(fd, offset, SEEK_SET) != offset) {
|
||||
perror("lseek");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
fprintf(stderr, "%s: copying %lu byte from %s\n",
|
||||
prog_name, (unsigned long) fil_size, inname);
|
||||
}
|
||||
|
||||
tocopy = fil_size;
|
||||
while (tocopy > 0) {
|
||||
n = tocopy;
|
||||
if (n > sizeof(buf)) {
|
||||
n = sizeof(buf);
|
||||
}
|
||||
tocopy -= n;
|
||||
if ((size_t) read(fd, buf, n) != n) {
|
||||
perror("read");
|
||||
exit(1);
|
||||
}
|
||||
do {
|
||||
nwritten = write(ofd, buf, n);
|
||||
if ((ssize_t) nwritten == -1) {
|
||||
perror("write");
|
||||
exit(1);
|
||||
}
|
||||
n -= nwritten;
|
||||
} while (n > 0);
|
||||
}
|
||||
|
||||
if (pad) {
|
||||
mem_size = ((mem_size + pad - 1) / pad) * pad;
|
||||
}
|
||||
|
||||
tocopy = mem_size - fil_size;
|
||||
if (tocopy > 0) {
|
||||
fprintf(stderr,
|
||||
"%s: zero-filling bss and aligning to %lu with %lu bytes\n",
|
||||
prog_name, pad, (unsigned long) tocopy);
|
||||
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
do {
|
||||
n = tocopy;
|
||||
if (n > sizeof(buf)) {
|
||||
n = sizeof(buf);
|
||||
}
|
||||
nwritten = write(ofd, buf, n);
|
||||
if ((ssize_t) nwritten == -1) {
|
||||
perror("write");
|
||||
exit(1);
|
||||
}
|
||||
tocopy -= nwritten;
|
||||
} while (tocopy > 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
73
arch/alpha/configs/defconfig
Normal file
73
arch/alpha/configs/defconfig
Normal file
@ -0,0 +1,73 @@
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_LOG_BUF_SHIFT=14
|
||||
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_VERBOSE_MCHECK=y
|
||||
CONFIG_SRM_ENV=m
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=m
|
||||
CONFIG_NET_KEY=m
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_INET_AH=m
|
||||
CONFIG_INET_ESP=m
|
||||
# CONFIG_IPV6 is not set
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_IP_NF_IPTABLES=m
|
||||
CONFIG_IP_NF_FILTER=m
|
||||
CONFIG_VLAN_8021Q=m
|
||||
CONFIG_PNP=y
|
||||
CONFIG_ISAPNP=y
|
||||
CONFIG_BLK_DEV_FD=y
|
||||
CONFIG_BLK_DEV_LOOP=m
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_DEV_SR=y
|
||||
CONFIG_SCSI_AIC7XXX=m
|
||||
CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
|
||||
# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
|
||||
CONFIG_ATA=y
|
||||
# CONFIG_SATA_PMP is not set
|
||||
CONFIG_PATA_ALI=y
|
||||
CONFIG_PATA_CMD64X=y
|
||||
CONFIG_PATA_CYPRESS=y
|
||||
CONFIG_ATA_GENERIC=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_DUMMY=m
|
||||
CONFIG_NET_ETHERNET=y
|
||||
CONFIG_NET_VENDOR_3COM=y
|
||||
CONFIG_VORTEX=y
|
||||
CONFIG_NET_TULIP=y
|
||||
CONFIG_DE2104X=m
|
||||
CONFIG_TULIP=y
|
||||
CONFIG_TULIP_MMIO=y
|
||||
CONFIG_NET_PCI=y
|
||||
CONFIG_YELLOWFIN=y
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_CMOS=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_REISERFS_FS=m
|
||||
CONFIG_ISO9660_FS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_PROC_KCORE=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_NFS_FS=m
|
||||
CONFIG_NFS_V3=y
|
||||
CONFIG_NFSD=m
|
||||
CONFIG_NFSD_V3=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_ALPHA_LEGACY_START_ADDRESS=y
|
||||
CONFIG_MATHEMU=y
|
||||
CONFIG_CRYPTO_HMAC=y
|
||||
CONFIG_DEVTMPFS=y
|
6
arch/alpha/include/asm/Kbuild
Normal file
6
arch/alpha/include/asm/Kbuild
Normal file
@ -0,0 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
generated-y += syscall_table.h
|
||||
generic-y += export.h
|
||||
generic-y += kvm_para.h
|
||||
generic-y += mcs_spinlock.h
|
16
arch/alpha/include/asm/a.out.h
Normal file
16
arch/alpha/include/asm/a.out.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_A_OUT_H__
|
||||
#define __ALPHA_A_OUT_H__
|
||||
|
||||
#include <uapi/asm/a.out.h>
|
||||
|
||||
|
||||
/* Assume that start addresses below 4G belong to a TASO application.
|
||||
Unfortunately, there is no proper bit in the exec header to check.
|
||||
Worse, we have to notice the start address before swapping to use
|
||||
/sbin/loader, which of course is _not_ a TASO application. */
|
||||
#define SET_AOUT_PERSONALITY(BFPM, EX) \
|
||||
set_personality (((BFPM->taso || EX.ah.entry < 0x100000000L \
|
||||
? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
|
||||
|
||||
#endif /* __A_OUT_GNU_H__ */
|
19
arch/alpha/include/asm/agp.h
Normal file
19
arch/alpha/include/asm/agp.h
Normal file
@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef AGP_H
|
||||
#define AGP_H 1
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
/* dummy for now */
|
||||
|
||||
#define map_page_into_agp(page) do { } while (0)
|
||||
#define unmap_page_from_agp(page) do { } while (0)
|
||||
#define flush_agp_cache() mb()
|
||||
|
||||
/* 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
|
43
arch/alpha/include/asm/agp_backend.h
Normal file
43
arch/alpha/include/asm/agp_backend.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ALPHA_AGP_BACKEND_H
|
||||
#define _ALPHA_AGP_BACKEND_H 1
|
||||
|
||||
typedef union _alpha_agp_mode {
|
||||
struct {
|
||||
u32 rate : 3;
|
||||
u32 reserved0 : 1;
|
||||
u32 fw : 1;
|
||||
u32 fourgb : 1;
|
||||
u32 reserved1 : 2;
|
||||
u32 enable : 1;
|
||||
u32 sba : 1;
|
||||
u32 reserved2 : 14;
|
||||
u32 rq : 8;
|
||||
} bits;
|
||||
u32 lw;
|
||||
} alpha_agp_mode;
|
||||
|
||||
typedef struct _alpha_agp_info {
|
||||
struct pci_controller *hose;
|
||||
struct {
|
||||
dma_addr_t bus_base;
|
||||
unsigned long size;
|
||||
void *sysdata;
|
||||
} aperture;
|
||||
alpha_agp_mode capability;
|
||||
alpha_agp_mode mode;
|
||||
void *private;
|
||||
struct alpha_agp_ops *ops;
|
||||
} alpha_agp_info;
|
||||
|
||||
struct alpha_agp_ops {
|
||||
int (*setup)(alpha_agp_info *);
|
||||
void (*cleanup)(alpha_agp_info *);
|
||||
int (*configure)(alpha_agp_info *);
|
||||
int (*bind)(alpha_agp_info *, off_t, struct agp_memory *);
|
||||
int (*unbind)(alpha_agp_info *, off_t, struct agp_memory *);
|
||||
unsigned long (*translate)(alpha_agp_info *, dma_addr_t);
|
||||
};
|
||||
|
||||
|
||||
#endif /* _ALPHA_AGP_BACKEND_H */
|
1
arch/alpha/include/asm/asm-offsets.h
Normal file
1
arch/alpha/include/asm/asm-offsets.h
Normal file
@ -0,0 +1 @@
|
||||
#include <generated/asm-offsets.h>
|
19
arch/alpha/include/asm/asm-prototypes.h
Normal file
19
arch/alpha/include/asm/asm-prototypes.h
Normal file
@ -0,0 +1,19 @@
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/checksum.h>
|
||||
#include <asm/console.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/string.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm-generic/asm-prototypes.h>
|
||||
|
||||
extern void __divl(void);
|
||||
extern void __reml(void);
|
||||
extern void __divq(void);
|
||||
extern void __remq(void);
|
||||
extern void __divlu(void);
|
||||
extern void __remlu(void);
|
||||
extern void __divqu(void);
|
||||
extern void __remqu(void);
|
||||
extern unsigned long __udiv_qrnnd(unsigned long *, unsigned long, unsigned long , unsigned long);
|
306
arch/alpha/include/asm/atomic.h
Normal file
306
arch/alpha/include/asm/atomic.h
Normal file
@ -0,0 +1,306 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ALPHA_ATOMIC_H
|
||||
#define _ALPHA_ATOMIC_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/cmpxchg.h>
|
||||
|
||||
/*
|
||||
* Atomic operations that C can't guarantee us. Useful for
|
||||
* resource counting etc...
|
||||
*
|
||||
* But use these as seldom as possible since they are much slower
|
||||
* than regular operations.
|
||||
*/
|
||||
|
||||
/*
|
||||
* To ensure dependency ordering is preserved for the _relaxed and
|
||||
* _release atomics, an smp_mb() is unconditionally inserted into the
|
||||
* _relaxed variants, which are used to build the barriered versions.
|
||||
* Avoid redundant back-to-back fences in the _acquire and _fence
|
||||
* versions.
|
||||
*/
|
||||
#define __atomic_acquire_fence()
|
||||
#define __atomic_post_full_fence()
|
||||
|
||||
#define ATOMIC64_INIT(i) { (i) }
|
||||
|
||||
#define arch_atomic_read(v) READ_ONCE((v)->counter)
|
||||
#define arch_atomic64_read(v) READ_ONCE((v)->counter)
|
||||
|
||||
#define arch_atomic_set(v,i) WRITE_ONCE((v)->counter, (i))
|
||||
#define arch_atomic64_set(v,i) WRITE_ONCE((v)->counter, (i))
|
||||
|
||||
/*
|
||||
* To get proper branch prediction for the main line, we must branch
|
||||
* forward to code at the end of this object's .text section, then
|
||||
* branch back to restart the operation.
|
||||
*/
|
||||
|
||||
#define ATOMIC_OP(op, asm_op) \
|
||||
static __inline__ void arch_atomic_##op(int i, atomic_t * v) \
|
||||
{ \
|
||||
unsigned long temp; \
|
||||
__asm__ __volatile__( \
|
||||
"1: ldl_l %0,%1\n" \
|
||||
" " #asm_op " %0,%2,%0\n" \
|
||||
" stl_c %0,%1\n" \
|
||||
" beq %0,2f\n" \
|
||||
".subsection 2\n" \
|
||||
"2: br 1b\n" \
|
||||
".previous" \
|
||||
:"=&r" (temp), "=m" (v->counter) \
|
||||
:"Ir" (i), "m" (v->counter)); \
|
||||
} \
|
||||
|
||||
#define ATOMIC_OP_RETURN(op, asm_op) \
|
||||
static inline int arch_atomic_##op##_return_relaxed(int i, atomic_t *v) \
|
||||
{ \
|
||||
long temp, result; \
|
||||
__asm__ __volatile__( \
|
||||
"1: ldl_l %0,%1\n" \
|
||||
" " #asm_op " %0,%3,%2\n" \
|
||||
" " #asm_op " %0,%3,%0\n" \
|
||||
" stl_c %0,%1\n" \
|
||||
" beq %0,2f\n" \
|
||||
".subsection 2\n" \
|
||||
"2: br 1b\n" \
|
||||
".previous" \
|
||||
:"=&r" (temp), "=m" (v->counter), "=&r" (result) \
|
||||
:"Ir" (i), "m" (v->counter) : "memory"); \
|
||||
smp_mb(); \
|
||||
return result; \
|
||||
}
|
||||
|
||||
#define ATOMIC_FETCH_OP(op, asm_op) \
|
||||
static inline int arch_atomic_fetch_##op##_relaxed(int i, atomic_t *v) \
|
||||
{ \
|
||||
long temp, result; \
|
||||
__asm__ __volatile__( \
|
||||
"1: ldl_l %2,%1\n" \
|
||||
" " #asm_op " %2,%3,%0\n" \
|
||||
" stl_c %0,%1\n" \
|
||||
" beq %0,2f\n" \
|
||||
".subsection 2\n" \
|
||||
"2: br 1b\n" \
|
||||
".previous" \
|
||||
:"=&r" (temp), "=m" (v->counter), "=&r" (result) \
|
||||
:"Ir" (i), "m" (v->counter) : "memory"); \
|
||||
smp_mb(); \
|
||||
return result; \
|
||||
}
|
||||
|
||||
#define ATOMIC64_OP(op, asm_op) \
|
||||
static __inline__ void arch_atomic64_##op(s64 i, atomic64_t * v) \
|
||||
{ \
|
||||
s64 temp; \
|
||||
__asm__ __volatile__( \
|
||||
"1: ldq_l %0,%1\n" \
|
||||
" " #asm_op " %0,%2,%0\n" \
|
||||
" stq_c %0,%1\n" \
|
||||
" beq %0,2f\n" \
|
||||
".subsection 2\n" \
|
||||
"2: br 1b\n" \
|
||||
".previous" \
|
||||
:"=&r" (temp), "=m" (v->counter) \
|
||||
:"Ir" (i), "m" (v->counter)); \
|
||||
} \
|
||||
|
||||
#define ATOMIC64_OP_RETURN(op, asm_op) \
|
||||
static __inline__ s64 \
|
||||
arch_atomic64_##op##_return_relaxed(s64 i, atomic64_t * v) \
|
||||
{ \
|
||||
s64 temp, result; \
|
||||
__asm__ __volatile__( \
|
||||
"1: ldq_l %0,%1\n" \
|
||||
" " #asm_op " %0,%3,%2\n" \
|
||||
" " #asm_op " %0,%3,%0\n" \
|
||||
" stq_c %0,%1\n" \
|
||||
" beq %0,2f\n" \
|
||||
".subsection 2\n" \
|
||||
"2: br 1b\n" \
|
||||
".previous" \
|
||||
:"=&r" (temp), "=m" (v->counter), "=&r" (result) \
|
||||
:"Ir" (i), "m" (v->counter) : "memory"); \
|
||||
smp_mb(); \
|
||||
return result; \
|
||||
}
|
||||
|
||||
#define ATOMIC64_FETCH_OP(op, asm_op) \
|
||||
static __inline__ s64 \
|
||||
arch_atomic64_fetch_##op##_relaxed(s64 i, atomic64_t * v) \
|
||||
{ \
|
||||
s64 temp, result; \
|
||||
__asm__ __volatile__( \
|
||||
"1: ldq_l %2,%1\n" \
|
||||
" " #asm_op " %2,%3,%0\n" \
|
||||
" stq_c %0,%1\n" \
|
||||
" beq %0,2f\n" \
|
||||
".subsection 2\n" \
|
||||
"2: br 1b\n" \
|
||||
".previous" \
|
||||
:"=&r" (temp), "=m" (v->counter), "=&r" (result) \
|
||||
:"Ir" (i), "m" (v->counter) : "memory"); \
|
||||
smp_mb(); \
|
||||
return result; \
|
||||
}
|
||||
|
||||
#define ATOMIC_OPS(op) \
|
||||
ATOMIC_OP(op, op##l) \
|
||||
ATOMIC_OP_RETURN(op, op##l) \
|
||||
ATOMIC_FETCH_OP(op, op##l) \
|
||||
ATOMIC64_OP(op, op##q) \
|
||||
ATOMIC64_OP_RETURN(op, op##q) \
|
||||
ATOMIC64_FETCH_OP(op, op##q)
|
||||
|
||||
ATOMIC_OPS(add)
|
||||
ATOMIC_OPS(sub)
|
||||
|
||||
#define arch_atomic_add_return_relaxed arch_atomic_add_return_relaxed
|
||||
#define arch_atomic_sub_return_relaxed arch_atomic_sub_return_relaxed
|
||||
#define arch_atomic_fetch_add_relaxed arch_atomic_fetch_add_relaxed
|
||||
#define arch_atomic_fetch_sub_relaxed arch_atomic_fetch_sub_relaxed
|
||||
|
||||
#define arch_atomic64_add_return_relaxed arch_atomic64_add_return_relaxed
|
||||
#define arch_atomic64_sub_return_relaxed arch_atomic64_sub_return_relaxed
|
||||
#define arch_atomic64_fetch_add_relaxed arch_atomic64_fetch_add_relaxed
|
||||
#define arch_atomic64_fetch_sub_relaxed arch_atomic64_fetch_sub_relaxed
|
||||
|
||||
#define arch_atomic_andnot arch_atomic_andnot
|
||||
#define arch_atomic64_andnot arch_atomic64_andnot
|
||||
|
||||
#undef ATOMIC_OPS
|
||||
#define ATOMIC_OPS(op, asm) \
|
||||
ATOMIC_OP(op, asm) \
|
||||
ATOMIC_FETCH_OP(op, asm) \
|
||||
ATOMIC64_OP(op, asm) \
|
||||
ATOMIC64_FETCH_OP(op, asm)
|
||||
|
||||
ATOMIC_OPS(and, and)
|
||||
ATOMIC_OPS(andnot, bic)
|
||||
ATOMIC_OPS(or, bis)
|
||||
ATOMIC_OPS(xor, xor)
|
||||
|
||||
#define arch_atomic_fetch_and_relaxed arch_atomic_fetch_and_relaxed
|
||||
#define arch_atomic_fetch_andnot_relaxed arch_atomic_fetch_andnot_relaxed
|
||||
#define arch_atomic_fetch_or_relaxed arch_atomic_fetch_or_relaxed
|
||||
#define arch_atomic_fetch_xor_relaxed arch_atomic_fetch_xor_relaxed
|
||||
|
||||
#define arch_atomic64_fetch_and_relaxed arch_atomic64_fetch_and_relaxed
|
||||
#define arch_atomic64_fetch_andnot_relaxed arch_atomic64_fetch_andnot_relaxed
|
||||
#define arch_atomic64_fetch_or_relaxed arch_atomic64_fetch_or_relaxed
|
||||
#define arch_atomic64_fetch_xor_relaxed arch_atomic64_fetch_xor_relaxed
|
||||
|
||||
#undef ATOMIC_OPS
|
||||
#undef ATOMIC64_FETCH_OP
|
||||
#undef ATOMIC64_OP_RETURN
|
||||
#undef ATOMIC64_OP
|
||||
#undef ATOMIC_FETCH_OP
|
||||
#undef ATOMIC_OP_RETURN
|
||||
#undef ATOMIC_OP
|
||||
|
||||
#define arch_atomic64_cmpxchg(v, old, new) \
|
||||
(arch_cmpxchg(&((v)->counter), old, new))
|
||||
#define arch_atomic64_xchg(v, new) \
|
||||
(arch_xchg(&((v)->counter), new))
|
||||
|
||||
#define arch_atomic_cmpxchg(v, old, new) \
|
||||
(arch_cmpxchg(&((v)->counter), old, new))
|
||||
#define arch_atomic_xchg(v, new) \
|
||||
(arch_xchg(&((v)->counter), new))
|
||||
|
||||
/**
|
||||
* arch_atomic_fetch_add_unless - add unless the number is a given value
|
||||
* @v: pointer of type atomic_t
|
||||
* @a: the amount to add to v...
|
||||
* @u: ...unless v is equal to u.
|
||||
*
|
||||
* Atomically adds @a to @v, so long as it was not @u.
|
||||
* Returns the old value of @v.
|
||||
*/
|
||||
static __inline__ int arch_atomic_fetch_add_unless(atomic_t *v, int a, int u)
|
||||
{
|
||||
int c, new, old;
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
"1: ldl_l %[old],%[mem]\n"
|
||||
" cmpeq %[old],%[u],%[c]\n"
|
||||
" addl %[old],%[a],%[new]\n"
|
||||
" bne %[c],2f\n"
|
||||
" stl_c %[new],%[mem]\n"
|
||||
" beq %[new],3f\n"
|
||||
"2:\n"
|
||||
".subsection 2\n"
|
||||
"3: br 1b\n"
|
||||
".previous"
|
||||
: [old] "=&r"(old), [new] "=&r"(new), [c] "=&r"(c)
|
||||
: [mem] "m"(*v), [a] "rI"(a), [u] "rI"((long)u)
|
||||
: "memory");
|
||||
smp_mb();
|
||||
return old;
|
||||
}
|
||||
#define arch_atomic_fetch_add_unless arch_atomic_fetch_add_unless
|
||||
|
||||
/**
|
||||
* arch_atomic64_fetch_add_unless - add unless the number is a given value
|
||||
* @v: pointer of type atomic64_t
|
||||
* @a: the amount to add to v...
|
||||
* @u: ...unless v is equal to u.
|
||||
*
|
||||
* Atomically adds @a to @v, so long as it was not @u.
|
||||
* Returns the old value of @v.
|
||||
*/
|
||||
static __inline__ s64 arch_atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u)
|
||||
{
|
||||
s64 c, new, old;
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
"1: ldq_l %[old],%[mem]\n"
|
||||
" cmpeq %[old],%[u],%[c]\n"
|
||||
" addq %[old],%[a],%[new]\n"
|
||||
" bne %[c],2f\n"
|
||||
" stq_c %[new],%[mem]\n"
|
||||
" beq %[new],3f\n"
|
||||
"2:\n"
|
||||
".subsection 2\n"
|
||||
"3: br 1b\n"
|
||||
".previous"
|
||||
: [old] "=&r"(old), [new] "=&r"(new), [c] "=&r"(c)
|
||||
: [mem] "m"(*v), [a] "rI"(a), [u] "rI"(u)
|
||||
: "memory");
|
||||
smp_mb();
|
||||
return old;
|
||||
}
|
||||
#define arch_atomic64_fetch_add_unless arch_atomic64_fetch_add_unless
|
||||
|
||||
/*
|
||||
* arch_atomic64_dec_if_positive - decrement by 1 if old value positive
|
||||
* @v: pointer of type atomic_t
|
||||
*
|
||||
* The function returns the old value of *v minus 1, even if
|
||||
* the atomic variable, v, was not decremented.
|
||||
*/
|
||||
static inline s64 arch_atomic64_dec_if_positive(atomic64_t *v)
|
||||
{
|
||||
s64 old, tmp;
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
"1: ldq_l %[old],%[mem]\n"
|
||||
" subq %[old],1,%[tmp]\n"
|
||||
" ble %[old],2f\n"
|
||||
" stq_c %[tmp],%[mem]\n"
|
||||
" beq %[tmp],3f\n"
|
||||
"2:\n"
|
||||
".subsection 2\n"
|
||||
"3: br 1b\n"
|
||||
".previous"
|
||||
: [old] "=&r"(old), [tmp] "=&r"(tmp)
|
||||
: [mem] "m"(*v)
|
||||
: "memory");
|
||||
smp_mb();
|
||||
return old - 1;
|
||||
}
|
||||
#define arch_atomic64_dec_if_positive arch_atomic64_dec_if_positive
|
||||
|
||||
#endif /* _ALPHA_ATOMIC_H */
|
23
arch/alpha/include/asm/barrier.h
Normal file
23
arch/alpha/include/asm/barrier.h
Normal file
@ -0,0 +1,23 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __BARRIER_H
|
||||
#define __BARRIER_H
|
||||
|
||||
#define mb() __asm__ __volatile__("mb": : :"memory")
|
||||
#define rmb() __asm__ __volatile__("mb": : :"memory")
|
||||
#define wmb() __asm__ __volatile__("wmb": : :"memory")
|
||||
|
||||
#define __smp_load_acquire(p) \
|
||||
({ \
|
||||
compiletime_assert_atomic_type(*p); \
|
||||
__READ_ONCE(*p); \
|
||||
})
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define __ASM_SMP_MB "\tmb\n"
|
||||
#else
|
||||
#define __ASM_SMP_MB
|
||||
#endif
|
||||
|
||||
#include <asm-generic/barrier.h>
|
||||
|
||||
#endif /* __BARRIER_H */
|
459
arch/alpha/include/asm/bitops.h
Normal file
459
arch/alpha/include/asm/bitops.h
Normal file
@ -0,0 +1,459 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ALPHA_BITOPS_H
|
||||
#define _ALPHA_BITOPS_H
|
||||
|
||||
#ifndef _LINUX_BITOPS_H
|
||||
#error only <linux/bitops.h> can be included directly
|
||||
#endif
|
||||
|
||||
#include <asm/compiler.h>
|
||||
#include <asm/barrier.h>
|
||||
|
||||
/*
|
||||
* Copyright 1994, Linus Torvalds.
|
||||
*/
|
||||
|
||||
/*
|
||||
* These have to be done with inline assembly: that way the bit-setting
|
||||
* is guaranteed to be atomic. All bit operations return 0 if the bit
|
||||
* was cleared before the operation and != 0 if it was not.
|
||||
*
|
||||
* To get proper branch prediction for the main line, we must branch
|
||||
* forward to code at the end of this object's .text section, then
|
||||
* branch back to restart the operation.
|
||||
*
|
||||
* bit 0 is the LSB of addr; bit 64 is the LSB of (addr+1).
|
||||
*/
|
||||
|
||||
static inline void
|
||||
set_bit(unsigned long nr, volatile void * addr)
|
||||
{
|
||||
unsigned long temp;
|
||||
int *m = ((int *) addr) + (nr >> 5);
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: ldl_l %0,%3\n"
|
||||
" bis %0,%2,%0\n"
|
||||
" stl_c %0,%1\n"
|
||||
" beq %0,2f\n"
|
||||
".subsection 2\n"
|
||||
"2: br 1b\n"
|
||||
".previous"
|
||||
:"=&r" (temp), "=m" (*m)
|
||||
:"Ir" (1UL << (nr & 31)), "m" (*m));
|
||||
}
|
||||
|
||||
/*
|
||||
* WARNING: non atomic version.
|
||||
*/
|
||||
static inline void
|
||||
__set_bit(unsigned long nr, volatile void * addr)
|
||||
{
|
||||
int *m = ((int *) addr) + (nr >> 5);
|
||||
|
||||
*m |= 1 << (nr & 31);
|
||||
}
|
||||
|
||||
static inline void
|
||||
clear_bit(unsigned long nr, volatile void * addr)
|
||||
{
|
||||
unsigned long temp;
|
||||
int *m = ((int *) addr) + (nr >> 5);
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: ldl_l %0,%3\n"
|
||||
" bic %0,%2,%0\n"
|
||||
" stl_c %0,%1\n"
|
||||
" beq %0,2f\n"
|
||||
".subsection 2\n"
|
||||
"2: br 1b\n"
|
||||
".previous"
|
||||
:"=&r" (temp), "=m" (*m)
|
||||
:"Ir" (1UL << (nr & 31)), "m" (*m));
|
||||
}
|
||||
|
||||
static inline void
|
||||
clear_bit_unlock(unsigned long nr, volatile void * addr)
|
||||
{
|
||||
smp_mb();
|
||||
clear_bit(nr, addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* WARNING: non atomic version.
|
||||
*/
|
||||
static __inline__ void
|
||||
__clear_bit(unsigned long nr, volatile void * addr)
|
||||
{
|
||||
int *m = ((int *) addr) + (nr >> 5);
|
||||
|
||||
*m &= ~(1 << (nr & 31));
|
||||
}
|
||||
|
||||
static inline void
|
||||
__clear_bit_unlock(unsigned long nr, volatile void * addr)
|
||||
{
|
||||
smp_mb();
|
||||
__clear_bit(nr, addr);
|
||||
}
|
||||
|
||||
static inline void
|
||||
change_bit(unsigned long nr, volatile void * addr)
|
||||
{
|
||||
unsigned long temp;
|
||||
int *m = ((int *) addr) + (nr >> 5);
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: ldl_l %0,%3\n"
|
||||
" xor %0,%2,%0\n"
|
||||
" stl_c %0,%1\n"
|
||||
" beq %0,2f\n"
|
||||
".subsection 2\n"
|
||||
"2: br 1b\n"
|
||||
".previous"
|
||||
:"=&r" (temp), "=m" (*m)
|
||||
:"Ir" (1UL << (nr & 31)), "m" (*m));
|
||||
}
|
||||
|
||||
/*
|
||||
* WARNING: non atomic version.
|
||||
*/
|
||||
static __inline__ void
|
||||
__change_bit(unsigned long nr, volatile void * addr)
|
||||
{
|
||||
int *m = ((int *) addr) + (nr >> 5);
|
||||
|
||||
*m ^= 1 << (nr & 31);
|
||||
}
|
||||
|
||||
static inline int
|
||||
test_and_set_bit(unsigned long nr, volatile void *addr)
|
||||
{
|
||||
unsigned long oldbit;
|
||||
unsigned long temp;
|
||||
int *m = ((int *) addr) + (nr >> 5);
|
||||
|
||||
__asm__ __volatile__(
|
||||
#ifdef CONFIG_SMP
|
||||
" mb\n"
|
||||
#endif
|
||||
"1: ldl_l %0,%4\n"
|
||||
" and %0,%3,%2\n"
|
||||
" bne %2,2f\n"
|
||||
" xor %0,%3,%0\n"
|
||||
" stl_c %0,%1\n"
|
||||
" beq %0,3f\n"
|
||||
"2:\n"
|
||||
#ifdef CONFIG_SMP
|
||||
" mb\n"
|
||||
#endif
|
||||
".subsection 2\n"
|
||||
"3: br 1b\n"
|
||||
".previous"
|
||||
:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
|
||||
:"Ir" (1UL << (nr & 31)), "m" (*m) : "memory");
|
||||
|
||||
return oldbit != 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
test_and_set_bit_lock(unsigned long nr, volatile void *addr)
|
||||
{
|
||||
unsigned long oldbit;
|
||||
unsigned long temp;
|
||||
int *m = ((int *) addr) + (nr >> 5);
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: ldl_l %0,%4\n"
|
||||
" and %0,%3,%2\n"
|
||||
" bne %2,2f\n"
|
||||
" xor %0,%3,%0\n"
|
||||
" stl_c %0,%1\n"
|
||||
" beq %0,3f\n"
|
||||
"2:\n"
|
||||
#ifdef CONFIG_SMP
|
||||
" mb\n"
|
||||
#endif
|
||||
".subsection 2\n"
|
||||
"3: br 1b\n"
|
||||
".previous"
|
||||
:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
|
||||
:"Ir" (1UL << (nr & 31)), "m" (*m) : "memory");
|
||||
|
||||
return oldbit != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* WARNING: non atomic version.
|
||||
*/
|
||||
static inline int
|
||||
__test_and_set_bit(unsigned long nr, volatile void * addr)
|
||||
{
|
||||
unsigned long mask = 1 << (nr & 0x1f);
|
||||
int *m = ((int *) addr) + (nr >> 5);
|
||||
int old = *m;
|
||||
|
||||
*m = old | mask;
|
||||
return (old & mask) != 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
test_and_clear_bit(unsigned long nr, volatile void * addr)
|
||||
{
|
||||
unsigned long oldbit;
|
||||
unsigned long temp;
|
||||
int *m = ((int *) addr) + (nr >> 5);
|
||||
|
||||
__asm__ __volatile__(
|
||||
#ifdef CONFIG_SMP
|
||||
" mb\n"
|
||||
#endif
|
||||
"1: ldl_l %0,%4\n"
|
||||
" and %0,%3,%2\n"
|
||||
" beq %2,2f\n"
|
||||
" xor %0,%3,%0\n"
|
||||
" stl_c %0,%1\n"
|
||||
" beq %0,3f\n"
|
||||
"2:\n"
|
||||
#ifdef CONFIG_SMP
|
||||
" mb\n"
|
||||
#endif
|
||||
".subsection 2\n"
|
||||
"3: br 1b\n"
|
||||
".previous"
|
||||
:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
|
||||
:"Ir" (1UL << (nr & 31)), "m" (*m) : "memory");
|
||||
|
||||
return oldbit != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* WARNING: non atomic version.
|
||||
*/
|
||||
static inline int
|
||||
__test_and_clear_bit(unsigned long nr, volatile void * addr)
|
||||
{
|
||||
unsigned long mask = 1 << (nr & 0x1f);
|
||||
int *m = ((int *) addr) + (nr >> 5);
|
||||
int old = *m;
|
||||
|
||||
*m = old & ~mask;
|
||||
return (old & mask) != 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
test_and_change_bit(unsigned long nr, volatile void * addr)
|
||||
{
|
||||
unsigned long oldbit;
|
||||
unsigned long temp;
|
||||
int *m = ((int *) addr) + (nr >> 5);
|
||||
|
||||
__asm__ __volatile__(
|
||||
#ifdef CONFIG_SMP
|
||||
" mb\n"
|
||||
#endif
|
||||
"1: ldl_l %0,%4\n"
|
||||
" and %0,%3,%2\n"
|
||||
" xor %0,%3,%0\n"
|
||||
" stl_c %0,%1\n"
|
||||
" beq %0,3f\n"
|
||||
#ifdef CONFIG_SMP
|
||||
" mb\n"
|
||||
#endif
|
||||
".subsection 2\n"
|
||||
"3: br 1b\n"
|
||||
".previous"
|
||||
:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
|
||||
:"Ir" (1UL << (nr & 31)), "m" (*m) : "memory");
|
||||
|
||||
return oldbit != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* WARNING: non atomic version.
|
||||
*/
|
||||
static __inline__ int
|
||||
__test_and_change_bit(unsigned long nr, volatile void * addr)
|
||||
{
|
||||
unsigned long mask = 1 << (nr & 0x1f);
|
||||
int *m = ((int *) addr) + (nr >> 5);
|
||||
int old = *m;
|
||||
|
||||
*m = old ^ mask;
|
||||
return (old & mask) != 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
test_bit(int nr, const volatile void * addr)
|
||||
{
|
||||
return (1UL & (((const int *) addr)[nr >> 5] >> (nr & 31))) != 0UL;
|
||||
}
|
||||
|
||||
/*
|
||||
* ffz = Find First Zero in word. Undefined if no zero exists,
|
||||
* so code should check against ~0UL first..
|
||||
*
|
||||
* Do a binary search on the bits. Due to the nature of large
|
||||
* constants on the alpha, it is worthwhile to split the search.
|
||||
*/
|
||||
static inline unsigned long ffz_b(unsigned long x)
|
||||
{
|
||||
unsigned long sum, x1, x2, x4;
|
||||
|
||||
x = ~x & -~x; /* set first 0 bit, clear others */
|
||||
x1 = x & 0xAA;
|
||||
x2 = x & 0xCC;
|
||||
x4 = x & 0xF0;
|
||||
sum = x2 ? 2 : 0;
|
||||
sum += (x4 != 0) * 4;
|
||||
sum += (x1 != 0);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
static inline unsigned long ffz(unsigned long word)
|
||||
{
|
||||
#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
|
||||
/* Whee. EV67 can calculate it directly. */
|
||||
return __kernel_cttz(~word);
|
||||
#else
|
||||
unsigned long bits, qofs, bofs;
|
||||
|
||||
bits = __kernel_cmpbge(word, ~0UL);
|
||||
qofs = ffz_b(bits);
|
||||
bits = __kernel_extbl(word, qofs);
|
||||
bofs = ffz_b(bits);
|
||||
|
||||
return qofs*8 + bofs;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* __ffs = Find First set bit in word. Undefined if no set bit exists.
|
||||
*/
|
||||
static inline unsigned long __ffs(unsigned long word)
|
||||
{
|
||||
#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
|
||||
/* Whee. EV67 can calculate it directly. */
|
||||
return __kernel_cttz(word);
|
||||
#else
|
||||
unsigned long bits, qofs, bofs;
|
||||
|
||||
bits = __kernel_cmpbge(0, word);
|
||||
qofs = ffz_b(bits);
|
||||
bits = __kernel_extbl(word, qofs);
|
||||
bofs = ffz_b(~bits);
|
||||
|
||||
return qofs*8 + bofs;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/*
|
||||
* ffs: find first bit set. This is defined the same way as
|
||||
* the libc and compiler builtin ffs routines, therefore
|
||||
* differs in spirit from the above __ffs.
|
||||
*/
|
||||
|
||||
static inline int ffs(int word)
|
||||
{
|
||||
int result = __ffs(word) + 1;
|
||||
return word ? result : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* fls: find last bit set.
|
||||
*/
|
||||
#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
|
||||
static inline int fls64(unsigned long word)
|
||||
{
|
||||
return 64 - __kernel_ctlz(word);
|
||||
}
|
||||
#else
|
||||
extern const unsigned char __flsm1_tab[256];
|
||||
|
||||
static inline int fls64(unsigned long x)
|
||||
{
|
||||
unsigned long t, a, r;
|
||||
|
||||
t = __kernel_cmpbge (x, 0x0101010101010101UL);
|
||||
a = __flsm1_tab[t];
|
||||
t = __kernel_extbl (x, a);
|
||||
r = a*8 + __flsm1_tab[t] + (x != 0);
|
||||
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline unsigned long __fls(unsigned long x)
|
||||
{
|
||||
return fls64(x) - 1;
|
||||
}
|
||||
|
||||
static inline int fls(unsigned int x)
|
||||
{
|
||||
return fls64(x);
|
||||
}
|
||||
|
||||
/*
|
||||
* hweightN: returns the hamming weight (i.e. the number
|
||||
* of bits set) of a N-bit word
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
|
||||
/* Whee. EV67 can calculate it directly. */
|
||||
static inline unsigned long __arch_hweight64(unsigned long w)
|
||||
{
|
||||
return __kernel_ctpop(w);
|
||||
}
|
||||
|
||||
static inline unsigned int __arch_hweight32(unsigned int w)
|
||||
{
|
||||
return __arch_hweight64(w);
|
||||
}
|
||||
|
||||
static inline unsigned int __arch_hweight16(unsigned int w)
|
||||
{
|
||||
return __arch_hweight64(w & 0xffff);
|
||||
}
|
||||
|
||||
static inline unsigned int __arch_hweight8(unsigned int w)
|
||||
{
|
||||
return __arch_hweight64(w & 0xff);
|
||||
}
|
||||
#else
|
||||
#include <asm-generic/bitops/arch_hweight.h>
|
||||
#endif
|
||||
|
||||
#include <asm-generic/bitops/const_hweight.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/*
|
||||
* Every architecture must define this function. It's the fastest
|
||||
* way of searching a 100-bit bitmap. It's guaranteed that at least
|
||||
* one of the 100 bits is cleared.
|
||||
*/
|
||||
static inline unsigned long
|
||||
sched_find_first_bit(const unsigned long b[2])
|
||||
{
|
||||
unsigned long b0, b1, ofs, tmp;
|
||||
|
||||
b0 = b[0];
|
||||
b1 = b[1];
|
||||
ofs = (b0 ? 0 : 64);
|
||||
tmp = (b0 ? b0 : b1);
|
||||
|
||||
return __ffs(tmp) + ofs;
|
||||
}
|
||||
|
||||
#include <asm-generic/bitops/le.h>
|
||||
|
||||
#include <asm-generic/bitops/ext2-atomic-setbit.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _ALPHA_BITOPS_H */
|
25
arch/alpha/include/asm/bug.h
Normal file
25
arch/alpha/include/asm/bug.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ALPHA_BUG_H
|
||||
#define _ALPHA_BUG_H
|
||||
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#ifdef CONFIG_BUG
|
||||
#include <asm/pal.h>
|
||||
|
||||
/* ??? Would be nice to use .gprel32 here, but we can't be sure that the
|
||||
function loaded the GP, so this could fail in modules. */
|
||||
#define BUG() do { \
|
||||
__asm__ __volatile__( \
|
||||
"call_pal %0 # bugchk\n\t" \
|
||||
".long %1\n\t.8byte %2" \
|
||||
: : "i"(PAL_bugchk), "i"(__LINE__), "i"(__FILE__)); \
|
||||
unreachable(); \
|
||||
} while (0)
|
||||
|
||||
#define HAVE_ARCH_BUG
|
||||
#endif
|
||||
|
||||
#include <asm-generic/bug.h>
|
||||
|
||||
#endif
|
20
arch/alpha/include/asm/bugs.h
Normal file
20
arch/alpha/include/asm/bugs.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* include/asm-alpha/bugs.h
|
||||
*
|
||||
* Copyright (C) 1994 Linus Torvalds
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is included by init/main.c to check for architecture-dependent bugs.
|
||||
*
|
||||
* Needs:
|
||||
* void check_bugs(void);
|
||||
*/
|
||||
|
||||
/*
|
||||
* I don't know of any alpha bugs yet.. Nice chip
|
||||
*/
|
||||
|
||||
static void check_bugs(void)
|
||||
{
|
||||
}
|
23
arch/alpha/include/asm/cache.h
Normal file
23
arch/alpha/include/asm/cache.h
Normal file
@ -0,0 +1,23 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* include/asm-alpha/cache.h
|
||||
*/
|
||||
#ifndef __ARCH_ALPHA_CACHE_H
|
||||
#define __ARCH_ALPHA_CACHE_H
|
||||
|
||||
|
||||
/* Bytes per L1 (data) cache line. */
|
||||
#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EV6)
|
||||
# define L1_CACHE_BYTES 64
|
||||
# define L1_CACHE_SHIFT 6
|
||||
#else
|
||||
/* Both EV4 and EV5 are write-through, read-allocate,
|
||||
direct-mapped, physical.
|
||||
*/
|
||||
# define L1_CACHE_BYTES 32
|
||||
# define L1_CACHE_SHIFT 5
|
||||
#endif
|
||||
|
||||
#define SMP_CACHE_BYTES L1_CACHE_BYTES
|
||||
|
||||
#endif
|
62
arch/alpha/include/asm/cacheflush.h
Normal file
62
arch/alpha/include/asm/cacheflush.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ALPHA_CACHEFLUSH_H
|
||||
#define _ALPHA_CACHEFLUSH_H
|
||||
|
||||
#include <linux/mm.h>
|
||||
|
||||
/* Note that the following two definitions are _highly_ dependent
|
||||
on the contexts in which they are used in the kernel. I personally
|
||||
think it is criminal how loosely defined these macros are. */
|
||||
|
||||
/* We need to flush the kernel's icache after loading modules. The
|
||||
only other use of this macro is in load_aout_interp which is not
|
||||
used on Alpha.
|
||||
|
||||
Note that this definition should *not* be used for userspace
|
||||
icache flushing. While functional, it is _way_ overkill. The
|
||||
icache is tagged with ASNs and it suffices to allocate a new ASN
|
||||
for the process. */
|
||||
#ifndef CONFIG_SMP
|
||||
#define flush_icache_range(start, end) imb()
|
||||
#else
|
||||
#define flush_icache_range(start, end) smp_imb()
|
||||
extern void smp_imb(void);
|
||||
#endif
|
||||
|
||||
/* We need to flush the userspace icache after setting breakpoints in
|
||||
ptrace.
|
||||
|
||||
Instead of indiscriminately using imb, take advantage of the fact
|
||||
that icache entries are tagged with the ASN and load a new mm context. */
|
||||
/* ??? Ought to use this in arch/alpha/kernel/signal.c too. */
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
#include <linux/sched.h>
|
||||
|
||||
extern void __load_new_mm_context(struct mm_struct *);
|
||||
static inline void
|
||||
flush_icache_user_page(struct vm_area_struct *vma, struct page *page,
|
||||
unsigned long addr, int len)
|
||||
{
|
||||
if (vma->vm_flags & VM_EXEC) {
|
||||
struct mm_struct *mm = vma->vm_mm;
|
||||
if (current->active_mm == mm)
|
||||
__load_new_mm_context(mm);
|
||||
else
|
||||
mm->context[smp_processor_id()] = 0;
|
||||
}
|
||||
}
|
||||
#define flush_icache_user_page flush_icache_user_page
|
||||
#else /* CONFIG_SMP */
|
||||
extern void flush_icache_user_page(struct vm_area_struct *vma,
|
||||
struct page *page, unsigned long addr, int len);
|
||||
#define flush_icache_user_page flush_icache_user_page
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
/* This is used only in __do_fault and do_swap_page. */
|
||||
#define flush_icache_page(vma, page) \
|
||||
flush_icache_user_page((vma), (page), 0, 0)
|
||||
|
||||
#include <asm-generic/cacheflush.h>
|
||||
|
||||
#endif /* _ALPHA_CACHEFLUSH_H */
|
74
arch/alpha/include/asm/checksum.h
Normal file
74
arch/alpha/include/asm/checksum.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ALPHA_CHECKSUM_H
|
||||
#define _ALPHA_CHECKSUM_H
|
||||
|
||||
#include <linux/in6.h>
|
||||
|
||||
/*
|
||||
* This is a version of ip_compute_csum() optimized for IP headers,
|
||||
* which always checksum on 4 octet boundaries.
|
||||
*/
|
||||
extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
|
||||
|
||||
/*
|
||||
* computes the checksum of the TCP/UDP pseudo-header
|
||||
* returns a 16-bit checksum, already complemented
|
||||
*/
|
||||
__sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
|
||||
__u32 len, __u8 proto, __wsum sum);
|
||||
|
||||
__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
|
||||
__u32 len, __u8 proto, __wsum sum);
|
||||
|
||||
/*
|
||||
* computes the checksum of a memory block at buff, length len,
|
||||
* and adds in "sum" (32-bit)
|
||||
*
|
||||
* returns a 32-bit number suitable for feeding into itself
|
||||
* or csum_tcpudp_magic
|
||||
*
|
||||
* this function must be called with even lengths, except
|
||||
* for the last fragment, which may be odd
|
||||
*
|
||||
* it's best to have buff aligned on a 32-bit boundary
|
||||
*/
|
||||
extern __wsum csum_partial(const void *buff, int len, __wsum sum);
|
||||
|
||||
/*
|
||||
* the same as csum_partial, but copies from src while it
|
||||
* checksums
|
||||
*
|
||||
* here even more important to align src and dst on a 32-bit (or even
|
||||
* better 64-bit) boundary
|
||||
*/
|
||||
#define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
|
||||
#define _HAVE_ARCH_CSUM_AND_COPY
|
||||
__wsum csum_and_copy_from_user(const void __user *src, void *dst, int len);
|
||||
|
||||
__wsum csum_partial_copy_nocheck(const void *src, void *dst, int len);
|
||||
|
||||
|
||||
/*
|
||||
* this routine is used for miscellaneous IP-like checksums, mainly
|
||||
* in icmp.c
|
||||
*/
|
||||
|
||||
extern __sum16 ip_compute_csum(const void *buff, int len);
|
||||
|
||||
/*
|
||||
* Fold a partial checksum without adding pseudo headers
|
||||
*/
|
||||
|
||||
static inline __sum16 csum_fold(__wsum csum)
|
||||
{
|
||||
u32 sum = (__force u32)csum;
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
return (__force __sum16)~sum;
|
||||
}
|
||||
|
||||
#define _HAVE_ARCH_IPV6_CSUM
|
||||
extern __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
|
||||
const struct in6_addr *daddr,
|
||||
__u32 len, __u8 proto, __wsum sum);
|
||||
#endif
|
76
arch/alpha/include/asm/cmpxchg.h
Normal file
76
arch/alpha/include/asm/cmpxchg.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ALPHA_CMPXCHG_H
|
||||
#define _ALPHA_CMPXCHG_H
|
||||
|
||||
/*
|
||||
* Atomic exchange routines.
|
||||
*/
|
||||
|
||||
#define ____xchg(type, args...) __xchg ## type ## _local(args)
|
||||
#define ____cmpxchg(type, args...) __cmpxchg ## type ## _local(args)
|
||||
#include <asm/xchg.h>
|
||||
|
||||
#define xchg_local(ptr, x) \
|
||||
({ \
|
||||
__typeof__(*(ptr)) _x_ = (x); \
|
||||
(__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \
|
||||
sizeof(*(ptr))); \
|
||||
})
|
||||
|
||||
#define arch_cmpxchg_local(ptr, o, n) \
|
||||
({ \
|
||||
__typeof__(*(ptr)) _o_ = (o); \
|
||||
__typeof__(*(ptr)) _n_ = (n); \
|
||||
(__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \
|
||||
(unsigned long)_n_, \
|
||||
sizeof(*(ptr))); \
|
||||
})
|
||||
|
||||
#define arch_cmpxchg64_local(ptr, o, n) \
|
||||
({ \
|
||||
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
|
||||
cmpxchg_local((ptr), (o), (n)); \
|
||||
})
|
||||
|
||||
#undef ____xchg
|
||||
#undef ____cmpxchg
|
||||
#define ____xchg(type, args...) __xchg ##type(args)
|
||||
#define ____cmpxchg(type, args...) __cmpxchg ##type(args)
|
||||
#include <asm/xchg.h>
|
||||
|
||||
/*
|
||||
* The leading and the trailing memory barriers guarantee that these
|
||||
* operations are fully ordered.
|
||||
*/
|
||||
#define arch_xchg(ptr, x) \
|
||||
({ \
|
||||
__typeof__(*(ptr)) __ret; \
|
||||
__typeof__(*(ptr)) _x_ = (x); \
|
||||
smp_mb(); \
|
||||
__ret = (__typeof__(*(ptr))) \
|
||||
__xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
|
||||
smp_mb(); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define arch_cmpxchg(ptr, o, n) \
|
||||
({ \
|
||||
__typeof__(*(ptr)) __ret; \
|
||||
__typeof__(*(ptr)) _o_ = (o); \
|
||||
__typeof__(*(ptr)) _n_ = (n); \
|
||||
smp_mb(); \
|
||||
__ret = (__typeof__(*(ptr))) __cmpxchg((ptr), \
|
||||
(unsigned long)_o_, (unsigned long)_n_, sizeof(*(ptr)));\
|
||||
smp_mb(); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define arch_cmpxchg64(ptr, o, n) \
|
||||
({ \
|
||||
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
|
||||
arch_cmpxchg((ptr), (o), (n)); \
|
||||
})
|
||||
|
||||
#undef ____cmpxchg
|
||||
|
||||
#endif /* _ALPHA_CMPXCHG_H */
|
7
arch/alpha/include/asm/compiler.h
Normal file
7
arch/alpha/include/asm/compiler.h
Normal file
@ -0,0 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_COMPILER_H
|
||||
#define __ALPHA_COMPILER_H
|
||||
|
||||
#include <uapi/asm/compiler.h>
|
||||
|
||||
#endif /* __ALPHA_COMPILER_H */
|
30
arch/alpha/include/asm/console.h
Normal file
30
arch/alpha/include/asm/console.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __AXP_CONSOLE_H
|
||||
#define __AXP_CONSOLE_H
|
||||
|
||||
#include <uapi/asm/console.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern long callback_puts(long unit, const char *s, long length);
|
||||
extern long callback_getc(long unit);
|
||||
extern long callback_open_console(void);
|
||||
extern long callback_close_console(void);
|
||||
extern long callback_open(const char *device, long length);
|
||||
extern long callback_close(long unit);
|
||||
extern long callback_read(long channel, long count, const char *buf, long lbn);
|
||||
extern long callback_getenv(long id, const char *buf, unsigned long buf_size);
|
||||
extern long callback_setenv(long id, const char *buf, unsigned long buf_size);
|
||||
extern long callback_save_env(void);
|
||||
|
||||
extern int srm_fixup(unsigned long new_callback_addr,
|
||||
unsigned long new_hwrpb_addr);
|
||||
extern long srm_puts(const char *, long);
|
||||
extern long srm_printk(const char *, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
|
||||
struct crb_struct;
|
||||
struct hwrpb_struct;
|
||||
extern int callback_init_done;
|
||||
extern void * callback_init(void *);
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __AXP_CONSOLE_H */
|
518
arch/alpha/include/asm/core_apecs.h
Normal file
518
arch/alpha/include/asm/core_apecs.h
Normal file
@ -0,0 +1,518 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_APECS__H__
|
||||
#define __ALPHA_APECS__H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/compiler.h>
|
||||
|
||||
/*
|
||||
* APECS is the internal name for the 2107x chipset which provides
|
||||
* memory controller and PCI access for the 21064 chip based systems.
|
||||
*
|
||||
* This file is based on:
|
||||
*
|
||||
* DECchip 21071-AA and DECchip 21072-AA Core Logic Chipsets
|
||||
* Data Sheet
|
||||
*
|
||||
* EC-N0648-72
|
||||
*
|
||||
*
|
||||
* david.rusling@reo.mts.dec.com Initial Version.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
An AVANTI *might* be an XL, and an XL has only 27 bits of ISA address
|
||||
that get passed through the PCI<->ISA bridge chip. So we've gotta use
|
||||
both windows to max out the physical memory we can DMA to. Sigh...
|
||||
|
||||
If we try a window at 0 for 1GB as a work-around, we run into conflicts
|
||||
with ISA/PCI bus memory which can't be relocated, like VGA aperture and
|
||||
BIOS ROMs. So we must put the windows high enough to avoid these areas.
|
||||
|
||||
We put window 1 at BUS 64Mb for 64Mb, mapping physical 0 to 64Mb-1,
|
||||
and window 2 at BUS 1Gb for 1Gb, mapping physical 0 to 1Gb-1.
|
||||
Yes, this does map 0 to 64Mb-1 twice, but only window 1 will actually
|
||||
be used for that range (via virt_to_bus()).
|
||||
|
||||
Note that we actually fudge the window 1 maximum as 48Mb instead of 64Mb,
|
||||
to keep virt_to_bus() from returning an address in the first window, for
|
||||
a data area that goes beyond the 64Mb first DMA window. Sigh...
|
||||
The fudge factor MUST match with <asm/dma.h> MAX_DMA_ADDRESS, but
|
||||
we can't just use that here, because of header file looping... :-(
|
||||
|
||||
Window 1 will be used for all DMA from the ISA bus; yes, that does
|
||||
limit what memory an ISA floppy or sound card or Ethernet can touch, but
|
||||
it's also a known limitation on other platforms as well. We use the
|
||||
same technique that is used on INTEL platforms with similar limitation:
|
||||
set MAX_DMA_ADDRESS and clear some pages' DMAable flags during mem_init().
|
||||
We trust that any ISA bus device drivers will *always* ask for DMAable
|
||||
memory explicitly via kmalloc()/get_free_pages() flags arguments.
|
||||
|
||||
Note that most PCI bus devices' drivers do *not* explicitly ask for
|
||||
DMAable memory; they count on being able to DMA to any memory they
|
||||
get from kmalloc()/get_free_pages(). They will also use window 1 for
|
||||
any physical memory accesses below 64Mb; the rest will be handled by
|
||||
window 2, maxing out at 1Gb of memory. I trust this is enough... :-)
|
||||
|
||||
We hope that the area before the first window is large enough so that
|
||||
there will be no overlap at the top end (64Mb). We *must* locate the
|
||||
PCI cards' memory just below window 1, so that there's still the
|
||||
possibility of being able to access it via SPARSE space. This is
|
||||
important for cards such as the Matrox Millennium, whose Xserver
|
||||
wants to access memory-mapped registers in byte and short lengths.
|
||||
|
||||
Note that the XL is treated differently from the AVANTI, even though
|
||||
for most other things they are identical. It didn't seem reasonable to
|
||||
make the AVANTI support pay for the limitations of the XL. It is true,
|
||||
however, that an XL kernel will run on an AVANTI without problems.
|
||||
|
||||
%%% All of this should be obviated by the ability to route
|
||||
everything through the iommu.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 21071-DA Control and Status registers.
|
||||
* These are used for PCI memory access.
|
||||
*/
|
||||
#define APECS_IOC_DCSR (IDENT_ADDR + 0x1A0000000UL)
|
||||
#define APECS_IOC_PEAR (IDENT_ADDR + 0x1A0000020UL)
|
||||
#define APECS_IOC_SEAR (IDENT_ADDR + 0x1A0000040UL)
|
||||
#define APECS_IOC_DR1 (IDENT_ADDR + 0x1A0000060UL)
|
||||
#define APECS_IOC_DR2 (IDENT_ADDR + 0x1A0000080UL)
|
||||
#define APECS_IOC_DR3 (IDENT_ADDR + 0x1A00000A0UL)
|
||||
|
||||
#define APECS_IOC_TB1R (IDENT_ADDR + 0x1A00000C0UL)
|
||||
#define APECS_IOC_TB2R (IDENT_ADDR + 0x1A00000E0UL)
|
||||
|
||||
#define APECS_IOC_PB1R (IDENT_ADDR + 0x1A0000100UL)
|
||||
#define APECS_IOC_PB2R (IDENT_ADDR + 0x1A0000120UL)
|
||||
|
||||
#define APECS_IOC_PM1R (IDENT_ADDR + 0x1A0000140UL)
|
||||
#define APECS_IOC_PM2R (IDENT_ADDR + 0x1A0000160UL)
|
||||
|
||||
#define APECS_IOC_HAXR0 (IDENT_ADDR + 0x1A0000180UL)
|
||||
#define APECS_IOC_HAXR1 (IDENT_ADDR + 0x1A00001A0UL)
|
||||
#define APECS_IOC_HAXR2 (IDENT_ADDR + 0x1A00001C0UL)
|
||||
|
||||
#define APECS_IOC_PMLT (IDENT_ADDR + 0x1A00001E0UL)
|
||||
|
||||
#define APECS_IOC_TLBTAG0 (IDENT_ADDR + 0x1A0000200UL)
|
||||
#define APECS_IOC_TLBTAG1 (IDENT_ADDR + 0x1A0000220UL)
|
||||
#define APECS_IOC_TLBTAG2 (IDENT_ADDR + 0x1A0000240UL)
|
||||
#define APECS_IOC_TLBTAG3 (IDENT_ADDR + 0x1A0000260UL)
|
||||
#define APECS_IOC_TLBTAG4 (IDENT_ADDR + 0x1A0000280UL)
|
||||
#define APECS_IOC_TLBTAG5 (IDENT_ADDR + 0x1A00002A0UL)
|
||||
#define APECS_IOC_TLBTAG6 (IDENT_ADDR + 0x1A00002C0UL)
|
||||
#define APECS_IOC_TLBTAG7 (IDENT_ADDR + 0x1A00002E0UL)
|
||||
|
||||
#define APECS_IOC_TLBDATA0 (IDENT_ADDR + 0x1A0000300UL)
|
||||
#define APECS_IOC_TLBDATA1 (IDENT_ADDR + 0x1A0000320UL)
|
||||
#define APECS_IOC_TLBDATA2 (IDENT_ADDR + 0x1A0000340UL)
|
||||
#define APECS_IOC_TLBDATA3 (IDENT_ADDR + 0x1A0000360UL)
|
||||
#define APECS_IOC_TLBDATA4 (IDENT_ADDR + 0x1A0000380UL)
|
||||
#define APECS_IOC_TLBDATA5 (IDENT_ADDR + 0x1A00003A0UL)
|
||||
#define APECS_IOC_TLBDATA6 (IDENT_ADDR + 0x1A00003C0UL)
|
||||
#define APECS_IOC_TLBDATA7 (IDENT_ADDR + 0x1A00003E0UL)
|
||||
|
||||
#define APECS_IOC_TBIA (IDENT_ADDR + 0x1A0000400UL)
|
||||
|
||||
|
||||
/*
|
||||
* 21071-CA Control and Status registers.
|
||||
* These are used to program memory timing,
|
||||
* configure memory and initialise the B-Cache.
|
||||
*/
|
||||
#define APECS_MEM_GCR (IDENT_ADDR + 0x180000000UL)
|
||||
#define APECS_MEM_EDSR (IDENT_ADDR + 0x180000040UL)
|
||||
#define APECS_MEM_TAR (IDENT_ADDR + 0x180000060UL)
|
||||
#define APECS_MEM_ELAR (IDENT_ADDR + 0x180000080UL)
|
||||
#define APECS_MEM_EHAR (IDENT_ADDR + 0x1800000a0UL)
|
||||
#define APECS_MEM_SFT_RST (IDENT_ADDR + 0x1800000c0UL)
|
||||
#define APECS_MEM_LDxLAR (IDENT_ADDR + 0x1800000e0UL)
|
||||
#define APECS_MEM_LDxHAR (IDENT_ADDR + 0x180000100UL)
|
||||
#define APECS_MEM_GTR (IDENT_ADDR + 0x180000200UL)
|
||||
#define APECS_MEM_RTR (IDENT_ADDR + 0x180000220UL)
|
||||
#define APECS_MEM_VFPR (IDENT_ADDR + 0x180000240UL)
|
||||
#define APECS_MEM_PDLDR (IDENT_ADDR + 0x180000260UL)
|
||||
#define APECS_MEM_PDhDR (IDENT_ADDR + 0x180000280UL)
|
||||
|
||||
/* Bank x Base Address Register */
|
||||
#define APECS_MEM_B0BAR (IDENT_ADDR + 0x180000800UL)
|
||||
#define APECS_MEM_B1BAR (IDENT_ADDR + 0x180000820UL)
|
||||
#define APECS_MEM_B2BAR (IDENT_ADDR + 0x180000840UL)
|
||||
#define APECS_MEM_B3BAR (IDENT_ADDR + 0x180000860UL)
|
||||
#define APECS_MEM_B4BAR (IDENT_ADDR + 0x180000880UL)
|
||||
#define APECS_MEM_B5BAR (IDENT_ADDR + 0x1800008A0UL)
|
||||
#define APECS_MEM_B6BAR (IDENT_ADDR + 0x1800008C0UL)
|
||||
#define APECS_MEM_B7BAR (IDENT_ADDR + 0x1800008E0UL)
|
||||
#define APECS_MEM_B8BAR (IDENT_ADDR + 0x180000900UL)
|
||||
|
||||
/* Bank x Configuration Register */
|
||||
#define APECS_MEM_B0BCR (IDENT_ADDR + 0x180000A00UL)
|
||||
#define APECS_MEM_B1BCR (IDENT_ADDR + 0x180000A20UL)
|
||||
#define APECS_MEM_B2BCR (IDENT_ADDR + 0x180000A40UL)
|
||||
#define APECS_MEM_B3BCR (IDENT_ADDR + 0x180000A60UL)
|
||||
#define APECS_MEM_B4BCR (IDENT_ADDR + 0x180000A80UL)
|
||||
#define APECS_MEM_B5BCR (IDENT_ADDR + 0x180000AA0UL)
|
||||
#define APECS_MEM_B6BCR (IDENT_ADDR + 0x180000AC0UL)
|
||||
#define APECS_MEM_B7BCR (IDENT_ADDR + 0x180000AE0UL)
|
||||
#define APECS_MEM_B8BCR (IDENT_ADDR + 0x180000B00UL)
|
||||
|
||||
/* Bank x Timing Register A */
|
||||
#define APECS_MEM_B0TRA (IDENT_ADDR + 0x180000C00UL)
|
||||
#define APECS_MEM_B1TRA (IDENT_ADDR + 0x180000C20UL)
|
||||
#define APECS_MEM_B2TRA (IDENT_ADDR + 0x180000C40UL)
|
||||
#define APECS_MEM_B3TRA (IDENT_ADDR + 0x180000C60UL)
|
||||
#define APECS_MEM_B4TRA (IDENT_ADDR + 0x180000C80UL)
|
||||
#define APECS_MEM_B5TRA (IDENT_ADDR + 0x180000CA0UL)
|
||||
#define APECS_MEM_B6TRA (IDENT_ADDR + 0x180000CC0UL)
|
||||
#define APECS_MEM_B7TRA (IDENT_ADDR + 0x180000CE0UL)
|
||||
#define APECS_MEM_B8TRA (IDENT_ADDR + 0x180000D00UL)
|
||||
|
||||
/* Bank x Timing Register B */
|
||||
#define APECS_MEM_B0TRB (IDENT_ADDR + 0x180000E00UL)
|
||||
#define APECS_MEM_B1TRB (IDENT_ADDR + 0x180000E20UL)
|
||||
#define APECS_MEM_B2TRB (IDENT_ADDR + 0x180000E40UL)
|
||||
#define APECS_MEM_B3TRB (IDENT_ADDR + 0x180000E60UL)
|
||||
#define APECS_MEM_B4TRB (IDENT_ADDR + 0x180000E80UL)
|
||||
#define APECS_MEM_B5TRB (IDENT_ADDR + 0x180000EA0UL)
|
||||
#define APECS_MEM_B6TRB (IDENT_ADDR + 0x180000EC0UL)
|
||||
#define APECS_MEM_B7TRB (IDENT_ADDR + 0x180000EE0UL)
|
||||
#define APECS_MEM_B8TRB (IDENT_ADDR + 0x180000F00UL)
|
||||
|
||||
|
||||
/*
|
||||
* Memory spaces:
|
||||
*/
|
||||
#define APECS_IACK_SC (IDENT_ADDR + 0x1b0000000UL)
|
||||
#define APECS_CONF (IDENT_ADDR + 0x1e0000000UL)
|
||||
#define APECS_IO (IDENT_ADDR + 0x1c0000000UL)
|
||||
#define APECS_SPARSE_MEM (IDENT_ADDR + 0x200000000UL)
|
||||
#define APECS_DENSE_MEM (IDENT_ADDR + 0x300000000UL)
|
||||
|
||||
|
||||
/*
|
||||
* Bit definitions for I/O Controller status register 0:
|
||||
*/
|
||||
#define APECS_IOC_STAT0_CMD 0xf
|
||||
#define APECS_IOC_STAT0_ERR (1<<4)
|
||||
#define APECS_IOC_STAT0_LOST (1<<5)
|
||||
#define APECS_IOC_STAT0_THIT (1<<6)
|
||||
#define APECS_IOC_STAT0_TREF (1<<7)
|
||||
#define APECS_IOC_STAT0_CODE_SHIFT 8
|
||||
#define APECS_IOC_STAT0_CODE_MASK 0x7
|
||||
#define APECS_IOC_STAT0_P_NBR_SHIFT 13
|
||||
#define APECS_IOC_STAT0_P_NBR_MASK 0x7ffff
|
||||
|
||||
#define APECS_HAE_ADDRESS APECS_IOC_HAXR1
|
||||
|
||||
|
||||
/*
|
||||
* Data structure for handling APECS machine checks:
|
||||
*/
|
||||
|
||||
struct el_apecs_mikasa_sysdata_mcheck
|
||||
{
|
||||
unsigned long coma_gcr;
|
||||
unsigned long coma_edsr;
|
||||
unsigned long coma_ter;
|
||||
unsigned long coma_elar;
|
||||
unsigned long coma_ehar;
|
||||
unsigned long coma_ldlr;
|
||||
unsigned long coma_ldhr;
|
||||
unsigned long coma_base0;
|
||||
unsigned long coma_base1;
|
||||
unsigned long coma_base2;
|
||||
unsigned long coma_base3;
|
||||
unsigned long coma_cnfg0;
|
||||
unsigned long coma_cnfg1;
|
||||
unsigned long coma_cnfg2;
|
||||
unsigned long coma_cnfg3;
|
||||
unsigned long epic_dcsr;
|
||||
unsigned long epic_pear;
|
||||
unsigned long epic_sear;
|
||||
unsigned long epic_tbr1;
|
||||
unsigned long epic_tbr2;
|
||||
unsigned long epic_pbr1;
|
||||
unsigned long epic_pbr2;
|
||||
unsigned long epic_pmr1;
|
||||
unsigned long epic_pmr2;
|
||||
unsigned long epic_harx1;
|
||||
unsigned long epic_harx2;
|
||||
unsigned long epic_pmlt;
|
||||
unsigned long epic_tag0;
|
||||
unsigned long epic_tag1;
|
||||
unsigned long epic_tag2;
|
||||
unsigned long epic_tag3;
|
||||
unsigned long epic_tag4;
|
||||
unsigned long epic_tag5;
|
||||
unsigned long epic_tag6;
|
||||
unsigned long epic_tag7;
|
||||
unsigned long epic_data0;
|
||||
unsigned long epic_data1;
|
||||
unsigned long epic_data2;
|
||||
unsigned long epic_data3;
|
||||
unsigned long epic_data4;
|
||||
unsigned long epic_data5;
|
||||
unsigned long epic_data6;
|
||||
unsigned long epic_data7;
|
||||
|
||||
unsigned long pceb_vid;
|
||||
unsigned long pceb_did;
|
||||
unsigned long pceb_revision;
|
||||
unsigned long pceb_command;
|
||||
unsigned long pceb_status;
|
||||
unsigned long pceb_latency;
|
||||
unsigned long pceb_control;
|
||||
unsigned long pceb_arbcon;
|
||||
unsigned long pceb_arbpri;
|
||||
|
||||
unsigned long esc_id;
|
||||
unsigned long esc_revision;
|
||||
unsigned long esc_int0;
|
||||
unsigned long esc_int1;
|
||||
unsigned long esc_elcr0;
|
||||
unsigned long esc_elcr1;
|
||||
unsigned long esc_last_eisa;
|
||||
unsigned long esc_nmi_stat;
|
||||
|
||||
unsigned long pci_ir;
|
||||
unsigned long pci_imr;
|
||||
unsigned long svr_mgr;
|
||||
};
|
||||
|
||||
/* This for the normal APECS machines. */
|
||||
struct el_apecs_sysdata_mcheck
|
||||
{
|
||||
unsigned long coma_gcr;
|
||||
unsigned long coma_edsr;
|
||||
unsigned long coma_ter;
|
||||
unsigned long coma_elar;
|
||||
unsigned long coma_ehar;
|
||||
unsigned long coma_ldlr;
|
||||
unsigned long coma_ldhr;
|
||||
unsigned long coma_base0;
|
||||
unsigned long coma_base1;
|
||||
unsigned long coma_base2;
|
||||
unsigned long coma_cnfg0;
|
||||
unsigned long coma_cnfg1;
|
||||
unsigned long coma_cnfg2;
|
||||
unsigned long epic_dcsr;
|
||||
unsigned long epic_pear;
|
||||
unsigned long epic_sear;
|
||||
unsigned long epic_tbr1;
|
||||
unsigned long epic_tbr2;
|
||||
unsigned long epic_pbr1;
|
||||
unsigned long epic_pbr2;
|
||||
unsigned long epic_pmr1;
|
||||
unsigned long epic_pmr2;
|
||||
unsigned long epic_harx1;
|
||||
unsigned long epic_harx2;
|
||||
unsigned long epic_pmlt;
|
||||
unsigned long epic_tag0;
|
||||
unsigned long epic_tag1;
|
||||
unsigned long epic_tag2;
|
||||
unsigned long epic_tag3;
|
||||
unsigned long epic_tag4;
|
||||
unsigned long epic_tag5;
|
||||
unsigned long epic_tag6;
|
||||
unsigned long epic_tag7;
|
||||
unsigned long epic_data0;
|
||||
unsigned long epic_data1;
|
||||
unsigned long epic_data2;
|
||||
unsigned long epic_data3;
|
||||
unsigned long epic_data4;
|
||||
unsigned long epic_data5;
|
||||
unsigned long epic_data6;
|
||||
unsigned long epic_data7;
|
||||
};
|
||||
|
||||
struct el_apecs_procdata
|
||||
{
|
||||
unsigned long paltemp[32]; /* PAL TEMP REGS. */
|
||||
/* EV4-specific fields */
|
||||
unsigned long exc_addr; /* Address of excepting instruction. */
|
||||
unsigned long exc_sum; /* Summary of arithmetic traps. */
|
||||
unsigned long exc_mask; /* Exception mask (from exc_sum). */
|
||||
unsigned long iccsr; /* IBox hardware enables. */
|
||||
unsigned long pal_base; /* Base address for PALcode. */
|
||||
unsigned long hier; /* Hardware Interrupt Enable. */
|
||||
unsigned long hirr; /* Hardware Interrupt Request. */
|
||||
unsigned long csr; /* D-stream fault info. */
|
||||
unsigned long dc_stat; /* D-cache status (ECC/Parity Err). */
|
||||
unsigned long dc_addr; /* EV3 Phys Addr for ECC/DPERR. */
|
||||
unsigned long abox_ctl; /* ABox Control Register. */
|
||||
unsigned long biu_stat; /* BIU Status. */
|
||||
unsigned long biu_addr; /* BUI Address. */
|
||||
unsigned long biu_ctl; /* BIU Control. */
|
||||
unsigned long fill_syndrome;/* For correcting ECC errors. */
|
||||
unsigned long fill_addr; /* Cache block which was being read */
|
||||
unsigned long va; /* Effective VA of fault or miss. */
|
||||
unsigned long bc_tag; /* Backup Cache Tag Probe Results.*/
|
||||
};
|
||||
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef __EXTERN_INLINE
|
||||
#define __EXTERN_INLINE extern inline
|
||||
#define __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I/O functions:
|
||||
*
|
||||
* Unlike Jensen, the APECS machines have no concept of local
|
||||
* I/O---everything goes over the PCI bus.
|
||||
*
|
||||
* There is plenty room for optimization here. In particular,
|
||||
* the Alpha's insb/insw/extb/extw should be useful in moving
|
||||
* data to/from the right byte-lanes.
|
||||
*/
|
||||
|
||||
#define vip volatile int __force *
|
||||
#define vuip volatile unsigned int __force *
|
||||
#define vulp volatile unsigned long __force *
|
||||
|
||||
#define APECS_SET_HAE \
|
||||
do { \
|
||||
if (addr >= (1UL << 24)) { \
|
||||
unsigned long msb = addr & 0xf8000000; \
|
||||
addr -= msb; \
|
||||
set_hae(msb); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
__EXTERN_INLINE unsigned int apecs_ioread8(const void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
unsigned long result, base_and_type;
|
||||
|
||||
if (addr >= APECS_DENSE_MEM) {
|
||||
addr -= APECS_DENSE_MEM;
|
||||
APECS_SET_HAE;
|
||||
base_and_type = APECS_SPARSE_MEM + 0x00;
|
||||
} else {
|
||||
addr -= APECS_IO;
|
||||
base_and_type = APECS_IO + 0x00;
|
||||
}
|
||||
|
||||
result = *(vip) ((addr << 5) + base_and_type);
|
||||
return __kernel_extbl(result, addr & 3);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void apecs_iowrite8(u8 b, void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
unsigned long w, base_and_type;
|
||||
|
||||
if (addr >= APECS_DENSE_MEM) {
|
||||
addr -= APECS_DENSE_MEM;
|
||||
APECS_SET_HAE;
|
||||
base_and_type = APECS_SPARSE_MEM + 0x00;
|
||||
} else {
|
||||
addr -= APECS_IO;
|
||||
base_and_type = APECS_IO + 0x00;
|
||||
}
|
||||
|
||||
w = __kernel_insbl(b, addr & 3);
|
||||
*(vuip) ((addr << 5) + base_and_type) = w;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE unsigned int apecs_ioread16(const void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
unsigned long result, base_and_type;
|
||||
|
||||
if (addr >= APECS_DENSE_MEM) {
|
||||
addr -= APECS_DENSE_MEM;
|
||||
APECS_SET_HAE;
|
||||
base_and_type = APECS_SPARSE_MEM + 0x08;
|
||||
} else {
|
||||
addr -= APECS_IO;
|
||||
base_and_type = APECS_IO + 0x08;
|
||||
}
|
||||
|
||||
result = *(vip) ((addr << 5) + base_and_type);
|
||||
return __kernel_extwl(result, addr & 3);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void apecs_iowrite16(u16 b, void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
unsigned long w, base_and_type;
|
||||
|
||||
if (addr >= APECS_DENSE_MEM) {
|
||||
addr -= APECS_DENSE_MEM;
|
||||
APECS_SET_HAE;
|
||||
base_and_type = APECS_SPARSE_MEM + 0x08;
|
||||
} else {
|
||||
addr -= APECS_IO;
|
||||
base_and_type = APECS_IO + 0x08;
|
||||
}
|
||||
|
||||
w = __kernel_inswl(b, addr & 3);
|
||||
*(vuip) ((addr << 5) + base_and_type) = w;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE unsigned int apecs_ioread32(const void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
if (addr < APECS_DENSE_MEM)
|
||||
addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18;
|
||||
return *(vuip)addr;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void apecs_iowrite32(u32 b, void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
if (addr < APECS_DENSE_MEM)
|
||||
addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18;
|
||||
*(vuip)addr = b;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void __iomem *apecs_ioportmap(unsigned long addr)
|
||||
{
|
||||
return (void __iomem *)(addr + APECS_IO);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void __iomem *apecs_ioremap(unsigned long addr,
|
||||
unsigned long size)
|
||||
{
|
||||
return (void __iomem *)(addr + APECS_DENSE_MEM);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int apecs_is_ioaddr(unsigned long addr)
|
||||
{
|
||||
return addr >= IDENT_ADDR + 0x180000000UL;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int apecs_is_mmio(const volatile void __iomem *addr)
|
||||
{
|
||||
return (unsigned long)addr >= APECS_DENSE_MEM;
|
||||
}
|
||||
|
||||
#undef APECS_SET_HAE
|
||||
|
||||
#undef vip
|
||||
#undef vuip
|
||||
#undef vulp
|
||||
|
||||
#undef __IO_PREFIX
|
||||
#define __IO_PREFIX apecs
|
||||
#define apecs_trivial_io_bw 0
|
||||
#define apecs_trivial_io_lq 0
|
||||
#define apecs_trivial_rw_bw 2
|
||||
#define apecs_trivial_rw_lq 1
|
||||
#define apecs_trivial_iounmap 1
|
||||
#include <asm/io_trivial.h>
|
||||
|
||||
#ifdef __IO_EXTERN_INLINE
|
||||
#undef __EXTERN_INLINE
|
||||
#undef __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ALPHA_APECS__H__ */
|
501
arch/alpha/include/asm/core_cia.h
Normal file
501
arch/alpha/include/asm/core_cia.h
Normal file
@ -0,0 +1,501 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_CIA__H__
|
||||
#define __ALPHA_CIA__H__
|
||||
|
||||
/* Define to experiment with fitting everything into one 512MB HAE window. */
|
||||
#define CIA_ONE_HAE_WINDOW 1
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/compiler.h>
|
||||
|
||||
/*
|
||||
* CIA is the internal name for the 21171 chipset which provides
|
||||
* memory controller and PCI access for the 21164 chip based systems.
|
||||
* Also supported here is the 21172 (CIA-2) and 21174 (PYXIS).
|
||||
*
|
||||
* The lineage is a bit confused, since the 21174 was reportedly started
|
||||
* from the 21171 Pass 1 mask, and so is missing bug fixes that appear
|
||||
* in 21171 Pass 2 and 21172, but it also contains additional features.
|
||||
*
|
||||
* This file is based on:
|
||||
*
|
||||
* DECchip 21171 Core Logic Chipset
|
||||
* Technical Reference Manual
|
||||
*
|
||||
* EC-QE18B-TE
|
||||
*
|
||||
* david.rusling@reo.mts.dec.com Initial Version.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* CIA ADDRESS BIT DEFINITIONS
|
||||
*
|
||||
* 3333 3333 3322 2222 2222 1111 1111 11
|
||||
* 9876 5432 1098 7654 3210 9876 5432 1098 7654 3210
|
||||
* ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
|
||||
* 1 000
|
||||
* ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
|
||||
* | |\|
|
||||
* | Byte Enable --+ |
|
||||
* | Transfer Length --+
|
||||
* +-- IO space, not cached
|
||||
*
|
||||
* Byte Transfer
|
||||
* Enable Length Transfer Byte Address
|
||||
* adr<6:5> adr<4:3> Length Enable Adder
|
||||
* ---------------------------------------------
|
||||
* 00 00 Byte 1110 0x000
|
||||
* 01 00 Byte 1101 0x020
|
||||
* 10 00 Byte 1011 0x040
|
||||
* 11 00 Byte 0111 0x060
|
||||
*
|
||||
* 00 01 Word 1100 0x008
|
||||
* 01 01 Word 1001 0x028 <= Not supported in this code.
|
||||
* 10 01 Word 0011 0x048
|
||||
*
|
||||
* 00 10 Tribyte 1000 0x010
|
||||
* 01 10 Tribyte 0001 0x030
|
||||
*
|
||||
* 10 11 Longword 0000 0x058
|
||||
*
|
||||
* Note that byte enables are asserted low.
|
||||
*
|
||||
*/
|
||||
|
||||
#define CIA_MEM_R1_MASK 0x1fffffff /* SPARSE Mem region 1 mask is 29 bits */
|
||||
#define CIA_MEM_R2_MASK 0x07ffffff /* SPARSE Mem region 2 mask is 27 bits */
|
||||
#define CIA_MEM_R3_MASK 0x03ffffff /* SPARSE Mem region 3 mask is 26 bits */
|
||||
|
||||
/*
|
||||
* 21171-CA Control and Status Registers
|
||||
*/
|
||||
#define CIA_IOC_CIA_REV (IDENT_ADDR + 0x8740000080UL)
|
||||
# define CIA_REV_MASK 0xff
|
||||
#define CIA_IOC_PCI_LAT (IDENT_ADDR + 0x87400000C0UL)
|
||||
#define CIA_IOC_CIA_CTRL (IDENT_ADDR + 0x8740000100UL)
|
||||
# define CIA_CTRL_PCI_EN (1 << 0)
|
||||
# define CIA_CTRL_PCI_LOCK_EN (1 << 1)
|
||||
# define CIA_CTRL_PCI_LOOP_EN (1 << 2)
|
||||
# define CIA_CTRL_FST_BB_EN (1 << 3)
|
||||
# define CIA_CTRL_PCI_MST_EN (1 << 4)
|
||||
# define CIA_CTRL_PCI_MEM_EN (1 << 5)
|
||||
# define CIA_CTRL_PCI_REQ64_EN (1 << 6)
|
||||
# define CIA_CTRL_PCI_ACK64_EN (1 << 7)
|
||||
# define CIA_CTRL_ADDR_PE_EN (1 << 8)
|
||||
# define CIA_CTRL_PERR_EN (1 << 9)
|
||||
# define CIA_CTRL_FILL_ERR_EN (1 << 10)
|
||||
# define CIA_CTRL_MCHK_ERR_EN (1 << 11)
|
||||
# define CIA_CTRL_ECC_CHK_EN (1 << 12)
|
||||
# define CIA_CTRL_ASSERT_IDLE_BC (1 << 13)
|
||||
# define CIA_CTRL_COM_IDLE_BC (1 << 14)
|
||||
# define CIA_CTRL_CSR_IOA_BYPASS (1 << 15)
|
||||
# define CIA_CTRL_IO_FLUSHREQ_EN (1 << 16)
|
||||
# define CIA_CTRL_CPU_FLUSHREQ_EN (1 << 17)
|
||||
# define CIA_CTRL_ARB_CPU_EN (1 << 18)
|
||||
# define CIA_CTRL_EN_ARB_LINK (1 << 19)
|
||||
# define CIA_CTRL_RD_TYPE_SHIFT 20
|
||||
# define CIA_CTRL_RL_TYPE_SHIFT 24
|
||||
# define CIA_CTRL_RM_TYPE_SHIFT 28
|
||||
# define CIA_CTRL_EN_DMA_RD_PERF (1 << 31)
|
||||
#define CIA_IOC_CIA_CNFG (IDENT_ADDR + 0x8740000140UL)
|
||||
# define CIA_CNFG_IOA_BWEN (1 << 0)
|
||||
# define CIA_CNFG_PCI_MWEN (1 << 4)
|
||||
# define CIA_CNFG_PCI_DWEN (1 << 5)
|
||||
# define CIA_CNFG_PCI_WLEN (1 << 8)
|
||||
#define CIA_IOC_FLASH_CTRL (IDENT_ADDR + 0x8740000200UL)
|
||||
#define CIA_IOC_HAE_MEM (IDENT_ADDR + 0x8740000400UL)
|
||||
#define CIA_IOC_HAE_IO (IDENT_ADDR + 0x8740000440UL)
|
||||
#define CIA_IOC_CFG (IDENT_ADDR + 0x8740000480UL)
|
||||
#define CIA_IOC_CACK_EN (IDENT_ADDR + 0x8740000600UL)
|
||||
# define CIA_CACK_EN_LOCK_EN (1 << 0)
|
||||
# define CIA_CACK_EN_MB_EN (1 << 1)
|
||||
# define CIA_CACK_EN_SET_DIRTY_EN (1 << 2)
|
||||
# define CIA_CACK_EN_BC_VICTIM_EN (1 << 3)
|
||||
|
||||
|
||||
/*
|
||||
* 21171-CA Diagnostic Registers
|
||||
*/
|
||||
#define CIA_IOC_CIA_DIAG (IDENT_ADDR + 0x8740002000UL)
|
||||
#define CIA_IOC_DIAG_CHECK (IDENT_ADDR + 0x8740003000UL)
|
||||
|
||||
/*
|
||||
* 21171-CA Performance Monitor registers
|
||||
*/
|
||||
#define CIA_IOC_PERF_MONITOR (IDENT_ADDR + 0x8740004000UL)
|
||||
#define CIA_IOC_PERF_CONTROL (IDENT_ADDR + 0x8740004040UL)
|
||||
|
||||
/*
|
||||
* 21171-CA Error registers
|
||||
*/
|
||||
#define CIA_IOC_CPU_ERR0 (IDENT_ADDR + 0x8740008000UL)
|
||||
#define CIA_IOC_CPU_ERR1 (IDENT_ADDR + 0x8740008040UL)
|
||||
#define CIA_IOC_CIA_ERR (IDENT_ADDR + 0x8740008200UL)
|
||||
# define CIA_ERR_COR_ERR (1 << 0)
|
||||
# define CIA_ERR_UN_COR_ERR (1 << 1)
|
||||
# define CIA_ERR_CPU_PE (1 << 2)
|
||||
# define CIA_ERR_MEM_NEM (1 << 3)
|
||||
# define CIA_ERR_PCI_SERR (1 << 4)
|
||||
# define CIA_ERR_PERR (1 << 5)
|
||||
# define CIA_ERR_PCI_ADDR_PE (1 << 6)
|
||||
# define CIA_ERR_RCVD_MAS_ABT (1 << 7)
|
||||
# define CIA_ERR_RCVD_TAR_ABT (1 << 8)
|
||||
# define CIA_ERR_PA_PTE_INV (1 << 9)
|
||||
# define CIA_ERR_FROM_WRT_ERR (1 << 10)
|
||||
# define CIA_ERR_IOA_TIMEOUT (1 << 11)
|
||||
# define CIA_ERR_LOST_CORR_ERR (1 << 16)
|
||||
# define CIA_ERR_LOST_UN_CORR_ERR (1 << 17)
|
||||
# define CIA_ERR_LOST_CPU_PE (1 << 18)
|
||||
# define CIA_ERR_LOST_MEM_NEM (1 << 19)
|
||||
# define CIA_ERR_LOST_PERR (1 << 21)
|
||||
# define CIA_ERR_LOST_PCI_ADDR_PE (1 << 22)
|
||||
# define CIA_ERR_LOST_RCVD_MAS_ABT (1 << 23)
|
||||
# define CIA_ERR_LOST_RCVD_TAR_ABT (1 << 24)
|
||||
# define CIA_ERR_LOST_PA_PTE_INV (1 << 25)
|
||||
# define CIA_ERR_LOST_FROM_WRT_ERR (1 << 26)
|
||||
# define CIA_ERR_LOST_IOA_TIMEOUT (1 << 27)
|
||||
# define CIA_ERR_VALID (1 << 31)
|
||||
#define CIA_IOC_CIA_STAT (IDENT_ADDR + 0x8740008240UL)
|
||||
#define CIA_IOC_ERR_MASK (IDENT_ADDR + 0x8740008280UL)
|
||||
#define CIA_IOC_CIA_SYN (IDENT_ADDR + 0x8740008300UL)
|
||||
#define CIA_IOC_MEM_ERR0 (IDENT_ADDR + 0x8740008400UL)
|
||||
#define CIA_IOC_MEM_ERR1 (IDENT_ADDR + 0x8740008440UL)
|
||||
#define CIA_IOC_PCI_ERR0 (IDENT_ADDR + 0x8740008800UL)
|
||||
#define CIA_IOC_PCI_ERR1 (IDENT_ADDR + 0x8740008840UL)
|
||||
#define CIA_IOC_PCI_ERR3 (IDENT_ADDR + 0x8740008880UL)
|
||||
|
||||
/*
|
||||
* 21171-CA System configuration registers
|
||||
*/
|
||||
#define CIA_IOC_MCR (IDENT_ADDR + 0x8750000000UL)
|
||||
#define CIA_IOC_MBA0 (IDENT_ADDR + 0x8750000600UL)
|
||||
#define CIA_IOC_MBA2 (IDENT_ADDR + 0x8750000680UL)
|
||||
#define CIA_IOC_MBA4 (IDENT_ADDR + 0x8750000700UL)
|
||||
#define CIA_IOC_MBA6 (IDENT_ADDR + 0x8750000780UL)
|
||||
#define CIA_IOC_MBA8 (IDENT_ADDR + 0x8750000800UL)
|
||||
#define CIA_IOC_MBAA (IDENT_ADDR + 0x8750000880UL)
|
||||
#define CIA_IOC_MBAC (IDENT_ADDR + 0x8750000900UL)
|
||||
#define CIA_IOC_MBAE (IDENT_ADDR + 0x8750000980UL)
|
||||
#define CIA_IOC_TMG0 (IDENT_ADDR + 0x8750000B00UL)
|
||||
#define CIA_IOC_TMG1 (IDENT_ADDR + 0x8750000B40UL)
|
||||
#define CIA_IOC_TMG2 (IDENT_ADDR + 0x8750000B80UL)
|
||||
|
||||
/*
|
||||
* 2117A-CA PCI Address and Scatter-Gather Registers.
|
||||
*/
|
||||
#define CIA_IOC_PCI_TBIA (IDENT_ADDR + 0x8760000100UL)
|
||||
|
||||
#define CIA_IOC_PCI_W0_BASE (IDENT_ADDR + 0x8760000400UL)
|
||||
#define CIA_IOC_PCI_W0_MASK (IDENT_ADDR + 0x8760000440UL)
|
||||
#define CIA_IOC_PCI_T0_BASE (IDENT_ADDR + 0x8760000480UL)
|
||||
|
||||
#define CIA_IOC_PCI_W1_BASE (IDENT_ADDR + 0x8760000500UL)
|
||||
#define CIA_IOC_PCI_W1_MASK (IDENT_ADDR + 0x8760000540UL)
|
||||
#define CIA_IOC_PCI_T1_BASE (IDENT_ADDR + 0x8760000580UL)
|
||||
|
||||
#define CIA_IOC_PCI_W2_BASE (IDENT_ADDR + 0x8760000600UL)
|
||||
#define CIA_IOC_PCI_W2_MASK (IDENT_ADDR + 0x8760000640UL)
|
||||
#define CIA_IOC_PCI_T2_BASE (IDENT_ADDR + 0x8760000680UL)
|
||||
|
||||
#define CIA_IOC_PCI_W3_BASE (IDENT_ADDR + 0x8760000700UL)
|
||||
#define CIA_IOC_PCI_W3_MASK (IDENT_ADDR + 0x8760000740UL)
|
||||
#define CIA_IOC_PCI_T3_BASE (IDENT_ADDR + 0x8760000780UL)
|
||||
|
||||
#define CIA_IOC_PCI_Wn_BASE(N) (IDENT_ADDR + 0x8760000400UL + (N)*0x100)
|
||||
#define CIA_IOC_PCI_Wn_MASK(N) (IDENT_ADDR + 0x8760000440UL + (N)*0x100)
|
||||
#define CIA_IOC_PCI_Tn_BASE(N) (IDENT_ADDR + 0x8760000480UL + (N)*0x100)
|
||||
|
||||
#define CIA_IOC_PCI_W_DAC (IDENT_ADDR + 0x87600007C0UL)
|
||||
|
||||
/*
|
||||
* 2117A-CA Address Translation Registers.
|
||||
*/
|
||||
|
||||
/* 8 tag registers, the first 4 of which are lockable. */
|
||||
#define CIA_IOC_TB_TAGn(n) \
|
||||
(IDENT_ADDR + 0x8760000800UL + (n)*0x40)
|
||||
|
||||
/* 4 page registers per tag register. */
|
||||
#define CIA_IOC_TBn_PAGEm(n,m) \
|
||||
(IDENT_ADDR + 0x8760001000UL + (n)*0x100 + (m)*0x40)
|
||||
|
||||
/*
|
||||
* Memory spaces:
|
||||
*/
|
||||
#define CIA_IACK_SC (IDENT_ADDR + 0x8720000000UL)
|
||||
#define CIA_CONF (IDENT_ADDR + 0x8700000000UL)
|
||||
#define CIA_IO (IDENT_ADDR + 0x8580000000UL)
|
||||
#define CIA_SPARSE_MEM (IDENT_ADDR + 0x8000000000UL)
|
||||
#define CIA_SPARSE_MEM_R2 (IDENT_ADDR + 0x8400000000UL)
|
||||
#define CIA_SPARSE_MEM_R3 (IDENT_ADDR + 0x8500000000UL)
|
||||
#define CIA_DENSE_MEM (IDENT_ADDR + 0x8600000000UL)
|
||||
#define CIA_BW_MEM (IDENT_ADDR + 0x8800000000UL)
|
||||
#define CIA_BW_IO (IDENT_ADDR + 0x8900000000UL)
|
||||
#define CIA_BW_CFG_0 (IDENT_ADDR + 0x8a00000000UL)
|
||||
#define CIA_BW_CFG_1 (IDENT_ADDR + 0x8b00000000UL)
|
||||
|
||||
/*
|
||||
* ALCOR's GRU ASIC registers
|
||||
*/
|
||||
#define GRU_INT_REQ (IDENT_ADDR + 0x8780000000UL)
|
||||
#define GRU_INT_MASK (IDENT_ADDR + 0x8780000040UL)
|
||||
#define GRU_INT_EDGE (IDENT_ADDR + 0x8780000080UL)
|
||||
#define GRU_INT_HILO (IDENT_ADDR + 0x87800000C0UL)
|
||||
#define GRU_INT_CLEAR (IDENT_ADDR + 0x8780000100UL)
|
||||
|
||||
#define GRU_CACHE_CNFG (IDENT_ADDR + 0x8780000200UL)
|
||||
#define GRU_SCR (IDENT_ADDR + 0x8780000300UL)
|
||||
#define GRU_LED (IDENT_ADDR + 0x8780000800UL)
|
||||
#define GRU_RESET (IDENT_ADDR + 0x8780000900UL)
|
||||
|
||||
#define ALCOR_GRU_INT_REQ_BITS 0x800fffffUL
|
||||
#define XLT_GRU_INT_REQ_BITS 0x80003fffUL
|
||||
#define GRU_INT_REQ_BITS (alpha_mv.sys.cia.gru_int_req_bits+0)
|
||||
|
||||
/*
|
||||
* PYXIS interrupt control registers
|
||||
*/
|
||||
#define PYXIS_INT_REQ (IDENT_ADDR + 0x87A0000000UL)
|
||||
#define PYXIS_INT_MASK (IDENT_ADDR + 0x87A0000040UL)
|
||||
#define PYXIS_INT_HILO (IDENT_ADDR + 0x87A00000C0UL)
|
||||
#define PYXIS_INT_ROUTE (IDENT_ADDR + 0x87A0000140UL)
|
||||
#define PYXIS_GPO (IDENT_ADDR + 0x87A0000180UL)
|
||||
#define PYXIS_INT_CNFG (IDENT_ADDR + 0x87A00001C0UL)
|
||||
#define PYXIS_RT_COUNT (IDENT_ADDR + 0x87A0000200UL)
|
||||
#define PYXIS_INT_TIME (IDENT_ADDR + 0x87A0000240UL)
|
||||
#define PYXIS_IIC_CTRL (IDENT_ADDR + 0x87A00002C0UL)
|
||||
#define PYXIS_RESET (IDENT_ADDR + 0x8780000900UL)
|
||||
|
||||
/* Offset between ram physical addresses and pci64 DAC bus addresses. */
|
||||
#define PYXIS_DAC_OFFSET (1UL << 40)
|
||||
|
||||
/*
|
||||
* Data structure for handling CIA machine checks.
|
||||
*/
|
||||
|
||||
/* System-specific info. */
|
||||
struct el_CIA_sysdata_mcheck {
|
||||
unsigned long cpu_err0;
|
||||
unsigned long cpu_err1;
|
||||
unsigned long cia_err;
|
||||
unsigned long cia_stat;
|
||||
unsigned long err_mask;
|
||||
unsigned long cia_syn;
|
||||
unsigned long mem_err0;
|
||||
unsigned long mem_err1;
|
||||
unsigned long pci_err0;
|
||||
unsigned long pci_err1;
|
||||
unsigned long pci_err2;
|
||||
};
|
||||
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef __EXTERN_INLINE
|
||||
/* Do not touch, this should *NOT* be static inline */
|
||||
#define __EXTERN_INLINE extern inline
|
||||
#define __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I/O functions:
|
||||
*
|
||||
* CIA (the 2117x PCI/memory support chipset for the EV5 (21164)
|
||||
* series of processors uses a sparse address mapping scheme to
|
||||
* get at PCI memory and I/O.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory functions. 64-bit and 32-bit accesses are done through
|
||||
* dense memory space, everything else through sparse space.
|
||||
*
|
||||
* For reading and writing 8 and 16 bit quantities we need to
|
||||
* go through one of the three sparse address mapping regions
|
||||
* and use the HAE_MEM CSR to provide some bits of the address.
|
||||
* The following few routines use only sparse address region 1
|
||||
* which gives 1Gbyte of accessible space which relates exactly
|
||||
* to the amount of PCI memory mapping *into* system address space.
|
||||
* See p 6-17 of the specification but it looks something like this:
|
||||
*
|
||||
* 21164 Address:
|
||||
*
|
||||
* 3 2 1
|
||||
* 9876543210987654321098765432109876543210
|
||||
* 1ZZZZ0.PCI.QW.Address............BBLL
|
||||
*
|
||||
* ZZ = SBZ
|
||||
* BB = Byte offset
|
||||
* LL = Transfer length
|
||||
*
|
||||
* PCI Address:
|
||||
*
|
||||
* 3 2 1
|
||||
* 10987654321098765432109876543210
|
||||
* HHH....PCI.QW.Address........ 00
|
||||
*
|
||||
* HHH = 31:29 HAE_MEM CSR
|
||||
*
|
||||
*/
|
||||
|
||||
#define vip volatile int __force *
|
||||
#define vuip volatile unsigned int __force *
|
||||
#define vulp volatile unsigned long __force *
|
||||
|
||||
__EXTERN_INLINE unsigned int cia_ioread8(const void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
unsigned long result, base_and_type;
|
||||
|
||||
if (addr >= CIA_DENSE_MEM)
|
||||
base_and_type = CIA_SPARSE_MEM + 0x00;
|
||||
else
|
||||
base_and_type = CIA_IO + 0x00;
|
||||
|
||||
/* We can use CIA_MEM_R1_MASK for io ports too, since it is large
|
||||
enough to cover all io ports, and smaller than CIA_IO. */
|
||||
addr &= CIA_MEM_R1_MASK;
|
||||
result = *(vip) ((addr << 5) + base_and_type);
|
||||
return __kernel_extbl(result, addr & 3);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void cia_iowrite8(u8 b, void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
unsigned long w, base_and_type;
|
||||
|
||||
if (addr >= CIA_DENSE_MEM)
|
||||
base_and_type = CIA_SPARSE_MEM + 0x00;
|
||||
else
|
||||
base_and_type = CIA_IO + 0x00;
|
||||
|
||||
addr &= CIA_MEM_R1_MASK;
|
||||
w = __kernel_insbl(b, addr & 3);
|
||||
*(vuip) ((addr << 5) + base_and_type) = w;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE unsigned int cia_ioread16(const void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
unsigned long result, base_and_type;
|
||||
|
||||
if (addr >= CIA_DENSE_MEM)
|
||||
base_and_type = CIA_SPARSE_MEM + 0x08;
|
||||
else
|
||||
base_and_type = CIA_IO + 0x08;
|
||||
|
||||
addr &= CIA_MEM_R1_MASK;
|
||||
result = *(vip) ((addr << 5) + base_and_type);
|
||||
return __kernel_extwl(result, addr & 3);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void cia_iowrite16(u16 b, void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
unsigned long w, base_and_type;
|
||||
|
||||
if (addr >= CIA_DENSE_MEM)
|
||||
base_and_type = CIA_SPARSE_MEM + 0x08;
|
||||
else
|
||||
base_and_type = CIA_IO + 0x08;
|
||||
|
||||
addr &= CIA_MEM_R1_MASK;
|
||||
w = __kernel_inswl(b, addr & 3);
|
||||
*(vuip) ((addr << 5) + base_and_type) = w;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE unsigned int cia_ioread32(const void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
if (addr < CIA_DENSE_MEM)
|
||||
addr = ((addr - CIA_IO) << 5) + CIA_IO + 0x18;
|
||||
return *(vuip)addr;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void cia_iowrite32(u32 b, void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
if (addr < CIA_DENSE_MEM)
|
||||
addr = ((addr - CIA_IO) << 5) + CIA_IO + 0x18;
|
||||
*(vuip)addr = b;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void __iomem *cia_ioportmap(unsigned long addr)
|
||||
{
|
||||
return (void __iomem *)(addr + CIA_IO);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void __iomem *cia_ioremap(unsigned long addr,
|
||||
unsigned long size)
|
||||
{
|
||||
return (void __iomem *)(addr + CIA_DENSE_MEM);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int cia_is_ioaddr(unsigned long addr)
|
||||
{
|
||||
return addr >= IDENT_ADDR + 0x8000000000UL;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int cia_is_mmio(const volatile void __iomem *addr)
|
||||
{
|
||||
return (unsigned long)addr >= CIA_DENSE_MEM;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void __iomem *cia_bwx_ioportmap(unsigned long addr)
|
||||
{
|
||||
return (void __iomem *)(addr + CIA_BW_IO);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void __iomem *cia_bwx_ioremap(unsigned long addr,
|
||||
unsigned long size)
|
||||
{
|
||||
return (void __iomem *)(addr + CIA_BW_MEM);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int cia_bwx_is_ioaddr(unsigned long addr)
|
||||
{
|
||||
return addr >= IDENT_ADDR + 0x8000000000UL;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int cia_bwx_is_mmio(const volatile void __iomem *addr)
|
||||
{
|
||||
return (unsigned long)addr < CIA_BW_IO;
|
||||
}
|
||||
|
||||
#undef vip
|
||||
#undef vuip
|
||||
#undef vulp
|
||||
|
||||
#undef __IO_PREFIX
|
||||
#define __IO_PREFIX cia
|
||||
#define cia_trivial_rw_bw 2
|
||||
#define cia_trivial_rw_lq 1
|
||||
#define cia_trivial_io_bw 0
|
||||
#define cia_trivial_io_lq 0
|
||||
#define cia_trivial_iounmap 1
|
||||
#include <asm/io_trivial.h>
|
||||
|
||||
#undef __IO_PREFIX
|
||||
#define __IO_PREFIX cia_bwx
|
||||
#define cia_bwx_trivial_rw_bw 1
|
||||
#define cia_bwx_trivial_rw_lq 1
|
||||
#define cia_bwx_trivial_io_bw 1
|
||||
#define cia_bwx_trivial_io_lq 1
|
||||
#define cia_bwx_trivial_iounmap 1
|
||||
#include <asm/io_trivial.h>
|
||||
|
||||
#undef __IO_PREFIX
|
||||
#ifdef CONFIG_ALPHA_PYXIS
|
||||
#define __IO_PREFIX cia_bwx
|
||||
#else
|
||||
#define __IO_PREFIX cia
|
||||
#endif
|
||||
|
||||
#ifdef __IO_EXTERN_INLINE
|
||||
#undef __EXTERN_INLINE
|
||||
#undef __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ALPHA_CIA__H__ */
|
233
arch/alpha/include/asm/core_irongate.h
Normal file
233
arch/alpha/include/asm/core_irongate.h
Normal file
@ -0,0 +1,233 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_IRONGATE__H__
|
||||
#define __ALPHA_IRONGATE__H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/compiler.h>
|
||||
|
||||
/*
|
||||
* IRONGATE is the internal name for the AMD-751 K7 core logic chipset
|
||||
* which provides memory controller and PCI access for NAUTILUS-based
|
||||
* EV6 (21264) systems.
|
||||
*
|
||||
* This file is based on:
|
||||
*
|
||||
* IronGate management library, (c) 1999 Alpha Processor, Inc.
|
||||
* Copyright (C) 1999 Alpha Processor, Inc.,
|
||||
* (David Daniel, Stig Telfer, Soohoon Lee)
|
||||
*/
|
||||
|
||||
/*
|
||||
* The 21264 supports, and internally recognizes, a 44-bit physical
|
||||
* address space that is divided equally between memory address space
|
||||
* and I/O address space. Memory address space resides in the lower
|
||||
* half of the physical address space (PA[43]=0) and I/O address space
|
||||
* resides in the upper half of the physical address space (PA[43]=1).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Irongate CSR map. Some of the CSRs are 8 or 16 bits, but all access
|
||||
* through the routines given is 32-bit.
|
||||
*
|
||||
* The first 0x40 bytes are standard as per the PCI spec.
|
||||
*/
|
||||
|
||||
typedef volatile __u32 igcsr32;
|
||||
|
||||
typedef struct {
|
||||
igcsr32 dev_vendor; /* 0x00 - device ID, vendor ID */
|
||||
igcsr32 stat_cmd; /* 0x04 - status, command */
|
||||
igcsr32 class; /* 0x08 - class code, rev ID */
|
||||
igcsr32 latency; /* 0x0C - header type, PCI latency */
|
||||
igcsr32 bar0; /* 0x10 - BAR0 - AGP */
|
||||
igcsr32 bar1; /* 0x14 - BAR1 - GART */
|
||||
igcsr32 bar2; /* 0x18 - Power Management reg block */
|
||||
|
||||
igcsr32 rsrvd0[6]; /* 0x1C-0x33 reserved */
|
||||
|
||||
igcsr32 capptr; /* 0x34 - Capabilities pointer */
|
||||
|
||||
igcsr32 rsrvd1[2]; /* 0x38-0x3F reserved */
|
||||
|
||||
igcsr32 bacsr10; /* 0x40 - base address chip selects */
|
||||
igcsr32 bacsr32; /* 0x44 - base address chip selects */
|
||||
igcsr32 bacsr54_eccms761; /* 0x48 - 751: base addr. chip selects
|
||||
761: ECC, mode/status */
|
||||
|
||||
igcsr32 rsrvd2[1]; /* 0x4C-0x4F reserved */
|
||||
|
||||
igcsr32 drammap; /* 0x50 - address mapping control */
|
||||
igcsr32 dramtm; /* 0x54 - timing, driver strength */
|
||||
igcsr32 dramms; /* 0x58 - DRAM mode/status */
|
||||
|
||||
igcsr32 rsrvd3[1]; /* 0x5C-0x5F reserved */
|
||||
|
||||
igcsr32 biu0; /* 0x60 - bus interface unit */
|
||||
igcsr32 biusip; /* 0x64 - Serial initialisation pkt */
|
||||
|
||||
igcsr32 rsrvd4[2]; /* 0x68-0x6F reserved */
|
||||
|
||||
igcsr32 mro; /* 0x70 - memory request optimiser */
|
||||
|
||||
igcsr32 rsrvd5[3]; /* 0x74-0x7F reserved */
|
||||
|
||||
igcsr32 whami; /* 0x80 - who am I */
|
||||
igcsr32 pciarb; /* 0x84 - PCI arbitration control */
|
||||
igcsr32 pcicfg; /* 0x88 - PCI config status */
|
||||
|
||||
igcsr32 rsrvd6[4]; /* 0x8C-0x9B reserved */
|
||||
|
||||
igcsr32 pci_mem; /* 0x9C - PCI top of memory,
|
||||
761 only */
|
||||
|
||||
/* AGP (bus 1) control registers */
|
||||
igcsr32 agpcap; /* 0xA0 - AGP Capability Identifier */
|
||||
igcsr32 agpstat; /* 0xA4 - AGP status register */
|
||||
igcsr32 agpcmd; /* 0xA8 - AGP control register */
|
||||
igcsr32 agpva; /* 0xAC - AGP Virtual Address Space */
|
||||
igcsr32 agpmode; /* 0xB0 - AGP/GART mode control */
|
||||
} Irongate0;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
igcsr32 dev_vendor; /* 0x00 - Device and Vendor IDs */
|
||||
igcsr32 stat_cmd; /* 0x04 - Status and Command regs */
|
||||
igcsr32 class; /* 0x08 - subclass, baseclass etc */
|
||||
igcsr32 htype; /* 0x0C - header type (at 0x0E) */
|
||||
igcsr32 rsrvd0[2]; /* 0x10-0x17 reserved */
|
||||
igcsr32 busnos; /* 0x18 - Primary, secondary bus nos */
|
||||
igcsr32 io_baselim_regs; /* 0x1C - IO base, IO lim, AGP status */
|
||||
igcsr32 mem_baselim; /* 0x20 - memory base, memory lim */
|
||||
igcsr32 pfmem_baselim; /* 0x24 - prefetchable base, lim */
|
||||
igcsr32 rsrvd1[2]; /* 0x28-0x2F reserved */
|
||||
igcsr32 io_baselim; /* 0x30 - IO base, IO limit */
|
||||
igcsr32 rsrvd2[2]; /* 0x34-0x3B - reserved */
|
||||
igcsr32 interrupt; /* 0x3C - interrupt, PCI bridge ctrl */
|
||||
|
||||
} Irongate1;
|
||||
|
||||
extern igcsr32 *IronECC;
|
||||
|
||||
/*
|
||||
* Memory spaces:
|
||||
*/
|
||||
|
||||
/* Irongate is consistent with a subset of the Tsunami memory map */
|
||||
#ifdef USE_48_BIT_KSEG
|
||||
#define IRONGATE_BIAS 0x80000000000UL
|
||||
#else
|
||||
#define IRONGATE_BIAS 0x10000000000UL
|
||||
#endif
|
||||
|
||||
|
||||
#define IRONGATE_MEM (IDENT_ADDR | IRONGATE_BIAS | 0x000000000UL)
|
||||
#define IRONGATE_IACK_SC (IDENT_ADDR | IRONGATE_BIAS | 0x1F8000000UL)
|
||||
#define IRONGATE_IO (IDENT_ADDR | IRONGATE_BIAS | 0x1FC000000UL)
|
||||
#define IRONGATE_CONF (IDENT_ADDR | IRONGATE_BIAS | 0x1FE000000UL)
|
||||
|
||||
/*
|
||||
* PCI Configuration space accesses are formed like so:
|
||||
*
|
||||
* 0x1FE << 24 | : 2 2 2 2 1 1 1 1 : 1 1 1 1 1 1 0 0 : 0 0 0 0 0 0 0 0 :
|
||||
* : 3 2 1 0 9 8 7 6 : 5 4 3 2 1 0 9 8 : 7 6 5 4 3 2 1 0 :
|
||||
* ---bus numer--- -device-- -fun- ---register----
|
||||
*/
|
||||
|
||||
#define IGCSR(dev,fun,reg) ( IRONGATE_CONF | \
|
||||
((dev)<<11) | \
|
||||
((fun)<<8) | \
|
||||
(reg) )
|
||||
|
||||
#define IRONGATE0 ((Irongate0 *) IGCSR(0, 0, 0))
|
||||
#define IRONGATE1 ((Irongate1 *) IGCSR(1, 0, 0))
|
||||
|
||||
/*
|
||||
* Data structure for handling IRONGATE machine checks:
|
||||
* This is the standard OSF logout frame
|
||||
*/
|
||||
|
||||
#define SCB_Q_SYSERR 0x620 /* OSF definitions */
|
||||
#define SCB_Q_PROCERR 0x630
|
||||
#define SCB_Q_SYSMCHK 0x660
|
||||
#define SCB_Q_PROCMCHK 0x670
|
||||
|
||||
struct el_IRONGATE_sysdata_mcheck {
|
||||
__u32 FrameSize; /* Bytes, including this field */
|
||||
__u32 FrameFlags; /* <31> = Retry, <30> = Second Error */
|
||||
__u32 CpuOffset; /* Offset to CPU-specific into */
|
||||
__u32 SystemOffset; /* Offset to system-specific info */
|
||||
__u32 MCHK_Code;
|
||||
__u32 MCHK_Frame_Rev;
|
||||
__u64 I_STAT;
|
||||
__u64 DC_STAT;
|
||||
__u64 C_ADDR;
|
||||
__u64 DC1_SYNDROME;
|
||||
__u64 DC0_SYNDROME;
|
||||
__u64 C_STAT;
|
||||
__u64 C_STS;
|
||||
__u64 RESERVED0;
|
||||
__u64 EXC_ADDR;
|
||||
__u64 IER_CM;
|
||||
__u64 ISUM;
|
||||
__u64 MM_STAT;
|
||||
__u64 PAL_BASE;
|
||||
__u64 I_CTL;
|
||||
__u64 PCTX;
|
||||
};
|
||||
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef __EXTERN_INLINE
|
||||
#define __EXTERN_INLINE extern inline
|
||||
#define __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I/O functions:
|
||||
*
|
||||
* IRONGATE (AMD-751) PCI/memory support chip for the EV6 (21264) and
|
||||
* K7 can only use linear accesses to get at PCI memory and I/O spaces.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory functions. All accesses are done through linear space.
|
||||
*/
|
||||
|
||||
__EXTERN_INLINE void __iomem *irongate_ioportmap(unsigned long addr)
|
||||
{
|
||||
return (void __iomem *)(addr + IRONGATE_IO);
|
||||
}
|
||||
|
||||
extern void __iomem *irongate_ioremap(unsigned long addr, unsigned long size);
|
||||
extern void irongate_iounmap(volatile void __iomem *addr);
|
||||
|
||||
__EXTERN_INLINE int irongate_is_ioaddr(unsigned long addr)
|
||||
{
|
||||
return addr >= IRONGATE_MEM;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int irongate_is_mmio(const volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long)xaddr;
|
||||
return addr < IRONGATE_IO || addr >= IRONGATE_CONF;
|
||||
}
|
||||
|
||||
#undef __IO_PREFIX
|
||||
#define __IO_PREFIX irongate
|
||||
#define irongate_trivial_rw_bw 1
|
||||
#define irongate_trivial_rw_lq 1
|
||||
#define irongate_trivial_io_bw 1
|
||||
#define irongate_trivial_io_lq 1
|
||||
#define irongate_trivial_iounmap 0
|
||||
#include <asm/io_trivial.h>
|
||||
|
||||
#ifdef __IO_EXTERN_INLINE
|
||||
#undef __EXTERN_INLINE
|
||||
#undef __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ALPHA_IRONGATE__H__ */
|
362
arch/alpha/include/asm/core_lca.h
Normal file
362
arch/alpha/include/asm/core_lca.h
Normal file
@ -0,0 +1,362 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_LCA__H__
|
||||
#define __ALPHA_LCA__H__
|
||||
|
||||
#include <asm/compiler.h>
|
||||
#include <asm/mce.h>
|
||||
|
||||
/*
|
||||
* Low Cost Alpha (LCA) definitions (these apply to 21066 and 21068,
|
||||
* for example).
|
||||
*
|
||||
* This file is based on:
|
||||
*
|
||||
* DECchip 21066 and DECchip 21068 Alpha AXP Microprocessors
|
||||
* Hardware Reference Manual; Digital Equipment Corp.; May 1994;
|
||||
* Maynard, MA; Order Number: EC-N2681-71.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: The LCA uses a Host Address Extension (HAE) register to access
|
||||
* PCI addresses that are beyond the first 27 bits of address
|
||||
* space. Updating the HAE requires an external cycle (and
|
||||
* a memory barrier), which tends to be slow. Instead of updating
|
||||
* it on each sparse memory access, we keep the current HAE value
|
||||
* cached in variable cache_hae. Only if the cached HAE differs
|
||||
* from the desired HAE value do we actually updated HAE register.
|
||||
* The HAE register is preserved by the interrupt handler entry/exit
|
||||
* code, so this scheme works even in the presence of interrupts.
|
||||
*
|
||||
* Dense memory space doesn't require the HAE, but is restricted to
|
||||
* aligned 32 and 64 bit accesses. Special Cycle and Interrupt
|
||||
* Acknowledge cycles may also require the use of the HAE. The LCA
|
||||
* limits I/O address space to the bottom 24 bits of address space,
|
||||
* but this easily covers the 16 bit ISA I/O address space.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE 2! The memory operations do not set any memory barriers, as
|
||||
* it's not needed for cases like a frame buffer that is essentially
|
||||
* memory-like. You need to do them by hand if the operations depend
|
||||
* on ordering.
|
||||
*
|
||||
* Similarly, the port I/O operations do a "mb" only after a write
|
||||
* operation: if an mb is needed before (as in the case of doing
|
||||
* memory mapped I/O first, and then a port I/O operation to the same
|
||||
* device), it needs to be done by hand.
|
||||
*
|
||||
* After the above has bitten me 100 times, I'll give up and just do
|
||||
* the mb all the time, but right now I'm hoping this will work out.
|
||||
* Avoiding mb's may potentially be a noticeable speed improvement,
|
||||
* but I can't honestly say I've tested it.
|
||||
*
|
||||
* Handling interrupts that need to do mb's to synchronize to
|
||||
* non-interrupts is another fun race area. Don't do it (because if
|
||||
* you do, I'll have to do *everything* with interrupts disabled,
|
||||
* ugh).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory Controller registers:
|
||||
*/
|
||||
#define LCA_MEM_BCR0 (IDENT_ADDR + 0x120000000UL)
|
||||
#define LCA_MEM_BCR1 (IDENT_ADDR + 0x120000008UL)
|
||||
#define LCA_MEM_BCR2 (IDENT_ADDR + 0x120000010UL)
|
||||
#define LCA_MEM_BCR3 (IDENT_ADDR + 0x120000018UL)
|
||||
#define LCA_MEM_BMR0 (IDENT_ADDR + 0x120000020UL)
|
||||
#define LCA_MEM_BMR1 (IDENT_ADDR + 0x120000028UL)
|
||||
#define LCA_MEM_BMR2 (IDENT_ADDR + 0x120000030UL)
|
||||
#define LCA_MEM_BMR3 (IDENT_ADDR + 0x120000038UL)
|
||||
#define LCA_MEM_BTR0 (IDENT_ADDR + 0x120000040UL)
|
||||
#define LCA_MEM_BTR1 (IDENT_ADDR + 0x120000048UL)
|
||||
#define LCA_MEM_BTR2 (IDENT_ADDR + 0x120000050UL)
|
||||
#define LCA_MEM_BTR3 (IDENT_ADDR + 0x120000058UL)
|
||||
#define LCA_MEM_GTR (IDENT_ADDR + 0x120000060UL)
|
||||
#define LCA_MEM_ESR (IDENT_ADDR + 0x120000068UL)
|
||||
#define LCA_MEM_EAR (IDENT_ADDR + 0x120000070UL)
|
||||
#define LCA_MEM_CAR (IDENT_ADDR + 0x120000078UL)
|
||||
#define LCA_MEM_VGR (IDENT_ADDR + 0x120000080UL)
|
||||
#define LCA_MEM_PLM (IDENT_ADDR + 0x120000088UL)
|
||||
#define LCA_MEM_FOR (IDENT_ADDR + 0x120000090UL)
|
||||
|
||||
/*
|
||||
* I/O Controller registers:
|
||||
*/
|
||||
#define LCA_IOC_HAE (IDENT_ADDR + 0x180000000UL)
|
||||
#define LCA_IOC_CONF (IDENT_ADDR + 0x180000020UL)
|
||||
#define LCA_IOC_STAT0 (IDENT_ADDR + 0x180000040UL)
|
||||
#define LCA_IOC_STAT1 (IDENT_ADDR + 0x180000060UL)
|
||||
#define LCA_IOC_TBIA (IDENT_ADDR + 0x180000080UL)
|
||||
#define LCA_IOC_TB_ENA (IDENT_ADDR + 0x1800000a0UL)
|
||||
#define LCA_IOC_SFT_RST (IDENT_ADDR + 0x1800000c0UL)
|
||||
#define LCA_IOC_PAR_DIS (IDENT_ADDR + 0x1800000e0UL)
|
||||
#define LCA_IOC_W_BASE0 (IDENT_ADDR + 0x180000100UL)
|
||||
#define LCA_IOC_W_BASE1 (IDENT_ADDR + 0x180000120UL)
|
||||
#define LCA_IOC_W_MASK0 (IDENT_ADDR + 0x180000140UL)
|
||||
#define LCA_IOC_W_MASK1 (IDENT_ADDR + 0x180000160UL)
|
||||
#define LCA_IOC_T_BASE0 (IDENT_ADDR + 0x180000180UL)
|
||||
#define LCA_IOC_T_BASE1 (IDENT_ADDR + 0x1800001a0UL)
|
||||
#define LCA_IOC_TB_TAG0 (IDENT_ADDR + 0x188000000UL)
|
||||
#define LCA_IOC_TB_TAG1 (IDENT_ADDR + 0x188000020UL)
|
||||
#define LCA_IOC_TB_TAG2 (IDENT_ADDR + 0x188000040UL)
|
||||
#define LCA_IOC_TB_TAG3 (IDENT_ADDR + 0x188000060UL)
|
||||
#define LCA_IOC_TB_TAG4 (IDENT_ADDR + 0x188000070UL)
|
||||
#define LCA_IOC_TB_TAG5 (IDENT_ADDR + 0x1880000a0UL)
|
||||
#define LCA_IOC_TB_TAG6 (IDENT_ADDR + 0x1880000c0UL)
|
||||
#define LCA_IOC_TB_TAG7 (IDENT_ADDR + 0x1880000e0UL)
|
||||
|
||||
/*
|
||||
* Memory spaces:
|
||||
*/
|
||||
#define LCA_IACK_SC (IDENT_ADDR + 0x1a0000000UL)
|
||||
#define LCA_CONF (IDENT_ADDR + 0x1e0000000UL)
|
||||
#define LCA_IO (IDENT_ADDR + 0x1c0000000UL)
|
||||
#define LCA_SPARSE_MEM (IDENT_ADDR + 0x200000000UL)
|
||||
#define LCA_DENSE_MEM (IDENT_ADDR + 0x300000000UL)
|
||||
|
||||
/*
|
||||
* Bit definitions for I/O Controller status register 0:
|
||||
*/
|
||||
#define LCA_IOC_STAT0_CMD 0xf
|
||||
#define LCA_IOC_STAT0_ERR (1<<4)
|
||||
#define LCA_IOC_STAT0_LOST (1<<5)
|
||||
#define LCA_IOC_STAT0_THIT (1<<6)
|
||||
#define LCA_IOC_STAT0_TREF (1<<7)
|
||||
#define LCA_IOC_STAT0_CODE_SHIFT 8
|
||||
#define LCA_IOC_STAT0_CODE_MASK 0x7
|
||||
#define LCA_IOC_STAT0_P_NBR_SHIFT 13
|
||||
#define LCA_IOC_STAT0_P_NBR_MASK 0x7ffff
|
||||
|
||||
#define LCA_HAE_ADDRESS LCA_IOC_HAE
|
||||
|
||||
/* LCA PMR Power Management register defines */
|
||||
#define LCA_PMR_ADDR (IDENT_ADDR + 0x120000098UL)
|
||||
#define LCA_PMR_PDIV 0x7 /* Primary clock divisor */
|
||||
#define LCA_PMR_ODIV 0x38 /* Override clock divisor */
|
||||
#define LCA_PMR_INTO 0x40 /* Interrupt override */
|
||||
#define LCA_PMR_DMAO 0x80 /* DMA override */
|
||||
#define LCA_PMR_OCCEB 0xffff0000L /* Override cycle counter - even bits */
|
||||
#define LCA_PMR_OCCOB 0xffff000000000000L /* Override cycle counter - even bits */
|
||||
#define LCA_PMR_PRIMARY_MASK 0xfffffffffffffff8L
|
||||
|
||||
/* LCA PMR Macros */
|
||||
|
||||
#define LCA_READ_PMR (*(volatile unsigned long *)LCA_PMR_ADDR)
|
||||
#define LCA_WRITE_PMR(d) (*((volatile unsigned long *)LCA_PMR_ADDR) = (d))
|
||||
|
||||
#define LCA_GET_PRIMARY(r) ((r) & LCA_PMR_PDIV)
|
||||
#define LCA_GET_OVERRIDE(r) (((r) >> 3) & LCA_PMR_PDIV)
|
||||
#define LCA_SET_PRIMARY_CLOCK(r, c) ((r) = (((r) & LCA_PMR_PRIMARY_MASK)|(c)))
|
||||
|
||||
/* LCA PMR Divisor values */
|
||||
#define LCA_PMR_DIV_1 0x0
|
||||
#define LCA_PMR_DIV_1_5 0x1
|
||||
#define LCA_PMR_DIV_2 0x2
|
||||
#define LCA_PMR_DIV_4 0x3
|
||||
#define LCA_PMR_DIV_8 0x4
|
||||
#define LCA_PMR_DIV_16 0x5
|
||||
#define LCA_PMR_DIV_MIN DIV_1
|
||||
#define LCA_PMR_DIV_MAX DIV_16
|
||||
|
||||
|
||||
/*
|
||||
* Data structure for handling LCA machine checks. Correctable errors
|
||||
* result in a short logout frame, uncorrectable ones in a long one.
|
||||
*/
|
||||
struct el_lca_mcheck_short {
|
||||
struct el_common h; /* common logout header */
|
||||
unsigned long esr; /* error-status register */
|
||||
unsigned long ear; /* error-address register */
|
||||
unsigned long dc_stat; /* dcache status register */
|
||||
unsigned long ioc_stat0; /* I/O controller status register 0 */
|
||||
unsigned long ioc_stat1; /* I/O controller status register 1 */
|
||||
};
|
||||
|
||||
struct el_lca_mcheck_long {
|
||||
struct el_common h; /* common logout header */
|
||||
unsigned long pt[31]; /* PAL temps */
|
||||
unsigned long exc_addr; /* exception address */
|
||||
unsigned long pad1[3];
|
||||
unsigned long pal_base; /* PALcode base address */
|
||||
unsigned long hier; /* hw interrupt enable */
|
||||
unsigned long hirr; /* hw interrupt request */
|
||||
unsigned long mm_csr; /* MMU control & status */
|
||||
unsigned long dc_stat; /* data cache status */
|
||||
unsigned long dc_addr; /* data cache addr register */
|
||||
unsigned long abox_ctl; /* address box control register */
|
||||
unsigned long esr; /* error status register */
|
||||
unsigned long ear; /* error address register */
|
||||
unsigned long car; /* cache control register */
|
||||
unsigned long ioc_stat0; /* I/O controller status register 0 */
|
||||
unsigned long ioc_stat1; /* I/O controller status register 1 */
|
||||
unsigned long va; /* virtual address register */
|
||||
};
|
||||
|
||||
union el_lca {
|
||||
struct el_common * c;
|
||||
struct el_lca_mcheck_long * l;
|
||||
struct el_lca_mcheck_short * s;
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef __EXTERN_INLINE
|
||||
#define __EXTERN_INLINE extern inline
|
||||
#define __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I/O functions:
|
||||
*
|
||||
* Unlike Jensen, the Noname machines have no concept of local
|
||||
* I/O---everything goes over the PCI bus.
|
||||
*
|
||||
* There is plenty room for optimization here. In particular,
|
||||
* the Alpha's insb/insw/extb/extw should be useful in moving
|
||||
* data to/from the right byte-lanes.
|
||||
*/
|
||||
|
||||
#define vip volatile int __force *
|
||||
#define vuip volatile unsigned int __force *
|
||||
#define vulp volatile unsigned long __force *
|
||||
|
||||
#define LCA_SET_HAE \
|
||||
do { \
|
||||
if (addr >= (1UL << 24)) { \
|
||||
unsigned long msb = addr & 0xf8000000; \
|
||||
addr -= msb; \
|
||||
set_hae(msb); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
__EXTERN_INLINE unsigned int lca_ioread8(const void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
unsigned long result, base_and_type;
|
||||
|
||||
if (addr >= LCA_DENSE_MEM) {
|
||||
addr -= LCA_DENSE_MEM;
|
||||
LCA_SET_HAE;
|
||||
base_and_type = LCA_SPARSE_MEM + 0x00;
|
||||
} else {
|
||||
addr -= LCA_IO;
|
||||
base_and_type = LCA_IO + 0x00;
|
||||
}
|
||||
|
||||
result = *(vip) ((addr << 5) + base_and_type);
|
||||
return __kernel_extbl(result, addr & 3);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void lca_iowrite8(u8 b, void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
unsigned long w, base_and_type;
|
||||
|
||||
if (addr >= LCA_DENSE_MEM) {
|
||||
addr -= LCA_DENSE_MEM;
|
||||
LCA_SET_HAE;
|
||||
base_and_type = LCA_SPARSE_MEM + 0x00;
|
||||
} else {
|
||||
addr -= LCA_IO;
|
||||
base_and_type = LCA_IO + 0x00;
|
||||
}
|
||||
|
||||
w = __kernel_insbl(b, addr & 3);
|
||||
*(vuip) ((addr << 5) + base_and_type) = w;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE unsigned int lca_ioread16(const void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
unsigned long result, base_and_type;
|
||||
|
||||
if (addr >= LCA_DENSE_MEM) {
|
||||
addr -= LCA_DENSE_MEM;
|
||||
LCA_SET_HAE;
|
||||
base_and_type = LCA_SPARSE_MEM + 0x08;
|
||||
} else {
|
||||
addr -= LCA_IO;
|
||||
base_and_type = LCA_IO + 0x08;
|
||||
}
|
||||
|
||||
result = *(vip) ((addr << 5) + base_and_type);
|
||||
return __kernel_extwl(result, addr & 3);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void lca_iowrite16(u16 b, void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
unsigned long w, base_and_type;
|
||||
|
||||
if (addr >= LCA_DENSE_MEM) {
|
||||
addr -= LCA_DENSE_MEM;
|
||||
LCA_SET_HAE;
|
||||
base_and_type = LCA_SPARSE_MEM + 0x08;
|
||||
} else {
|
||||
addr -= LCA_IO;
|
||||
base_and_type = LCA_IO + 0x08;
|
||||
}
|
||||
|
||||
w = __kernel_inswl(b, addr & 3);
|
||||
*(vuip) ((addr << 5) + base_and_type) = w;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE unsigned int lca_ioread32(const void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
if (addr < LCA_DENSE_MEM)
|
||||
addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
|
||||
return *(vuip)addr;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void lca_iowrite32(u32 b, void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
if (addr < LCA_DENSE_MEM)
|
||||
addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
|
||||
*(vuip)addr = b;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void __iomem *lca_ioportmap(unsigned long addr)
|
||||
{
|
||||
return (void __iomem *)(addr + LCA_IO);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void __iomem *lca_ioremap(unsigned long addr,
|
||||
unsigned long size)
|
||||
{
|
||||
return (void __iomem *)(addr + LCA_DENSE_MEM);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int lca_is_ioaddr(unsigned long addr)
|
||||
{
|
||||
return addr >= IDENT_ADDR + 0x120000000UL;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int lca_is_mmio(const volatile void __iomem *addr)
|
||||
{
|
||||
return (unsigned long)addr >= LCA_DENSE_MEM;
|
||||
}
|
||||
|
||||
#undef vip
|
||||
#undef vuip
|
||||
#undef vulp
|
||||
|
||||
#undef __IO_PREFIX
|
||||
#define __IO_PREFIX lca
|
||||
#define lca_trivial_rw_bw 2
|
||||
#define lca_trivial_rw_lq 1
|
||||
#define lca_trivial_io_bw 0
|
||||
#define lca_trivial_io_lq 0
|
||||
#define lca_trivial_iounmap 1
|
||||
#include <asm/io_trivial.h>
|
||||
|
||||
#ifdef __IO_EXTERN_INLINE
|
||||
#undef __EXTERN_INLINE
|
||||
#undef __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ALPHA_LCA__H__ */
|
378
arch/alpha/include/asm/core_marvel.h
Normal file
378
arch/alpha/include/asm/core_marvel.h
Normal file
@ -0,0 +1,378 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Marvel systems use the IO7 I/O chip provides PCI/PCIX/AGP access
|
||||
*
|
||||
* This file is based on:
|
||||
*
|
||||
* Marvel / EV7 System Programmer's Manual
|
||||
* Revision 1.00
|
||||
* 14 May 2001
|
||||
*/
|
||||
|
||||
#ifndef __ALPHA_MARVEL__H__
|
||||
#define __ALPHA_MARVEL__H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/compiler.h>
|
||||
|
||||
#define MARVEL_MAX_PIDS 32 /* as long as we rely on 43-bit superpage */
|
||||
#define MARVEL_IRQ_VEC_PE_SHIFT (10)
|
||||
#define MARVEL_IRQ_VEC_IRQ_MASK ((1 << MARVEL_IRQ_VEC_PE_SHIFT) - 1)
|
||||
#define MARVEL_NR_IRQS \
|
||||
(16 + (MARVEL_MAX_PIDS * (1 << MARVEL_IRQ_VEC_PE_SHIFT)))
|
||||
|
||||
/*
|
||||
* EV7 RBOX Registers
|
||||
*/
|
||||
typedef struct {
|
||||
volatile unsigned long csr __attribute__((aligned(16)));
|
||||
} ev7_csr;
|
||||
|
||||
typedef struct {
|
||||
ev7_csr RBOX_CFG; /* 0x0000 */
|
||||
ev7_csr RBOX_NSVC;
|
||||
ev7_csr RBOX_EWVC;
|
||||
ev7_csr RBOX_WHAMI;
|
||||
ev7_csr RBOX_TCTL; /* 0x0040 */
|
||||
ev7_csr RBOX_INT;
|
||||
ev7_csr RBOX_IMASK;
|
||||
ev7_csr RBOX_IREQ;
|
||||
ev7_csr RBOX_INTQ; /* 0x0080 */
|
||||
ev7_csr RBOX_INTA;
|
||||
ev7_csr RBOX_IT;
|
||||
ev7_csr RBOX_SCRATCH1;
|
||||
ev7_csr RBOX_SCRATCH2; /* 0x00c0 */
|
||||
ev7_csr RBOX_L_ERR;
|
||||
} ev7_csrs;
|
||||
|
||||
/*
|
||||
* EV7 CSR addressing macros
|
||||
*/
|
||||
#define EV7_MASK40(addr) ((addr) & ((1UL << 41) - 1))
|
||||
#define EV7_KERN_ADDR(addr) ((void *)(IDENT_ADDR | EV7_MASK40(addr)))
|
||||
|
||||
#define EV7_PE_MASK 0x1ffUL /* 9 bits ( 256 + mem/io ) */
|
||||
#define EV7_IPE(pe) ((~((long)(pe)) & EV7_PE_MASK) << 35)
|
||||
|
||||
#define EV7_CSR_PHYS(pe, off) (EV7_IPE(pe) | (0x7FFCUL << 20) | (off))
|
||||
#define EV7_CSRS_PHYS(pe) (EV7_CSR_PHYS(pe, 0UL))
|
||||
|
||||
#define EV7_CSR_KERN(pe, off) (EV7_KERN_ADDR(EV7_CSR_PHYS(pe, off)))
|
||||
#define EV7_CSRS_KERN(pe) (EV7_KERN_ADDR(EV7_CSRS_PHYS(pe)))
|
||||
|
||||
#define EV7_CSR_OFFSET(name) ((unsigned long)&((ev7_csrs *)NULL)->name.csr)
|
||||
|
||||
/*
|
||||
* IO7 registers
|
||||
*/
|
||||
typedef struct {
|
||||
volatile unsigned long csr __attribute__((aligned(64)));
|
||||
} io7_csr;
|
||||
|
||||
typedef struct {
|
||||
/* I/O Port Control Registers */
|
||||
io7_csr POx_CTRL; /* 0x0000 */
|
||||
io7_csr POx_CACHE_CTL;
|
||||
io7_csr POx_TIMER;
|
||||
io7_csr POx_IO_ADR_EXT;
|
||||
io7_csr POx_MEM_ADR_EXT; /* 0x0100 */
|
||||
io7_csr POx_XCAL_CTRL;
|
||||
io7_csr rsvd1[2]; /* ?? spec doesn't show 0x180 */
|
||||
io7_csr POx_DM_SOURCE; /* 0x0200 */
|
||||
io7_csr POx_DM_DEST;
|
||||
io7_csr POx_DM_SIZE;
|
||||
io7_csr POx_DM_CTRL;
|
||||
io7_csr rsvd2[4]; /* 0x0300 */
|
||||
|
||||
/* AGP Control Registers -- port 3 only */
|
||||
io7_csr AGP_CAP_ID; /* 0x0400 */
|
||||
io7_csr AGP_STAT;
|
||||
io7_csr AGP_CMD;
|
||||
io7_csr rsvd3;
|
||||
|
||||
/* I/O Port Monitor Registers */
|
||||
io7_csr POx_MONCTL; /* 0x0500 */
|
||||
io7_csr POx_CTRA;
|
||||
io7_csr POx_CTRB;
|
||||
io7_csr POx_CTR56;
|
||||
io7_csr POx_SCRATCH; /* 0x0600 */
|
||||
io7_csr POx_XTRA_A;
|
||||
io7_csr POx_XTRA_TS;
|
||||
io7_csr POx_XTRA_Z;
|
||||
io7_csr rsvd4; /* 0x0700 */
|
||||
io7_csr POx_THRESHA;
|
||||
io7_csr POx_THRESHB;
|
||||
io7_csr rsvd5[33];
|
||||
|
||||
/* System Address Space Window Control Registers */
|
||||
|
||||
io7_csr POx_WBASE[4]; /* 0x1000 */
|
||||
io7_csr POx_WMASK[4];
|
||||
io7_csr POx_TBASE[4];
|
||||
io7_csr POx_SG_TBIA;
|
||||
io7_csr POx_MSI_WBASE;
|
||||
io7_csr rsvd6[50];
|
||||
|
||||
/* I/O Port Error Registers */
|
||||
io7_csr POx_ERR_SUM;
|
||||
io7_csr POx_FIRST_ERR;
|
||||
io7_csr POx_MSK_HEI;
|
||||
io7_csr POx_TLB_ERR;
|
||||
io7_csr POx_SPL_COMPLT;
|
||||
io7_csr POx_TRANS_SUM;
|
||||
io7_csr POx_FRC_PCI_ERR;
|
||||
io7_csr POx_MULT_ERR;
|
||||
io7_csr rsvd7[8];
|
||||
|
||||
/* I/O Port End of Interrupt Registers */
|
||||
io7_csr EOI_DAT;
|
||||
io7_csr rsvd8[7];
|
||||
io7_csr POx_IACK_SPECIAL;
|
||||
io7_csr rsvd9[103];
|
||||
} io7_ioport_csrs;
|
||||
|
||||
typedef struct {
|
||||
io7_csr IO_ASIC_REV; /* 0x30.0000 */
|
||||
io7_csr IO_SYS_REV;
|
||||
io7_csr SER_CHAIN3;
|
||||
io7_csr PO7_RST1;
|
||||
io7_csr PO7_RST2; /* 0x30.0100 */
|
||||
io7_csr POx_RST[4];
|
||||
io7_csr IO7_DWNH;
|
||||
io7_csr IO7_MAF;
|
||||
io7_csr IO7_MAF_TO;
|
||||
io7_csr IO7_ACC_CLUMP; /* 0x30.0300 */
|
||||
io7_csr IO7_PMASK;
|
||||
io7_csr IO7_IOMASK;
|
||||
io7_csr IO7_UPH;
|
||||
io7_csr IO7_UPH_TO; /* 0x30.0400 */
|
||||
io7_csr RBX_IREQ_OFF;
|
||||
io7_csr RBX_INTA_OFF;
|
||||
io7_csr INT_RTY;
|
||||
io7_csr PO7_MONCTL; /* 0x30.0500 */
|
||||
io7_csr PO7_CTRA;
|
||||
io7_csr PO7_CTRB;
|
||||
io7_csr PO7_CTR56;
|
||||
io7_csr PO7_SCRATCH; /* 0x30.0600 */
|
||||
io7_csr PO7_XTRA_A;
|
||||
io7_csr PO7_XTRA_TS;
|
||||
io7_csr PO7_XTRA_Z;
|
||||
io7_csr PO7_PMASK; /* 0x30.0700 */
|
||||
io7_csr PO7_THRESHA;
|
||||
io7_csr PO7_THRESHB;
|
||||
io7_csr rsvd1[97];
|
||||
io7_csr PO7_ERROR_SUM; /* 0x30.2000 */
|
||||
io7_csr PO7_BHOLE_MASK;
|
||||
io7_csr PO7_HEI_MSK;
|
||||
io7_csr PO7_CRD_MSK;
|
||||
io7_csr PO7_UNCRR_SYM; /* 0x30.2100 */
|
||||
io7_csr PO7_CRRCT_SYM;
|
||||
io7_csr PO7_ERR_PKT[2];
|
||||
io7_csr PO7_UGBGE_SYM; /* 0x30.2200 */
|
||||
io7_csr rsbv2[887];
|
||||
io7_csr PO7_LSI_CTL[128]; /* 0x31.0000 */
|
||||
io7_csr rsvd3[123];
|
||||
io7_csr HLT_CTL; /* 0x31.3ec0 */
|
||||
io7_csr HPI_CTL; /* 0x31.3f00 */
|
||||
io7_csr CRD_CTL;
|
||||
io7_csr STV_CTL;
|
||||
io7_csr HEI_CTL;
|
||||
io7_csr PO7_MSI_CTL[16]; /* 0x31.4000 */
|
||||
io7_csr rsvd4[240];
|
||||
|
||||
/*
|
||||
* Interrupt Diagnostic / Test
|
||||
*/
|
||||
struct {
|
||||
io7_csr INT_PND;
|
||||
io7_csr INT_CLR;
|
||||
io7_csr INT_EOI;
|
||||
io7_csr rsvd[29];
|
||||
} INT_DIAG[4];
|
||||
io7_csr rsvd5[125]; /* 0x31.a000 */
|
||||
io7_csr MISC_PND; /* 0x31.b800 */
|
||||
io7_csr rsvd6[31];
|
||||
io7_csr MSI_PND[16]; /* 0x31.c000 */
|
||||
io7_csr rsvd7[16];
|
||||
io7_csr MSI_CLR[16]; /* 0x31.c800 */
|
||||
} io7_port7_csrs;
|
||||
|
||||
/*
|
||||
* IO7 DMA Window Base register (POx_WBASEx)
|
||||
*/
|
||||
#define wbase_m_ena 0x1
|
||||
#define wbase_m_sg 0x2
|
||||
#define wbase_m_dac 0x4
|
||||
#define wbase_m_addr 0xFFF00000
|
||||
union IO7_POx_WBASE {
|
||||
struct {
|
||||
unsigned ena : 1; /* <0> */
|
||||
unsigned sg : 1; /* <1> */
|
||||
unsigned dac : 1; /* <2> -- window 3 only */
|
||||
unsigned rsvd1 : 17;
|
||||
unsigned addr : 12; /* <31:20> */
|
||||
unsigned rsvd2 : 32;
|
||||
} bits;
|
||||
unsigned as_long[2];
|
||||
unsigned as_quad;
|
||||
};
|
||||
|
||||
/*
|
||||
* IO7 IID (Interrupt IDentifier) format
|
||||
*
|
||||
* For level-sensative interrupts, int_num is encoded as:
|
||||
*
|
||||
* bus/port slot/device INTx
|
||||
* <7:5> <4:2> <1:0>
|
||||
*/
|
||||
union IO7_IID {
|
||||
struct {
|
||||
unsigned int_num : 9; /* <8:0> */
|
||||
unsigned tpu_mask : 4; /* <12:9> rsvd */
|
||||
unsigned msi : 1; /* 13 */
|
||||
unsigned ipe : 10; /* <23:14> */
|
||||
unsigned long rsvd : 40;
|
||||
} bits;
|
||||
unsigned int as_long[2];
|
||||
unsigned long as_quad;
|
||||
};
|
||||
|
||||
/*
|
||||
* IO7 addressing macros
|
||||
*/
|
||||
#define IO7_KERN_ADDR(addr) (EV7_KERN_ADDR(addr))
|
||||
|
||||
#define IO7_PORT_MASK 0x07UL /* 3 bits of port */
|
||||
|
||||
#define IO7_IPE(pe) (EV7_IPE(pe))
|
||||
#define IO7_IPORT(port) ((~((long)(port)) & IO7_PORT_MASK) << 32)
|
||||
|
||||
#define IO7_HOSE(pe, port) (IO7_IPE(pe) | IO7_IPORT(port))
|
||||
|
||||
#define IO7_MEM_PHYS(pe, port) (IO7_HOSE(pe, port) | 0x00000000UL)
|
||||
#define IO7_CONF_PHYS(pe, port) (IO7_HOSE(pe, port) | 0xFE000000UL)
|
||||
#define IO7_IO_PHYS(pe, port) (IO7_HOSE(pe, port) | 0xFF000000UL)
|
||||
#define IO7_CSR_PHYS(pe, port, off) \
|
||||
(IO7_HOSE(pe, port) | 0xFF800000UL | (off))
|
||||
#define IO7_CSRS_PHYS(pe, port) (IO7_CSR_PHYS(pe, port, 0UL))
|
||||
#define IO7_PORT7_CSRS_PHYS(pe) (IO7_CSR_PHYS(pe, 7, 0x300000UL))
|
||||
|
||||
#define IO7_MEM_KERN(pe, port) (IO7_KERN_ADDR(IO7_MEM_PHYS(pe, port)))
|
||||
#define IO7_CONF_KERN(pe, port) (IO7_KERN_ADDR(IO7_CONF_PHYS(pe, port)))
|
||||
#define IO7_IO_KERN(pe, port) (IO7_KERN_ADDR(IO7_IO_PHYS(pe, port)))
|
||||
#define IO7_CSR_KERN(pe, port, off) (IO7_KERN_ADDR(IO7_CSR_PHYS(pe,port,off)))
|
||||
#define IO7_CSRS_KERN(pe, port) (IO7_KERN_ADDR(IO7_CSRS_PHYS(pe, port)))
|
||||
#define IO7_PORT7_CSRS_KERN(pe) (IO7_KERN_ADDR(IO7_PORT7_CSRS_PHYS(pe)))
|
||||
|
||||
#define IO7_PLL_RNGA(pll) (((pll) >> 3) & 0x7)
|
||||
#define IO7_PLL_RNGB(pll) (((pll) >> 6) & 0x7)
|
||||
|
||||
#define IO7_MEM_SPACE (2UL * 1024 * 1024 * 1024) /* 2GB MEM */
|
||||
#define IO7_IO_SPACE (8UL * 1024 * 1024) /* 8MB I/O */
|
||||
|
||||
|
||||
/*
|
||||
* Offset between ram physical addresses and pci64 DAC addresses
|
||||
*/
|
||||
#define IO7_DAC_OFFSET (1UL << 49)
|
||||
|
||||
/*
|
||||
* This is needed to satisify the IO() macro used in initializing the machvec
|
||||
*/
|
||||
#define MARVEL_IACK_SC \
|
||||
((unsigned long) \
|
||||
(&(((io7_ioport_csrs *)IO7_CSRS_KERN(0, 0))->POx_IACK_SPECIAL)))
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/*
|
||||
* IO7 structs
|
||||
*/
|
||||
#define IO7_NUM_PORTS 4
|
||||
#define IO7_AGP_PORT 3
|
||||
|
||||
struct io7_port {
|
||||
struct io7 *io7;
|
||||
struct pci_controller *hose;
|
||||
|
||||
int enabled;
|
||||
unsigned int port;
|
||||
io7_ioport_csrs *csrs;
|
||||
|
||||
unsigned long saved_wbase[4];
|
||||
unsigned long saved_wmask[4];
|
||||
unsigned long saved_tbase[4];
|
||||
};
|
||||
|
||||
struct io7 {
|
||||
struct io7 *next;
|
||||
|
||||
unsigned int pe;
|
||||
io7_port7_csrs *csrs;
|
||||
struct io7_port ports[IO7_NUM_PORTS];
|
||||
|
||||
raw_spinlock_t irq_lock;
|
||||
};
|
||||
|
||||
#ifndef __EXTERN_INLINE
|
||||
# define __EXTERN_INLINE extern inline
|
||||
# define __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I/O functions. All access through linear space.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory functions. All accesses through linear space.
|
||||
*/
|
||||
|
||||
#define vucp volatile unsigned char __force *
|
||||
#define vusp volatile unsigned short __force *
|
||||
|
||||
extern unsigned int marvel_ioread8(const void __iomem *);
|
||||
extern void marvel_iowrite8(u8 b, void __iomem *);
|
||||
|
||||
__EXTERN_INLINE unsigned int marvel_ioread16(const void __iomem *addr)
|
||||
{
|
||||
return __kernel_ldwu(*(vusp)addr);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void marvel_iowrite16(u16 b, void __iomem *addr)
|
||||
{
|
||||
__kernel_stw(b, *(vusp)addr);
|
||||
}
|
||||
|
||||
extern void __iomem *marvel_ioremap(unsigned long addr, unsigned long size);
|
||||
extern void marvel_iounmap(volatile void __iomem *addr);
|
||||
extern void __iomem *marvel_ioportmap (unsigned long addr);
|
||||
|
||||
__EXTERN_INLINE int marvel_is_ioaddr(unsigned long addr)
|
||||
{
|
||||
return (addr >> 40) & 1;
|
||||
}
|
||||
|
||||
extern int marvel_is_mmio(const volatile void __iomem *);
|
||||
|
||||
#undef vucp
|
||||
#undef vusp
|
||||
|
||||
#undef __IO_PREFIX
|
||||
#define __IO_PREFIX marvel
|
||||
#define marvel_trivial_rw_bw 1
|
||||
#define marvel_trivial_rw_lq 1
|
||||
#define marvel_trivial_io_bw 0
|
||||
#define marvel_trivial_io_lq 1
|
||||
#define marvel_trivial_iounmap 0
|
||||
#include <asm/io_trivial.h>
|
||||
|
||||
#ifdef __IO_EXTERN_INLINE
|
||||
# undef __EXTERN_INLINE
|
||||
# undef __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ALPHA_MARVEL__H__ */
|
382
arch/alpha/include/asm/core_mcpcia.h
Normal file
382
arch/alpha/include/asm/core_mcpcia.h
Normal file
@ -0,0 +1,382 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_MCPCIA__H__
|
||||
#define __ALPHA_MCPCIA__H__
|
||||
|
||||
/* Define to experiment with fitting everything into one 128MB HAE window.
|
||||
One window per bus, that is. */
|
||||
#define MCPCIA_ONE_HAE_WINDOW 1
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/compiler.h>
|
||||
#include <asm/mce.h>
|
||||
|
||||
/*
|
||||
* MCPCIA is the internal name for a core logic chipset which provides
|
||||
* PCI access for the RAWHIDE family of systems.
|
||||
*
|
||||
* This file is based on:
|
||||
*
|
||||
* RAWHIDE System Programmer's Manual
|
||||
* 16-May-96
|
||||
* Rev. 1.4
|
||||
*
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------**
|
||||
** **
|
||||
** I/O procedures **
|
||||
** **
|
||||
** inport[b|w|t|l], outport[b|w|t|l] 8:16:24:32 IO xfers **
|
||||
** inportbxt: 8 bits only **
|
||||
** inport: alias of inportw **
|
||||
** outport: alias of outportw **
|
||||
** **
|
||||
** inmem[b|w|t|l], outmem[b|w|t|l] 8:16:24:32 ISA memory xfers **
|
||||
** inmembxt: 8 bits only **
|
||||
** inmem: alias of inmemw **
|
||||
** outmem: alias of outmemw **
|
||||
** **
|
||||
**------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* MCPCIA ADDRESS BIT DEFINITIONS
|
||||
*
|
||||
* 3333 3333 3322 2222 2222 1111 1111 11
|
||||
* 9876 5432 1098 7654 3210 9876 5432 1098 7654 3210
|
||||
* ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
|
||||
* 1 000
|
||||
* ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
|
||||
* | |\|
|
||||
* | Byte Enable --+ |
|
||||
* | Transfer Length --+
|
||||
* +-- IO space, not cached
|
||||
*
|
||||
* Byte Transfer
|
||||
* Enable Length Transfer Byte Address
|
||||
* adr<6:5> adr<4:3> Length Enable Adder
|
||||
* ---------------------------------------------
|
||||
* 00 00 Byte 1110 0x000
|
||||
* 01 00 Byte 1101 0x020
|
||||
* 10 00 Byte 1011 0x040
|
||||
* 11 00 Byte 0111 0x060
|
||||
*
|
||||
* 00 01 Word 1100 0x008
|
||||
* 01 01 Word 1001 0x028 <= Not supported in this code.
|
||||
* 10 01 Word 0011 0x048
|
||||
*
|
||||
* 00 10 Tribyte 1000 0x010
|
||||
* 01 10 Tribyte 0001 0x030
|
||||
*
|
||||
* 10 11 Longword 0000 0x058
|
||||
*
|
||||
* Note that byte enables are asserted low.
|
||||
*
|
||||
*/
|
||||
|
||||
#define MCPCIA_MAX_HOSES 4
|
||||
|
||||
#define MCPCIA_MID(m) ((unsigned long)(m) << 33)
|
||||
|
||||
/* Dodge has PCI0 and PCI1 at MID 4 and 5 respectively.
|
||||
Durango adds PCI2 and PCI3 at MID 6 and 7 respectively. */
|
||||
#define MCPCIA_HOSE2MID(h) ((h) + 4)
|
||||
|
||||
#define MCPCIA_MEM_MASK 0x07ffffff /* SPARSE Mem region mask is 27 bits */
|
||||
|
||||
/*
|
||||
* Memory spaces:
|
||||
*/
|
||||
#define MCPCIA_SPARSE(m) (IDENT_ADDR + 0xf000000000UL + MCPCIA_MID(m))
|
||||
#define MCPCIA_DENSE(m) (IDENT_ADDR + 0xf100000000UL + MCPCIA_MID(m))
|
||||
#define MCPCIA_IO(m) (IDENT_ADDR + 0xf180000000UL + MCPCIA_MID(m))
|
||||
#define MCPCIA_CONF(m) (IDENT_ADDR + 0xf1c0000000UL + MCPCIA_MID(m))
|
||||
#define MCPCIA_CSR(m) (IDENT_ADDR + 0xf1e0000000UL + MCPCIA_MID(m))
|
||||
#define MCPCIA_IO_IACK(m) (IDENT_ADDR + 0xf1f0000000UL + MCPCIA_MID(m))
|
||||
#define MCPCIA_DENSE_IO(m) (IDENT_ADDR + 0xe1fc000000UL + MCPCIA_MID(m))
|
||||
#define MCPCIA_DENSE_CONF(m) (IDENT_ADDR + 0xe1fe000000UL + MCPCIA_MID(m))
|
||||
|
||||
/*
|
||||
* General Registers
|
||||
*/
|
||||
#define MCPCIA_REV(m) (MCPCIA_CSR(m) + 0x000)
|
||||
#define MCPCIA_WHOAMI(m) (MCPCIA_CSR(m) + 0x040)
|
||||
#define MCPCIA_PCI_LAT(m) (MCPCIA_CSR(m) + 0x080)
|
||||
#define MCPCIA_CAP_CTRL(m) (MCPCIA_CSR(m) + 0x100)
|
||||
#define MCPCIA_HAE_MEM(m) (MCPCIA_CSR(m) + 0x400)
|
||||
#define MCPCIA_HAE_IO(m) (MCPCIA_CSR(m) + 0x440)
|
||||
#define _MCPCIA_IACK_SC(m) (MCPCIA_CSR(m) + 0x480)
|
||||
#define MCPCIA_HAE_DENSE(m) (MCPCIA_CSR(m) + 0x4C0)
|
||||
|
||||
/*
|
||||
* Interrupt Control registers
|
||||
*/
|
||||
#define MCPCIA_INT_CTL(m) (MCPCIA_CSR(m) + 0x500)
|
||||
#define MCPCIA_INT_REQ(m) (MCPCIA_CSR(m) + 0x540)
|
||||
#define MCPCIA_INT_TARG(m) (MCPCIA_CSR(m) + 0x580)
|
||||
#define MCPCIA_INT_ADR(m) (MCPCIA_CSR(m) + 0x5C0)
|
||||
#define MCPCIA_INT_ADR_EXT(m) (MCPCIA_CSR(m) + 0x600)
|
||||
#define MCPCIA_INT_MASK0(m) (MCPCIA_CSR(m) + 0x640)
|
||||
#define MCPCIA_INT_MASK1(m) (MCPCIA_CSR(m) + 0x680)
|
||||
#define MCPCIA_INT_ACK0(m) (MCPCIA_CSR(m) + 0x10003f00)
|
||||
#define MCPCIA_INT_ACK1(m) (MCPCIA_CSR(m) + 0x10003f40)
|
||||
|
||||
/*
|
||||
* Performance Monitor registers
|
||||
*/
|
||||
#define MCPCIA_PERF_MON(m) (MCPCIA_CSR(m) + 0x300)
|
||||
#define MCPCIA_PERF_CONT(m) (MCPCIA_CSR(m) + 0x340)
|
||||
|
||||
/*
|
||||
* Diagnostic Registers
|
||||
*/
|
||||
#define MCPCIA_CAP_DIAG(m) (MCPCIA_CSR(m) + 0x700)
|
||||
#define MCPCIA_TOP_OF_MEM(m) (MCPCIA_CSR(m) + 0x7C0)
|
||||
|
||||
/*
|
||||
* Error registers
|
||||
*/
|
||||
#define MCPCIA_MC_ERR0(m) (MCPCIA_CSR(m) + 0x800)
|
||||
#define MCPCIA_MC_ERR1(m) (MCPCIA_CSR(m) + 0x840)
|
||||
#define MCPCIA_CAP_ERR(m) (MCPCIA_CSR(m) + 0x880)
|
||||
#define MCPCIA_PCI_ERR1(m) (MCPCIA_CSR(m) + 0x1040)
|
||||
#define MCPCIA_MDPA_STAT(m) (MCPCIA_CSR(m) + 0x4000)
|
||||
#define MCPCIA_MDPA_SYN(m) (MCPCIA_CSR(m) + 0x4040)
|
||||
#define MCPCIA_MDPA_DIAG(m) (MCPCIA_CSR(m) + 0x4080)
|
||||
#define MCPCIA_MDPB_STAT(m) (MCPCIA_CSR(m) + 0x8000)
|
||||
#define MCPCIA_MDPB_SYN(m) (MCPCIA_CSR(m) + 0x8040)
|
||||
#define MCPCIA_MDPB_DIAG(m) (MCPCIA_CSR(m) + 0x8080)
|
||||
|
||||
/*
|
||||
* PCI Address Translation Registers.
|
||||
*/
|
||||
#define MCPCIA_SG_TBIA(m) (MCPCIA_CSR(m) + 0x1300)
|
||||
#define MCPCIA_HBASE(m) (MCPCIA_CSR(m) + 0x1340)
|
||||
|
||||
#define MCPCIA_W0_BASE(m) (MCPCIA_CSR(m) + 0x1400)
|
||||
#define MCPCIA_W0_MASK(m) (MCPCIA_CSR(m) + 0x1440)
|
||||
#define MCPCIA_T0_BASE(m) (MCPCIA_CSR(m) + 0x1480)
|
||||
|
||||
#define MCPCIA_W1_BASE(m) (MCPCIA_CSR(m) + 0x1500)
|
||||
#define MCPCIA_W1_MASK(m) (MCPCIA_CSR(m) + 0x1540)
|
||||
#define MCPCIA_T1_BASE(m) (MCPCIA_CSR(m) + 0x1580)
|
||||
|
||||
#define MCPCIA_W2_BASE(m) (MCPCIA_CSR(m) + 0x1600)
|
||||
#define MCPCIA_W2_MASK(m) (MCPCIA_CSR(m) + 0x1640)
|
||||
#define MCPCIA_T2_BASE(m) (MCPCIA_CSR(m) + 0x1680)
|
||||
|
||||
#define MCPCIA_W3_BASE(m) (MCPCIA_CSR(m) + 0x1700)
|
||||
#define MCPCIA_W3_MASK(m) (MCPCIA_CSR(m) + 0x1740)
|
||||
#define MCPCIA_T3_BASE(m) (MCPCIA_CSR(m) + 0x1780)
|
||||
|
||||
/* Hack! Only words for bus 0. */
|
||||
|
||||
#ifndef MCPCIA_ONE_HAE_WINDOW
|
||||
#define MCPCIA_HAE_ADDRESS MCPCIA_HAE_MEM(4)
|
||||
#endif
|
||||
#define MCPCIA_IACK_SC _MCPCIA_IACK_SC(4)
|
||||
|
||||
/*
|
||||
* The canonical non-remaped I/O and MEM addresses have these values
|
||||
* subtracted out. This is arranged so that folks manipulating ISA
|
||||
* devices can use their familiar numbers and have them map to bus 0.
|
||||
*/
|
||||
|
||||
#define MCPCIA_IO_BIAS MCPCIA_IO(4)
|
||||
#define MCPCIA_MEM_BIAS MCPCIA_DENSE(4)
|
||||
|
||||
/* Offset between ram physical addresses and pci64 DAC bus addresses. */
|
||||
#define MCPCIA_DAC_OFFSET (1UL << 40)
|
||||
|
||||
/*
|
||||
* Data structure for handling MCPCIA machine checks:
|
||||
*/
|
||||
struct el_MCPCIA_uncorrected_frame_mcheck {
|
||||
struct el_common header;
|
||||
struct el_common_EV5_uncorrectable_mcheck procdata;
|
||||
};
|
||||
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef __EXTERN_INLINE
|
||||
#define __EXTERN_INLINE extern inline
|
||||
#define __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I/O functions:
|
||||
*
|
||||
* MCPCIA, the RAWHIDE family PCI/memory support chipset for the EV5 (21164)
|
||||
* and EV56 (21164a) processors, can use either a sparse address mapping
|
||||
* scheme, or the so-called byte-word PCI address space, to get at PCI memory
|
||||
* and I/O.
|
||||
*
|
||||
* Unfortunately, we can't use BWIO with EV5, so for now, we always use SPARSE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory functions. 64-bit and 32-bit accesses are done through
|
||||
* dense memory space, everything else through sparse space.
|
||||
*
|
||||
* For reading and writing 8 and 16 bit quantities we need to
|
||||
* go through one of the three sparse address mapping regions
|
||||
* and use the HAE_MEM CSR to provide some bits of the address.
|
||||
* The following few routines use only sparse address region 1
|
||||
* which gives 1Gbyte of accessible space which relates exactly
|
||||
* to the amount of PCI memory mapping *into* system address space.
|
||||
* See p 6-17 of the specification but it looks something like this:
|
||||
*
|
||||
* 21164 Address:
|
||||
*
|
||||
* 3 2 1
|
||||
* 9876543210987654321098765432109876543210
|
||||
* 1ZZZZ0.PCI.QW.Address............BBLL
|
||||
*
|
||||
* ZZ = SBZ
|
||||
* BB = Byte offset
|
||||
* LL = Transfer length
|
||||
*
|
||||
* PCI Address:
|
||||
*
|
||||
* 3 2 1
|
||||
* 10987654321098765432109876543210
|
||||
* HHH....PCI.QW.Address........ 00
|
||||
*
|
||||
* HHH = 31:29 HAE_MEM CSR
|
||||
*
|
||||
*/
|
||||
|
||||
#define vip volatile int __force *
|
||||
#define vuip volatile unsigned int __force *
|
||||
|
||||
#ifndef MCPCIA_ONE_HAE_WINDOW
|
||||
#define MCPCIA_FROB_MMIO \
|
||||
if (__mcpcia_is_mmio(hose)) { \
|
||||
set_hae(hose & 0xffffffff); \
|
||||
hose = hose - MCPCIA_DENSE(4) + MCPCIA_SPARSE(4); \
|
||||
}
|
||||
#else
|
||||
#define MCPCIA_FROB_MMIO \
|
||||
if (__mcpcia_is_mmio(hose)) { \
|
||||
hose = hose - MCPCIA_DENSE(4) + MCPCIA_SPARSE(4); \
|
||||
}
|
||||
#endif
|
||||
|
||||
extern inline int __mcpcia_is_mmio(unsigned long addr)
|
||||
{
|
||||
return (addr & 0x80000000UL) == 0;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE unsigned int mcpcia_ioread8(const void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long)xaddr & MCPCIA_MEM_MASK;
|
||||
unsigned long hose = (unsigned long)xaddr & ~MCPCIA_MEM_MASK;
|
||||
unsigned long result;
|
||||
|
||||
MCPCIA_FROB_MMIO;
|
||||
|
||||
result = *(vip) ((addr << 5) + hose + 0x00);
|
||||
return __kernel_extbl(result, addr & 3);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void mcpcia_iowrite8(u8 b, void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long)xaddr & MCPCIA_MEM_MASK;
|
||||
unsigned long hose = (unsigned long)xaddr & ~MCPCIA_MEM_MASK;
|
||||
unsigned long w;
|
||||
|
||||
MCPCIA_FROB_MMIO;
|
||||
|
||||
w = __kernel_insbl(b, addr & 3);
|
||||
*(vuip) ((addr << 5) + hose + 0x00) = w;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE unsigned int mcpcia_ioread16(const void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long)xaddr & MCPCIA_MEM_MASK;
|
||||
unsigned long hose = (unsigned long)xaddr & ~MCPCIA_MEM_MASK;
|
||||
unsigned long result;
|
||||
|
||||
MCPCIA_FROB_MMIO;
|
||||
|
||||
result = *(vip) ((addr << 5) + hose + 0x08);
|
||||
return __kernel_extwl(result, addr & 3);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void mcpcia_iowrite16(u16 b, void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long)xaddr & MCPCIA_MEM_MASK;
|
||||
unsigned long hose = (unsigned long)xaddr & ~MCPCIA_MEM_MASK;
|
||||
unsigned long w;
|
||||
|
||||
MCPCIA_FROB_MMIO;
|
||||
|
||||
w = __kernel_inswl(b, addr & 3);
|
||||
*(vuip) ((addr << 5) + hose + 0x08) = w;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE unsigned int mcpcia_ioread32(const void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long)xaddr;
|
||||
|
||||
if (!__mcpcia_is_mmio(addr))
|
||||
addr = ((addr & 0xffff) << 5) + (addr & ~0xfffful) + 0x18;
|
||||
|
||||
return *(vuip)addr;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void mcpcia_iowrite32(u32 b, void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long)xaddr;
|
||||
|
||||
if (!__mcpcia_is_mmio(addr))
|
||||
addr = ((addr & 0xffff) << 5) + (addr & ~0xfffful) + 0x18;
|
||||
|
||||
*(vuip)addr = b;
|
||||
}
|
||||
|
||||
|
||||
__EXTERN_INLINE void __iomem *mcpcia_ioportmap(unsigned long addr)
|
||||
{
|
||||
return (void __iomem *)(addr + MCPCIA_IO_BIAS);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void __iomem *mcpcia_ioremap(unsigned long addr,
|
||||
unsigned long size)
|
||||
{
|
||||
return (void __iomem *)(addr + MCPCIA_MEM_BIAS);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int mcpcia_is_ioaddr(unsigned long addr)
|
||||
{
|
||||
return addr >= MCPCIA_SPARSE(0);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int mcpcia_is_mmio(const volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
return __mcpcia_is_mmio(addr);
|
||||
}
|
||||
|
||||
#undef MCPCIA_FROB_MMIO
|
||||
|
||||
#undef vip
|
||||
#undef vuip
|
||||
|
||||
#undef __IO_PREFIX
|
||||
#define __IO_PREFIX mcpcia
|
||||
#define mcpcia_trivial_rw_bw 2
|
||||
#define mcpcia_trivial_rw_lq 1
|
||||
#define mcpcia_trivial_io_bw 0
|
||||
#define mcpcia_trivial_io_lq 0
|
||||
#define mcpcia_trivial_iounmap 1
|
||||
#include <asm/io_trivial.h>
|
||||
|
||||
#ifdef __IO_EXTERN_INLINE
|
||||
#undef __EXTERN_INLINE
|
||||
#undef __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ALPHA_MCPCIA__H__ */
|
111
arch/alpha/include/asm/core_polaris.h
Normal file
111
arch/alpha/include/asm/core_polaris.h
Normal file
@ -0,0 +1,111 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_POLARIS__H__
|
||||
#define __ALPHA_POLARIS__H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/compiler.h>
|
||||
|
||||
/*
|
||||
* POLARIS is the internal name for a core logic chipset which provides
|
||||
* memory controller and PCI access for the 21164PC chip based systems.
|
||||
*
|
||||
* This file is based on:
|
||||
*
|
||||
* Polaris System Controller
|
||||
* Device Functional Specification
|
||||
* 22-Jan-98
|
||||
* Rev. 4.2
|
||||
*
|
||||
*/
|
||||
|
||||
/* Polaris memory regions */
|
||||
#define POLARIS_SPARSE_MEM_BASE (IDENT_ADDR + 0xf800000000UL)
|
||||
#define POLARIS_DENSE_MEM_BASE (IDENT_ADDR + 0xf900000000UL)
|
||||
#define POLARIS_SPARSE_IO_BASE (IDENT_ADDR + 0xf980000000UL)
|
||||
#define POLARIS_SPARSE_CONFIG_BASE (IDENT_ADDR + 0xf9c0000000UL)
|
||||
#define POLARIS_IACK_BASE (IDENT_ADDR + 0xf9f8000000UL)
|
||||
#define POLARIS_DENSE_IO_BASE (IDENT_ADDR + 0xf9fc000000UL)
|
||||
#define POLARIS_DENSE_CONFIG_BASE (IDENT_ADDR + 0xf9fe000000UL)
|
||||
|
||||
#define POLARIS_IACK_SC POLARIS_IACK_BASE
|
||||
|
||||
/* The Polaris command/status registers live in PCI Config space for
|
||||
* bus 0/device 0. As such, they may be bytes, words, or doublewords.
|
||||
*/
|
||||
#define POLARIS_W_VENID (POLARIS_DENSE_CONFIG_BASE)
|
||||
#define POLARIS_W_DEVID (POLARIS_DENSE_CONFIG_BASE+2)
|
||||
#define POLARIS_W_CMD (POLARIS_DENSE_CONFIG_BASE+4)
|
||||
#define POLARIS_W_STATUS (POLARIS_DENSE_CONFIG_BASE+6)
|
||||
|
||||
/*
|
||||
* Data structure for handling POLARIS machine checks:
|
||||
*/
|
||||
struct el_POLARIS_sysdata_mcheck {
|
||||
u_long psc_status;
|
||||
u_long psc_pcictl0;
|
||||
u_long psc_pcictl1;
|
||||
u_long psc_pcictl2;
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef __EXTERN_INLINE
|
||||
#define __EXTERN_INLINE extern inline
|
||||
#define __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I/O functions:
|
||||
*
|
||||
* POLARIS, the PCI/memory support chipset for the PCA56 (21164PC)
|
||||
* processors, can use either a sparse address mapping scheme, or the
|
||||
* so-called byte-word PCI address space, to get at PCI memory and I/O.
|
||||
*
|
||||
* However, we will support only the BWX form.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory functions. Polaris allows all accesses (byte/word
|
||||
* as well as long/quad) to be done through dense space.
|
||||
*
|
||||
* We will only support DENSE access via BWX insns.
|
||||
*/
|
||||
|
||||
__EXTERN_INLINE void __iomem *polaris_ioportmap(unsigned long addr)
|
||||
{
|
||||
return (void __iomem *)(addr + POLARIS_DENSE_IO_BASE);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void __iomem *polaris_ioremap(unsigned long addr,
|
||||
unsigned long size)
|
||||
{
|
||||
return (void __iomem *)(addr + POLARIS_DENSE_MEM_BASE);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int polaris_is_ioaddr(unsigned long addr)
|
||||
{
|
||||
return addr >= POLARIS_SPARSE_MEM_BASE;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int polaris_is_mmio(const volatile void __iomem *addr)
|
||||
{
|
||||
return (unsigned long)addr < POLARIS_SPARSE_IO_BASE;
|
||||
}
|
||||
|
||||
#undef __IO_PREFIX
|
||||
#define __IO_PREFIX polaris
|
||||
#define polaris_trivial_rw_bw 1
|
||||
#define polaris_trivial_rw_lq 1
|
||||
#define polaris_trivial_io_bw 1
|
||||
#define polaris_trivial_io_lq 1
|
||||
#define polaris_trivial_iounmap 1
|
||||
#include <asm/io_trivial.h>
|
||||
|
||||
#ifdef __IO_EXTERN_INLINE
|
||||
#undef __EXTERN_INLINE
|
||||
#undef __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ALPHA_POLARIS__H__ */
|
615
arch/alpha/include/asm/core_t2.h
Normal file
615
arch/alpha/include/asm/core_t2.h
Normal file
@ -0,0 +1,615 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_T2__H__
|
||||
#define __ALPHA_T2__H__
|
||||
|
||||
/* Fit everything into one 128MB HAE window. */
|
||||
#define T2_ONE_HAE_WINDOW 1
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <asm/compiler.h>
|
||||
|
||||
/*
|
||||
* T2 is the internal name for the core logic chipset which provides
|
||||
* memory controller and PCI access for the SABLE-based systems.
|
||||
*
|
||||
* This file is based on:
|
||||
*
|
||||
* SABLE I/O Specification
|
||||
* Revision/Update Information: 1.3
|
||||
*
|
||||
* jestabro@amt.tay1.dec.com Initial Version.
|
||||
*
|
||||
*/
|
||||
|
||||
#define T2_MEM_R1_MASK 0x07ffffff /* Mem sparse region 1 mask is 27 bits */
|
||||
|
||||
/* GAMMA-SABLE is a SABLE with EV5-based CPUs */
|
||||
/* All LYNX machines, EV4 or EV5, use the GAMMA bias also */
|
||||
#define _GAMMA_BIAS 0x8000000000UL
|
||||
|
||||
#if defined(CONFIG_ALPHA_GENERIC)
|
||||
#define GAMMA_BIAS alpha_mv.sys.t2.gamma_bias
|
||||
#elif defined(CONFIG_ALPHA_GAMMA)
|
||||
#define GAMMA_BIAS _GAMMA_BIAS
|
||||
#else
|
||||
#define GAMMA_BIAS 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Memory spaces:
|
||||
*/
|
||||
#define T2_CONF (IDENT_ADDR + GAMMA_BIAS + 0x390000000UL)
|
||||
#define T2_IO (IDENT_ADDR + GAMMA_BIAS + 0x3a0000000UL)
|
||||
#define T2_SPARSE_MEM (IDENT_ADDR + GAMMA_BIAS + 0x200000000UL)
|
||||
#define T2_DENSE_MEM (IDENT_ADDR + GAMMA_BIAS + 0x3c0000000UL)
|
||||
|
||||
#define T2_IOCSR (IDENT_ADDR + GAMMA_BIAS + 0x38e000000UL)
|
||||
#define T2_CERR1 (IDENT_ADDR + GAMMA_BIAS + 0x38e000020UL)
|
||||
#define T2_CERR2 (IDENT_ADDR + GAMMA_BIAS + 0x38e000040UL)
|
||||
#define T2_CERR3 (IDENT_ADDR + GAMMA_BIAS + 0x38e000060UL)
|
||||
#define T2_PERR1 (IDENT_ADDR + GAMMA_BIAS + 0x38e000080UL)
|
||||
#define T2_PERR2 (IDENT_ADDR + GAMMA_BIAS + 0x38e0000a0UL)
|
||||
#define T2_PSCR (IDENT_ADDR + GAMMA_BIAS + 0x38e0000c0UL)
|
||||
#define T2_HAE_1 (IDENT_ADDR + GAMMA_BIAS + 0x38e0000e0UL)
|
||||
#define T2_HAE_2 (IDENT_ADDR + GAMMA_BIAS + 0x38e000100UL)
|
||||
#define T2_HBASE (IDENT_ADDR + GAMMA_BIAS + 0x38e000120UL)
|
||||
#define T2_WBASE1 (IDENT_ADDR + GAMMA_BIAS + 0x38e000140UL)
|
||||
#define T2_WMASK1 (IDENT_ADDR + GAMMA_BIAS + 0x38e000160UL)
|
||||
#define T2_TBASE1 (IDENT_ADDR + GAMMA_BIAS + 0x38e000180UL)
|
||||
#define T2_WBASE2 (IDENT_ADDR + GAMMA_BIAS + 0x38e0001a0UL)
|
||||
#define T2_WMASK2 (IDENT_ADDR + GAMMA_BIAS + 0x38e0001c0UL)
|
||||
#define T2_TBASE2 (IDENT_ADDR + GAMMA_BIAS + 0x38e0001e0UL)
|
||||
#define T2_TLBBR (IDENT_ADDR + GAMMA_BIAS + 0x38e000200UL)
|
||||
#define T2_IVR (IDENT_ADDR + GAMMA_BIAS + 0x38e000220UL)
|
||||
#define T2_HAE_3 (IDENT_ADDR + GAMMA_BIAS + 0x38e000240UL)
|
||||
#define T2_HAE_4 (IDENT_ADDR + GAMMA_BIAS + 0x38e000260UL)
|
||||
|
||||
/* The CSRs below are T3/T4 only */
|
||||
#define T2_WBASE3 (IDENT_ADDR + GAMMA_BIAS + 0x38e000280UL)
|
||||
#define T2_WMASK3 (IDENT_ADDR + GAMMA_BIAS + 0x38e0002a0UL)
|
||||
#define T2_TBASE3 (IDENT_ADDR + GAMMA_BIAS + 0x38e0002c0UL)
|
||||
|
||||
#define T2_TDR0 (IDENT_ADDR + GAMMA_BIAS + 0x38e000300UL)
|
||||
#define T2_TDR1 (IDENT_ADDR + GAMMA_BIAS + 0x38e000320UL)
|
||||
#define T2_TDR2 (IDENT_ADDR + GAMMA_BIAS + 0x38e000340UL)
|
||||
#define T2_TDR3 (IDENT_ADDR + GAMMA_BIAS + 0x38e000360UL)
|
||||
#define T2_TDR4 (IDENT_ADDR + GAMMA_BIAS + 0x38e000380UL)
|
||||
#define T2_TDR5 (IDENT_ADDR + GAMMA_BIAS + 0x38e0003a0UL)
|
||||
#define T2_TDR6 (IDENT_ADDR + GAMMA_BIAS + 0x38e0003c0UL)
|
||||
#define T2_TDR7 (IDENT_ADDR + GAMMA_BIAS + 0x38e0003e0UL)
|
||||
|
||||
#define T2_WBASE4 (IDENT_ADDR + GAMMA_BIAS + 0x38e000400UL)
|
||||
#define T2_WMASK4 (IDENT_ADDR + GAMMA_BIAS + 0x38e000420UL)
|
||||
#define T2_TBASE4 (IDENT_ADDR + GAMMA_BIAS + 0x38e000440UL)
|
||||
|
||||
#define T2_AIR (IDENT_ADDR + GAMMA_BIAS + 0x38e000460UL)
|
||||
#define T2_VAR (IDENT_ADDR + GAMMA_BIAS + 0x38e000480UL)
|
||||
#define T2_DIR (IDENT_ADDR + GAMMA_BIAS + 0x38e0004a0UL)
|
||||
#define T2_ICE (IDENT_ADDR + GAMMA_BIAS + 0x38e0004c0UL)
|
||||
|
||||
#ifndef T2_ONE_HAE_WINDOW
|
||||
#define T2_HAE_ADDRESS T2_HAE_1
|
||||
#endif
|
||||
|
||||
/* T2 CSRs are in the non-cachable primary IO space from 3.8000.0000 to
|
||||
3.8fff.ffff
|
||||
*
|
||||
* +--------------+ 3 8000 0000
|
||||
* | CPU 0 CSRs |
|
||||
* +--------------+ 3 8100 0000
|
||||
* | CPU 1 CSRs |
|
||||
* +--------------+ 3 8200 0000
|
||||
* | CPU 2 CSRs |
|
||||
* +--------------+ 3 8300 0000
|
||||
* | CPU 3 CSRs |
|
||||
* +--------------+ 3 8400 0000
|
||||
* | CPU Reserved |
|
||||
* +--------------+ 3 8700 0000
|
||||
* | Mem Reserved |
|
||||
* +--------------+ 3 8800 0000
|
||||
* | Mem 0 CSRs |
|
||||
* +--------------+ 3 8900 0000
|
||||
* | Mem 1 CSRs |
|
||||
* +--------------+ 3 8a00 0000
|
||||
* | Mem 2 CSRs |
|
||||
* +--------------+ 3 8b00 0000
|
||||
* | Mem 3 CSRs |
|
||||
* +--------------+ 3 8c00 0000
|
||||
* | Mem Reserved |
|
||||
* +--------------+ 3 8e00 0000
|
||||
* | PCI Bridge |
|
||||
* +--------------+ 3 8f00 0000
|
||||
* | Expansion IO |
|
||||
* +--------------+ 3 9000 0000
|
||||
*
|
||||
*
|
||||
*/
|
||||
#define T2_CPU0_BASE (IDENT_ADDR + GAMMA_BIAS + 0x380000000L)
|
||||
#define T2_CPU1_BASE (IDENT_ADDR + GAMMA_BIAS + 0x381000000L)
|
||||
#define T2_CPU2_BASE (IDENT_ADDR + GAMMA_BIAS + 0x382000000L)
|
||||
#define T2_CPU3_BASE (IDENT_ADDR + GAMMA_BIAS + 0x383000000L)
|
||||
|
||||
#define T2_CPUn_BASE(n) (T2_CPU0_BASE + (((n)&3) * 0x001000000L))
|
||||
|
||||
#define T2_MEM0_BASE (IDENT_ADDR + GAMMA_BIAS + 0x388000000L)
|
||||
#define T2_MEM1_BASE (IDENT_ADDR + GAMMA_BIAS + 0x389000000L)
|
||||
#define T2_MEM2_BASE (IDENT_ADDR + GAMMA_BIAS + 0x38a000000L)
|
||||
#define T2_MEM3_BASE (IDENT_ADDR + GAMMA_BIAS + 0x38b000000L)
|
||||
|
||||
|
||||
/*
|
||||
* Sable CPU Module CSRS
|
||||
*
|
||||
* These are CSRs for hardware other than the CPU chip on the CPU module.
|
||||
* The CPU module has Backup Cache control logic, Cbus control logic, and
|
||||
* interrupt control logic on it. There is a duplicate tag store to speed
|
||||
* up maintaining cache coherency.
|
||||
*/
|
||||
|
||||
struct sable_cpu_csr {
|
||||
unsigned long bcc; long fill_00[3]; /* Backup Cache Control */
|
||||
unsigned long bcce; long fill_01[3]; /* Backup Cache Correctable Error */
|
||||
unsigned long bccea; long fill_02[3]; /* B-Cache Corr Err Address Latch */
|
||||
unsigned long bcue; long fill_03[3]; /* B-Cache Uncorrectable Error */
|
||||
unsigned long bcuea; long fill_04[3]; /* B-Cache Uncorr Err Addr Latch */
|
||||
unsigned long dter; long fill_05[3]; /* Duplicate Tag Error */
|
||||
unsigned long cbctl; long fill_06[3]; /* CBus Control */
|
||||
unsigned long cbe; long fill_07[3]; /* CBus Error */
|
||||
unsigned long cbeal; long fill_08[3]; /* CBus Error Addr Latch low */
|
||||
unsigned long cbeah; long fill_09[3]; /* CBus Error Addr Latch high */
|
||||
unsigned long pmbx; long fill_10[3]; /* Processor Mailbox */
|
||||
unsigned long ipir; long fill_11[3]; /* Inter-Processor Int Request */
|
||||
unsigned long sic; long fill_12[3]; /* System Interrupt Clear */
|
||||
unsigned long adlk; long fill_13[3]; /* Address Lock (LDxL/STxC) */
|
||||
unsigned long madrl; long fill_14[3]; /* CBus Miss Address */
|
||||
unsigned long rev; long fill_15[3]; /* CMIC Revision */
|
||||
};
|
||||
|
||||
/*
|
||||
* Data structure for handling T2 machine checks:
|
||||
*/
|
||||
struct el_t2_frame_header {
|
||||
unsigned int elcf_fid; /* Frame ID (from above) */
|
||||
unsigned int elcf_size; /* Size of frame in bytes */
|
||||
};
|
||||
|
||||
struct el_t2_procdata_mcheck {
|
||||
unsigned long elfmc_paltemp[32]; /* PAL TEMP REGS. */
|
||||
/* EV4-specific fields */
|
||||
unsigned long elfmc_exc_addr; /* Addr of excepting insn. */
|
||||
unsigned long elfmc_exc_sum; /* Summary of arith traps. */
|
||||
unsigned long elfmc_exc_mask; /* Exception mask (from exc_sum). */
|
||||
unsigned long elfmc_iccsr; /* IBox hardware enables. */
|
||||
unsigned long elfmc_pal_base; /* Base address for PALcode. */
|
||||
unsigned long elfmc_hier; /* Hardware Interrupt Enable. */
|
||||
unsigned long elfmc_hirr; /* Hardware Interrupt Request. */
|
||||
unsigned long elfmc_mm_csr; /* D-stream fault info. */
|
||||
unsigned long elfmc_dc_stat; /* D-cache status (ECC/Parity Err). */
|
||||
unsigned long elfmc_dc_addr; /* EV3 Phys Addr for ECC/DPERR. */
|
||||
unsigned long elfmc_abox_ctl; /* ABox Control Register. */
|
||||
unsigned long elfmc_biu_stat; /* BIU Status. */
|
||||
unsigned long elfmc_biu_addr; /* BUI Address. */
|
||||
unsigned long elfmc_biu_ctl; /* BIU Control. */
|
||||
unsigned long elfmc_fill_syndrome; /* For correcting ECC errors. */
|
||||
unsigned long elfmc_fill_addr;/* Cache block which was being read. */
|
||||
unsigned long elfmc_va; /* Effective VA of fault or miss. */
|
||||
unsigned long elfmc_bc_tag; /* Backup Cache Tag Probe Results. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Sable processor specific Machine Check Data segment.
|
||||
*/
|
||||
|
||||
struct el_t2_logout_header {
|
||||
unsigned int elfl_size; /* size in bytes of logout area. */
|
||||
unsigned int elfl_sbz1:31; /* Should be zero. */
|
||||
unsigned int elfl_retry:1; /* Retry flag. */
|
||||
unsigned int elfl_procoffset; /* Processor-specific offset. */
|
||||
unsigned int elfl_sysoffset; /* Offset of system-specific. */
|
||||
unsigned int elfl_error_type; /* PAL error type code. */
|
||||
unsigned int elfl_frame_rev; /* PAL Frame revision. */
|
||||
};
|
||||
struct el_t2_sysdata_mcheck {
|
||||
unsigned long elcmc_bcc; /* CSR 0 */
|
||||
unsigned long elcmc_bcce; /* CSR 1 */
|
||||
unsigned long elcmc_bccea; /* CSR 2 */
|
||||
unsigned long elcmc_bcue; /* CSR 3 */
|
||||
unsigned long elcmc_bcuea; /* CSR 4 */
|
||||
unsigned long elcmc_dter; /* CSR 5 */
|
||||
unsigned long elcmc_cbctl; /* CSR 6 */
|
||||
unsigned long elcmc_cbe; /* CSR 7 */
|
||||
unsigned long elcmc_cbeal; /* CSR 8 */
|
||||
unsigned long elcmc_cbeah; /* CSR 9 */
|
||||
unsigned long elcmc_pmbx; /* CSR 10 */
|
||||
unsigned long elcmc_ipir; /* CSR 11 */
|
||||
unsigned long elcmc_sic; /* CSR 12 */
|
||||
unsigned long elcmc_adlk; /* CSR 13 */
|
||||
unsigned long elcmc_madrl; /* CSR 14 */
|
||||
unsigned long elcmc_crrev4; /* CSR 15 */
|
||||
};
|
||||
|
||||
/*
|
||||
* Sable memory error frame - sable pfms section 3.42
|
||||
*/
|
||||
struct el_t2_data_memory {
|
||||
struct el_t2_frame_header elcm_hdr; /* ID$MEM-FERR = 0x08 */
|
||||
unsigned int elcm_module; /* Module id. */
|
||||
unsigned int elcm_res04; /* Reserved. */
|
||||
unsigned long elcm_merr; /* CSR0: Error Reg 1. */
|
||||
unsigned long elcm_mcmd1; /* CSR1: Command Trap 1. */
|
||||
unsigned long elcm_mcmd2; /* CSR2: Command Trap 2. */
|
||||
unsigned long elcm_mconf; /* CSR3: Configuration. */
|
||||
unsigned long elcm_medc1; /* CSR4: EDC Status 1. */
|
||||
unsigned long elcm_medc2; /* CSR5: EDC Status 2. */
|
||||
unsigned long elcm_medcc; /* CSR6: EDC Control. */
|
||||
unsigned long elcm_msctl; /* CSR7: Stream Buffer Control. */
|
||||
unsigned long elcm_mref; /* CSR8: Refresh Control. */
|
||||
unsigned long elcm_filter; /* CSR9: CRD Filter Control. */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Sable other CPU error frame - sable pfms section 3.43
|
||||
*/
|
||||
struct el_t2_data_other_cpu {
|
||||
short elco_cpuid; /* CPU ID */
|
||||
short elco_res02[3];
|
||||
unsigned long elco_bcc; /* CSR 0 */
|
||||
unsigned long elco_bcce; /* CSR 1 */
|
||||
unsigned long elco_bccea; /* CSR 2 */
|
||||
unsigned long elco_bcue; /* CSR 3 */
|
||||
unsigned long elco_bcuea; /* CSR 4 */
|
||||
unsigned long elco_dter; /* CSR 5 */
|
||||
unsigned long elco_cbctl; /* CSR 6 */
|
||||
unsigned long elco_cbe; /* CSR 7 */
|
||||
unsigned long elco_cbeal; /* CSR 8 */
|
||||
unsigned long elco_cbeah; /* CSR 9 */
|
||||
unsigned long elco_pmbx; /* CSR 10 */
|
||||
unsigned long elco_ipir; /* CSR 11 */
|
||||
unsigned long elco_sic; /* CSR 12 */
|
||||
unsigned long elco_adlk; /* CSR 13 */
|
||||
unsigned long elco_madrl; /* CSR 14 */
|
||||
unsigned long elco_crrev4; /* CSR 15 */
|
||||
};
|
||||
|
||||
/*
|
||||
* Sable other CPU error frame - sable pfms section 3.44
|
||||
*/
|
||||
struct el_t2_data_t2{
|
||||
struct el_t2_frame_header elct_hdr; /* ID$T2-FRAME */
|
||||
unsigned long elct_iocsr; /* IO Control and Status Register */
|
||||
unsigned long elct_cerr1; /* Cbus Error Register 1 */
|
||||
unsigned long elct_cerr2; /* Cbus Error Register 2 */
|
||||
unsigned long elct_cerr3; /* Cbus Error Register 3 */
|
||||
unsigned long elct_perr1; /* PCI Error Register 1 */
|
||||
unsigned long elct_perr2; /* PCI Error Register 2 */
|
||||
unsigned long elct_hae0_1; /* High Address Extension Register 1 */
|
||||
unsigned long elct_hae0_2; /* High Address Extension Register 2 */
|
||||
unsigned long elct_hbase; /* High Base Register */
|
||||
unsigned long elct_wbase1; /* Window Base Register 1 */
|
||||
unsigned long elct_wmask1; /* Window Mask Register 1 */
|
||||
unsigned long elct_tbase1; /* Translated Base Register 1 */
|
||||
unsigned long elct_wbase2; /* Window Base Register 2 */
|
||||
unsigned long elct_wmask2; /* Window Mask Register 2 */
|
||||
unsigned long elct_tbase2; /* Translated Base Register 2 */
|
||||
unsigned long elct_tdr0; /* TLB Data Register 0 */
|
||||
unsigned long elct_tdr1; /* TLB Data Register 1 */
|
||||
unsigned long elct_tdr2; /* TLB Data Register 2 */
|
||||
unsigned long elct_tdr3; /* TLB Data Register 3 */
|
||||
unsigned long elct_tdr4; /* TLB Data Register 4 */
|
||||
unsigned long elct_tdr5; /* TLB Data Register 5 */
|
||||
unsigned long elct_tdr6; /* TLB Data Register 6 */
|
||||
unsigned long elct_tdr7; /* TLB Data Register 7 */
|
||||
};
|
||||
|
||||
/*
|
||||
* Sable error log data structure - sable pfms section 3.40
|
||||
*/
|
||||
struct el_t2_data_corrected {
|
||||
unsigned long elcpb_biu_stat;
|
||||
unsigned long elcpb_biu_addr;
|
||||
unsigned long elcpb_biu_ctl;
|
||||
unsigned long elcpb_fill_syndrome;
|
||||
unsigned long elcpb_fill_addr;
|
||||
unsigned long elcpb_bc_tag;
|
||||
};
|
||||
|
||||
/*
|
||||
* Sable error log data structure
|
||||
* Note there are 4 memory slots on sable (see t2.h)
|
||||
*/
|
||||
struct el_t2_frame_mcheck {
|
||||
struct el_t2_frame_header elfmc_header; /* ID$P-FRAME_MCHECK */
|
||||
struct el_t2_logout_header elfmc_hdr;
|
||||
struct el_t2_procdata_mcheck elfmc_procdata;
|
||||
struct el_t2_sysdata_mcheck elfmc_sysdata;
|
||||
struct el_t2_data_t2 elfmc_t2data;
|
||||
struct el_t2_data_memory elfmc_memdata[4];
|
||||
struct el_t2_frame_header elfmc_footer; /* empty */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Sable error log data structures on memory errors
|
||||
*/
|
||||
struct el_t2_frame_corrected {
|
||||
struct el_t2_frame_header elfcc_header; /* ID$P-BC-COR */
|
||||
struct el_t2_logout_header elfcc_hdr;
|
||||
struct el_t2_data_corrected elfcc_procdata;
|
||||
/* struct el_t2_data_t2 elfcc_t2data; */
|
||||
/* struct el_t2_data_memory elfcc_memdata[4]; */
|
||||
struct el_t2_frame_header elfcc_footer; /* empty */
|
||||
};
|
||||
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef __EXTERN_INLINE
|
||||
#define __EXTERN_INLINE extern inline
|
||||
#define __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I/O functions:
|
||||
*
|
||||
* T2 (the core logic PCI/memory support chipset for the SABLE
|
||||
* series of processors uses a sparse address mapping scheme to
|
||||
* get at PCI memory and I/O.
|
||||
*/
|
||||
|
||||
#define vip volatile int *
|
||||
#define vuip volatile unsigned int *
|
||||
|
||||
extern inline u8 t2_inb(unsigned long addr)
|
||||
{
|
||||
long result = *(vip) ((addr << 5) + T2_IO + 0x00);
|
||||
return __kernel_extbl(result, addr & 3);
|
||||
}
|
||||
|
||||
extern inline void t2_outb(u8 b, unsigned long addr)
|
||||
{
|
||||
unsigned long w;
|
||||
|
||||
w = __kernel_insbl(b, addr & 3);
|
||||
*(vuip) ((addr << 5) + T2_IO + 0x00) = w;
|
||||
mb();
|
||||
}
|
||||
|
||||
extern inline u16 t2_inw(unsigned long addr)
|
||||
{
|
||||
long result = *(vip) ((addr << 5) + T2_IO + 0x08);
|
||||
return __kernel_extwl(result, addr & 3);
|
||||
}
|
||||
|
||||
extern inline void t2_outw(u16 b, unsigned long addr)
|
||||
{
|
||||
unsigned long w;
|
||||
|
||||
w = __kernel_inswl(b, addr & 3);
|
||||
*(vuip) ((addr << 5) + T2_IO + 0x08) = w;
|
||||
mb();
|
||||
}
|
||||
|
||||
extern inline u32 t2_inl(unsigned long addr)
|
||||
{
|
||||
return *(vuip) ((addr << 5) + T2_IO + 0x18);
|
||||
}
|
||||
|
||||
extern inline void t2_outl(u32 b, unsigned long addr)
|
||||
{
|
||||
*(vuip) ((addr << 5) + T2_IO + 0x18) = b;
|
||||
mb();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Memory functions.
|
||||
*
|
||||
* For reading and writing 8 and 16 bit quantities we need to
|
||||
* go through one of the three sparse address mapping regions
|
||||
* and use the HAE_MEM CSR to provide some bits of the address.
|
||||
* The following few routines use only sparse address region 1
|
||||
* which gives 1Gbyte of accessible space which relates exactly
|
||||
* to the amount of PCI memory mapping *into* system address space.
|
||||
* See p 6-17 of the specification but it looks something like this:
|
||||
*
|
||||
* 21164 Address:
|
||||
*
|
||||
* 3 2 1
|
||||
* 9876543210987654321098765432109876543210
|
||||
* 1ZZZZ0.PCI.QW.Address............BBLL
|
||||
*
|
||||
* ZZ = SBZ
|
||||
* BB = Byte offset
|
||||
* LL = Transfer length
|
||||
*
|
||||
* PCI Address:
|
||||
*
|
||||
* 3 2 1
|
||||
* 10987654321098765432109876543210
|
||||
* HHH....PCI.QW.Address........ 00
|
||||
*
|
||||
* HHH = 31:29 HAE_MEM CSR
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef T2_ONE_HAE_WINDOW
|
||||
#define t2_set_hae
|
||||
#else
|
||||
#define t2_set_hae { \
|
||||
unsigned long msb = addr >> 27; \
|
||||
addr &= T2_MEM_R1_MASK; \
|
||||
set_hae(msb); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NOTE: take T2_DENSE_MEM off in each readX/writeX routine, since
|
||||
* they may be called directly, rather than through the
|
||||
* ioreadNN/iowriteNN routines.
|
||||
*/
|
||||
|
||||
__EXTERN_INLINE u8 t2_readb(const volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
|
||||
unsigned long result;
|
||||
|
||||
t2_set_hae;
|
||||
|
||||
result = *(vip) ((addr << 5) + T2_SPARSE_MEM + 0x00);
|
||||
return __kernel_extbl(result, addr & 3);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE u16 t2_readw(const volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
|
||||
unsigned long result;
|
||||
|
||||
t2_set_hae;
|
||||
|
||||
result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08);
|
||||
return __kernel_extwl(result, addr & 3);
|
||||
}
|
||||
|
||||
/*
|
||||
* On SABLE with T2, we must use SPARSE memory even for 32-bit access,
|
||||
* because we cannot access all of DENSE without changing its HAE.
|
||||
*/
|
||||
__EXTERN_INLINE u32 t2_readl(const volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
|
||||
unsigned long result;
|
||||
|
||||
t2_set_hae;
|
||||
|
||||
result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18);
|
||||
return result & 0xffffffffUL;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE u64 t2_readq(const volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
|
||||
unsigned long r0, r1, work;
|
||||
|
||||
t2_set_hae;
|
||||
|
||||
work = (addr << 5) + T2_SPARSE_MEM + 0x18;
|
||||
r0 = *(vuip)(work);
|
||||
r1 = *(vuip)(work + (4 << 5));
|
||||
return r1 << 32 | r0;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void t2_writeb(u8 b, volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
|
||||
unsigned long w;
|
||||
|
||||
t2_set_hae;
|
||||
|
||||
w = __kernel_insbl(b, addr & 3);
|
||||
*(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x00) = w;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void t2_writew(u16 b, volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
|
||||
unsigned long w;
|
||||
|
||||
t2_set_hae;
|
||||
|
||||
w = __kernel_inswl(b, addr & 3);
|
||||
*(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08) = w;
|
||||
}
|
||||
|
||||
/*
|
||||
* On SABLE with T2, we must use SPARSE memory even for 32-bit access,
|
||||
* because we cannot access all of DENSE without changing its HAE.
|
||||
*/
|
||||
__EXTERN_INLINE void t2_writel(u32 b, volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
|
||||
|
||||
t2_set_hae;
|
||||
|
||||
*(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18) = b;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void t2_writeq(u64 b, volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
|
||||
unsigned long work;
|
||||
|
||||
t2_set_hae;
|
||||
|
||||
work = (addr << 5) + T2_SPARSE_MEM + 0x18;
|
||||
*(vuip)work = b;
|
||||
*(vuip)(work + (4 << 5)) = b >> 32;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void __iomem *t2_ioportmap(unsigned long addr)
|
||||
{
|
||||
return (void __iomem *)(addr + T2_IO);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void __iomem *t2_ioremap(unsigned long addr,
|
||||
unsigned long size)
|
||||
{
|
||||
return (void __iomem *)(addr + T2_DENSE_MEM);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int t2_is_ioaddr(unsigned long addr)
|
||||
{
|
||||
return (long)addr >= 0;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int t2_is_mmio(const volatile void __iomem *addr)
|
||||
{
|
||||
return (unsigned long)addr >= T2_DENSE_MEM;
|
||||
}
|
||||
|
||||
/* New-style ioread interface. The mmio routines are so ugly for T2 that
|
||||
it doesn't make sense to merge the pio and mmio routines. */
|
||||
|
||||
#define IOPORT(OS, NS) \
|
||||
__EXTERN_INLINE unsigned int t2_ioread##NS(const void __iomem *xaddr) \
|
||||
{ \
|
||||
if (t2_is_mmio(xaddr)) \
|
||||
return t2_read##OS(xaddr); \
|
||||
else \
|
||||
return t2_in##OS((unsigned long)xaddr - T2_IO); \
|
||||
} \
|
||||
__EXTERN_INLINE void t2_iowrite##NS(u##NS b, void __iomem *xaddr) \
|
||||
{ \
|
||||
if (t2_is_mmio(xaddr)) \
|
||||
t2_write##OS(b, xaddr); \
|
||||
else \
|
||||
t2_out##OS(b, (unsigned long)xaddr - T2_IO); \
|
||||
}
|
||||
|
||||
IOPORT(b, 8)
|
||||
IOPORT(w, 16)
|
||||
IOPORT(l, 32)
|
||||
|
||||
#undef IOPORT
|
||||
|
||||
#undef vip
|
||||
#undef vuip
|
||||
|
||||
#undef __IO_PREFIX
|
||||
#define __IO_PREFIX t2
|
||||
#define t2_trivial_rw_bw 0
|
||||
#define t2_trivial_rw_lq 0
|
||||
#define t2_trivial_io_bw 0
|
||||
#define t2_trivial_io_lq 0
|
||||
#define t2_trivial_iounmap 1
|
||||
#include <asm/io_trivial.h>
|
||||
|
||||
#ifdef __IO_EXTERN_INLINE
|
||||
#undef __EXTERN_INLINE
|
||||
#undef __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ALPHA_T2__H__ */
|
410
arch/alpha/include/asm/core_titan.h
Normal file
410
arch/alpha/include/asm/core_titan.h
Normal file
@ -0,0 +1,410 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_TITAN__H__
|
||||
#define __ALPHA_TITAN__H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/compiler.h>
|
||||
|
||||
/*
|
||||
* TITAN is the internal names for a core logic chipset which provides
|
||||
* memory controller and PCI/AGP access for 21264 based systems.
|
||||
*
|
||||
* This file is based on:
|
||||
*
|
||||
* Titan Chipset Engineering Specification
|
||||
* Revision 0.12
|
||||
* 13 July 1999
|
||||
*
|
||||
*/
|
||||
|
||||
/* XXX: Do we need to conditionalize on this? */
|
||||
#ifdef USE_48_BIT_KSEG
|
||||
#define TI_BIAS 0x80000000000UL
|
||||
#else
|
||||
#define TI_BIAS 0x10000000000UL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* CChip, DChip, and PChip registers
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned long csr __attribute__((aligned(64)));
|
||||
} titan_64;
|
||||
|
||||
typedef struct {
|
||||
titan_64 csc;
|
||||
titan_64 mtr;
|
||||
titan_64 misc;
|
||||
titan_64 mpd;
|
||||
titan_64 aar0;
|
||||
titan_64 aar1;
|
||||
titan_64 aar2;
|
||||
titan_64 aar3;
|
||||
titan_64 dim0;
|
||||
titan_64 dim1;
|
||||
titan_64 dir0;
|
||||
titan_64 dir1;
|
||||
titan_64 drir;
|
||||
titan_64 prben;
|
||||
titan_64 iic0;
|
||||
titan_64 iic1;
|
||||
titan_64 mpr0;
|
||||
titan_64 mpr1;
|
||||
titan_64 mpr2;
|
||||
titan_64 mpr3;
|
||||
titan_64 rsvd[2];
|
||||
titan_64 ttr;
|
||||
titan_64 tdr;
|
||||
titan_64 dim2;
|
||||
titan_64 dim3;
|
||||
titan_64 dir2;
|
||||
titan_64 dir3;
|
||||
titan_64 iic2;
|
||||
titan_64 iic3;
|
||||
titan_64 pwr;
|
||||
titan_64 reserved[17];
|
||||
titan_64 cmonctla;
|
||||
titan_64 cmonctlb;
|
||||
titan_64 cmoncnt01;
|
||||
titan_64 cmoncnt23;
|
||||
titan_64 cpen;
|
||||
} titan_cchip;
|
||||
|
||||
typedef struct {
|
||||
titan_64 dsc;
|
||||
titan_64 str;
|
||||
titan_64 drev;
|
||||
titan_64 dsc2;
|
||||
} titan_dchip;
|
||||
|
||||
typedef struct {
|
||||
titan_64 wsba[4];
|
||||
titan_64 wsm[4];
|
||||
titan_64 tba[4];
|
||||
titan_64 pctl;
|
||||
titan_64 plat;
|
||||
titan_64 reserved0[2];
|
||||
union {
|
||||
struct {
|
||||
titan_64 serror;
|
||||
titan_64 serren;
|
||||
titan_64 serrset;
|
||||
titan_64 reserved0;
|
||||
titan_64 gperror;
|
||||
titan_64 gperren;
|
||||
titan_64 gperrset;
|
||||
titan_64 reserved1;
|
||||
titan_64 gtlbiv;
|
||||
titan_64 gtlbia;
|
||||
titan_64 reserved2[2];
|
||||
titan_64 sctl;
|
||||
titan_64 reserved3[3];
|
||||
} g;
|
||||
struct {
|
||||
titan_64 agperror;
|
||||
titan_64 agperren;
|
||||
titan_64 agperrset;
|
||||
titan_64 agplastwr;
|
||||
titan_64 aperror;
|
||||
titan_64 aperren;
|
||||
titan_64 aperrset;
|
||||
titan_64 reserved0;
|
||||
titan_64 atlbiv;
|
||||
titan_64 atlbia;
|
||||
titan_64 reserved1[6];
|
||||
} a;
|
||||
} port_specific;
|
||||
titan_64 sprst;
|
||||
titan_64 reserved1[31];
|
||||
} titan_pachip_port;
|
||||
|
||||
typedef struct {
|
||||
titan_pachip_port g_port;
|
||||
titan_pachip_port a_port;
|
||||
} titan_pachip;
|
||||
|
||||
#define TITAN_cchip ((titan_cchip *)(IDENT_ADDR+TI_BIAS+0x1A0000000UL))
|
||||
#define TITAN_dchip ((titan_dchip *)(IDENT_ADDR+TI_BIAS+0x1B0000800UL))
|
||||
#define TITAN_pachip0 ((titan_pachip *)(IDENT_ADDR+TI_BIAS+0x180000000UL))
|
||||
#define TITAN_pachip1 ((titan_pachip *)(IDENT_ADDR+TI_BIAS+0x380000000UL))
|
||||
extern unsigned TITAN_agp;
|
||||
extern int TITAN_bootcpu;
|
||||
|
||||
/*
|
||||
* TITAN PA-chip Window Space Base Address register.
|
||||
* (WSBA[0-2])
|
||||
*/
|
||||
#define wsba_m_ena 0x1
|
||||
#define wsba_m_sg 0x2
|
||||
#define wsba_m_addr 0xFFF00000
|
||||
#define wmask_k_sz1gb 0x3FF00000
|
||||
union TPAchipWSBA {
|
||||
struct {
|
||||
unsigned wsba_v_ena : 1;
|
||||
unsigned wsba_v_sg : 1;
|
||||
unsigned wsba_v_rsvd1 : 18;
|
||||
unsigned wsba_v_addr : 12;
|
||||
unsigned wsba_v_rsvd2 : 32;
|
||||
} wsba_r_bits;
|
||||
int wsba_q_whole [2];
|
||||
};
|
||||
|
||||
/*
|
||||
* TITAN PA-chip Control Register
|
||||
* This definition covers both the G-Port GPCTL and the A-PORT APCTL.
|
||||
* Bits <51:0> are the same in both cases. APCTL<63:52> are only
|
||||
* applicable to AGP.
|
||||
*/
|
||||
#define pctl_m_fbtb 0x00000001
|
||||
#define pctl_m_thdis 0x00000002
|
||||
#define pctl_m_chaindis 0x00000004
|
||||
#define pctl_m_tgtlat 0x00000018
|
||||
#define pctl_m_hole 0x00000020
|
||||
#define pctl_m_mwin 0x00000040
|
||||
#define pctl_m_arbena 0x00000080
|
||||
#define pctl_m_prigrp 0x0000FF00
|
||||
#define pctl_m_ppri 0x00010000
|
||||
#define pctl_m_pcispd66 0x00020000
|
||||
#define pctl_m_cngstlt 0x003C0000
|
||||
#define pctl_m_ptpdesten 0x3FC00000
|
||||
#define pctl_m_dpcen 0x40000000
|
||||
#define pctl_m_apcen 0x0000000080000000UL
|
||||
#define pctl_m_dcrtv 0x0000000300000000UL
|
||||
#define pctl_m_en_stepping 0x0000000400000000UL
|
||||
#define apctl_m_rsvd1 0x000FFFF800000000UL
|
||||
#define apctl_m_agp_rate 0x0030000000000000UL
|
||||
#define apctl_m_agp_sba_en 0x0040000000000000UL
|
||||
#define apctl_m_agp_en 0x0080000000000000UL
|
||||
#define apctl_m_rsvd2 0x0100000000000000UL
|
||||
#define apctl_m_agp_present 0x0200000000000000UL
|
||||
#define apctl_agp_hp_rd 0x1C00000000000000UL
|
||||
#define apctl_agp_lp_rd 0xE000000000000000UL
|
||||
#define gpctl_m_rsvd 0xFFFFFFF800000000UL
|
||||
union TPAchipPCTL {
|
||||
struct {
|
||||
unsigned pctl_v_fbtb : 1; /* A/G [0] */
|
||||
unsigned pctl_v_thdis : 1; /* A/G [1] */
|
||||
unsigned pctl_v_chaindis : 1; /* A/G [2] */
|
||||
unsigned pctl_v_tgtlat : 2; /* A/G [4:3] */
|
||||
unsigned pctl_v_hole : 1; /* A/G [5] */
|
||||
unsigned pctl_v_mwin : 1; /* A/G [6] */
|
||||
unsigned pctl_v_arbena : 1; /* A/G [7] */
|
||||
unsigned pctl_v_prigrp : 8; /* A/G [15:8] */
|
||||
unsigned pctl_v_ppri : 1; /* A/G [16] */
|
||||
unsigned pctl_v_pcispd66 : 1; /* A/G [17] */
|
||||
unsigned pctl_v_cngstlt : 4; /* A/G [21:18] */
|
||||
unsigned pctl_v_ptpdesten : 8; /* A/G [29:22] */
|
||||
unsigned pctl_v_dpcen : 1; /* A/G [30] */
|
||||
unsigned pctl_v_apcen : 1; /* A/G [31] */
|
||||
unsigned pctl_v_dcrtv : 2; /* A/G [33:32] */
|
||||
unsigned pctl_v_en_stepping :1; /* A/G [34] */
|
||||
unsigned apctl_v_rsvd1 : 17; /* A [51:35] */
|
||||
unsigned apctl_v_agp_rate : 2; /* A [53:52] */
|
||||
unsigned apctl_v_agp_sba_en : 1; /* A [54] */
|
||||
unsigned apctl_v_agp_en : 1; /* A [55] */
|
||||
unsigned apctl_v_rsvd2 : 1; /* A [56] */
|
||||
unsigned apctl_v_agp_present : 1; /* A [57] */
|
||||
unsigned apctl_v_agp_hp_rd : 3; /* A [60:58] */
|
||||
unsigned apctl_v_agp_lp_rd : 3; /* A [63:61] */
|
||||
} pctl_r_bits;
|
||||
unsigned int pctl_l_whole [2];
|
||||
unsigned long pctl_q_whole;
|
||||
};
|
||||
|
||||
/*
|
||||
* SERROR / SERREN / SERRSET
|
||||
*/
|
||||
union TPAchipSERR {
|
||||
struct {
|
||||
unsigned serr_v_lost_uecc : 1; /* [0] */
|
||||
unsigned serr_v_uecc : 1; /* [1] */
|
||||
unsigned serr_v_cre : 1; /* [2] */
|
||||
unsigned serr_v_nxio : 1; /* [3] */
|
||||
unsigned serr_v_lost_cre : 1; /* [4] */
|
||||
unsigned serr_v_rsvd0 : 10; /* [14:5] */
|
||||
unsigned serr_v_addr : 32; /* [46:15] */
|
||||
unsigned serr_v_rsvd1 : 5; /* [51:47] */
|
||||
unsigned serr_v_source : 2; /* [53:52] */
|
||||
unsigned serr_v_cmd : 2; /* [55:54] */
|
||||
unsigned serr_v_syn : 8; /* [63:56] */
|
||||
} serr_r_bits;
|
||||
unsigned int serr_l_whole[2];
|
||||
unsigned long serr_q_whole;
|
||||
};
|
||||
|
||||
/*
|
||||
* GPERROR / APERROR / GPERREN / APERREN / GPERRSET / APERRSET
|
||||
*/
|
||||
union TPAchipPERR {
|
||||
struct {
|
||||
unsigned long perr_v_lost : 1; /* [0] */
|
||||
unsigned long perr_v_serr : 1; /* [1] */
|
||||
unsigned long perr_v_perr : 1; /* [2] */
|
||||
unsigned long perr_v_dcrto : 1; /* [3] */
|
||||
unsigned long perr_v_sge : 1; /* [4] */
|
||||
unsigned long perr_v_ape : 1; /* [5] */
|
||||
unsigned long perr_v_ta : 1; /* [6] */
|
||||
unsigned long perr_v_dpe : 1; /* [7] */
|
||||
unsigned long perr_v_nds : 1; /* [8] */
|
||||
unsigned long perr_v_iptpr : 1; /* [9] */
|
||||
unsigned long perr_v_iptpw : 1; /* [10] */
|
||||
unsigned long perr_v_rsvd0 : 3; /* [13:11] */
|
||||
unsigned long perr_v_addr : 33; /* [46:14] */
|
||||
unsigned long perr_v_dac : 1; /* [47] */
|
||||
unsigned long perr_v_mwin : 1; /* [48] */
|
||||
unsigned long perr_v_rsvd1 : 3; /* [51:49] */
|
||||
unsigned long perr_v_cmd : 4; /* [55:52] */
|
||||
unsigned long perr_v_rsvd2 : 8; /* [63:56] */
|
||||
} perr_r_bits;
|
||||
unsigned int perr_l_whole[2];
|
||||
unsigned long perr_q_whole;
|
||||
};
|
||||
|
||||
/*
|
||||
* AGPERROR / AGPERREN / AGPERRSET
|
||||
*/
|
||||
union TPAchipAGPERR {
|
||||
struct {
|
||||
unsigned agperr_v_lost : 1; /* [0] */
|
||||
unsigned agperr_v_lpqfull : 1; /* [1] */
|
||||
unsigned apgerr_v_hpqfull : 1; /* [2] */
|
||||
unsigned agperr_v_rescmd : 1; /* [3] */
|
||||
unsigned agperr_v_ipte : 1; /* [4] */
|
||||
unsigned agperr_v_ptp : 1; /* [5] */
|
||||
unsigned agperr_v_nowindow : 1; /* [6] */
|
||||
unsigned agperr_v_rsvd0 : 8; /* [14:7] */
|
||||
unsigned agperr_v_addr : 32; /* [46:15] */
|
||||
unsigned agperr_v_rsvd1 : 1; /* [47] */
|
||||
unsigned agperr_v_dac : 1; /* [48] */
|
||||
unsigned agperr_v_mwin : 1; /* [49] */
|
||||
unsigned agperr_v_cmd : 3; /* [52:50] */
|
||||
unsigned agperr_v_length : 6; /* [58:53] */
|
||||
unsigned agperr_v_fence : 1; /* [59] */
|
||||
unsigned agperr_v_rsvd2 : 4; /* [63:60] */
|
||||
} agperr_r_bits;
|
||||
unsigned int agperr_l_whole[2];
|
||||
unsigned long agperr_q_whole;
|
||||
};
|
||||
/*
|
||||
* Memory spaces:
|
||||
* Hose numbers are assigned as follows:
|
||||
* 0 - pachip 0 / G Port
|
||||
* 1 - pachip 1 / G Port
|
||||
* 2 - pachip 0 / A Port
|
||||
* 3 - pachip 1 / A Port
|
||||
*/
|
||||
#define TITAN_HOSE_SHIFT (33)
|
||||
#define TITAN_HOSE(h) (((unsigned long)(h)) << TITAN_HOSE_SHIFT)
|
||||
#define TITAN_BASE (IDENT_ADDR + TI_BIAS)
|
||||
#define TITAN_MEM(h) (TITAN_BASE+TITAN_HOSE(h)+0x000000000UL)
|
||||
#define _TITAN_IACK_SC(h) (TITAN_BASE+TITAN_HOSE(h)+0x1F8000000UL)
|
||||
#define TITAN_IO(h) (TITAN_BASE+TITAN_HOSE(h)+0x1FC000000UL)
|
||||
#define TITAN_CONF(h) (TITAN_BASE+TITAN_HOSE(h)+0x1FE000000UL)
|
||||
|
||||
#define TITAN_HOSE_MASK TITAN_HOSE(3)
|
||||
#define TITAN_IACK_SC _TITAN_IACK_SC(0) /* hack! */
|
||||
|
||||
/*
|
||||
* The canonical non-remaped I/O and MEM addresses have these values
|
||||
* subtracted out. This is arranged so that folks manipulating ISA
|
||||
* devices can use their familiar numbers and have them map to bus 0.
|
||||
*/
|
||||
|
||||
#define TITAN_IO_BIAS TITAN_IO(0)
|
||||
#define TITAN_MEM_BIAS TITAN_MEM(0)
|
||||
|
||||
/* The IO address space is larger than 0xffff */
|
||||
#define TITAN_IO_SPACE (TITAN_CONF(0) - TITAN_IO(0))
|
||||
|
||||
/* TIG Space */
|
||||
#define TITAN_TIG_SPACE (TITAN_BASE + 0x100000000UL)
|
||||
|
||||
/* Offset between ram physical addresses and pci64 DAC bus addresses. */
|
||||
/* ??? Just a guess. Ought to confirm it hasn't been moved. */
|
||||
#define TITAN_DAC_OFFSET (1UL << 40)
|
||||
|
||||
/*
|
||||
* Data structure for handling TITAN machine checks:
|
||||
*/
|
||||
#define SCB_Q_SYSERR 0x620
|
||||
#define SCB_Q_PROCERR 0x630
|
||||
#define SCB_Q_SYSMCHK 0x660
|
||||
#define SCB_Q_PROCMCHK 0x670
|
||||
#define SCB_Q_SYSEVENT 0x680 /* environmental / system management */
|
||||
struct el_TITAN_sysdata_mcheck {
|
||||
u64 summary; /* 0x00 */
|
||||
u64 c_dirx; /* 0x08 */
|
||||
u64 c_misc; /* 0x10 */
|
||||
u64 p0_serror; /* 0x18 */
|
||||
u64 p0_gperror; /* 0x20 */
|
||||
u64 p0_aperror; /* 0x28 */
|
||||
u64 p0_agperror;/* 0x30 */
|
||||
u64 p1_serror; /* 0x38 */
|
||||
u64 p1_gperror; /* 0x40 */
|
||||
u64 p1_aperror; /* 0x48 */
|
||||
u64 p1_agperror;/* 0x50 */
|
||||
};
|
||||
|
||||
/*
|
||||
* System area for a privateer 680 environmental/system management mcheck
|
||||
*/
|
||||
struct el_PRIVATEER_envdata_mcheck {
|
||||
u64 summary; /* 0x00 */
|
||||
u64 c_dirx; /* 0x08 */
|
||||
u64 smir; /* 0x10 */
|
||||
u64 cpuir; /* 0x18 */
|
||||
u64 psir; /* 0x20 */
|
||||
u64 fault; /* 0x28 */
|
||||
u64 sys_doors; /* 0x30 */
|
||||
u64 temp_warn; /* 0x38 */
|
||||
u64 fan_ctrl; /* 0x40 */
|
||||
u64 code; /* 0x48 */
|
||||
u64 reserved; /* 0x50 */
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef __EXTERN_INLINE
|
||||
#define __EXTERN_INLINE extern inline
|
||||
#define __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I/O functions:
|
||||
*
|
||||
* TITAN, a 21??? PCI/memory support chipset for the EV6 (21264)
|
||||
* can only use linear accesses to get at PCI/AGP memory and I/O spaces.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory functions. all accesses are done through linear space.
|
||||
*/
|
||||
extern void __iomem *titan_ioportmap(unsigned long addr);
|
||||
extern void __iomem *titan_ioremap(unsigned long addr, unsigned long size);
|
||||
extern void titan_iounmap(volatile void __iomem *addr);
|
||||
|
||||
__EXTERN_INLINE int titan_is_ioaddr(unsigned long addr)
|
||||
{
|
||||
return addr >= TITAN_BASE;
|
||||
}
|
||||
|
||||
extern int titan_is_mmio(const volatile void __iomem *addr);
|
||||
|
||||
#undef __IO_PREFIX
|
||||
#define __IO_PREFIX titan
|
||||
#define titan_trivial_rw_bw 1
|
||||
#define titan_trivial_rw_lq 1
|
||||
#define titan_trivial_io_bw 1
|
||||
#define titan_trivial_io_lq 1
|
||||
#define titan_trivial_iounmap 0
|
||||
#include <asm/io_trivial.h>
|
||||
|
||||
#ifdef __IO_EXTERN_INLINE
|
||||
#undef __EXTERN_INLINE
|
||||
#undef __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ALPHA_TITAN__H__ */
|
335
arch/alpha/include/asm/core_tsunami.h
Normal file
335
arch/alpha/include/asm/core_tsunami.h
Normal file
@ -0,0 +1,335 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_TSUNAMI__H__
|
||||
#define __ALPHA_TSUNAMI__H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/compiler.h>
|
||||
|
||||
/*
|
||||
* TSUNAMI/TYPHOON are the internal names for the core logic chipset which
|
||||
* provides memory controller and PCI access for the 21264 based systems.
|
||||
*
|
||||
* This file is based on:
|
||||
*
|
||||
* Tsunami System Programmers Manual
|
||||
* Preliminary, Chapters 2-5
|
||||
*
|
||||
*/
|
||||
|
||||
/* XXX: Do we need to conditionalize on this? */
|
||||
#ifdef USE_48_BIT_KSEG
|
||||
#define TS_BIAS 0x80000000000UL
|
||||
#else
|
||||
#define TS_BIAS 0x10000000000UL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* CChip, DChip, and PChip registers
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned long csr __attribute__((aligned(64)));
|
||||
} tsunami_64;
|
||||
|
||||
typedef struct {
|
||||
tsunami_64 csc;
|
||||
tsunami_64 mtr;
|
||||
tsunami_64 misc;
|
||||
tsunami_64 mpd;
|
||||
tsunami_64 aar0;
|
||||
tsunami_64 aar1;
|
||||
tsunami_64 aar2;
|
||||
tsunami_64 aar3;
|
||||
tsunami_64 dim0;
|
||||
tsunami_64 dim1;
|
||||
tsunami_64 dir0;
|
||||
tsunami_64 dir1;
|
||||
tsunami_64 drir;
|
||||
tsunami_64 prben;
|
||||
tsunami_64 iic; /* a.k.a. iic0 */
|
||||
tsunami_64 wdr; /* a.k.a. iic1 */
|
||||
tsunami_64 mpr0;
|
||||
tsunami_64 mpr1;
|
||||
tsunami_64 mpr2;
|
||||
tsunami_64 mpr3;
|
||||
tsunami_64 mctl;
|
||||
tsunami_64 __pad1;
|
||||
tsunami_64 ttr;
|
||||
tsunami_64 tdr;
|
||||
tsunami_64 dim2;
|
||||
tsunami_64 dim3;
|
||||
tsunami_64 dir2;
|
||||
tsunami_64 dir3;
|
||||
tsunami_64 iic2;
|
||||
tsunami_64 iic3;
|
||||
} tsunami_cchip;
|
||||
|
||||
typedef struct {
|
||||
tsunami_64 dsc;
|
||||
tsunami_64 str;
|
||||
tsunami_64 drev;
|
||||
} tsunami_dchip;
|
||||
|
||||
typedef struct {
|
||||
tsunami_64 wsba[4];
|
||||
tsunami_64 wsm[4];
|
||||
tsunami_64 tba[4];
|
||||
tsunami_64 pctl;
|
||||
tsunami_64 plat;
|
||||
tsunami_64 reserved;
|
||||
tsunami_64 perror;
|
||||
tsunami_64 perrmask;
|
||||
tsunami_64 perrset;
|
||||
tsunami_64 tlbiv;
|
||||
tsunami_64 tlbia;
|
||||
tsunami_64 pmonctl;
|
||||
tsunami_64 pmoncnt;
|
||||
} tsunami_pchip;
|
||||
|
||||
#define TSUNAMI_cchip ((tsunami_cchip *)(IDENT_ADDR+TS_BIAS+0x1A0000000UL))
|
||||
#define TSUNAMI_dchip ((tsunami_dchip *)(IDENT_ADDR+TS_BIAS+0x1B0000800UL))
|
||||
#define TSUNAMI_pchip0 ((tsunami_pchip *)(IDENT_ADDR+TS_BIAS+0x180000000UL))
|
||||
#define TSUNAMI_pchip1 ((tsunami_pchip *)(IDENT_ADDR+TS_BIAS+0x380000000UL))
|
||||
extern int TSUNAMI_bootcpu;
|
||||
|
||||
/*
|
||||
* TSUNAMI Pchip Error register.
|
||||
*/
|
||||
|
||||
#define perror_m_lost 0x1
|
||||
#define perror_m_serr 0x2
|
||||
#define perror_m_perr 0x4
|
||||
#define perror_m_dcrto 0x8
|
||||
#define perror_m_sge 0x10
|
||||
#define perror_m_ape 0x20
|
||||
#define perror_m_ta 0x40
|
||||
#define perror_m_rdpe 0x80
|
||||
#define perror_m_nds 0x100
|
||||
#define perror_m_rto 0x200
|
||||
#define perror_m_uecc 0x400
|
||||
#define perror_m_cre 0x800
|
||||
#define perror_m_addrl 0xFFFFFFFF0000UL
|
||||
#define perror_m_addrh 0x7000000000000UL
|
||||
#define perror_m_cmd 0xF0000000000000UL
|
||||
#define perror_m_syn 0xFF00000000000000UL
|
||||
union TPchipPERROR {
|
||||
struct {
|
||||
unsigned int perror_v_lost : 1;
|
||||
unsigned perror_v_serr : 1;
|
||||
unsigned perror_v_perr : 1;
|
||||
unsigned perror_v_dcrto : 1;
|
||||
unsigned perror_v_sge : 1;
|
||||
unsigned perror_v_ape : 1;
|
||||
unsigned perror_v_ta : 1;
|
||||
unsigned perror_v_rdpe : 1;
|
||||
unsigned perror_v_nds : 1;
|
||||
unsigned perror_v_rto : 1;
|
||||
unsigned perror_v_uecc : 1;
|
||||
unsigned perror_v_cre : 1;
|
||||
unsigned perror_v_rsvd1 : 4;
|
||||
unsigned perror_v_addrl : 32;
|
||||
unsigned perror_v_addrh : 3;
|
||||
unsigned perror_v_rsvd2 : 1;
|
||||
unsigned perror_v_cmd : 4;
|
||||
unsigned perror_v_syn : 8;
|
||||
} perror_r_bits;
|
||||
int perror_q_whole [2];
|
||||
};
|
||||
|
||||
/*
|
||||
* TSUNAMI Pchip Window Space Base Address register.
|
||||
*/
|
||||
#define wsba_m_ena 0x1
|
||||
#define wsba_m_sg 0x2
|
||||
#define wsba_m_ptp 0x4
|
||||
#define wsba_m_addr 0xFFF00000
|
||||
#define wmask_k_sz1gb 0x3FF00000
|
||||
union TPchipWSBA {
|
||||
struct {
|
||||
unsigned wsba_v_ena : 1;
|
||||
unsigned wsba_v_sg : 1;
|
||||
unsigned wsba_v_ptp : 1;
|
||||
unsigned wsba_v_rsvd1 : 17;
|
||||
unsigned wsba_v_addr : 12;
|
||||
unsigned wsba_v_rsvd2 : 32;
|
||||
} wsba_r_bits;
|
||||
int wsba_q_whole [2];
|
||||
};
|
||||
|
||||
/*
|
||||
* TSUNAMI Pchip Control Register
|
||||
*/
|
||||
#define pctl_m_fdsc 0x1
|
||||
#define pctl_m_fbtb 0x2
|
||||
#define pctl_m_thdis 0x4
|
||||
#define pctl_m_chaindis 0x8
|
||||
#define pctl_m_tgtlat 0x10
|
||||
#define pctl_m_hole 0x20
|
||||
#define pctl_m_mwin 0x40
|
||||
#define pctl_m_arbena 0x80
|
||||
#define pctl_m_prigrp 0x7F00
|
||||
#define pctl_m_ppri 0x8000
|
||||
#define pctl_m_rsvd1 0x30000
|
||||
#define pctl_m_eccen 0x40000
|
||||
#define pctl_m_padm 0x80000
|
||||
#define pctl_m_cdqmax 0xF00000
|
||||
#define pctl_m_rev 0xFF000000
|
||||
#define pctl_m_crqmax 0xF00000000UL
|
||||
#define pctl_m_ptpmax 0xF000000000UL
|
||||
#define pctl_m_pclkx 0x30000000000UL
|
||||
#define pctl_m_fdsdis 0x40000000000UL
|
||||
#define pctl_m_fdwdis 0x80000000000UL
|
||||
#define pctl_m_ptevrfy 0x100000000000UL
|
||||
#define pctl_m_rpp 0x200000000000UL
|
||||
#define pctl_m_pid 0xC00000000000UL
|
||||
#define pctl_m_rsvd2 0xFFFF000000000000UL
|
||||
|
||||
union TPchipPCTL {
|
||||
struct {
|
||||
unsigned pctl_v_fdsc : 1;
|
||||
unsigned pctl_v_fbtb : 1;
|
||||
unsigned pctl_v_thdis : 1;
|
||||
unsigned pctl_v_chaindis : 1;
|
||||
unsigned pctl_v_tgtlat : 1;
|
||||
unsigned pctl_v_hole : 1;
|
||||
unsigned pctl_v_mwin : 1;
|
||||
unsigned pctl_v_arbena : 1;
|
||||
unsigned pctl_v_prigrp : 7;
|
||||
unsigned pctl_v_ppri : 1;
|
||||
unsigned pctl_v_rsvd1 : 2;
|
||||
unsigned pctl_v_eccen : 1;
|
||||
unsigned pctl_v_padm : 1;
|
||||
unsigned pctl_v_cdqmax : 4;
|
||||
unsigned pctl_v_rev : 8;
|
||||
unsigned pctl_v_crqmax : 4;
|
||||
unsigned pctl_v_ptpmax : 4;
|
||||
unsigned pctl_v_pclkx : 2;
|
||||
unsigned pctl_v_fdsdis : 1;
|
||||
unsigned pctl_v_fdwdis : 1;
|
||||
unsigned pctl_v_ptevrfy : 1;
|
||||
unsigned pctl_v_rpp : 1;
|
||||
unsigned pctl_v_pid : 2;
|
||||
unsigned pctl_v_rsvd2 : 16;
|
||||
} pctl_r_bits;
|
||||
int pctl_q_whole [2];
|
||||
};
|
||||
|
||||
/*
|
||||
* TSUNAMI Pchip Error Mask Register.
|
||||
*/
|
||||
#define perrmask_m_lost 0x1
|
||||
#define perrmask_m_serr 0x2
|
||||
#define perrmask_m_perr 0x4
|
||||
#define perrmask_m_dcrto 0x8
|
||||
#define perrmask_m_sge 0x10
|
||||
#define perrmask_m_ape 0x20
|
||||
#define perrmask_m_ta 0x40
|
||||
#define perrmask_m_rdpe 0x80
|
||||
#define perrmask_m_nds 0x100
|
||||
#define perrmask_m_rto 0x200
|
||||
#define perrmask_m_uecc 0x400
|
||||
#define perrmask_m_cre 0x800
|
||||
#define perrmask_m_rsvd 0xFFFFFFFFFFFFF000UL
|
||||
union TPchipPERRMASK {
|
||||
struct {
|
||||
unsigned int perrmask_v_lost : 1;
|
||||
unsigned perrmask_v_serr : 1;
|
||||
unsigned perrmask_v_perr : 1;
|
||||
unsigned perrmask_v_dcrto : 1;
|
||||
unsigned perrmask_v_sge : 1;
|
||||
unsigned perrmask_v_ape : 1;
|
||||
unsigned perrmask_v_ta : 1;
|
||||
unsigned perrmask_v_rdpe : 1;
|
||||
unsigned perrmask_v_nds : 1;
|
||||
unsigned perrmask_v_rto : 1;
|
||||
unsigned perrmask_v_uecc : 1;
|
||||
unsigned perrmask_v_cre : 1;
|
||||
unsigned perrmask_v_rsvd1 : 20;
|
||||
unsigned perrmask_v_rsvd2 : 32;
|
||||
} perrmask_r_bits;
|
||||
int perrmask_q_whole [2];
|
||||
};
|
||||
|
||||
/*
|
||||
* Memory spaces:
|
||||
*/
|
||||
#define TSUNAMI_HOSE(h) (((unsigned long)(h)) << 33)
|
||||
#define TSUNAMI_BASE (IDENT_ADDR + TS_BIAS)
|
||||
|
||||
#define TSUNAMI_MEM(h) (TSUNAMI_BASE+TSUNAMI_HOSE(h) + 0x000000000UL)
|
||||
#define _TSUNAMI_IACK_SC(h) (TSUNAMI_BASE+TSUNAMI_HOSE(h) + 0x1F8000000UL)
|
||||
#define TSUNAMI_IO(h) (TSUNAMI_BASE+TSUNAMI_HOSE(h) + 0x1FC000000UL)
|
||||
#define TSUNAMI_CONF(h) (TSUNAMI_BASE+TSUNAMI_HOSE(h) + 0x1FE000000UL)
|
||||
|
||||
#define TSUNAMI_IACK_SC _TSUNAMI_IACK_SC(0) /* hack! */
|
||||
|
||||
|
||||
/*
|
||||
* The canonical non-remaped I/O and MEM addresses have these values
|
||||
* subtracted out. This is arranged so that folks manipulating ISA
|
||||
* devices can use their familiar numbers and have them map to bus 0.
|
||||
*/
|
||||
|
||||
#define TSUNAMI_IO_BIAS TSUNAMI_IO(0)
|
||||
#define TSUNAMI_MEM_BIAS TSUNAMI_MEM(0)
|
||||
|
||||
/* The IO address space is larger than 0xffff */
|
||||
#define TSUNAMI_IO_SPACE (TSUNAMI_CONF(0) - TSUNAMI_IO(0))
|
||||
|
||||
/* Offset between ram physical addresses and pci64 DAC bus addresses. */
|
||||
#define TSUNAMI_DAC_OFFSET (1UL << 40)
|
||||
|
||||
/*
|
||||
* Data structure for handling TSUNAMI machine checks:
|
||||
*/
|
||||
struct el_TSUNAMI_sysdata_mcheck {
|
||||
};
|
||||
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef __EXTERN_INLINE
|
||||
#define __EXTERN_INLINE extern inline
|
||||
#define __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I/O functions:
|
||||
*
|
||||
* TSUNAMI, the 21??? PCI/memory support chipset for the EV6 (21264)
|
||||
* can only use linear accesses to get at PCI memory and I/O spaces.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory functions. all accesses are done through linear space.
|
||||
*/
|
||||
extern void __iomem *tsunami_ioportmap(unsigned long addr);
|
||||
extern void __iomem *tsunami_ioremap(unsigned long addr, unsigned long size);
|
||||
__EXTERN_INLINE int tsunami_is_ioaddr(unsigned long addr)
|
||||
{
|
||||
return addr >= TSUNAMI_BASE;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int tsunami_is_mmio(const volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
return (addr & 0x100000000UL) == 0;
|
||||
}
|
||||
|
||||
#undef __IO_PREFIX
|
||||
#define __IO_PREFIX tsunami
|
||||
#define tsunami_trivial_rw_bw 1
|
||||
#define tsunami_trivial_rw_lq 1
|
||||
#define tsunami_trivial_io_bw 1
|
||||
#define tsunami_trivial_io_lq 1
|
||||
#define tsunami_trivial_iounmap 1
|
||||
#include <asm/io_trivial.h>
|
||||
|
||||
#ifdef __IO_EXTERN_INLINE
|
||||
#undef __EXTERN_INLINE
|
||||
#undef __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ALPHA_TSUNAMI__H__ */
|
319
arch/alpha/include/asm/core_wildfire.h
Normal file
319
arch/alpha/include/asm/core_wildfire.h
Normal file
@ -0,0 +1,319 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_WILDFIRE__H__
|
||||
#define __ALPHA_WILDFIRE__H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/compiler.h>
|
||||
|
||||
#define WILDFIRE_MAX_QBB 8 /* more than 8 requires other mods */
|
||||
#define WILDFIRE_PCA_PER_QBB 4
|
||||
#define WILDFIRE_IRQ_PER_PCA 64
|
||||
|
||||
#define WILDFIRE_NR_IRQS \
|
||||
(WILDFIRE_MAX_QBB * WILDFIRE_PCA_PER_QBB * WILDFIRE_IRQ_PER_PCA)
|
||||
|
||||
extern unsigned char wildfire_hard_qbb_map[WILDFIRE_MAX_QBB];
|
||||
extern unsigned char wildfire_soft_qbb_map[WILDFIRE_MAX_QBB];
|
||||
#define QBB_MAP_EMPTY 0xff
|
||||
|
||||
extern unsigned long wildfire_hard_qbb_mask;
|
||||
extern unsigned long wildfire_soft_qbb_mask;
|
||||
extern unsigned long wildfire_gp_mask;
|
||||
extern unsigned long wildfire_hs_mask;
|
||||
extern unsigned long wildfire_iop_mask;
|
||||
extern unsigned long wildfire_ior_mask;
|
||||
extern unsigned long wildfire_pca_mask;
|
||||
extern unsigned long wildfire_cpu_mask;
|
||||
extern unsigned long wildfire_mem_mask;
|
||||
|
||||
#define WILDFIRE_QBB_EXISTS(qbbno) (wildfire_soft_qbb_mask & (1 << (qbbno)))
|
||||
|
||||
#define WILDFIRE_MEM_EXISTS(qbbno) (wildfire_mem_mask & (0xf << ((qbbno) << 2)))
|
||||
|
||||
#define WILDFIRE_PCA_EXISTS(qbbno, pcano) \
|
||||
(wildfire_pca_mask & (1 << (((qbbno) << 2) + (pcano))))
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned long csr __attribute__((aligned(64)));
|
||||
} wildfire_64;
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned long csr __attribute__((aligned(256)));
|
||||
} wildfire_256;
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned long csr __attribute__((aligned(2048)));
|
||||
} wildfire_2k;
|
||||
|
||||
typedef struct {
|
||||
wildfire_64 qsd_whami;
|
||||
wildfire_64 qsd_rev;
|
||||
wildfire_64 qsd_port_present;
|
||||
wildfire_64 qsd_port_active;
|
||||
wildfire_64 qsd_fault_ena;
|
||||
wildfire_64 qsd_cpu_int_ena;
|
||||
wildfire_64 qsd_mem_config;
|
||||
wildfire_64 qsd_err_sum;
|
||||
wildfire_64 ce_sum[4];
|
||||
wildfire_64 dev_init[4];
|
||||
wildfire_64 it_int[4];
|
||||
wildfire_64 ip_int[4];
|
||||
wildfire_64 uce_sum[4];
|
||||
wildfire_64 se_sum__non_dev_int[4];
|
||||
wildfire_64 scratch[4];
|
||||
wildfire_64 qsd_timer;
|
||||
wildfire_64 qsd_diag;
|
||||
} wildfire_qsd;
|
||||
|
||||
typedef struct {
|
||||
wildfire_256 qsd_whami;
|
||||
wildfire_256 __pad1;
|
||||
wildfire_256 ce_sum;
|
||||
wildfire_256 dev_init;
|
||||
wildfire_256 it_int;
|
||||
wildfire_256 ip_int;
|
||||
wildfire_256 uce_sum;
|
||||
wildfire_256 se_sum;
|
||||
} wildfire_fast_qsd;
|
||||
|
||||
typedef struct {
|
||||
wildfire_2k qsa_qbb_id;
|
||||
wildfire_2k __pad1;
|
||||
wildfire_2k qsa_port_ena;
|
||||
wildfire_2k qsa_scratch;
|
||||
wildfire_2k qsa_config[5];
|
||||
wildfire_2k qsa_ref_int;
|
||||
wildfire_2k qsa_qbb_pop[2];
|
||||
wildfire_2k qsa_dtag_fc;
|
||||
wildfire_2k __pad2[3];
|
||||
wildfire_2k qsa_diag;
|
||||
wildfire_2k qsa_diag_lock[4];
|
||||
wildfire_2k __pad3[11];
|
||||
wildfire_2k qsa_cpu_err_sum;
|
||||
wildfire_2k qsa_misc_err_sum;
|
||||
wildfire_2k qsa_tmo_err_sum;
|
||||
wildfire_2k qsa_err_ena;
|
||||
wildfire_2k qsa_tmo_config;
|
||||
wildfire_2k qsa_ill_cmd_err_sum;
|
||||
wildfire_2k __pad4[26];
|
||||
wildfire_2k qsa_busy_mask;
|
||||
wildfire_2k qsa_arr_valid;
|
||||
wildfire_2k __pad5[2];
|
||||
wildfire_2k qsa_port_map[4];
|
||||
wildfire_2k qsa_arr_addr[8];
|
||||
wildfire_2k qsa_arr_mask[8];
|
||||
} wildfire_qsa;
|
||||
|
||||
typedef struct {
|
||||
wildfire_64 ioa_config;
|
||||
wildfire_64 iod_config;
|
||||
wildfire_64 iop_switch_credits;
|
||||
wildfire_64 __pad1;
|
||||
wildfire_64 iop_hose_credits;
|
||||
wildfire_64 __pad2[11];
|
||||
struct {
|
||||
wildfire_64 __pad3;
|
||||
wildfire_64 init;
|
||||
} iop_hose[4];
|
||||
wildfire_64 ioa_hose_0_ctrl;
|
||||
wildfire_64 iod_hose_0_ctrl;
|
||||
wildfire_64 ioa_hose_1_ctrl;
|
||||
wildfire_64 iod_hose_1_ctrl;
|
||||
wildfire_64 ioa_hose_2_ctrl;
|
||||
wildfire_64 iod_hose_2_ctrl;
|
||||
wildfire_64 ioa_hose_3_ctrl;
|
||||
wildfire_64 iod_hose_3_ctrl;
|
||||
struct {
|
||||
wildfire_64 target;
|
||||
wildfire_64 __pad4;
|
||||
} iop_dev_int[4];
|
||||
|
||||
wildfire_64 iop_err_int_target;
|
||||
wildfire_64 __pad5[7];
|
||||
wildfire_64 iop_qbb_err_sum;
|
||||
wildfire_64 __pad6;
|
||||
wildfire_64 iop_qbb_se_sum;
|
||||
wildfire_64 __pad7;
|
||||
wildfire_64 ioa_err_sum;
|
||||
wildfire_64 iod_err_sum;
|
||||
wildfire_64 __pad8[4];
|
||||
wildfire_64 ioa_diag_force_err;
|
||||
wildfire_64 iod_diag_force_err;
|
||||
wildfire_64 __pad9[4];
|
||||
wildfire_64 iop_diag_send_err_int;
|
||||
wildfire_64 __pad10[15];
|
||||
wildfire_64 ioa_scratch;
|
||||
wildfire_64 iod_scratch;
|
||||
} wildfire_iop;
|
||||
|
||||
typedef struct {
|
||||
wildfire_2k gpa_qbb_map[4];
|
||||
wildfire_2k gpa_mem_pop_map;
|
||||
wildfire_2k gpa_scratch;
|
||||
wildfire_2k gpa_diag;
|
||||
wildfire_2k gpa_config_0;
|
||||
wildfire_2k __pad1;
|
||||
wildfire_2k gpa_init_id;
|
||||
wildfire_2k gpa_config_2;
|
||||
/* not complete */
|
||||
} wildfire_gp;
|
||||
|
||||
typedef struct {
|
||||
wildfire_64 pca_what_am_i;
|
||||
wildfire_64 pca_err_sum;
|
||||
wildfire_64 pca_diag_force_err;
|
||||
wildfire_64 pca_diag_send_err_int;
|
||||
wildfire_64 pca_hose_credits;
|
||||
wildfire_64 pca_scratch;
|
||||
wildfire_64 pca_micro_addr;
|
||||
wildfire_64 pca_micro_data;
|
||||
wildfire_64 pca_pend_int;
|
||||
wildfire_64 pca_sent_int;
|
||||
wildfire_64 __pad1;
|
||||
wildfire_64 pca_stdio_edge_level;
|
||||
wildfire_64 __pad2[52];
|
||||
struct {
|
||||
wildfire_64 target;
|
||||
wildfire_64 enable;
|
||||
} pca_int[4];
|
||||
wildfire_64 __pad3[56];
|
||||
wildfire_64 pca_alt_sent_int[32];
|
||||
} wildfire_pca;
|
||||
|
||||
typedef struct {
|
||||
wildfire_64 ne_what_am_i;
|
||||
/* not complete */
|
||||
} wildfire_ne;
|
||||
|
||||
typedef struct {
|
||||
wildfire_64 fe_what_am_i;
|
||||
/* not complete */
|
||||
} wildfire_fe;
|
||||
|
||||
typedef struct {
|
||||
wildfire_64 pci_io_addr_ext;
|
||||
wildfire_64 pci_ctrl;
|
||||
wildfire_64 pci_err_sum;
|
||||
wildfire_64 pci_err_addr;
|
||||
wildfire_64 pci_stall_cnt;
|
||||
wildfire_64 pci_iack_special;
|
||||
wildfire_64 __pad1[2];
|
||||
wildfire_64 pci_pend_int;
|
||||
wildfire_64 pci_sent_int;
|
||||
wildfire_64 __pad2[54];
|
||||
struct {
|
||||
wildfire_64 wbase;
|
||||
wildfire_64 wmask;
|
||||
wildfire_64 tbase;
|
||||
} pci_window[4];
|
||||
wildfire_64 pci_flush_tlb;
|
||||
wildfire_64 pci_perf_mon;
|
||||
} wildfire_pci;
|
||||
|
||||
#define WILDFIRE_ENTITY_SHIFT 18
|
||||
|
||||
#define WILDFIRE_GP_ENTITY (0x10UL << WILDFIRE_ENTITY_SHIFT)
|
||||
#define WILDFIRE_IOP_ENTITY (0x08UL << WILDFIRE_ENTITY_SHIFT)
|
||||
#define WILDFIRE_QSA_ENTITY (0x04UL << WILDFIRE_ENTITY_SHIFT)
|
||||
#define WILDFIRE_QSD_ENTITY_SLOW (0x05UL << WILDFIRE_ENTITY_SHIFT)
|
||||
#define WILDFIRE_QSD_ENTITY_FAST (0x01UL << WILDFIRE_ENTITY_SHIFT)
|
||||
|
||||
#define WILDFIRE_PCA_ENTITY(pca) ((0xc|(pca))<<WILDFIRE_ENTITY_SHIFT)
|
||||
|
||||
#define WILDFIRE_BASE (IDENT_ADDR | (1UL << 40))
|
||||
|
||||
#define WILDFIRE_QBB_MASK 0x0fUL /* for now, only 4 bits/16 QBBs */
|
||||
|
||||
#define WILDFIRE_QBB(q) ((~((long)(q)) & WILDFIRE_QBB_MASK) << 36)
|
||||
#define WILDFIRE_HOSE(h) ((long)(h) << 33)
|
||||
|
||||
#define WILDFIRE_QBB_IO(q) (WILDFIRE_BASE | WILDFIRE_QBB(q))
|
||||
#define WILDFIRE_QBB_HOSE(q,h) (WILDFIRE_QBB_IO(q) | WILDFIRE_HOSE(h))
|
||||
|
||||
#define WILDFIRE_MEM(q,h) (WILDFIRE_QBB_HOSE(q,h) | 0x000000000UL)
|
||||
#define WILDFIRE_CONF(q,h) (WILDFIRE_QBB_HOSE(q,h) | 0x1FE000000UL)
|
||||
#define WILDFIRE_IO(q,h) (WILDFIRE_QBB_HOSE(q,h) | 0x1FF000000UL)
|
||||
|
||||
#define WILDFIRE_qsd(q) \
|
||||
((wildfire_qsd *)(WILDFIRE_QBB_IO(q)|WILDFIRE_QSD_ENTITY_SLOW|(((1UL<<13)-1)<<23)))
|
||||
|
||||
#define WILDFIRE_fast_qsd() \
|
||||
((wildfire_fast_qsd *)(WILDFIRE_QBB_IO(0)|WILDFIRE_QSD_ENTITY_FAST|(((1UL<<13)-1)<<23)))
|
||||
|
||||
#define WILDFIRE_qsa(q) \
|
||||
((wildfire_qsa *)(WILDFIRE_QBB_IO(q)|WILDFIRE_QSA_ENTITY|(((1UL<<13)-1)<<23)))
|
||||
|
||||
#define WILDFIRE_iop(q) \
|
||||
((wildfire_iop *)(WILDFIRE_QBB_IO(q)|WILDFIRE_IOP_ENTITY|(((1UL<<13)-1)<<23)))
|
||||
|
||||
#define WILDFIRE_gp(q) \
|
||||
((wildfire_gp *)(WILDFIRE_QBB_IO(q)|WILDFIRE_GP_ENTITY|(((1UL<<13)-1)<<23)))
|
||||
|
||||
#define WILDFIRE_pca(q,pca) \
|
||||
((wildfire_pca *)(WILDFIRE_QBB_IO(q)|WILDFIRE_PCA_ENTITY(pca)|(((1UL<<13)-1)<<23)))
|
||||
|
||||
#define WILDFIRE_ne(q,pca) \
|
||||
((wildfire_ne *)(WILDFIRE_QBB_IO(q)|WILDFIRE_PCA_ENTITY(pca)|(((1UL<<13)-1)<<23)|(1UL<<16)))
|
||||
|
||||
#define WILDFIRE_fe(q,pca) \
|
||||
((wildfire_fe *)(WILDFIRE_QBB_IO(q)|WILDFIRE_PCA_ENTITY(pca)|(((1UL<<13)-1)<<23)|(3UL<<15)))
|
||||
|
||||
#define WILDFIRE_pci(q,h) \
|
||||
((wildfire_pci *)(WILDFIRE_QBB_IO(q)|WILDFIRE_PCA_ENTITY(((h)&6)>>1)|((((h)&1)|2)<<16)|(((1UL<<13)-1)<<23)))
|
||||
|
||||
#define WILDFIRE_IO_BIAS WILDFIRE_IO(0,0)
|
||||
#define WILDFIRE_MEM_BIAS WILDFIRE_MEM(0,0) /* ??? */
|
||||
|
||||
/* The IO address space is larger than 0xffff */
|
||||
#define WILDFIRE_IO_SPACE (8UL*1024*1024)
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef __EXTERN_INLINE
|
||||
#define __EXTERN_INLINE extern inline
|
||||
#define __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Memory functions. all accesses are done through linear space.
|
||||
*/
|
||||
|
||||
__EXTERN_INLINE void __iomem *wildfire_ioportmap(unsigned long addr)
|
||||
{
|
||||
return (void __iomem *)(addr + WILDFIRE_IO_BIAS);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void __iomem *wildfire_ioremap(unsigned long addr,
|
||||
unsigned long size)
|
||||
{
|
||||
return (void __iomem *)(addr + WILDFIRE_MEM_BIAS);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int wildfire_is_ioaddr(unsigned long addr)
|
||||
{
|
||||
return addr >= WILDFIRE_BASE;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int wildfire_is_mmio(const volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long)xaddr;
|
||||
return (addr & 0x100000000UL) == 0;
|
||||
}
|
||||
|
||||
#undef __IO_PREFIX
|
||||
#define __IO_PREFIX wildfire
|
||||
#define wildfire_trivial_rw_bw 1
|
||||
#define wildfire_trivial_rw_lq 1
|
||||
#define wildfire_trivial_io_bw 1
|
||||
#define wildfire_trivial_io_lq 1
|
||||
#define wildfire_trivial_iounmap 1
|
||||
#include <asm/io_trivial.h>
|
||||
|
||||
#ifdef __IO_EXTERN_INLINE
|
||||
#undef __EXTERN_INLINE
|
||||
#undef __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ALPHA_WILDFIRE__H__ */
|
11
arch/alpha/include/asm/delay.h
Normal file
11
arch/alpha/include/asm/delay.h
Normal file
@ -0,0 +1,11 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_DELAY_H
|
||||
#define __ALPHA_DELAY_H
|
||||
|
||||
extern void __delay(int loops);
|
||||
extern void udelay(unsigned long usecs);
|
||||
|
||||
extern void ndelay(unsigned long nsecs);
|
||||
#define ndelay ndelay
|
||||
|
||||
#endif /* defined(__ALPHA_DELAY_H) */
|
6
arch/alpha/include/asm/device.h
Normal file
6
arch/alpha/include/asm/device.h
Normal file
@ -0,0 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Arch specific extensions to struct device
|
||||
*/
|
||||
#include <asm-generic/device.h>
|
||||
|
1
arch/alpha/include/asm/div64.h
Normal file
1
arch/alpha/include/asm/div64.h
Normal file
@ -0,0 +1 @@
|
||||
#include <asm-generic/div64.h>
|
16
arch/alpha/include/asm/dma-mapping.h
Normal file
16
arch/alpha/include/asm/dma-mapping.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ALPHA_DMA_MAPPING_H
|
||||
#define _ALPHA_DMA_MAPPING_H
|
||||
|
||||
extern const struct dma_map_ops alpha_pci_ops;
|
||||
|
||||
static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
|
||||
{
|
||||
#ifdef CONFIG_ALPHA_JENSEN
|
||||
return NULL;
|
||||
#else
|
||||
return &alpha_pci_ops;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* _ALPHA_DMA_MAPPING_H */
|
377
arch/alpha/include/asm/dma.h
Normal file
377
arch/alpha/include/asm/dma.h
Normal file
@ -0,0 +1,377 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* include/asm-alpha/dma.h
|
||||
*
|
||||
* This is essentially the same as the i386 DMA stuff, as the AlphaPCs
|
||||
* use ISA-compatible dma. The only extension is support for high-page
|
||||
* registers that allow to set the top 8 bits of a 32-bit DMA address.
|
||||
* This register should be written last when setting up a DMA address
|
||||
* as this will also enable DMA across 64 KB boundaries.
|
||||
*/
|
||||
|
||||
/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $
|
||||
* linux/include/asm/dma.h: Defines for using and allocating dma channels.
|
||||
* Written by Hennus Bergman, 1992.
|
||||
* High DMA channel support & info by Hannu Savolainen
|
||||
* and John Boyd, Nov. 1992.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_DMA_H
|
||||
#define _ASM_DMA_H
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define dma_outb outb
|
||||
#define dma_inb inb
|
||||
|
||||
/*
|
||||
* NOTES about DMA transfers:
|
||||
*
|
||||
* controller 1: channels 0-3, byte operations, ports 00-1F
|
||||
* controller 2: channels 4-7, word operations, ports C0-DF
|
||||
*
|
||||
* - ALL registers are 8 bits only, regardless of transfer size
|
||||
* - channel 4 is not used - cascades 1 into 2.
|
||||
* - channels 0-3 are byte - addresses/counts are for physical bytes
|
||||
* - channels 5-7 are word - addresses/counts are for physical words
|
||||
* - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
|
||||
* - transfer count loaded to registers is 1 less than actual count
|
||||
* - controller 2 offsets are all even (2x offsets for controller 1)
|
||||
* - page registers for 5-7 don't use data bit 0, represent 128K pages
|
||||
* - page registers for 0-3 use bit 0, represent 64K pages
|
||||
*
|
||||
* DMA transfers are limited to the lower 16MB of _physical_ memory.
|
||||
* Note that addresses loaded into registers must be _physical_ addresses,
|
||||
* not logical addresses (which may differ if paging is active).
|
||||
*
|
||||
* Address mapping for channels 0-3:
|
||||
*
|
||||
* A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses)
|
||||
* | ... | | ... | | ... |
|
||||
* | ... | | ... | | ... |
|
||||
* | ... | | ... | | ... |
|
||||
* P7 ... P0 A7 ... A0 A7 ... A0
|
||||
* | Page | Addr MSB | Addr LSB | (DMA registers)
|
||||
*
|
||||
* Address mapping for channels 5-7:
|
||||
*
|
||||
* A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses)
|
||||
* | ... | \ \ ... \ \ \ ... \ \
|
||||
* | ... | \ \ ... \ \ \ ... \ (not used)
|
||||
* | ... | \ \ ... \ \ \ ... \
|
||||
* P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0
|
||||
* | Page | Addr MSB | Addr LSB | (DMA registers)
|
||||
*
|
||||
* Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
|
||||
* and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
|
||||
* the hardware level, so odd-byte transfers aren't possible).
|
||||
*
|
||||
* Transfer count (_not # bytes_) is limited to 64K, represented as actual
|
||||
* count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more,
|
||||
* and up to 128K bytes may be transferred on channels 5-7 in one operation.
|
||||
*
|
||||
*/
|
||||
|
||||
#define MAX_DMA_CHANNELS 8
|
||||
|
||||
/*
|
||||
ISA DMA limitations on Alpha platforms,
|
||||
|
||||
These may be due to SIO (PCI<->ISA bridge) chipset limitation, or
|
||||
just a wiring limit.
|
||||
*/
|
||||
|
||||
/* The maximum address for ISA DMA transfer on Alpha XL, due to an
|
||||
hardware SIO limitation, is 64MB.
|
||||
*/
|
||||
#define ALPHA_XL_MAX_ISA_DMA_ADDRESS 0x04000000UL
|
||||
|
||||
/* The maximum address for ISA DMA transfer on RUFFIAN,
|
||||
due to an hardware SIO limitation, is 16MB.
|
||||
*/
|
||||
#define ALPHA_RUFFIAN_MAX_ISA_DMA_ADDRESS 0x01000000UL
|
||||
|
||||
/* The maximum address for ISA DMA transfer on SABLE, and some ALCORs,
|
||||
due to an hardware SIO chip limitation, is 2GB.
|
||||
*/
|
||||
#define ALPHA_SABLE_MAX_ISA_DMA_ADDRESS 0x80000000UL
|
||||
#define ALPHA_ALCOR_MAX_ISA_DMA_ADDRESS 0x80000000UL
|
||||
|
||||
/*
|
||||
Maximum address for all the others is the complete 32-bit bus
|
||||
address space.
|
||||
*/
|
||||
#define ALPHA_MAX_ISA_DMA_ADDRESS 0x100000000UL
|
||||
|
||||
#ifdef CONFIG_ALPHA_GENERIC
|
||||
# define MAX_ISA_DMA_ADDRESS (alpha_mv.max_isa_dma_address)
|
||||
#else
|
||||
# if defined(CONFIG_ALPHA_XL)
|
||||
# define MAX_ISA_DMA_ADDRESS ALPHA_XL_MAX_ISA_DMA_ADDRESS
|
||||
# elif defined(CONFIG_ALPHA_RUFFIAN)
|
||||
# define MAX_ISA_DMA_ADDRESS ALPHA_RUFFIAN_MAX_ISA_DMA_ADDRESS
|
||||
# elif defined(CONFIG_ALPHA_SABLE)
|
||||
# define MAX_ISA_DMA_ADDRESS ALPHA_SABLE_MAX_ISA_DMA_ADDRESS
|
||||
# elif defined(CONFIG_ALPHA_ALCOR)
|
||||
# define MAX_ISA_DMA_ADDRESS ALPHA_ALCOR_MAX_ISA_DMA_ADDRESS
|
||||
# else
|
||||
# define MAX_ISA_DMA_ADDRESS ALPHA_MAX_ISA_DMA_ADDRESS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* If we have the iommu, we don't have any address limitations on DMA.
|
||||
Otherwise (Nautilus, RX164), we have to have 0-16 Mb DMA zone
|
||||
like i386. */
|
||||
#define MAX_DMA_ADDRESS (alpha_mv.mv_pci_tbi ? \
|
||||
~0UL : IDENT_ADDR + 0x01000000)
|
||||
|
||||
/* 8237 DMA controllers */
|
||||
#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */
|
||||
#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */
|
||||
|
||||
/* DMA controller registers */
|
||||
#define DMA1_CMD_REG 0x08 /* command register (w) */
|
||||
#define DMA1_STAT_REG 0x08 /* status register (r) */
|
||||
#define DMA1_REQ_REG 0x09 /* request register (w) */
|
||||
#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */
|
||||
#define DMA1_MODE_REG 0x0B /* mode register (w) */
|
||||
#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */
|
||||
#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */
|
||||
#define DMA1_RESET_REG 0x0D /* Master Clear (w) */
|
||||
#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */
|
||||
#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */
|
||||
#define DMA1_EXT_MODE_REG (0x400 | DMA1_MODE_REG)
|
||||
|
||||
#define DMA2_CMD_REG 0xD0 /* command register (w) */
|
||||
#define DMA2_STAT_REG 0xD0 /* status register (r) */
|
||||
#define DMA2_REQ_REG 0xD2 /* request register (w) */
|
||||
#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */
|
||||
#define DMA2_MODE_REG 0xD6 /* mode register (w) */
|
||||
#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */
|
||||
#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */
|
||||
#define DMA2_RESET_REG 0xDA /* Master Clear (w) */
|
||||
#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */
|
||||
#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */
|
||||
#define DMA2_EXT_MODE_REG (0x400 | DMA2_MODE_REG)
|
||||
|
||||
#define DMA_ADDR_0 0x00 /* DMA address registers */
|
||||
#define DMA_ADDR_1 0x02
|
||||
#define DMA_ADDR_2 0x04
|
||||
#define DMA_ADDR_3 0x06
|
||||
#define DMA_ADDR_4 0xC0
|
||||
#define DMA_ADDR_5 0xC4
|
||||
#define DMA_ADDR_6 0xC8
|
||||
#define DMA_ADDR_7 0xCC
|
||||
|
||||
#define DMA_CNT_0 0x01 /* DMA count registers */
|
||||
#define DMA_CNT_1 0x03
|
||||
#define DMA_CNT_2 0x05
|
||||
#define DMA_CNT_3 0x07
|
||||
#define DMA_CNT_4 0xC2
|
||||
#define DMA_CNT_5 0xC6
|
||||
#define DMA_CNT_6 0xCA
|
||||
#define DMA_CNT_7 0xCE
|
||||
|
||||
#define DMA_PAGE_0 0x87 /* DMA page registers */
|
||||
#define DMA_PAGE_1 0x83
|
||||
#define DMA_PAGE_2 0x81
|
||||
#define DMA_PAGE_3 0x82
|
||||
#define DMA_PAGE_5 0x8B
|
||||
#define DMA_PAGE_6 0x89
|
||||
#define DMA_PAGE_7 0x8A
|
||||
|
||||
#define DMA_HIPAGE_0 (0x400 | DMA_PAGE_0)
|
||||
#define DMA_HIPAGE_1 (0x400 | DMA_PAGE_1)
|
||||
#define DMA_HIPAGE_2 (0x400 | DMA_PAGE_2)
|
||||
#define DMA_HIPAGE_3 (0x400 | DMA_PAGE_3)
|
||||
#define DMA_HIPAGE_4 (0x400 | DMA_PAGE_4)
|
||||
#define DMA_HIPAGE_5 (0x400 | DMA_PAGE_5)
|
||||
#define DMA_HIPAGE_6 (0x400 | DMA_PAGE_6)
|
||||
#define DMA_HIPAGE_7 (0x400 | DMA_PAGE_7)
|
||||
|
||||
#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
|
||||
#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
|
||||
#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
|
||||
|
||||
#define DMA_AUTOINIT 0x10
|
||||
|
||||
extern spinlock_t dma_spin_lock;
|
||||
|
||||
static __inline__ unsigned long claim_dma_lock(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&dma_spin_lock, flags);
|
||||
return flags;
|
||||
}
|
||||
|
||||
static __inline__ void release_dma_lock(unsigned long flags)
|
||||
{
|
||||
spin_unlock_irqrestore(&dma_spin_lock, flags);
|
||||
}
|
||||
|
||||
/* enable/disable a specific DMA channel */
|
||||
static __inline__ void enable_dma(unsigned int dmanr)
|
||||
{
|
||||
if (dmanr<=3)
|
||||
dma_outb(dmanr, DMA1_MASK_REG);
|
||||
else
|
||||
dma_outb(dmanr & 3, DMA2_MASK_REG);
|
||||
}
|
||||
|
||||
static __inline__ void disable_dma(unsigned int dmanr)
|
||||
{
|
||||
if (dmanr<=3)
|
||||
dma_outb(dmanr | 4, DMA1_MASK_REG);
|
||||
else
|
||||
dma_outb((dmanr & 3) | 4, DMA2_MASK_REG);
|
||||
}
|
||||
|
||||
/* Clear the 'DMA Pointer Flip Flop'.
|
||||
* Write 0 for LSB/MSB, 1 for MSB/LSB access.
|
||||
* Use this once to initialize the FF to a known state.
|
||||
* After that, keep track of it. :-)
|
||||
* --- In order to do that, the DMA routines below should ---
|
||||
* --- only be used while interrupts are disabled! ---
|
||||
*/
|
||||
static __inline__ void clear_dma_ff(unsigned int dmanr)
|
||||
{
|
||||
if (dmanr<=3)
|
||||
dma_outb(0, DMA1_CLEAR_FF_REG);
|
||||
else
|
||||
dma_outb(0, DMA2_CLEAR_FF_REG);
|
||||
}
|
||||
|
||||
/* set mode (above) for a specific DMA channel */
|
||||
static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
|
||||
{
|
||||
if (dmanr<=3)
|
||||
dma_outb(mode | dmanr, DMA1_MODE_REG);
|
||||
else
|
||||
dma_outb(mode | (dmanr&3), DMA2_MODE_REG);
|
||||
}
|
||||
|
||||
/* set extended mode for a specific DMA channel */
|
||||
static __inline__ void set_dma_ext_mode(unsigned int dmanr, char ext_mode)
|
||||
{
|
||||
if (dmanr<=3)
|
||||
dma_outb(ext_mode | dmanr, DMA1_EXT_MODE_REG);
|
||||
else
|
||||
dma_outb(ext_mode | (dmanr&3), DMA2_EXT_MODE_REG);
|
||||
}
|
||||
|
||||
/* Set only the page register bits of the transfer address.
|
||||
* This is used for successive transfers when we know the contents of
|
||||
* the lower 16 bits of the DMA current address register.
|
||||
*/
|
||||
static __inline__ void set_dma_page(unsigned int dmanr, unsigned int pagenr)
|
||||
{
|
||||
switch(dmanr) {
|
||||
case 0:
|
||||
dma_outb(pagenr, DMA_PAGE_0);
|
||||
dma_outb((pagenr >> 8), DMA_HIPAGE_0);
|
||||
break;
|
||||
case 1:
|
||||
dma_outb(pagenr, DMA_PAGE_1);
|
||||
dma_outb((pagenr >> 8), DMA_HIPAGE_1);
|
||||
break;
|
||||
case 2:
|
||||
dma_outb(pagenr, DMA_PAGE_2);
|
||||
dma_outb((pagenr >> 8), DMA_HIPAGE_2);
|
||||
break;
|
||||
case 3:
|
||||
dma_outb(pagenr, DMA_PAGE_3);
|
||||
dma_outb((pagenr >> 8), DMA_HIPAGE_3);
|
||||
break;
|
||||
case 5:
|
||||
dma_outb(pagenr & 0xfe, DMA_PAGE_5);
|
||||
dma_outb((pagenr >> 8), DMA_HIPAGE_5);
|
||||
break;
|
||||
case 6:
|
||||
dma_outb(pagenr & 0xfe, DMA_PAGE_6);
|
||||
dma_outb((pagenr >> 8), DMA_HIPAGE_6);
|
||||
break;
|
||||
case 7:
|
||||
dma_outb(pagenr & 0xfe, DMA_PAGE_7);
|
||||
dma_outb((pagenr >> 8), DMA_HIPAGE_7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Set transfer address & page bits for specific DMA channel.
|
||||
* Assumes dma flipflop is clear.
|
||||
*/
|
||||
static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
|
||||
{
|
||||
if (dmanr <= 3) {
|
||||
dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
|
||||
dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
|
||||
} else {
|
||||
dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
|
||||
dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
|
||||
}
|
||||
set_dma_page(dmanr, a>>16); /* set hipage last to enable 32-bit mode */
|
||||
}
|
||||
|
||||
|
||||
/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
|
||||
* a specific DMA channel.
|
||||
* You must ensure the parameters are valid.
|
||||
* NOTE: from a manual: "the number of transfers is one more
|
||||
* than the initial word count"! This is taken into account.
|
||||
* Assumes dma flip-flop is clear.
|
||||
* NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
|
||||
*/
|
||||
static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
|
||||
{
|
||||
count--;
|
||||
if (dmanr <= 3) {
|
||||
dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
|
||||
dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
|
||||
} else {
|
||||
dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
|
||||
dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Get DMA residue count. After a DMA transfer, this
|
||||
* should return zero. Reading this while a DMA transfer is
|
||||
* still in progress will return unpredictable results.
|
||||
* If called before the channel has been used, it may return 1.
|
||||
* Otherwise, it returns the number of _bytes_ left to transfer.
|
||||
*
|
||||
* Assumes DMA flip-flop is clear.
|
||||
*/
|
||||
static __inline__ int get_dma_residue(unsigned int dmanr)
|
||||
{
|
||||
unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
|
||||
: ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
|
||||
|
||||
/* using short to get 16-bit wrap around */
|
||||
unsigned short count;
|
||||
|
||||
count = 1 + dma_inb(io_port);
|
||||
count += dma_inb(io_port) << 8;
|
||||
|
||||
return (dmanr<=3)? count : (count<<1);
|
||||
}
|
||||
|
||||
|
||||
/* These are in kernel/dma.c: */
|
||||
extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
|
||||
extern void free_dma(unsigned int dmanr); /* release it again */
|
||||
#define KERNEL_HAVE_CHECK_DMA
|
||||
extern int check_dma(unsigned int dmanr);
|
||||
|
||||
/* From PCI */
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
extern int isa_dma_bridge_buggy;
|
||||
#else
|
||||
#define isa_dma_bridge_buggy (0)
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _ASM_DMA_H */
|
166
arch/alpha/include/asm/elf.h
Normal file
166
arch/alpha/include/asm/elf.h
Normal file
@ -0,0 +1,166 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_ALPHA_ELF_H
|
||||
#define __ASM_ALPHA_ELF_H
|
||||
|
||||
#include <asm/auxvec.h>
|
||||
#include <asm/special_insns.h>
|
||||
|
||||
/* Special values for the st_other field in the symbol table. */
|
||||
|
||||
#define STO_ALPHA_NOPV 0x80
|
||||
#define STO_ALPHA_STD_GPLOAD 0x88
|
||||
|
||||
/*
|
||||
* Alpha ELF relocation types
|
||||
*/
|
||||
#define R_ALPHA_NONE 0 /* No reloc */
|
||||
#define R_ALPHA_REFLONG 1 /* Direct 32 bit */
|
||||
#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */
|
||||
#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */
|
||||
#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */
|
||||
#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */
|
||||
#define R_ALPHA_GPDISP 6 /* Add displacement to GP */
|
||||
#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */
|
||||
#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */
|
||||
#define R_ALPHA_SREL16 9 /* PC relative 16 bit */
|
||||
#define R_ALPHA_SREL32 10 /* PC relative 32 bit */
|
||||
#define R_ALPHA_SREL64 11 /* PC relative 64 bit */
|
||||
#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */
|
||||
#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */
|
||||
#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */
|
||||
#define R_ALPHA_COPY 24 /* Copy symbol at runtime */
|
||||
#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */
|
||||
#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */
|
||||
#define R_ALPHA_RELATIVE 27 /* Adjust by program base */
|
||||
#define R_ALPHA_BRSGP 28
|
||||
#define R_ALPHA_TLSGD 29
|
||||
#define R_ALPHA_TLS_LDM 30
|
||||
#define R_ALPHA_DTPMOD64 31
|
||||
#define R_ALPHA_GOTDTPREL 32
|
||||
#define R_ALPHA_DTPREL64 33
|
||||
#define R_ALPHA_DTPRELHI 34
|
||||
#define R_ALPHA_DTPRELLO 35
|
||||
#define R_ALPHA_DTPREL16 36
|
||||
#define R_ALPHA_GOTTPREL 37
|
||||
#define R_ALPHA_TPREL64 38
|
||||
#define R_ALPHA_TPRELHI 39
|
||||
#define R_ALPHA_TPRELLO 40
|
||||
#define R_ALPHA_TPREL16 41
|
||||
|
||||
#define SHF_ALPHA_GPREL 0x10000000
|
||||
|
||||
/* Legal values for e_flags field of Elf64_Ehdr. */
|
||||
|
||||
#define EF_ALPHA_32BIT 1 /* All addresses are below 2GB */
|
||||
|
||||
/*
|
||||
* ELF register definitions..
|
||||
*/
|
||||
|
||||
/*
|
||||
* The OSF/1 version of <sys/procfs.h> makes gregset_t 46 entries long.
|
||||
* I have no idea why that is so. For now, we just leave it at 33
|
||||
* (32 general regs + processor status word).
|
||||
*/
|
||||
#define ELF_NGREG 33
|
||||
#define ELF_NFPREG 32
|
||||
|
||||
typedef unsigned long elf_greg_t;
|
||||
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
||||
|
||||
typedef double elf_fpreg_t;
|
||||
typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
|
||||
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
#define elf_check_arch(x) ((x)->e_machine == EM_ALPHA)
|
||||
|
||||
/*
|
||||
* These are used to set parameters in the core dumps.
|
||||
*/
|
||||
#define ELF_CLASS ELFCLASS64
|
||||
#define ELF_DATA ELFDATA2LSB
|
||||
#define ELF_ARCH EM_ALPHA
|
||||
|
||||
#define ELF_EXEC_PAGESIZE 8192
|
||||
|
||||
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
|
||||
use of this is to invoke "./ld.so someprog" to test out a new version of
|
||||
the loader. We need to make sure that it is out of the way of the program
|
||||
that it will "exec", and that there is sufficient room for the brk. */
|
||||
|
||||
#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
|
||||
|
||||
/* $0 is set by ld.so to a pointer to a function which might be
|
||||
registered using atexit. This provides a mean for the dynamic
|
||||
linker to call DT_FINI functions for shared libraries that have
|
||||
been loaded before the code runs.
|
||||
|
||||
So that we can use the same startup file with static executables,
|
||||
we start programs with a value of 0 to indicate that there is no
|
||||
such function. */
|
||||
|
||||
#define ELF_PLAT_INIT(_r, load_addr) _r->r0 = 0
|
||||
|
||||
/* The registers are laid out in pt_regs for PAL and syscall
|
||||
convenience. Re-order them for the linear elf_gregset_t. */
|
||||
|
||||
struct pt_regs;
|
||||
struct thread_info;
|
||||
struct task_struct;
|
||||
extern void dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt,
|
||||
struct thread_info *ti);
|
||||
#define ELF_CORE_COPY_REGS(DEST, REGS) \
|
||||
dump_elf_thread(DEST, REGS, current_thread_info());
|
||||
|
||||
/* Similar, but for a thread other than current. */
|
||||
|
||||
extern int dump_elf_task(elf_greg_t *dest, struct task_struct *task);
|
||||
#define ELF_CORE_COPY_TASK_REGS(TASK, DEST) \
|
||||
dump_elf_task(*(DEST), TASK)
|
||||
|
||||
/* Similar, but for the FP registers. */
|
||||
|
||||
extern int dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task);
|
||||
#define ELF_CORE_COPY_FPREGS(TASK, DEST) \
|
||||
dump_elf_task_fp(*(DEST), TASK)
|
||||
|
||||
/* This yields a mask that user programs can use to figure out what
|
||||
instruction set this CPU supports. This is trivial on Alpha,
|
||||
but not so on other machines. */
|
||||
|
||||
#define ELF_HWCAP (~amask(-1))
|
||||
|
||||
/* This yields a string that ld.so will use to load implementation
|
||||
specific libraries for optimization. This is more specific in
|
||||
intent than poking at uname or /proc/cpuinfo. */
|
||||
|
||||
#define ELF_PLATFORM \
|
||||
({ \
|
||||
enum implver_enum i_ = implver(); \
|
||||
( i_ == IMPLVER_EV4 ? "ev4" \
|
||||
: i_ == IMPLVER_EV5 \
|
||||
? (amask(AMASK_BWX) ? "ev5" : "ev56") \
|
||||
: amask (AMASK_CIX) ? "ev6" : "ev67"); \
|
||||
})
|
||||
|
||||
#define SET_PERSONALITY(EX) \
|
||||
set_personality(((EX).e_flags & EF_ALPHA_32BIT) \
|
||||
? PER_LINUX_32BIT : PER_LINUX)
|
||||
|
||||
extern int alpha_l1i_cacheshape;
|
||||
extern int alpha_l1d_cacheshape;
|
||||
extern int alpha_l2_cacheshape;
|
||||
extern int alpha_l3_cacheshape;
|
||||
|
||||
/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
|
||||
#define ARCH_DLINFO \
|
||||
do { \
|
||||
NEW_AUX_ENT(AT_L1I_CACHESHAPE, alpha_l1i_cacheshape); \
|
||||
NEW_AUX_ENT(AT_L1D_CACHESHAPE, alpha_l1d_cacheshape); \
|
||||
NEW_AUX_ENT(AT_L2_CACHESHAPE, alpha_l2_cacheshape); \
|
||||
NEW_AUX_ENT(AT_L3_CACHESHAPE, alpha_l3_cacheshape); \
|
||||
} while (0)
|
||||
|
||||
#endif /* __ASM_ALPHA_ELF_H */
|
6
arch/alpha/include/asm/emergency-restart.h
Normal file
6
arch/alpha/include/asm/emergency-restart.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef _ASM_EMERGENCY_RESTART_H
|
||||
#define _ASM_EMERGENCY_RESTART_H
|
||||
|
||||
#include <asm-generic/emergency-restart.h>
|
||||
|
||||
#endif /* _ASM_EMERGENCY_RESTART_H */
|
119
arch/alpha/include/asm/err_common.h
Normal file
119
arch/alpha/include/asm/err_common.h
Normal file
@ -0,0 +1,119 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* linux/include/asm-alpha/err_common.h
|
||||
*
|
||||
* Copyright (C) 2000 Jeff Wiedemeier (Compaq Computer Corporation)
|
||||
*
|
||||
* Contains declarations and macros to support Alpha error handling
|
||||
* implementations.
|
||||
*/
|
||||
|
||||
#ifndef __ALPHA_ERR_COMMON_H
|
||||
#define __ALPHA_ERR_COMMON_H 1
|
||||
|
||||
/*
|
||||
* SCB Vector definitions
|
||||
*/
|
||||
#define SCB_Q_SYSERR 0x620
|
||||
#define SCB_Q_PROCERR 0x630
|
||||
#define SCB_Q_SYSMCHK 0x660
|
||||
#define SCB_Q_PROCMCHK 0x670
|
||||
#define SCB_Q_SYSEVENT 0x680
|
||||
|
||||
/*
|
||||
* Disposition definitions for logout frame parser
|
||||
*/
|
||||
#define MCHK_DISPOSITION_UNKNOWN_ERROR 0x00
|
||||
#define MCHK_DISPOSITION_REPORT 0x01
|
||||
#define MCHK_DISPOSITION_DISMISS 0x02
|
||||
|
||||
/*
|
||||
* Error Log definitions
|
||||
*/
|
||||
/*
|
||||
* Types
|
||||
*/
|
||||
|
||||
#define EL_CLASS__TERMINATION (0)
|
||||
# define EL_TYPE__TERMINATION__TERMINATION (0)
|
||||
#define EL_CLASS__HEADER (5)
|
||||
# define EL_TYPE__HEADER__SYSTEM_ERROR_FRAME (1)
|
||||
# define EL_TYPE__HEADER__SYSTEM_EVENT_FRAME (2)
|
||||
# define EL_TYPE__HEADER__HALT_FRAME (3)
|
||||
# define EL_TYPE__HEADER__LOGOUT_FRAME (19)
|
||||
#define EL_CLASS__GENERAL_NOTIFICATION (9)
|
||||
#define EL_CLASS__PCI_ERROR_FRAME (11)
|
||||
#define EL_CLASS__REGATTA_FAMILY (12)
|
||||
# define EL_TYPE__REGATTA__PROCESSOR_ERROR_FRAME (1)
|
||||
# define EL_TYPE__REGATTA__SYSTEM_ERROR_FRAME (2)
|
||||
# define EL_TYPE__REGATTA__ENVIRONMENTAL_FRAME (3)
|
||||
# define EL_TYPE__REGATTA__TITAN_PCHIP0_EXTENDED (8)
|
||||
# define EL_TYPE__REGATTA__TITAN_PCHIP1_EXTENDED (9)
|
||||
# define EL_TYPE__REGATTA__TITAN_MEMORY_EXTENDED (10)
|
||||
# define EL_TYPE__REGATTA__PROCESSOR_DBL_ERROR_HALT (11)
|
||||
# define EL_TYPE__REGATTA__SYSTEM_DBL_ERROR_HALT (12)
|
||||
#define EL_CLASS__PAL (14)
|
||||
# define EL_TYPE__PAL__LOGOUT_FRAME (1)
|
||||
# define EL_TYPE__PAL__EV7_PROCESSOR (4)
|
||||
# define EL_TYPE__PAL__EV7_ZBOX (5)
|
||||
# define EL_TYPE__PAL__EV7_RBOX (6)
|
||||
# define EL_TYPE__PAL__EV7_IO (7)
|
||||
# define EL_TYPE__PAL__ENV__AMBIENT_TEMPERATURE (10)
|
||||
# define EL_TYPE__PAL__ENV__AIRMOVER_FAN (11)
|
||||
# define EL_TYPE__PAL__ENV__VOLTAGE (12)
|
||||
# define EL_TYPE__PAL__ENV__INTRUSION (13)
|
||||
# define EL_TYPE__PAL__ENV__POWER_SUPPLY (14)
|
||||
# define EL_TYPE__PAL__ENV__LAN (15)
|
||||
# define EL_TYPE__PAL__ENV__HOT_PLUG (16)
|
||||
|
||||
union el_timestamp {
|
||||
struct {
|
||||
u8 second;
|
||||
u8 minute;
|
||||
u8 hour;
|
||||
u8 day;
|
||||
u8 month;
|
||||
u8 year;
|
||||
} b;
|
||||
u64 as_int;
|
||||
};
|
||||
|
||||
struct el_subpacket {
|
||||
u16 length; /* length of header (in bytes) */
|
||||
u16 class; /* header class and type... */
|
||||
u16 type; /* ...determine content */
|
||||
u16 revision; /* header revision */
|
||||
union {
|
||||
struct { /* Class 5, Type 1 - System Error */
|
||||
u32 frame_length;
|
||||
u32 frame_packet_count;
|
||||
} sys_err;
|
||||
struct { /* Class 5, Type 2 - System Event */
|
||||
union el_timestamp timestamp;
|
||||
u32 frame_length;
|
||||
u32 frame_packet_count;
|
||||
} sys_event;
|
||||
struct { /* Class 5, Type 3 - Double Error Halt */
|
||||
u16 halt_code;
|
||||
u16 reserved;
|
||||
union el_timestamp timestamp;
|
||||
u32 frame_length;
|
||||
u32 frame_packet_count;
|
||||
} err_halt;
|
||||
struct { /* Clasee 5, Type 19 - Logout Frame Header */
|
||||
u32 frame_length;
|
||||
u32 frame_flags;
|
||||
u32 cpu_offset;
|
||||
u32 system_offset;
|
||||
} logout_header;
|
||||
struct { /* Class 12 - Regatta */
|
||||
u64 cpuid;
|
||||
u64 data_start[1];
|
||||
} regatta_frame;
|
||||
struct { /* Raw */
|
||||
u64 data_start[1];
|
||||
} raw;
|
||||
} by_type;
|
||||
};
|
||||
|
||||
#endif /* __ALPHA_ERR_COMMON_H */
|
6
arch/alpha/include/asm/err_ev6.h
Normal file
6
arch/alpha/include/asm/err_ev6.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __ALPHA_ERR_EV6_H
|
||||
#define __ALPHA_ERR_EV6_H 1
|
||||
|
||||
/* Dummy include for now. */
|
||||
|
||||
#endif /* __ALPHA_ERR_EV6_H */
|
203
arch/alpha/include/asm/err_ev7.h
Normal file
203
arch/alpha/include/asm/err_ev7.h
Normal file
@ -0,0 +1,203 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_ERR_EV7_H
|
||||
#define __ALPHA_ERR_EV7_H 1
|
||||
|
||||
/*
|
||||
* Data for el packet class PAL (14), type LOGOUT_FRAME (1)
|
||||
*/
|
||||
struct ev7_pal_logout_subpacket {
|
||||
u32 mchk_code;
|
||||
u32 subpacket_count;
|
||||
u64 whami;
|
||||
u64 rbox_whami;
|
||||
u64 rbox_int;
|
||||
u64 exc_addr;
|
||||
union el_timestamp timestamp;
|
||||
u64 halt_code;
|
||||
u64 reserved;
|
||||
};
|
||||
|
||||
/*
|
||||
* Data for el packet class PAL (14), type EV7_PROCESSOR (4)
|
||||
*/
|
||||
struct ev7_pal_processor_subpacket {
|
||||
u64 i_stat;
|
||||
u64 dc_stat;
|
||||
u64 c_addr;
|
||||
u64 c_syndrome_1;
|
||||
u64 c_syndrome_0;
|
||||
u64 c_stat;
|
||||
u64 c_sts;
|
||||
u64 mm_stat;
|
||||
u64 exc_addr;
|
||||
u64 ier_cm;
|
||||
u64 isum;
|
||||
u64 pal_base;
|
||||
u64 i_ctl;
|
||||
u64 process_context;
|
||||
u64 cbox_ctl;
|
||||
u64 cbox_stp_ctl;
|
||||
u64 cbox_acc_ctl;
|
||||
u64 cbox_lcl_set;
|
||||
u64 cbox_gbl_set;
|
||||
u64 bbox_ctl;
|
||||
u64 bbox_err_sts;
|
||||
u64 bbox_err_idx;
|
||||
u64 cbox_ddp_err_sts;
|
||||
u64 bbox_dat_rmp;
|
||||
u64 reserved[2];
|
||||
};
|
||||
|
||||
/*
|
||||
* Data for el packet class PAL (14), type EV7_ZBOX (5)
|
||||
*/
|
||||
struct ev7_pal_zbox_subpacket {
|
||||
u32 zbox0_dram_err_status_1;
|
||||
u32 zbox0_dram_err_status_2;
|
||||
u32 zbox0_dram_err_status_3;
|
||||
u32 zbox0_dram_err_ctl;
|
||||
u32 zbox0_dram_err_adr;
|
||||
u32 zbox0_dift_timeout;
|
||||
u32 zbox0_dram_mapper_ctl;
|
||||
u32 zbox0_frc_err_adr;
|
||||
u32 zbox0_dift_err_status;
|
||||
u32 reserved1;
|
||||
u32 zbox1_dram_err_status_1;
|
||||
u32 zbox1_dram_err_status_2;
|
||||
u32 zbox1_dram_err_status_3;
|
||||
u32 zbox1_dram_err_ctl;
|
||||
u32 zbox1_dram_err_adr;
|
||||
u32 zbox1_dift_timeout;
|
||||
u32 zbox1_dram_mapper_ctl;
|
||||
u32 zbox1_frc_err_adr;
|
||||
u32 zbox1_dift_err_status;
|
||||
u32 reserved2;
|
||||
u64 cbox_ctl;
|
||||
u64 cbox_stp_ctl;
|
||||
u64 zbox0_error_pa;
|
||||
u64 zbox1_error_pa;
|
||||
u64 zbox0_ored_syndrome;
|
||||
u64 zbox1_ored_syndrome;
|
||||
u64 reserved3[2];
|
||||
};
|
||||
|
||||
/*
|
||||
* Data for el packet class PAL (14), type EV7_RBOX (6)
|
||||
*/
|
||||
struct ev7_pal_rbox_subpacket {
|
||||
u64 rbox_cfg;
|
||||
u64 rbox_n_cfg;
|
||||
u64 rbox_s_cfg;
|
||||
u64 rbox_e_cfg;
|
||||
u64 rbox_w_cfg;
|
||||
u64 rbox_n_err;
|
||||
u64 rbox_s_err;
|
||||
u64 rbox_e_err;
|
||||
u64 rbox_w_err;
|
||||
u64 rbox_io_cfg;
|
||||
u64 rbox_io_err;
|
||||
u64 rbox_l_err;
|
||||
u64 rbox_whoami;
|
||||
u64 rbox_imask;
|
||||
u64 rbox_intq;
|
||||
u64 rbox_int;
|
||||
u64 reserved[2];
|
||||
};
|
||||
|
||||
/*
|
||||
* Data for el packet class PAL (14), type EV7_IO (7)
|
||||
*/
|
||||
struct ev7_pal_io_one_port {
|
||||
u64 pox_err_sum;
|
||||
u64 pox_tlb_err;
|
||||
u64 pox_spl_cmplt;
|
||||
u64 pox_trans_sum;
|
||||
u64 pox_first_err;
|
||||
u64 pox_mult_err;
|
||||
u64 pox_dm_source;
|
||||
u64 pox_dm_dest;
|
||||
u64 pox_dm_size;
|
||||
u64 pox_dm_ctrl;
|
||||
u64 reserved;
|
||||
};
|
||||
|
||||
struct ev7_pal_io_subpacket {
|
||||
u64 io_asic_rev;
|
||||
u64 io_sys_rev;
|
||||
u64 io7_uph;
|
||||
u64 hpi_ctl;
|
||||
u64 crd_ctl;
|
||||
u64 hei_ctl;
|
||||
u64 po7_error_sum;
|
||||
u64 po7_uncrr_sym;
|
||||
u64 po7_crrct_sym;
|
||||
u64 po7_ugbge_sym;
|
||||
u64 po7_err_pkt0;
|
||||
u64 po7_err_pkt1;
|
||||
u64 reserved[2];
|
||||
struct ev7_pal_io_one_port ports[4];
|
||||
};
|
||||
|
||||
/*
|
||||
* Environmental subpacket. Data used for el packets:
|
||||
* class PAL (14), type AMBIENT_TEMPERATURE (10)
|
||||
* class PAL (14), type AIRMOVER_FAN (11)
|
||||
* class PAL (14), type VOLTAGE (12)
|
||||
* class PAL (14), type INTRUSION (13)
|
||||
* class PAL (14), type POWER_SUPPLY (14)
|
||||
* class PAL (14), type LAN (15)
|
||||
* class PAL (14), type HOT_PLUG (16)
|
||||
*/
|
||||
struct ev7_pal_environmental_subpacket {
|
||||
u16 cabinet;
|
||||
u16 drawer;
|
||||
u16 reserved1[2];
|
||||
u8 module_type;
|
||||
u8 unit_id; /* unit reporting condition */
|
||||
u8 reserved2;
|
||||
u8 condition; /* condition reported */
|
||||
};
|
||||
|
||||
/*
|
||||
* Convert environmental type to index
|
||||
*/
|
||||
static inline int ev7_lf_env_index(int type)
|
||||
{
|
||||
BUG_ON((type < EL_TYPE__PAL__ENV__AMBIENT_TEMPERATURE)
|
||||
|| (type > EL_TYPE__PAL__ENV__HOT_PLUG));
|
||||
|
||||
return type - EL_TYPE__PAL__ENV__AMBIENT_TEMPERATURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Data for generic el packet class PAL.
|
||||
*/
|
||||
struct ev7_pal_subpacket {
|
||||
union {
|
||||
struct ev7_pal_logout_subpacket logout; /* Type 1 */
|
||||
struct ev7_pal_processor_subpacket ev7; /* Type 4 */
|
||||
struct ev7_pal_zbox_subpacket zbox; /* Type 5 */
|
||||
struct ev7_pal_rbox_subpacket rbox; /* Type 6 */
|
||||
struct ev7_pal_io_subpacket io; /* Type 7 */
|
||||
struct ev7_pal_environmental_subpacket env; /* Type 10-16 */
|
||||
u64 as_quad[1]; /* Raw u64 */
|
||||
} by_type;
|
||||
};
|
||||
|
||||
/*
|
||||
* Struct to contain collected logout from subpackets.
|
||||
*/
|
||||
struct ev7_lf_subpackets {
|
||||
struct ev7_pal_logout_subpacket *logout; /* Type 1 */
|
||||
struct ev7_pal_processor_subpacket *ev7; /* Type 4 */
|
||||
struct ev7_pal_zbox_subpacket *zbox; /* Type 5 */
|
||||
struct ev7_pal_rbox_subpacket *rbox; /* Type 6 */
|
||||
struct ev7_pal_io_subpacket *io; /* Type 7 */
|
||||
struct ev7_pal_environmental_subpacket *env[7]; /* Type 10-16 */
|
||||
|
||||
unsigned int io_pid;
|
||||
};
|
||||
|
||||
#endif /* __ALPHA_ERR_EV7_H */
|
||||
|
||||
|
56
arch/alpha/include/asm/extable.h
Normal file
56
arch/alpha/include/asm/extable.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_EXTABLE_H
|
||||
#define _ASM_EXTABLE_H
|
||||
|
||||
/*
|
||||
* About the exception table:
|
||||
*
|
||||
* - insn is a 32-bit pc-relative offset from the faulting insn.
|
||||
* - nextinsn is a 16-bit offset off of the faulting instruction
|
||||
* (not off of the *next* instruction as branches are).
|
||||
* - errreg is the register in which to place -EFAULT.
|
||||
* - valreg is the final target register for the load sequence
|
||||
* and will be zeroed.
|
||||
*
|
||||
* Either errreg or valreg may be $31, in which case nothing happens.
|
||||
*
|
||||
* The exception fixup information "just so happens" to be arranged
|
||||
* as in a MEM format instruction. This lets us emit our three
|
||||
* values like so:
|
||||
*
|
||||
* lda valreg, nextinsn(errreg)
|
||||
*
|
||||
*/
|
||||
|
||||
struct exception_table_entry
|
||||
{
|
||||
signed int insn;
|
||||
union exception_fixup {
|
||||
unsigned unit;
|
||||
struct {
|
||||
signed int nextinsn : 16;
|
||||
unsigned int errreg : 5;
|
||||
unsigned int valreg : 5;
|
||||
} bits;
|
||||
} fixup;
|
||||
};
|
||||
|
||||
/* Returns the new pc */
|
||||
#define fixup_exception(map_reg, _fixup, pc) \
|
||||
({ \
|
||||
if ((_fixup)->fixup.bits.valreg != 31) \
|
||||
map_reg((_fixup)->fixup.bits.valreg) = 0; \
|
||||
if ((_fixup)->fixup.bits.errreg != 31) \
|
||||
map_reg((_fixup)->fixup.bits.errreg) = -EFAULT; \
|
||||
(pc) + (_fixup)->fixup.bits.nextinsn; \
|
||||
})
|
||||
|
||||
#define ARCH_HAS_RELATIVE_EXTABLE
|
||||
|
||||
#define swap_ex_entry_fixup(a, b, tmp, delta) \
|
||||
do { \
|
||||
(a)->fixup.unit = (b)->fixup.unit; \
|
||||
(b)->fixup.unit = (tmp).fixup.unit; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
113
arch/alpha/include/asm/floppy.h
Normal file
113
arch/alpha/include/asm/floppy.h
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Architecture specific parts of the Floppy driver
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 1995
|
||||
*/
|
||||
#ifndef __ASM_ALPHA_FLOPPY_H
|
||||
#define __ASM_ALPHA_FLOPPY_H
|
||||
|
||||
|
||||
#define fd_inb(base, reg) inb_p((base) + (reg))
|
||||
#define fd_outb(value, base, reg) outb_p(value, (base) + (reg))
|
||||
|
||||
#define fd_enable_dma() enable_dma(FLOPPY_DMA)
|
||||
#define fd_disable_dma() disable_dma(FLOPPY_DMA)
|
||||
#define fd_request_dma() request_dma(FLOPPY_DMA,"floppy")
|
||||
#define fd_free_dma() free_dma(FLOPPY_DMA)
|
||||
#define fd_clear_dma_ff() clear_dma_ff(FLOPPY_DMA)
|
||||
#define fd_set_dma_mode(mode) set_dma_mode(FLOPPY_DMA,mode)
|
||||
#define fd_set_dma_addr(addr) set_dma_addr(FLOPPY_DMA,virt_to_bus(addr))
|
||||
#define fd_set_dma_count(count) set_dma_count(FLOPPY_DMA,count)
|
||||
#define fd_enable_irq() enable_irq(FLOPPY_IRQ)
|
||||
#define fd_disable_irq() disable_irq(FLOPPY_IRQ)
|
||||
#define fd_request_irq() request_irq(FLOPPY_IRQ, floppy_interrupt,\
|
||||
0, "floppy", NULL)
|
||||
#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL)
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
|
||||
#include <linux/pci.h>
|
||||
|
||||
#define fd_dma_setup(addr,size,mode,io) alpha_fd_dma_setup(addr,size,mode,io)
|
||||
|
||||
static __inline__ int
|
||||
alpha_fd_dma_setup(char *addr, unsigned long size, int mode, int io)
|
||||
{
|
||||
static unsigned long prev_size;
|
||||
static dma_addr_t bus_addr = 0;
|
||||
static char *prev_addr;
|
||||
static int prev_dir;
|
||||
int dir;
|
||||
|
||||
dir = (mode != DMA_MODE_READ) ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE;
|
||||
|
||||
if (bus_addr
|
||||
&& (addr != prev_addr || size != prev_size || dir != prev_dir)) {
|
||||
/* different from last time -- unmap prev */
|
||||
pci_unmap_single(isa_bridge, bus_addr, prev_size, prev_dir);
|
||||
bus_addr = 0;
|
||||
}
|
||||
|
||||
if (!bus_addr) /* need to map it */
|
||||
bus_addr = pci_map_single(isa_bridge, addr, size, dir);
|
||||
|
||||
/* remember this one as prev */
|
||||
prev_addr = addr;
|
||||
prev_size = size;
|
||||
prev_dir = dir;
|
||||
|
||||
fd_clear_dma_ff();
|
||||
fd_set_dma_mode(mode);
|
||||
set_dma_addr(FLOPPY_DMA, bus_addr);
|
||||
fd_set_dma_count(size);
|
||||
virtual_dma_port = io;
|
||||
fd_enable_dma();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
__inline__ void virtual_dma_init(void)
|
||||
{
|
||||
/* Nothing to do on an Alpha */
|
||||
}
|
||||
|
||||
static int FDC1 = 0x3f0;
|
||||
static int FDC2 = -1;
|
||||
|
||||
/*
|
||||
* Again, the CMOS information doesn't work on the alpha..
|
||||
*/
|
||||
#define FLOPPY0_TYPE 6
|
||||
#define FLOPPY1_TYPE 0
|
||||
|
||||
#define N_FDC 2
|
||||
#define N_DRIVE 8
|
||||
|
||||
/*
|
||||
* Most Alphas have no problems with floppy DMA crossing 64k borders,
|
||||
* except for certain ones, like XL and RUFFIAN.
|
||||
*
|
||||
* However, the test is simple and fast, and this *is* floppy, after all,
|
||||
* so we do it for all platforms, just to make sure.
|
||||
*
|
||||
* This is advantageous in other circumstances as well, as in moving
|
||||
* about the PCI DMA windows and forcing the floppy to start doing
|
||||
* scatter-gather when it never had before, and there *is* a problem
|
||||
* on that platform... ;-}
|
||||
*/
|
||||
|
||||
static inline unsigned long CROSS_64KB(void *a, unsigned long s)
|
||||
{
|
||||
unsigned long p = (unsigned long)a;
|
||||
return ((p + s - 1) ^ p) & ~0xffffUL;
|
||||
}
|
||||
|
||||
#define EXTRA_FLOPPY_PARAMS
|
||||
|
||||
#endif /* __ASM_ALPHA_FLOPPY_H */
|
76
arch/alpha/include/asm/fpu.h
Normal file
76
arch/alpha/include/asm/fpu.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_ALPHA_FPU_H
|
||||
#define __ASM_ALPHA_FPU_H
|
||||
|
||||
#include <asm/special_insns.h>
|
||||
#include <uapi/asm/fpu.h>
|
||||
|
||||
/* The following two functions don't need trapb/excb instructions
|
||||
around the mf_fpcr/mt_fpcr instructions because (a) the kernel
|
||||
never generates arithmetic faults and (b) call_pal instructions
|
||||
are implied trap barriers. */
|
||||
|
||||
static inline unsigned long
|
||||
rdfpcr(void)
|
||||
{
|
||||
unsigned long tmp, ret;
|
||||
|
||||
#if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
|
||||
__asm__ __volatile__ (
|
||||
"ftoit $f0,%0\n\t"
|
||||
"mf_fpcr $f0\n\t"
|
||||
"ftoit $f0,%1\n\t"
|
||||
"itoft %0,$f0"
|
||||
: "=r"(tmp), "=r"(ret));
|
||||
#else
|
||||
__asm__ __volatile__ (
|
||||
"stt $f0,%0\n\t"
|
||||
"mf_fpcr $f0\n\t"
|
||||
"stt $f0,%1\n\t"
|
||||
"ldt $f0,%0"
|
||||
: "=m"(tmp), "=m"(ret));
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void
|
||||
wrfpcr(unsigned long val)
|
||||
{
|
||||
unsigned long tmp;
|
||||
|
||||
#if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
|
||||
__asm__ __volatile__ (
|
||||
"ftoit $f0,%0\n\t"
|
||||
"itoft %1,$f0\n\t"
|
||||
"mt_fpcr $f0\n\t"
|
||||
"itoft %0,$f0"
|
||||
: "=&r"(tmp) : "r"(val));
|
||||
#else
|
||||
__asm__ __volatile__ (
|
||||
"stt $f0,%0\n\t"
|
||||
"ldt $f0,%1\n\t"
|
||||
"mt_fpcr $f0\n\t"
|
||||
"ldt $f0,%0"
|
||||
: "=m"(tmp) : "m"(val));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
swcr_update_status(unsigned long swcr, unsigned long fpcr)
|
||||
{
|
||||
/* EV6 implements most of the bits in hardware. Collect
|
||||
the acrued exception bits from the real fpcr. */
|
||||
if (implver() == IMPLVER_EV6) {
|
||||
swcr &= ~IEEE_STATUS_MASK;
|
||||
swcr |= (fpcr >> 35) & IEEE_STATUS_MASK;
|
||||
}
|
||||
return swcr;
|
||||
}
|
||||
|
||||
extern unsigned long alpha_read_fp_reg (unsigned long reg);
|
||||
extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
|
||||
extern unsigned long alpha_read_fp_reg_s (unsigned long reg);
|
||||
extern void alpha_write_fp_reg_s (unsigned long reg, unsigned long val);
|
||||
|
||||
#endif /* __ASM_ALPHA_FPU_H */
|
1
arch/alpha/include/asm/ftrace.h
Normal file
1
arch/alpha/include/asm/ftrace.h
Normal file
@ -0,0 +1 @@
|
||||
/* empty */
|
95
arch/alpha/include/asm/futex.h
Normal file
95
arch/alpha/include/asm/futex.h
Normal file
@ -0,0 +1,95 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_ALPHA_FUTEX_H
|
||||
#define _ASM_ALPHA_FUTEX_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/futex.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/barrier.h>
|
||||
|
||||
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
|
||||
__asm__ __volatile__( \
|
||||
__ASM_SMP_MB \
|
||||
"1: ldl_l %0,0(%2)\n" \
|
||||
insn \
|
||||
"2: stl_c %1,0(%2)\n" \
|
||||
" beq %1,4f\n" \
|
||||
" mov $31,%1\n" \
|
||||
"3: .subsection 2\n" \
|
||||
"4: br 1b\n" \
|
||||
" .previous\n" \
|
||||
EXC(1b,3b,$31,%1) \
|
||||
EXC(2b,3b,$31,%1) \
|
||||
: "=&r" (oldval), "=&r"(ret) \
|
||||
: "r" (uaddr), "r"(oparg) \
|
||||
: "memory")
|
||||
|
||||
static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
|
||||
u32 __user *uaddr)
|
||||
{
|
||||
int oldval = 0, ret;
|
||||
|
||||
if (!access_ok(uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
switch (op) {
|
||||
case FUTEX_OP_SET:
|
||||
__futex_atomic_op("mov %3,%1\n", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_ADD:
|
||||
__futex_atomic_op("addl %0,%3,%1\n", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_OR:
|
||||
__futex_atomic_op("or %0,%3,%1\n", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_ANDN:
|
||||
__futex_atomic_op("andnot %0,%3,%1\n", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_XOR:
|
||||
__futex_atomic_op("xor %0,%3,%1\n", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int
|
||||
futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
|
||||
u32 oldval, u32 newval)
|
||||
{
|
||||
int ret = 0, cmp;
|
||||
u32 prev;
|
||||
|
||||
if (!access_ok(uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
__ASM_SMP_MB
|
||||
"1: ldl_l %1,0(%3)\n"
|
||||
" cmpeq %1,%4,%2\n"
|
||||
" beq %2,3f\n"
|
||||
" mov %5,%2\n"
|
||||
"2: stl_c %2,0(%3)\n"
|
||||
" beq %2,4f\n"
|
||||
"3: .subsection 2\n"
|
||||
"4: br 1b\n"
|
||||
" .previous\n"
|
||||
EXC(1b,3b,$31,%0)
|
||||
EXC(2b,3b,$31,%0)
|
||||
: "+r"(ret), "=&r"(prev), "=&r"(cmp)
|
||||
: "r"(uaddr), "r"((long)(int)oldval), "r"(newval)
|
||||
: "memory");
|
||||
|
||||
*uval = prev;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_ALPHA_FUTEX_H */
|
59
arch/alpha/include/asm/gct.h
Normal file
59
arch/alpha/include/asm/gct.h
Normal file
@ -0,0 +1,59 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_GCT_H
|
||||
#define __ALPHA_GCT_H
|
||||
|
||||
typedef u64 gct_id;
|
||||
typedef u64 gct6_handle;
|
||||
|
||||
typedef struct __gct6_node {
|
||||
u8 type;
|
||||
u8 subtype;
|
||||
u16 size;
|
||||
u32 hd_extension;
|
||||
gct6_handle owner;
|
||||
gct6_handle active_user;
|
||||
gct_id id;
|
||||
u64 flags;
|
||||
u16 rev;
|
||||
u16 change_counter;
|
||||
u16 max_child;
|
||||
u16 reserved1;
|
||||
gct6_handle saved_owner;
|
||||
gct6_handle affinity;
|
||||
gct6_handle parent;
|
||||
gct6_handle next;
|
||||
gct6_handle prev;
|
||||
gct6_handle child;
|
||||
u64 fw_flags;
|
||||
u64 os_usage;
|
||||
u64 fru_id;
|
||||
u32 checksum;
|
||||
u32 magic; /* 'GLXY' */
|
||||
} gct6_node;
|
||||
|
||||
typedef struct {
|
||||
u8 type;
|
||||
u8 subtype;
|
||||
void (*callout)(gct6_node *);
|
||||
} gct6_search_struct;
|
||||
|
||||
#define GCT_NODE_MAGIC 0x59584c47 /* 'GLXY' */
|
||||
|
||||
/*
|
||||
* node types
|
||||
*/
|
||||
#define GCT_TYPE_HOSE 0x0E
|
||||
|
||||
/*
|
||||
* node subtypes
|
||||
*/
|
||||
#define GCT_SUBTYPE_IO_PORT_MODULE 0x2C
|
||||
|
||||
#define GCT_NODE_PTR(off) ((gct6_node *)((char *)hwrpb + \
|
||||
hwrpb->frut_offset + \
|
||||
(gct6_handle)(off))) \
|
||||
|
||||
int gct6_find_nodes(gct6_node *, gct6_search_struct *);
|
||||
|
||||
#endif /* __ALPHA_GCT_H */
|
||||
|
10
arch/alpha/include/asm/hardirq.h
Normal file
10
arch/alpha/include/asm/hardirq.h
Normal file
@ -0,0 +1,10 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ALPHA_HARDIRQ_H
|
||||
#define _ALPHA_HARDIRQ_H
|
||||
|
||||
void ack_bad_irq(unsigned int irq);
|
||||
#define ack_bad_irq ack_bad_irq
|
||||
|
||||
#include <asm-generic/hardirq.h>
|
||||
|
||||
#endif /* _ALPHA_HARDIRQ_H */
|
15
arch/alpha/include/asm/hw_irq.h
Normal file
15
arch/alpha/include/asm/hw_irq.h
Normal file
@ -0,0 +1,15 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ALPHA_HW_IRQ_H
|
||||
#define _ALPHA_HW_IRQ_H
|
||||
|
||||
|
||||
extern volatile unsigned long irq_err_count;
|
||||
DECLARE_PER_CPU(unsigned long, irq_pmi_count);
|
||||
|
||||
#ifdef CONFIG_ALPHA_GENERIC
|
||||
#define ACTUAL_NR_IRQS alpha_mv.nr_irqs
|
||||
#else
|
||||
#define ACTUAL_NR_IRQS NR_IRQS
|
||||
#endif
|
||||
|
||||
#endif
|
221
arch/alpha/include/asm/hwrpb.h
Normal file
221
arch/alpha/include/asm/hwrpb.h
Normal file
@ -0,0 +1,221 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_HWRPB_H
|
||||
#define __ALPHA_HWRPB_H
|
||||
|
||||
#define INIT_HWRPB ((struct hwrpb_struct *) 0x10000000)
|
||||
|
||||
/*
|
||||
* DEC processor types for Alpha systems. Found in HWRPB.
|
||||
* These values are architected.
|
||||
*/
|
||||
|
||||
#define EV3_CPU 1 /* EV3 */
|
||||
#define EV4_CPU 2 /* EV4 (21064) */
|
||||
#define LCA4_CPU 4 /* LCA4 (21066/21068) */
|
||||
#define EV5_CPU 5 /* EV5 (21164) */
|
||||
#define EV45_CPU 6 /* EV4.5 (21064/xxx) */
|
||||
#define EV56_CPU 7 /* EV5.6 (21164) */
|
||||
#define EV6_CPU 8 /* EV6 (21264) */
|
||||
#define PCA56_CPU 9 /* PCA56 (21164PC) */
|
||||
#define PCA57_CPU 10 /* PCA57 (notyet) */
|
||||
#define EV67_CPU 11 /* EV67 (21264A) */
|
||||
#define EV68CB_CPU 12 /* EV68CB (21264C) */
|
||||
#define EV68AL_CPU 13 /* EV68AL (21264B) */
|
||||
#define EV68CX_CPU 14 /* EV68CX (21264D) */
|
||||
#define EV7_CPU 15 /* EV7 (21364) */
|
||||
#define EV79_CPU 16 /* EV79 (21364??) */
|
||||
#define EV69_CPU 17 /* EV69 (21264/EV69A) */
|
||||
|
||||
/*
|
||||
* DEC system types for Alpha systems. Found in HWRPB.
|
||||
* These values are architected.
|
||||
*/
|
||||
|
||||
#define ST_ADU 1 /* Alpha ADU systype */
|
||||
#define ST_DEC_4000 2 /* Cobra systype */
|
||||
#define ST_DEC_7000 3 /* Ruby systype */
|
||||
#define ST_DEC_3000_500 4 /* Flamingo systype */
|
||||
#define ST_DEC_2000_300 6 /* Jensen systype */
|
||||
#define ST_DEC_3000_300 7 /* Pelican systype */
|
||||
#define ST_DEC_2100_A500 9 /* Sable systype */
|
||||
#define ST_DEC_AXPVME_64 10 /* AXPvme system type */
|
||||
#define ST_DEC_AXPPCI_33 11 /* NoName system type */
|
||||
#define ST_DEC_TLASER 12 /* Turbolaser systype */
|
||||
#define ST_DEC_2100_A50 13 /* Avanti systype */
|
||||
#define ST_DEC_MUSTANG 14 /* Mustang systype */
|
||||
#define ST_DEC_ALCOR 15 /* Alcor (EV5) systype */
|
||||
#define ST_DEC_1000 17 /* Mikasa systype */
|
||||
#define ST_DEC_EB64 18 /* EB64 systype */
|
||||
#define ST_DEC_EB66 19 /* EB66 systype */
|
||||
#define ST_DEC_EB64P 20 /* EB64+ systype */
|
||||
#define ST_DEC_BURNS 21 /* laptop systype */
|
||||
#define ST_DEC_RAWHIDE 22 /* Rawhide systype */
|
||||
#define ST_DEC_K2 23 /* K2 systype */
|
||||
#define ST_DEC_LYNX 24 /* Lynx systype */
|
||||
#define ST_DEC_XL 25 /* Alpha XL systype */
|
||||
#define ST_DEC_EB164 26 /* EB164 systype */
|
||||
#define ST_DEC_NORITAKE 27 /* Noritake systype */
|
||||
#define ST_DEC_CORTEX 28 /* Cortex systype */
|
||||
#define ST_DEC_MIATA 30 /* Miata systype */
|
||||
#define ST_DEC_XXM 31 /* XXM systype */
|
||||
#define ST_DEC_TAKARA 32 /* Takara systype */
|
||||
#define ST_DEC_YUKON 33 /* Yukon systype */
|
||||
#define ST_DEC_TSUNAMI 34 /* Tsunami systype */
|
||||
#define ST_DEC_WILDFIRE 35 /* Wildfire systype */
|
||||
#define ST_DEC_CUSCO 36 /* CUSCO systype */
|
||||
#define ST_DEC_EIGER 37 /* Eiger systype */
|
||||
#define ST_DEC_TITAN 38 /* Titan systype */
|
||||
#define ST_DEC_MARVEL 39 /* Marvel systype */
|
||||
|
||||
/* UNOFFICIAL!!! */
|
||||
#define ST_UNOFFICIAL_BIAS 100
|
||||
#define ST_DTI_RUFFIAN 101 /* RUFFIAN systype */
|
||||
|
||||
/* Alpha Processor, Inc. systems */
|
||||
#define ST_API_BIAS 200
|
||||
#define ST_API_NAUTILUS 201 /* UP1000 systype */
|
||||
|
||||
struct pcb_struct {
|
||||
unsigned long ksp;
|
||||
unsigned long usp;
|
||||
unsigned long ptbr;
|
||||
unsigned int pcc;
|
||||
unsigned int asn;
|
||||
unsigned long unique;
|
||||
unsigned long flags;
|
||||
unsigned long res1, res2;
|
||||
};
|
||||
|
||||
struct percpu_struct {
|
||||
unsigned long hwpcb[16];
|
||||
unsigned long flags;
|
||||
unsigned long pal_mem_size;
|
||||
unsigned long pal_scratch_size;
|
||||
unsigned long pal_mem_pa;
|
||||
unsigned long pal_scratch_pa;
|
||||
unsigned long pal_revision;
|
||||
unsigned long type;
|
||||
unsigned long variation;
|
||||
unsigned long revision;
|
||||
unsigned long serial_no[2];
|
||||
unsigned long logout_area_pa;
|
||||
unsigned long logout_area_len;
|
||||
unsigned long halt_PCBB;
|
||||
unsigned long halt_PC;
|
||||
unsigned long halt_PS;
|
||||
unsigned long halt_arg;
|
||||
unsigned long halt_ra;
|
||||
unsigned long halt_pv;
|
||||
unsigned long halt_reason;
|
||||
unsigned long res;
|
||||
unsigned long ipc_buffer[21];
|
||||
unsigned long palcode_avail[16];
|
||||
unsigned long compatibility;
|
||||
unsigned long console_data_log_pa;
|
||||
unsigned long console_data_log_length;
|
||||
unsigned long bcache_info;
|
||||
};
|
||||
|
||||
struct procdesc_struct {
|
||||
unsigned long weird_vms_stuff;
|
||||
unsigned long address;
|
||||
};
|
||||
|
||||
struct vf_map_struct {
|
||||
unsigned long va;
|
||||
unsigned long pa;
|
||||
unsigned long count;
|
||||
};
|
||||
|
||||
struct crb_struct {
|
||||
struct procdesc_struct * dispatch_va;
|
||||
struct procdesc_struct * dispatch_pa;
|
||||
struct procdesc_struct * fixup_va;
|
||||
struct procdesc_struct * fixup_pa;
|
||||
/* virtual->physical map */
|
||||
unsigned long map_entries;
|
||||
unsigned long map_pages;
|
||||
struct vf_map_struct map[1];
|
||||
};
|
||||
|
||||
struct memclust_struct {
|
||||
unsigned long start_pfn;
|
||||
unsigned long numpages;
|
||||
unsigned long numtested;
|
||||
unsigned long bitmap_va;
|
||||
unsigned long bitmap_pa;
|
||||
unsigned long bitmap_chksum;
|
||||
unsigned long usage;
|
||||
};
|
||||
|
||||
struct memdesc_struct {
|
||||
unsigned long chksum;
|
||||
unsigned long optional_pa;
|
||||
unsigned long numclusters;
|
||||
struct memclust_struct cluster[0];
|
||||
};
|
||||
|
||||
struct dsr_struct {
|
||||
long smm; /* SMM nubber used by LMF */
|
||||
unsigned long lurt_off; /* offset to LURT table */
|
||||
unsigned long sysname_off; /* offset to sysname char count */
|
||||
};
|
||||
|
||||
struct hwrpb_struct {
|
||||
unsigned long phys_addr; /* check: physical address of the hwrpb */
|
||||
unsigned long id; /* check: "HWRPB\0\0\0" */
|
||||
unsigned long revision;
|
||||
unsigned long size; /* size of hwrpb */
|
||||
unsigned long cpuid;
|
||||
unsigned long pagesize; /* 8192, I hope */
|
||||
unsigned long pa_bits; /* number of physical address bits */
|
||||
unsigned long max_asn;
|
||||
unsigned char ssn[16]; /* system serial number: big bother is watching */
|
||||
unsigned long sys_type;
|
||||
unsigned long sys_variation;
|
||||
unsigned long sys_revision;
|
||||
unsigned long intr_freq; /* interval clock frequency * 4096 */
|
||||
unsigned long cycle_freq; /* cycle counter frequency */
|
||||
unsigned long vptb; /* Virtual Page Table Base address */
|
||||
unsigned long res1;
|
||||
unsigned long tbhb_offset; /* Translation Buffer Hint Block */
|
||||
unsigned long nr_processors;
|
||||
unsigned long processor_size;
|
||||
unsigned long processor_offset;
|
||||
unsigned long ctb_nr;
|
||||
unsigned long ctb_size; /* console terminal block size */
|
||||
unsigned long ctbt_offset; /* console terminal block table offset */
|
||||
unsigned long crb_offset; /* console callback routine block */
|
||||
unsigned long mddt_offset; /* memory data descriptor table */
|
||||
unsigned long cdb_offset; /* configuration data block (or NULL) */
|
||||
unsigned long frut_offset; /* FRU table (or NULL) */
|
||||
void (*save_terminal)(unsigned long);
|
||||
unsigned long save_terminal_data;
|
||||
void (*restore_terminal)(unsigned long);
|
||||
unsigned long restore_terminal_data;
|
||||
void (*CPU_restart)(unsigned long);
|
||||
unsigned long CPU_restart_data;
|
||||
unsigned long res2;
|
||||
unsigned long res3;
|
||||
unsigned long chksum;
|
||||
unsigned long rxrdy;
|
||||
unsigned long txrdy;
|
||||
unsigned long dsr_offset; /* "Dynamic System Recognition Data Block Table" */
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
extern struct hwrpb_struct *hwrpb;
|
||||
|
||||
static inline void
|
||||
hwrpb_update_checksum(struct hwrpb_struct *h)
|
||||
{
|
||||
unsigned long sum = 0, *l;
|
||||
for (l = (unsigned long *) h; l < (unsigned long *) &h->chksum; ++l)
|
||||
sum += *l;
|
||||
h->chksum = sum;
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ALPHA_HWRPB_H */
|
607
arch/alpha/include/asm/io.h
Normal file
607
arch/alpha/include/asm/io.h
Normal file
@ -0,0 +1,607 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_IO_H
|
||||
#define __ALPHA_IO_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/compiler.h>
|
||||
#include <asm/machvec.h>
|
||||
#include <asm/hwrpb.h>
|
||||
|
||||
/* The generic header contains only prototypes. Including it ensures that
|
||||
the implementation we have here matches that interface. */
|
||||
#include <asm-generic/iomap.h>
|
||||
|
||||
/* We don't use IO slowdowns on the Alpha, but.. */
|
||||
#define __SLOW_DOWN_IO do { } while (0)
|
||||
#define SLOW_DOWN_IO do { } while (0)
|
||||
|
||||
/*
|
||||
* Virtual -> physical identity mapping starts at this offset
|
||||
*/
|
||||
#ifdef USE_48_BIT_KSEG
|
||||
#define IDENT_ADDR 0xffff800000000000UL
|
||||
#else
|
||||
#define IDENT_ADDR 0xfffffc0000000000UL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We try to avoid hae updates (thus the cache), but when we
|
||||
* do need to update the hae, we need to do it atomically, so
|
||||
* that any interrupts wouldn't get confused with the hae
|
||||
* register not being up-to-date with respect to the hardware
|
||||
* value.
|
||||
*/
|
||||
extern inline void __set_hae(unsigned long new_hae)
|
||||
{
|
||||
unsigned long flags = swpipl(IPL_MAX);
|
||||
|
||||
barrier();
|
||||
|
||||
alpha_mv.hae_cache = new_hae;
|
||||
*alpha_mv.hae_register = new_hae;
|
||||
mb();
|
||||
/* Re-read to make sure it was written. */
|
||||
new_hae = *alpha_mv.hae_register;
|
||||
|
||||
setipl(flags);
|
||||
barrier();
|
||||
}
|
||||
|
||||
extern inline void set_hae(unsigned long new_hae)
|
||||
{
|
||||
if (new_hae != alpha_mv.hae_cache)
|
||||
__set_hae(new_hae);
|
||||
}
|
||||
|
||||
/*
|
||||
* Change virtual addresses to physical addresses and vv.
|
||||
*/
|
||||
#ifdef USE_48_BIT_KSEG
|
||||
static inline unsigned long virt_to_phys(volatile void *address)
|
||||
{
|
||||
return (unsigned long)address - IDENT_ADDR;
|
||||
}
|
||||
|
||||
static inline void * phys_to_virt(unsigned long address)
|
||||
{
|
||||
return (void *) (address + IDENT_ADDR);
|
||||
}
|
||||
#else
|
||||
static inline unsigned long virt_to_phys(volatile void *address)
|
||||
{
|
||||
unsigned long phys = (unsigned long)address;
|
||||
|
||||
/* Sign-extend from bit 41. */
|
||||
phys <<= (64 - 41);
|
||||
phys = (long)phys >> (64 - 41);
|
||||
|
||||
/* Crop to the physical address width of the processor. */
|
||||
phys &= (1ul << hwrpb->pa_bits) - 1;
|
||||
|
||||
return phys;
|
||||
}
|
||||
|
||||
static inline void * phys_to_virt(unsigned long address)
|
||||
{
|
||||
return (void *)(IDENT_ADDR + (address & ((1ul << 41) - 1)));
|
||||
}
|
||||
#endif
|
||||
|
||||
#define page_to_phys(page) page_to_pa(page)
|
||||
|
||||
/* Maximum PIO space address supported? */
|
||||
#define IO_SPACE_LIMIT 0xffff
|
||||
|
||||
/*
|
||||
* Change addresses as seen by the kernel (virtual) to addresses as
|
||||
* seen by a device (bus), and vice versa.
|
||||
*
|
||||
* Note that this only works for a limited range of kernel addresses,
|
||||
* and very well may not span all memory. Consider this interface
|
||||
* deprecated in favour of the DMA-mapping API.
|
||||
*/
|
||||
extern unsigned long __direct_map_base;
|
||||
extern unsigned long __direct_map_size;
|
||||
|
||||
static inline unsigned long __deprecated virt_to_bus(volatile void *address)
|
||||
{
|
||||
unsigned long phys = virt_to_phys(address);
|
||||
unsigned long bus = phys + __direct_map_base;
|
||||
return phys <= __direct_map_size ? bus : 0;
|
||||
}
|
||||
#define isa_virt_to_bus virt_to_bus
|
||||
|
||||
static inline void * __deprecated bus_to_virt(unsigned long address)
|
||||
{
|
||||
void *virt;
|
||||
|
||||
/* This check is a sanity check but also ensures that bus address 0
|
||||
maps to virtual address 0 which is useful to detect null pointers
|
||||
(the NCR driver is much simpler if NULL pointers are preserved). */
|
||||
address -= __direct_map_base;
|
||||
virt = phys_to_virt(address);
|
||||
return (long)address <= 0 ? NULL : virt;
|
||||
}
|
||||
#define isa_bus_to_virt bus_to_virt
|
||||
|
||||
/*
|
||||
* There are different chipsets to interface the Alpha CPUs to the world.
|
||||
*/
|
||||
|
||||
#define IO_CONCAT(a,b) _IO_CONCAT(a,b)
|
||||
#define _IO_CONCAT(a,b) a ## _ ## b
|
||||
|
||||
#ifdef CONFIG_ALPHA_GENERIC
|
||||
|
||||
/* In a generic kernel, we always go through the machine vector. */
|
||||
|
||||
#define REMAP1(TYPE, NAME, QUAL) \
|
||||
static inline TYPE generic_##NAME(QUAL void __iomem *addr) \
|
||||
{ \
|
||||
return alpha_mv.mv_##NAME(addr); \
|
||||
}
|
||||
|
||||
#define REMAP2(TYPE, NAME, QUAL) \
|
||||
static inline void generic_##NAME(TYPE b, QUAL void __iomem *addr) \
|
||||
{ \
|
||||
alpha_mv.mv_##NAME(b, addr); \
|
||||
}
|
||||
|
||||
REMAP1(unsigned int, ioread8, const)
|
||||
REMAP1(unsigned int, ioread16, const)
|
||||
REMAP1(unsigned int, ioread32, const)
|
||||
REMAP1(u8, readb, const volatile)
|
||||
REMAP1(u16, readw, const volatile)
|
||||
REMAP1(u32, readl, const volatile)
|
||||
REMAP1(u64, readq, const volatile)
|
||||
|
||||
REMAP2(u8, iowrite8, /**/)
|
||||
REMAP2(u16, iowrite16, /**/)
|
||||
REMAP2(u32, iowrite32, /**/)
|
||||
REMAP2(u8, writeb, volatile)
|
||||
REMAP2(u16, writew, volatile)
|
||||
REMAP2(u32, writel, volatile)
|
||||
REMAP2(u64, writeq, volatile)
|
||||
|
||||
#undef REMAP1
|
||||
#undef REMAP2
|
||||
|
||||
extern inline void __iomem *generic_ioportmap(unsigned long a)
|
||||
{
|
||||
return alpha_mv.mv_ioportmap(a);
|
||||
}
|
||||
|
||||
static inline void __iomem *generic_ioremap(unsigned long a, unsigned long s)
|
||||
{
|
||||
return alpha_mv.mv_ioremap(a, s);
|
||||
}
|
||||
|
||||
static inline void generic_iounmap(volatile void __iomem *a)
|
||||
{
|
||||
return alpha_mv.mv_iounmap(a);
|
||||
}
|
||||
|
||||
static inline int generic_is_ioaddr(unsigned long a)
|
||||
{
|
||||
return alpha_mv.mv_is_ioaddr(a);
|
||||
}
|
||||
|
||||
static inline int generic_is_mmio(const volatile void __iomem *a)
|
||||
{
|
||||
return alpha_mv.mv_is_mmio(a);
|
||||
}
|
||||
|
||||
#define __IO_PREFIX generic
|
||||
#define generic_trivial_rw_bw 0
|
||||
#define generic_trivial_rw_lq 0
|
||||
#define generic_trivial_io_bw 0
|
||||
#define generic_trivial_io_lq 0
|
||||
#define generic_trivial_iounmap 0
|
||||
|
||||
#else
|
||||
|
||||
#if defined(CONFIG_ALPHA_APECS)
|
||||
# include <asm/core_apecs.h>
|
||||
#elif defined(CONFIG_ALPHA_CIA)
|
||||
# include <asm/core_cia.h>
|
||||
#elif defined(CONFIG_ALPHA_IRONGATE)
|
||||
# include <asm/core_irongate.h>
|
||||
#elif defined(CONFIG_ALPHA_JENSEN)
|
||||
# include <asm/jensen.h>
|
||||
#elif defined(CONFIG_ALPHA_LCA)
|
||||
# include <asm/core_lca.h>
|
||||
#elif defined(CONFIG_ALPHA_MARVEL)
|
||||
# include <asm/core_marvel.h>
|
||||
#elif defined(CONFIG_ALPHA_MCPCIA)
|
||||
# include <asm/core_mcpcia.h>
|
||||
#elif defined(CONFIG_ALPHA_POLARIS)
|
||||
# include <asm/core_polaris.h>
|
||||
#elif defined(CONFIG_ALPHA_T2)
|
||||
# include <asm/core_t2.h>
|
||||
#elif defined(CONFIG_ALPHA_TSUNAMI)
|
||||
# include <asm/core_tsunami.h>
|
||||
#elif defined(CONFIG_ALPHA_TITAN)
|
||||
# include <asm/core_titan.h>
|
||||
#elif defined(CONFIG_ALPHA_WILDFIRE)
|
||||
# include <asm/core_wildfire.h>
|
||||
#else
|
||||
#error "What system is this?"
|
||||
#endif
|
||||
|
||||
#endif /* GENERIC */
|
||||
|
||||
/*
|
||||
* We always have external versions of these routines.
|
||||
*/
|
||||
extern u8 inb(unsigned long port);
|
||||
extern u16 inw(unsigned long port);
|
||||
extern u32 inl(unsigned long port);
|
||||
extern void outb(u8 b, unsigned long port);
|
||||
extern void outw(u16 b, unsigned long port);
|
||||
extern void outl(u32 b, unsigned long port);
|
||||
|
||||
extern u8 readb(const volatile void __iomem *addr);
|
||||
extern u16 readw(const volatile void __iomem *addr);
|
||||
extern u32 readl(const volatile void __iomem *addr);
|
||||
extern u64 readq(const volatile void __iomem *addr);
|
||||
extern void writeb(u8 b, volatile void __iomem *addr);
|
||||
extern void writew(u16 b, volatile void __iomem *addr);
|
||||
extern void writel(u32 b, volatile void __iomem *addr);
|
||||
extern void writeq(u64 b, volatile void __iomem *addr);
|
||||
|
||||
extern u8 __raw_readb(const volatile void __iomem *addr);
|
||||
extern u16 __raw_readw(const volatile void __iomem *addr);
|
||||
extern u32 __raw_readl(const volatile void __iomem *addr);
|
||||
extern u64 __raw_readq(const volatile void __iomem *addr);
|
||||
extern void __raw_writeb(u8 b, volatile void __iomem *addr);
|
||||
extern void __raw_writew(u16 b, volatile void __iomem *addr);
|
||||
extern void __raw_writel(u32 b, volatile void __iomem *addr);
|
||||
extern void __raw_writeq(u64 b, volatile void __iomem *addr);
|
||||
|
||||
/*
|
||||
* Mapping from port numbers to __iomem space is pretty easy.
|
||||
*/
|
||||
|
||||
/* These two have to be extern inline because of the extern prototype from
|
||||
<asm-generic/iomap.h>. It is not legal to mix "extern" and "static" for
|
||||
the same declaration. */
|
||||
extern inline void __iomem *ioport_map(unsigned long port, unsigned int size)
|
||||
{
|
||||
return IO_CONCAT(__IO_PREFIX,ioportmap) (port);
|
||||
}
|
||||
|
||||
extern inline void ioport_unmap(void __iomem *addr)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void __iomem *ioremap(unsigned long port, unsigned long size)
|
||||
{
|
||||
return IO_CONCAT(__IO_PREFIX,ioremap) (port, size);
|
||||
}
|
||||
|
||||
#define ioremap_wc ioremap
|
||||
#define ioremap_uc ioremap
|
||||
|
||||
static inline void iounmap(volatile void __iomem *addr)
|
||||
{
|
||||
IO_CONCAT(__IO_PREFIX,iounmap)(addr);
|
||||
}
|
||||
|
||||
static inline int __is_ioaddr(unsigned long addr)
|
||||
{
|
||||
return IO_CONCAT(__IO_PREFIX,is_ioaddr)(addr);
|
||||
}
|
||||
#define __is_ioaddr(a) __is_ioaddr((unsigned long)(a))
|
||||
|
||||
static inline int __is_mmio(const volatile void __iomem *addr)
|
||||
{
|
||||
return IO_CONCAT(__IO_PREFIX,is_mmio)(addr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If the actual I/O bits are sufficiently trivial, then expand inline.
|
||||
*/
|
||||
|
||||
#if IO_CONCAT(__IO_PREFIX,trivial_io_bw)
|
||||
extern inline unsigned int ioread8(const void __iomem *addr)
|
||||
{
|
||||
unsigned int ret;
|
||||
mb();
|
||||
ret = IO_CONCAT(__IO_PREFIX,ioread8)(addr);
|
||||
mb();
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern inline unsigned int ioread16(const void __iomem *addr)
|
||||
{
|
||||
unsigned int ret;
|
||||
mb();
|
||||
ret = IO_CONCAT(__IO_PREFIX,ioread16)(addr);
|
||||
mb();
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern inline void iowrite8(u8 b, void __iomem *addr)
|
||||
{
|
||||
mb();
|
||||
IO_CONCAT(__IO_PREFIX, iowrite8)(b, addr);
|
||||
}
|
||||
|
||||
extern inline void iowrite16(u16 b, void __iomem *addr)
|
||||
{
|
||||
mb();
|
||||
IO_CONCAT(__IO_PREFIX, iowrite16)(b, addr);
|
||||
}
|
||||
|
||||
extern inline u8 inb(unsigned long port)
|
||||
{
|
||||
return ioread8(ioport_map(port, 1));
|
||||
}
|
||||
|
||||
extern inline u16 inw(unsigned long port)
|
||||
{
|
||||
return ioread16(ioport_map(port, 2));
|
||||
}
|
||||
|
||||
extern inline void outb(u8 b, unsigned long port)
|
||||
{
|
||||
iowrite8(b, ioport_map(port, 1));
|
||||
}
|
||||
|
||||
extern inline void outw(u16 b, unsigned long port)
|
||||
{
|
||||
iowrite16(b, ioport_map(port, 2));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IO_CONCAT(__IO_PREFIX,trivial_io_lq)
|
||||
extern inline unsigned int ioread32(const void __iomem *addr)
|
||||
{
|
||||
unsigned int ret;
|
||||
mb();
|
||||
ret = IO_CONCAT(__IO_PREFIX,ioread32)(addr);
|
||||
mb();
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern inline void iowrite32(u32 b, void __iomem *addr)
|
||||
{
|
||||
mb();
|
||||
IO_CONCAT(__IO_PREFIX, iowrite32)(b, addr);
|
||||
}
|
||||
|
||||
extern inline u32 inl(unsigned long port)
|
||||
{
|
||||
return ioread32(ioport_map(port, 4));
|
||||
}
|
||||
|
||||
extern inline void outl(u32 b, unsigned long port)
|
||||
{
|
||||
iowrite32(b, ioport_map(port, 4));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IO_CONCAT(__IO_PREFIX,trivial_rw_bw) == 1
|
||||
extern inline u8 __raw_readb(const volatile void __iomem *addr)
|
||||
{
|
||||
return IO_CONCAT(__IO_PREFIX,readb)(addr);
|
||||
}
|
||||
|
||||
extern inline u16 __raw_readw(const volatile void __iomem *addr)
|
||||
{
|
||||
return IO_CONCAT(__IO_PREFIX,readw)(addr);
|
||||
}
|
||||
|
||||
extern inline void __raw_writeb(u8 b, volatile void __iomem *addr)
|
||||
{
|
||||
IO_CONCAT(__IO_PREFIX,writeb)(b, addr);
|
||||
}
|
||||
|
||||
extern inline void __raw_writew(u16 b, volatile void __iomem *addr)
|
||||
{
|
||||
IO_CONCAT(__IO_PREFIX,writew)(b, addr);
|
||||
}
|
||||
|
||||
extern inline u8 readb(const volatile void __iomem *addr)
|
||||
{
|
||||
u8 ret;
|
||||
mb();
|
||||
ret = __raw_readb(addr);
|
||||
mb();
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern inline u16 readw(const volatile void __iomem *addr)
|
||||
{
|
||||
u16 ret;
|
||||
mb();
|
||||
ret = __raw_readw(addr);
|
||||
mb();
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern inline void writeb(u8 b, volatile void __iomem *addr)
|
||||
{
|
||||
mb();
|
||||
__raw_writeb(b, addr);
|
||||
}
|
||||
|
||||
extern inline void writew(u16 b, volatile void __iomem *addr)
|
||||
{
|
||||
mb();
|
||||
__raw_writew(b, addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IO_CONCAT(__IO_PREFIX,trivial_rw_lq) == 1
|
||||
extern inline u32 __raw_readl(const volatile void __iomem *addr)
|
||||
{
|
||||
return IO_CONCAT(__IO_PREFIX,readl)(addr);
|
||||
}
|
||||
|
||||
extern inline u64 __raw_readq(const volatile void __iomem *addr)
|
||||
{
|
||||
return IO_CONCAT(__IO_PREFIX,readq)(addr);
|
||||
}
|
||||
|
||||
extern inline void __raw_writel(u32 b, volatile void __iomem *addr)
|
||||
{
|
||||
IO_CONCAT(__IO_PREFIX,writel)(b, addr);
|
||||
}
|
||||
|
||||
extern inline void __raw_writeq(u64 b, volatile void __iomem *addr)
|
||||
{
|
||||
IO_CONCAT(__IO_PREFIX,writeq)(b, addr);
|
||||
}
|
||||
|
||||
extern inline u32 readl(const volatile void __iomem *addr)
|
||||
{
|
||||
u32 ret;
|
||||
mb();
|
||||
ret = __raw_readl(addr);
|
||||
mb();
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern inline u64 readq(const volatile void __iomem *addr)
|
||||
{
|
||||
u64 ret;
|
||||
mb();
|
||||
ret = __raw_readq(addr);
|
||||
mb();
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern inline void writel(u32 b, volatile void __iomem *addr)
|
||||
{
|
||||
mb();
|
||||
__raw_writel(b, addr);
|
||||
}
|
||||
|
||||
extern inline void writeq(u64 b, volatile void __iomem *addr)
|
||||
{
|
||||
mb();
|
||||
__raw_writeq(b, addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ioread16be(p) swab16(ioread16(p))
|
||||
#define ioread32be(p) swab32(ioread32(p))
|
||||
#define iowrite16be(v,p) iowrite16(swab16(v), (p))
|
||||
#define iowrite32be(v,p) iowrite32(swab32(v), (p))
|
||||
|
||||
#define inb_p inb
|
||||
#define inw_p inw
|
||||
#define inl_p inl
|
||||
#define outb_p outb
|
||||
#define outw_p outw
|
||||
#define outl_p outl
|
||||
|
||||
extern u8 readb_relaxed(const volatile void __iomem *addr);
|
||||
extern u16 readw_relaxed(const volatile void __iomem *addr);
|
||||
extern u32 readl_relaxed(const volatile void __iomem *addr);
|
||||
extern u64 readq_relaxed(const volatile void __iomem *addr);
|
||||
|
||||
#if IO_CONCAT(__IO_PREFIX,trivial_io_bw)
|
||||
extern inline u8 readb_relaxed(const volatile void __iomem *addr)
|
||||
{
|
||||
mb();
|
||||
return __raw_readb(addr);
|
||||
}
|
||||
|
||||
extern inline u16 readw_relaxed(const volatile void __iomem *addr)
|
||||
{
|
||||
mb();
|
||||
return __raw_readw(addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IO_CONCAT(__IO_PREFIX,trivial_io_lq)
|
||||
extern inline u32 readl_relaxed(const volatile void __iomem *addr)
|
||||
{
|
||||
mb();
|
||||
return __raw_readl(addr);
|
||||
}
|
||||
|
||||
extern inline u64 readq_relaxed(const volatile void __iomem *addr)
|
||||
{
|
||||
mb();
|
||||
return __raw_readq(addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define writeb_relaxed writeb
|
||||
#define writew_relaxed writew
|
||||
#define writel_relaxed writel
|
||||
#define writeq_relaxed writeq
|
||||
|
||||
/*
|
||||
* String version of IO memory access ops:
|
||||
*/
|
||||
extern void memcpy_fromio(void *, const volatile void __iomem *, long);
|
||||
extern void memcpy_toio(volatile void __iomem *, const void *, long);
|
||||
extern void _memset_c_io(volatile void __iomem *, unsigned long, long);
|
||||
|
||||
static inline void memset_io(volatile void __iomem *addr, u8 c, long len)
|
||||
{
|
||||
_memset_c_io(addr, 0x0101010101010101UL * c, len);
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_MEMSETW_IO
|
||||
static inline void memsetw_io(volatile void __iomem *addr, u16 c, long len)
|
||||
{
|
||||
_memset_c_io(addr, 0x0001000100010001UL * c, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* String versions of in/out ops:
|
||||
*/
|
||||
extern void insb (unsigned long port, void *dst, unsigned long count);
|
||||
extern void insw (unsigned long port, void *dst, unsigned long count);
|
||||
extern void insl (unsigned long port, void *dst, unsigned long count);
|
||||
extern void outsb (unsigned long port, const void *src, unsigned long count);
|
||||
extern void outsw (unsigned long port, const void *src, unsigned long count);
|
||||
extern void outsl (unsigned long port, const void *src, unsigned long count);
|
||||
|
||||
/*
|
||||
* The Alpha Jensen hardware for some rather strange reason puts
|
||||
* the RTC clock at 0x170 instead of 0x70. Probably due to some
|
||||
* misguided idea about using 0x70 for NMI stuff.
|
||||
*
|
||||
* These defines will override the defaults when doing RTC queries
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ALPHA_GENERIC
|
||||
# define RTC_PORT(x) ((x) + alpha_mv.rtc_port)
|
||||
#else
|
||||
# ifdef CONFIG_ALPHA_JENSEN
|
||||
# define RTC_PORT(x) (0x170+(x))
|
||||
# else
|
||||
# define RTC_PORT(x) (0x70 + (x))
|
||||
# endif
|
||||
#endif
|
||||
#define RTC_ALWAYS_BCD 0
|
||||
|
||||
/*
|
||||
* Some mucking forons use if[n]def writeq to check if platform has it.
|
||||
* It's a bloody bad idea and we probably want ARCH_HAS_WRITEQ for them
|
||||
* to play with; for now just use cpp anti-recursion logics and make sure
|
||||
* that damn thing is defined and expands to itself.
|
||||
*/
|
||||
|
||||
#define writeq writeq
|
||||
#define readq readq
|
||||
|
||||
/*
|
||||
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
|
||||
* access
|
||||
*/
|
||||
#define xlate_dev_mem_ptr(p) __va(p)
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ALPHA_IO_H */
|
132
arch/alpha/include/asm/io_trivial.h
Normal file
132
arch/alpha/include/asm/io_trivial.h
Normal file
@ -0,0 +1,132 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Trivial implementations of basic i/o routines. Assumes that all
|
||||
of the hard work has been done by ioremap and ioportmap, and that
|
||||
access to i/o space is linear. */
|
||||
|
||||
/* This file may be included multiple times. */
|
||||
|
||||
#if IO_CONCAT(__IO_PREFIX,trivial_io_bw)
|
||||
__EXTERN_INLINE unsigned int
|
||||
IO_CONCAT(__IO_PREFIX,ioread8)(const void __iomem *a)
|
||||
{
|
||||
return __kernel_ldbu(*(const volatile u8 __force *)a);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE unsigned int
|
||||
IO_CONCAT(__IO_PREFIX,ioread16)(const void __iomem *a)
|
||||
{
|
||||
return __kernel_ldwu(*(const volatile u16 __force *)a);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void
|
||||
IO_CONCAT(__IO_PREFIX,iowrite8)(u8 b, void __iomem *a)
|
||||
{
|
||||
__kernel_stb(b, *(volatile u8 __force *)a);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void
|
||||
IO_CONCAT(__IO_PREFIX,iowrite16)(u16 b, void __iomem *a)
|
||||
{
|
||||
__kernel_stw(b, *(volatile u16 __force *)a);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IO_CONCAT(__IO_PREFIX,trivial_io_lq)
|
||||
__EXTERN_INLINE unsigned int
|
||||
IO_CONCAT(__IO_PREFIX,ioread32)(const void __iomem *a)
|
||||
{
|
||||
return *(const volatile u32 __force *)a;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void
|
||||
IO_CONCAT(__IO_PREFIX,iowrite32)(u32 b, void __iomem *a)
|
||||
{
|
||||
*(volatile u32 __force *)a = b;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IO_CONCAT(__IO_PREFIX,trivial_rw_bw) == 1
|
||||
__EXTERN_INLINE u8
|
||||
IO_CONCAT(__IO_PREFIX,readb)(const volatile void __iomem *a)
|
||||
{
|
||||
return __kernel_ldbu(*(const volatile u8 __force *)a);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE u16
|
||||
IO_CONCAT(__IO_PREFIX,readw)(const volatile void __iomem *a)
|
||||
{
|
||||
return __kernel_ldwu(*(const volatile u16 __force *)a);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void
|
||||
IO_CONCAT(__IO_PREFIX,writeb)(u8 b, volatile void __iomem *a)
|
||||
{
|
||||
__kernel_stb(b, *(volatile u8 __force *)a);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void
|
||||
IO_CONCAT(__IO_PREFIX,writew)(u16 b, volatile void __iomem *a)
|
||||
{
|
||||
__kernel_stw(b, *(volatile u16 __force *)a);
|
||||
}
|
||||
#elif IO_CONCAT(__IO_PREFIX,trivial_rw_bw) == 2
|
||||
__EXTERN_INLINE u8
|
||||
IO_CONCAT(__IO_PREFIX,readb)(const volatile void __iomem *a)
|
||||
{
|
||||
const void __iomem *addr = (const void __iomem *)a;
|
||||
return IO_CONCAT(__IO_PREFIX,ioread8)(addr);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE u16
|
||||
IO_CONCAT(__IO_PREFIX,readw)(const volatile void __iomem *a)
|
||||
{
|
||||
const void __iomem *addr = (const void __iomem *)a;
|
||||
return IO_CONCAT(__IO_PREFIX,ioread16)(addr);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void
|
||||
IO_CONCAT(__IO_PREFIX,writeb)(u8 b, volatile void __iomem *a)
|
||||
{
|
||||
void __iomem *addr = (void __iomem *)a;
|
||||
IO_CONCAT(__IO_PREFIX,iowrite8)(b, addr);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void
|
||||
IO_CONCAT(__IO_PREFIX,writew)(u16 b, volatile void __iomem *a)
|
||||
{
|
||||
void __iomem *addr = (void __iomem *)a;
|
||||
IO_CONCAT(__IO_PREFIX,iowrite16)(b, addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IO_CONCAT(__IO_PREFIX,trivial_rw_lq) == 1
|
||||
__EXTERN_INLINE u32
|
||||
IO_CONCAT(__IO_PREFIX,readl)(const volatile void __iomem *a)
|
||||
{
|
||||
return *(const volatile u32 __force *)a;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE u64
|
||||
IO_CONCAT(__IO_PREFIX,readq)(const volatile void __iomem *a)
|
||||
{
|
||||
return *(const volatile u64 __force *)a;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void
|
||||
IO_CONCAT(__IO_PREFIX,writel)(u32 b, volatile void __iomem *a)
|
||||
{
|
||||
*(volatile u32 __force *)a = b;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void
|
||||
IO_CONCAT(__IO_PREFIX,writeq)(u64 b, volatile void __iomem *a)
|
||||
{
|
||||
*(volatile u64 __force *)a = b;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IO_CONCAT(__IO_PREFIX,trivial_iounmap)
|
||||
__EXTERN_INLINE void IO_CONCAT(__IO_PREFIX,iounmap)(volatile void __iomem *a)
|
||||
{
|
||||
}
|
||||
#endif
|
92
arch/alpha/include/asm/irq.h
Normal file
92
arch/alpha/include/asm/irq.h
Normal file
@ -0,0 +1,92 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ALPHA_IRQ_H
|
||||
#define _ALPHA_IRQ_H
|
||||
|
||||
/*
|
||||
* linux/include/alpha/irq.h
|
||||
*
|
||||
* (C) 1994 Linus Torvalds
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#if defined(CONFIG_ALPHA_GENERIC)
|
||||
|
||||
/* Here NR_IRQS is not exact, but rather an upper bound. This is used
|
||||
many places throughout the kernel to size static arrays. That's ok,
|
||||
we'll use alpha_mv.nr_irqs when we want the real thing. */
|
||||
|
||||
/* When LEGACY_START_ADDRESS is selected, we leave out:
|
||||
TITAN
|
||||
WILDFIRE
|
||||
MARVEL
|
||||
|
||||
This helps keep the kernel object size reasonable for the majority
|
||||
of machines.
|
||||
*/
|
||||
|
||||
# if defined(CONFIG_ALPHA_LEGACY_START_ADDRESS)
|
||||
# define NR_IRQS (128) /* max is RAWHIDE/TAKARA */
|
||||
# else
|
||||
# define NR_IRQS (32768 + 16) /* marvel - 32 pids */
|
||||
# endif
|
||||
|
||||
#elif defined(CONFIG_ALPHA_CABRIOLET) || \
|
||||
defined(CONFIG_ALPHA_EB66P) || \
|
||||
defined(CONFIG_ALPHA_EB164) || \
|
||||
defined(CONFIG_ALPHA_PC164) || \
|
||||
defined(CONFIG_ALPHA_LX164)
|
||||
# define NR_IRQS 35
|
||||
|
||||
#elif defined(CONFIG_ALPHA_EB66) || \
|
||||
defined(CONFIG_ALPHA_EB64P) || \
|
||||
defined(CONFIG_ALPHA_MIKASA)
|
||||
# define NR_IRQS 32
|
||||
|
||||
#elif defined(CONFIG_ALPHA_ALCOR) || \
|
||||
defined(CONFIG_ALPHA_MIATA) || \
|
||||
defined(CONFIG_ALPHA_RUFFIAN) || \
|
||||
defined(CONFIG_ALPHA_RX164) || \
|
||||
defined(CONFIG_ALPHA_NORITAKE)
|
||||
# define NR_IRQS 48
|
||||
|
||||
#elif defined(CONFIG_ALPHA_SABLE) || \
|
||||
defined(CONFIG_ALPHA_SX164)
|
||||
# define NR_IRQS 40
|
||||
|
||||
#elif defined(CONFIG_ALPHA_DP264) || \
|
||||
defined(CONFIG_ALPHA_LYNX) || \
|
||||
defined(CONFIG_ALPHA_SHARK)
|
||||
# define NR_IRQS 64
|
||||
|
||||
#elif defined(CONFIG_ALPHA_TITAN)
|
||||
#define NR_IRQS 80
|
||||
|
||||
#elif defined(CONFIG_ALPHA_RAWHIDE) || \
|
||||
defined(CONFIG_ALPHA_TAKARA) || \
|
||||
defined(CONFIG_ALPHA_EIGER)
|
||||
# define NR_IRQS 128
|
||||
|
||||
#elif defined(CONFIG_ALPHA_WILDFIRE)
|
||||
# define NR_IRQS 2048 /* enuff for 8 QBBs */
|
||||
|
||||
#elif defined(CONFIG_ALPHA_MARVEL)
|
||||
# define NR_IRQS (32768 + 16) /* marvel - 32 pids*/
|
||||
|
||||
#else /* everyone else */
|
||||
# define NR_IRQS 16
|
||||
#endif
|
||||
|
||||
static __inline__ int irq_canonicalize(int irq)
|
||||
{
|
||||
/*
|
||||
* XXX is this true for all Alpha's? The old serial driver
|
||||
* did it this way for years without any complaints, so....
|
||||
*/
|
||||
return ((irq == 2) ? 9 : irq);
|
||||
}
|
||||
|
||||
struct pt_regs;
|
||||
extern void (*perf_irq)(unsigned long, struct pt_regs *);
|
||||
|
||||
#endif /* _ALPHA_IRQ_H */
|
1
arch/alpha/include/asm/irq_regs.h
Normal file
1
arch/alpha/include/asm/irq_regs.h
Normal file
@ -0,0 +1 @@
|
||||
#include <asm-generic/irq_regs.h>
|
68
arch/alpha/include/asm/irqflags.h
Normal file
68
arch/alpha/include/asm/irqflags.h
Normal file
@ -0,0 +1,68 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_IRQFLAGS_H
|
||||
#define __ALPHA_IRQFLAGS_H
|
||||
|
||||
#include <asm/pal.h>
|
||||
|
||||
#define IPL_MIN 0
|
||||
#define IPL_SW0 1
|
||||
#define IPL_SW1 2
|
||||
#define IPL_DEV0 3
|
||||
#define IPL_DEV1 4
|
||||
#define IPL_TIMER 5
|
||||
#define IPL_PERF 6
|
||||
#define IPL_POWERFAIL 6
|
||||
#define IPL_MCHECK 7
|
||||
#define IPL_MAX 7
|
||||
|
||||
#ifdef CONFIG_ALPHA_BROKEN_IRQ_MASK
|
||||
#undef IPL_MIN
|
||||
#define IPL_MIN __min_ipl
|
||||
extern int __min_ipl;
|
||||
#endif
|
||||
|
||||
#define getipl() (rdps() & 7)
|
||||
#define setipl(ipl) ((void) swpipl(ipl))
|
||||
|
||||
static inline unsigned long arch_local_save_flags(void)
|
||||
{
|
||||
return rdps();
|
||||
}
|
||||
|
||||
static inline void arch_local_irq_disable(void)
|
||||
{
|
||||
setipl(IPL_MAX);
|
||||
barrier();
|
||||
}
|
||||
|
||||
static inline unsigned long arch_local_irq_save(void)
|
||||
{
|
||||
unsigned long flags = swpipl(IPL_MAX);
|
||||
barrier();
|
||||
return flags;
|
||||
}
|
||||
|
||||
static inline void arch_local_irq_enable(void)
|
||||
{
|
||||
barrier();
|
||||
setipl(IPL_MIN);
|
||||
}
|
||||
|
||||
static inline void arch_local_irq_restore(unsigned long flags)
|
||||
{
|
||||
barrier();
|
||||
setipl(flags);
|
||||
barrier();
|
||||
}
|
||||
|
||||
static inline bool arch_irqs_disabled_flags(unsigned long flags)
|
||||
{
|
||||
return flags == IPL_MAX;
|
||||
}
|
||||
|
||||
static inline bool arch_irqs_disabled(void)
|
||||
{
|
||||
return arch_irqs_disabled_flags(getipl());
|
||||
}
|
||||
|
||||
#endif /* __ALPHA_IRQFLAGS_H */
|
347
arch/alpha/include/asm/jensen.h
Normal file
347
arch/alpha/include/asm/jensen.h
Normal file
@ -0,0 +1,347 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_JENSEN_H
|
||||
#define __ALPHA_JENSEN_H
|
||||
|
||||
#include <asm/compiler.h>
|
||||
|
||||
/*
|
||||
* Defines for the AlphaPC EISA IO and memory address space.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE! The memory operations do not set any memory barriers, as it's
|
||||
* not needed for cases like a frame buffer that is essentially memory-like.
|
||||
* You need to do them by hand if the operations depend on ordering.
|
||||
*
|
||||
* Similarly, the port IO operations do a "mb" only after a write operation:
|
||||
* if an mb is needed before (as in the case of doing memory mapped IO
|
||||
* first, and then a port IO operation to the same device), it needs to be
|
||||
* done by hand.
|
||||
*
|
||||
* After the above has bitten me 100 times, I'll give up and just do the
|
||||
* mb all the time, but right now I'm hoping this will work out. Avoiding
|
||||
* mb's may potentially be a noticeable speed improvement, but I can't
|
||||
* honestly say I've tested it.
|
||||
*
|
||||
* Handling interrupts that need to do mb's to synchronize to non-interrupts
|
||||
* is another fun race area. Don't do it (because if you do, I'll have to
|
||||
* do *everything* with interrupts disabled, ugh).
|
||||
*/
|
||||
|
||||
/*
|
||||
* EISA Interrupt Acknowledge address
|
||||
*/
|
||||
#define EISA_INTA (IDENT_ADDR + 0x100000000UL)
|
||||
|
||||
/*
|
||||
* FEPROM addresses
|
||||
*/
|
||||
#define EISA_FEPROM0 (IDENT_ADDR + 0x180000000UL)
|
||||
#define EISA_FEPROM1 (IDENT_ADDR + 0x1A0000000UL)
|
||||
|
||||
/*
|
||||
* VL82C106 base address
|
||||
*/
|
||||
#define EISA_VL82C106 (IDENT_ADDR + 0x1C0000000UL)
|
||||
|
||||
/*
|
||||
* EISA "Host Address Extension" address (bits 25-31 of the EISA address)
|
||||
*/
|
||||
#define EISA_HAE (IDENT_ADDR + 0x1D0000000UL)
|
||||
|
||||
/*
|
||||
* "SYSCTL" register address
|
||||
*/
|
||||
#define EISA_SYSCTL (IDENT_ADDR + 0x1E0000000UL)
|
||||
|
||||
/*
|
||||
* "spare" register address
|
||||
*/
|
||||
#define EISA_SPARE (IDENT_ADDR + 0x1F0000000UL)
|
||||
|
||||
/*
|
||||
* EISA memory address offset
|
||||
*/
|
||||
#define EISA_MEM (IDENT_ADDR + 0x200000000UL)
|
||||
|
||||
/*
|
||||
* EISA IO address offset
|
||||
*/
|
||||
#define EISA_IO (IDENT_ADDR + 0x300000000UL)
|
||||
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef __EXTERN_INLINE
|
||||
#define __EXTERN_INLINE extern inline
|
||||
#define __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Handle the "host address register". This needs to be set
|
||||
* to the high 7 bits of the EISA address. This is also needed
|
||||
* for EISA IO addresses, which are only 16 bits wide (the
|
||||
* hae needs to be set to 0).
|
||||
*
|
||||
* HAE isn't needed for the local IO operations, though.
|
||||
*/
|
||||
|
||||
#define JENSEN_HAE_ADDRESS EISA_HAE
|
||||
#define JENSEN_HAE_MASK 0x1ffffff
|
||||
|
||||
__EXTERN_INLINE void jensen_set_hae(unsigned long addr)
|
||||
{
|
||||
/* hae on the Jensen is bits 31:25 shifted right */
|
||||
addr >>= 25;
|
||||
if (addr != alpha_mv.hae_cache)
|
||||
set_hae(addr);
|
||||
}
|
||||
|
||||
#define vuip volatile unsigned int *
|
||||
|
||||
/*
|
||||
* IO functions
|
||||
*
|
||||
* The "local" functions are those that don't go out to the EISA bus,
|
||||
* but instead act on the VL82C106 chip directly.. This is mainly the
|
||||
* keyboard, RTC, printer and first two serial lines..
|
||||
*
|
||||
* The local stuff makes for some complications, but it seems to be
|
||||
* gone in the PCI version. I hope I can get DEC suckered^H^H^H^H^H^H^H^H
|
||||
* convinced that I need one of the newer machines.
|
||||
*/
|
||||
|
||||
__EXTERN_INLINE unsigned int jensen_local_inb(unsigned long addr)
|
||||
{
|
||||
return 0xff & *(vuip)((addr << 9) + EISA_VL82C106);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void jensen_local_outb(u8 b, unsigned long addr)
|
||||
{
|
||||
*(vuip)((addr << 9) + EISA_VL82C106) = b;
|
||||
mb();
|
||||
}
|
||||
|
||||
__EXTERN_INLINE unsigned int jensen_bus_inb(unsigned long addr)
|
||||
{
|
||||
long result;
|
||||
|
||||
jensen_set_hae(0);
|
||||
result = *(volatile int *)((addr << 7) + EISA_IO + 0x00);
|
||||
return __kernel_extbl(result, addr & 3);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void jensen_bus_outb(u8 b, unsigned long addr)
|
||||
{
|
||||
jensen_set_hae(0);
|
||||
*(vuip)((addr << 7) + EISA_IO + 0x00) = b * 0x01010101;
|
||||
mb();
|
||||
}
|
||||
|
||||
/*
|
||||
* It seems gcc is not very good at optimizing away logical
|
||||
* operations that result in operations across inline functions.
|
||||
* Which is why this is a macro.
|
||||
*/
|
||||
|
||||
#define jensen_is_local(addr) ( \
|
||||
/* keyboard */ (addr == 0x60 || addr == 0x64) || \
|
||||
/* RTC */ (addr == 0x170 || addr == 0x171) || \
|
||||
/* mb COM2 */ (addr >= 0x2f8 && addr <= 0x2ff) || \
|
||||
/* mb LPT1 */ (addr >= 0x3bc && addr <= 0x3be) || \
|
||||
/* mb COM2 */ (addr >= 0x3f8 && addr <= 0x3ff))
|
||||
|
||||
__EXTERN_INLINE u8 jensen_inb(unsigned long addr)
|
||||
{
|
||||
if (jensen_is_local(addr))
|
||||
return jensen_local_inb(addr);
|
||||
else
|
||||
return jensen_bus_inb(addr);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void jensen_outb(u8 b, unsigned long addr)
|
||||
{
|
||||
if (jensen_is_local(addr))
|
||||
jensen_local_outb(b, addr);
|
||||
else
|
||||
jensen_bus_outb(b, addr);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE u16 jensen_inw(unsigned long addr)
|
||||
{
|
||||
long result;
|
||||
|
||||
jensen_set_hae(0);
|
||||
result = *(volatile int *) ((addr << 7) + EISA_IO + 0x20);
|
||||
result >>= (addr & 3) * 8;
|
||||
return 0xffffUL & result;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE u32 jensen_inl(unsigned long addr)
|
||||
{
|
||||
jensen_set_hae(0);
|
||||
return *(vuip) ((addr << 7) + EISA_IO + 0x60);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void jensen_outw(u16 b, unsigned long addr)
|
||||
{
|
||||
jensen_set_hae(0);
|
||||
*(vuip) ((addr << 7) + EISA_IO + 0x20) = b * 0x00010001;
|
||||
mb();
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void jensen_outl(u32 b, unsigned long addr)
|
||||
{
|
||||
jensen_set_hae(0);
|
||||
*(vuip) ((addr << 7) + EISA_IO + 0x60) = b;
|
||||
mb();
|
||||
}
|
||||
|
||||
/*
|
||||
* Memory functions.
|
||||
*/
|
||||
|
||||
__EXTERN_INLINE u8 jensen_readb(const volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
long result;
|
||||
|
||||
jensen_set_hae(addr);
|
||||
addr &= JENSEN_HAE_MASK;
|
||||
result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x00);
|
||||
result >>= (addr & 3) * 8;
|
||||
return 0xffUL & result;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE u16 jensen_readw(const volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
long result;
|
||||
|
||||
jensen_set_hae(addr);
|
||||
addr &= JENSEN_HAE_MASK;
|
||||
result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x20);
|
||||
result >>= (addr & 3) * 8;
|
||||
return 0xffffUL & result;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE u32 jensen_readl(const volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
jensen_set_hae(addr);
|
||||
addr &= JENSEN_HAE_MASK;
|
||||
return *(vuip) ((addr << 7) + EISA_MEM + 0x60);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE u64 jensen_readq(const volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
unsigned long r0, r1;
|
||||
|
||||
jensen_set_hae(addr);
|
||||
addr &= JENSEN_HAE_MASK;
|
||||
addr = (addr << 7) + EISA_MEM + 0x60;
|
||||
r0 = *(vuip) (addr);
|
||||
r1 = *(vuip) (addr + (4 << 7));
|
||||
return r1 << 32 | r0;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void jensen_writeb(u8 b, volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
jensen_set_hae(addr);
|
||||
addr &= JENSEN_HAE_MASK;
|
||||
*(vuip) ((addr << 7) + EISA_MEM + 0x00) = b * 0x01010101;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void jensen_writew(u16 b, volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
jensen_set_hae(addr);
|
||||
addr &= JENSEN_HAE_MASK;
|
||||
*(vuip) ((addr << 7) + EISA_MEM + 0x20) = b * 0x00010001;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void jensen_writel(u32 b, volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
jensen_set_hae(addr);
|
||||
addr &= JENSEN_HAE_MASK;
|
||||
*(vuip) ((addr << 7) + EISA_MEM + 0x60) = b;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void jensen_writeq(u64 b, volatile void __iomem *xaddr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) xaddr;
|
||||
jensen_set_hae(addr);
|
||||
addr &= JENSEN_HAE_MASK;
|
||||
addr = (addr << 7) + EISA_MEM + 0x60;
|
||||
*(vuip) (addr) = b;
|
||||
*(vuip) (addr + (4 << 7)) = b >> 32;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void __iomem *jensen_ioportmap(unsigned long addr)
|
||||
{
|
||||
return (void __iomem *)addr;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void __iomem *jensen_ioremap(unsigned long addr,
|
||||
unsigned long size)
|
||||
{
|
||||
return (void __iomem *)(addr + 0x100000000ul);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int jensen_is_ioaddr(unsigned long addr)
|
||||
{
|
||||
return (long)addr >= 0;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE int jensen_is_mmio(const volatile void __iomem *addr)
|
||||
{
|
||||
return (unsigned long)addr >= 0x100000000ul;
|
||||
}
|
||||
|
||||
/* New-style ioread interface. All the routines are so ugly for Jensen
|
||||
that it doesn't make sense to merge them. */
|
||||
|
||||
#define IOPORT(OS, NS) \
|
||||
__EXTERN_INLINE unsigned int jensen_ioread##NS(const void __iomem *xaddr) \
|
||||
{ \
|
||||
if (jensen_is_mmio(xaddr)) \
|
||||
return jensen_read##OS(xaddr - 0x100000000ul); \
|
||||
else \
|
||||
return jensen_in##OS((unsigned long)xaddr); \
|
||||
} \
|
||||
__EXTERN_INLINE void jensen_iowrite##NS(u##NS b, void __iomem *xaddr) \
|
||||
{ \
|
||||
if (jensen_is_mmio(xaddr)) \
|
||||
jensen_write##OS(b, xaddr - 0x100000000ul); \
|
||||
else \
|
||||
jensen_out##OS(b, (unsigned long)xaddr); \
|
||||
}
|
||||
|
||||
IOPORT(b, 8)
|
||||
IOPORT(w, 16)
|
||||
IOPORT(l, 32)
|
||||
|
||||
#undef IOPORT
|
||||
|
||||
#undef vuip
|
||||
|
||||
#undef __IO_PREFIX
|
||||
#define __IO_PREFIX jensen
|
||||
#define jensen_trivial_rw_bw 0
|
||||
#define jensen_trivial_rw_lq 0
|
||||
#define jensen_trivial_io_bw 0
|
||||
#define jensen_trivial_io_lq 0
|
||||
#define jensen_trivial_iounmap 1
|
||||
#include <asm/io_trivial.h>
|
||||
|
||||
#ifdef __IO_EXTERN_INLINE
|
||||
#undef __EXTERN_INLINE
|
||||
#undef __IO_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ALPHA_JENSEN_H */
|
1
arch/alpha/include/asm/kdebug.h
Normal file
1
arch/alpha/include/asm/kdebug.h
Normal file
@ -0,0 +1 @@
|
||||
#include <asm-generic/kdebug.h>
|
15
arch/alpha/include/asm/kmap_types.h
Normal file
15
arch/alpha/include/asm/kmap_types.h
Normal file
@ -0,0 +1,15 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_KMAP_TYPES_H
|
||||
#define _ASM_KMAP_TYPES_H
|
||||
|
||||
/* Dummy header just to define km_type. */
|
||||
|
||||
#ifdef CONFIG_DEBUG_HIGHMEM
|
||||
#define __WITH_KM_FENCE
|
||||
#endif
|
||||
|
||||
#include <asm-generic/kmap_types.h>
|
||||
|
||||
#undef __WITH_KM_FENCE
|
||||
|
||||
#endif
|
9
arch/alpha/include/asm/linkage.h
Normal file
9
arch/alpha/include/asm/linkage.h
Normal file
@ -0,0 +1,9 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_LINKAGE_H
|
||||
#define __ASM_LINKAGE_H
|
||||
|
||||
#define cond_syscall(x) asm(".weak\t" #x "\n" #x " = sys_ni_syscall")
|
||||
#define SYSCALL_ALIAS(alias, name) \
|
||||
asm ( #alias " = " #name "\n\t.globl " #alias)
|
||||
|
||||
#endif
|
102
arch/alpha/include/asm/local.h
Normal file
102
arch/alpha/include/asm/local.h
Normal file
@ -0,0 +1,102 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ALPHA_LOCAL_H
|
||||
#define _ALPHA_LOCAL_H
|
||||
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/atomic.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
atomic_long_t a;
|
||||
} local_t;
|
||||
|
||||
#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
|
||||
#define local_read(l) atomic_long_read(&(l)->a)
|
||||
#define local_set(l,i) atomic_long_set(&(l)->a, (i))
|
||||
#define local_inc(l) atomic_long_inc(&(l)->a)
|
||||
#define local_dec(l) atomic_long_dec(&(l)->a)
|
||||
#define local_add(i,l) atomic_long_add((i),(&(l)->a))
|
||||
#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
|
||||
|
||||
static __inline__ long local_add_return(long i, local_t * l)
|
||||
{
|
||||
long temp, result;
|
||||
__asm__ __volatile__(
|
||||
"1: ldq_l %0,%1\n"
|
||||
" addq %0,%3,%2\n"
|
||||
" addq %0,%3,%0\n"
|
||||
" stq_c %0,%1\n"
|
||||
" beq %0,2f\n"
|
||||
".subsection 2\n"
|
||||
"2: br 1b\n"
|
||||
".previous"
|
||||
:"=&r" (temp), "=m" (l->a.counter), "=&r" (result)
|
||||
:"Ir" (i), "m" (l->a.counter) : "memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
static __inline__ long local_sub_return(long i, local_t * l)
|
||||
{
|
||||
long temp, result;
|
||||
__asm__ __volatile__(
|
||||
"1: ldq_l %0,%1\n"
|
||||
" subq %0,%3,%2\n"
|
||||
" subq %0,%3,%0\n"
|
||||
" stq_c %0,%1\n"
|
||||
" beq %0,2f\n"
|
||||
".subsection 2\n"
|
||||
"2: br 1b\n"
|
||||
".previous"
|
||||
:"=&r" (temp), "=m" (l->a.counter), "=&r" (result)
|
||||
:"Ir" (i), "m" (l->a.counter) : "memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
#define local_cmpxchg(l, o, n) \
|
||||
(cmpxchg_local(&((l)->a.counter), (o), (n)))
|
||||
#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
|
||||
|
||||
/**
|
||||
* local_add_unless - add unless the number is a given value
|
||||
* @l: pointer of type local_t
|
||||
* @a: the amount to add to l...
|
||||
* @u: ...unless l is equal to u.
|
||||
*
|
||||
* Atomically adds @a to @l, so long as it was not @u.
|
||||
* Returns non-zero if @l was not @u, and zero otherwise.
|
||||
*/
|
||||
#define local_add_unless(l, a, u) \
|
||||
({ \
|
||||
long c, old; \
|
||||
c = local_read(l); \
|
||||
for (;;) { \
|
||||
if (unlikely(c == (u))) \
|
||||
break; \
|
||||
old = local_cmpxchg((l), c, c + (a)); \
|
||||
if (likely(old == c)) \
|
||||
break; \
|
||||
c = old; \
|
||||
} \
|
||||
c != (u); \
|
||||
})
|
||||
#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
|
||||
|
||||
#define local_add_negative(a, l) (local_add_return((a), (l)) < 0)
|
||||
|
||||
#define local_dec_return(l) local_sub_return(1,(l))
|
||||
|
||||
#define local_inc_return(l) local_add_return(1,(l))
|
||||
|
||||
#define local_sub_and_test(i,l) (local_sub_return((i), (l)) == 0)
|
||||
|
||||
#define local_inc_and_test(l) (local_add_return(1, (l)) == 0)
|
||||
|
||||
#define local_dec_and_test(l) (local_sub_return(1, (l)) == 0)
|
||||
|
||||
/* Verify if faster than atomic ops */
|
||||
#define __local_inc(l) ((l)->a.counter++)
|
||||
#define __local_dec(l) ((l)->a.counter++)
|
||||
#define __local_add(i,l) ((l)->a.counter+=(i))
|
||||
#define __local_sub(i,l) ((l)->a.counter-=(i))
|
||||
|
||||
#endif /* _ALPHA_LOCAL_H */
|
137
arch/alpha/include/asm/machvec.h
Normal file
137
arch/alpha/include/asm/machvec.h
Normal file
@ -0,0 +1,137 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_MACHVEC_H
|
||||
#define __ALPHA_MACHVEC_H 1
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
* This file gets pulled in by asm/io.h from user space. We don't
|
||||
* want most of this escaping.
|
||||
*/
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/* The following structure vectors all of the I/O and IRQ manipulation
|
||||
from the generic kernel to the hardware specific backend. */
|
||||
|
||||
struct task_struct;
|
||||
struct mm_struct;
|
||||
struct vm_area_struct;
|
||||
struct linux_hose_info;
|
||||
struct pci_dev;
|
||||
struct pci_ops;
|
||||
struct pci_controller;
|
||||
struct _alpha_agp_info;
|
||||
struct rtc_time;
|
||||
|
||||
struct alpha_machine_vector
|
||||
{
|
||||
/* This "belongs" down below with the rest of the runtime
|
||||
variables, but it is convenient for entry.S if these
|
||||
two slots are at the beginning of the struct. */
|
||||
unsigned long hae_cache;
|
||||
unsigned long *hae_register;
|
||||
|
||||
int nr_irqs;
|
||||
int rtc_port;
|
||||
int rtc_boot_cpu_only;
|
||||
unsigned int max_asn;
|
||||
unsigned long max_isa_dma_address;
|
||||
unsigned long irq_probe_mask;
|
||||
unsigned long iack_sc;
|
||||
unsigned long min_io_address;
|
||||
unsigned long min_mem_address;
|
||||
unsigned long pci_dac_offset;
|
||||
|
||||
void (*mv_pci_tbi)(struct pci_controller *hose,
|
||||
dma_addr_t start, dma_addr_t end);
|
||||
|
||||
unsigned int (*mv_ioread8)(const void __iomem *);
|
||||
unsigned int (*mv_ioread16)(const void __iomem *);
|
||||
unsigned int (*mv_ioread32)(const void __iomem *);
|
||||
|
||||
void (*mv_iowrite8)(u8, void __iomem *);
|
||||
void (*mv_iowrite16)(u16, void __iomem *);
|
||||
void (*mv_iowrite32)(u32, void __iomem *);
|
||||
|
||||
u8 (*mv_readb)(const volatile void __iomem *);
|
||||
u16 (*mv_readw)(const volatile void __iomem *);
|
||||
u32 (*mv_readl)(const volatile void __iomem *);
|
||||
u64 (*mv_readq)(const volatile void __iomem *);
|
||||
|
||||
void (*mv_writeb)(u8, volatile void __iomem *);
|
||||
void (*mv_writew)(u16, volatile void __iomem *);
|
||||
void (*mv_writel)(u32, volatile void __iomem *);
|
||||
void (*mv_writeq)(u64, volatile void __iomem *);
|
||||
|
||||
void __iomem *(*mv_ioportmap)(unsigned long);
|
||||
void __iomem *(*mv_ioremap)(unsigned long, unsigned long);
|
||||
void (*mv_iounmap)(volatile void __iomem *);
|
||||
int (*mv_is_ioaddr)(unsigned long);
|
||||
int (*mv_is_mmio)(const volatile void __iomem *);
|
||||
|
||||
void (*mv_switch_mm)(struct mm_struct *, struct mm_struct *,
|
||||
struct task_struct *);
|
||||
void (*mv_activate_mm)(struct mm_struct *, struct mm_struct *);
|
||||
|
||||
void (*mv_flush_tlb_current)(struct mm_struct *);
|
||||
void (*mv_flush_tlb_current_page)(struct mm_struct * mm,
|
||||
struct vm_area_struct *vma,
|
||||
unsigned long addr);
|
||||
|
||||
void (*update_irq_hw)(unsigned long, unsigned long, int);
|
||||
void (*ack_irq)(unsigned long);
|
||||
void (*device_interrupt)(unsigned long vector);
|
||||
void (*machine_check)(unsigned long vector, unsigned long la);
|
||||
|
||||
void (*smp_callin)(void);
|
||||
void (*init_arch)(void);
|
||||
void (*init_irq)(void);
|
||||
void (*init_rtc)(void);
|
||||
void (*init_pci)(void);
|
||||
void (*kill_arch)(int);
|
||||
|
||||
u8 (*pci_swizzle)(struct pci_dev *, u8 *);
|
||||
int (*pci_map_irq)(const struct pci_dev *, u8, u8);
|
||||
struct pci_ops *pci_ops;
|
||||
|
||||
struct _alpha_agp_info *(*agp_info)(void);
|
||||
|
||||
const char *vector_name;
|
||||
|
||||
/* System specific parameters. */
|
||||
union {
|
||||
struct {
|
||||
unsigned long gru_int_req_bits;
|
||||
} cia;
|
||||
|
||||
struct {
|
||||
unsigned long gamma_bias;
|
||||
} t2;
|
||||
|
||||
struct {
|
||||
unsigned int route_tab;
|
||||
} sio;
|
||||
} sys;
|
||||
};
|
||||
|
||||
extern struct alpha_machine_vector alpha_mv;
|
||||
|
||||
#ifdef CONFIG_ALPHA_GENERIC
|
||||
extern int alpha_using_srm;
|
||||
extern int alpha_using_qemu;
|
||||
#else
|
||||
# ifdef CONFIG_ALPHA_SRM
|
||||
# define alpha_using_srm 1
|
||||
# else
|
||||
# define alpha_using_srm 0
|
||||
# endif
|
||||
# ifdef CONFIG_ALPHA_QEMU
|
||||
# define alpha_using_qemu 1
|
||||
# else
|
||||
# define alpha_using_qemu 0
|
||||
# endif
|
||||
#endif /* GENERIC */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __ALPHA_MACHVEC_H */
|
28
arch/alpha/include/asm/mc146818rtc.h
Normal file
28
arch/alpha/include/asm/mc146818rtc.h
Normal file
@ -0,0 +1,28 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Machine dependent access functions for RTC registers.
|
||||
*/
|
||||
#ifndef __ASM_ALPHA_MC146818RTC_H
|
||||
#define __ASM_ALPHA_MC146818RTC_H
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
#ifndef RTC_PORT
|
||||
#define RTC_PORT(x) (0x70 + (x))
|
||||
#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The yet supported machines all access the RTC index register via
|
||||
* an ISA port access but the way to access the date register differs ...
|
||||
*/
|
||||
#define CMOS_READ(addr) ({ \
|
||||
outb_p((addr),RTC_PORT(0)); \
|
||||
inb_p(RTC_PORT(1)); \
|
||||
})
|
||||
#define CMOS_WRITE(val, addr) ({ \
|
||||
outb_p((addr),RTC_PORT(0)); \
|
||||
outb_p((val),RTC_PORT(1)); \
|
||||
})
|
||||
|
||||
#endif /* __ASM_ALPHA_MC146818RTC_H */
|
84
arch/alpha/include/asm/mce.h
Normal file
84
arch/alpha/include/asm/mce.h
Normal file
@ -0,0 +1,84 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_MCE_H
|
||||
#define __ALPHA_MCE_H
|
||||
|
||||
/*
|
||||
* This is the logout header that should be common to all platforms
|
||||
* (assuming they are running OSF/1 PALcode, I guess).
|
||||
*/
|
||||
struct el_common {
|
||||
unsigned int size; /* size in bytes of logout area */
|
||||
unsigned int sbz1 : 30; /* should be zero */
|
||||
unsigned int err2 : 1; /* second error */
|
||||
unsigned int retry : 1; /* retry flag */
|
||||
unsigned int proc_offset; /* processor-specific offset */
|
||||
unsigned int sys_offset; /* system-specific offset */
|
||||
unsigned int code; /* machine check code */
|
||||
unsigned int frame_rev; /* frame revision */
|
||||
};
|
||||
|
||||
/* Machine Check Frame for uncorrectable errors (Large format)
|
||||
* --- This is used to log uncorrectable errors such as
|
||||
* double bit ECC errors.
|
||||
* --- These errors are detected by both processor and systems.
|
||||
*/
|
||||
struct el_common_EV5_uncorrectable_mcheck {
|
||||
unsigned long shadow[8]; /* Shadow reg. 8-14, 25 */
|
||||
unsigned long paltemp[24]; /* PAL TEMP REGS. */
|
||||
unsigned long exc_addr; /* Address of excepting instruction*/
|
||||
unsigned long exc_sum; /* Summary of arithmetic traps. */
|
||||
unsigned long exc_mask; /* Exception mask (from exc_sum). */
|
||||
unsigned long pal_base; /* Base address for PALcode. */
|
||||
unsigned long isr; /* Interrupt Status Reg. */
|
||||
unsigned long icsr; /* CURRENT SETUP OF EV5 IBOX */
|
||||
unsigned long ic_perr_stat; /* I-CACHE Reg. <11> set Data parity
|
||||
<12> set TAG parity*/
|
||||
unsigned long dc_perr_stat; /* D-CACHE error Reg. Bits set to 1:
|
||||
<2> Data error in bank 0
|
||||
<3> Data error in bank 1
|
||||
<4> Tag error in bank 0
|
||||
<5> Tag error in bank 1 */
|
||||
unsigned long va; /* Effective VA of fault or miss. */
|
||||
unsigned long mm_stat; /* Holds the reason for D-stream
|
||||
fault or D-cache parity errors */
|
||||
unsigned long sc_addr; /* Address that was being accessed
|
||||
when EV5 detected Secondary cache
|
||||
failure. */
|
||||
unsigned long sc_stat; /* Helps determine if the error was
|
||||
TAG/Data parity(Secondary Cache)*/
|
||||
unsigned long bc_tag_addr; /* Contents of EV5 BC_TAG_ADDR */
|
||||
unsigned long ei_addr; /* Physical address of any transfer
|
||||
that is logged in EV5 EI_STAT */
|
||||
unsigned long fill_syndrome; /* For correcting ECC errors. */
|
||||
unsigned long ei_stat; /* Helps identify reason of any
|
||||
processor uncorrectable error
|
||||
at its external interface. */
|
||||
unsigned long ld_lock; /* Contents of EV5 LD_LOCK register*/
|
||||
};
|
||||
|
||||
struct el_common_EV6_mcheck {
|
||||
unsigned int FrameSize; /* Bytes, including this field */
|
||||
unsigned int FrameFlags; /* <31> = Retry, <30> = Second Error */
|
||||
unsigned int CpuOffset; /* Offset to CPU-specific info */
|
||||
unsigned int SystemOffset; /* Offset to system-specific info */
|
||||
unsigned int MCHK_Code;
|
||||
unsigned int MCHK_Frame_Rev;
|
||||
unsigned long I_STAT; /* EV6 Internal Processor Registers */
|
||||
unsigned long DC_STAT; /* (See the 21264 Spec) */
|
||||
unsigned long C_ADDR;
|
||||
unsigned long DC1_SYNDROME;
|
||||
unsigned long DC0_SYNDROME;
|
||||
unsigned long C_STAT;
|
||||
unsigned long C_STS;
|
||||
unsigned long MM_STAT;
|
||||
unsigned long EXC_ADDR;
|
||||
unsigned long IER_CM;
|
||||
unsigned long ISUM;
|
||||
unsigned long RESERVED0;
|
||||
unsigned long PAL_BASE;
|
||||
unsigned long I_CTL;
|
||||
unsigned long PCTX;
|
||||
};
|
||||
|
||||
|
||||
#endif /* __ALPHA_MCE_H */
|
8
arch/alpha/include/asm/mmu.h
Normal file
8
arch/alpha/include/asm/mmu.h
Normal file
@ -0,0 +1,8 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_MMU_H
|
||||
#define __ALPHA_MMU_H
|
||||
|
||||
/* The alpha MMU context is one "unsigned long" bitmap per CPU */
|
||||
typedef unsigned long mm_context_t[NR_CPUS];
|
||||
|
||||
#endif
|
259
arch/alpha/include/asm/mmu_context.h
Normal file
259
arch/alpha/include/asm/mmu_context.h
Normal file
@ -0,0 +1,259 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_MMU_CONTEXT_H
|
||||
#define __ALPHA_MMU_CONTEXT_H
|
||||
|
||||
/*
|
||||
* get a new mmu context..
|
||||
*
|
||||
* Copyright (C) 1996, Linus Torvalds
|
||||
*/
|
||||
|
||||
#include <linux/mm_types.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#include <asm/machvec.h>
|
||||
#include <asm/compiler.h>
|
||||
#include <asm-generic/mm_hooks.h>
|
||||
|
||||
/*
|
||||
* Force a context reload. This is needed when we change the page
|
||||
* table pointer or when we update the ASN of the current process.
|
||||
*/
|
||||
|
||||
/* Don't get into trouble with dueling __EXTERN_INLINEs. */
|
||||
#ifndef __EXTERN_INLINE
|
||||
#include <asm/io.h>
|
||||
#endif
|
||||
|
||||
|
||||
static inline unsigned long
|
||||
__reload_thread(struct pcb_struct *pcb)
|
||||
{
|
||||
register unsigned long a0 __asm__("$16");
|
||||
register unsigned long v0 __asm__("$0");
|
||||
|
||||
a0 = virt_to_phys(pcb);
|
||||
__asm__ __volatile__(
|
||||
"call_pal %2 #__reload_thread"
|
||||
: "=r"(v0), "=r"(a0)
|
||||
: "i"(PAL_swpctx), "r"(a0)
|
||||
: "$1", "$22", "$23", "$24", "$25");
|
||||
|
||||
return v0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The maximum ASN's the processor supports. On the EV4 this is 63
|
||||
* but the PAL-code doesn't actually use this information. On the
|
||||
* EV5 this is 127, and EV6 has 255.
|
||||
*
|
||||
* On the EV4, the ASNs are more-or-less useless anyway, as they are
|
||||
* only used as an icache tag, not for TB entries. On the EV5 and EV6,
|
||||
* ASN's also validate the TB entries, and thus make a lot more sense.
|
||||
*
|
||||
* The EV4 ASN's don't even match the architecture manual, ugh. And
|
||||
* I quote: "If a processor implements address space numbers (ASNs),
|
||||
* and the old PTE has the Address Space Match (ASM) bit clear (ASNs
|
||||
* in use) and the Valid bit set, then entries can also effectively be
|
||||
* made coherent by assigning a new, unused ASN to the currently
|
||||
* running process and not reusing the previous ASN before calling the
|
||||
* appropriate PALcode routine to invalidate the translation buffer (TB)".
|
||||
*
|
||||
* In short, the EV4 has a "kind of" ASN capability, but it doesn't actually
|
||||
* work correctly and can thus not be used (explaining the lack of PAL-code
|
||||
* support).
|
||||
*/
|
||||
#define EV4_MAX_ASN 63
|
||||
#define EV5_MAX_ASN 127
|
||||
#define EV6_MAX_ASN 255
|
||||
|
||||
#ifdef CONFIG_ALPHA_GENERIC
|
||||
# define MAX_ASN (alpha_mv.max_asn)
|
||||
#else
|
||||
# ifdef CONFIG_ALPHA_EV4
|
||||
# define MAX_ASN EV4_MAX_ASN
|
||||
# elif defined(CONFIG_ALPHA_EV5)
|
||||
# define MAX_ASN EV5_MAX_ASN
|
||||
# else
|
||||
# define MAX_ASN EV6_MAX_ASN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* cpu_last_asn(processor):
|
||||
* 63 0
|
||||
* +-------------+----------------+--------------+
|
||||
* | asn version | this processor | hardware asn |
|
||||
* +-------------+----------------+--------------+
|
||||
*/
|
||||
|
||||
#include <asm/smp.h>
|
||||
#ifdef CONFIG_SMP
|
||||
#define cpu_last_asn(cpuid) (cpu_data[cpuid].last_asn)
|
||||
#else
|
||||
extern unsigned long last_asn;
|
||||
#define cpu_last_asn(cpuid) last_asn
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#define WIDTH_HARDWARE_ASN 8
|
||||
#define ASN_FIRST_VERSION (1UL << WIDTH_HARDWARE_ASN)
|
||||
#define HARDWARE_ASN_MASK ((1UL << WIDTH_HARDWARE_ASN) - 1)
|
||||
|
||||
/*
|
||||
* NOTE! The way this is set up, the high bits of the "asn_cache" (and
|
||||
* the "mm->context") are the ASN _version_ code. A version of 0 is
|
||||
* always considered invalid, so to invalidate another process you only
|
||||
* need to do "p->mm->context = 0".
|
||||
*
|
||||
* If we need more ASN's than the processor has, we invalidate the old
|
||||
* user TLB's (tbiap()) and start a new ASN version. That will automatically
|
||||
* force a new asn for any other processes the next time they want to
|
||||
* run.
|
||||
*/
|
||||
|
||||
#ifndef __EXTERN_INLINE
|
||||
#define __EXTERN_INLINE extern inline
|
||||
#define __MMU_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
extern inline unsigned long
|
||||
__get_new_mm_context(struct mm_struct *mm, long cpu)
|
||||
{
|
||||
unsigned long asn = cpu_last_asn(cpu);
|
||||
unsigned long next = asn + 1;
|
||||
|
||||
if ((asn & HARDWARE_ASN_MASK) >= MAX_ASN) {
|
||||
tbiap();
|
||||
imb();
|
||||
next = (asn & ~HARDWARE_ASN_MASK) + ASN_FIRST_VERSION;
|
||||
}
|
||||
cpu_last_asn(cpu) = next;
|
||||
return next;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void
|
||||
ev5_switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
|
||||
struct task_struct *next)
|
||||
{
|
||||
/* Check if our ASN is of an older version, and thus invalid. */
|
||||
unsigned long asn;
|
||||
unsigned long mmc;
|
||||
long cpu = smp_processor_id();
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
cpu_data[cpu].asn_lock = 1;
|
||||
barrier();
|
||||
#endif
|
||||
asn = cpu_last_asn(cpu);
|
||||
mmc = next_mm->context[cpu];
|
||||
if ((mmc ^ asn) & ~HARDWARE_ASN_MASK) {
|
||||
mmc = __get_new_mm_context(next_mm, cpu);
|
||||
next_mm->context[cpu] = mmc;
|
||||
}
|
||||
#ifdef CONFIG_SMP
|
||||
else
|
||||
cpu_data[cpu].need_new_asn = 1;
|
||||
#endif
|
||||
|
||||
/* Always update the PCB ASN. Another thread may have allocated
|
||||
a new mm->context (via flush_tlb_mm) without the ASN serial
|
||||
number wrapping. We have no way to detect when this is needed. */
|
||||
task_thread_info(next)->pcb.asn = mmc & HARDWARE_ASN_MASK;
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void
|
||||
ev4_switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
|
||||
struct task_struct *next)
|
||||
{
|
||||
/* As described, ASN's are broken for TLB usage. But we can
|
||||
optimize for switching between threads -- if the mm is
|
||||
unchanged from current we needn't flush. */
|
||||
/* ??? May not be needed because EV4 PALcode recognizes that
|
||||
ASN's are broken and does a tbiap itself on swpctx, under
|
||||
the "Must set ASN or flush" rule. At least this is true
|
||||
for a 1992 SRM, reports Joseph Martin (jmartin@hlo.dec.com).
|
||||
I'm going to leave this here anyway, just to Be Sure. -- r~ */
|
||||
if (prev_mm != next_mm)
|
||||
tbiap();
|
||||
|
||||
/* Do continue to allocate ASNs, because we can still use them
|
||||
to avoid flushing the icache. */
|
||||
ev5_switch_mm(prev_mm, next_mm, next);
|
||||
}
|
||||
|
||||
extern void __load_new_mm_context(struct mm_struct *);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define check_mmu_context() \
|
||||
do { \
|
||||
int cpu = smp_processor_id(); \
|
||||
cpu_data[cpu].asn_lock = 0; \
|
||||
barrier(); \
|
||||
if (cpu_data[cpu].need_new_asn) { \
|
||||
struct mm_struct * mm = current->active_mm; \
|
||||
cpu_data[cpu].need_new_asn = 0; \
|
||||
if (!mm->context[cpu]) \
|
||||
__load_new_mm_context(mm); \
|
||||
} \
|
||||
} while(0)
|
||||
#else
|
||||
#define check_mmu_context() do { } while(0)
|
||||
#endif
|
||||
|
||||
__EXTERN_INLINE void
|
||||
ev5_activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
|
||||
{
|
||||
__load_new_mm_context(next_mm);
|
||||
}
|
||||
|
||||
__EXTERN_INLINE void
|
||||
ev4_activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
|
||||
{
|
||||
__load_new_mm_context(next_mm);
|
||||
tbiap();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ALPHA_GENERIC
|
||||
# define switch_mm(a,b,c) alpha_mv.mv_switch_mm((a),(b),(c))
|
||||
# define activate_mm(x,y) alpha_mv.mv_activate_mm((x),(y))
|
||||
#else
|
||||
# ifdef CONFIG_ALPHA_EV4
|
||||
# define switch_mm(a,b,c) ev4_switch_mm((a),(b),(c))
|
||||
# define activate_mm(x,y) ev4_activate_mm((x),(y))
|
||||
# else
|
||||
# define switch_mm(a,b,c) ev5_switch_mm((a),(b),(c))
|
||||
# define activate_mm(x,y) ev5_activate_mm((x),(y))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define init_new_context init_new_context
|
||||
static inline int
|
||||
init_new_context(struct task_struct *tsk, struct mm_struct *mm)
|
||||
{
|
||||
int i;
|
||||
|
||||
for_each_online_cpu(i)
|
||||
mm->context[i] = 0;
|
||||
if (tsk != current)
|
||||
task_thread_info(tsk)->pcb.ptbr
|
||||
= ((unsigned long)mm->pgd - IDENT_ADDR) >> PAGE_SHIFT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define enter_lazy_tlb enter_lazy_tlb
|
||||
static inline void
|
||||
enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
|
||||
{
|
||||
task_thread_info(tsk)->pcb.ptbr
|
||||
= ((unsigned long)mm->pgd - IDENT_ADDR) >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
#include <asm-generic/mmu_context.h>
|
||||
|
||||
#ifdef __MMU_EXTERN_INLINE
|
||||
#undef __EXTERN_INLINE
|
||||
#undef __MMU_EXTERN_INLINE
|
||||
#endif
|
||||
|
||||
#endif /* __ALPHA_MMU_CONTEXT_H */
|
110
arch/alpha/include/asm/mmzone.h
Normal file
110
arch/alpha/include/asm/mmzone.h
Normal file
@ -0,0 +1,110 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Written by Kanoj Sarcar (kanoj@sgi.com) Aug 99
|
||||
* Adapted for the alpha wildfire architecture Jan 2001.
|
||||
*/
|
||||
#ifndef _ASM_MMZONE_H_
|
||||
#define _ASM_MMZONE_H_
|
||||
|
||||
#include <asm/smp.h>
|
||||
|
||||
/*
|
||||
* Following are macros that are specific to this numa platform.
|
||||
*/
|
||||
|
||||
extern pg_data_t node_data[];
|
||||
|
||||
#define alpha_pa_to_nid(pa) \
|
||||
(alpha_mv.pa_to_nid \
|
||||
? alpha_mv.pa_to_nid(pa) \
|
||||
: (0))
|
||||
#define node_mem_start(nid) \
|
||||
(alpha_mv.node_mem_start \
|
||||
? alpha_mv.node_mem_start(nid) \
|
||||
: (0UL))
|
||||
#define node_mem_size(nid) \
|
||||
(alpha_mv.node_mem_size \
|
||||
? alpha_mv.node_mem_size(nid) \
|
||||
: ((nid) ? (0UL) : (~0UL)))
|
||||
|
||||
#define pa_to_nid(pa) alpha_pa_to_nid(pa)
|
||||
#define NODE_DATA(nid) (&node_data[(nid)])
|
||||
|
||||
#define node_localnr(pfn, nid) ((pfn) - NODE_DATA(nid)->node_start_pfn)
|
||||
|
||||
#if 1
|
||||
#define PLAT_NODE_DATA_LOCALNR(p, n) \
|
||||
(((p) >> PAGE_SHIFT) - PLAT_NODE_DATA(n)->gendata.node_start_pfn)
|
||||
#else
|
||||
static inline unsigned long
|
||||
PLAT_NODE_DATA_LOCALNR(unsigned long p, int n)
|
||||
{
|
||||
unsigned long temp;
|
||||
temp = p >> PAGE_SHIFT;
|
||||
return temp - PLAT_NODE_DATA(n)->gendata.node_start_pfn;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DISCONTIGMEM
|
||||
|
||||
/*
|
||||
* Following are macros that each numa implementation must define.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Given a kernel address, find the home node of the underlying memory.
|
||||
*/
|
||||
#define kvaddr_to_nid(kaddr) pa_to_nid(__pa(kaddr))
|
||||
|
||||
/*
|
||||
* Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory
|
||||
* and returns the kaddr corresponding to first physical page in the
|
||||
* node's mem_map.
|
||||
*/
|
||||
#define LOCAL_BASE_ADDR(kaddr) \
|
||||
((unsigned long)__va(NODE_DATA(kvaddr_to_nid(kaddr))->node_start_pfn \
|
||||
<< PAGE_SHIFT))
|
||||
|
||||
/* XXX: FIXME -- nyc */
|
||||
#define kern_addr_valid(kaddr) (0)
|
||||
|
||||
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
|
||||
|
||||
#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> 32))
|
||||
#define pte_pfn(pte) (pte_val(pte) >> 32)
|
||||
|
||||
#define mk_pte(page, pgprot) \
|
||||
({ \
|
||||
pte_t pte; \
|
||||
unsigned long pfn; \
|
||||
\
|
||||
pfn = page_to_pfn(page) << 32; \
|
||||
pte_val(pte) = pfn | pgprot_val(pgprot); \
|
||||
\
|
||||
pte; \
|
||||
})
|
||||
|
||||
#define pte_page(x) \
|
||||
({ \
|
||||
unsigned long kvirt; \
|
||||
struct page * __xx; \
|
||||
\
|
||||
kvirt = (unsigned long)__va(pte_val(x) >> (32-PAGE_SHIFT)); \
|
||||
__xx = virt_to_page(kvirt); \
|
||||
\
|
||||
__xx; \
|
||||
})
|
||||
|
||||
#define page_to_pa(page) \
|
||||
(page_to_pfn(page) << PAGE_SHIFT)
|
||||
|
||||
#define pfn_to_nid(pfn) pa_to_nid(((u64)(pfn) << PAGE_SHIFT))
|
||||
#define pfn_valid(pfn) \
|
||||
(((pfn) - node_start_pfn(pfn_to_nid(pfn))) < \
|
||||
node_spanned_pages(pfn_to_nid(pfn))) \
|
||||
|
||||
#define virt_addr_valid(kaddr) pfn_valid((__pa(kaddr) >> PAGE_SHIFT))
|
||||
|
||||
#endif /* CONFIG_DISCONTIGMEM */
|
||||
|
||||
#endif /* _ASM_MMZONE_H_ */
|
18
arch/alpha/include/asm/module.h
Normal file
18
arch/alpha/include/asm/module.h
Normal file
@ -0,0 +1,18 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ALPHA_MODULE_H
|
||||
#define _ALPHA_MODULE_H
|
||||
|
||||
#include <asm-generic/module.h>
|
||||
|
||||
struct mod_arch_specific
|
||||
{
|
||||
unsigned int gotsecindex;
|
||||
};
|
||||
|
||||
#define ARCH_SHF_SMALL SHF_ALPHA_GPREL
|
||||
|
||||
#ifdef MODULE
|
||||
asm(".section .got,\"aws\",@progbits; .align 3; .previous");
|
||||
#endif
|
||||
|
||||
#endif /*_ALPHA_MODULE_H*/
|
97
arch/alpha/include/asm/page.h
Normal file
97
arch/alpha/include/asm/page.h
Normal file
@ -0,0 +1,97 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ALPHA_PAGE_H
|
||||
#define _ALPHA_PAGE_H
|
||||
|
||||
#include <linux/const.h>
|
||||
#include <asm/pal.h>
|
||||
|
||||
/* PAGE_SHIFT determines the page size */
|
||||
#define PAGE_SHIFT 13
|
||||
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
|
||||
#define PAGE_MASK (~(PAGE_SIZE-1))
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#define STRICT_MM_TYPECHECKS
|
||||
|
||||
extern void clear_page(void *page);
|
||||
#define clear_user_page(page, vaddr, pg) clear_page(page)
|
||||
|
||||
#define alloc_zeroed_user_highpage_movable(vma, vaddr) \
|
||||
alloc_page_vma(GFP_HIGHUSER_MOVABLE | __GFP_ZERO, vma, vmaddr)
|
||||
#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE_MOVABLE
|
||||
|
||||
extern void copy_page(void * _to, void * _from);
|
||||
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
|
||||
|
||||
#ifdef STRICT_MM_TYPECHECKS
|
||||
/*
|
||||
* These are used to make use of C type-checking..
|
||||
*/
|
||||
typedef struct { unsigned long pte; } pte_t;
|
||||
typedef struct { unsigned long pmd; } pmd_t;
|
||||
typedef struct { unsigned long pgd; } pgd_t;
|
||||
typedef struct { unsigned long pgprot; } pgprot_t;
|
||||
|
||||
#define pte_val(x) ((x).pte)
|
||||
#define pmd_val(x) ((x).pmd)
|
||||
#define pgd_val(x) ((x).pgd)
|
||||
#define pgprot_val(x) ((x).pgprot)
|
||||
|
||||
#define __pte(x) ((pte_t) { (x) } )
|
||||
#define __pmd(x) ((pmd_t) { (x) } )
|
||||
#define __pgd(x) ((pgd_t) { (x) } )
|
||||
#define __pgprot(x) ((pgprot_t) { (x) } )
|
||||
|
||||
#else
|
||||
/*
|
||||
* .. while these make it easier on the compiler
|
||||
*/
|
||||
typedef unsigned long pte_t;
|
||||
typedef unsigned long pmd_t;
|
||||
typedef unsigned long pgd_t;
|
||||
typedef unsigned long pgprot_t;
|
||||
|
||||
#define pte_val(x) (x)
|
||||
#define pmd_val(x) (x)
|
||||
#define pgd_val(x) (x)
|
||||
#define pgprot_val(x) (x)
|
||||
|
||||
#define __pte(x) (x)
|
||||
#define __pgd(x) (x)
|
||||
#define __pgprot(x) (x)
|
||||
|
||||
#endif /* STRICT_MM_TYPECHECKS */
|
||||
|
||||
typedef struct page *pgtable_t;
|
||||
|
||||
#ifdef USE_48_BIT_KSEG
|
||||
#define PAGE_OFFSET 0xffff800000000000UL
|
||||
#else
|
||||
#define PAGE_OFFSET 0xfffffc0000000000UL
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifdef USE_48_BIT_KSEG
|
||||
#define PAGE_OFFSET 0xffff800000000000
|
||||
#else
|
||||
#define PAGE_OFFSET 0xfffffc0000000000
|
||||
#endif
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET)
|
||||
#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET))
|
||||
|
||||
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
|
||||
#define virt_addr_valid(kaddr) pfn_valid((__pa(kaddr) >> PAGE_SHIFT))
|
||||
|
||||
#ifdef CONFIG_FLATMEM
|
||||
#define pfn_valid(pfn) ((pfn) < max_mapnr)
|
||||
#endif /* CONFIG_FLATMEM */
|
||||
|
||||
#include <asm-generic/memory_model.h>
|
||||
#include <asm-generic/getorder.h>
|
||||
|
||||
#endif /* _ALPHA_PAGE_H */
|
187
arch/alpha/include/asm/pal.h
Normal file
187
arch/alpha/include/asm/pal.h
Normal file
@ -0,0 +1,187 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_PAL_H
|
||||
#define __ALPHA_PAL_H
|
||||
|
||||
#include <uapi/asm/pal.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern void halt(void) __attribute__((noreturn));
|
||||
#define __halt() __asm__ __volatile__ ("call_pal %0 #halt" : : "i" (PAL_halt))
|
||||
|
||||
#define imb() \
|
||||
__asm__ __volatile__ ("call_pal %0 #imb" : : "i" (PAL_imb) : "memory")
|
||||
|
||||
#define draina() \
|
||||
__asm__ __volatile__ ("call_pal %0 #draina" : : "i" (PAL_draina) : "memory")
|
||||
|
||||
#define __CALL_PAL_R0(NAME, TYPE) \
|
||||
extern inline TYPE NAME(void) \
|
||||
{ \
|
||||
register TYPE __r0 __asm__("$0"); \
|
||||
__asm__ __volatile__( \
|
||||
"call_pal %1 # " #NAME \
|
||||
:"=r" (__r0) \
|
||||
:"i" (PAL_ ## NAME) \
|
||||
:"$1", "$16", "$22", "$23", "$24", "$25"); \
|
||||
return __r0; \
|
||||
}
|
||||
|
||||
#define __CALL_PAL_W1(NAME, TYPE0) \
|
||||
extern inline void NAME(TYPE0 arg0) \
|
||||
{ \
|
||||
register TYPE0 __r16 __asm__("$16") = arg0; \
|
||||
__asm__ __volatile__( \
|
||||
"call_pal %1 # "#NAME \
|
||||
: "=r"(__r16) \
|
||||
: "i"(PAL_ ## NAME), "0"(__r16) \
|
||||
: "$1", "$22", "$23", "$24", "$25"); \
|
||||
}
|
||||
|
||||
#define __CALL_PAL_W2(NAME, TYPE0, TYPE1) \
|
||||
extern inline void NAME(TYPE0 arg0, TYPE1 arg1) \
|
||||
{ \
|
||||
register TYPE0 __r16 __asm__("$16") = arg0; \
|
||||
register TYPE1 __r17 __asm__("$17") = arg1; \
|
||||
__asm__ __volatile__( \
|
||||
"call_pal %2 # "#NAME \
|
||||
: "=r"(__r16), "=r"(__r17) \
|
||||
: "i"(PAL_ ## NAME), "0"(__r16), "1"(__r17) \
|
||||
: "$1", "$22", "$23", "$24", "$25"); \
|
||||
}
|
||||
|
||||
#define __CALL_PAL_RW1(NAME, RTYPE, TYPE0) \
|
||||
extern inline RTYPE NAME(TYPE0 arg0) \
|
||||
{ \
|
||||
register RTYPE __r0 __asm__("$0"); \
|
||||
register TYPE0 __r16 __asm__("$16") = arg0; \
|
||||
__asm__ __volatile__( \
|
||||
"call_pal %2 # "#NAME \
|
||||
: "=r"(__r16), "=r"(__r0) \
|
||||
: "i"(PAL_ ## NAME), "0"(__r16) \
|
||||
: "$1", "$22", "$23", "$24", "$25"); \
|
||||
return __r0; \
|
||||
}
|
||||
|
||||
#define __CALL_PAL_RW2(NAME, RTYPE, TYPE0, TYPE1) \
|
||||
extern inline RTYPE NAME(TYPE0 arg0, TYPE1 arg1) \
|
||||
{ \
|
||||
register RTYPE __r0 __asm__("$0"); \
|
||||
register TYPE0 __r16 __asm__("$16") = arg0; \
|
||||
register TYPE1 __r17 __asm__("$17") = arg1; \
|
||||
__asm__ __volatile__( \
|
||||
"call_pal %3 # "#NAME \
|
||||
: "=r"(__r16), "=r"(__r17), "=r"(__r0) \
|
||||
: "i"(PAL_ ## NAME), "0"(__r16), "1"(__r17) \
|
||||
: "$1", "$22", "$23", "$24", "$25"); \
|
||||
return __r0; \
|
||||
}
|
||||
|
||||
__CALL_PAL_W1(cflush, unsigned long);
|
||||
__CALL_PAL_R0(rdmces, unsigned long);
|
||||
__CALL_PAL_R0(rdps, unsigned long);
|
||||
__CALL_PAL_R0(rdusp, unsigned long);
|
||||
__CALL_PAL_RW1(swpipl, unsigned long, unsigned long);
|
||||
__CALL_PAL_R0(whami, unsigned long);
|
||||
__CALL_PAL_W2(wrent, void*, unsigned long);
|
||||
__CALL_PAL_W1(wripir, unsigned long);
|
||||
__CALL_PAL_W1(wrkgp, unsigned long);
|
||||
__CALL_PAL_W1(wrmces, unsigned long);
|
||||
__CALL_PAL_RW2(wrperfmon, unsigned long, unsigned long, unsigned long);
|
||||
__CALL_PAL_W1(wrusp, unsigned long);
|
||||
__CALL_PAL_W1(wrvptptr, unsigned long);
|
||||
__CALL_PAL_RW1(wtint, unsigned long, unsigned long);
|
||||
|
||||
/*
|
||||
* TB routines..
|
||||
*/
|
||||
#define __tbi(nr,arg,arg1...) \
|
||||
({ \
|
||||
register unsigned long __r16 __asm__("$16") = (nr); \
|
||||
register unsigned long __r17 __asm__("$17"); arg; \
|
||||
__asm__ __volatile__( \
|
||||
"call_pal %3 #__tbi" \
|
||||
:"=r" (__r16),"=r" (__r17) \
|
||||
:"0" (__r16),"i" (PAL_tbi) ,##arg1 \
|
||||
:"$0", "$1", "$22", "$23", "$24", "$25"); \
|
||||
})
|
||||
|
||||
#define tbi(x,y) __tbi(x,__r17=(y),"1" (__r17))
|
||||
#define tbisi(x) __tbi(1,__r17=(x),"1" (__r17))
|
||||
#define tbisd(x) __tbi(2,__r17=(x),"1" (__r17))
|
||||
#define tbis(x) __tbi(3,__r17=(x),"1" (__r17))
|
||||
#define tbiap() __tbi(-1, /* no second argument */)
|
||||
#define tbia() __tbi(-2, /* no second argument */)
|
||||
|
||||
/*
|
||||
* QEMU Cserv routines..
|
||||
*/
|
||||
|
||||
static inline unsigned long
|
||||
qemu_get_walltime(void)
|
||||
{
|
||||
register unsigned long v0 __asm__("$0");
|
||||
register unsigned long a0 __asm__("$16") = 3;
|
||||
|
||||
asm("call_pal %2 # cserve get_time"
|
||||
: "=r"(v0), "+r"(a0)
|
||||
: "i"(PAL_cserve)
|
||||
: "$17", "$18", "$19", "$20", "$21");
|
||||
|
||||
return v0;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
qemu_get_alarm(void)
|
||||
{
|
||||
register unsigned long v0 __asm__("$0");
|
||||
register unsigned long a0 __asm__("$16") = 4;
|
||||
|
||||
asm("call_pal %2 # cserve get_alarm"
|
||||
: "=r"(v0), "+r"(a0)
|
||||
: "i"(PAL_cserve)
|
||||
: "$17", "$18", "$19", "$20", "$21");
|
||||
|
||||
return v0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
qemu_set_alarm_rel(unsigned long expire)
|
||||
{
|
||||
register unsigned long a0 __asm__("$16") = 5;
|
||||
register unsigned long a1 __asm__("$17") = expire;
|
||||
|
||||
asm volatile("call_pal %2 # cserve set_alarm_rel"
|
||||
: "+r"(a0), "+r"(a1)
|
||||
: "i"(PAL_cserve)
|
||||
: "$0", "$18", "$19", "$20", "$21");
|
||||
}
|
||||
|
||||
static inline void
|
||||
qemu_set_alarm_abs(unsigned long expire)
|
||||
{
|
||||
register unsigned long a0 __asm__("$16") = 6;
|
||||
register unsigned long a1 __asm__("$17") = expire;
|
||||
|
||||
asm volatile("call_pal %2 # cserve set_alarm_abs"
|
||||
: "+r"(a0), "+r"(a1)
|
||||
: "i"(PAL_cserve)
|
||||
: "$0", "$18", "$19", "$20", "$21");
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
qemu_get_vmtime(void)
|
||||
{
|
||||
register unsigned long v0 __asm__("$0");
|
||||
register unsigned long a0 __asm__("$16") = 7;
|
||||
|
||||
asm("call_pal %2 # cserve get_time"
|
||||
: "=r"(v0), "+r"(a0)
|
||||
: "i"(PAL_cserve)
|
||||
: "$17", "$18", "$19", "$20", "$21");
|
||||
|
||||
return v0;
|
||||
}
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
#endif /* __ALPHA_PAL_H */
|
12
arch/alpha/include/asm/param.h
Normal file
12
arch/alpha/include/asm/param.h
Normal file
@ -0,0 +1,12 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_ALPHA_PARAM_H
|
||||
#define _ASM_ALPHA_PARAM_H
|
||||
|
||||
#include <uapi/asm/param.h>
|
||||
|
||||
# undef HZ
|
||||
# define HZ CONFIG_HZ
|
||||
# define USER_HZ 1024
|
||||
# define CLOCKS_PER_SEC USER_HZ /* frequency at which times() counts */
|
||||
|
||||
#endif /* _ASM_ALPHA_PARAM_H */
|
19
arch/alpha/include/asm/parport.h
Normal file
19
arch/alpha/include/asm/parport.h
Normal file
@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* parport.h: platform-specific PC-style parport initialisation
|
||||
*
|
||||
* Copyright (C) 1999, 2000 Tim Waugh <tim@cyberelk.demon.co.uk>
|
||||
*
|
||||
* This file should only be included by drivers/parport/parport_pc.c.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_AXP_PARPORT_H
|
||||
#define _ASM_AXP_PARPORT_H 1
|
||||
|
||||
static int parport_pc_find_isa_ports (int autoirq, int autodma);
|
||||
static int parport_pc_find_nonpci_ports (int autoirq, int autodma)
|
||||
{
|
||||
return parport_pc_find_isa_ports (autoirq, autodma);
|
||||
}
|
||||
|
||||
#endif /* !(_ASM_AXP_PARPORT_H) */
|
100
arch/alpha/include/asm/pci.h
Normal file
100
arch/alpha/include/asm/pci.h
Normal file
@ -0,0 +1,100 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_PCI_H
|
||||
#define __ALPHA_PCI_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <asm/machvec.h>
|
||||
|
||||
/*
|
||||
* The following structure is used to manage multiple PCI busses.
|
||||
*/
|
||||
|
||||
struct pci_iommu_arena;
|
||||
struct page;
|
||||
|
||||
/* A controller. Used to manage multiple PCI busses. */
|
||||
|
||||
struct pci_controller {
|
||||
struct pci_controller *next;
|
||||
struct pci_bus *bus;
|
||||
struct resource *io_space;
|
||||
struct resource *mem_space;
|
||||
|
||||
/* The following are for reporting to userland. The invariant is
|
||||
that if we report a BWX-capable dense memory, we do not report
|
||||
a sparse memory at all, even if it exists. */
|
||||
unsigned long sparse_mem_base;
|
||||
unsigned long dense_mem_base;
|
||||
unsigned long sparse_io_base;
|
||||
unsigned long dense_io_base;
|
||||
|
||||
/* This one's for the kernel only. It's in KSEG somewhere. */
|
||||
unsigned long config_space_base;
|
||||
|
||||
unsigned int index;
|
||||
/* For compatibility with current (as of July 2003) pciutils
|
||||
and XFree86. Eventually will be removed. */
|
||||
unsigned int need_domain_info;
|
||||
|
||||
struct pci_iommu_arena *sg_pci;
|
||||
struct pci_iommu_arena *sg_isa;
|
||||
|
||||
void *sysdata;
|
||||
};
|
||||
|
||||
/* Override the logic in pci_scan_bus for skipping already-configured
|
||||
bus numbers. */
|
||||
|
||||
#define pcibios_assign_all_busses() 1
|
||||
|
||||
#define PCIBIOS_MIN_IO alpha_mv.min_io_address
|
||||
#define PCIBIOS_MIN_MEM alpha_mv.min_mem_address
|
||||
|
||||
/* IOMMU controls. */
|
||||
|
||||
/* TODO: integrate with include/asm-generic/pci.h ? */
|
||||
static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
|
||||
{
|
||||
return channel ? 15 : 14;
|
||||
}
|
||||
|
||||
#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
|
||||
|
||||
static inline int pci_proc_domain(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_controller *hose = bus->sysdata;
|
||||
return hose->need_domain_info;
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
/* Values for the `which' argument to sys_pciconfig_iobase. */
|
||||
#define IOBASE_HOSE 0
|
||||
#define IOBASE_SPARSE_MEM 1
|
||||
#define IOBASE_DENSE_MEM 2
|
||||
#define IOBASE_SPARSE_IO 3
|
||||
#define IOBASE_DENSE_IO 4
|
||||
#define IOBASE_ROOT_BUS 5
|
||||
#define IOBASE_FROM_HOSE 0x10000
|
||||
|
||||
extern struct pci_dev *isa_bridge;
|
||||
|
||||
extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val,
|
||||
size_t count);
|
||||
extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val,
|
||||
size_t count);
|
||||
extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
|
||||
struct vm_area_struct *vma,
|
||||
enum pci_mmap_state mmap_state);
|
||||
extern void pci_adjust_legacy_attr(struct pci_bus *bus,
|
||||
enum pci_mmap_state mmap_type);
|
||||
#define HAVE_PCI_LEGACY 1
|
||||
|
||||
extern int pci_create_resource_files(struct pci_dev *dev);
|
||||
extern void pci_remove_resource_files(struct pci_dev *dev);
|
||||
|
||||
#endif /* __ALPHA_PCI_H */
|
19
arch/alpha/include/asm/percpu.h
Normal file
19
arch/alpha/include/asm/percpu.h
Normal file
@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_PERCPU_H
|
||||
#define __ALPHA_PERCPU_H
|
||||
|
||||
/*
|
||||
* To calculate addresses of locally defined variables, GCC uses
|
||||
* 32-bit displacement from the GP. Which doesn't work for per cpu
|
||||
* variables in modules, as an offset to the kernel per cpu area is
|
||||
* way above 4G.
|
||||
*
|
||||
* Always use weak definitions for percpu variables in modules.
|
||||
*/
|
||||
#if defined(MODULE) && defined(CONFIG_SMP)
|
||||
#define ARCH_NEEDS_WEAK_PER_CPU
|
||||
#endif
|
||||
|
||||
#include <asm-generic/percpu.h>
|
||||
|
||||
#endif /* __ALPHA_PERCPU_H */
|
4
arch/alpha/include/asm/perf_event.h
Normal file
4
arch/alpha/include/asm/perf_event.h
Normal file
@ -0,0 +1,4 @@
|
||||
#ifndef __ASM_ALPHA_PERF_EVENT_H
|
||||
#define __ASM_ALPHA_PERF_EVENT_H
|
||||
|
||||
#endif /* __ASM_ALPHA_PERF_EVENT_H */
|
36
arch/alpha/include/asm/pgalloc.h
Normal file
36
arch/alpha/include/asm/pgalloc.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ALPHA_PGALLOC_H
|
||||
#define _ALPHA_PGALLOC_H
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/mmzone.h>
|
||||
|
||||
#include <asm-generic/pgalloc.h>
|
||||
|
||||
/*
|
||||
* Allocate and free page tables. The xxx_kernel() versions are
|
||||
* used to allocate a kernel page table - this turns on ASN bits
|
||||
* if any.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t pte)
|
||||
{
|
||||
pmd_set(pmd, (pte_t *)(page_to_pa(pte) + PAGE_OFFSET));
|
||||
}
|
||||
|
||||
static inline void
|
||||
pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
|
||||
{
|
||||
pmd_set(pmd, pte);
|
||||
}
|
||||
|
||||
static inline void
|
||||
pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
|
||||
{
|
||||
pud_set(pud, pmd);
|
||||
}
|
||||
|
||||
extern pgd_t *pgd_alloc(struct mm_struct *mm);
|
||||
|
||||
#endif /* _ALPHA_PGALLOC_H */
|
346
arch/alpha/include/asm/pgtable.h
Normal file
346
arch/alpha/include/asm/pgtable.h
Normal file
@ -0,0 +1,346 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ALPHA_PGTABLE_H
|
||||
#define _ALPHA_PGTABLE_H
|
||||
|
||||
#include <asm-generic/pgtable-nopud.h>
|
||||
|
||||
/*
|
||||
* This file contains the functions and defines necessary to modify and use
|
||||
* the Alpha page table tree.
|
||||
*
|
||||
* This hopefully works with any standard Alpha page-size, as defined
|
||||
* in <asm/page.h> (currently 8192).
|
||||
*/
|
||||
#include <linux/mmzone.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/processor.h> /* For TASK_SIZE */
|
||||
#include <asm/machvec.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
struct mm_struct;
|
||||
struct vm_area_struct;
|
||||
|
||||
/* Certain architectures need to do special things when PTEs
|
||||
* within a page table are directly modified. Thus, the following
|
||||
* hook is made available.
|
||||
*/
|
||||
#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
|
||||
#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
|
||||
|
||||
/* PMD_SHIFT determines the size of the area a second-level page table can map */
|
||||
#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3))
|
||||
#define PMD_SIZE (1UL << PMD_SHIFT)
|
||||
#define PMD_MASK (~(PMD_SIZE-1))
|
||||
|
||||
/* PGDIR_SHIFT determines what a third-level page table entry can map */
|
||||
#define PGDIR_SHIFT (PAGE_SHIFT + 2*(PAGE_SHIFT-3))
|
||||
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
|
||||
#define PGDIR_MASK (~(PGDIR_SIZE-1))
|
||||
|
||||
/*
|
||||
* Entries per page directory level: the Alpha is three-level, with
|
||||
* all levels having a one-page page table.
|
||||
*/
|
||||
#define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3))
|
||||
#define PTRS_PER_PMD (1UL << (PAGE_SHIFT-3))
|
||||
#define PTRS_PER_PGD (1UL << (PAGE_SHIFT-3))
|
||||
#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
|
||||
|
||||
/* Number of pointers that fit on a page: this will go away. */
|
||||
#define PTRS_PER_PAGE (1UL << (PAGE_SHIFT-3))
|
||||
|
||||
#ifdef CONFIG_ALPHA_LARGE_VMALLOC
|
||||
#define VMALLOC_START 0xfffffe0000000000
|
||||
#else
|
||||
#define VMALLOC_START (-2*PGDIR_SIZE)
|
||||
#endif
|
||||
#define VMALLOC_END (-PGDIR_SIZE)
|
||||
|
||||
/*
|
||||
* OSF/1 PAL-code-imposed page table bits
|
||||
*/
|
||||
#define _PAGE_VALID 0x0001
|
||||
#define _PAGE_FOR 0x0002 /* used for page protection (fault on read) */
|
||||
#define _PAGE_FOW 0x0004 /* used for page protection (fault on write) */
|
||||
#define _PAGE_FOE 0x0008 /* used for page protection (fault on exec) */
|
||||
#define _PAGE_ASM 0x0010
|
||||
#define _PAGE_KRE 0x0100 /* xxx - see below on the "accessed" bit */
|
||||
#define _PAGE_URE 0x0200 /* xxx */
|
||||
#define _PAGE_KWE 0x1000 /* used to do the dirty bit in software */
|
||||
#define _PAGE_UWE 0x2000 /* used to do the dirty bit in software */
|
||||
|
||||
/* .. and these are ours ... */
|
||||
#define _PAGE_DIRTY 0x20000
|
||||
#define _PAGE_ACCESSED 0x40000
|
||||
|
||||
/*
|
||||
* NOTE! The "accessed" bit isn't necessarily exact: it can be kept exactly
|
||||
* by software (use the KRE/URE/KWE/UWE bits appropriately), but I'll fake it.
|
||||
* Under Linux/AXP, the "accessed" bit just means "read", and I'll just use
|
||||
* the KRE/URE bits to watch for it. That way we don't need to overload the
|
||||
* KWE/UWE bits with both handling dirty and accessed.
|
||||
*
|
||||
* Note that the kernel uses the accessed bit just to check whether to page
|
||||
* out a page or not, so it doesn't have to be exact anyway.
|
||||
*/
|
||||
|
||||
#define __DIRTY_BITS (_PAGE_DIRTY | _PAGE_KWE | _PAGE_UWE)
|
||||
#define __ACCESS_BITS (_PAGE_ACCESSED | _PAGE_KRE | _PAGE_URE)
|
||||
|
||||
#define _PFN_MASK 0xFFFFFFFF00000000UL
|
||||
|
||||
#define _PAGE_TABLE (_PAGE_VALID | __DIRTY_BITS | __ACCESS_BITS)
|
||||
#define _PAGE_CHG_MASK (_PFN_MASK | __DIRTY_BITS | __ACCESS_BITS)
|
||||
|
||||
/*
|
||||
* All the normal masks have the "page accessed" bits on, as any time they are used,
|
||||
* the page is accessed. They are cleared only by the page-out routines
|
||||
*/
|
||||
#define PAGE_NONE __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOR | _PAGE_FOW | _PAGE_FOE)
|
||||
#define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
|
||||
#define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
|
||||
#define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
|
||||
#define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
|
||||
|
||||
#define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
|
||||
|
||||
#define _PAGE_P(x) _PAGE_NORMAL((x) | (((x) & _PAGE_FOW)?0:_PAGE_FOW))
|
||||
#define _PAGE_S(x) _PAGE_NORMAL(x)
|
||||
|
||||
/*
|
||||
* The hardware can handle write-only mappings, but as the Alpha
|
||||
* architecture does byte-wide writes with a read-modify-write
|
||||
* sequence, it's not practical to have write-without-read privs.
|
||||
* Thus the "-w- -> rw-" and "-wx -> rwx" mapping here (and in
|
||||
* arch/alpha/mm/fault.c)
|
||||
*/
|
||||
/* xwr */
|
||||
#define __P000 _PAGE_P(_PAGE_FOE | _PAGE_FOW | _PAGE_FOR)
|
||||
#define __P001 _PAGE_P(_PAGE_FOE | _PAGE_FOW)
|
||||
#define __P010 _PAGE_P(_PAGE_FOE)
|
||||
#define __P011 _PAGE_P(_PAGE_FOE)
|
||||
#define __P100 _PAGE_P(_PAGE_FOW | _PAGE_FOR)
|
||||
#define __P101 _PAGE_P(_PAGE_FOW)
|
||||
#define __P110 _PAGE_P(0)
|
||||
#define __P111 _PAGE_P(0)
|
||||
|
||||
#define __S000 _PAGE_S(_PAGE_FOE | _PAGE_FOW | _PAGE_FOR)
|
||||
#define __S001 _PAGE_S(_PAGE_FOE | _PAGE_FOW)
|
||||
#define __S010 _PAGE_S(_PAGE_FOE)
|
||||
#define __S011 _PAGE_S(_PAGE_FOE)
|
||||
#define __S100 _PAGE_S(_PAGE_FOW | _PAGE_FOR)
|
||||
#define __S101 _PAGE_S(_PAGE_FOW)
|
||||
#define __S110 _PAGE_S(0)
|
||||
#define __S111 _PAGE_S(0)
|
||||
|
||||
/*
|
||||
* pgprot_noncached() is only for infiniband pci support, and a real
|
||||
* implementation for RAM would be more complicated.
|
||||
*/
|
||||
#define pgprot_noncached(prot) (prot)
|
||||
|
||||
/*
|
||||
* BAD_PAGETABLE is used when we need a bogus page-table, while
|
||||
* BAD_PAGE is used for a bogus page.
|
||||
*
|
||||
* ZERO_PAGE is a global shared page that is always zero: used
|
||||
* for zero-mapped memory areas etc..
|
||||
*/
|
||||
extern pte_t __bad_page(void);
|
||||
extern pmd_t * __bad_pagetable(void);
|
||||
|
||||
extern unsigned long __zero_page(void);
|
||||
|
||||
#define BAD_PAGETABLE __bad_pagetable()
|
||||
#define BAD_PAGE __bad_page()
|
||||
#define ZERO_PAGE(vaddr) (virt_to_page(ZERO_PGE))
|
||||
|
||||
/* number of bits that fit into a memory pointer */
|
||||
#define BITS_PER_PTR (8*sizeof(unsigned long))
|
||||
|
||||
/* to align the pointer to a pointer address */
|
||||
#define PTR_MASK (~(sizeof(void*)-1))
|
||||
|
||||
/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
|
||||
#define SIZEOF_PTR_LOG2 3
|
||||
|
||||
/* to find an entry in a page-table */
|
||||
#define PAGE_PTR(address) \
|
||||
((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
|
||||
|
||||
/*
|
||||
* On certain platforms whose physical address space can overlap KSEG,
|
||||
* namely EV6 and above, we must re-twiddle the physaddr to restore the
|
||||
* correct high-order bits.
|
||||
*
|
||||
* This is extremely confusing until you realize that this is actually
|
||||
* just working around a userspace bug. The X server was intending to
|
||||
* provide the physical address but instead provided the KSEG address.
|
||||
* Or tried to, except it's not representable.
|
||||
*
|
||||
* On Tsunami there's nothing meaningful at 0x40000000000, so this is
|
||||
* a safe thing to do. Come the first core logic that does put something
|
||||
* in this area -- memory or whathaveyou -- then this hack will have
|
||||
* to go away. So be prepared!
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ALPHA_GENERIC) && defined(USE_48_BIT_KSEG)
|
||||
#error "EV6-only feature in a generic kernel"
|
||||
#endif
|
||||
#if defined(CONFIG_ALPHA_GENERIC) || \
|
||||
(defined(CONFIG_ALPHA_EV6) && !defined(USE_48_BIT_KSEG))
|
||||
#define KSEG_PFN (0xc0000000000UL >> PAGE_SHIFT)
|
||||
#define PHYS_TWIDDLE(pfn) \
|
||||
((((pfn) & KSEG_PFN) == (0x40000000000UL >> PAGE_SHIFT)) \
|
||||
? ((pfn) ^= KSEG_PFN) : (pfn))
|
||||
#else
|
||||
#define PHYS_TWIDDLE(pfn) (pfn)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Conversion functions: convert a page and protection to a page entry,
|
||||
* and a page entry and page directory to the page they refer to.
|
||||
*/
|
||||
#define page_to_pa(page) (page_to_pfn(page) << PAGE_SHIFT)
|
||||
#define pte_pfn(pte) (pte_val(pte) >> 32)
|
||||
|
||||
#define pte_page(pte) pfn_to_page(pte_pfn(pte))
|
||||
#define mk_pte(page, pgprot) \
|
||||
({ \
|
||||
pte_t pte; \
|
||||
\
|
||||
pte_val(pte) = (page_to_pfn(page) << 32) | pgprot_val(pgprot); \
|
||||
pte; \
|
||||
})
|
||||
|
||||
extern inline pte_t pfn_pte(unsigned long physpfn, pgprot_t pgprot)
|
||||
{ pte_t pte; pte_val(pte) = (PHYS_TWIDDLE(physpfn) << 32) | pgprot_val(pgprot); return pte; }
|
||||
|
||||
extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
||||
{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
|
||||
|
||||
extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
|
||||
{ pmd_val(*pmdp) = _PAGE_TABLE | ((((unsigned long) ptep) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }
|
||||
|
||||
extern inline void pud_set(pud_t * pudp, pmd_t * pmdp)
|
||||
{ pud_val(*pudp) = _PAGE_TABLE | ((((unsigned long) pmdp) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }
|
||||
|
||||
|
||||
extern inline unsigned long
|
||||
pmd_page_vaddr(pmd_t pmd)
|
||||
{
|
||||
return ((pmd_val(pmd) & _PFN_MASK) >> (32-PAGE_SHIFT)) + PAGE_OFFSET;
|
||||
}
|
||||
|
||||
#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> 32))
|
||||
#define pud_page(pud) (pfn_to_page(pud_val(pud) >> 32))
|
||||
|
||||
extern inline pmd_t *pud_pgtable(pud_t pgd)
|
||||
{
|
||||
return (pmd_t *)(PAGE_OFFSET + ((pud_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT)));
|
||||
}
|
||||
|
||||
extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
|
||||
extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_VALID; }
|
||||
extern inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
pte_val(*ptep) = 0;
|
||||
}
|
||||
|
||||
extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); }
|
||||
extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~_PFN_MASK) != _PAGE_TABLE; }
|
||||
extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_VALID; }
|
||||
extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = 0; }
|
||||
|
||||
extern inline int pud_none(pud_t pud) { return !pud_val(pud); }
|
||||
extern inline int pud_bad(pud_t pud) { return (pud_val(pud) & ~_PFN_MASK) != _PAGE_TABLE; }
|
||||
extern inline int pud_present(pud_t pud) { return pud_val(pud) & _PAGE_VALID; }
|
||||
extern inline void pud_clear(pud_t * pudp) { pud_val(*pudp) = 0; }
|
||||
|
||||
/*
|
||||
* The following only work if pte_present() is true.
|
||||
* Undefined behaviour if not..
|
||||
*/
|
||||
extern inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_FOW); }
|
||||
extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
|
||||
extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
|
||||
|
||||
extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_FOW; return pte; }
|
||||
extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~(__DIRTY_BITS); return pte; }
|
||||
extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~(__ACCESS_BITS); return pte; }
|
||||
extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_FOW; return pte; }
|
||||
extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= __DIRTY_BITS; return pte; }
|
||||
extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= __ACCESS_BITS; return pte; }
|
||||
|
||||
/*
|
||||
* The smp_rmb() in the following functions are required to order the load of
|
||||
* *dir (the pointer in the top level page table) with any subsequent load of
|
||||
* the returned pmd_t *ret (ret is data dependent on *dir).
|
||||
*
|
||||
* If this ordering is not enforced, the CPU might load an older value of
|
||||
* *ret, which may be uninitialized data. See mm/memory.c:__pte_alloc for
|
||||
* more details.
|
||||
*
|
||||
* Note that we never change the mm->pgd pointer after the task is running, so
|
||||
* pgd_offset does not require such a barrier.
|
||||
*/
|
||||
|
||||
/* Find an entry in the second-level page table.. */
|
||||
extern inline pmd_t * pmd_offset(pud_t * dir, unsigned long address)
|
||||
{
|
||||
pmd_t *ret = pud_pgtable(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
|
||||
smp_rmb(); /* see above */
|
||||
return ret;
|
||||
}
|
||||
#define pmd_offset pmd_offset
|
||||
|
||||
/* Find an entry in the third-level page table.. */
|
||||
extern inline pte_t * pte_offset_kernel(pmd_t * dir, unsigned long address)
|
||||
{
|
||||
pte_t *ret = (pte_t *) pmd_page_vaddr(*dir)
|
||||
+ ((address >> PAGE_SHIFT) & (PTRS_PER_PAGE - 1));
|
||||
smp_rmb(); /* see above */
|
||||
return ret;
|
||||
}
|
||||
#define pte_offset_kernel pte_offset_kernel
|
||||
|
||||
extern pgd_t swapper_pg_dir[1024];
|
||||
|
||||
/*
|
||||
* The Alpha doesn't have any external MMU info: the kernel page
|
||||
* tables contain all the necessary information.
|
||||
*/
|
||||
extern inline void update_mmu_cache(struct vm_area_struct * vma,
|
||||
unsigned long address, pte_t *ptep)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Non-present pages: high 24 bits are offset, next 8 bits type,
|
||||
* low 32 bits zero.
|
||||
*/
|
||||
extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
|
||||
{ pte_t pte; pte_val(pte) = (type << 32) | (offset << 40); return pte; }
|
||||
|
||||
#define __swp_type(x) (((x).val >> 32) & 0xff)
|
||||
#define __swp_offset(x) ((x).val >> 40)
|
||||
#define __swp_entry(type, off) ((swp_entry_t) { pte_val(mk_swap_pte((type), (off))) })
|
||||
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
|
||||
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
|
||||
|
||||
#define kern_addr_valid(addr) (1)
|
||||
|
||||
#define pte_ERROR(e) \
|
||||
printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
|
||||
#define pmd_ERROR(e) \
|
||||
printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
|
||||
#define pgd_ERROR(e) \
|
||||
printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))
|
||||
|
||||
extern void paging_init(void);
|
||||
|
||||
/* We have our own get_unmapped_area to cope with ADDR_LIMIT_32BIT. */
|
||||
#define HAVE_ARCH_UNMAPPED_AREA
|
||||
|
||||
#endif /* _ALPHA_PGTABLE_H */
|
80
arch/alpha/include/asm/processor.h
Normal file
80
arch/alpha/include/asm/processor.h
Normal file
@ -0,0 +1,80 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* include/asm-alpha/processor.h
|
||||
*
|
||||
* Copyright (C) 1994 Linus Torvalds
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ALPHA_PROCESSOR_H
|
||||
#define __ASM_ALPHA_PROCESSOR_H
|
||||
|
||||
#include <linux/personality.h> /* for ADDR_LIMIT_32BIT */
|
||||
|
||||
/*
|
||||
* We have a 42-bit user address space: 4TB user VM...
|
||||
*/
|
||||
#define TASK_SIZE (0x40000000000UL)
|
||||
|
||||
#define STACK_TOP \
|
||||
(current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
|
||||
|
||||
#define STACK_TOP_MAX 0x00120000000UL
|
||||
|
||||
/* This decides where the kernel will search for a free chunk of vm
|
||||
* space during mmap's.
|
||||
*/
|
||||
#define TASK_UNMAPPED_BASE \
|
||||
((current->personality & ADDR_LIMIT_32BIT) ? 0x40000000 : TASK_SIZE / 2)
|
||||
|
||||
typedef struct {
|
||||
unsigned long seg;
|
||||
} mm_segment_t;
|
||||
|
||||
/* This is dead. Everything has been moved to thread_info. */
|
||||
struct thread_struct { };
|
||||
#define INIT_THREAD { }
|
||||
|
||||
/* Do necessary setup to start up a newly executed thread. */
|
||||
struct pt_regs;
|
||||
extern void start_thread(struct pt_regs *, unsigned long, unsigned long);
|
||||
|
||||
/* Free all resources held by a thread. */
|
||||
struct task_struct;
|
||||
extern void release_thread(struct task_struct *);
|
||||
|
||||
unsigned long __get_wchan(struct task_struct *p);
|
||||
|
||||
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
|
||||
|
||||
#define KSTK_ESP(tsk) \
|
||||
((tsk) == current ? rdusp() : task_thread_info(tsk)->pcb.usp)
|
||||
|
||||
#define cpu_relax() barrier()
|
||||
|
||||
#define ARCH_HAS_PREFETCH
|
||||
#define ARCH_HAS_PREFETCHW
|
||||
#define ARCH_HAS_SPINLOCK_PREFETCH
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
/* Nothing to prefetch. */
|
||||
#define spin_lock_prefetch(lock) do { } while (0)
|
||||
#endif
|
||||
|
||||
extern inline void prefetch(const void *ptr)
|
||||
{
|
||||
__builtin_prefetch(ptr, 0, 3);
|
||||
}
|
||||
|
||||
extern inline void prefetchw(const void *ptr)
|
||||
{
|
||||
__builtin_prefetch(ptr, 1, 3);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
extern inline void spin_lock_prefetch(const void *ptr)
|
||||
{
|
||||
__builtin_prefetch(ptr, 1, 3);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_ALPHA_PROCESSOR_H */
|
28
arch/alpha/include/asm/ptrace.h
Normal file
28
arch/alpha/include/asm/ptrace.h
Normal file
@ -0,0 +1,28 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASMAXP_PTRACE_H
|
||||
#define _ASMAXP_PTRACE_H
|
||||
|
||||
#include <uapi/asm/ptrace.h>
|
||||
|
||||
|
||||
#define arch_has_single_step() (1)
|
||||
#define user_mode(regs) (((regs)->ps & 8) != 0)
|
||||
#define instruction_pointer(regs) ((regs)->pc)
|
||||
#define profile_pc(regs) instruction_pointer(regs)
|
||||
#define current_user_stack_pointer() rdusp()
|
||||
|
||||
#define task_pt_regs(task) \
|
||||
((struct pt_regs *) (task_stack_page(task) + 2*PAGE_SIZE) - 1)
|
||||
|
||||
#define current_pt_regs() \
|
||||
((struct pt_regs *) ((char *)current_thread_info() + 2*PAGE_SIZE) - 1)
|
||||
#define signal_pt_regs current_pt_regs
|
||||
|
||||
#define force_successful_syscall_return() (current_pt_regs()->r0 = 0)
|
||||
|
||||
static inline unsigned long regs_return_value(struct pt_regs *regs)
|
||||
{
|
||||
return regs->r0;
|
||||
}
|
||||
|
||||
#endif
|
35
arch/alpha/include/asm/rwonce.h
Normal file
35
arch/alpha/include/asm/rwonce.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2019 Google LLC.
|
||||
*/
|
||||
#ifndef __ASM_RWONCE_H
|
||||
#define __ASM_RWONCE_H
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
#include <asm/barrier.h>
|
||||
|
||||
/*
|
||||
* Alpha is apparently daft enough to reorder address-dependent loads
|
||||
* on some CPU implementations. Knock some common sense into it with
|
||||
* a memory barrier in READ_ONCE().
|
||||
*
|
||||
* For the curious, more information about this unusual reordering is
|
||||
* available in chapter 15 of the "perfbook":
|
||||
*
|
||||
* https://kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.html
|
||||
*
|
||||
*/
|
||||
#define __READ_ONCE(x) \
|
||||
({ \
|
||||
__unqual_scalar_typeof(x) __x = \
|
||||
(*(volatile typeof(__x) *)(&(x))); \
|
||||
mb(); \
|
||||
(typeof(x))__x; \
|
||||
})
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#include <asm-generic/rwonce.h>
|
||||
|
||||
#endif /* __ASM_RWONCE_H */
|
30
arch/alpha/include/asm/serial.h
Normal file
30
arch/alpha/include/asm/serial.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* include/asm-alpha/serial.h
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This assumes you have a 1.8432 MHz clock for your UART.
|
||||
*
|
||||
* It'd be nice if someone built a serial card with a 24.576 MHz
|
||||
* clock, since the 16550A is capable of handling a top speed of 1.5
|
||||
* megabits/second; but this requires the faster clock.
|
||||
*/
|
||||
#define BASE_BAUD ( 1843200 / 16 )
|
||||
|
||||
/* Standard COM flags (except for COM4, because of the 8514 problem) */
|
||||
#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
|
||||
#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ)
|
||||
#define STD_COM4_FLAGS (UPF_BOOT_AUTOCONF | UPF_AUTO_IRQ)
|
||||
#else
|
||||
#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST)
|
||||
#define STD_COM4_FLAGS UPF_BOOT_AUTOCONF
|
||||
#endif
|
||||
|
||||
#define SERIAL_PORT_DFNS \
|
||||
/* UART CLK PORT IRQ FLAGS */ \
|
||||
{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
|
||||
{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
|
||||
{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \
|
||||
{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
|
43
arch/alpha/include/asm/setup.h
Normal file
43
arch/alpha/include/asm/setup.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef __ALPHA_SETUP_H
|
||||
#define __ALPHA_SETUP_H
|
||||
|
||||
#include <uapi/asm/setup.h>
|
||||
|
||||
/*
|
||||
* We leave one page for the initial stack page, and one page for
|
||||
* the initial process structure. Also, the console eats 3 MB for
|
||||
* the initial bootloader (one of which we can reclaim later).
|
||||
*/
|
||||
#define BOOT_PCB 0x20000000
|
||||
#define BOOT_ADDR 0x20000000
|
||||
/* Remove when official MILO sources have ELF support: */
|
||||
#define BOOT_SIZE (16*1024)
|
||||
|
||||
#ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS
|
||||
#define KERNEL_START_PHYS 0x300000 /* Old bootloaders hardcoded this. */
|
||||
#else
|
||||
#define KERNEL_START_PHYS 0x1000000 /* required: Wildfire/Titan/Marvel */
|
||||
#endif
|
||||
|
||||
#define KERNEL_START (PAGE_OFFSET+KERNEL_START_PHYS)
|
||||
#define SWAPPER_PGD KERNEL_START
|
||||
#define INIT_STACK (PAGE_OFFSET+KERNEL_START_PHYS+0x02000)
|
||||
#define EMPTY_PGT (PAGE_OFFSET+KERNEL_START_PHYS+0x04000)
|
||||
#define EMPTY_PGE (PAGE_OFFSET+KERNEL_START_PHYS+0x08000)
|
||||
#define ZERO_PGE (PAGE_OFFSET+KERNEL_START_PHYS+0x0A000)
|
||||
|
||||
#define START_ADDR (PAGE_OFFSET+KERNEL_START_PHYS+0x10000)
|
||||
|
||||
/*
|
||||
* This is setup by the secondary bootstrap loader. Because
|
||||
* the zero page is zeroed out as soon as the vm system is
|
||||
* initialized, we need to copy things out into a more permanent
|
||||
* place.
|
||||
*/
|
||||
#define PARAM ZERO_PGE
|
||||
#define COMMAND_LINE ((char *)(absolute_pointer(PARAM + 0x0000)))
|
||||
#define INITRD_START (*(unsigned long *) (PARAM+0x100))
|
||||
#define INITRD_SIZE (*(unsigned long *) (PARAM+0x108))
|
||||
|
||||
#endif
|
82
arch/alpha/include/asm/sfp-machine.h
Normal file
82
arch/alpha/include/asm/sfp-machine.h
Normal file
@ -0,0 +1,82 @@
|
||||
/* Machine-dependent software floating-point definitions.
|
||||
Alpha kernel version.
|
||||
Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com),
|
||||
Jakub Jelinek (jakub@redhat.com) and
|
||||
David S. Miller (davem@redhat.com).
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _SFP_MACHINE_H
|
||||
#define _SFP_MACHINE_H
|
||||
|
||||
#define _FP_W_TYPE_SIZE 64
|
||||
#define _FP_W_TYPE unsigned long
|
||||
#define _FP_WS_TYPE signed long
|
||||
#define _FP_I_TYPE long
|
||||
|
||||
#define _FP_MUL_MEAT_S(R,X,Y) \
|
||||
_FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
|
||||
#define _FP_MUL_MEAT_D(R,X,Y) \
|
||||
_FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
|
||||
#define _FP_MUL_MEAT_Q(R,X,Y) \
|
||||
_FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
|
||||
|
||||
#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
|
||||
#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv(D,R,X,Y)
|
||||
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
|
||||
|
||||
#define _FP_NANFRAC_S _FP_QNANBIT_S
|
||||
#define _FP_NANFRAC_D _FP_QNANBIT_D
|
||||
#define _FP_NANFRAC_Q _FP_QNANBIT_Q
|
||||
#define _FP_NANSIGN_S 1
|
||||
#define _FP_NANSIGN_D 1
|
||||
#define _FP_NANSIGN_Q 1
|
||||
|
||||
#define _FP_KEEPNANFRACP 1
|
||||
|
||||
/* Alpha Architecture Handbook, 4.7.10.4 sais that
|
||||
* we should prefer any type of NaN in Fb, then Fa.
|
||||
*/
|
||||
#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
|
||||
do { \
|
||||
R##_s = Y##_s; \
|
||||
_FP_FRAC_COPY_##wc(R,X); \
|
||||
R##_c = FP_CLS_NAN; \
|
||||
} while (0)
|
||||
|
||||
/* Obtain the current rounding mode. */
|
||||
#define FP_ROUNDMODE mode
|
||||
#define FP_RND_NEAREST (FPCR_DYN_NORMAL >> FPCR_DYN_SHIFT)
|
||||
#define FP_RND_ZERO (FPCR_DYN_CHOPPED >> FPCR_DYN_SHIFT)
|
||||
#define FP_RND_PINF (FPCR_DYN_PLUS >> FPCR_DYN_SHIFT)
|
||||
#define FP_RND_MINF (FPCR_DYN_MINUS >> FPCR_DYN_SHIFT)
|
||||
|
||||
/* Exception flags. */
|
||||
#define FP_EX_INVALID IEEE_TRAP_ENABLE_INV
|
||||
#define FP_EX_OVERFLOW IEEE_TRAP_ENABLE_OVF
|
||||
#define FP_EX_UNDERFLOW IEEE_TRAP_ENABLE_UNF
|
||||
#define FP_EX_DIVZERO IEEE_TRAP_ENABLE_DZE
|
||||
#define FP_EX_INEXACT IEEE_TRAP_ENABLE_INE
|
||||
#define FP_EX_DENORM IEEE_TRAP_ENABLE_DNO
|
||||
|
||||
#define FP_DENORM_ZERO (swcr & IEEE_MAP_DMZ)
|
||||
|
||||
/* We write the results always */
|
||||
#define FP_INHIBIT_RESULTS 0
|
||||
|
||||
#endif
|
7
arch/alpha/include/asm/shmparam.h
Normal file
7
arch/alpha/include/asm/shmparam.h
Normal file
@ -0,0 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASMAXP_SHMPARAM_H
|
||||
#define _ASMAXP_SHMPARAM_H
|
||||
|
||||
#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
|
||||
|
||||
#endif /* _ASMAXP_SHMPARAM_H */
|
28
arch/alpha/include/asm/signal.h
Normal file
28
arch/alpha/include/asm/signal.h
Normal file
@ -0,0 +1,28 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASMAXP_SIGNAL_H
|
||||
#define _ASMAXP_SIGNAL_H
|
||||
|
||||
#include <uapi/asm/signal.h>
|
||||
|
||||
/* Digital Unix defines 64 signals. Most things should be clean enough
|
||||
to redefine this at will, if care is taken to make libc match. */
|
||||
|
||||
#define _NSIG 64
|
||||
#define _NSIG_BPW 64
|
||||
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
|
||||
|
||||
typedef unsigned long old_sigset_t; /* at least 32 bits */
|
||||
|
||||
typedef struct {
|
||||
unsigned long sig[_NSIG_WORDS];
|
||||
} sigset_t;
|
||||
|
||||
struct osf_sigaction {
|
||||
__sighandler_t sa_handler;
|
||||
old_sigset_t sa_mask;
|
||||
int sa_flags;
|
||||
};
|
||||
|
||||
#define __ARCH_HAS_KA_RESTORER
|
||||
#include <asm/sigcontext.h>
|
||||
#endif
|
60
arch/alpha/include/asm/smp.h
Normal file
60
arch/alpha/include/asm/smp.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_SMP_H
|
||||
#define __ASM_SMP_H
|
||||
|
||||
#include <linux/threads.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <asm/pal.h>
|
||||
|
||||
/* HACK: Cabrio WHAMI return value is bogus if more than 8 bits used.. :-( */
|
||||
|
||||
static __inline__ unsigned char
|
||||
__hard_smp_processor_id(void)
|
||||
{
|
||||
register unsigned char __r0 __asm__("$0");
|
||||
__asm__ __volatile__(
|
||||
"call_pal %1 #whami"
|
||||
: "=r"(__r0)
|
||||
:"i" (PAL_whami)
|
||||
: "$1", "$22", "$23", "$24", "$25");
|
||||
return __r0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
#include <asm/irq.h>
|
||||
|
||||
struct cpuinfo_alpha {
|
||||
unsigned long loops_per_jiffy;
|
||||
unsigned long last_asn;
|
||||
int need_new_asn;
|
||||
int asn_lock;
|
||||
unsigned long ipi_count;
|
||||
unsigned long prof_multiplier;
|
||||
unsigned long prof_counter;
|
||||
unsigned char mcheck_expected;
|
||||
unsigned char mcheck_taken;
|
||||
unsigned char mcheck_extra;
|
||||
} __attribute__((aligned(64)));
|
||||
|
||||
extern struct cpuinfo_alpha cpu_data[NR_CPUS];
|
||||
|
||||
#define hard_smp_processor_id() __hard_smp_processor_id()
|
||||
#define raw_smp_processor_id() (current_thread_info()->cpu)
|
||||
|
||||
extern int smp_num_cpus;
|
||||
|
||||
extern void arch_send_call_function_single_ipi(int cpu);
|
||||
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
|
||||
|
||||
#else /* CONFIG_SMP */
|
||||
|
||||
#define hard_smp_processor_id() 0
|
||||
#define smp_call_function_on_cpu(func,info,wait,cpu) ({ 0; })
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#define NO_PROC_ID (-1)
|
||||
|
||||
#endif
|
11
arch/alpha/include/asm/socket.h
Normal file
11
arch/alpha/include/asm/socket.h
Normal file
@ -0,0 +1,11 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_SOCKET_H
|
||||
#define _ASM_SOCKET_H
|
||||
|
||||
#include <uapi/asm/socket.h>
|
||||
|
||||
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
|
||||
* have to define SOCK_NONBLOCK to a different value here.
|
||||
*/
|
||||
#define SOCK_NONBLOCK 0x40000000
|
||||
#endif /* _ASM_SOCKET_H */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user