提交 c690eddc 编写于 作者: J Jesper Nilsson 提交者: Arnd Bergmann

CRIS: Drop support for the CRIS port

The port was added back in 2000 so it's no longer even a good source
of inspiration for newer ports (if it ever was)

The last SoC (ARTPEC-3) with a CRIS main CPU was launched in 2008.

Coupled with time and working developer board hardware being
in low supply, it's time to drop the port from Linux.

So long and thanks for all the fish!
Signed-off-by: NJesper Nilsson <jesper.nilsson@axis.com>
Signed-off-by: NArnd Bergmann <arnd@arndb.de>
上级 bb9d8126
......@@ -112,8 +112,6 @@ cputopology.txt
- documentation on how CPU topology info is exported via sysfs.
crc32.txt
- brief tutorial on CRC computation
cris/
- directory with info about Linux on CRIS architecture.
crypto/
- directory with info on the Crypto API.
dcdbas.txt
......
Linux on the CRIS architecture
==============================
This is a port of Linux to Axis Communications ETRAX 100LX,
ETRAX FS and ARTPEC-3 embedded network CPUs.
For more information about CRIS and ETRAX please see further below.
In order to compile this you need a version of gcc with support for the
ETRAX chip family. Please see this link for more information on how to
download the compiler and other tools useful when building and booting
software for the ETRAX platform:
http://developer.axis.com/wiki/doku.php?id=axis:install-howto-2_20
What is CRIS ?
--------------
CRIS is an acronym for 'Code Reduced Instruction Set'. It is the CPU
architecture in Axis Communication AB's range of embedded network CPU's,
called ETRAX.
The ETRAX 100LX chip
--------------------
For reference, please see the following link:
http://www.axis.com/products/dev_etrax_100lx/index.htm
The ETRAX 100LX is a 100 MIPS processor with 8kB cache, MMU, and a very broad
range of built-in interfaces, all with modern scatter/gather DMA.
Memory interfaces:
* SRAM
* NOR-flash/ROM
* EDO or page-mode DRAM
* SDRAM
I/O interfaces:
* one 10/100 Mbit/s ethernet controller
* four serial-ports (up to 6 Mbit/s)
* two synchronous serial-ports for multimedia codec's etc.
* USB host controller and USB slave
* ATA
* SCSI
* two parallel-ports
* two generic 8-bit ports
(not all interfaces are available at the same time due to chip pin
multiplexing)
ETRAX 100LX is CRISv10 architecture.
The ETRAX FS and ARTPEC-3 chips
-------------------------------
The ETRAX FS is a 200MHz 32-bit RISC processor with on-chip 16kB
I-cache and 16kB D-cache and with a wide range of device interfaces
including multiple high speed serial ports and an integrated USB 1.1 PHY.
The ARTPEC-3 is a variant of the ETRAX FS with additional IO-units
used by the Axis Communications network cameras.
See below link for more information:
http://www.axis.com/products/dev_etrax_fs/index.htm
ETRAX FS and ARTPEC-3 are both CRISv32 architectures.
Bootlog
-------
Just as an example, this is the debug-output from a boot of Linux 2.4 on
a board with ETRAX 100LX. The displayed BogoMIPS value is 5 times too small :)
At the end you see some user-mode programs booting like telnet and ftp daemons.
Linux version 2.4.1 (bjornw@godzilla.axis.se) (gcc version 2.96 20000427 (experimental)) #207 Wed Feb 21 15:48:15 CET 2001
ROM fs in RAM, size 1376256 bytes
Setting up paging and the MMU.
On node 0 totalpages: 2048
zone(0): 2048 pages.
zone(1): 0 pages.
zone(2): 0 pages.
Linux/CRIS port on ETRAX 100LX (c) 2001 Axis Communications AB
Kernel command line:
Calibrating delay loop... 19.91 BogoMIPS
Memory: 13872k/16384k available (587k kernel code, 2512k reserved, 44k data, 24k init)
kmem_create: Forcing size word alignment - vm_area_struct
kmem_create: Forcing size word alignment - filp
Dentry-cache hash table entries: 2048 (order: 1, 16384 bytes)
Buffer-cache hash table entries: 2048 (order: 0, 8192 bytes)
Page-cache hash table entries: 2048 (order: 0, 8192 bytes)
kmem_create: Forcing size word alignment - kiobuf
kmem_create: Forcing size word alignment - bdev_cache
Inode-cache hash table entries: 1024 (order: 0, 8192 bytes)
kmem_create: Forcing size word alignment - inode_cache
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Starting kswapd v1.8
kmem_create: Forcing size word alignment - file lock cache
kmem_create: Forcing size word alignment - blkdev_requests
block: queued sectors max/low 9109kB/3036kB, 64 slots per queue
ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000 Axis Communications AB
eth0 initialized
eth0: changed MAC to 00:40:8C:CD:00:00
ETRAX 100LX serial-driver $Revision: 1.7 $, (c) 2000 Axis Communications AB
ttyS0 at 0xb0000060 is a builtin UART with DMA
ttyS1 at 0xb0000068 is a builtin UART with DMA
ttyS2 at 0xb0000070 is a builtin UART with DMA
ttyS3 at 0xb0000078 is a builtin UART with DMA
Axis flash mapping: 200000 at 50000000
Axis flash: Found 1 x16 CFI device at 0x0 in 16 bit mode
Amd/Fujitsu Extended Query Table v1.0 at 0x0040
Axis flash: JEDEC Device ID is 0xC4. Assuming broken CFI table.
Axis flash: Swapping erase regions for broken CFI table.
number of CFI chips: 1
Using default partition table
I2C driver v2.2, (c) 1999-2001 Axis Communications AB
ETRAX 100LX GPIO driver v2.1, (c) 2001 Axis Communications AB
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP
kmem_create: Forcing size word alignment - ip_dst_cache
IP: routing cache hash table of 1024 buckets, 8Kbytes
TCP: Hash tables configured (established 2048 bind 2048)
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
VFS: Mounted root (cramfs filesystem) readonly.
Init starts up...
Mounted none on /proc ok.
Setting up eth0 with ip 10.13.9.116 and mac 00:40:8c:18:04:60
eth0: changed MAC to 00:40:8C:18:04:60
Setting up lo with ip 127.0.0.1
Default gateway is 10.13.9.1
Hostname is bbox1
Telnetd starting, using port 23.
using /bin/sash as shell.
sftpd[15]: sftpd $Revision: 1.7 $ starting up
And here is how some /proc entries look:
17# cd /proc
17# cat cpuinfo
cpu : CRIS
cpu revision : 10
cpu model : ETRAX 100LX
cache size : 8 kB
fpu : no
mmu : yes
ethernet : 10/100 Mbps
token ring : no
scsi : yes
ata : yes
usb : yes
bogomips : 99.84
17# cat meminfo
total: used: free: shared: buffers: cached:
Mem: 7028736 925696 6103040 114688 0 229376
Swap: 0 0 0
MemTotal: 6864 kB
MemFree: 5960 kB
MemShared: 112 kB
Buffers: 0 kB
Cached: 224 kB
Active: 224 kB
Inact_dirty: 0 kB
Inact_clean: 0 kB
Inact_target: 0 kB
HighTotal: 0 kB
HighFree: 0 kB
LowTotal: 6864 kB
LowFree: 5960 kB
SwapTotal: 0 kB
SwapFree: 0 kB
17# ls -l /bin
-rwxr-xr-x 1 342 100 10356 Jan 01 00:00 ifconfig
-rwxr-xr-x 1 342 100 17548 Jan 01 00:00 init
-rwxr-xr-x 1 342 100 9488 Jan 01 00:00 route
-rwxr-xr-x 1 342 100 46036 Jan 01 00:00 sftpd
-rwxr-xr-x 1 342 100 48104 Jan 01 00:00 sh
-rwxr-xr-x 1 342 100 16252 Jan 01 00:00 telnetd
Axis Communications AB
ARTPEC series SoC Device Tree Bindings
CRISv32 based SoCs are ETRAX FS and ARTPEC-3:
- compatible = "axis,crisv32";
Boards based on the CRIS SoCs:
Required root node properties:
- compatible = should be one or more of the following:
- "axis,dev88" - for Axis devboard 88 with ETRAX FS
Optional:
* CRISv32 Interrupt Controller
Interrupt controller for the CRISv32 SoCs.
Main node required properties:
- compatible : should be:
"axis,crisv32-intc"
- interrupt-controller : Identifies the node as an interrupt controller
- #interrupt-cells : Specifies the number of cells needed to encode an
interrupt source. The type shall be a <u32> and the value shall be 1.
- reg: physical base address and size of the intc registers map.
Example:
intc: interrupt-controller {
compatible = "axis,crisv32-intc";
reg = <0xb001c000 0x1000>;
interrupt-controller;
#interrupt-cells = <1>;
};
......@@ -3704,16 +3704,6 @@ S: Maintained
F: Documentation/filesystems/cramfs.txt
F: fs/cramfs/
CRIS PORT
M: Mikael Starvik <starvik@axis.com>
M: Jesper Nilsson <jesper.nilsson@axis.com>
L: linux-cris-kernel@axis.com
W: http://developer.axis.com
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jesper/cris.git
S: Maintained
F: arch/cris/
F: drivers/tty/serial/crisv10.*
CRYPTO API
M: Herbert Xu <herbert@gondor.apana.org.au>
M: "David S. Miller" <davem@davemloft.net>
......
# SPDX-License-Identifier: GPL-2.0
config MMU
bool
default y
config ZONE_DMA
bool
default y
config RWSEM_GENERIC_SPINLOCK
bool
default y
config RWSEM_XCHGADD_ALGORITHM
bool
config ARCH_HAS_ILOG2_U32
bool
default n
config ARCH_HAS_ILOG2_U64
bool
default n
config GENERIC_HWEIGHT
bool
default y
config GENERIC_CALIBRATE_DELAY
bool
default y
config NO_IOPORT_MAP
def_bool y if !PCI
config NO_DMA
def_bool y if !PCI
config FORCE_MAX_ZONEORDER
int
default 6
config TRACE_IRQFLAGS_SUPPORT
depends on ETRAX_ARCH_V32
def_bool y
config STACKTRACE_SUPPORT
def_bool y
config LOCKDEP_SUPPORT
depends on ETRAX_ARCH_V32
def_bool y
config CRIS
bool
default y
select HAVE_IDE
select GENERIC_ATOMIC64
select HAVE_UID16
select VIRT_TO_BUS
select ARCH_WANT_IPC_PARSE_VERSION
select GENERIC_IRQ_SHOW
select GENERIC_IOMAP
select MODULES_USE_ELF_RELA
select CLONE_BACKWARDS2
select HAVE_EXIT_THREAD if ETRAX_ARCH_V32
select OLD_SIGSUSPEND
select OLD_SIGACTION
select GPIOLIB
select IRQ_DOMAIN if ETRAX_ARCH_V32
select OF if ETRAX_ARCH_V32
select OF_EARLY_FLATTREE if ETRAX_ARCH_V32
select CLKSRC_MMIO if ETRAX_ARCH_V32
select GENERIC_CLOCKEVENTS if ETRAX_ARCH_V32
select GENERIC_SCHED_CLOCK if ETRAX_ARCH_V32
select HAVE_DEBUG_BUGVERBOSE if ETRAX_ARCH_V32
select HAVE_NMI
select DMA_DIRECT_OPS if PCI
config HZ
int
default 100
config NR_CPUS
int
default "1"
config BUILTIN_DTB
string "DTB to build into the kernel image"
depends on OF
source "init/Kconfig"
source "kernel/Kconfig.freezer"
menu "General setup"
source "fs/Kconfig.binfmt"
config ETRAX_CMDLINE
string "Kernel command line"
default "root=/dev/mtdblock3"
help
Pass additional commands to the kernel.
config ETRAX_WATCHDOG
bool "Enable ETRAX watchdog"
help
Enable the built-in watchdog timer support on ETRAX based embedded
network computers.
config ETRAX_WATCHDOG_NICE_DOGGY
bool "Disable watchdog during Oops printouts"
depends on ETRAX_WATCHDOG
help
By enabling this you make sure that the watchdog does not bite while
printing oopses. Recommended for development systems but not for
production releases.
config ETRAX_FAST_TIMER
bool "Enable ETRAX fast timer API"
help
This options enables the API to a fast timer implementation using
timer1 to get sub jiffie resolution timers (primarily one-shot
timers).
This is needed if CONFIG_ETRAX_SERIAL_FAST_TIMER is enabled.
config ETRAX_KMALLOCED_MODULES
bool "Enable module allocation with kmalloc"
help
Enable module allocation with kmalloc instead of vmalloc.
source "kernel/Kconfig.preempt"
source mm/Kconfig
endmenu
menu "Hardware setup"
choice
prompt "Processor type"
default ETRAX100LX
config ETRAX100LX
bool "ETRAX-100LX-v1"
select ARCH_USES_GETTIMEOFFSET
help
Support version 1 of the ETRAX 100LX.
config ETRAX100LX_V2
bool "ETRAX-100LX-v2"
select ARCH_USES_GETTIMEOFFSET
help
Support version 2 of the ETRAX 100LX.
config ETRAXFS
bool "ETRAX-FS-V32"
help
Support CRIS V32.
config CRIS_MACH_ARTPEC3
bool "ARTPEC-3"
help
Support Axis ARTPEC-3.
endchoice
config ETRAX_ARCH_V10
bool
default y if ETRAX100LX || ETRAX100LX_V2
default n if !(ETRAX100LX || ETRAX100LX_V2)
select TTY
config ETRAX_ARCH_V32
bool
default y if (ETRAXFS || CRIS_MACH_ARTPEC3)
default n if !(ETRAXFS || CRIS_MACH_ARTPEC3)
config ETRAX_DRAM_SIZE
int "DRAM size (dec, in MB)"
default "8"
help
Size of DRAM (decimal in MB) typically 2, 8 or 16.
config ETRAX_VMEM_SIZE
int "Video memory size (dec, in MB)"
depends on ETRAX_ARCH_V32 && !ETRAXFS
default 8 if !ETRAXFS
help
Size of Video accessible memory (decimal, in MB).
config ETRAX_FLASH_BUSWIDTH
int "Buswidth of NOR flash in bytes"
default "2"
help
Width in bytes of the NOR Flash bus (1, 2 or 4). Is usually 2.
config ETRAX_FLASH1_SIZE
int "FLASH1 size (dec, in MB. 0 = Unknown)"
default "0"
choice
prompt "Product debug-port"
default ETRAX_DEBUG_PORT0
config ETRAX_DEBUG_PORT0
bool "Serial-0"
help
Choose a serial port for the ETRAX debug console. Default to
port 0.
config ETRAX_DEBUG_PORT1
bool "Serial-1"
help
Use serial port 1 for the console.
config ETRAX_DEBUG_PORT2
bool "Serial-2"
help
Use serial port 2 for the console.
config ETRAX_DEBUG_PORT3
bool "Serial-3"
help
Use serial port 3 for the console.
config ETRAX_DEBUG_PORT_NULL
bool "disabled"
help
Disable serial-port debugging.
endchoice
choice
prompt "Kernel GDB port"
depends on ETRAX_KGDB
default ETRAX_KGDB_PORT0
help
Choose a serial port for kernel debugging. NOTE: This port should
not be enabled under Drivers for built-in interfaces (as it has its
own initialization code) and should not be the same as the debug port.
config ETRAX_KGDB_PORT0
bool "Serial-0"
help
Use serial port 0 for kernel debugging.
config ETRAX_KGDB_PORT1
bool "Serial-1"
help
Use serial port 1 for kernel debugging.
config ETRAX_KGDB_PORT2
bool "Serial-2"
help
Use serial port 2 for kernel debugging.
config ETRAX_KGDB_PORT3
bool "Serial-3"
help
Use serial port 3 for kernel debugging.
endchoice
source arch/cris/arch-v10/Kconfig
source arch/cris/arch-v32/Kconfig
endmenu
source "net/Kconfig"
# bring in ETRAX built-in drivers
menu "Drivers for built-in interfaces"
source arch/cris/arch-v10/drivers/Kconfig
source arch/cris/arch-v32/drivers/Kconfig
config ETRAX_AXISFLASHMAP
bool "Axis flash-map support"
select MTD
select MTD_CFI
select MTD_CFI_AMDSTD
select MTD_JEDECPROBE if ETRAX_ARCH_V32
select MTD_BLOCK
select MTD_COMPLEX_MAPPINGS
help
This option enables MTD mapping of flash devices. Needed to use
flash memories. If unsure, say Y.
config ETRAX_SYNCHRONOUS_SERIAL
bool "Synchronous serial-port support"
help
Select this to enable the synchronous serial port driver.
config ETRAX_SYNCHRONOUS_SERIAL_PORT0
bool "Synchronous serial port 0 enabled"
depends on ETRAX_SYNCHRONOUS_SERIAL
help
Enabled synchronous serial port 0.
config ETRAX_SYNCHRONOUS_SERIAL0_DMA
bool "Enable DMA on synchronous serial port 0."
depends on ETRAX_SYNCHRONOUS_SERIAL_PORT0
help
A synchronous serial port can run in manual or DMA mode.
Selecting this option will make it run in DMA mode.
config ETRAX_SYNCHRONOUS_SERIAL_PORT1
bool "Synchronous serial port 1 enabled"
depends on ETRAX_SYNCHRONOUS_SERIAL && (ETRAXFS || ETRAX_ARCH_V10)
help
Enabled synchronous serial port 1.
config ETRAX_SYNCHRONOUS_SERIAL1_DMA
bool "Enable DMA on synchronous serial port 1."
depends on ETRAX_SYNCHRONOUS_SERIAL_PORT1
help
A synchronous serial port can run in manual or DMA mode.
Selecting this option will make it run in DMA mode.
choice
prompt "Network LED behavior"
depends on ETRAX_ETHERNET
default ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY
config ETRAX_NETWORK_LED_ON_WHEN_LINK
bool "LED_on_when_link"
help
Selecting LED_on_when_link will light the LED when there is a
connection and will flash off when there is activity.
Selecting LED_on_when_activity will light the LED only when
there is activity.
This setting will also affect the behaviour of other activity LEDs
e.g. Bluetooth.
config ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY
bool "LED_on_when_activity"
help
Selecting LED_on_when_link will light the LED when there is a
connection and will flash off when there is activity.
Selecting LED_on_when_activity will light the LED only when
there is activity.
This setting will also affect the behaviour of other activity LEDs
e.g. Bluetooth.
endchoice
choice
prompt "Ser0 DMA out channel"
depends on ETRAX_SERIAL_PORT0
default ETRAX_SERIAL_PORT0_DMA6_OUT if ETRAX_ARCH_V32
default ETRAX_SERIAL_PORT0_NO_DMA_OUT if ETRAX_ARCH_V10
config ETRAX_SERIAL_PORT0_NO_DMA_OUT
bool "Ser0 uses no DMA for output"
help
Do not use DMA for ser0 output.
config ETRAX_SERIAL_PORT0_DMA6_OUT
bool "Ser0 uses DMA6 for output"
depends on ETRAXFS
help
Enables the DMA6 output channel for ser0 (ttyS0).
If you do not enable DMA, an interrupt for each character will be
used when transmitting data.
Normally you want to use DMA, unless you use the DMA channel for
something else.
config ETRAX_SERIAL_PORT0_DMA0_OUT
bool "Ser0 uses DMA0 for output"
depends on CRIS_MACH_ARTPEC3
help
Enables the DMA0 output channel for ser0 (ttyS0).
If you do not enable DMA, an interrupt for each character will be
used when transmitting data.
Normally you want to use DMA, unless you use the DMA channel for
something else.
endchoice
choice
prompt "Ser0 DMA in channel "
depends on ETRAX_SERIAL_PORT0
default ETRAX_SERIAL_PORT0_NO_DMA_IN if ETRAX_ARCH_V32
default ETRAX_SERIAL_PORT0_DMA7_IN if ETRAX_ARCH_V10
help
What DMA channel to use for ser0.
config ETRAX_SERIAL_PORT0_NO_DMA_IN
bool "Ser0 uses no DMA for input"
help
Do not use DMA for ser0 input.
config ETRAX_SERIAL_PORT0_DMA7_IN
bool "Ser0 uses DMA7 for input"
depends on ETRAXFS
help
Enables the DMA7 input channel for ser0 (ttyS0).
If you do not enable DMA, an interrupt for each character will be
used when receiving data.
Normally you want to use DMA, unless you use the DMA channel for
something else.
config ETRAX_SERIAL_PORT0_DMA1_IN
bool "Ser0 uses DMA1 for input"
depends on CRIS_MACH_ARTPEC3
help
Enables the DMA1 input channel for ser0 (ttyS0).
If you do not enable DMA, an interrupt for each character will be
used when receiving data.
Normally you want to use DMA, unless you use the DMA channel for
something else.
endchoice
choice
prompt "Ser1 DMA in channel "
depends on ETRAX_SERIAL_PORT1
default ETRAX_SERIAL_PORT1_NO_DMA_IN if ETRAX_ARCH_V32
default ETRAX_SERIAL_PORT1_DMA9_IN if ETRAX_ARCH_V10
help
What DMA channel to use for ser1.
config ETRAX_SERIAL_PORT1_NO_DMA_IN
bool "Ser1 uses no DMA for input"
help
Do not use DMA for ser1 input.
config ETRAX_SERIAL_PORT1_DMA5_IN
bool "Ser1 uses DMA5 for input"
depends on ETRAX_ARCH_V32
help
Enables the DMA5 input channel for ser1 (ttyS1).
If you do not enable DMA, an interrupt for each character will be
used when receiving data.
Normally you want this on, unless you use the DMA channel for
something else.
config ETRAX_SERIAL_PORT1_DMA9_IN
depends on ETRAX_ARCH_V10
bool "Ser1 uses DMA9 for input"
endchoice
choice
prompt "Ser1 DMA out channel"
depends on ETRAX_SERIAL_PORT1
default ETRAX_SERIAL_PORT1_NO_DMA_OUT if ETRAX_ARCH_V32
default ETRAX_SERIAL_PORT1_DMA8_OUT if ETRAX_ARCH_V10
help
What DMA channel to use for ser1.
config ETRAX_SERIAL_PORT1_NO_DMA_OUT
bool "Ser1 uses no DMA for output"
help
Do not use DMA for ser1 output.
config ETRAX_SERIAL_PORT1_DMA8_OUT
depends on ETRAX_ARCH_V10
bool "Ser1 uses DMA8 for output"
config ETRAX_SERIAL_PORT1_DMA4_OUT
depends on ETRAX_ARCH_V32
bool "Ser1 uses DMA4 for output"
help
Enables the DMA4 output channel for ser1 (ttyS1).
If you do not enable DMA, an interrupt for each character will be
used when transmitting data.
Normally you want this on, unless you use the DMA channel for
something else.
endchoice
choice
prompt "Ser2 DMA out channel"
depends on ETRAX_SERIAL_PORT2
default ETRAX_SERIAL_PORT2_NO_DMA_OUT if ETRAX_ARCH_V32
default ETRAX_SERIAL_PORT2_DMA2_OUT if ETRAX_ARCH_V10
config ETRAX_SERIAL_PORT2_NO_DMA_OUT
bool "Ser2 uses no DMA for output"
help
Do not use DMA for ser2 output.
config ETRAX_SERIAL_PORT2_DMA2_OUT
bool "Ser2 uses DMA2 for output"
depends on ETRAXFS || ETRAX_ARCH_V10
help
Enables the DMA2 output channel for ser2 (ttyS2).
If you do not enable DMA, an interrupt for each character will be
used when transmitting data.
Normally you want to use DMA, unless you use the DMA channel for
something else.
config ETRAX_SERIAL_PORT2_DMA6_OUT
bool "Ser2 uses DMA6 for output"
depends on CRIS_MACH_ARTPEC3
help
Enables the DMA6 output channel for ser2 (ttyS2).
If you do not enable DMA, an interrupt for each character will be
used when transmitting data.
Normally you want to use DMA, unless you use the DMA channel for
something else.
endchoice
choice
prompt "Ser2 DMA in channel"
depends on ETRAX_SERIAL_PORT2
default ETRAX_SERIAL_PORT2_NO_DMA_IN if ETRAX_ARCH_V32
default ETRAX_SERIAL_PORT2_DMA3_IN if ETRAX_ARCH_V10
help
What DMA channel to use for ser2.
config ETRAX_SERIAL_PORT2_NO_DMA_IN
bool "Ser2 uses no DMA for input"
help
Do not use DMA for ser2 input.
config ETRAX_SERIAL_PORT2_DMA3_IN
bool "Ser2 uses DMA3 for input"
depends on ETRAXFS || ETRAX_ARCH_V10
help
Enables the DMA3 input channel for ser2 (ttyS2).
If you do not enable DMA, an interrupt for each character will be
used when receiving data.
Normally you want to use DMA, unless you use the DMA channel for
something else.
config ETRAX_SERIAL_PORT2_DMA7_IN
bool "Ser2 uses DMA7 for input"
depends on CRIS_MACH_ARTPEC3
help
Enables the DMA7 input channel for ser2 (ttyS2).
If you do not enable DMA, an interrupt for each character will be
used when receiving data.
Normally you want to use DMA, unless you use the DMA channel for
something else.
endchoice
choice
prompt "Ser3 DMA in channel"
depends on ETRAX_SERIAL_PORT3
default ETRAX_SERIAL_PORT3_NO_DMA_IN if ETRAX_ARCH_V32
default ETRAX_SERIAL_PORT3_DMA5_IN if ETRAX_ARCH_V10
help
What DMA channel to use for ser3.
config ETRAX_SERIAL_PORT3_NO_DMA_IN
bool "Ser3 uses no DMA for input"
help
Do not use DMA for ser3 input.
config ETRAX_SERIAL_PORT3_DMA5_IN
depends on ETRAX_ARCH_V10
bool "DMA 5"
endchoice
choice
prompt "Ser3 DMA out channel"
depends on ETRAX_SERIAL_PORT3
default ETRAX_SERIAL_PORT3_NO_DMA_OUT if ETRAX_ARCH_V32
default ETRAX_SERIAL_PORT3_DMA4_OUT if ETRAX_ARCH_V10
config ETRAX_SERIAL_PORT3_NO_DMA_OUT
bool "Ser3 uses no DMA for output"
help
Do not use DMA for ser3 output.
config ETRAX_SERIAL_PORT3_DMA4_OUT
depends on ETRAX_ARCH_V10
bool "DMA 4"
endchoice
endmenu
source "drivers/Kconfig"
source "fs/Kconfig"
source "arch/cris/Kconfig.debug"
source "security/Kconfig"
source "crypto/Kconfig"
source "lib/Kconfig"
# SPDX-License-Identifier: GPL-2.0
menu "Kernel hacking"
config PROFILING
bool "Kernel profiling support"
config SYSTEM_PROFILER
bool "System profiling support"
source "lib/Kconfig.debug"
config ETRAX_KGDB
bool "Use kernel GDB debugger"
depends on DEBUG_KERNEL
---help---
The CRIS version of gdb can be used to remotely debug a running
Linux kernel via the serial debug port. Provided you have gdb-cris
installed, run gdb-cris vmlinux, then type
(gdb) set remotebaud 115200 <- kgdb uses 115200 as default
(gdb) target remote /dev/ttyS0 <- maybe you use another port
This should connect you to your booted kernel (or boot it now if you
didn't before). The kernel halts when it boots, waiting for gdb if
this option is turned on!
config DEBUG_NMI_OOPS
bool "NMI causes oops printout"
depends on DEBUG_KERNEL
help
If the system locks up without any debug information you can say Y
here to make it possible to dump an OOPS with an external NMI.
config NO_SEGFAULT_TERMINATION
bool "Keep segfaulting processes"
help
Place segfaulting user mode processes on a wait queue instead of
delivering a terminating SIGSEGV to allow debugging with gdb.
endmenu
#
# cris/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.
KBUILD_DEFCONFIG := etrax-100lx_v2_defconfig
arch-y := v10
arch-$(CONFIG_ETRAX_ARCH_V10) := v10
arch-$(CONFIG_ETRAX_ARCH_V32) := v32
# No config available for make clean etc
mach-y := fs
mach-$(CONFIG_CRIS_MACH_ARTPEC3) := a3
mach-$(CONFIG_ETRAXFS) := fs
ifneq ($(arch-y),)
SARCH := arch-$(arch-y)
inc := -Iarch/cris/include/uapi/$(SARCH)
inc += -Iarch/cris/include/$(SARCH)
inc += -Iarch/cris/include/uapi/$(SARCH)/arch
inc += -Iarch/cris/include/$(SARCH)/arch
else
SARCH :=
inc :=
endif
ifneq ($(mach-y),)
MACH := mach-$(mach-y)
inc += -Iarch/cris/include/$(SARCH)/$(MACH)/
inc += -Iarch/cris/include/$(SARCH)/$(MACH)/mach
else
MACH :=
endif
ifneq ($(CONFIG_BUILTIN_DTB),"")
core-$(CONFIG_OF) += arch/cris/boot/dts/
endif
LD = $(CROSS_COMPILE)ld -mcrislinux
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
KBUILD_AFLAGS += -mlinux -march=$(arch-y) $(inc)
KBUILD_CFLAGS += -mlinux -march=$(arch-y) -pipe $(inc)
KBUILD_CPPFLAGS += $(inc)
ifdef CONFIG_FRAME_POINTER
KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g
KBUILD_CFLAGS += -fno-omit-frame-pointer
endif
head-y := arch/cris/$(SARCH)/kernel/head.o
LIBGCC = $(shell $(CC) $(KBUILD_CFLAGS) -print-file-name=libgcc.a)
core-y += arch/cris/kernel/ arch/cris/mm/
core-y += arch/cris/$(SARCH)/kernel/ arch/cris/$(SARCH)/mm/
ifdef CONFIG_ETRAX_ARCH_V32
core-y += arch/cris/$(SARCH)/$(MACH)/
endif
drivers-y += arch/cris/$(SARCH)/drivers/
libs-y += arch/cris/$(SARCH)/lib/ $(LIBGCC)
# cris source path
SRC_ARCH = $(srctree)/arch/cris
# cris object files path
OBJ_ARCH = $(objtree)/arch/cris
boot := arch/cris/boot
MACHINE := arch/cris/$(SARCH)
all: zImage
zImage Image: vmlinux
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
archprepare:
archclean:
$(Q)if [ -e arch/cris/boot ]; then \
$(MAKE) $(clean)=arch/cris/boot; \
fi
CLEAN_FILES += \
$(boot)/zImage \
$(boot)/compressed/decompress.bin \
$(boot)/compressed/piggy.gz \
$(boot)/rescue/rescue.bin
# MRPROPER_FILES +=
define archhelp
echo '* zImage - Compressed kernel image (arch/cris/boot/zImage)'
echo '* Image - Uncompressed kernel image (arch/cris/boot/Image)'
endef
# SPDX-License-Identifier: GPL-2.0
if ETRAX_ARCH_V10
menu "CRIS v10 options"
# ETRAX 100LX v1 has a MMU "feature" requiring a low mapping
config CRIS_LOW_MAP
bool
depends on ETRAX_ARCH_V10 && ETRAX100LX
default y
config ETRAX_DRAM_VIRTUAL_BASE
hex
depends on ETRAX_ARCH_V10
default "c0000000" if !ETRAX100LX
default "60000000" if ETRAX100LX
choice
prompt "Product LED port"
depends on ETRAX_ARCH_V10
default ETRAX_PA_LEDS
config ETRAX_PA_LEDS
bool "Port-PA-LEDs"
help
The ETRAX network driver is responsible for flashing LED's when
packets arrive and are sent. It uses macros defined in
<file:arch/cris/include/asm/io.h>, and those macros are defined after
what YOU choose in this option. The actual bits used are configured
separately. Select this if the LEDs are on port PA. Some products
put the leds on PB or a memory-mapped latch (CSP0) instead.
config ETRAX_PB_LEDS
bool "Port-PB-LEDs"
help
The ETRAX network driver is responsible for flashing LED's when
packets arrive and are sent. It uses macros defined in
<file:arch/cris/include/asm/io.h>, and those macros are defined after
what YOU choose in this option. The actual bits used are configured
separately. Select this if the LEDs are on port PB. Some products
put the leds on PA or a memory-mapped latch (CSP0) instead.
config ETRAX_CSP0_LEDS
bool "Port-CSP0-LEDs"
help
The ETRAX network driver is responsible for flashing LED's when
packets arrive and are sent. It uses macros defined in
<file:arch/cris/include/asm/io.h>, and those macros are defined after
what YOU choose in this option. The actual bits used are configured
separately. Select this if the LEDs are on a memory-mapped latch
using chip select CSP0, this is mapped at 0x90000000.
Some products put the leds on PA or PB instead.
config ETRAX_NO_LEDS
bool "None"
help
Select this option if you don't have any LED at all.
endchoice
config ETRAX_LED1G
int "First green LED bit"
depends on ETRAX_ARCH_V10 && !ETRAX_NO_LEDS
default "2"
help
Bit to use for the first green LED.
Most Axis products use bit 2 here.
config ETRAX_LED1R
int "First red LED bit"
depends on ETRAX_ARCH_V10 && !ETRAX_NO_LEDS
default "3"
help
Bit to use for the first red LED.
Most Axis products use bit 3 here.
For products with only one controllable LED,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED2G
int "Second green LED bit"
depends on ETRAX_ARCH_V10 && !ETRAX_NO_LEDS
default "4"
help
Bit to use for the second green LED. The "Active" LED.
Most Axis products use bit 4 here.
For products with only one controllable LED,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED2R
int "Second red LED bit"
depends on ETRAX_ARCH_V10 && !ETRAX_NO_LEDS
default "5"
help
Bit to use for the second red LED.
Most Axis products use bit 5 here.
For products with only one controllable LED,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED3G
int "Third green LED bit"
depends on ETRAX_ARCH_V10 && !ETRAX_NO_LEDS
default "2"
help
Bit to use for the third green LED. The "Drive" LED.
For products with only one or two controllable LEDs,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED3R
int "Third red LED bit"
depends on ETRAX_ARCH_V10 && !ETRAX_NO_LEDS
default "2"
help
Bit to use for the third red LED.
For products with only one or two controllable LEDs,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED4R
int "Fourth red LED bit"
depends on ETRAX_CSP0_LEDS
default "2"
help
Bit to use for the fourth red LED.
For products with only one or two controllable LEDs,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED4G
int "Fourth green LED bit"
depends on ETRAX_CSP0_LEDS
default "2"
help
Bit to use for the fourth green LED.
For products with only one or two controllable LEDs,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED5R
int "Fifth red LED bit"
depends on ETRAX_CSP0_LEDS
default "2"
help
Bit to use for the fifth red LED.
For products with only one or two controllable LEDs,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED5G
int "Fifth green LED bit"
depends on ETRAX_CSP0_LEDS
default "2"
help
Bit to use for the fifth green LED.
For products with only one or two controllable LEDs,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED6R
int "Sixth red LED bit"
depends on ETRAX_CSP0_LEDS
default "2"
help
Bit to use for the sixth red LED.
For products with only one or two controllable LEDs,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED6G
int "Sixth green LED bit"
depends on ETRAX_CSP0_LEDS
default "2"
help
Bit to use for the sixth green LED. The "Drive" LED.
For products with only one or two controllable LEDs,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED7R
int "Seventh red LED bit"
depends on ETRAX_CSP0_LEDS
default "2"
help
Bit to use for the seventh red LED.
For products with only one or two controllable LEDs,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED7G
int "Seventh green LED bit"
depends on ETRAX_CSP0_LEDS
default "2"
help
Bit to use for the seventh green LED.
For products with only one or two controllable LEDs,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED8Y
int "Eighth yellow LED bit"
depends on ETRAX_CSP0_LEDS
default "2"
help
Bit to use for the eighth yellow LED. The "Drive" LED.
For products with only one or two controllable LEDs,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED9Y
int "Ninth yellow LED bit"
depends on ETRAX_CSP0_LEDS
default "2"
help
Bit to use for the ninth yellow LED.
For products with only one or two controllable LEDs,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED10Y
int "Tenth yellow LED bit"
depends on ETRAX_CSP0_LEDS
default "2"
help
Bit to use for the tenth yellow LED.
For products with only one or two controllable LEDs,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED11Y
int "Eleventh yellow LED bit"
depends on ETRAX_CSP0_LEDS
default "2"
help
Bit to use for the eleventh yellow LED.
For products with only one or two controllable LEDs,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED12R
int "Twelfth red LED bit"
depends on ETRAX_CSP0_LEDS
default "2"
help
Bit to use for the twelfth red LED.
For products with only one or two controllable LEDs,
set this to same as CONFIG_ETRAX_LED1G (normally 2).
choice
prompt "Product rescue-port"
depends on ETRAX_ARCH_V10
default ETRAX_RESCUE_SER0
config ETRAX_RESCUE_SER0
bool "Serial-0"
help
Select one of the four serial ports as a rescue port. The default
is port 0.
config ETRAX_RESCUE_SER1
bool "Serial-1"
help
Use serial port 1 as the rescue port.
config ETRAX_RESCUE_SER2
bool "Serial-2"
help
Use serial port 2 as the rescue port.
config ETRAX_RESCUE_SER3
bool "Serial-3"
help
Use serial port 3 as the rescue port.
endchoice
config ETRAX_DEF_R_WAITSTATES
hex "R_WAITSTATES"
depends on ETRAX_ARCH_V10
default "95a6"
help
Waitstates for SRAM, Flash and peripherals (not DRAM). 95f8 is a
good choice for most Axis products...
config ETRAX_DEF_R_BUS_CONFIG
hex "R_BUS_CONFIG"
depends on ETRAX_ARCH_V10
default "104"
help
Assorted bits controlling write mode, DMA burst length etc. 104 is
a good choice for most Axis products...
config ETRAX_SDRAM
bool "SDRAM support"
depends on ETRAX_ARCH_V10
help
Enable this if you use SDRAM chips and configure
R_SDRAM_CONFIG and R_SDRAM_TIMING as well.
config ETRAX_DEF_R_DRAM_CONFIG
hex "R_DRAM_CONFIG"
depends on ETRAX_ARCH_V10 && !ETRAX_SDRAM
default "1a200040"
help
The R_DRAM_CONFIG register specifies everything on how the DRAM
chips in the system are connected to the ETRAX CPU. This is
different depending on the manufacturer, chip type and number of
chips. So this value often needs to be different for each Axis
product.
config ETRAX_DEF_R_DRAM_TIMING
hex "R_DRAM_TIMING"
depends on ETRAX_ARCH_V10 && !ETRAX_SDRAM
default "5611"
help
Different DRAM chips have different speeds. Current Axis products
use 50ns DRAM chips which can use the timing: 5611.
config ETRAX_DEF_R_SDRAM_CONFIG
hex "R_SDRAM_CONFIG"
depends on ETRAX_ARCH_V10 && ETRAX_SDRAM
default "d2fa7878"
help
The R_SDRAM_CONFIG register specifies everything on how the SDRAM
chips in the system are connected to the ETRAX CPU. This is
different depending on the manufacturer, chip type and number of
chips. So this value often needs to be different for each Axis
product.
config ETRAX_DEF_R_SDRAM_TIMING
hex "R_SDRAM_TIMING"
depends on ETRAX_ARCH_V10 && ETRAX_SDRAM
default "80004801"
help
Different SDRAM chips have different timing.
config ETRAX_DEF_R_PORT_PA_DIR
hex "R_PORT_PA_DIR"
depends on ETRAX_ARCH_V10
default "1c"
help
Configures the direction of general port A bits. 1 is out, 0 is in.
This is often totally different depending on the product used.
There are some guidelines though - if you know that only LED's are
connected to port PA, then they are usually connected to bits 2-4
and you can therefore use 1c. On other boards which don't have the
LED's at the general ports, these bits are used for all kinds of
stuff. If you don't know what to use, it is always safe to put all
as inputs, although floating inputs isn't good.
config ETRAX_DEF_R_PORT_PA_DATA
hex "R_PORT_PA_DATA"
depends on ETRAX_ARCH_V10
default "00"
help
Configures the initial data for the general port A bits. Most
products should use 00 here.
config ETRAX_DEF_R_PORT_PB_CONFIG
hex "R_PORT_PB_CONFIG"
depends on ETRAX_ARCH_V10
default "00"
help
Configures the type of the general port B bits. 1 is chip select,
0 is port. Most products should use 00 here.
config ETRAX_DEF_R_PORT_PB_DIR
hex "R_PORT_PB_DIR"
depends on ETRAX_ARCH_V10
default "00"
help
Configures the direction of general port B bits. 1 is out, 0 is in.
This is often totally different depending on the product used. Bits
0 and 1 on port PB are usually used for I2C communication, but the
kernel I2C driver sets the appropriate directions itself so you
don't need to take that into consideration when setting this option.
If you don't know what to use, it is always safe to put all as
inputs.
config ETRAX_DEF_R_PORT_PB_DATA
hex "R_PORT_PB_DATA"
depends on ETRAX_ARCH_V10
default "ff"
help
Configures the initial data for the general port A bits. Most
products should use FF here.
config ETRAX_SOFT_SHUTDOWN
bool "Software Shutdown Support"
depends on ETRAX_ARCH_V10
help
Enable this if ETRAX is used with a power-supply that can be turned
off and on with PS_ON signal. Gives the possibility to detect
powerbutton and then do a power off after unmounting disks.
config ETRAX_SHUTDOWN_BIT
int "Shutdown bit on port CSP0"
depends on ETRAX_SOFT_SHUTDOWN
default "12"
help
Configure what pin on CSPO-port that is used for controlling power
supply.
config ETRAX_POWERBUTTON_BIT
int "Power button bit on port G"
depends on ETRAX_SOFT_SHUTDOWN
default "25"
help
Configure where power button is connected.
endmenu
endif
Memory management for CRIS/MMU
------------------------------
HISTORY:
$Log: README.mm,v $
Revision 1.1 2001/12/17 13:59:27 bjornw
Initial revision
Revision 1.1 2000/07/10 16:25:21 bjornw
Initial revision
Revision 1.4 2000/01/17 02:31:59 bjornw
Added discussion of paging and VM.
Revision 1.3 1999/12/03 16:43:23 hp
Blurb about that the 3.5G-limitation is not a MMU limitation
Revision 1.2 1999/12/03 16:04:21 hp
Picky comment about not mapping the first page
Revision 1.1 1999/12/03 15:41:30 bjornw
First version of CRIS/MMU memory layout specification.
------------------------------
See the ETRAX-NG HSDD for reference.
We use the page-size of 8 kbytes, as opposed to the i386 page-size of 4 kbytes.
The MMU can, apart from the normal mapping of pages, also do a top-level
segmentation of the kernel memory space. We use this feature to avoid having
to use page-tables to map the physical memory into the kernel's address
space. We also use it to keep the user-mode virtual mapping in the same
map during kernel-mode, so that the kernel easily can access the corresponding
user-mode process' data.
As a comparison, the Linux/i386 2.0 puts the kernel and physical RAM at
address 0, overlapping with the user-mode virtual space, so that descriptor
registers are needed for each memory access to specify which MMU space to
map through. That changed in 2.2, putting the kernel/physical RAM at
0xc0000000, to co-exist with the user-mode mapping. We will do something
quite similar, but with the additional complexity of having to map the
internal chip I/O registers and the flash memory area (including SRAM
and peripherial chip-selets).
The kernel-mode segmentation map:
------------------------ ------------------------
FFFFFFFF| | => cached | |
| kernel seg_f | flash | |
F0000000|______________________| | |
EFFFFFFF| | => uncached | |
| kernel seg_e | flash | |
E0000000|______________________| | DRAM |
DFFFFFFF| | paged to any | Un-cached |
| kernel seg_d | =======> | |
D0000000|______________________| | |
CFFFFFFF| | | |
| kernel seg_c |==\ | |
C0000000|______________________| \ |______________________|
BFFFFFFF| | uncached | |
| kernel seg_b |=====\=========>| Registers |
B0000000|______________________| \c |______________________|
AFFFFFFF| | \a | |
| | \c | FLASH/SRAM/Peripheral|
| | \h |______________________|
| | \e | |
| | \d | |
| kernel seg_0 - seg_a | \==>| DRAM |
| | | Cached |
| | paged to any | |
| | =======> |______________________|
| | | |
| | | Illegal |
| | |______________________|
| | | |
| | | FLASH/SRAM/Peripheral|
00000000|______________________| |______________________|
In user-mode it looks the same except that only the space 0-AFFFFFFF is
available. Therefore, in this model, the virtual address space per process
is limited to 0xb0000000 bytes (minus 8192 bytes, since the first page,
0..8191, is never mapped, in order to trap NULL references).
It also means that the total physical RAM that can be mapped is 256 MB
(kseg_c above). More RAM can be mapped by choosing a different segmentation
and shrinking the user-mode memory space.
The MMU can map all 4 GB in user mode, but doing that would mean that a
few extra instructions would be needed for each access to user mode
memory.
The kernel needs access to both cached and uncached flash. Uncached is
necessary because of the special write/erase sequences. Also, the
peripherial chip-selects are decoded from that region.
The kernel also needs its own virtual memory space. That is kseg_d. It
is used by the vmalloc() kernel function to allocate virtual contiguous
chunks of memory not possible using the normal kmalloc physical RAM
allocator.
The setting of the actual MMU control registers to use this layout would
be something like this:
R_MMU_KSEG = ( ( seg_f, seg ) | // Flash cached
( seg_e, seg ) | // Flash uncached
( seg_d, page ) | // kernel vmalloc area
( seg_c, seg ) | // kernel linear segment
( seg_b, seg ) | // kernel linear segment
( seg_a, page ) |
( seg_9, page ) |
( seg_8, page ) |
( seg_7, page ) |
( seg_6, page ) |
( seg_5, page ) |
( seg_4, page ) |
( seg_3, page ) |
( seg_2, page ) |
( seg_1, page ) |
( seg_0, page ) );
R_MMU_KBASE_HI = ( ( base_f, 0x0 ) | // flash/sram/periph cached
( base_e, 0x8 ) | // flash/sram/periph uncached
( base_d, 0x0 ) | // don't care
( base_c, 0x4 ) | // physical RAM cached area
( base_b, 0xb ) | // uncached on-chip registers
( base_a, 0x0 ) | // don't care
( base_9, 0x0 ) | // don't care
( base_8, 0x0 ) ); // don't care
R_MMU_KBASE_LO = ( ( base_7, 0x0 ) | // don't care
( base_6, 0x0 ) | // don't care
( base_5, 0x0 ) | // don't care
( base_4, 0x0 ) | // don't care
( base_3, 0x0 ) | // don't care
( base_2, 0x0 ) | // don't care
( base_1, 0x0 ) | // don't care
( base_0, 0x0 ) ); // don't care
NOTE: while setting up the MMU, we run in a non-mapped mode in the DRAM (0x40
segment) and need to setup the seg_4 to a unity mapping, so that we don't get
a fault before we have had time to jump into the real kernel segment (0xc0). This
is done in head.S temporarily, but fixed by the kernel later in paging_init.
Paging - PTE's, PMD's and PGD's
-------------------------------
[ References: asm/pgtable.h, asm/page.h, asm/mmu.h ]
The paging mechanism uses virtual addresses to split a process memory-space into
pages, a page being the smallest unit that can be freely remapped in memory. On
Linux/CRIS, a page is 8192 bytes (for technical reasons not equal to 4096 as in
most other 32-bit architectures). It would be inefficient to let a virtual memory
mapping be controlled by a long table of page mappings, so it is broken down into
a 2-level structure with a Page Directory containing pointers to Page Tables which
each have maps of up to 2048 pages (8192 / sizeof(void *)). Linux can actually
handle 3-level structures as well, with a Page Middle Directory in between, but
in many cases, this is folded into a two-level structure by excluding the Middle
Directory.
We'll take a look at how an address is translated while we discuss how it's handled
in the Linux kernel.
The example address is 0xd004000c; in binary this is:
31 23 15 7 0
11010000 00000100 00000000 00001100
|______| |__________||____________|
PGD PTE page offset
Given the top-level Page Directory, the offset in that directory is calculated
using the upper 8 bits:
static inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
{
return mm->pgd + (address >> PGDIR_SHIFT);
}
PGDIR_SHIFT is the log2 of the amount of memory an entry in the PGD can map; in our
case it is 24, corresponding to 16 MB. This means that each entry in the PGD
corresponds to 16 MB of virtual memory.
The pgd_t from our example will therefore be the 208'th (0xd0) entry in mm->pgd.
Since the Middle Directory does not exist, it is a unity mapping:
static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
{
return (pmd_t *) dir;
}
The Page Table provides the final lookup by using bits 13 to 23 as index:
static inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
{
return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) &
(PTRS_PER_PTE - 1));
}
PAGE_SHIFT is the log2 of the size of a page; 13 in our case. PTRS_PER_PTE is
the number of pointers that fit in a Page Table and is used to mask off the
PGD-part of the address.
The so-far unused bits 0 to 12 are used to index inside a page linearily.
The VM system
-------------
The kernels own page-directory is the swapper_pg_dir, cleared in paging_init,
and contains the kernels virtual mappings (the kernel itself is not paged - it
is mapped linearily using kseg_c as described above). Architectures without
kernel segments like the i386, need to setup swapper_pg_dir directly in head.S
to map the kernel itself. swapper_pg_dir is pointed to by init_mm.pgd as the
init-task's PGD.
To see what support functions are used to setup a page-table, let's look at the
kernel's internal paged memory system, vmalloc/vfree.
void * vmalloc(unsigned long size)
The vmalloc-system keeps a paged segment in kernel-space at 0xd0000000. What
happens first is that a virtual address chunk is allocated to the request using
get_vm_area(size). After that, physical RAM pages are allocated and put into
the kernel's page-table using alloc_area_pages(addr, size).
static int alloc_area_pages(unsigned long address, unsigned long size)
First the PGD entry is found using init_mm.pgd. This is passed to
alloc_area_pmd (remember the 3->2 folding). It uses pte_alloc_kernel to
check if the PGD entry points anywhere - if not, a page table page is
allocated and the PGD entry updated. Then the alloc_area_pte function is
used just like alloc_area_pmd to check which page table entry is desired,
and a physical page is allocated and the table entry updated. All of this
is repeated at the top-level until the entire address range specified has
been mapped.
此差异已折叠。
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for Etrax-specific drivers
#
obj-$(CONFIG_ETRAX_AXISFLASHMAP) += axisflashmap.o
obj-$(CONFIG_ETRAX_I2C) += i2c.o
obj-$(CONFIG_ETRAX_I2C_EEPROM) += eeprom.o
obj-$(CONFIG_ETRAX_GPIO) += gpio.o
obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o
/*
* Physical mapping layer for MTD using the Axis partitiontable format
*
* Copyright (c) 2001, 2002 Axis Communications AB
*
* This file is under the GPL.
*
* First partition is always sector 0 regardless of if we find a partitiontable
* or not. In the start of the next sector, there can be a partitiontable that
* tells us what other partitions to define. If there isn't, we use a default
* partition split defined below.
*
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/mtd/concat.h>
#include <linux/mtd/map.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/mtdram.h>
#include <linux/mtd/partitions.h>
#include <asm/axisflashmap.h>
#include <asm/mmu.h>
#include <arch/sv_addr_ag.h>
#ifdef CONFIG_CRIS_LOW_MAP
#define FLASH_UNCACHED_ADDR KSEG_8
#define FLASH_CACHED_ADDR KSEG_5
#else
#define FLASH_UNCACHED_ADDR KSEG_E
#define FLASH_CACHED_ADDR KSEG_F
#endif
#if CONFIG_ETRAX_FLASH_BUSWIDTH==1
#define flash_data __u8
#elif CONFIG_ETRAX_FLASH_BUSWIDTH==2
#define flash_data __u16
#elif CONFIG_ETRAX_FLASH_BUSWIDTH==4
#define flash_data __u32
#endif
/* From head.S */
extern unsigned long romfs_start, romfs_length, romfs_in_flash;
/* The master mtd for the entire flash. */
struct mtd_info* axisflash_mtd = NULL;
/* Map driver functions. */
static map_word flash_read(struct map_info *map, unsigned long ofs)
{
map_word tmp;
tmp.x[0] = *(flash_data *)(map->map_priv_1 + ofs);
return tmp;
}
static void flash_copy_from(struct map_info *map, void *to,
unsigned long from, ssize_t len)
{
memcpy(to, (void *)(map->map_priv_1 + from), len);
}
static void flash_write(struct map_info *map, map_word d, unsigned long adr)
{
*(flash_data *)(map->map_priv_1 + adr) = (flash_data)d.x[0];
}
/*
* The map for chip select e0.
*
* We run into tricky coherence situations if we mix cached with uncached
* accesses to we only use the uncached version here.
*
* The size field is the total size where the flash chips may be mapped on the
* chip select. MTD probes should find all devices there and it does not matter
* if there are unmapped gaps or aliases (mirrors of flash devices). The MTD
* probes will ignore them.
*
* The start address in map_priv_1 is in virtual memory so we cannot use
* MEM_CSE0_START but must rely on that FLASH_UNCACHED_ADDR is the start
* address of cse0.
*/
static struct map_info map_cse0 = {
.name = "cse0",
.size = MEM_CSE0_SIZE,
.bankwidth = CONFIG_ETRAX_FLASH_BUSWIDTH,
.read = flash_read,
.copy_from = flash_copy_from,
.write = flash_write,
.map_priv_1 = FLASH_UNCACHED_ADDR
};
/*
* The map for chip select e1.
*
* If there was a gap between cse0 and cse1, map_priv_1 would get the wrong
* address, but there isn't.
*/
static struct map_info map_cse1 = {
.name = "cse1",
.size = MEM_CSE1_SIZE,
.bankwidth = CONFIG_ETRAX_FLASH_BUSWIDTH,
.read = flash_read,
.copy_from = flash_copy_from,
.write = flash_write,
.map_priv_1 = FLASH_UNCACHED_ADDR + MEM_CSE0_SIZE
};
/* If no partition-table was found, we use this default-set. */
#define MAX_PARTITIONS 7
#define NUM_DEFAULT_PARTITIONS 3
/*
* Default flash size is 2MB. CONFIG_ETRAX_PTABLE_SECTOR is most likely the
* size of one flash block and "filesystem"-partition needs 5 blocks to be able
* to use JFFS.
*/
static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
{
.name = "boot firmware",
.size = CONFIG_ETRAX_PTABLE_SECTOR,
.offset = 0
},
{
.name = "kernel",
.size = 0x200000 - (6 * CONFIG_ETRAX_PTABLE_SECTOR),
.offset = CONFIG_ETRAX_PTABLE_SECTOR
},
{
.name = "filesystem",
.size = 5 * CONFIG_ETRAX_PTABLE_SECTOR,
.offset = 0x200000 - (5 * CONFIG_ETRAX_PTABLE_SECTOR)
}
};
/* Initialize the ones normally used. */
static struct mtd_partition axis_partitions[MAX_PARTITIONS] = {
{
.name = "part0",
.size = CONFIG_ETRAX_PTABLE_SECTOR,
.offset = 0
},
{
.name = "part1",
.size = 0,
.offset = 0
},
{
.name = "part2",
.size = 0,
.offset = 0
},
{
.name = "part3",
.size = 0,
.offset = 0
},
{
.name = "part4",
.size = 0,
.offset = 0
},
{
.name = "part5",
.size = 0,
.offset = 0
},
{
.name = "part6",
.size = 0,
.offset = 0
},
};
/*
* Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash
* chips in that order (because the amd_flash-driver is faster).
*/
static struct mtd_info *probe_cs(struct map_info *map_cs)
{
struct mtd_info *mtd_cs = NULL;
printk(KERN_INFO
"%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n",
map_cs->name, map_cs->size, map_cs->map_priv_1);
#ifdef CONFIG_MTD_CFI
mtd_cs = do_map_probe("cfi_probe", map_cs);
#endif
#ifdef CONFIG_MTD_JEDECPROBE
if (!mtd_cs)
mtd_cs = do_map_probe("jedec_probe", map_cs);
#endif
return mtd_cs;
}
/*
* Probe each chip select individually for flash chips. If there are chips on
* both cse0 and cse1, the mtd_info structs will be concatenated to one struct
* so that MTD partitions can cross chip boundaries.
*
* The only known restriction to how you can mount your chips is that each
* chip select must hold similar flash chips. But you need external hardware
* to do that anyway and you can put totally different chips on cse0 and cse1
* so it isn't really much of a restriction.
*/
static struct mtd_info *flash_probe(void)
{
struct mtd_info *mtd_cse0;
struct mtd_info *mtd_cse1;
struct mtd_info *mtd_cse;
mtd_cse0 = probe_cs(&map_cse0);
mtd_cse1 = probe_cs(&map_cse1);
if (!mtd_cse0 && !mtd_cse1) {
/* No chip found. */
return NULL;
}
if (mtd_cse0 && mtd_cse1) {
struct mtd_info *mtds[] = { mtd_cse0, mtd_cse1 };
/* Since the concatenation layer adds a small overhead we
* could try to figure out if the chips in cse0 and cse1 are
* identical and reprobe the whole cse0+cse1 window. But since
* flash chips are slow, the overhead is relatively small.
* So we use the MTD concatenation layer instead of further
* complicating the probing procedure.
*/
mtd_cse = mtd_concat_create(mtds, ARRAY_SIZE(mtds),
"cse0+cse1");
if (!mtd_cse) {
printk(KERN_ERR "%s and %s: Concatenation failed!\n",
map_cse0.name, map_cse1.name);
/* The best we can do now is to only use what we found
* at cse0.
*/
mtd_cse = mtd_cse0;
map_destroy(mtd_cse1);
}
} else {
mtd_cse = mtd_cse0? mtd_cse0 : mtd_cse1;
}
return mtd_cse;
}
/*
* Probe the flash chip(s) and, if it succeeds, read the partition-table
* and register the partitions with MTD.
*/
static int __init init_axis_flash(void)
{
struct mtd_info *mymtd;
int err = 0;
int pidx = 0;
struct partitiontable_head *ptable_head = NULL;
struct partitiontable_entry *ptable;
int use_default_ptable = 1; /* Until proven otherwise. */
const char pmsg[] = " /dev/flash%d at 0x%08x, size 0x%08x\n";
if (!(mymtd = flash_probe())) {
/* There's no reason to use this module if no flash chip can
* be identified. Make sure that's understood.
*/
printk(KERN_INFO "axisflashmap: Found no flash chip.\n");
} else {
printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n",
mymtd->name, mymtd->size);
axisflash_mtd = mymtd;
}
if (mymtd) {
mymtd->owner = THIS_MODULE;
ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR +
CONFIG_ETRAX_PTABLE_SECTOR +
PARTITION_TABLE_OFFSET);
}
pidx++; /* First partition is always set to the default. */
if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC)
&& (ptable_head->size <
(MAX_PARTITIONS * sizeof(struct partitiontable_entry) +
PARTITIONTABLE_END_MARKER_SIZE))
&& (*(unsigned long*)((void*)ptable_head + sizeof(*ptable_head) +
ptable_head->size -
PARTITIONTABLE_END_MARKER_SIZE)
== PARTITIONTABLE_END_MARKER)) {
/* Looks like a start, sane length and end of a
* partition table, lets check csum etc.
*/
int ptable_ok = 0;
struct partitiontable_entry *max_addr =
(struct partitiontable_entry *)
((unsigned long)ptable_head + sizeof(*ptable_head) +
ptable_head->size);
unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR;
unsigned char *p;
unsigned long csum = 0;
ptable = (struct partitiontable_entry *)
((unsigned long)ptable_head + sizeof(*ptable_head));
/* Lets be PARANOID, and check the checksum. */
p = (unsigned char*) ptable;
while (p <= (unsigned char*)max_addr) {
csum += *p++;
csum += *p++;
csum += *p++;
csum += *p++;
}
ptable_ok = (csum == ptable_head->checksum);
/* Read the entries and use/show the info. */
printk(KERN_INFO " Found a%s partition table at 0x%p-0x%p.\n",
(ptable_ok ? " valid" : "n invalid"), ptable_head,
max_addr);
/* We have found a working bootblock. Now read the
* partition table. Scan the table. It ends when
* there is 0xffffffff, that is, empty flash.
*/
while (ptable_ok
&& ptable->offset != 0xffffffff
&& ptable < max_addr
&& pidx < MAX_PARTITIONS) {
axis_partitions[pidx].offset = offset + ptable->offset;
axis_partitions[pidx].size = ptable->size;
printk(pmsg, pidx, axis_partitions[pidx].offset,
axis_partitions[pidx].size);
pidx++;
ptable++;
}
use_default_ptable = !ptable_ok;
}
if (romfs_in_flash) {
/* Add an overlapping device for the root partition (romfs). */
axis_partitions[pidx].name = "romfs";
axis_partitions[pidx].size = romfs_length;
axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR;
axis_partitions[pidx].mask_flags |= MTD_WRITEABLE;
printk(KERN_INFO
" Adding readonly flash partition for romfs image:\n");
printk(pmsg, pidx, axis_partitions[pidx].offset,
axis_partitions[pidx].size);
pidx++;
}
if (mymtd) {
if (use_default_ptable) {
printk(KERN_INFO " Using default partition table.\n");
err = mtd_device_register(mymtd,
axis_default_partitions,
NUM_DEFAULT_PARTITIONS);
} else {
err = mtd_device_register(mymtd, axis_partitions,
pidx);
}
if (err)
panic("axisflashmap could not add MTD partitions!\n");
}
if (!romfs_in_flash) {
/* Create an RAM device for the root partition (romfs). */
#if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0)
/* No use trying to boot this kernel from RAM. Panic! */
printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM "
"device due to kernel (mis)configuration!\n");
panic("This kernel cannot boot from RAM!\n");
#else
struct mtd_info *mtd_ram;
mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
if (!mtd_ram)
panic("axisflashmap couldn't allocate memory for "
"mtd_info!\n");
printk(KERN_INFO " Adding RAM partition for romfs image:\n");
printk(pmsg, pidx, (unsigned)romfs_start,
(unsigned)romfs_length);
err = mtdram_init_device(mtd_ram,
(void *)romfs_start,
romfs_length,
"romfs");
if (err)
panic("axisflashmap could not initialize MTD RAM "
"device!\n");
#endif
}
return err;
}
/* This adds the above to the kernels init-call chain. */
module_init(init_axis_flash);
EXPORT_SYMBOL(axisflash_mtd);
此差异已折叠。
此差异已折叠。
此差异已折叠。
/* SPDX-License-Identifier: GPL-2.0 */
/* i2c.h */
int i2c_init(void);
/* High level I2C actions */
int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue);
unsigned char i2c_readreg(unsigned char theSlave, unsigned char theReg);
/* Low level I2C */
void i2c_start(void);
void i2c_stop(void);
void i2c_outbyte(unsigned char x);
unsigned char i2c_inbyte(void);
int i2c_getack(void);
void i2c_sendack(void);
此差异已折叠。
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the linux kernel.
#
extra-y := head.o
obj-y := entry.o traps.o shadows.o debugport.o irq.o \
process.o setup.o signal.o traps.o time.o ptrace.o \
dma.o io_interface_mux.o
obj-$(CONFIG_ETRAX_KGDB) += kgdb.o
obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o
obj-$(CONFIG_MODULES) += crisksyms.o
clean:
// SPDX-License-Identifier: GPL-2.0
#include <linux/module.h>
#include <asm/io.h>
#include <arch/svinto.h>
/* Export shadow registers for the CPU I/O pins */
EXPORT_SYMBOL(genconfig_shadow);
EXPORT_SYMBOL(port_pa_data_shadow);
EXPORT_SYMBOL(port_pa_dir_shadow);
EXPORT_SYMBOL(port_pb_data_shadow);
EXPORT_SYMBOL(port_pb_dir_shadow);
EXPORT_SYMBOL(port_pb_config_shadow);
EXPORT_SYMBOL(port_g_data_shadow);
/* Cache flush functions */
EXPORT_SYMBOL(flush_etrax_cache);
EXPORT_SYMBOL(prepare_rx_descriptor);
// SPDX-License-Identifier: GPL-2.0
/* Serialport functions for debugging
*
* Copyright (c) 2000-2007 Axis Communications AB
*
* Authors: Bjorn Wesen
*
* Exports:
* console_print_etrax(char *buf)
* int getDebugChar()
* putDebugChar(int)
* enableDebugIRQ()
* init_etrax_debug()
*
*/
#include <linux/console.h>
#include <linux/init.h>
#include <linux/major.h>
#include <linux/delay.h>
#include <linux/tty.h>
#include <arch/svinto.h>
extern void reset_watchdog(void);
struct dbg_port
{
unsigned int index;
const volatile unsigned* read;
volatile char* write;
volatile unsigned* xoff;
volatile char* baud;
volatile char* tr_ctrl;
volatile char* rec_ctrl;
unsigned long irq;
unsigned int started;
unsigned long baudrate;
unsigned char parity;
unsigned int bits;
};
struct dbg_port ports[]=
{
{
0,
R_SERIAL0_READ,
R_SERIAL0_TR_DATA,
R_SERIAL0_XOFF,
R_SERIAL0_BAUD,
R_SERIAL0_TR_CTRL,
R_SERIAL0_REC_CTRL,
IO_STATE(R_IRQ_MASK1_SET, ser0_data, set),
0,
115200,
'N',
8
},
{
1,
R_SERIAL1_READ,
R_SERIAL1_TR_DATA,
R_SERIAL1_XOFF,
R_SERIAL1_BAUD,
R_SERIAL1_TR_CTRL,
R_SERIAL1_REC_CTRL,
IO_STATE(R_IRQ_MASK1_SET, ser1_data, set),
0,
115200,
'N',
8
},
{
2,
R_SERIAL2_READ,
R_SERIAL2_TR_DATA,
R_SERIAL2_XOFF,
R_SERIAL2_BAUD,
R_SERIAL2_TR_CTRL,
R_SERIAL2_REC_CTRL,
IO_STATE(R_IRQ_MASK1_SET, ser2_data, set),
0,
115200,
'N',
8
},
{
3,
R_SERIAL3_READ,
R_SERIAL3_TR_DATA,
R_SERIAL3_XOFF,
R_SERIAL3_BAUD,
R_SERIAL3_TR_CTRL,
R_SERIAL3_REC_CTRL,
IO_STATE(R_IRQ_MASK1_SET, ser3_data, set),
0,
115200,
'N',
8
}
};
#ifdef CONFIG_ETRAX_SERIAL
extern struct tty_driver *serial_driver;
#endif
struct dbg_port* port =
#if defined(CONFIG_ETRAX_DEBUG_PORT0)
&ports[0];
#elif defined(CONFIG_ETRAX_DEBUG_PORT1)
&ports[1];
#elif defined(CONFIG_ETRAX_DEBUG_PORT2)
&ports[2];
#elif defined(CONFIG_ETRAX_DEBUG_PORT3)
&ports[3];
#else
NULL;
#endif
static struct dbg_port* kgdb_port =
#if defined(CONFIG_ETRAX_KGDB_PORT0)
&ports[0];
#elif defined(CONFIG_ETRAX_KGDB_PORT1)
&ports[1];
#elif defined(CONFIG_ETRAX_KGDB_PORT2)
&ports[2];
#elif defined(CONFIG_ETRAX_KGDB_PORT3)
&ports[3];
#else
NULL;
#endif
static void
start_port(struct dbg_port* p)
{
unsigned long rec_ctrl = 0;
unsigned long tr_ctrl = 0;
if (!p)
return;
if (p->started)
return;
p->started = 1;
if (p->index == 0)
{
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6);
genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused);
}
else if (p->index == 1)
{
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8);
genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb);
}
else if (p->index == 2)
{
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2);
genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0);
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma3);
genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma3, par0);
genconfig_shadow |= IO_STATE(R_GEN_CONFIG, ser2, select);
}
else
{
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma4);
genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, par1);
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma5);
genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma5, par1);
genconfig_shadow |= IO_STATE(R_GEN_CONFIG, ser3, select);
}
*R_GEN_CONFIG = genconfig_shadow;
*p->xoff =
IO_STATE(R_SERIAL0_XOFF, tx_stop, enable) |
IO_STATE(R_SERIAL0_XOFF, auto_xoff, disable) |
IO_FIELD(R_SERIAL0_XOFF, xoff_char, 0);
switch (p->baudrate)
{
case 0:
case 115200:
*p->baud =
IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) |
IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz);
break;
case 1200:
*p->baud =
IO_STATE(R_SERIAL0_BAUD, tr_baud, c1200Hz) |
IO_STATE(R_SERIAL0_BAUD, rec_baud, c1200Hz);
break;
case 2400:
*p->baud =
IO_STATE(R_SERIAL0_BAUD, tr_baud, c2400Hz) |
IO_STATE(R_SERIAL0_BAUD, rec_baud, c2400Hz);
break;
case 4800:
*p->baud =
IO_STATE(R_SERIAL0_BAUD, tr_baud, c4800Hz) |
IO_STATE(R_SERIAL0_BAUD, rec_baud, c4800Hz);
break;
case 9600:
*p->baud =
IO_STATE(R_SERIAL0_BAUD, tr_baud, c9600Hz) |
IO_STATE(R_SERIAL0_BAUD, rec_baud, c9600Hz);
break;
case 19200:
*p->baud =
IO_STATE(R_SERIAL0_BAUD, tr_baud, c19k2Hz) |
IO_STATE(R_SERIAL0_BAUD, rec_baud, c19k2Hz);
break;
case 38400:
*p->baud =
IO_STATE(R_SERIAL0_BAUD, tr_baud, c38k4Hz) |
IO_STATE(R_SERIAL0_BAUD, rec_baud, c38k4Hz);
break;
case 57600:
*p->baud =
IO_STATE(R_SERIAL0_BAUD, tr_baud, c57k6Hz) |
IO_STATE(R_SERIAL0_BAUD, rec_baud, c57k6Hz);
break;
default:
*p->baud =
IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) |
IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz);
break;
}
if (p->parity == 'E') {
rec_ctrl =
IO_STATE(R_SERIAL0_REC_CTRL, rec_par, even) |
IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable);
tr_ctrl =
IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) |
IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, enable);
} else if (p->parity == 'O') {
rec_ctrl =
IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd) |
IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable);
tr_ctrl =
IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd) |
IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, enable);
} else {
rec_ctrl =
IO_STATE(R_SERIAL0_REC_CTRL, rec_par, even) |
IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, disable);
tr_ctrl =
IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) |
IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, disable);
}
if (p->bits == 7)
{
rec_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_bitnr, rec_7bit);
tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_7bit);
}
else
{
rec_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_bitnr, rec_8bit);
tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_8bit);
}
*p->rec_ctrl =
IO_STATE(R_SERIAL0_REC_CTRL, dma_err, stop) |
IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable) |
IO_STATE(R_SERIAL0_REC_CTRL, rts_, active) |
IO_STATE(R_SERIAL0_REC_CTRL, sampling, middle) |
IO_STATE(R_SERIAL0_REC_CTRL, rec_stick_par, normal) |
rec_ctrl;
*p->tr_ctrl =
IO_FIELD(R_SERIAL0_TR_CTRL, txd, 0) |
IO_STATE(R_SERIAL0_TR_CTRL, tr_enable, enable) |
IO_STATE(R_SERIAL0_TR_CTRL, auto_cts, disabled) |
IO_STATE(R_SERIAL0_TR_CTRL, stop_bits, one_bit) |
IO_STATE(R_SERIAL0_TR_CTRL, tr_stick_par, normal) |
tr_ctrl;
}
static void
console_write_direct(struct console *co, const char *buf, unsigned int len)
{
int i;
unsigned long flags;
if (!port)
return;
local_irq_save(flags);
/* Send data */
for (i = 0; i < len; i++) {
/* LF -> CRLF */
if (buf[i] == '\n') {
while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready)))
;
*port->write = '\r';
}
/* Wait until transmitter is ready and send.*/
while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready)))
;
*port->write = buf[i];
}
/*
* Feed the watchdog, otherwise it will reset the chip during boot.
* The time to send an ordinary boot message line (10-90 chars)
* varies between 1-8ms at 115200. What makes up for the additional
* 90ms that allows the watchdog to bite?
*/
reset_watchdog();
local_irq_restore(flags);
}
static void
console_write(struct console *co, const char *buf, unsigned int len)
{
if (!port)
return;
console_write_direct(co, buf, len);
}
/* legacy function */
void
console_print_etrax(const char *buf)
{
console_write(NULL, buf, strlen(buf));
}
/* Use polling to get a single character FROM the debug port */
int
getDebugChar(void)
{
unsigned long readval;
if (!kgdb_port)
return 0;
do {
readval = *kgdb_port->read;
} while (!(readval & IO_MASK(R_SERIAL0_READ, data_avail)));
return (readval & IO_MASK(R_SERIAL0_READ, data_in));
}
/* Use polling to put a single character to the debug port */
void
putDebugChar(int val)
{
if (!kgdb_port)
return;
while (!(*kgdb_port->read & IO_MASK(R_SERIAL0_READ, tr_ready)))
;
*kgdb_port->write = val;
}
/* Enable irq for receiving chars on the debug port, used by kgdb */
void
enableDebugIRQ(void)
{
if (!kgdb_port)
return;
*R_IRQ_MASK1_SET = kgdb_port->irq;
/* use R_VECT_MASK directly, since we really bypass Linux normal
* IRQ handling in kgdb anyway, we don't need to use enable_irq
*/
*R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set);
*kgdb_port->rec_ctrl = IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable);
}
static int __init
console_setup(struct console *co, char *options)
{
char* s;
if (options) {
port = &ports[co->index];
port->baudrate = 115200;
port->parity = 'N';
port->bits = 8;
port->baudrate = simple_strtoul(options, NULL, 10);
s = options;
while(*s >= '0' && *s <= '9')
s++;
if (*s) port->parity = *s++;
if (*s) port->bits = *s++ - '0';
port->started = 0;
start_port(0);
}
return 0;
}
/* This is a dummy serial device that throws away anything written to it.
* This is used when no debug output is wanted.
*/
static struct tty_driver dummy_driver;
static int dummy_open(struct tty_struct *tty, struct file * filp)
{
return 0;
}
static void dummy_close(struct tty_struct *tty, struct file * filp)
{
}
static int dummy_write(struct tty_struct * tty,
const unsigned char *buf, int count)
{
return count;
}
static int dummy_write_room(struct tty_struct *tty)
{
return 8192;
}
static const struct tty_operations dummy_ops = {
.open = dummy_open,
.close = dummy_close,
.write = dummy_write,
.write_room = dummy_write_room,
};
void __init
init_dummy_console(void)
{
memset(&dummy_driver, 0, sizeof(struct tty_driver));
dummy_driver.driver_name = "serial";
dummy_driver.name = "ttyS";
dummy_driver.major = TTY_MAJOR;
dummy_driver.minor_start = 68;
dummy_driver.num = 1; /* etrax100 has 4 serial ports */
dummy_driver.type = TTY_DRIVER_TYPE_SERIAL;
dummy_driver.subtype = SERIAL_TYPE_NORMAL;
dummy_driver.init_termios = tty_std_termios;
/* Normally B9600 default... */
dummy_driver.init_termios.c_cflag =
B115200 | CS8 | CREAD | HUPCL | CLOCAL;
dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
dummy_driver.init_termios.c_ispeed = 115200;
dummy_driver.init_termios.c_ospeed = 115200;
dummy_driver.ops = &dummy_ops;
if (tty_register_driver(&dummy_driver))
panic("Couldn't register dummy serial driver\n");
}
static struct tty_driver*
etrax_console_device(struct console* co, int *index)
{
if (port)
*index = port->index;
else
*index = 0;
#ifdef CONFIG_ETRAX_SERIAL
return port ? serial_driver : &dummy_driver;
#else
return &dummy_driver;
#endif
}
static struct console ser_console = {
name : "ttyS",
write: console_write,
read : NULL,
device : etrax_console_device,
unblank : NULL,
setup : console_setup,
flags : CON_PRINTBUFFER,
index : -1,
cflag : 0,
next : NULL
};
static struct console ser0_console = {
name : "ttyS",
write: console_write,
read : NULL,
device : etrax_console_device,
unblank : NULL,
setup : console_setup,
flags : CON_PRINTBUFFER,
index : 0,
cflag : 0,
next : NULL
};
static struct console ser1_console = {
name : "ttyS",
write: console_write,
read : NULL,
device : etrax_console_device,
unblank : NULL,
setup : console_setup,
flags : CON_PRINTBUFFER,
index : 1,
cflag : 0,
next : NULL
};
static struct console ser2_console = {
name : "ttyS",
write: console_write,
read : NULL,
device : etrax_console_device,
unblank : NULL,
setup : console_setup,
flags : CON_PRINTBUFFER,
index : 2,
cflag : 0,
next : NULL
};
static struct console ser3_console = {
name : "ttyS",
write: console_write,
read : NULL,
device : etrax_console_device,
unblank : NULL,
setup : console_setup,
flags : CON_PRINTBUFFER,
index : 3,
cflag : 0,
next : NULL
};
/*
* Register console (for printk's etc)
*/
int __init
init_etrax_debug(void)
{
static int first = 1;
if (!first) {
unregister_console(&ser_console);
register_console(&ser0_console);
register_console(&ser1_console);
register_console(&ser2_console);
register_console(&ser3_console);
init_dummy_console();
return 0;
}
first = 0;
register_console(&ser_console);
start_port(port);
#ifdef CONFIG_ETRAX_KGDB
start_port(kgdb_port);
#endif
return 0;
}
__initcall(init_etrax_debug);
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
// SPDX-License-Identifier: GPL-2.0
/*
* Various shadow registers. Defines for these are in include/asm-etrax100/io.h
*/
/* Shadows for internal Etrax-registers */
unsigned long genconfig_shadow;
unsigned long gen_config_ii_shadow;
unsigned long port_g_data_shadow;
unsigned char port_pa_dir_shadow;
unsigned char port_pa_data_shadow;
unsigned char port_pb_i2c_shadow;
unsigned char port_pb_config_shadow;
unsigned char port_pb_dir_shadow;
unsigned char port_pb_data_shadow;
unsigned long r_timer_ctrl_shadow;
/* Shadows for external I/O port registers.
* These are only usable if there actually IS a latch connected
* to the corresponding external chip-select pin.
*
* A common usage is that CSP0 controls LEDs and CSP4 video chips.
*/
unsigned long port_cse1_shadow;
unsigned long port_csp0_shadow;
unsigned long port_csp4_shadow;
/* Corresponding addresses for the ports.
* These are initialized in arch/cris/mm/init.c using ioremap.
*/
volatile unsigned long *port_cse1_addr;
volatile unsigned long *port_csp0_addr;
volatile unsigned long *port_csp4_addr;
此差异已折叠。
此差异已折叠。
此差异已折叠。
#
# Makefile for Etrax-specific library files..
#
lib-y = checksum.o checksumcopy.o string.o usercopy.o memset.o csumcpfruser.o
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
#
# Makefile for the linux cris-specific parts of the memory manager.
#
obj-y := fault.o init.o tlb.o
此差异已折叠。
此差异已折叠。
此差异已折叠。
/* At the time of this writing, there's no equivalent ld option. */
OUTPUT_ARCH (cris)
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册