Commit fd8773f9 authored by Arnd Bergmann's avatar Arnd Bergmann

arch: remove frv port

The Fujitsu FRV kernel port has been around for a long time, but has not
seen regular updates in several years and instead was marked 'Orphaned'
in 2016 by long-time maintainer David Howells.

The SoC product line apparently is apparently still around in the form
of the Socionext Milbeaut image processor, but this one no longer uses
the FRV CPU cores.

This removes all FRV specific files from the kernel.

Link: http://www.socionext.com/en/products/assp/milbeaut/
Cc: David Howells <dhowells@redhat.com>
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parent 739d875d
......@@ -172,8 +172,6 @@ fmc/
- information about the FMC bus abstraction
fpga/
- FPGA Manager Core.
frv/
- Fujitsu FR-V Linux documentation.
futex-requeue-pi.txt
- info on requeueing of tasks from a non-PI futex to a PI futex
gcc-plugins.txt
......
================================
Fujitsu FR-V LINUX DOCUMENTATION
================================
This directory contains documentation for the Fujitsu FR-V CPU architecture
port of Linux.
The following documents are available:
(*) features.txt
A description of the basic features inherent in this architecture port.
(*) configuring.txt
A summary of the configuration options particular to this architecture.
(*) booting.txt
A description of how to boot the kernel image and a summary of the kernel
command line options.
(*) gdbstub.txt
A description of how to debug the kernel using GDB attached by serial
port, and a summary of the services available.
(*) mmu-layout.txt
A description of the virtual and physical memory layout used in the
MMU linux kernel, and the registers used to support it.
(*) gdbinit
An example .gdbinit file for use with GDB. It includes macros for viewing
MMU state on the FR451. See mmu-layout.txt for more information.
(*) clock.txt
A description of the CPU clock scaling interface.
(*) atomic-ops.txt
A description of how the FR-V kernel's atomic operations work.
=====================================
FUJITSU FR-V KERNEL ATOMIC OPERATIONS
=====================================
On the FR-V CPUs, there is only one atomic Read-Modify-Write operation: the SWAP/SWAPI
instruction. Unfortunately, this alone can't be used to implement the following operations:
(*) Atomic add to memory
(*) Atomic subtract from memory
(*) Atomic bit modification (set, clear or invert)
(*) Atomic compare and exchange
On such CPUs, the standard way of emulating such operations in uniprocessor mode is to disable
interrupts, but on the FR-V CPUs, modifying the PSR takes a lot of clock cycles, and it has to be
done twice. This means the CPU runs for a relatively long time with interrupts disabled,
potentially having a great effect on interrupt latency.
=============
NEW ALGORITHM
=============
To get around this, the following algorithm has been implemented. It operates in a way similar to
the LL/SC instruction pairs supported on a number of platforms.
(*) The CCCR.CC3 register is reserved within the kernel to act as an atomic modify abort flag.
(*) In the exception prologues run on kernel->kernel entry, CCCR.CC3 is set to 0 (Undefined
state).
(*) All atomic operations can then be broken down into the following algorithm:
(1) Set ICC3.Z to true and set CC3 to True (ORCC/CKEQ/ORCR).
(2) Load the value currently in the memory to be modified into a register.
(3) Make changes to the value.
(4) If CC3 is still True, simultaneously and atomically (by VLIW packing):
(a) Store the modified value back to memory.
(b) Set ICC3.Z to false (CORCC on GR29 is sufficient for this - GR29 holds the current
task pointer in the kernel, and so is guaranteed to be non-zero).
(5) If ICC3.Z is still true, go back to step (1).
This works in a non-SMP environment because any interrupt or other exception that happens between
steps (1) and (4) will set CC3 to the Undefined, thus aborting the store in (4a), and causing the
condition in ICC3 to remain with the Z flag set, thus causing step (5) to loop back to step (1).
This algorithm suffers from two problems:
(1) The condition CCCR.CC3 is cleared unconditionally by an exception, irrespective of whether or
not any changes were made to the target memory location during that exception.
(2) The branch from step (5) back to step (1) may have to happen more than once until the store
manages to take place. In theory, this loop could cycle forever because there are too many
interrupts coming in, but it's unlikely.
=======
EXAMPLE
=======
Taking an example from include/asm-frv/atomic.h:
static inline int atomic_add_return(int i, atomic_t *v)
{
unsigned long val;
asm("0: \n"
It starts by setting ICC3.Z to true for later use, and also transforming that into CC3 being in the
True state.
" orcc gr0,gr0,gr0,icc3 \n" <-- (1)
" ckeq icc3,cc7 \n" <-- (1)
Then it does the load. Note that the final phase of step (1) is done at the same time as the
load. The VLIW packing ensures they are done simultaneously. The ".p" on the load must not be
removed without swapping the order of these two instructions.
" ld.p %M0,%1 \n" <-- (2)
" orcr cc7,cc7,cc3 \n" <-- (1)
Then the proposed modification is generated. Note that the old value can be retained if required
(such as in test_and_set_bit()).
" add%I2 %1,%2,%1 \n" <-- (3)
Then it attempts to store the value back, contingent on no exception having cleared CC3 since it
was set to True.
" cst.p %1,%M0 ,cc3,#1 \n" <-- (4a)
It simultaneously records the success or failure of the store in ICC3.Z.
" corcc gr29,gr29,gr0 ,cc3,#1 \n" <-- (4b)
Such that the branch can then be taken if the operation was aborted.
" beq icc3,#0,0b \n" <-- (5)
: "+U"(v->counter), "=&r"(val)
: "NPr"(i)
: "memory", "cc7", "cc3", "icc3"
);
return val;
}
=============
CONFIGURATION
=============
The atomic ops implementation can be made inline or out-of-line by changing the
CONFIG_FRV_OUTOFLINE_ATOMIC_OPS configuration variable. Making it out-of-line has a number of
advantages:
- The resulting kernel image may be smaller
- Debugging is easier as atomic ops can just be stepped over and they can be breakpointed
Keeping it inline also has a number of advantages:
- The resulting kernel may be Faster
- no out-of-line function calls need to be made
- the compiler doesn't have half its registers clobbered by making a call
The out-of-line implementations live in arch/frv/lib/atomic-ops.S.
=========================
BOOTING FR-V LINUX KERNEL
=========================
======================
PROVIDING A FILESYSTEM
======================
First of all, a root filesystem must be made available. This can be done in
one of two ways:
(1) NFS Export
A filesystem should be constructed in a directory on an NFS server that
the target board can reach. This directory should then be NFS exported
such that the target board can read and write into it as root.
(2) Flash Filesystem (JFFS2 Recommended)
In this case, the image must be stored or built up on flash before it
can be used. A complete image can be built using the mkfs.jffs2 or
similar program and then downloaded and stored into flash by RedBoot.
========================
LOADING THE KERNEL IMAGE
========================
The kernel will need to be loaded into RAM by RedBoot (or by some alternative
boot loader) before it can be run. The kernel image (arch/frv/boot/Image) may
be loaded in one of three ways:
(1) Load from Flash
This is the simplest. RedBoot can store an image in the flash (see the
RedBoot documentation) and then load it back into RAM. RedBoot keeps
track of the load address, entry point and size, so the command to do
this is simply:
fis load linux
The image is then ready to be executed.
(2) Load by TFTP
The following command will download a raw binary kernel image from the
default server (as negotiated by BOOTP) and store it into RAM:
load -b 0x00100000 -r /tftpboot/image.bin
The image is then ready to be executed.
(3) Load by Y-Modem
The following command will download a raw binary kernel image across the
serial port that RedBoot is currently using:
load -m ymodem -b 0x00100000 -r zImage
The serial client (such as minicom) must then be told to transmit the
program by Y-Modem.
When finished, the image will then be ready to be executed.
==================
BOOTING THE KERNEL
==================
Boot the image with the following RedBoot command:
exec -c "<CMDLINE>" 0x00100000
For example:
exec -c "console=ttySM0,115200 ip=:::::dhcp root=/dev/mtdblock2 rw"
This will start the kernel running. Note that if the GDB-stub is compiled in,
then the kernel will immediately wait for GDB to connect over serial before
doing anything else. See the section on kernel debugging with GDB.
The kernel command line <CMDLINE> tells the kernel where its console is and
how to find its root filesystem. This is made up of the following components,
separated by spaces:
(*) console=ttyS<x>[,<baud>[<parity>[<bits>[<flow>]]]]
This specifies that the system console should output through on-chip
serial port <x> (which can be "0" or "1").
<baud> is a standard baud rate between 1200 and 115200 (default 9600).
<parity> is a parity setting of "N", "O", "E", "M" or "S" for None, Odd,
Even, Mark or Space. "None" is the default.
<stop> is "7" or "8" for the number of bits per character. "8" is the
default.
<flow> is "r" to use flow control (XCTS on serial port 2 only). The
default is to not use flow control.
For example:
console=ttyS0,115200
To use the first on-chip serial port at baud rate 115200, no parity, 8
bits, and no flow control.
(*) root=<xxxx>
This specifies the device upon which the root filesystem resides. It
may be specified by major and minor number, device path, or even
partition uuid, if supported. For example:
/dev/nfs NFS root filesystem
/dev/mtdblock3 Fourth RedBoot partition on the System Flash
PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF/PARTNROFF=1
first partition after the partition with the given UUID
253:0 Device with major 253 and minor 0
Authoritative information can be found in
"Documentation/admin-guide/kernel-parameters.rst".
(*) rw
Start with the root filesystem mounted Read/Write.
The remaining components are all optional:
(*) ip=<ip>::::<host>:<iface>:<cfg>
Configure the network interface. If <cfg> is "off" then <ip> should
specify the IP address for the network device <iface>. <host> provide
the hostname for the device.
If <cfg> is "bootp" or "dhcp", then all of these parameters will be
discovered by consulting a BOOTP or DHCP server.
For example, the following might be used:
ip=192.168.73.12::::frv:eth0:off
This sets the IP address on the VDK motherboard RTL8029 ethernet chipset
(eth0) to be 192.168.73.12, and sets the board's hostname to be "frv".
(*) nfsroot=<server>:<dir>[,v<vers>]
This is mandatory if "root=/dev/nfs" is given as an option. It tells the
kernel the IP address of the NFS server providing its root filesystem,
and the pathname on that server of the filesystem.
The NFS version to use can also be specified. v2 and v3 are supported by
Linux.
For example:
nfsroot=192.168.73.1:/nfsroot-frv
(*) profile=1
Turns on the kernel profiler (accessible through /proc/profile).
(*) console=gdb0
This can be used as an alternative to the "console=ttyS..." listed
above. I tells the kernel to pass the console output to GDB if the
gdbstub is compiled in to the kernel.
If this is used, then the gdbstub passes the text to GDB, which then
simply dumps it to its standard output.
(*) mem=<xxx>M
Normally the kernel will work out how much SDRAM it has by reading the
SDRAM controller registers. That can be overridden with this
option. This allows the kernel to be told that it has <xxx> megabytes of
memory available.
(*) init=<prog> [<arg> [<arg> [<arg> ...]]]
This tells the kernel what program to run initially. By default this is
/sbin/init, but /sbin/sash or /bin/sh are common alternatives.
Clock scaling
-------------
The kernel supports scaling of CLCK.CMODE, CLCK.CM and CLKC.P0 clock
registers. If built with CONFIG_PM and CONFIG_SYSCTL options enabled, four
extra files will appear in the directory /proc/sys/pm/. Reading these files
will show:
p0 -- current value of the P0 bit in CLKC register.
cm -- current value of the CM bits in CLKC register.
cmode -- current value of the CMODE bits in CLKC register.
On all boards, the 'p0' file should also be writable, and either '1' or '0'
can be rewritten, to set or clear the CLKC_P0 bit respectively, hence
controlling whether the resource bus rate clock is halved.
The 'cm' file should also be available on all boards. '0' can be written to it
to shift the board into High-Speed mode (normal), and '1' can be written to
shift the board into Medium-Speed mode. Selecting Low-Speed mode is not
supported by this interface, even though some CPUs do support it.
On the boards with FR405 CPU (i.e. CB60 and CB70), the 'cmode' file is also
writable, allowing the CPU core speed (and other clock speeds) to be
controlled from userspace.
Determining current and possible settings
-----------------------------------------
The current state and the available masks can be found in /proc/cpuinfo. For
example, on the CB70:
# cat /proc/cpuinfo
CPU-Series: fr400
CPU-Core: fr405, gr0-31, BE, CCCR
CPU: mb93405
MMU: Prot
FP-Media: fr0-31, Media
System: mb93091-cb70, mb93090-mb00
PM-Controls: cmode=0xd31f, cm=0x3, p0=0x3, suspend=0x9
PM-Status: cmode=3, cm=0, p0=0
Clock-In: 50.00 MHz
Clock-Core: 300.00 MHz
Clock-SDRAM: 100.00 MHz
Clock-CBus: 100.00 MHz
Clock-Res: 50.00 MHz
Clock-Ext: 50.00 MHz
Clock-DSU: 25.00 MHz
BogoMips: 300.00
And on the PDK, the PM lines look like the following:
PM-Controls: cm=0x3, p0=0x3, suspend=0x9
PM-Status: cmode=9, cm=0, p0=0
The PM-Controls line, if present, will indicate which /proc/sys/pm files can
be set to what values. The specification values are bitmasks; so, for example,
"suspend=0x9" indicates that 0 and 3 can be written validly to
/proc/sys/pm/suspend.
The PM-Controls line will only be present if CONFIG_PM is configured to Y.
The PM-Status line indicates which clock controls are set to which value. If
the file can be read, then the suspend value must be 0, and so that's not
included.
=======================================
FUJITSU FR-V LINUX KERNEL CONFIGURATION
=======================================
=====================
CONFIGURATION OPTIONS
=====================
The most important setting is in the "MMU support options" tab (the first
presented in the configuration tools available):
(*) "Kernel Type"
This options allows selection of normal, MMU-requiring linux, and uClinux
(which doesn't require an MMU and doesn't have inter-process protection).
There are a number of settings in the "Processor type and features" section of
the kernel configuration that need to be considered.
(*) "CPU"
The register and instruction sets at the core of the processor. This can
only be set to "FR40x/45x/55x" at the moment - but this permits usage of
the kernel with MB93091 CB10, CB11, CB30, CB41, CB60, CB70 and CB451
CPU boards, and with the MB93093 PDK board.
(*) "System"
This option allows a choice of basic system. This governs the peripherals
that are expected to be available.
(*) "Motherboard"
This specifies the type of motherboard being used, and the peripherals
upon it. Currently only "MB93090-MB00" can be set here.
(*) "Default cache-write mode"
This controls the initial data cache write management mode. By default
Write-Through is selected, but Write-Back (Copy-Back) can also be
selected. This can be changed dynamically once the kernel is running (see
features.txt).
There are some architecture specific configuration options in the "General
Setup" section of the kernel configuration too:
(*) "Reserve memory uncached for (PCI) DMA"
This requests that a uClinux kernel set aside some memory in an uncached
window for the use as consistent DMA memory (mainly for PCI). At least a
megabyte will be allocated in this way, possibly more. Any memory so
reserved will not be available for normal allocations.
(*) "Kernel support for ELF-FDPIC binaries"
This enables the binary-format driver for the new FDPIC ELF binaries that
this platform normally uses. These binaries are totally relocatable -
their separate sections can relocated independently, allowing them to be
shared on uClinux where possible. This should normally be enabled.
(*) "Kernel image protection"
This makes the protection register governing access to the core kernel
image prohibit access by userspace programs. This option is available on
uClinux only.
There are also a number of settings in the "Kernel Hacking" section of the
kernel configuration especially for debugging a kernel on this
architecture. See the "gdbstub.txt" file for information about those.
======================
DEFAULT CONFIGURATIONS
======================
The kernel sources include a number of example default configurations:
(*) defconfig-mb93091
Default configuration for the MB93091-VDK with both CPU board and
MB93090-MB00 motherboard running uClinux.
(*) defconfig-mb93091-fb
Default configuration for the MB93091-VDK with CPU board,
MB93090-MB00 motherboard, and DAV board running uClinux.
Includes framebuffer driver.
(*) defconfig-mb93093
Default configuration for the MB93093-PDK board running uClinux.
(*) defconfig-cb70-standalone
Default configuration for the MB93091-VDK with only CB70 CPU board
running uClinux. This will use the CB70's DM9000 for network access.
(*) defconfig-mmu
Default configuration for the MB93091-VDK with both CB451 CPU board and
MB93090-MB00 motherboard running MMU linux.
(*) defconfig-mmu-audio
Default configuration for the MB93091-VDK with CB451 CPU board, DAV
board, and MB93090-MB00 motherboard running MMU linux. Includes
audio driver.
(*) defconfig-mmu-fb
Default configuration for the MB93091-VDK with CB451 CPU board, DAV
board, and MB93090-MB00 motherboard running MMU linux. Includes
framebuffer driver.
(*) defconfig-mmu-standalone
Default configuration for the MB93091-VDK with only CB451 CPU board
running MMU linux.
This diff is collapsed.
This diff is collapsed.
====================
DEBUGGING FR-V LINUX
====================
The kernel contains a GDB stub that talks GDB remote protocol across a serial
port. This permits GDB to single step through the kernel, set breakpoints and
trap exceptions that happen in kernel space and interrupt execution. It also
permits the NMI interrupt button or serial port events to jump the kernel into
the debugger.
On the CPUs that have on-chip UARTs (FR400, FR403, FR405, FR555), the
GDB stub hijacks a serial port for its own purposes, and makes it
generate level 15 interrupts (NMI). The kernel proper cannot see the serial
port in question under these conditions.
On the MB93091-VDK CPU boards, the GDB stub uses UART1, which would otherwise
be /dev/ttyS1. On the MB93093-PDK, the GDB stub uses UART0. Therefore, on the
PDK there is no externally accessible serial port and the serial port to
which the touch screen is attached becomes /dev/ttyS0.
Note that the GDB stub runs entirely within CPU debug mode, and so should not
incur any exceptions or interrupts whilst it is active. In particular, note
that the clock will lose time since it is implemented in software.
==================
KERNEL PREPARATION
==================
Firstly, a debuggable kernel must be built. To do this, unpack the kernel tree
and copy the configuration that you wish to use to .config. Then reconfigure
the following things on the "Kernel Hacking" tab:
(*) "Include debugging information"
Set this to "Y". This causes all C and Assembly files to be compiled
to include debugging information.
(*) "In-kernel GDB stub"
Set this to "Y". This causes the GDB stub to be compiled into the
kernel.
(*) "Immediate activation"
Set this to "Y" if you want the GDB stub to activate as soon as possible
and wait for GDB to connect. This allows you to start tracing right from
the beginning of start_kernel() in init/main.c.
(*) "Console through GDB stub"
Set this to "Y" if you wish to be able to use "console=gdb0" on the
command line. That tells the kernel to pass system console messages to
GDB (which then prints them on its standard output). This is useful when
debugging the serial drivers that'd otherwise be used to pass console
messages to the outside world.
Then build as usual, download to the board and execute. Note that if
"Immediate activation" was selected, then the kernel will wait for GDB to
attach. If not, then the kernel will boot immediately and GDB will have to
interrupt it or wait for an exception to occur before doing anything with
the kernel.
=========================
KERNEL DEBUGGING WITH GDB
=========================
Set the serial port on the computer that's going to run GDB to the appropriate
baud rate. Assuming the board's debug port is connected to ttyS0/COM1 on the
computer doing the debugging:
stty -F /dev/ttyS0 115200
Then start GDB in the base of the kernel tree:
frv-uclinux-gdb linux [uClinux]
Or:
frv-uclinux-gdb vmlinux [MMU linux]
When the prompt appears:
GNU gdb frv-031024
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=frv-uclinux"...
(gdb)
Attach to the board like this:
(gdb) target remote /dev/ttyS0
Remote debugging using /dev/ttyS0
start_kernel () at init/main.c:395
(gdb)
This should show the appropriate lines from the source too. The kernel can
then be debugged almost as if it's any other program.
===============================
INTERRUPTING THE RUNNING KERNEL
===============================
The kernel can be interrupted whilst it is running, causing a jump back to the
GDB stub and the debugger:
(*) Pressing Ctrl-C in GDB. This will cause GDB to try and interrupt the
kernel by sending an RS232 BREAK over the serial line to the GDB
stub. This will (mostly) immediately interrupt the kernel and return it
to the debugger.
(*) Pressing the NMI button on the board will also cause a jump into the
debugger.
(*) Setting a software breakpoint. This sets a break instruction at the
desired location which the GDB stub then traps the exception for.
(*) Setting a hardware breakpoint. The GDB stub is capable of using the IBAR
and DBAR registers to assist debugging.
Furthermore, the GDB stub will intercept a number of exceptions automatically
if they are caused by kernel execution. It will also intercept BUG() macro
invocation.
=================================
INTERNAL KERNEL ABI FOR FR-V ARCH
=================================
The internal FRV kernel ABI is not quite the same as the userspace ABI. A
number of the registers are used for special purposed, and the ABI is not
consistent between modules vs core, and MMU vs no-MMU.
This partly stems from the fact that FRV CPUs do not have a separate
supervisor stack pointer, and most of them do not have any scratch
registers, thus requiring at least one general purpose register to be
clobbered in such an event. Also, within the kernel core, it is possible to
simply jump or call directly between functions using a relative offset.
This cannot be extended to modules for the displacement is likely to be too
far. Thus in modules the address of a function to call must be calculated
in a register and then used, requiring two extra instructions.
This document has the following sections:
(*) System call register ABI
(*) CPU operating modes
(*) Internal kernel-mode register ABI
(*) Internal debug-mode register ABI
(*) Virtual interrupt handling
========================
SYSTEM CALL REGISTER ABI
========================
When a system call is made, the following registers are effective:
REGISTERS CALL RETURN
=============== ======================= =======================
GR7 System call number Preserved
GR8 Syscall arg #1 Return value
GR9-GR13 Syscall arg #2-6 Preserved
===================
CPU OPERATING MODES
===================
The FR-V CPU has three basic operating modes. In order of increasing
capability:
(1) User mode.
Basic userspace running mode.
(2) Kernel mode.
Normal kernel mode. There are many additional control registers
available that may be accessed in this mode, in addition to all the
stuff available to user mode. This has two submodes:
(a) Exceptions enabled (PSR.T == 1).
Exceptions will invoke the appropriate normal kernel mode
handler. On entry to the handler, the PSR.T bit will be cleared.
(b) Exceptions disabled (PSR.T == 0).
No exceptions or interrupts may happen. Any mandatory exceptions
will cause the CPU to halt unless the CPU is told to jump into
debug mode instead.
(3) Debug mode.
No exceptions may happen in this mode. Memory protection and
management exceptions will be flagged for later consideration, but
the exception handler won't be invoked. Debugging traps such as
hardware breakpoints and watchpoints will be ignored. This mode is
entered only by debugging events obtained from the other two modes.
All kernel mode registers may be accessed, plus a few extra debugging
specific registers.
=================================
INTERNAL KERNEL-MODE REGISTER ABI
=================================
There are a number of permanent register assignments that are set up by
entry.S in the exception prologue. Note that there is a complete set of
exception prologues for each of user->kernel transition and kernel->kernel
transition. There are also user->debug and kernel->debug mode transition
prologues.
REGISTER FLAVOUR USE
=============== ======= ==============================================
GR1 Supervisor stack pointer
GR15 Current thread info pointer
GR16 GP-Rel base register for small data
GR28 Current exception frame pointer (__frame)
GR29 Current task pointer (current)
GR30 Destroyed by kernel mode entry
GR31 NOMMU Destroyed by debug mode entry
GR31 MMU Destroyed by TLB miss kernel mode entry
CCR.ICC2 Virtual interrupt disablement tracking
CCCR.CC3 Cleared by exception prologue
(atomic op emulation)
SCR0 MMU See mmu-layout.txt.
SCR1 MMU See mmu-layout.txt.
SCR2 MMU Save for EAR0 (destroyed by icache insns
in debug mode)
SCR3 MMU Save for GR31 during debug exceptions
DAMR/IAMR NOMMU Fixed memory protection layout.
DAMR/IAMR MMU See mmu-layout.txt.
Certain registers are also used or modified across function calls:
REGISTER CALL RETURN
=============== =============================== ======================
GR0 Fixed Zero -
GR2 Function call frame pointer
GR3 Special Preserved
GR3-GR7 - Clobbered
GR8 Function call arg #1 Return value
(or clobbered)
GR9 Function call arg #2 Return value MSW
(or clobbered)
GR10-GR13 Function call arg #3-#6 Clobbered
GR14 - Clobbered
GR15-GR16 Special Preserved
GR17-GR27 - Preserved
GR28-GR31 Special Only accessed
explicitly
LR Return address after CALL Clobbered
CCR/CCCR - Mostly Clobbered
================================
INTERNAL DEBUG-MODE REGISTER ABI
================================
This is the same as the kernel-mode register ABI for functions calls. The
difference is that in debug-mode there's a different stack and a different
exception frame. Almost all the global registers from kernel-mode
(including the stack pointer) may be changed.
REGISTER FLAVOUR USE
=============== ======= ==============================================
GR1 Debug stack pointer
GR16 GP-Rel base register for small data
GR31 Current debug exception frame pointer
(__debug_frame)
SCR3 MMU Saved value of GR31
Note that debug mode is able to interfere with the kernel's emulated atomic
ops, so it must be exceedingly careful not to do any that would interact
with the main kernel in this regard. Hence the debug mode code (gdbstub) is
almost completely self-contained. The only external code used is the
sprintf family of functions.
Furthermore, break.S is so complicated because single-step mode does not
switch off on entry to an exception. That means unless manually disabled,
single-stepping will blithely go on stepping into things like interrupts.
See gdbstub.txt for more information.
==========================
VIRTUAL INTERRUPT HANDLING
==========================
Because accesses to the PSR is so slow, and to disable interrupts we have
to access it twice (once to read and once to write), we don't actually
disable interrupts at all if we don't have to. What we do instead is use
the ICC2 condition code flags to note virtual disablement, such that if we
then do take an interrupt, we note the flag, really disable interrupts, set
another flag and resume execution at the point the interrupt happened.
Setting condition flags as a side effect of an arithmetic or logical
instruction is really fast. This use of the ICC2 only occurs within the
kernel - it does not affect userspace.
The flags we use are:
(*) CCR.ICC2.Z [Zero flag]
Set to virtually disable interrupts, clear when interrupts are
virtually enabled. Can be modified by logical instructions without
affecting the Carry flag.
(*) CCR.ICC2.C [Carry flag]
Clear to indicate hardware interrupts are really disabled, set otherwise.
What happens is this:
(1) Normal kernel-mode operation.
ICC2.Z is 0, ICC2.C is 1.
(2) An interrupt occurs. The exception prologue examines ICC2.Z and
determines that nothing needs doing. This is done simply with an
unlikely BEQ instruction.
(3) The interrupts are disabled (local_irq_disable)
ICC2.Z is set to 1.
(4) If interrupts were then re-enabled (local_irq_enable):
ICC2.Z would be set to 0.
A TIHI #2 instruction (trap #2 if condition HI - Z==0 && C==0) would
be used to trap if interrupts were now virtually enabled, but
physically disabled - which they're not, so the trap isn't taken. The
kernel would then be back to state (1).
(5) An interrupt occurs. The exception prologue examines ICC2.Z and
determines that the interrupt shouldn't actually have happened. It
jumps aside, and there disabled interrupts by setting PSR.PIL to 14
and then it clears ICC2.C.
(6) If interrupts were then saved and disabled again (local_irq_save):
ICC2.Z would be shifted into the save variable and masked off
(giving a 1).
ICC2.Z would then be set to 1 (thus unchanged), and ICC2.C would be
unaffected (ie: 0).
(7) If interrupts were then restored from state (6) (local_irq_restore):
ICC2.Z would be set to indicate the result of XOR'ing the saved
value (ie: 1) with 1, which gives a result of 0 - thus leaving
ICC2.Z set.
ICC2.C would remain unaffected (ie: 0).
A TIHI #2 instruction would be used to again assay the current state,
but this would do nothing as Z==1.
(8) If interrupts were then enabled (local_irq_enable):
ICC2.Z would be cleared. ICC2.C would be left unaffected. Both
flags would now be 0.
A TIHI #2 instruction again issued to assay the current state would
then trap as both Z==0 [interrupts virtually enabled] and C==0
[interrupts really disabled] would then be true.
(9) The trap #2 handler would simply enable hardware interrupts
(set PSR.PIL to 0), set ICC2.C to 1 and return.
(10) Immediately upon returning, the pending interrupt would be taken.
(11) The interrupt handler would take the path of actually processing the
interrupt (ICC2.Z is clear, BEQ fails as per step (2)).
(12) The interrupt handler would then set ICC2.C to 1 since hardware
interrupts are definitely enabled - or else the kernel wouldn't be here.
(13) On return from the interrupt handler, things would be back to state (1).
This trap (#2) is only available in kernel mode. In user mode it will
result in SIGILL.
This diff is collapsed.
......@@ -5799,10 +5799,6 @@ F: fs/crypto/
F: include/linux/fscrypt*.h
F: Documentation/filesystems/fscrypt.rst
FUJITSU FR-V (FRV) PORT
S: Orphan
F: arch/frv/
FUJITSU LAPTOP EXTRAS
M: Jonathan Woithe <jwoithe@just42.net>
L: platform-driver-x86@vger.kernel.org
......
# SPDX-License-Identifier: GPL-2.0
config FRV
bool
default y
select HAVE_IDE
select HAVE_ARCH_TRACEHOOK
select HAVE_PERF_EVENTS
select HAVE_UID16
select VIRT_TO_BUS
select GENERIC_IRQ_SHOW
select HAVE_DEBUG_BUGVERBOSE
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_CPU_DEVICES
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_WANT_IPC_PARSE_VERSION
select OLD_SIGSUSPEND3
select OLD_SIGACTION
select HAVE_DEBUG_STACKOVERFLOW
select ARCH_NO_COHERENT_DMA_MMAP
config CPU_BIG_ENDIAN
def_bool y
config ZONE_DMA
bool
default y
config RWSEM_GENERIC_SPINLOCK
bool
default y
config RWSEM_XCHGADD_ALGORITHM
bool
config GENERIC_HWEIGHT
bool
default y
config GENERIC_CALIBRATE_DELAY
bool
default n
config TIME_LOW_RES
bool
default y
config QUICKLIST
bool
default y
config ARCH_HAS_ILOG2_U32
bool
default y
config ARCH_HAS_ILOG2_U64
bool
default y
config HZ
int
default 1000
source "init/Kconfig"
source "kernel/Kconfig.freezer"
menu "Fujitsu FR-V system setup"
config MMU
bool "MMU support"
help
This options switches on and off support for the FR-V MMU
(effectively switching between vmlinux and uClinux). Not all FR-V
CPUs support this. Currently only the FR451 has a sufficiently
featured MMU.
config FRV_OUTOFLINE_ATOMIC_OPS
bool "Out-of-line the FRV atomic operations"
default n
help
Setting this option causes the FR-V atomic operations to be mostly
implemented out-of-line.
See Documentation/frv/atomic-ops.txt for more information.
config HIGHMEM
bool "High memory support"
depends on MMU
default y
help
If you wish to use more than 256MB of memory with your MMU based
system, you will need to select this option. The kernel can only see
the memory between 0xC0000000 and 0xD0000000 directly... everything
else must be kmapped.
The arch is, however, capable of supporting up to 3GB of SDRAM.
config HIGHPTE
bool "Allocate page tables in highmem"
depends on HIGHMEM
default y
help
The VM uses one page of memory for each page table. For systems
with a lot of RAM, this can be wasteful of precious low memory.
Setting this option will put user-space page tables in high memory.
source "mm/Kconfig"
choice
prompt "uClinux kernel load address"
depends on !MMU
default UCPAGE_OFFSET_C0000000
help
This option sets the base address for the uClinux kernel. The kernel
will rearrange the SDRAM layout to start at this address, and move
itself to start there. It must be greater than 0, and it must be
sufficiently less than 0xE0000000 that the SDRAM does not intersect
the I/O region.
The base address must also be aligned such that the SDRAM controller
can decode it. For instance, a 512MB SDRAM bank must be 512MB aligned.
config UCPAGE_OFFSET_20000000
bool "0x20000000"
config UCPAGE_OFFSET_40000000
bool "0x40000000"
config UCPAGE_OFFSET_60000000
bool "0x60000000"
config UCPAGE_OFFSET_80000000
bool "0x80000000"
config UCPAGE_OFFSET_A0000000
bool "0xA0000000"
config UCPAGE_OFFSET_C0000000
bool "0xC0000000 (Recommended)"
endchoice
config PAGE_OFFSET
hex
default 0x20000000 if UCPAGE_OFFSET_20000000
default 0x40000000 if UCPAGE_OFFSET_40000000
default 0x60000000 if UCPAGE_OFFSET_60000000
default 0x80000000 if UCPAGE_OFFSET_80000000
default 0xA0000000 if UCPAGE_OFFSET_A0000000
default 0xC0000000
config PROTECT_KERNEL
bool "Protect core kernel against userspace"
depends on !MMU
default y
help
Selecting this option causes the uClinux kernel to change the
permittivity of DAMPR register covering the core kernel image to
prevent userspace accessing the underlying memory directly.
choice
prompt "CPU Caching mode"
default FRV_DEFL_CACHE_WBACK
help
This option determines the default caching mode for the kernel.
Write-Back caching mode involves the all reads and writes causing
the affected cacheline to be read into the cache first before being
operated upon. Memory is not then updated by a write until the cache
is filled and a cacheline needs to be displaced from the cache to
make room. Only at that point is it written back.
Write-Behind caching is similar to Write-Back caching, except that a
write won't fetch a cacheline into the cache if there isn't already
one there; it will write directly to memory instead.
Write-Through caching only fetches cachelines from memory on a
read. Writes always get written directly to memory. If the affected
cacheline is also in cache, it will be updated too.
The final option is to turn of caching entirely.
Note that not all CPUs support Write-Behind caching. If the CPU on
which the kernel is running doesn't, it'll fall back to Write-Back
caching.
config FRV_DEFL_CACHE_WBACK
bool "Write-Back"
config FRV_DEFL_CACHE_WBEHIND
bool "Write-Behind"
config FRV_DEFL_CACHE_WTHRU
bool "Write-Through"
config FRV_DEFL_CACHE_DISABLED
bool "Disabled"
endchoice
menu "CPU core support"
config CPU_FR401
bool "Include FR401 core support"
depends on !MMU
default y
help
This enables support for the FR401, FR401A and FR403 CPUs
config CPU_FR405
bool "Include FR405 core support"
depends on !MMU
default y
help
This enables support for the FR405 CPU
config CPU_FR451
bool "Include FR451 core support"
default y
help
This enables support for the FR451 CPU
config CPU_FR451_COMPILE
bool "Specifically compile for FR451 core"
depends on CPU_FR451 && !CPU_FR401 && !CPU_FR405 && !CPU_FR551
default y
help
This causes appropriate flags to be passed to the compiler to
optimise for the FR451 CPU
config CPU_FR551
bool "Include FR551 core support"
depends on !MMU
default y
help
This enables support for the FR555 CPU
config CPU_FR551_COMPILE
bool "Specifically compile for FR551 core"
depends on CPU_FR551 && !CPU_FR401 && !CPU_FR405 && !CPU_FR451
default y
help
This causes appropriate flags to be passed to the compiler to
optimise for the FR555 CPU
config FRV_L1_CACHE_SHIFT
int
default "5" if CPU_FR401 || CPU_FR405 || CPU_FR451
default "6" if CPU_FR551
endmenu
choice
prompt "System support"
default MB93091_VDK
config MB93091_VDK
bool "MB93091 CPU board with or without motherboard"
config MB93093_PDK
bool "MB93093 PDK unit"
endchoice
if MB93091_VDK
choice
prompt "Motherboard support"
default MB93090_MB00
config MB93090_MB00
bool "Use the MB93090-MB00 motherboard"
help
Select this option if the MB93091 CPU board is going to be used with
a MB93090-MB00 VDK motherboard
config MB93091_NO_MB
bool "Use standalone"
help
Select this option if the MB93091 CPU board is going to be used
without a motherboard
endchoice
endif
config FUJITSU_MB93493
bool "MB93493 Multimedia chip"
help
Select this option if the MB93493 multimedia chip is going to be
used.
choice
prompt "GP-Relative data support"
default GPREL_DATA_8
help
This option controls what data, if any, should be placed in the GP
relative data sections. Using this means that the compiler can
generate accesses to the data using GR16-relative addressing which
is faster than absolute instructions and saves space (2 instructions
per access).
However, the GPREL region is limited in size because the immediate
value used in the load and store instructions is limited to a 12-bit
signed number.
So if the linker starts complaining that accesses to GPREL data are
out of range, try changing this option from the default.
Note that modules will always be compiled with this feature disabled
as the module data will not be in range of the GP base address.
config GPREL_DATA_8
bool "Put data objects of up to 8 bytes into GP-REL"
config GPREL_DATA_4
bool "Put data objects of up to 4 bytes into GP-REL"
config GPREL_DATA_NONE
bool "Don't use GP-REL"
endchoice
config FRV_ONCPU_SERIAL
bool "Use on-CPU serial ports"
select SERIAL_8250
default y
config PCI
bool "Use PCI"
depends on MB93090_MB00
default y
select GENERIC_PCI_IOMAP
help
Some FR-V systems (such as the MB93090-MB00 VDK) have PCI
onboard. If you have one of these boards and you wish to use the PCI
facilities, say Y here.
config RESERVE_DMA_COHERENT
bool "Reserve DMA coherent memory"
depends on PCI && !MMU
default y
help
Many PCI drivers require access to uncached memory for DMA device
communications (such as is done with some Ethernet buffer rings). If
a fully featured MMU is available, this can be done through page
table settings, but if not, a region has to be set aside and marked
with a special DAMPR register.
Setting this option causes uClinux to set aside a portion of the
available memory for use in this manner. The memory will then be
unavailable for normal kernel use.
source "drivers/pci/Kconfig"
source "drivers/pcmcia/Kconfig"
menu "Power management options"
config ARCH_SUSPEND_POSSIBLE
def_bool y
source kernel/power/Kconfig
endmenu
endmenu
menu "Executable formats"
source "fs/Kconfig.binfmt"
endmenu
source "net/Kconfig"
source "drivers/Kconfig"
source "fs/Kconfig"
source "arch/frv/Kconfig.debug"
source "security/Kconfig"
source "crypto/Kconfig"
source "lib/Kconfig"
# SPDX-License-Identifier: GPL-2.0
menu "Kernel hacking"
source "lib/Kconfig.debug"
config GDBSTUB
bool "Remote GDB kernel debugging"
depends on DEBUG_KERNEL
select DEBUG_INFO
select FRAME_POINTER
help
If you say Y here, it will be possible to remotely debug the kernel
using gdb. This enlarges your kernel ELF image disk size by several
megabytes and requires a machine with more than 16 MB, better 32 MB
RAM to avoid excessive linking time. This is only useful for kernel
hackers. If unsure, say N.
choice
prompt "GDB stub port"
default GDBSTUB_UART1
depends on GDBSTUB
help
Select the on-CPU port used for GDB-stub
config GDBSTUB_UART0
bool "/dev/ttyS0"
config GDBSTUB_UART1
bool "/dev/ttyS1"
endchoice
config GDBSTUB_IMMEDIATE
bool "Break into GDB stub immediately"
depends on GDBSTUB
help
If you say Y here, GDB stub will break into the program as soon as
possible, leaving the program counter at the beginning of
start_kernel() in init/main.c.
config GDB_CONSOLE
bool "Console output to GDB"
depends on GDBSTUB
help
If you are using GDB for remote debugging over a serial port and
would like kernel messages to be formatted into GDB $O packets so
that GDB prints them as program output, say 'Y'.
endmenu
#
# frv/Makefile
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies. Remember to do have actions
# for "archclean" and "archdep" for cleaning up and making dependencies for
# this architecture
#
# 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) 2003, 2004 Red Hat Inc.
# - Written by David Howells <dhowells@redhat.com>
# - Derived from arch/m68knommu/Makefile,
# Copyright (c) 1999,2001 D. Jeff Dionne <jeff@lineo.ca>,
# Rt-Control Inc. / Lineo, Inc.
#
# Copyright (C) 1998,1999 D. Jeff Dionne <jeff@uclinux.org>,
# Kenneth Albanowski <kjahds@kjahds.com>,
#
# Based on arch/m68k/Makefile:
# Copyright (C) 1994 by Hamish Macdonald
#
ifdef CONFIG_MMU
UTS_SYSNAME = -DUTS_SYSNAME=\"Linux\"
else
UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\"
endif
KBUILD_AFLAGS_MODULE += -G0 -mlong-calls
KBUILD_CFLAGS_MODULE += -G0 -mlong-calls
ifdef CONFIG_GPREL_DATA_8
KBUILD_CFLAGS += -G8
else
ifdef CONFIG_GPREL_DATA_4
KBUILD_CFLAGS += -G4
else
ifdef CONFIG_GPREL_DATA_NONE
KBUILD_CFLAGS += -G0
endif
endif
endif
#LDFLAGS_vmlinux := -Map linkmap.txt
ifdef CONFIG_GC_SECTIONS
KBUILD_CFLAGS += -ffunction-sections -fdata-sections
endif
ifndef CONFIG_FRAME_POINTER
KBUILD_CFLAGS += -mno-linked-fp
endif
ifdef CONFIG_CPU_FR451_COMPILE
KBUILD_CFLAGS += -mcpu=fr450
KBUILD_AFLAGS += -mcpu=fr450
else
ifdef CONFIG_CPU_FR551_COMPILE
KBUILD_CFLAGS += -mcpu=fr550
KBUILD_AFLAGS += -mcpu=fr550
else
KBUILD_CFLAGS += -mcpu=fr400
KBUILD_AFLAGS += -mcpu=fr400
endif
endif
# pretend the kernel is going to run on an FR400 with no media-fp unit
# - reserve CC3 for use with atomic ops
# - all the extra registers are dealt with only at context switch time
KBUILD_CFLAGS += -mno-fdpic -mgpr-32 -msoft-float -mno-media
KBUILD_CFLAGS += -ffixed-fcc3 -ffixed-cc3 -ffixed-gr15 -ffixed-icc2
KBUILD_AFLAGS += -mno-fdpic
head-y := arch/frv/kernel/head.o
core-y += arch/frv/kernel/ arch/frv/mm/
libs-y += arch/frv/lib/
core-$(CONFIG_MB93090_MB00) += arch/frv/mb93090-mb00/
all: Image
Image: vmlinux
$(Q)$(MAKE) $(build)=arch/frv/boot $@
archclean:
$(Q)$(MAKE) $(clean)=arch/frv/boot
#
# arch/arm/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) 1995-2000 Russell King
#
targets := Image zImage bootpImage
SYSTEM =$(LINUX)
ZTEXTADDR = 0x02080000
PARAMS_PHYS = 0x0207c000
INITRD_PHYS = 0x02180000
INITRD_VIRT = 0x02180000
OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment
#
# If you don't define ZRELADDR above,
# then it defaults to ZTEXTADDR
#
ifeq ($(ZRELADDR),)
ZRELADDR = $(ZTEXTADDR)
endif
export SYSTEM ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS INITRD_VIRT PARAMS_PHYS
Image: $(obj)/Image
targets: $(obj)/Image
$(obj)/Image: vmlinux FORCE
$(OBJCOPY) $(OBJCOPYFLAGS) -S vmlinux $@
#$(obj)/Image: $(CONFIGURE) $(SYSTEM)
# $(OBJCOPY) $(OBJCOPYFLAGS) -g -S $(SYSTEM) $@
bzImage: zImage
zImage: $(CONFIGURE) compressed/$(LINUX)
$(OBJCOPY) $(OBJCOPYFLAGS) -S compressed/$(LINUX) $@
bootpImage: bootp/bootp
$(OBJCOPY) $(OBJCOPYFLAGS) -S bootp/bootp $@
compressed/$(LINUX): $(LINUX) dep
@$(MAKE) -C compressed $(LINUX)
bootp/bootp: zImage initrd
@$(MAKE) -C bootp bootp
initrd:
@test "$(INITRD_VIRT)" != "" || (echo This architecture does not support INITRD; exit -1)
@test "$(INITRD)" != "" || (echo You must specify INITRD; exit -1)
#
# installation
#
install: $(CONFIGURE) Image
sh ./install.sh $(KERNELRELEASE) Image System.map "$(INSTALL_PATH)"
zinstall: $(CONFIGURE) zImage
sh ./install.sh $(KERNELRELEASE) zImage System.map "$(INSTALL_PATH)"
#
# miscellany
#
mrproper clean:
# @$(MAKE) -C compressed clean
# @$(MAKE) -C bootp clean
dep:
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_EXPERT=y
# CONFIG_HOTPLUG is not set
CONFIG_MMU=y
CONFIG_FRV_OUTOFLINE_ATOMIC_OPS=y
CONFIG_FRV_DEFL_CACHE_WTHRU=y
CONFIG_GPREL_DATA_4=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_PNP=y
# CONFIG_IPV6 is not set
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
CONFIG_NET_PCI=y
CONFIG_NE2K_PCI=y
# CONFIG_INPUT is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=1
CONFIG_SERIAL_8250_RUNTIME_UARTS=1
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_TMPFS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_DEBUG_STACKOVERFLOW=y
generic-y += device.h
generic-y += exec.h
generic-y += extable.h
generic-y += fb.h
generic-y += irq_work.h
generic-y += mcs_spinlock.h
generic-y += mm-arch-hooks.h
generic-y += preempt.h
generic-y += trace_clock.h
generic-y += word-at-a-time.h
generic-y += kprobes.h
#include <generated/asm-offsets.h>
/* atomic.h: atomic operation emulation for FR-V
*
* For an explanation of how atomic ops work in this arch, see:
* Documentation/frv/atomic-ops.txt
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_ATOMIC_H
#define _ASM_ATOMIC_H
#include <linux/types.h>
#include <asm/cmpxchg.h>
#include <asm/barrier.h>
#ifdef CONFIG_SMP
#error not SMP safe
#endif
#include <asm/atomic_defs.h>
/*
* Atomic operations that C can't guarantee us. Useful for
* resource counting etc..
*
* We do not have SMP systems, so we don't have to deal with that.
*/
#define ATOMIC_INIT(i) { (i) }
#define atomic_read(v) READ_ONCE((v)->counter)
#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
static inline int atomic_inc_return(atomic_t *v)
{
return __atomic_add_return(1, &v->counter);
}
static inline int atomic_dec_return(atomic_t *v)
{
return __atomic_sub_return(1, &v->counter);
}
static inline int atomic_add_return(int i, atomic_t *v)
{
return __atomic_add_return(i, &v->counter);
}
static inline int atomic_sub_return(int i, atomic_t *v)
{
return __atomic_sub_return(i, &v->counter);
}
static inline int atomic_add_negative(int i, atomic_t *v)
{
return atomic_add_return(i, v) < 0;
}
static inline void atomic_inc(atomic_t *v)
{
atomic_inc_return(v);
}
static inline void atomic_dec(atomic_t *v)
{
atomic_dec_return(v);
}
#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0)
/*
* 64-bit atomic ops
*/
typedef struct {
long long counter;
} atomic64_t;
#define ATOMIC64_INIT(i) { (i) }
static inline long long atomic64_read(const atomic64_t *v)
{
long long counter;
asm("ldd%I1 %M1,%0"
: "=e"(counter)
: "m"(v->counter));
return counter;
}
static inline void atomic64_set(atomic64_t *v, long long i)
{
asm volatile("std%I0 %1,%M0"
: "=m"(v->counter)
: "e"(i));
}
static inline long long atomic64_inc_return(atomic64_t *v)
{
return __atomic64_add_return(1, &v->counter);
}
static inline long long atomic64_dec_return(atomic64_t *v)
{
return __atomic64_sub_return(1, &v->counter);
}
static inline long long atomic64_add_return(long long i, atomic64_t *v)
{
return __atomic64_add_return(i, &v->counter);
}
static inline long long atomic64_sub_return(long long i, atomic64_t *v)
{
return __atomic64_sub_return(i, &v->counter);
}
static inline long long atomic64_add_negative(long long i, atomic64_t *v)
{
return atomic64_add_return(i, v) < 0;
}
static inline void atomic64_inc(atomic64_t *v)
{
atomic64_inc_return(v);
}
static inline void atomic64_dec(atomic64_t *v)
{
atomic64_dec_return(v);
}
#define atomic64_sub_and_test(i,v) (atomic64_sub_return((i), (v)) == 0)
#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0)
#define atomic64_inc_and_test(v) (atomic64_inc_return((v)) == 0)
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
#define atomic_cmpxchg(v, old, new) (cmpxchg(&(v)->counter, old, new))
#define atomic_xchg(v, new) (xchg(&(v)->counter, new))
#define atomic64_cmpxchg(v, old, new) (__cmpxchg_64(old, new, &(v)->counter))
#define atomic64_xchg(v, new) (__xchg_64(new, &(v)->counter))
static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
{
int c, old;
c = atomic_read(v);
for (;;) {
if (unlikely(c == (u)))
break;
old = atomic_cmpxchg((v), c, c + (a));
if (likely(old == c))
break;
c = old;
}
return c;
}
static inline int atomic64_add_unless(atomic64_t *v, long long i, long long u)
{
long long c, old;
c = atomic64_read(v);
for (;;) {
if (unlikely(c == u))
break;
old = atomic64_cmpxchg(v, c, c + i);
if (likely(old == c))
break;
c = old;
}
return c != u;
}
static inline long long atomic64_dec_if_positive(atomic64_t *v)
{
long long c, old, dec;
c = atomic64_read(v);
for (;;) {
dec = c - 1;
if (unlikely(dec < 0))
break;
old = atomic64_cmpxchg((v), c, dec);
if (likely(old == c))
break;
c = old;
}
return dec;
}
#define ATOMIC_OP(op) \
static inline int atomic_fetch_##op(int i, atomic_t *v) \
{ \
return __atomic32_fetch_##op(i, &v->counter); \
} \
static inline void atomic_##op(int i, atomic_t *v) \
{ \
(void)__atomic32_fetch_##op(i, &v->counter); \
} \
\
static inline long long atomic64_fetch_##op(long long i, atomic64_t *v) \
{ \
return __atomic64_fetch_##op(i, &v->counter); \
} \
static inline void atomic64_##op(long long i, atomic64_t *v) \
{ \
(void)__atomic64_fetch_##op(i, &v->counter); \
}
ATOMIC_OP(or)
ATOMIC_OP(and)
ATOMIC_OP(xor)
ATOMIC_OP(add)
ATOMIC_OP(sub)
#undef ATOMIC_OP
#endif /* _ASM_ATOMIC_H */
/* SPDX-License-Identifier: GPL-2.0 */
#include <asm/spr-regs.h>
#ifdef __ATOMIC_LIB__
#ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
#define ATOMIC_QUALS
#define ATOMIC_EXPORT(x) EXPORT_SYMBOL(x)
#else /* !OUTOFLINE && LIB */
#define ATOMIC_OP_RETURN(op)
#define ATOMIC_FETCH_OP(op)
#endif /* OUTOFLINE */
#else /* !__ATOMIC_LIB__ */
#define ATOMIC_EXPORT(x)
#ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
#define ATOMIC_OP_RETURN(op) \
extern int __atomic_##op##_return(int i, int *v); \
extern long long __atomic64_##op##_return(long long i, long long *v);
#define ATOMIC_FETCH_OP(op) \
extern int __atomic32_fetch_##op(int i, int *v); \
extern long long __atomic64_fetch_##op(long long i, long long *v);
#else /* !OUTOFLINE && !LIB */
#define ATOMIC_QUALS static inline
#endif /* OUTOFLINE */
#endif /* __ATOMIC_LIB__ */
/*
* Note on the 64 bit inline asm variants...
*
* CSTD is a conditional instruction and needs a constrained memory reference.
* Normally 'U' provides the correct constraints for conditional instructions
* and this is used for the 32 bit version, however 'U' does not appear to work
* for 64 bit values (gcc-4.9)
*
* The exact constraint is that conditional instructions cannot deal with an
* immediate displacement in the memory reference, so what we do is we read the
* address through a volatile cast into a local variable in order to insure we
* _have_ to compute the correct address without displacement. This allows us
* to use the regular 'm' for the memory address.
*
* Furthermore, the %Ln operand, which prints the low word register (r+1),
* really only works for registers, this means we cannot allow immediate values
* for the 64 bit versions -- like we do for the 32 bit ones.
*
*/
#ifndef ATOMIC_OP_RETURN
#define ATOMIC_OP_RETURN(op) \
ATOMIC_QUALS int __atomic_##op##_return(int i, int *v) \
{ \
int val; \
\
asm volatile( \
"0: \n" \
" orcc gr0,gr0,gr0,icc3 \n" \
" ckeq icc3,cc7 \n" \
" ld.p %M0,%1 \n" \
" orcr cc7,cc7,cc3 \n" \
" "#op"%I2 %1,%2,%1 \n" \
" cst.p %1,%M0 ,cc3,#1 \n" \
" corcc gr29,gr29,gr0 ,cc3,#1 \n" \
" beq icc3,#0,0b \n" \
: "+U"(*v), "=&r"(val) \
: "NPr"(i) \
: "memory", "cc7", "cc3", "icc3" \
); \
\
return val; \
} \
ATOMIC_EXPORT(__atomic_##op##_return); \
\
ATOMIC_QUALS long long __atomic64_##op##_return(long long i, long long *v) \
{ \
long long *__v = READ_ONCE(v); \
long long val; \
\
asm volatile( \
"0: \n" \
" orcc gr0,gr0,gr0,icc3 \n" \
" ckeq icc3,cc7 \n" \
" ldd.p %M0,%1 \n" \
" orcr cc7,cc7,cc3 \n" \
" "#op"cc %L1,%L2,%L1,icc0 \n" \
" "#op"x %1,%2,%1,icc0 \n" \
" cstd.p %1,%M0 ,cc3,#1 \n" \
" corcc gr29,gr29,gr0 ,cc3,#1 \n" \
" beq icc3,#0,0b \n" \
: "+m"(*__v), "=&e"(val) \
: "e"(i) \
: "memory", "cc7", "cc3", "icc0", "icc3" \
); \
\
return val; \
} \
ATOMIC_EXPORT(__atomic64_##op##_return);
#endif
#ifndef ATOMIC_FETCH_OP
#define ATOMIC_FETCH_OP(op) \
ATOMIC_QUALS int __atomic32_fetch_##op(int i, int *v) \
{ \
int old, tmp; \
\
asm volatile( \
"0: \n" \
" orcc gr0,gr0,gr0,icc3 \n" \
" ckeq icc3,cc7 \n" \
" ld.p %M0,%1 \n" \
" orcr cc7,cc7,cc3 \n" \
" "#op"%I3 %1,%3,%2 \n" \
" cst.p %2,%M0 ,cc3,#1 \n" \
" corcc gr29,gr29,gr0 ,cc3,#1 \n" \
" beq icc3,#0,0b \n" \
: "+U"(*v), "=&r"(old), "=r"(tmp) \
: "NPr"(i) \
: "memory", "cc7", "cc3", "icc3" \
); \
\
return old; \
} \
ATOMIC_EXPORT(__atomic32_fetch_##op); \
\
ATOMIC_QUALS long long __atomic64_fetch_##op(long long i, long long *v) \
{ \
long long *__v = READ_ONCE(v); \
long long old, tmp; \
\
asm volatile( \
"0: \n" \
" orcc gr0,gr0,gr0,icc3 \n" \
" ckeq icc3,cc7 \n" \
" ldd.p %M0,%1 \n" \
" orcr cc7,cc7,cc3 \n" \
" "#op" %L1,%L3,%L2 \n" \
" "#op" %1,%3,%2 \n" \
" cstd.p %2,%M0 ,cc3,#1 \n" \
" corcc gr29,gr29,gr0 ,cc3,#1 \n" \
" beq icc3,#0,0b \n" \
: "+m"(*__v), "=&e"(old), "=e"(tmp) \
: "e"(i) \
: "memory", "cc7", "cc3", "icc3" \
); \
\
return old; \
} \
ATOMIC_EXPORT(__atomic64_fetch_##op);
#endif
ATOMIC_FETCH_OP(or)
ATOMIC_FETCH_OP(and)
ATOMIC_FETCH_OP(xor)
ATOMIC_FETCH_OP(add)
ATOMIC_FETCH_OP(sub)
ATOMIC_OP_RETURN(add)
ATOMIC_OP_RETURN(sub)
#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
#undef ATOMIC_QUALS
#undef ATOMIC_EXPORT
/* ax88796.h: access points to the driver for the AX88796 NE2000 clone
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_AX88796_H
#define _ASM_AX88796_H
#include <asm/mb-regs.h>
#define AX88796_IOADDR (__region_CS1 + 0x200)
#define AX88796_IRQ IRQ_CPU_EXTERNAL7
#define AX88796_FULL_DUPLEX 0 /* force full duplex */
#define AX88796_BUS_INFO "CS1#+0x200" /* bus info for ethtool */
#endif /* _ASM_AX88796_H */
/* FR-V CPU memory barrier definitions
*
* Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_BARRIER_H
#define _ASM_BARRIER_H
#define nop() asm volatile ("nop"::)
#define mb() asm volatile ("membar" : : :"memory")
#define rmb() asm volatile ("membar" : : :"memory")
#define wmb() asm volatile ("membar" : : :"memory")
#include <asm-generic/barrier.h>
#endif /* _ASM_BARRIER_H */
/* bitops.h: bit operations for the Fujitsu FR-V CPUs
*
* For an explanation of how atomic ops work in this arch, see:
* Documentation/frv/atomic-ops.txt
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_BITOPS_H
#define _ASM_BITOPS_H
#include <linux/compiler.h>
#include <asm/byteorder.h>
#ifdef __KERNEL__
#ifndef _LINUX_BITOPS_H
#error only <linux/bitops.h> can be included directly
#endif
#include <asm-generic/bitops/ffz.h>
#include <asm/atomic.h>
static inline int test_and_clear_bit(unsigned long nr, volatile void *addr)
{
unsigned int *ptr = (void *)addr;
unsigned int mask = 1UL << (nr & 31);
ptr += nr >> 5;
return (__atomic32_fetch_and(~mask, ptr) & mask) != 0;
}
static inline int test_and_set_bit(unsigned long nr, volatile void *addr)
{
unsigned int *ptr = (void *)addr;
unsigned int mask = 1UL << (nr & 31);
ptr += nr >> 5;
return (__atomic32_fetch_or(mask, ptr) & mask) != 0;
}
static inline int test_and_change_bit(unsigned long nr, volatile void *addr)
{
unsigned int *ptr = (void *)addr;
unsigned int mask = 1UL << (nr & 31);
ptr += nr >> 5;
return (__atomic32_fetch_xor(mask, ptr) & mask) != 0;
}
static inline void clear_bit(unsigned long nr, volatile void *addr)
{
test_and_clear_bit(nr, addr);
}
static inline void set_bit(unsigned long nr, volatile void *addr)
{
test_and_set_bit(nr, addr);
}
static inline void change_bit(unsigned long nr, volatile void *addr)
{
test_and_change_bit(nr, addr);
}
static inline void __clear_bit(unsigned long nr, volatile void *addr)
{
volatile unsigned long *a = addr;
int mask;
a += nr >> 5;
mask = 1 << (nr & 31);
*a &= ~mask;
}
static inline void __set_bit(unsigned long nr, volatile void *addr)
{
volatile unsigned long *a = addr;
int mask;
a += nr >> 5;
mask = 1 << (nr & 31);
*a |= mask;
}
static inline void __change_bit(unsigned long nr, volatile void *addr)
{
volatile unsigned long *a = addr;
int mask;
a += nr >> 5;
mask = 1 << (nr & 31);
*a ^= mask;
}
static inline int __test_and_clear_bit(unsigned long nr, volatile void *addr)
{
volatile unsigned long *a = addr;
int mask, retval;
a += nr >> 5;
mask = 1 << (nr & 31);
retval = (mask & *a) != 0;
*a &= ~mask;
return retval;
}
static inline int __test_and_set_bit(unsigned long nr, volatile void *addr)
{
volatile unsigned long *a = addr;
int mask, retval;
a += nr >> 5;
mask = 1 << (nr & 31);
retval = (mask & *a) != 0;
*a |= mask;
return retval;
}
static inline int __test_and_change_bit(unsigned long nr, volatile void *addr)
{
volatile unsigned long *a = addr;
int mask, retval;
a += nr >> 5;
mask = 1 << (nr & 31);
retval = (mask & *a) != 0;
*a ^= mask;
return retval;
}
/*
* This routine doesn't need to be atomic.
*/
static inline int
__constant_test_bit(unsigned long nr, const volatile void *addr)
{
return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
}
static inline int __test_bit(unsigned long nr, const volatile void *addr)
{
int * a = (int *) addr;
int mask;
a += nr >> 5;
mask = 1 << (nr & 0x1f);
return ((mask & *a) != 0);
}
#define test_bit(nr,addr) \
(__builtin_constant_p(nr) ? \
__constant_test_bit((nr),(addr)) : \
__test_bit((nr),(addr)))
#include <asm-generic/bitops/find.h>
/**
* fls - find last bit set
* @x: the word to search
*
* This is defined the same way as ffs:
* - return 32..1 to indicate bit 31..0 most significant bit set
* - return 0 to indicate no bits set
*/
#define fls(x) \
({ \
int bit; \
\
asm(" subcc %1,gr0,gr0,icc0 \n" \
" ckne icc0,cc4 \n" \
" cscan.p %1,gr0,%0 ,cc4,#1 \n" \
" csub %0,%0,%0 ,cc4,#0 \n" \
" csub %2,%0,%0 ,cc4,#1 \n" \
: "=&r"(bit) \
: "r"(x), "r"(32) \
: "icc0", "cc4" \
); \
\
bit; \
})
/**
* fls64 - find last bit set in a 64-bit value
* @n: the value to search
*
* This is defined the same way as ffs:
* - return 64..1 to indicate bit 63..0 most significant bit set
* - return 0 to indicate no bits set
*/
static inline __attribute__((const))
int fls64(u64 n)
{
union {
u64 ll;
struct { u32 h, l; };
} _;
int bit, x, y;
_.ll = n;
asm(" subcc.p %3,gr0,gr0,icc0 \n"
" subcc %4,gr0,gr0,icc1 \n"
" ckne icc0,cc4 \n"
" ckne icc1,cc5 \n"
" norcr cc4,cc5,cc6 \n"
" csub.p %0,%0,%0 ,cc6,1 \n"
" orcr cc5,cc4,cc4 \n"
" andcr cc4,cc5,cc4 \n"
" cscan.p %3,gr0,%0 ,cc4,0 \n"
" setlos #64,%1 \n"
" cscan.p %4,gr0,%0 ,cc4,1 \n"
" setlos #32,%2 \n"
" csub.p %1,%0,%0 ,cc4,0 \n"
" csub %2,%0,%0 ,cc4,1 \n"
: "=&r"(bit), "=r"(x), "=r"(y)
: "0r"(_.h), "r"(_.l)
: "icc0", "icc1", "cc4", "cc5", "cc6"
);
return bit;
}
/**
* ffs - find first bit set
* @x: the word to search
*
* - return 32..1 to indicate bit 31..0 most least significant bit set
* - return 0 to indicate no bits set
*/
static inline __attribute__((const))
int ffs(int x)
{
/* Note: (x & -x) gives us a mask that is the least significant
* (rightmost) 1-bit of the value in x.
*/
return fls(x & -x);
}
/**
* __ffs - find first bit set
* @x: the word to search
*
* - return 31..0 to indicate bit 31..0 most least significant bit set
* - if no bits are set in x, the result is undefined
*/
static inline __attribute__((const))
int __ffs(unsigned long x)
{
int bit;
asm("scan %1,gr0,%0" : "=r"(bit) : "r"(x & -x));
return 31 - bit;
}
/**
* __fls - find last (most-significant) set bit in a long word
* @word: the word to search
*
* Undefined if no set bit exists, so code should check against 0 first.
*/
static inline unsigned long __fls(unsigned long word)
{
unsigned long bit;
asm("scan %1,gr0,%0" : "=r"(bit) : "r"(word));
return bit;
}
/*
* special slimline version of fls() for calculating ilog2_u32()
* - note: no protection against n == 0
*/
#define ARCH_HAS_ILOG2_U32
static inline __attribute__((const))
int __ilog2_u32(u32 n)
{
int bit;
asm("scan %1,gr0,%0" : "=r"(bit) : "r"(n));
return 31 - bit;
}
/*
* special slimline version of fls64() for calculating ilog2_u64()
* - note: no protection against n == 0
*/
#define ARCH_HAS_ILOG2_U64
static inline __attribute__((const))
int __ilog2_u64(u64 n)
{
union {
u64 ll;
struct { u32 h, l; };
} _;
int bit, x, y;
_.ll = n;
asm(" subcc %3,gr0,gr0,icc0 \n"
" ckeq icc0,cc4 \n"
" cscan.p %3,gr0,%0 ,cc4,0 \n"
" setlos #63,%1 \n"
" cscan.p %4,gr0,%0 ,cc4,1 \n"
" setlos #31,%2 \n"
" csub.p %1,%0,%0 ,cc4,0 \n"
" csub %2,%0,%0 ,cc4,1 \n"
: "=&r"(bit), "=r"(x), "=r"(y)
: "0r"(_.h), "r"(_.l)
: "icc0", "cc4"
);
return bit;
}
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/le.h>
#include <asm-generic/bitops/ext2-atomic-setbit.h>
#endif /* __KERNEL__ */
#endif /* _ASM_BITOPS_H */
/* bug.h: FRV bug trapping
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_BUG_H
#define _ASM_BUG_H
#include <linux/linkage.h>
#ifdef CONFIG_BUG
/*
* Tell the user there is some problem.
*/
extern asmlinkage void __debug_bug_trap(int signr);
#ifdef CONFIG_NO_KERNEL_MSG
#define _debug_bug_printk()
#else
extern void __debug_bug_printk(const char *file, unsigned line);
#define _debug_bug_printk() __debug_bug_printk(__FILE__, __LINE__)
#endif
#define _debug_bug_trap(signr) \
do { \
__debug_bug_trap(signr); \
asm volatile("nop"); \
} while(1)
#define HAVE_ARCH_BUG
#define BUG() \
do { \
_debug_bug_printk(); \
_debug_bug_trap(6 /*SIGABRT*/); \
} while (0)
#ifdef CONFIG_GDBSTUB
#define HAVE_ARCH_KGDB_RAISE
#define kgdb_raise(signr) do { _debug_bug_trap(signr); } while(0)
#define HAVE_ARCH_KGDB_BAD_PAGE
#define kgdb_bad_page(page) do { kgdb_raise(SIGABRT); } while(0)
#endif
#endif /* CONFIG_BUG */
#include <asm-generic/bug.h>
extern void die_if_kernel(const char *, ...) __attribute__((format(printf, 1, 2)));
#endif
/* bugs.h: arch bug checking entry
*
* Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
static inline void check_bugs(void)
{
}
/* busctl-regs.h: FR400-series CPU bus controller registers
*
* Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_BUSCTL_REGS_H
#define _ASM_BUSCTL_REGS_H
/* bus controller registers */
#define __get_LGCR() ({ *(volatile unsigned long *)(0xfe000010); })
#define __get_LMAICR() ({ *(volatile unsigned long *)(0xfe000030); })
#define __get_LEMBR() ({ *(volatile unsigned long *)(0xfe000040); })
#define __get_LEMAM() ({ *(volatile unsigned long *)(0xfe000048); })
#define __get_LCR(R) ({ *(volatile unsigned long *)(0xfe000100 + 8*(R)); })
#define __get_LSBR(R) ({ *(volatile unsigned long *)(0xfe000c00 + 8*(R)); })
#define __get_LSAM(R) ({ *(volatile unsigned long *)(0xfe000d00 + 8*(R)); })
#define __set_LGCR(V) do { *(volatile unsigned long *)(0xfe000010) = (V); } while(0)
#define __set_LMAICR(V) do { *(volatile unsigned long *)(0xfe000030) = (V); } while(0)
#define __set_LEMBR(V) do { *(volatile unsigned long *)(0xfe000040) = (V); } while(0)
#define __set_LEMAM(V) do { *(volatile unsigned long *)(0xfe000048) = (V); } while(0)
#define __set_LCR(R,V) do { *(volatile unsigned long *)(0xfe000100 + 8*(R)) = (V); } while(0)
#define __set_LSBR(R,V) do { *(volatile unsigned long *)(0xfe000c00 + 8*(R)) = (V); } while(0)
#define __set_LSAM(R,V) do { *(volatile unsigned long *)(0xfe000d00 + 8*(R)) = (V); } while(0)
/* FR401 SDRAM controller registers */
#define __get_DBR(R) ({ *(volatile unsigned long *)(0xfe000e00 + 8*(R)); })
#define __get_DAM(R) ({ *(volatile unsigned long *)(0xfe000f00 + 8*(R)); })
/* FR551 SDRAM controller registers */
#define __get_DARS(R) ({ *(volatile unsigned long *)(0xfeff0100 + 8*(R)); })
#define __get_DAMK(R) ({ *(volatile unsigned long *)(0xfeff0110 + 8*(R)); })
#endif /* _ASM_BUSCTL_REGS_H */
/* cache.h: FRV cache definitions
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef __ASM_CACHE_H
#define __ASM_CACHE_H
/* bytes per L1 cache line */
#define L1_CACHE_SHIFT (CONFIG_FRV_L1_CACHE_SHIFT)
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
#define __cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES)))
#define ____cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES)))
#endif
/* cacheflush.h: FRV cache flushing routines
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_CACHEFLUSH_H
#define _ASM_CACHEFLUSH_H
/* Keep includes the same across arches. */
#include <linux/mm.h>
/*
* virtually-indexed cache management (our cache is physically indexed)
*/
#define flush_cache_all() do {} while(0)
#define flush_cache_mm(mm) do {} while(0)
#define flush_cache_dup_mm(mm) do {} while(0)
#define flush_cache_range(mm, start, end) do {} while(0)
#define flush_cache_page(vma, vmaddr, pfn) do {} while(0)
#define flush_cache_vmap(start, end) do {} while(0)
#define flush_cache_vunmap(start, end) do {} while(0)
#define flush_dcache_mmap_lock(mapping) do {} while(0)
#define flush_dcache_mmap_unlock(mapping) do {} while(0)
/*
* physically-indexed cache management
* - see arch/frv/lib/cache.S
*/
extern void frv_dcache_writeback(unsigned long start, unsigned long size);
extern void frv_cache_invalidate(unsigned long start, unsigned long size);
extern void frv_icache_invalidate(unsigned long start, unsigned long size);
extern void frv_cache_wback_inv(unsigned long start, unsigned long size);
static inline void __flush_cache_all(void)
{
asm volatile(" dcef @(gr0,gr0),#1 \n"
" icei @(gr0,gr0),#1 \n"
" membar \n"
: : : "memory"
);
}
/* dcache/icache coherency... */
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
#ifdef CONFIG_MMU
extern void flush_dcache_page(struct page *page);
#else
static inline void flush_dcache_page(struct page *page)
{
unsigned long addr = page_to_phys(page);
frv_dcache_writeback(addr, addr + PAGE_SIZE);
}
#endif
static inline void flush_page_to_ram(struct page *page)
{
flush_dcache_page(page);
}
static inline void flush_icache(void)
{
__flush_cache_all();
}
static inline void flush_icache_range(unsigned long start, unsigned long end)
{
frv_cache_wback_inv(start, end);
}
#ifdef CONFIG_MMU
extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
unsigned long start, unsigned long len);
#else
static inline void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
unsigned long start, unsigned long len)
{
frv_cache_wback_inv(start, start + len);
}
#endif
static inline void flush_icache_page(struct vm_area_struct *vma, struct page *page)
{
flush_icache_user_range(vma, page, page_to_phys(page), PAGE_SIZE);
}
/*
* permit ptrace to access another process's address space through the icache
* and the dcache
*/
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
do { \
memcpy((dst), (src), (len)); \
flush_icache_user_range((vma), (page), (vaddr), (len)); \
} while(0)
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
memcpy((dst), (src), (len))
#endif /* _ASM_CACHEFLUSH_H */
/* checksum.h: FRV checksumming
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_CHECKSUM_H
#define _ASM_CHECKSUM_H
#include <linux/in6.h>
/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
*
* returns a 32-bit number suitable for feeding into itself
* or csum_tcpudp_magic
*
* this function must be called with even lengths, except
* for the last fragment, which may be odd
*
* it's best to have buff aligned on a 32-bit boundary
*/
__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
*/
__wsum csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum);
/*
* the same as csum_partial_copy, but copies from user space.
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
int len, __wsum sum, int *csum_err);
/*
* This is a version of ip_compute_csum() optimized for IP headers,
* which always checksum on 4 octet boundaries.
*
*/
static inline
__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
{
unsigned int tmp, inc, sum = 0;
asm(" addcc gr0,gr0,gr0,icc0\n" /* clear icc0.C */
" subi %1,#4,%1 \n"
"0: \n"
" ldu.p @(%1,%3),%4 \n"
" subicc %2,#1,%2,icc1 \n"
" addxcc.p %4,%0,%0,icc0 \n"
" bhi icc1,#2,0b \n"
/* fold the 33-bit result into 16-bits */
" addxcc gr0,%0,%0,icc0 \n"
" srli %0,#16,%1 \n"
" sethi #0,%0 \n"
" add %1,%0,%0 \n"
" srli %0,#16,%1 \n"
" add %1,%0,%0 \n"
: "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (inc), "=&r"(tmp)
: "0" (sum), "1" (iph), "2" (ihl), "3" (4),
"m"(*(volatile struct { int _[100]; } *)iph)
: "icc0", "icc1", "memory"
);
return (__force __sum16)~sum;
}
/*
* Fold a partial checksum
*/
static inline __sum16 csum_fold(__wsum sum)
{
unsigned int tmp;
asm(" srli %0,#16,%1 \n"
" sethi #0,%0 \n"
" add %1,%0,%0 \n"
" srli %0,#16,%1 \n"
" add %1,%0,%0 \n"
: "=r"(sum), "=&r"(tmp)
: "0"(sum)
);
return (__force __sum16)~sum;
}
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
asm(" addcc %1,%0,%0,icc0 \n"
" addxcc %2,%0,%0,icc0 \n"
" addxcc %3,%0,%0,icc0 \n"
" addxcc gr0,%0,%0,icc0 \n"
: "=r" (sum)
: "r" (daddr), "r" (saddr), "r" (len + proto), "0"(sum)
: "icc0"
);
return sum;
}
static inline __sum16
csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
extern __sum16 ip_compute_csum(const void *buff, int len);
#define _HAVE_ARCH_IPV6_CSUM
static inline __sum16
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, __u8 proto, __wsum sum)
{
unsigned long tmp, tmp2;
asm(" addcc %2,%0,%0,icc0 \n"
/* add up the source addr */
" ldi @(%3,0),%1 \n"
" addxcc %1,%0,%0,icc0 \n"
" ldi @(%3,4),%2 \n"
" addxcc %2,%0,%0,icc0 \n"
" ldi @(%3,8),%1 \n"
" addxcc %1,%0,%0,icc0 \n"
" ldi @(%3,12),%2 \n"
" addxcc %2,%0,%0,icc0 \n"
/* add up the dest addr */
" ldi @(%4,0),%1 \n"
" addxcc %1,%0,%0,icc0 \n"
" ldi @(%4,4),%2 \n"
" addxcc %2,%0,%0,icc0 \n"
" ldi @(%4,8),%1 \n"
" addxcc %1,%0,%0,icc0 \n"
" ldi @(%4,12),%2 \n"
" addxcc %2,%0,%0,icc0 \n"
/* fold the 33-bit result into 16-bits */
" addxcc gr0,%0,%0,icc0 \n"
" srli %0,#16,%1 \n"
" sethi #0,%0 \n"
" add %1,%0,%0 \n"
" srli %0,#16,%1 \n"
" add %1,%0,%0 \n"
: "=r" (sum), "=&r" (tmp), "=r" (tmp2)
: "r" (saddr), "r" (daddr), "0" (sum), "2" (len + proto)
: "icc0"
);
return (__force __sum16)~sum;
}
#endif /* _ASM_CHECKSUM_H */
/* xchg and cmpxchg operation emulation for FR-V
*
* For an explanation of how atomic ops work in this arch, see:
* Documentation/frv/atomic-ops.txt
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_CMPXCHG_H
#define _ASM_CMPXCHG_H
#include <linux/types.h>
/*****************************************************************************/
/*
* exchange value with memory
*/
extern uint64_t __xchg_64(uint64_t i, volatile void *v);
#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
#define xchg(ptr, x) \
({ \
__typeof__(ptr) __xg_ptr = (ptr); \
__typeof__(*(ptr)) __xg_orig; \
\
switch (sizeof(__xg_orig)) { \
case 4: \
asm volatile( \
"swap%I0 %M0,%1" \
: "+m"(*__xg_ptr), "=r"(__xg_orig) \
: "1"(x) \
: "memory" \
); \
break; \
\
default: \
__xg_orig = (__typeof__(__xg_orig))0; \
asm volatile("break"); \
break; \
} \
\
__xg_orig; \
})
#else
extern uint32_t __xchg_32(uint32_t i, volatile void *v);
#define xchg(ptr, x) \
({ \
__typeof__(ptr) __xg_ptr = (ptr); \
__typeof__(*(ptr)) __xg_orig; \
\
switch (sizeof(__xg_orig)) { \
case 4: __xg_orig = (__typeof__(*(ptr))) __xchg_32((uint32_t) x, __xg_ptr); break; \
default: \
__xg_orig = (__typeof__(__xg_orig))0; \
asm volatile("break"); \
break; \
} \
__xg_orig; \
})
#endif
/*****************************************************************************/
/*
* compare and conditionally exchange value with memory
* - if (*ptr == test) then orig = *ptr; *ptr = test;
* - if (*ptr != test) then orig = *ptr;
*/
extern uint64_t __cmpxchg_64(uint64_t test, uint64_t new, volatile uint64_t *v);
#define cmpxchg64(p, o, n) __cmpxchg_64((o), (n), (p))
#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
#define cmpxchg(ptr, test, new) \
({ \
__typeof__(ptr) __xg_ptr = (ptr); \
__typeof__(*(ptr)) __xg_orig, __xg_tmp; \
__typeof__(*(ptr)) __xg_test = (test); \
__typeof__(*(ptr)) __xg_new = (new); \
\
switch (sizeof(__xg_orig)) { \
case 4: \
asm volatile( \
"0: \n" \
" orcc gr0,gr0,gr0,icc3 \n" \
" ckeq icc3,cc7 \n" \
" ld.p %M0,%1 \n" \
" orcr cc7,cc7,cc3 \n" \
" sub%I4cc %1,%4,%2,icc0 \n" \
" bne icc0,#0,1f \n" \
" cst.p %3,%M0 ,cc3,#1 \n" \
" corcc gr29,gr29,gr0 ,cc3,#1 \n" \
" beq icc3,#0,0b \n" \
"1: \n" \
: "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp) \
: "r"(__xg_new), "NPr"(__xg_test) \
: "memory", "cc7", "cc3", "icc3", "icc0" \
); \
break; \
\
default: \
__xg_orig = (__typeof__(__xg_orig))0; \
asm volatile("break"); \
break; \
} \
\
__xg_orig; \
})
#else
extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new);
#define cmpxchg(ptr, test, new) \
({ \
__typeof__(ptr) __xg_ptr = (ptr); \
__typeof__(*(ptr)) __xg_orig; \
__typeof__(*(ptr)) __xg_test = (test); \
__typeof__(*(ptr)) __xg_new = (new); \
\
switch (sizeof(__xg_orig)) { \
case 4: __xg_orig = (__force __typeof__(*ptr)) \
__cmpxchg_32((__force uint32_t *)__xg_ptr, \
(__force uint32_t)__xg_test, \
(__force uint32_t)__xg_new); break; \
default: \
__xg_orig = (__typeof__(__xg_orig))0; \
asm volatile("break"); \
break; \
} \
\
__xg_orig; \
})
#endif
#include <asm-generic/cmpxchg-local.h>
static inline unsigned long __cmpxchg_local(volatile void *ptr,
unsigned long old,
unsigned long new, int size)
{
switch (size) {
case 4:
return cmpxchg((unsigned long *)ptr, old, new);
default:
return __cmpxchg_local_generic(ptr, old, new, size);
}
return old;
}
/*
* cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
* them available.
*/
#define cmpxchg_local(ptr, o, n) \
((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
(unsigned long)(n), sizeof(*(ptr))))
#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
#endif /* _ASM_CMPXCHG_H */
/* cpu-irqs.h: on-CPU peripheral irqs
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_CPU_IRQS_H
#define _ASM_CPU_IRQS_H
#ifndef __ASSEMBLY__
/* IRQ to level mappings */
#define IRQ_GDBSTUB_LEVEL 15
#define IRQ_UART_LEVEL 13
#ifdef CONFIG_GDBSTUB_UART0
#define IRQ_UART0_LEVEL IRQ_GDBSTUB_LEVEL
#else
#define IRQ_UART0_LEVEL IRQ_UART_LEVEL
#endif
#ifdef CONFIG_GDBSTUB_UART1
#define IRQ_UART1_LEVEL IRQ_GDBSTUB_LEVEL
#else
#define IRQ_UART1_LEVEL IRQ_UART_LEVEL
#endif
#define IRQ_DMA0_LEVEL 14
#define IRQ_DMA1_LEVEL 14
#define IRQ_DMA2_LEVEL 14
#define IRQ_DMA3_LEVEL 14
#define IRQ_DMA4_LEVEL 14
#define IRQ_DMA5_LEVEL 14
#define IRQ_DMA6_LEVEL 14
#define IRQ_DMA7_LEVEL 14
#define IRQ_TIMER0_LEVEL 12
#define IRQ_TIMER1_LEVEL 11
#define IRQ_TIMER2_LEVEL 10
#define IRQ_XIRQ0_LEVEL 1
#define IRQ_XIRQ1_LEVEL 2
#define IRQ_XIRQ2_LEVEL 3
#define IRQ_XIRQ3_LEVEL 4
#define IRQ_XIRQ4_LEVEL 5
#define IRQ_XIRQ5_LEVEL 6
#define IRQ_XIRQ6_LEVEL 7
#define IRQ_XIRQ7_LEVEL 8
/* IRQ IDs presented to drivers */
#define IRQ_CPU__UNUSED IRQ_BASE_CPU
#define IRQ_CPU_UART0 (IRQ_BASE_CPU + IRQ_UART0_LEVEL)
#define IRQ_CPU_UART1 (IRQ_BASE_CPU + IRQ_UART1_LEVEL)
#define IRQ_CPU_TIMER0 (IRQ_BASE_CPU + IRQ_TIMER0_LEVEL)
#define IRQ_CPU_TIMER1 (IRQ_BASE_CPU + IRQ_TIMER1_LEVEL)
#define IRQ_CPU_TIMER2 (IRQ_BASE_CPU + IRQ_TIMER2_LEVEL)
#define IRQ_CPU_DMA0 (IRQ_BASE_CPU + IRQ_DMA0_LEVEL)
#define IRQ_CPU_DMA1 (IRQ_BASE_CPU + IRQ_DMA1_LEVEL)
#define IRQ_CPU_DMA2 (IRQ_BASE_CPU + IRQ_DMA2_LEVEL)
#define IRQ_CPU_DMA3 (IRQ_BASE_CPU + IRQ_DMA3_LEVEL)
#define IRQ_CPU_DMA4 (IRQ_BASE_CPU + IRQ_DMA4_LEVEL)
#define IRQ_CPU_DMA5 (IRQ_BASE_CPU + IRQ_DMA5_LEVEL)
#define IRQ_CPU_DMA6 (IRQ_BASE_CPU + IRQ_DMA6_LEVEL)
#define IRQ_CPU_DMA7 (IRQ_BASE_CPU + IRQ_DMA7_LEVEL)
#define IRQ_CPU_EXTERNAL0 (IRQ_BASE_CPU + IRQ_XIRQ0_LEVEL)
#define IRQ_CPU_EXTERNAL1 (IRQ_BASE_CPU + IRQ_XIRQ1_LEVEL)
#define IRQ_CPU_EXTERNAL2 (IRQ_BASE_CPU + IRQ_XIRQ2_LEVEL)
#define IRQ_CPU_EXTERNAL3 (IRQ_BASE_CPU + IRQ_XIRQ3_LEVEL)
#define IRQ_CPU_EXTERNAL4 (IRQ_BASE_CPU + IRQ_XIRQ4_LEVEL)
#define IRQ_CPU_EXTERNAL5 (IRQ_BASE_CPU + IRQ_XIRQ5_LEVEL)
#define IRQ_CPU_EXTERNAL6 (IRQ_BASE_CPU + IRQ_XIRQ6_LEVEL)
#define IRQ_CPU_EXTERNAL7 (IRQ_BASE_CPU + IRQ_XIRQ7_LEVEL)
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_CPU_IRQS_H */
/* current.h: FRV current task pointer
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_CURRENT_H
#define _ASM_CURRENT_H
#ifndef __ASSEMBLY__
/*
* dedicate GR29 to keeping the current task pointer
*/
register struct task_struct *current asm("gr29");
#define get_current() current
#else
#define CURRENT gr29
#endif
#endif /* _ASM_CURRENT_H */
/* delay.h: FRV delay code
*
* Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_DELAY_H
#define _ASM_DELAY_H
#include <asm/param.h>
#include <asm/timer-regs.h>
/*
* delay loop - runs at __core_clock_speed_HZ / 2 [there are 2 insns in the loop]
*/
extern unsigned long __delay_loops_MHz;
static inline void __delay(unsigned long loops)
{
asm volatile("1: subicc %0,#1,%0,icc0 \n"
" bnc icc0,#2,1b \n"
: "=r" (loops)
: "0" (loops)
: "icc0"
);
}
/*
* Use only for very small delays ( < 1 msec). Should probably use a
* lookup table, really, as the multiplications take much too long with
* short delays. This is a "reasonable" implementation, though (and the
* first constant multiplications gets optimized away if the delay is
* a constant)
*/
extern unsigned long loops_per_jiffy;
static inline void udelay(unsigned long usecs)
{
__delay(usecs * __delay_loops_MHz);
}
#define ndelay(n) udelay((n) * 5)
#endif /* _ASM_DELAY_H */
#include <asm-generic/div64.h>
/* dm9000.h: Davicom DM9000 adapter configuration
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_DM9000_H
#define _ASM_DM9000_H
#include <asm/mb-regs.h>
#define DM9000_ARCH_IOBASE (__region_CS6 + 0x300)
#define DM9000_ARCH_IRQ IRQ_CPU_EXTERNAL3 /* XIRQ #3 (shared with FPGA) */
#undef DM9000_ARCH_IRQ_ACTLOW /* IRQ pin active high */
#define DM9000_ARCH_BUS_INFO "CS6#+0x300" /* bus info for ethtool */
#undef __is_PCI_IO
#define __is_PCI_IO(addr) 0 /* not PCI */
#undef inl
#define inl(addr) \
({ \
unsigned long __ioaddr = (unsigned long) addr; \
uint32_t x = readl(__ioaddr); \
((x & 0xff) << 24) | ((x & 0xff00) << 8) | ((x >> 8) & 0xff00) | ((x >> 24) & 0xff); \
})
#undef insl
#define insl(a,b,l) __insl(a,b,l,0) /* don't byte-swap */
#endif /* _ASM_DM9000_H */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_DMA_MAPPING_H
#define _ASM_DMA_MAPPING_H
#include <asm/cache.h>
#include <asm/cacheflush.h>
extern unsigned long __nongprelbss dma_coherent_mem_start;
extern unsigned long __nongprelbss dma_coherent_mem_end;
extern const struct dma_map_ops frv_dma_ops;
static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
{
return &frv_dma_ops;
}
#endif /* _ASM_DMA_MAPPING_H */
/* dma.h: FRV DMA controller management
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_DMA_H
#define _ASM_DMA_H
//#define DMA_DEBUG 1
#include <linux/interrupt.h>
#undef MAX_DMA_CHANNELS /* don't use kernel/dma.c */
/* under 2.4 this is actually needed by the new bootmem allocator */
#define MAX_DMA_ADDRESS PAGE_OFFSET
/*
* FRV DMA controller management
*/
typedef irqreturn_t (*dma_irq_handler_t)(int dmachan, unsigned long cstr, void *data);
extern void frv_dma_init(void);
extern int frv_dma_open(const char *devname,
unsigned long dmamask,
int dmacap,
dma_irq_handler_t handler,
unsigned long irq_flags,
void *data);
/* channels required */
#define FRV_DMA_MASK_ANY ULONG_MAX /* any channel */
/* capabilities required */
#define FRV_DMA_CAP_DREQ 0x01 /* DMA request pin */
#define FRV_DMA_CAP_DACK 0x02 /* DMA ACK pin */
#define FRV_DMA_CAP_DONE 0x04 /* DMA done pin */
extern void frv_dma_close(int dma);
extern void frv_dma_config(int dma, unsigned long ccfr, unsigned long cctr, unsigned long apr);
extern void frv_dma_start(int dma,
unsigned long sba, unsigned long dba,
unsigned long pix, unsigned long six, unsigned long bcl);
extern void frv_dma_restart_circular(int dma, unsigned long six);
extern void frv_dma_stop(int dma);
extern int is_frv_dma_interrupting(int dma);
extern void frv_dma_dump(int dma);
extern void frv_dma_status_clear(int dma);
#define FRV_DMA_NCHANS 8
#define FRV_DMA_4CHANS 4
#define FRV_DMA_8CHANS 8
#define DMAC_CCFRx 0x00 /* channel configuration reg */
#define DMAC_CCFRx_CM_SHIFT 16
#define DMAC_CCFRx_CM_DA 0x00000000
#define DMAC_CCFRx_CM_SCA 0x00010000
#define DMAC_CCFRx_CM_DCA 0x00020000
#define DMAC_CCFRx_CM_2D 0x00030000
#define DMAC_CCFRx_ATS_SHIFT 8
#define DMAC_CCFRx_RS_INTERN 0x00000000
#define DMAC_CCFRx_RS_EXTERN 0x00000001
#define DMAC_CCFRx_RS_SHIFT 0
#define DMAC_CSTRx 0x08 /* channel status reg */
#define DMAC_CSTRx_FS 0x0000003f
#define DMAC_CSTRx_NE 0x00000100
#define DMAC_CSTRx_FED 0x00000200
#define DMAC_CSTRx_WER 0x00000800
#define DMAC_CSTRx_RER 0x00001000
#define DMAC_CSTRx_CE 0x00002000
#define DMAC_CSTRx_INT 0x00800000
#define DMAC_CSTRx_BUSY 0x80000000
#define DMAC_CCTRx 0x10 /* channel control reg */
#define DMAC_CCTRx_DSIZ_1 0x00000000
#define DMAC_CCTRx_DSIZ_2 0x00000001
#define DMAC_CCTRx_DSIZ_4 0x00000002
#define DMAC_CCTRx_DSIZ_32 0x00000005
#define DMAC_CCTRx_DAU_HOLD 0x00000000
#define DMAC_CCTRx_DAU_INC 0x00000010
#define DMAC_CCTRx_DAU_DEC 0x00000020
#define DMAC_CCTRx_SSIZ_1 0x00000000
#define DMAC_CCTRx_SSIZ_2 0x00000100
#define DMAC_CCTRx_SSIZ_4 0x00000200
#define DMAC_CCTRx_SSIZ_32 0x00000500
#define DMAC_CCTRx_SAU_HOLD 0x00000000
#define DMAC_CCTRx_SAU_INC 0x00001000
#define DMAC_CCTRx_SAU_DEC 0x00002000
#define DMAC_CCTRx_FC 0x08000000
#define DMAC_CCTRx_ICE 0x10000000
#define DMAC_CCTRx_IE 0x40000000
#define DMAC_CCTRx_ACT 0x80000000
#define DMAC_SBAx 0x18 /* source base address reg */
#define DMAC_DBAx 0x20 /* data base address reg */
#define DMAC_PIXx 0x28 /* primary index reg */
#define DMAC_SIXx 0x30 /* secondary index reg */
#define DMAC_BCLx 0x38 /* byte count limit reg */
#define DMAC_APRx 0x40 /* alternate pointer reg */
/*
* required for PCI + MODULES
*/
#ifdef CONFIG_PCI
extern int isa_dma_bridge_buggy;
#else
#define isa_dma_bridge_buggy (0)
#endif
#endif /* _ASM_DMA_H */
/* elf.h: FR-V ELF definitions
*
* Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
* - Derived from include/asm-m68knommu/elf.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef __ASM_ELF_H
#define __ASM_ELF_H
#include <asm/ptrace.h>
#include <asm/user.h>
struct elf32_hdr;
/*
* ELF header e_flags defines.
*/
#define EF_FRV_GPR_MASK 0x00000003 /* mask for # of gprs */
#define EF_FRV_GPR32 0x00000001 /* Only uses GR on 32-register */
#define EF_FRV_GPR64 0x00000002 /* Only uses GR on 64-register */
#define EF_FRV_FPR_MASK 0x0000000c /* mask for # of fprs */
#define EF_FRV_FPR32 0x00000004 /* Only uses FR on 32-register */
#define EF_FRV_FPR64 0x00000008 /* Only uses FR on 64-register */
#define EF_FRV_FPR_NONE 0x0000000C /* Uses software floating-point */
#define EF_FRV_DWORD_MASK 0x00000030 /* mask for dword support */
#define EF_FRV_DWORD_YES 0x00000010 /* Assumes stack aligned to 8-byte boundaries. */
#define EF_FRV_DWORD_NO 0x00000020 /* Assumes stack aligned to 4-byte boundaries. */
#define EF_FRV_DOUBLE 0x00000040 /* Uses double instructions. */
#define EF_FRV_MEDIA 0x00000080 /* Uses media instructions. */
#define EF_FRV_PIC 0x00000100 /* Uses position independent code. */
#define EF_FRV_NON_PIC_RELOCS 0x00000200 /* Does not use position Independent code. */
#define EF_FRV_MULADD 0x00000400 /* -mmuladd */
#define EF_FRV_BIGPIC 0x00000800 /* -fPIC */
#define EF_FRV_LIBPIC 0x00001000 /* -mlibrary-pic */
#define EF_FRV_G0 0x00002000 /* -G 0, no small data ptr */
#define EF_FRV_NOPACK 0x00004000 /* -mnopack */
#define EF_FRV_FDPIC 0x00008000 /* -mfdpic */
#define EF_FRV_CPU_MASK 0xff000000 /* specific cpu bits */
#define EF_FRV_CPU_GENERIC 0x00000000 /* Set CPU type is FR-V */
#define EF_FRV_CPU_FR500 0x01000000 /* Set CPU type is FR500 */
#define EF_FRV_CPU_FR300 0x02000000 /* Set CPU type is FR300 */
#define EF_FRV_CPU_SIMPLE 0x03000000 /* SIMPLE */
#define EF_FRV_CPU_TOMCAT 0x04000000 /* Tomcat, FR500 prototype */
#define EF_FRV_CPU_FR400 0x05000000 /* Set CPU type is FR400 */
#define EF_FRV_CPU_FR550 0x06000000 /* Set CPU type is FR550 */
#define EF_FRV_CPU_FR405 0x07000000 /* Set CPU type is FR405 */
#define EF_FRV_CPU_FR450 0x08000000 /* Set CPU type is FR450 */
/*
* FR-V ELF relocation types
*/
/*
* ELF register definitions..
*/
typedef unsigned long elf_greg_t;
#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
typedef struct user_fpmedia_regs elf_fpregset_t;
/*
* This is used to ensure we don't load something for the wrong architecture.
*/
extern int elf_check_arch(const struct elf32_hdr *hdr);
#define elf_check_fdpic(x) ((x)->e_flags & EF_FRV_FDPIC && !((x)->e_flags & EF_FRV_NON_PIC_RELOCS))
#define elf_check_const_displacement(x) ((x)->e_flags & EF_FRV_PIC)
/*
* These are used to set parameters in the core dumps.
*/
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2MSB
#define ELF_ARCH EM_FRV
#define ELF_PLAT_INIT(_r) \
do { \
__kernel_frame0_ptr->gr16 = 0; \
__kernel_frame0_ptr->gr17 = 0; \
__kernel_frame0_ptr->gr18 = 0; \
__kernel_frame0_ptr->gr19 = 0; \
__kernel_frame0_ptr->gr20 = 0; \
__kernel_frame0_ptr->gr21 = 0; \
__kernel_frame0_ptr->gr22 = 0; \
__kernel_frame0_ptr->gr23 = 0; \
__kernel_frame0_ptr->gr24 = 0; \
__kernel_frame0_ptr->gr25 = 0; \
__kernel_frame0_ptr->gr26 = 0; \
__kernel_frame0_ptr->gr27 = 0; \
__kernel_frame0_ptr->gr29 = 0; \
} while(0)
#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map_addr, _interp_map_addr, _dynamic_addr) \
do { \
__kernel_frame0_ptr->gr16 = _exec_map_addr; \
__kernel_frame0_ptr->gr17 = _interp_map_addr; \
__kernel_frame0_ptr->gr18 = _dynamic_addr; \
__kernel_frame0_ptr->gr19 = 0; \
__kernel_frame0_ptr->gr20 = 0; \
__kernel_frame0_ptr->gr21 = 0; \
__kernel_frame0_ptr->gr22 = 0; \
__kernel_frame0_ptr->gr23 = 0; \
__kernel_frame0_ptr->gr24 = 0; \
__kernel_frame0_ptr->gr25 = 0; \
__kernel_frame0_ptr->gr26 = 0; \
__kernel_frame0_ptr->gr27 = 0; \
__kernel_frame0_ptr->gr29 = 0; \
} while(0)
#define CORE_DUMP_USE_REGSET
#define ELF_FDPIC_CORE_EFLAGS EF_FRV_FDPIC
#define ELF_EXEC_PAGESIZE 16384
/* 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 0x08000000UL
/* This yields a mask that user programs can use to figure out what
instruction set this cpu supports. */
#define ELF_HWCAP (0)
/* This yields a string that ld.so will use to load implementation
specific libraries for optimization. This is more specific in
intent than poking at uname or /proc/cpuinfo. */
#define ELF_PLATFORM (NULL)
#endif
#ifndef _ASM_EMERGENCY_RESTART_H
#define _ASM_EMERGENCY_RESTART_H
#include <asm-generic/emergency-restart.h>
#endif /* _ASM_EMERGENCY_RESTART_H */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_FPU_H
#define __ASM_FPU_H
/*
* MAX floating point unit state size (FSAVE/FRESTORE)
*/
#define kernel_fpu_end() do { asm volatile("bar":::"memory"); preempt_enable(); } while(0)
#endif /* __ASM_FPU_H */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_FUTEX_H
#define _ASM_FUTEX_H
#ifdef __KERNEL__
#include <linux/futex.h>
#include <asm/errno.h>
#include <linux/uaccess.h>
extern int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
u32 __user *uaddr);
static inline int
futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval)
{
return -ENOSYS;
}
#endif
#endif
/* gdb-stub.h: FRV GDB stub
*
* Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
* - Derived from asm-mips/gdb-stub.h (c) 1995 Andreas Busse
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef __ASM_GDB_STUB_H
#define __ASM_GDB_STUB_H
#undef GDBSTUB_DEBUG_IO
#undef GDBSTUB_DEBUG_PROTOCOL
#include <asm/ptrace.h>
/*
* important register numbers in GDB protocol
* - GR0, GR1, GR2, GR3, GR4, GR5, GR6, GR7,
* - GR8, GR9, GR10, GR11, GR12, GR13, GR14, GR15,
* - GR16, GR17, GR18, GR19, GR20, GR21, GR22, GR23,
* - GR24, GR25, GR26, GR27, GR28, GR29, GR30, GR31,
* - GR32, GR33, GR34, GR35, GR36, GR37, GR38, GR39,
* - GR40, GR41, GR42, GR43, GR44, GR45, GR46, GR47,
* - GR48, GR49, GR50, GR51, GR52, GR53, GR54, GR55,
* - GR56, GR57, GR58, GR59, GR60, GR61, GR62, GR63,
* - FR0, FR1, FR2, FR3, FR4, FR5, FR6, FR7,
* - FR8, FR9, FR10, FR11, FR12, FR13, FR14, FR15,
* - FR16, FR17, FR18, FR19, FR20, FR21, FR22, FR23,
* - FR24, FR25, FR26, FR27, FR28, FR29, FR30, FR31,
* - FR32, FR33, FR34, FR35, FR36, FR37, FR38, FR39,
* - FR40, FR41, FR42, FR43, FR44, FR45, FR46, FR47,
* - FR48, FR49, FR50, FR51, FR52, FR53, FR54, FR55,
* - FR56, FR57, FR58, FR59, FR60, FR61, FR62, FR63,
* - PC, PSR, CCR, CCCR,
* - _X132, _X133, _X134
* - TBR, BRR, DBAR0, DBAR1, DBAR2, DBAR3,
* - SCR0, SCR1, SCR2, SCR3,
* - LR, LCR,
* - IACC0H, IACC0L,
* - FSR0,
* - ACC0, ACC1, ACC2, ACC3, ACC4, ACC5, ACC6, ACC7,
* - ACCG0123, ACCG4567,
* - MSR0, MSR1,
* - GNER0, GNER1,
* - FNER0, FNER1,
*/
#define GDB_REG_GR(N) (N)
#define GDB_REG_FR(N) (64+(N))
#define GDB_REG_PC 128
#define GDB_REG_PSR 129
#define GDB_REG_CCR 130
#define GDB_REG_CCCR 131
#define GDB_REG_TBR 135
#define GDB_REG_BRR 136
#define GDB_REG_DBAR(N) (137+(N))
#define GDB_REG_SCR(N) (141+(N))
#define GDB_REG_LR 145
#define GDB_REG_LCR 146
#define GDB_REG_FSR0 149
#define GDB_REG_ACC(N) (150+(N))
#define GDB_REG_ACCG(N) (158+(N)/4)
#define GDB_REG_MSR(N) (160+(N))
#define GDB_REG_GNER(N) (162+(N))
#define GDB_REG_FNER(N) (164+(N))
#define GDB_REG_SP GDB_REG_GR(1)
#define GDB_REG_FP GDB_REG_GR(2)
#ifndef _LANGUAGE_ASSEMBLY
/*
* Prototypes
*/
extern void show_registers_only(struct pt_regs *regs);
extern void gdbstub_init(void);
extern void gdbstub(int type);
extern void gdbstub_exit(int status);
extern void gdbstub_io_init(void);
extern void gdbstub_set_baud(unsigned baud);
extern int gdbstub_rx_char(unsigned char *_ch, int nonblock);
extern void gdbstub_tx_char(unsigned char ch);
extern void gdbstub_tx_flush(void);
extern void gdbstub_do_rx(void);
extern asmlinkage void __debug_stub_init_break(void);
extern asmlinkage void __break_hijack_kernel_event(void);
extern asmlinkage void __break_hijack_kernel_event_breaks_here(void);
extern asmlinkage void gdbstub_rx_handler(void);
extern asmlinkage void gdbstub_rx_irq(void);
extern asmlinkage void gdbstub_intercept(void);
extern uint32_t __entry_usertrap_table[];
extern uint32_t __entry_kerneltrap_table[];
extern volatile u8 gdbstub_rx_buffer[PAGE_SIZE];
extern volatile u32 gdbstub_rx_inp;
extern volatile u32 gdbstub_rx_outp;
extern volatile u8 gdbstub_rx_overflow;
extern u8 gdbstub_rx_unget;
extern void gdbstub_printk(const char *fmt, ...);
extern void debug_to_serial(const char *p, int n);
extern void console_set_baud(unsigned baud);
#ifdef GDBSTUB_DEBUG_IO
#define gdbstub_io(FMT,...) gdbstub_printk(FMT, ##__VA_ARGS__)
#else
#define gdbstub_io(FMT,...) ({ 0; })
#endif
#ifdef GDBSTUB_DEBUG_PROTOCOL
#define gdbstub_proto(FMT,...) gdbstub_printk(FMT,##__VA_ARGS__)
#else
#define gdbstub_proto(FMT,...) ({ 0; })
#endif
/*
* we dedicate GR31 to keeping a pointer to the gdbstub exception frame
* - gr31 is destroyed on entry to the gdbstub if !MMU
* - gr31 is saved in scr3 on entry to the gdbstub if in !MMU
*/
register struct frv_frame0 *__debug_frame0 asm("gr31");
#define __debug_frame (&__debug_frame0->regs)
#define __debug_user_context (&__debug_frame0->uc)
#define __debug_regs (&__debug_frame0->debug)
#define __debug_reg(X) ((unsigned long *) ((unsigned long) &__debug_frame0 + (X)))
struct frv_debug_status {
unsigned long bpsr;
unsigned long dcr;
unsigned long brr;
unsigned long nmar;
};
extern struct frv_debug_status __debug_status;
#endif /* _LANGUAGE_ASSEMBLY */
#endif /* __ASM_GDB_STUB_H */
/* gpio-regs.h: on-chip general purpose I/O registers
*
* Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_GPIO_REGS
#define _ASM_GPIO_REGS
#define __reg(ADDR) (*(volatile unsigned long *)(ADDR))
#define __get_PDR() ({ __reg(0xfeff0400); })
#define __set_PDR(V) do { __reg(0xfeff0400) = (V); mb(); } while(0)
#define __get_GPDR() ({ __reg(0xfeff0408); })
#define __set_GPDR(V) do { __reg(0xfeff0408) = (V); mb(); } while(0)
#define __get_SIR() ({ __reg(0xfeff0410); })
#define __set_SIR(V) do { __reg(0xfeff0410) = (V); mb(); } while(0)
#define __get_SOR() ({ __reg(0xfeff0418); })
#define __set_SOR(V) do { __reg(0xfeff0418) = (V); mb(); } while(0)
#define __set_PDSR(V) do { __reg(0xfeff0420) = (V); mb(); } while(0)
#define __set_PDCR(V) do { __reg(0xfeff0428) = (V); mb(); } while(0)
#define __get_RSTR() ({ __reg(0xfeff0500); })
#define __set_RSTR(V) do { __reg(0xfeff0500) = (V); mb(); } while(0)
/* PDR definitions */
#define PDR_GPIO_DATA(X) (1 << (X))
/* GPDR definitions */
#define GPDR_INPUT 0
#define GPDR_OUTPUT 1
#define GPDR_DREQ0_BIT 0x00001000
#define GPDR_DREQ1_BIT 0x00008000
#define GPDR_DREQ2_BIT 0x00040000
#define GPDR_DREQ3_BIT 0x00080000
#define GPDR_DREQ4_BIT 0x00004000
#define GPDR_DREQ5_BIT 0x00020000
#define GPDR_DREQ6_BIT 0x00100000
#define GPDR_DREQ7_BIT 0x00200000
#define GPDR_DACK0_BIT 0x00002000
#define GPDR_DACK1_BIT 0x00010000
#define GPDR_DACK2_BIT 0x00100000
#define GPDR_DACK3_BIT 0x00200000
#define GPDR_DONE0_BIT 0x00004000
#define GPDR_DONE1_BIT 0x00020000
#define GPDR_GPIO_DIR(X,D) ((D) << (X))
/* SIR definitions */
#define SIR_GPIO_INPUT 0
#define SIR_DREQ7_INPUT 0x00200000
#define SIR_DREQ6_INPUT 0x00100000
#define SIR_DREQ3_INPUT 0x00080000
#define SIR_DREQ2_INPUT 0x00040000
#define SIR_DREQ5_INPUT 0x00020000
#define SIR_DREQ1_INPUT 0x00008000
#define SIR_DREQ4_INPUT 0x00004000
#define SIR_DREQ0_INPUT 0x00001000
#define SIR_RXD1_INPUT 0x00000400
#define SIR_CTS0_INPUT 0x00000100
#define SIR_RXD0_INPUT 0x00000040
#define SIR_GATE1_INPUT 0x00000020
#define SIR_GATE0_INPUT 0x00000010
#define SIR_IRQ3_INPUT 0x00000008
#define SIR_IRQ2_INPUT 0x00000004
#define SIR_IRQ1_INPUT 0x00000002
#define SIR_IRQ0_INPUT 0x00000001
#define SIR_DREQ_BITS (SIR_DREQ0_INPUT | SIR_DREQ1_INPUT | \
SIR_DREQ2_INPUT | SIR_DREQ3_INPUT | \
SIR_DREQ4_INPUT | SIR_DREQ5_INPUT | \
SIR_DREQ6_INPUT | SIR_DREQ7_INPUT)
/* SOR definitions */
#define SOR_GPIO_OUTPUT 0
#define SOR_DACK3_OUTPUT 0x00200000
#define SOR_DACK2_OUTPUT 0x00100000
#define SOR_DONE1_OUTPUT 0x00020000
#define SOR_DACK1_OUTPUT 0x00010000
#define SOR_DONE0_OUTPUT 0x00004000
#define SOR_DACK0_OUTPUT 0x00002000
#define SOR_TXD1_OUTPUT 0x00000800
#define SOR_RTS0_OUTPUT 0x00000200
#define SOR_TXD0_OUTPUT 0x00000080
#define SOR_TOUT1_OUTPUT 0x00000020
#define SOR_TOUT0_OUTPUT 0x00000010
#define SOR_DONE_BITS (SOR_DONE0_OUTPUT | SOR_DONE1_OUTPUT)
#define SOR_DACK_BITS (SOR_DACK0_OUTPUT | SOR_DACK1_OUTPUT | \
SOR_DACK2_OUTPUT | SOR_DACK3_OUTPUT)
/* PDSR definitions */
#define PDSR_UNCHANGED 0
#define PDSR_SET_BIT(X) (1 << (X))
/* PDCR definitions */
#define PDCR_UNCHANGED 0
#define PDCR_CLEAR_BIT(X) (1 << (X))
/* RSTR definitions */
/* Read Only */
#define RSTR_POWERON 0x00000400
#define RSTR_SOFTRESET_STATUS 0x00000100
/* Write Only */
#define RSTR_SOFTRESET 0x00000001
#endif /* _ASM_GPIO_REGS */
/* hardirq.h: FRV hardware IRQ management
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef __ASM_HARDIRQ_H
#define __ASM_HARDIRQ_H
#include <linux/atomic.h>
extern atomic_t irq_err_count;
static inline void ack_bad_irq(int irq)
{
atomic_inc(&irq_err_count);
}
#define ack_bad_irq ack_bad_irq
#include <asm-generic/hardirq.h>
#endif
/* highmem.h: virtual kernel memory mappings for high memory
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
* - Derived from include/asm-i386/highmem.h
*
* See Documentation/frv/mmu-layout.txt for more information.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_HIGHMEM_H
#define _ASM_HIGHMEM_H
#ifdef __KERNEL__
#include <linux/init.h>
#include <linux/highmem.h>
#include <asm/mem-layout.h>
#include <asm/spr-regs.h>
#include <asm/mb-regs.h>
#define NR_TLB_LINES 64 /* number of lines in the TLB */
#ifndef __ASSEMBLY__
#include <linux/interrupt.h>
#include <asm/kmap_types.h>
#include <asm/pgtable.h>
#ifdef CONFIG_DEBUG_HIGHMEM
#define HIGHMEM_DEBUG 1
#else
#define HIGHMEM_DEBUG 0
#endif
/* declarations for highmem.c */
extern unsigned long highstart_pfn, highend_pfn;
#define kmap_prot PAGE_KERNEL
#define kmap_pte ______kmap_pte_in_TLB
extern pte_t *pkmap_page_table;
#define flush_cache_kmaps() do { } while (0)
/*
* Right now we initialize only a single pte table. It can be extended
* easily, subsequent pte tables have to be allocated in one physical
* chunk of RAM.
*/
#define LAST_PKMAP PTRS_PER_PTE
#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
#define PKMAP_NR(virt) ((virt - PKMAP_BASE) >> PAGE_SHIFT)
#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
extern void *kmap_high(struct page *page);
extern void kunmap_high(struct page *page);
extern void *kmap(struct page *page);
extern void kunmap(struct page *page);
#endif /* !__ASSEMBLY__ */
/*
* The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
* gives a more generic (and caching) interface. But kmap_atomic can
* be used in IRQ contexts, so in some (very limited) cases we need
* it.
*/
#define KMAP_ATOMIC_CACHE_DAMR 8
#ifndef __ASSEMBLY__
#define __kmap_atomic_primary(cached, paddr, ampr) \
({ \
unsigned long damlr, dampr; \
\
dampr = paddr | xAMPRx_L | xAMPRx_M | xAMPRx_S | xAMPRx_SS_16Kb | xAMPRx_V; \
\
if (!cached) \
asm volatile("movgs %0,dampr"#ampr :: "r"(dampr) : "memory"); \
else \
/* cache flush page attachment point */ \
asm volatile("movgs %0,iampr"#ampr"\n" \
"movgs %0,dampr"#ampr"\n" \
:: "r"(dampr) : "memory" \
); \
\
asm("movsg damlr"#ampr",%0" : "=r"(damlr)); \
\
/*printk("DAMR"#ampr": PRIM sl=%d L=%08lx P=%08lx\n", type, damlr, dampr);*/ \
\
(void *) damlr; \
})
#define __kmap_atomic_secondary(slot, paddr) \
({ \
unsigned long damlr = KMAP_ATOMIC_SECONDARY_FRAME + (slot) * PAGE_SIZE; \
unsigned long dampr = paddr | xAMPRx_L | xAMPRx_M | xAMPRx_S | xAMPRx_SS_16Kb | xAMPRx_V; \
\
asm volatile("movgs %0,tplr \n" \
"movgs %1,tppr \n" \
"tlbpr %0,gr0,#2,#1" \
: : "r"(damlr), "r"(dampr) : "memory"); \
\
/*printk("TLB: SECN sl=%d L=%08lx P=%08lx\n", slot, damlr, dampr);*/ \
\
(void *) damlr; \
})
static inline void *kmap_atomic_primary(struct page *page)
{
unsigned long paddr;
pagefault_disable();
paddr = page_to_phys(page);
return __kmap_atomic_primary(1, paddr, 2);
}
#define __kunmap_atomic_primary(cached, ampr) \
do { \
asm volatile("movgs gr0,dampr"#ampr"\n" ::: "memory"); \
if (cached) \
asm volatile("movgs gr0,iampr"#ampr"\n" ::: "memory"); \
} while(0)
#define __kunmap_atomic_secondary(slot, vaddr) \
do { \
asm volatile("tlbpr %0,gr0,#4,#1" : : "r"(vaddr) : "memory"); \
} while(0)
static inline void kunmap_atomic_primary(void *kvaddr)
{
__kunmap_atomic_primary(1, 2);
pagefault_enable();
}
void *kmap_atomic(struct page *page);
void __kunmap_atomic(void *kvaddr);
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_HIGHMEM_H */
/* hw_irq.h: FR-V specific h/w IRQ stuff
*
* Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_HW_IRQ_H
#define _ASM_HW_IRQ_H
#endif /* _ASM_HW_IRQ_H */
This diff is collapsed.
/* irc-regs.h: on-chip interrupt controller registers
*
* Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_IRC_REGS
#define _ASM_IRC_REGS
#define __reg(ADDR) (*(volatile unsigned long *)(ADDR))
#define __get_TM0() ({ __reg(0xfeff9800); })
#define __get_TM1() ({ __reg(0xfeff9808); })
#define __set_TM1(V) do { __reg(0xfeff9808) = (V); mb(); } while(0)
#define __set_TM1x(XI,V) \
do { \
int shift = (XI) * 2 + 16; \
unsigned long tm1 = __reg(0xfeff9808); \
tm1 &= ~(0x3 << shift); \
tm1 |= (V) << shift; \
__reg(0xfeff9808) = tm1; \
mb(); \
} while(0)
#define __get_RS(C) ({ (__reg(0xfeff9810) >> ((C)+16)) & 1; })
#define __clr_RC(C) do { __reg(0xfeff9818) = 1 << ((C)+16); mb(); } while(0)
#define __get_MASK(C) ({ (__reg(0xfeff9820) >> ((C)+16)) & 1; })
#define __set_MASK(C) do { __reg(0xfeff9820) |= 1 << ((C)+16); mb(); } while(0)
#define __clr_MASK(C) do { __reg(0xfeff9820) &= ~(1 << ((C)+16)); mb(); } while(0)
#define __get_MASK_all() __get_MASK(0)
#define __set_MASK_all() __set_MASK(0)
#define __clr_MASK_all() __clr_MASK(0)
#define __get_IRL() ({ (__reg(0xfeff9828) >> 16) & 0xf; })
#define __clr_IRL() do { __reg(0xfeff9828) = 0x100000; mb(); } while(0)
#define __get_IRR(N) ({ __reg(0xfeff9840 + (N) * 8); })
#define __set_IRR(N,V) do { __reg(0xfeff9840 + (N) * 8) = (V); } while(0)
#define __get_IITMR(N) ({ __reg(0xfeff9880 + (N) * 8); })
#define __set_IITMR(N,V) do { __reg(0xfeff9880 + (N) * 8) = (V); } while(0)
#endif /* _ASM_IRC_REGS */
/* irq.h: FRV IRQ definitions
*
* Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_IRQ_H_
#define _ASM_IRQ_H_
#define NR_IRQS 48
#define IRQ_BASE_CPU (0 * 16)
#define IRQ_BASE_FPGA (1 * 16)
#define IRQ_BASE_MB93493 (2 * 16)
/* probe returns a 32-bit IRQ mask:-/ */
#define MIN_PROBE_IRQ (NR_IRQS - 32)
#ifndef __ASSEMBLY__
static inline int irq_canonicalize(int irq)
{
return irq;
}
#endif
#endif /* _ASM_IRQ_H_ */
/* FRV per-CPU frame pointer holder
*
* Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_IRQ_REGS_H
#define _ASM_IRQ_REGS_H
/*
* Per-cpu current frame pointer - the location of the last exception frame on
* the stack
* - on FRV, GR28 is dedicated to keeping a pointer to the current exception
* frame
*/
#define ARCH_HAS_OWN_IRQ_REGS
#ifndef __ASSEMBLY__
#define get_irq_regs() (__frame)
#endif
#endif /* _ASM_IRQ_REGS_H */
/* FR-V interrupt handling
*
* Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licence
* as published by the Free Software Foundation; either version
* 2 of the Licence, or (at your option) any later version.
*/
#ifndef _ASM_IRQFLAGS_H
#define _ASM_IRQFLAGS_H
/*
* interrupt flag manipulation
* - use virtual interrupt management since touching the PSR is slow
* - ICC2.Z: T if interrupts virtually disabled
* - ICC2.C: F if interrupts really disabled
* - if Z==1 upon interrupt:
* - C is set to 0
* - interrupts are really disabled
* - entry.S returns immediately
* - uses TIHI (TRAP if Z==0 && C==0) #2 to really reenable interrupts
* - if taken, the trap:
* - sets ICC2.C
* - enables interrupts
*/
static inline void arch_local_irq_disable(void)
{
/* set Z flag, but don't change the C flag */
asm volatile(" andcc gr0,gr0,gr0,icc2 \n"
:
:
: "memory", "icc2"
);
}
static inline void arch_local_irq_enable(void)
{
/* clear Z flag and then test the C flag */
asm volatile(" oricc gr0,#1,gr0,icc2 \n"
" tihi icc2,gr0,#2 \n"
:
:
: "memory", "icc2"
);
}
static inline unsigned long arch_local_save_flags(void)
{
unsigned long flags;
asm volatile("movsg ccr,%0"
: "=r"(flags)
:
: "memory");
/* shift ICC2.Z to bit 0 */
flags >>= 26;
/* make flags 1 if interrupts disabled, 0 otherwise */
return flags & 1UL;
}
static inline unsigned long arch_local_irq_save(void)
{
unsigned long flags = arch_local_save_flags();
arch_local_irq_disable();
return flags;
}
static inline void arch_local_irq_restore(unsigned long flags)
{
/* load the Z flag by turning 1 if disabled into 0 if disabled
* and thus setting the Z flag but not the C flag */
asm volatile(" xoricc %0,#1,gr0,icc2 \n"
/* then trap if Z=0 and C=0 */
" tihi icc2,gr0,#2 \n"
:
: "r"(flags)
: "memory", "icc2"
);
}
static inline bool arch_irqs_disabled_flags(unsigned long flags)
{
return flags;
}
static inline bool arch_irqs_disabled(void)
{
return arch_irqs_disabled_flags(arch_local_save_flags());
}
/*
* real interrupt flag manipulation
*/
#define __arch_local_irq_disable() \
do { \
unsigned long psr; \
asm volatile(" movsg psr,%0 \n" \
" andi %0,%2,%0 \n" \
" ori %0,%1,%0 \n" \
" movgs %0,psr \n" \
: "=r"(psr) \
: "i" (PSR_PIL_14), "i" (~PSR_PIL) \
: "memory"); \
} while (0)
#define __arch_local_irq_enable() \
do { \
unsigned long psr; \
asm volatile(" movsg psr,%0 \n" \
" andi %0,%1,%0 \n" \
" movgs %0,psr \n" \
: "=r"(psr) \
: "i" (~PSR_PIL) \
: "memory"); \
} while (0)
#define __arch_local_save_flags(flags) \
do { \
typecheck(unsigned long, flags); \
asm("movsg psr,%0" \
: "=r"(flags) \
: \
: "memory"); \
} while (0)
#define __arch_local_irq_save(flags) \
do { \
unsigned long npsr; \
typecheck(unsigned long, flags); \
asm volatile(" movsg psr,%0 \n" \
" andi %0,%3,%1 \n" \
" ori %1,%2,%1 \n" \
" movgs %1,psr \n" \
: "=r"(flags), "=r"(npsr) \
: "i" (PSR_PIL_14), "i" (~PSR_PIL) \
: "memory"); \
} while (0)
#define __arch_local_irq_restore(flags) \
do { \
typecheck(unsigned long, flags); \
asm volatile(" movgs %0,psr \n" \
: \
: "r" (flags) \
: "memory"); \
} while (0)
#define __arch_irqs_disabled() \
((__get_PSR() & PSR_PIL) >= PSR_PIL_14)
#endif /* _ASM_IRQFLAGS_H */
#include <asm-generic/kdebug.h>
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_KMAP_TYPES_H
#define _ASM_KMAP_TYPES_H
#define KM_TYPE_NR 17
#endif
#ifndef __ASM_LINKAGE_H
#define __ASM_LINKAGE_H
#define __ALIGN .align 4
#define __ALIGN_STR ".align 4"
#endif
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_LOCAL_H
#define _ASM_LOCAL_H
#include <asm-generic/local.h>
#endif /* _ASM_LOCAL_H */
#include <asm-generic/local64.h>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* mb93093-fpga-irqs.h: MB93093 CPU board FPGA IRQs
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_MB93093_FPGA_IRQS_H
#define _ASM_MB93093_FPGA_IRQS_H
#include <asm/irq.h>
#ifndef __ASSEMBLY__
/* IRQ IDs presented to drivers */
enum {
IRQ_FPGA_PUSH_BUTTON_SW1_5 = IRQ_BASE_FPGA + 8,
IRQ_FPGA_ROCKER_C_SW8 = IRQ_BASE_FPGA + 9,
IRQ_FPGA_ROCKER_C_SW9 = IRQ_BASE_FPGA + 10,
};
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_MB93093_FPGA_IRQS_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment