The main MIPS changes for 5.5:

- Atomics-related code sees some rework & cleanup, most notably allowing
   Loongson LL/SC errata workarounds to be more bulletproof & their
   correctness to be checked at build time.
 
 - Command line setup code is simplified somewhat, resolving various
   corner cases.
 
 - MIPS kernels can now be built with kcov code coverage support.
 
 - We can now build with CONFIG_FORTIFY_SOURCE=y.
 
 - Miscellaneous cleanups.
 
 And some platform specific changes:
 
 - We now disable some broken TLB functionality on certain Ingenic
   systems, and JZ4780 systems gain some devicetree nodes to support
   more devices.
 
 - Loongson support sees a number of cleanups, and we gain initial
   support for Loongson 3A R4 systems.
 
 - We gain support for MediaTek MT7688-based GARDENA Smart Gateway
   systems.
 
 - SGI IP27 (Origin 2*) see a number of fixes, cleanups &
   simplifications.
 
 - SGI IP30 (Octane) systems are now supported.
 -----BEGIN PGP SIGNATURE-----
 
 iIwEABYIADQWIQRgLjeFAZEXQzy86/s+p5+stXUA3QUCXdwj2RYccGF1bGJ1cnRv
 bkBrZXJuZWwub3JnAAoJED6nn6y1dQDd54QA/2CrWLcWCcWVwN8XwLTh3gWf8/k7
 d19Ttd0bYrsBUnaHAP9s9kc9RFOAhB3p1G0dsMZqI0YX7emLGPgW3ejJ7CXNCg==
 =/Hsa
 -----END PGP SIGNATURE-----

Merge tag 'mips_5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux

Pull MIPS updates from Paul Burton:
 "The main MIPS changes for 5.5:

   - Atomics-related code sees some rework & cleanup, most notably
     allowing Loongson LL/SC errata workarounds to be more bulletproof &
     their correctness to be checked at build time.

   - Command line setup code is simplified somewhat, resolving various
     corner cases.

   - MIPS kernels can now be built with kcov code coverage support.

   - We can now build with CONFIG_FORTIFY_SOURCE=y.

   - Miscellaneous cleanups.

  And some platform specific changes:

   - We now disable some broken TLB functionality on certain Ingenic
     systems, and JZ4780 systems gain some devicetree nodes to support
     more devices.

   - Loongson support sees a number of cleanups, and we gain initial
     support for Loongson 3A R4 systems.

   - We gain support for MediaTek MT7688-based GARDENA Smart Gateway
     systems.

   - SGI IP27 (Origin 2*) see a number of fixes, cleanups &
     simplifications.

   - SGI IP30 (Octane) systems are now supported"

* tag 'mips_5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: (107 commits)
  MIPS: SGI-IP27: Enable ethernet phy on second Origin 200 module
  MIPS: PCI: Fix fake subdevice ID for IOC3
  MIPS: Ingenic: Disable abandoned HPTLB function.
  MIPS: PCI: remember nasid changed by set interrupt affinity
  MIPS: SGI-IP27: Fix crash, when CPUs are disabled via nr_cpus parameter
  mips: add support for folded p4d page tables
  mips: drop __pXd_offset() macros that duplicate pXd_index() ones
  mips: fix build when "48 bits virtual memory" is enabled
  MIPS: math-emu: Reuse name array in debugfs_fpuemu()
  MIPS: allow building with kcov coverage
  MIPS: Loongson64: Drop setup_pcimap
  MIPS: Loongson2ef: Convert to early_printk_8250
  MIPS: Drop CPU_SUPPORTS_UNCACHED_ACCELERATED
  MIPS: Loongson{2ef, 32, 64} convert to generic fw cmdline
  MIPS: Drop pmon.h
  MIPS: Loongson: Unify LOONGSON3/LOONGSON64 Kconfig usage
  MIPS: Loongson: Rename LOONGSON1 to LOONGSON32
  MIPS: Loongson: Fix return value of loongson_hwmon_init
  MIPS: add support for SGI Octane (IP30)
  MIPS: PCI: make phys_to_dma/dma_to_phys for pci-xtalk-bridge common
  ...
This commit is contained in:
Linus Torvalds 2019-11-25 17:42:56 -08:00
commit 2981dcf333
238 changed files with 5690 additions and 3690 deletions

View File

@ -16,3 +16,17 @@ value must be one of the following values:
ralink,mt7620a-soc
ralink,mt7620n-soc
ralink,mt7628a-soc
ralink,mt7688a-soc
2. Boards
GARDENA smart Gateway (MT7688)
This board is based on the MediaTek MT7688 and equipped with 128 MiB
of DDR and 8 MiB of flash (SPI NOR) and additional 128MiB SPI NAND
storage.
------------------------------
Required root node properties:
- compatible = "gardena,smart-gateway-mt7688", "ralink,mt7688a-soc",
"ralink,mt7628a-soc";

View File

@ -343,6 +343,8 @@ patternProperties:
description: Freescale Semiconductor
"^fujitsu,.*":
description: Fujitsu Ltd.
"^gardena,.*":
description: GARDENA GmbH
"^gateworks,.*":
description: Gateworks Corporation
"^gcw,.*":

View File

@ -129,6 +129,8 @@ To facilitate such consumers NVMEM framework provides below apis::
struct nvmem_device *nvmem_device_get(struct device *dev, const char *name);
struct nvmem_device *devm_nvmem_device_get(struct device *dev,
const char *name);
struct nvmem_device *nvmem_device_find(void *data,
int (*match)(struct device *dev, const void *data));
void nvmem_device_put(struct nvmem_device *nvmem);
int nvmem_device_read(struct nvmem_device *nvmem, unsigned int offset,
size_t bytes, void *buf);

View File

@ -10900,18 +10900,18 @@ F: arch/mips/include/asm/mach-loongson32/
F: drivers/*/*loongson1*
F: drivers/*/*/*loongson1*
MIPS/LOONGSON2 ARCHITECTURE
MIPS/LOONGSON2EF ARCHITECTURE
M: Jiaxun Yang <jiaxun.yang@flygoat.com>
L: linux-mips@vger.kernel.org
S: Maintained
F: arch/mips/loongson64/fuloong-2e/
F: arch/mips/loongson64/lemote-2f/
F: arch/mips/include/asm/mach-loongson64/
F: arch/mips/loongson2ef/
F: arch/mips/include/asm/mach-loongson2ef/
F: drivers/*/*loongson2*
F: drivers/*/*/*loongson2*
MIPS/LOONGSON3 ARCHITECTURE
MIPS/LOONGSON64 ARCHITECTURE
M: Huacai Chen <chenhc@lemote.com>
M: Jiaxun Yang <jiaxun.yang@flygoat.com>
L: linux-mips@vger.kernel.org
S: Maintained
F: arch/mips/loongson64/

View File

@ -17,6 +17,7 @@ platforms += jazz
platforms += jz4740
platforms += lantiq
platforms += lasat
platforms += loongson2ef
platforms += loongson32
platforms += loongson64
platforms += mti-malta
@ -30,6 +31,7 @@ platforms += ralink
platforms += rb532
platforms += sgi-ip22
platforms += sgi-ip27
platforms += sgi-ip30
platforms += sgi-ip32
platforms += sibyte
platforms += sni

View File

@ -7,6 +7,7 @@ config MIPS
select ARCH_CLOCKSOURCE_DATA
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_HAS_UBSAN_SANITIZE_ALL
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_SUPPORTS_UPROBES
select ARCH_USE_BUILTIN_BSWAP
select ARCH_USE_CMPXCHG_LOCKREF if 64BIT
@ -86,6 +87,8 @@ config MIPS
select SYSCTL_EXCEPTION_TRACE
select VIRT_TO_BUS
select ARCH_HAS_PTE_SPECIAL if !(32BIT && CPU_HAS_RIXI)
select ARCH_HAS_KCOV
select HAVE_GCC_PLUGINS
menu "Machine selection"
@ -359,6 +362,8 @@ config MACH_DECSTATION
config MACH_JAZZ
bool "Jazz family of machines"
select ARC_MEMORY
select ARC_PROMLIB
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
select FW_ARC
@ -441,7 +446,7 @@ config LASAT
select SYS_SUPPORTS_LITTLE_ENDIAN
config MACH_LOONGSON32
bool "Loongson-1 family of machines"
bool "Loongson 32-bit family of machines"
select SYS_SUPPORTS_ZBOOT
help
This enables support for the Loongson-1 family of machines.
@ -450,18 +455,48 @@ config MACH_LOONGSON32
the Institute of Computing Technology (ICT), Chinese Academy of
Sciences (CAS).
config MACH_LOONGSON64
bool "Loongson-2/3 family of machines"
config MACH_LOONGSON2EF
bool "Loongson-2E/F family of machines"
select SYS_SUPPORTS_ZBOOT
help
This enables the support of early Loongson-2E/F family of machines.
config MACH_LOONGSON64
bool "Loongson 64-bit family of machines"
select ARCH_SPARSEMEM_ENABLE
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
select GENERIC_ISA_DMA_SUPPORT_BROKEN
select BOOT_ELF32
select BOARD_SCACHE
select CSRC_R4K
select CEVT_R4K
select CPU_HAS_WB
select FORCE_PCI
select ISA
select I8259
select IRQ_MIPS_CPU
select NR_CPUS_DEFAULT_4
select USE_GENERIC_EARLY_PRINTK_8250
select SYS_HAS_CPU_LOONGSON64
select SYS_HAS_EARLY_PRINTK
select SYS_SUPPORTS_SMP
select SYS_SUPPORTS_HOTPLUG_CPU
select SYS_SUPPORTS_NUMA
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_HIGHMEM
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_ZBOOT
select LOONGSON_MC146818
select ZONE_DMA32
select NUMA
help
This enables the support of Loongson-2/3 family of machines.
Loongson-2 is a family of single-core CPUs and Loongson-3 is a
family of multi-core CPUs. They are both 64-bit general-purpose
MIPS-compatible CPUs. Loongson-2/3 are developed by the Institute
of Computing Technology (ICT), Chinese Academy of Sciences (CAS)
in the People's Republic of China. The chief architect is Professor
Weiwu Hu.
Loongson-2 and Loongson-3 are 64-bit general-purpose processors with
GS264/GS464/GS464E/GS464V microarchitecture (except old Loongson-2E
and Loongson-2F which will be removed), developed by the Institute
of Computing Technology (ICT), Chinese Academy of Sciences (CAS).
config MACH_PISTACHIO
bool "IMG Pistachio SoC based boards"
@ -631,6 +666,8 @@ config RALINK
config SGI_IP22
bool "SGI IP22 (Indy/Indigo2)"
select ARC_MEMORY
select ARC_PROMLIB
select FW_ARC
select FW_ARC32
select ARCH_MIGHT_HAVE_PC_SERIO
@ -654,14 +691,7 @@ config SGI_IP22
select SWAP_IO_SPACE
select SYS_HAS_CPU_R4X00
select SYS_HAS_CPU_R5000
#
# Disable EARLY_PRINTK for now since it leads to overwritten prom
# memory during early boot on some machines.
#
# See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com
# for a more details discussion
#
# select SYS_HAS_EARLY_PRINTK
select SYS_HAS_EARLY_PRINTK
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
@ -674,8 +704,10 @@ config SGI_IP22
config SGI_IP27
bool "SGI IP27 (Origin200/2000)"
select ARCH_HAS_PHYS_TO_DMA
select ARCH_SPARSEMEM_ENABLE
select FW_ARC
select FW_ARC64
select ARC_CMDLINE_ONLY
select BOOT_ELF64
select DEFAULT_SGI_PARTITION
select SYS_HAS_EARLY_PRINTK
@ -698,6 +730,8 @@ config SGI_IP27
config SGI_IP28
bool "SGI IP28 (Indigo2 R10k)"
select ARC_MEMORY
select ARC_PROMLIB
select FW_ARC
select FW_ARC64
select ARCH_MIGHT_HAVE_PC_SERIO
@ -719,14 +753,7 @@ config SGI_IP28
select SGI_HAS_ZILOG
select SWAP_IO_SPACE
select SYS_HAS_CPU_R10000
#
# Disable EARLY_PRINTK for now since it leads to overwritten prom
# memory during early boot on some machines.
#
# See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com
# for a more details discussion
#
# select SYS_HAS_EARLY_PRINTK
select SYS_HAS_EARLY_PRINTK
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
select MIPS_L1_CACHE_SHIFT_7
@ -734,8 +761,37 @@ config SGI_IP28
This is the SGI Indigo2 with R10000 processor. To compile a Linux
kernel that runs on these, say Y here.
config SGI_IP30
bool "SGI IP30 (Octane/Octane2)"
select ARCH_HAS_PHYS_TO_DMA
select FW_ARC
select FW_ARC64
select BOOT_ELF64
select CEVT_R4K
select CSRC_R4K
select SYNC_R4K if SMP
select ZONE_DMA32
select HAVE_PCI
select IRQ_MIPS_CPU
select IRQ_DOMAIN_HIERARCHY
select NR_CPUS_DEFAULT_2
select PCI_DRIVERS_GENERIC
select PCI_XTALK_BRIDGE
select SYS_HAS_EARLY_PRINTK
select SYS_HAS_CPU_R10000
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_SMP
select MIPS_L1_CACHE_SHIFT_7
select ARC_MEMORY
help
These are the SGI Octane and Octane2 graphics workstations. To
compile a Linux kernel that runs on these, say Y here.
config SGI_IP32
bool "SGI IP32 (O2)"
select ARC_MEMORY
select ARC_PROMLIB
select ARCH_HAS_PHYS_TO_DMA
select FW_ARC
select FW_ARC32
@ -843,6 +899,8 @@ config SIBYTE_BIGSUR
config SNI_RM
bool "SNI RM200/300/400"
select ARC_MEMORY
select ARC_PROMLIB
select FW_ARC if CPU_LITTLE_ENDIAN
select FW_ARC32 if CPU_LITTLE_ENDIAN
select FW_SNIPROM if CPU_BIG_ENDIAN
@ -1038,6 +1096,7 @@ source "arch/mips/sibyte/Kconfig"
source "arch/mips/txx9/Kconfig"
source "arch/mips/vr41xx/Kconfig"
source "arch/mips/cavium-octeon/Kconfig"
source "arch/mips/loongson2ef/Kconfig"
source "arch/mips/loongson32/Kconfig"
source "arch/mips/loongson64/Kconfig"
source "arch/mips/netlogic/Kconfig"
@ -1353,19 +1412,18 @@ config MIPS_L1_CACHE_SHIFT
config HAVE_STD_PC_SERIAL_PORT
bool
config ARC_CMDLINE_ONLY
bool
config ARC_CONSOLE
bool "ARC console support"
depends on SGI_IP22 || SGI_IP28 || (SNI_RM && CPU_LITTLE_ENDIAN)
config ARC_MEMORY
bool
depends on MACH_JAZZ || SNI_RM || SGI_IP32
default y
config ARC_PROMLIB
bool
depends on MACH_JAZZ || SNI_RM || SGI_IP22 || SGI_IP28 || SGI_IP32
default y
config FW_ARC64
bool
@ -1379,51 +1437,56 @@ choice
prompt "CPU type"
default CPU_R4X00
config CPU_LOONGSON3
bool "Loongson 3 CPU"
depends on SYS_HAS_CPU_LOONGSON3
config CPU_LOONGSON64
bool "Loongson 64-bit CPU"
depends on SYS_HAS_CPU_LOONGSON64
select ARCH_HAS_PHYS_TO_DMA
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_HUGEPAGES
select CPU_SUPPORTS_MSA
select CPU_HAS_LOAD_STORE_LR
select WEAK_ORDERING
select WEAK_REORDERING_BEYOND_LLSC
select MIPS_ASID_BITS_VARIABLE
select MIPS_PGD_C0_CONTEXT
select MIPS_L1_CACHE_SHIFT_6
select GPIOLIB
select SWIOTLB
help
The Loongson 3 processor implements the MIPS64R2 instruction
set with many extensions.
The Loongson GSx64(GS264/GS464/GS464E/GS464V) series of processor
cores implements the MIPS64R2 instruction set with many extensions,
including most 64-bit Loongson-2 (2H, 2K) and Loongson-3 (3A1000,
3B1000, 3B1500, 3A2000, 3A3000 and 3A4000) processors. However, old
Loongson-2E/2F is not covered here and will be removed in future.
config LOONGSON3_ENHANCEMENT
bool "New Loongson 3 CPU Enhancements"
bool "New Loongson-3 CPU Enhancements"
default n
select CPU_MIPSR2
select CPU_HAS_PREFETCH
depends on CPU_LOONGSON3
depends on CPU_LOONGSON64
help
New Loongson 3 CPU (since Loongson-3A R2, as opposed to Loongson-3A
New Loongson-3 cores (since Loongson-3A R2, as opposed to Loongson-3A
R1, Loongson-3B R1 and Loongson-3B R2) has many enhancements, such as
FTLB, L1-VCache, EI/DI/Wait/Prefetch instruction, DSP/DSPv2 ASE, User
FTLB, L1-VCache, EI/DI/Wait/Prefetch instruction, DSP/DSPr2 ASE, User
Local register, Read-Inhibit/Execute-Inhibit, SFB (Store Fill Buffer),
Fast TLB refill support, etc.
This option enable those enhancements which are not probed at run
time. If you want a generic kernel to run on all Loongson 3 machines,
please say 'N' here. If you want a high-performance kernel to run on
new Loongson 3 machines only, please say 'Y' here.
new Loongson-3 machines only, please say 'Y' here.
config CPU_LOONGSON3_WORKAROUNDS
bool "Old Loongson 3 LLSC Workarounds"
bool "Old Loongson-3 LLSC Workarounds"
default y if SMP
depends on CPU_LOONGSON3
depends on CPU_LOONGSON64
help
Loongson 3 processors have the llsc issues which require workarounds.
Loongson-3 processors have the llsc issues which require workarounds.
Without workarounds the system may hang unexpectedly.
Newer Loongson 3 will fix these issues and no workarounds are needed.
Newer Loongson-3 will fix these issues and no workarounds are needed.
The workarounds have no significant side effect on them but may
decrease the performance of the system so this option should be
disabled unless the kernel is intended to be run on old systems.
@ -1433,7 +1496,7 @@ config CPU_LOONGSON3_WORKAROUNDS
config CPU_LOONGSON2E
bool "Loongson 2E"
depends on SYS_HAS_CPU_LOONGSON2E
select CPU_LOONGSON2
select CPU_LOONGSON2EF
help
The Loongson 2E processor implements the MIPS III instruction set
with many extensions.
@ -1444,7 +1507,7 @@ config CPU_LOONGSON2E
config CPU_LOONGSON2F
bool "Loongson 2F"
depends on SYS_HAS_CPU_LOONGSON2F
select CPU_LOONGSON2
select CPU_LOONGSON2EF
select GPIOLIB
help
The Loongson 2F processor implements the MIPS III instruction set
@ -1457,7 +1520,7 @@ config CPU_LOONGSON2F
config CPU_LOONGSON1B
bool "Loongson 1B"
depends on SYS_HAS_CPU_LOONGSON1B
select CPU_LOONGSON1
select CPU_LOONGSON32
select LEDS_GPIO_REGISTER
help
The Loongson 1B is a 32-bit SoC, which implements the MIPS32
@ -1467,7 +1530,7 @@ config CPU_LOONGSON1B
config CPU_LOONGSON1C
bool "Loongson 1C"
depends on SYS_HAS_CPU_LOONGSON1C
select CPU_LOONGSON1
select CPU_LOONGSON32
select LEDS_GPIO_REGISTER
help
The Loongson 1C is a 32-bit SoC, which implements the MIPS32
@ -1857,7 +1920,7 @@ config SYS_SUPPORTS_ZBOOT_UART_PROM
bool
select SYS_SUPPORTS_ZBOOT
config CPU_LOONGSON2
config CPU_LOONGSON2EF
bool
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
@ -1866,7 +1929,7 @@ config CPU_LOONGSON2
select ARCH_HAS_PHYS_TO_DMA
select CPU_HAS_LOAD_STORE_LR
config CPU_LOONGSON1
config CPU_LOONGSON32
bool
select CPU_MIPS32
select CPU_MIPSR2
@ -1900,7 +1963,7 @@ config CPU_BMIPS5000
select SYS_SUPPORTS_HOTPLUG_CPU
select CPU_HAS_RIXI
config SYS_HAS_CPU_LOONGSON3
config SYS_HAS_CPU_LOONGSON64
bool
select CPU_SUPPORTS_CPUFREQ
select CPU_HAS_RIXI
@ -1912,7 +1975,6 @@ config SYS_HAS_CPU_LOONGSON2F
bool
select CPU_SUPPORTS_CPUFREQ
select CPU_SUPPORTS_ADDRWINCFG if 64BIT
select CPU_SUPPORTS_UNCACHED_ACCELERATED
config SYS_HAS_CPU_LOONGSON1B
bool
@ -2089,8 +2151,6 @@ config CPU_SUPPORTS_ADDRWINCFG
config CPU_SUPPORTS_HUGEPAGES
bool
depends on !(32BIT && (ARCH_PHYS_ADDR_T_64BIT || EVA))
config CPU_SUPPORTS_UNCACHED_ACCELERATED
bool
config MIPS_PGD_C0_CONTEXT
bool
default y if 64BIT && (CPU_MIPSR2 || CPU_MIPSR6) && !CPU_XLP
@ -2162,7 +2222,7 @@ choice
config PAGE_SIZE_4KB
bool "4kB"
depends on !CPU_LOONGSON2 && !CPU_LOONGSON3
depends on !CPU_LOONGSON2EF && !CPU_LOONGSON64
help
This option select the standard 4kB Linux page size. On some
R3000-family processors this is the only available page size. Using
@ -2554,6 +2614,10 @@ config CPU_R4000_WORKAROUNDS
config CPU_R4400_WORKAROUNDS
bool
config CPU_R4X00_BUGS64
bool
default y if SYS_HAS_CPU_R4X00 && 64BIT && (TARGET_ISA_REV < 1)
config MIPS_ASID_SHIFT
int
default 6 if CPU_R3000 || CPU_TX39XX
@ -2612,20 +2676,11 @@ config CPU_SUPPORTS_MSA
config ARCH_FLATMEM_ENABLE
def_bool y
depends on !NUMA && !CPU_LOONGSON2
config ARCH_DISCONTIGMEM_ENABLE
bool
default y if SGI_IP27
help
Say Y to support efficient handling of discontiguous physical memory,
for architectures which are either NUMA (Non-Uniform Memory Access)
or have huge holes in the physical address space for other reasons.
See <file:Documentation/vm/numa.rst> for more.
depends on !NUMA && !CPU_LOONGSON2EF
config ARCH_SPARSEMEM_ENABLE
bool
select SPARSEMEM_STATIC
select SPARSEMEM_STATIC if !SGI_IP27
config NUMA
bool "NUMA Support"
@ -2702,7 +2757,7 @@ config NODES_SHIFT
config HW_PERF_EVENTS
bool "Enable hardware performance counter support for perf events"
depends on PERF_EVENTS && !OPROFILE && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP || CPU_LOONGSON3)
depends on PERF_EVENTS && !OPROFILE && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP || CPU_LOONGSON64)
default y
help
Enable hardware performance counter support for perf events. If

View File

@ -32,7 +32,6 @@ config USE_GENERIC_EARLY_PRINTK_8250
config CMDLINE_BOOL
bool "Built-in kernel command line"
default n
help
For most systems, it is firmware or second stage bootloader that
by default specifies the kernel command line options. However,
@ -53,7 +52,6 @@ config CMDLINE_BOOL
config CMDLINE
string "Default kernel command string"
depends on CMDLINE_BOOL
default ""
help
On some platforms, there is currently no way for the boot loader to
pass arguments to the kernel. For these platforms, and for the cases
@ -68,7 +66,6 @@ config CMDLINE
config CMDLINE_OVERRIDE
bool "Built-in command line overrides firmware arguments"
default n
depends on CMDLINE_BOOL
help
By setting this option to 'Y' you will have your kernel ignore

View File

@ -14,6 +14,9 @@
archscripts: scripts_basic
$(Q)$(MAKE) $(build)=arch/mips/tools elf-entry
ifeq ($(CONFIG_CPU_LOONGSON3_WORKAROUNDS),y)
$(Q)$(MAKE) $(build)=arch/mips/tools loongson3-llsc-check
endif
$(Q)$(MAKE) $(build)=arch/mips/boot/tools relocs
KBUILD_DEFCONFIG := 32r2el_defconfig

View File

@ -3,7 +3,8 @@
# Post-link MIPS pass
# ===========================================================================
#
# 1. Insert relocations into vmlinux
# 1. Check that Loongson3 LL/SC workarounds are applied correctly
# 2. Insert relocations into vmlinux
PHONY := __archpost
__archpost:
@ -11,6 +12,10 @@ __archpost:
-include include/config/auto.conf
include scripts/Kbuild.include
CMD_LS3_LLSC = arch/mips/tools/loongson3-llsc-check
quiet_cmd_ls3_llsc = LLSCCHK $@
cmd_ls3_llsc = $(CMD_LS3_LLSC) $@
CMD_RELOCS = arch/mips/boot/tools/relocs
quiet_cmd_relocs = RELOCS $@
cmd_relocs = $(CMD_RELOCS) $@
@ -19,6 +24,9 @@ quiet_cmd_relocs = RELOCS $@
vmlinux: FORCE
@true
ifeq ($(CONFIG_CPU_LOONGSON3_WORKAROUNDS),y)
$(call if_changed,ls3_llsc)
endif
ifeq ($(CONFIG_RELOCATABLE),y)
$(call if_changed,relocs)
endif

View File

@ -25,12 +25,47 @@
0x30000000 0x30000000>;
};
leds {
compatible = "gpio-leds";
led0 {
label = "ci20:red:led0";
gpios = <&gpc 3 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "none";
};
led1 {
label = "ci20:red:led1";
gpios = <&gpc 2 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "nand-disk";
};
led2 {
label = "ci20:red:led2";
gpios = <&gpc 1 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "cpu1";
};
led3 {
label = "ci20:red:led3";
gpios = <&gpc 0 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "cpu0";
};
};
eth0_power: fixedregulator@0 {
compatible = "regulator-fixed";
regulator-name = "eth0_power";
gpio = <&gpb 25 GPIO_ACTIVE_LOW>;
enable-active-high;
};
wlan0_power: fixedregulator@1 {
compatible = "regulator-fixed";
regulator-name = "wlan0_power";
gpio = <&gpb 19 GPIO_ACTIVE_LOW>;
enable-active-high;
};
};
&ext {
@ -54,9 +89,18 @@
bus-width = <4>;
max-frequency = <50000000>;
non-removable;
pinctrl-names = "default";
pinctrl-0 = <&pins_mmc1>;
brcmf: wifi@1 {
/* reg = <4>;*/
compatible = "brcm,bcm4330-fmac";
vcc-supply = <&wlan0_power>;
device-wakeup-gpios = <&gpd 9 GPIO_ACTIVE_HIGH>;
shutdown-gpios = <&gpf 7 GPIO_ACTIVE_LOW>;
};
};
&uart0 {
@ -73,6 +117,23 @@
pinctrl-0 = <&pins_uart1>;
};
&uart2 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pins_uart2>;
uart-has-rtscts;
bluetooth {
compatible = "brcm,bcm4330-bt";
reset-gpios = <&gpf 8 GPIO_ACTIVE_HIGH>;
vcc-supply = <&wlan0_power>;
device-wakeup-gpios = <&gpf 5 GPIO_ACTIVE_HIGH>;
host-wakeup-gpios = <&gpf 6 GPIO_ACTIVE_HIGH>;
shutdown-gpios = <&gpf 4 GPIO_ACTIVE_LOW>;
};
};
&uart3 {
status = "okay";
@ -87,6 +148,123 @@
pinctrl-0 = <&pins_uart4>;
};
&i2c0 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pins_i2c0>;
clock-frequency = <400000>;
act8600: act8600@5a {
compatible = "active-semi,act8600";
reg = <0x5a>;
status = "okay";
regulators {
vddcore: SUDCDC1 {
regulator-name = "VDDCORE";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
};
vddmem: SUDCDC2 {
regulator-name = "VDDMEM";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
regulator-always-on;
};
vcc_33: SUDCDC3 {
regulator-name = "VCC33";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
vcc_50: SUDCDC4 {
regulator-name = "VCC50";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
regulator-always-on;
};
vcc_25: LDO_REG5 {
regulator-name = "VCC25";
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <2500000>;
regulator-always-on;
};
wifi_io: LDO_REG6 {
regulator-name = "WIFIIO";
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <2500000>;
regulator-always-on;
};
vcc_28: LDO_REG7 {
regulator-name = "VCC28";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-always-on;
};
vcc_15: LDO_REG8 {
regulator-name = "VCC15";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
regulator-always-on;
};
vcc_18: LDO_REG9 {
regulator-name = "VCC18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
vcc_11: LDO_REG10 {
regulator-name = "VCC11";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
};
};
};
};
&i2c1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pins_i2c1>;
};
&i2c2 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pins_i2c2>;
};
&i2c3 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pins_i2c3>;
};
&i2c4 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pins_i2c4>;
clock-frequency = <400000>;
rtc@51 {
compatible = "nxp,pcf8563";
reg = <0x51>;
interrupts = <110>;
};
};
&nemc {
status = "okay";
@ -197,6 +375,12 @@
bias-disable;
};
pins_uart2: uart2 {
function = "uart2";
groups = "uart2-data", "uart2-hwflow";
bias-disable;
};
pins_uart3: uart3 {
function = "uart3";
groups = "uart3-data", "uart3-hwflow";
@ -209,6 +393,36 @@
bias-disable;
};
pins_i2c0: i2c0 {
function = "i2c0";
groups = "i2c0-data";
bias-disable;
};
pins_i2c1: i2c1 {
function = "i2c1";
groups = "i2c1-data";
bias-disable;
};
pins_i2c2: i2c2 {
function = "i2c2";
groups = "i2c2-data";
bias-disable;
};
pins_i2c3: i2c3 {
function = "i2c3";
groups = "i2c3-data";
bias-disable;
};
pins_i2c4: i2c4 {
function = "i2c4";
groups = "i2c4-data-e";
bias-disable;
};
pins_nemc: nemc {
function = "nemc";
groups = "nemc-data", "nemc-cle-ale", "nemc-rd-we", "nemc-frd-fwe";

View File

@ -262,6 +262,92 @@
status = "disabled";
};
i2c0: i2c@10050000 {
compatible = "ingenic,jz4780-i2c";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x10050000 0x1000>;
interrupt-parent = <&intc>;
interrupts = <60>;
clocks = <&cgu JZ4780_CLK_SMB0>;
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pins_i2c0_data>;
status = "disabled";
};
i2c1: i2c@10051000 {
compatible = "ingenic,jz4780-i2c";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x10051000 0x1000>;
interrupt-parent = <&intc>;
interrupts = <59>;
clocks = <&cgu JZ4780_CLK_SMB1>;
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pins_i2c1_data>;
status = "disabled";
};
i2c2: i2c@10052000 {
compatible = "ingenic,jz4780-i2c";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x10052000 0x1000>;
interrupt-parent = <&intc>;
interrupts = <58>;
clocks = <&cgu JZ4780_CLK_SMB2>;
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pins_i2c2_data>;
status = "disabled";
};
i2c3: i2c@10053000 {
compatible = "ingenic,jz4780-i2c";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x10053000 0x1000>;
interrupt-parent = <&intc>;
interrupts = <57>;
clocks = <&cgu JZ4780_CLK_SMB3>;
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pins_i2c3_data>;
status = "disabled";
};
i2c4: i2c@10054000 {
compatible = "ingenic,jz4780-i2c";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x10054000 0x1000>;
interrupt-parent = <&intc>;
interrupts = <56>;
clocks = <&cgu JZ4780_CLK_SMB4>;
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pins_i2c4_data>;
status = "disabled";
};
watchdog: watchdog@10002000 {
compatible = "ingenic,jz4780-watchdog";
reg = <0x10002000 0x10>;

View File

@ -0,0 +1,197 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2019 Stefan Roese <sr@denx.de>
*/
/dts-v1/;
/include/ "mt7628a.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
/ {
compatible = "gardena,smart-gateway-mt7688", "ralink,mt7688a-soc",
"ralink,mt7628a-soc";
model = "GARDENA smart Gateway (MT7688)";
memory@0 {
device_type = "memory";
reg = <0x0 0x8000000>;
};
gpio-keys {
compatible = "gpio-keys";
pinctrl-names = "default";
pinctrl-0 = <&pinmux_gpio_gpio>; /* GPIO11 */
user_btn1 {
label = "USER_BTN1";
gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
linux,code =<KEY_PROG1> ;
};
};
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
pinctrl-0 = <&pinmux_pwm0_gpio>, /* GPIO18 */
<&pinmux_pwm1_gpio>, /* GPIO19 */
<&pinmux_sdmode_gpio>, /* GPIO22..29 */
<&pinmux_p0led_an_gpio>; /* GPIO43 */
/*
* <&pinmux_i2s_gpio> (covers GPIO0..3) is needed here as
* well for GPIO3. But this is already claimed for uart1
* (see below). So we can't include it in this LED node.
*/
power_blue {
label = "smartgw:power:blue";
gpios = <&gpio 18 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
power_green {
label = "smartgw:power:green";
gpios = <&gpio 19 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
power_red {
label = "smartgw:power:red";
gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
radio_blue {
label = "smartgw:radio:blue";
gpios = <&gpio 23 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
radio_green {
label = "smartgw:radio:green";
gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
radio_red {
label = "smartgw:radio:red";
gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
internet_blue {
label = "smartgw:internet:blue";
gpios = <&gpio 26 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
internet_green {
label = "smartgw:internet:green";
gpios = <&gpio 27 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
internet_red {
label = "smartgw:internet:red";
gpios = <&gpio 28 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
ethernet_link {
label = "smartgw:eth:link";
gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
linux,default-trigger = "netdev";
};
ethernet_activity {
label = "smartgw:eth:act";
gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
linux,default-trigger = "netdev";
};
};
aliases {
serial0 = &uart0;
};
};
&i2c {
status = "okay";
};
&spi {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinmux_spi_spi>, <&pinmux_spi_cs1_cs>;
m25p80@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <40000000>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "uboot";
reg = <0x0 0xa0000>;
read-only;
};
partition@a0000 {
label = "uboot_env0";
reg = <0xa0000 0x10000>;
};
partition@b0000 {
label = "uboot_env1";
reg = <0xb0000 0x10000>;
};
factory: partition@c0000 {
label = "factory";
reg = <0xc0000 0x10000>;
read-only;
};
};
};
nand_flash@1 {
compatible = "spi-nand";
linux,mtd-name = "gd5f";
reg = <1>;
spi-max-frequency = <40000000>;
};
};
&uart1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinmux_i2s_gpio>; /* GPIO0..3 */
rts-gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
cts-gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
};
&uart2 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinmux_p2led_an_gpio>, /* GPIO41 */
<&pinmux_p3led_an_gpio>; /* GPIO40 */
rts-gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
cts-gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
};
&watchdog {
status = "okay";
};

View File

@ -199,6 +199,22 @@
status = "disabled";
};
i2c: i2c@900 {
compatible = "mediatek,mt7621-i2c";
reg = <0x900 0x100>;
pinctrl-names = "default";
pinctrl-0 = <&pinmux_i2c_i2c>;
resets = <&resetc 16>;
reset-names = "i2c";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
uart0: uartlite@c00 {
compatible = "ns16550a";
reg = <0xc00 0x100>;

View File

@ -844,7 +844,7 @@ void __init prom_init(void)
* BIST should always be enabled when doing a soft reset. L2
* Cache locking for instance is not cleared unless BIST is
* enabled. Unfortunately due to a chip errata G-200 for
* Cn38XX and CN31XX, BIST msut be disabled on these parts.
* Cn38XX and CN31XX, BIST must be disabled on these parts.
*/
if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2) ||
OCTEON_IS_MODEL(OCTEON_CN31XX))

View File

@ -15,7 +15,7 @@ CONFIG_EXPERT=y
# CONFIG_COMPAT_BRK is not set
CONFIG_SLAB=y
CONFIG_PROFILING=y
CONFIG_MACH_LOONGSON64=y
CONFIG_MACH_LOONGSON2EF=y
CONFIG_PCI=y
CONFIG_MIPS32_O32=y
CONFIG_MIPS32_N32=y

View File

@ -12,7 +12,7 @@ CONFIG_LOG_BUF_SHIFT=15
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
CONFIG_PROFILING=y
CONFIG_MACH_LOONGSON64=y
CONFIG_MACH_LOONGSON2EF=y
CONFIG_LEMOTE_MACH2F=y
CONFIG_KEXEC=y
# CONFIG_SECCOMP is not set

View File

@ -12,7 +12,6 @@ CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
CONFIG_BLK_CGROUP=y
@ -24,7 +23,6 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_EMBEDDED=y
CONFIG_MACH_LOONGSON64=y
CONFIG_LOONGSON_MACH3X=y
CONFIG_SMP=y
CONFIG_HZ_256=y
CONFIG_KEXEC=y

View File

@ -3,8 +3,12 @@
# Makefile for the ARC prom monitor library routines under Linux.
#
ifdef CONFIG_ARC_CMDLINE_ONLY
lib-y += cmdline.o
else
lib-y += cmdline.o env.o file.o identify.o init.o \
misc.o salone.o time.o tree.o
misc.o
endif
lib-$(CONFIG_ARC_MEMORY) += memory.o
lib-$(CONFIG_ARC_CONSOLE) += arc_con.o

View File

@ -17,6 +17,12 @@
#undef DEBUG_CMDLINE
/*
* A 32-bit ARC PROM pass arguments and environment as 32-bit pointer.
* These macro take care of sign extension.
*/
#define prom_argv(index) ((char *) (long)argv[(index)])
static char *ignored[] = {
"ConsoleIn=",
"ConsoleOut=",
@ -32,14 +38,14 @@ static char *used_arc[][2] = {
{ "OSLoadOptions=", "" }
};
static char * __init move_firmware_args(char* cp)
static char __init *move_firmware_args(int argc, LONG *argv, char *cp)
{
char *s;
int actr, i;
actr = 1; /* Always ignore argv[0] */
while (actr < prom_argc) {
while (actr < argc) {
for(i = 0; i < ARRAY_SIZE(used_arc); i++) {
int len = strlen(used_arc[i][0]);
@ -64,7 +70,7 @@ static char * __init move_firmware_args(char* cp)
return cp;
}
void __init prom_init_cmdline(void)
void __init prom_init_cmdline(int argc, LONG *argv)
{
char *cp;
int actr, i;
@ -76,9 +82,9 @@ void __init prom_init_cmdline(void)
* Move ARC variables to the beginning to make sure they can be
* overridden by later arguments.
*/
cp = move_firmware_args(cp);
cp = move_firmware_args(argc, argv, cp);
while (actr < prom_argc) {
while (actr < argc) {
for (i = 0; i < ARRAY_SIZE(ignored); i++) {
int len = strlen(ignored[i]);

View File

@ -19,9 +19,3 @@ ArcGetEnvironmentVariable(CHAR *name)
{
return (CHAR *) ARC_CALL1(get_evar, name);
}
LONG __init
ArcSetEnvironmentVariable(PCHAR name, PCHAR value)
{
return ARC_CALL2(set_evar, name, value);
}

View File

@ -12,63 +12,14 @@
#include <asm/fw/arc/types.h>
#include <asm/sgialib.h>
LONG
ArcGetDirectoryEntry(ULONG FileID, struct linux_vdirent *Buffer,
ULONG N, ULONG *Count)
{
return ARC_CALL4(get_vdirent, FileID, Buffer, N, Count);
}
LONG
ArcOpen(CHAR *Path, enum linux_omode OpenMode, ULONG *FileID)
{
return ARC_CALL3(open, Path, OpenMode, FileID);
}
LONG
ArcClose(ULONG FileID)
{
return ARC_CALL1(close, FileID);
}
LONG
ArcRead(ULONG FileID, VOID *Buffer, ULONG N, ULONG *Count)
{
return ARC_CALL4(read, FileID, Buffer, N, Count);
}
LONG
ArcGetReadStatus(ULONG FileID)
{
return ARC_CALL1(get_rstatus, FileID);
}
LONG
ArcWrite(ULONG FileID, PVOID Buffer, ULONG N, PULONG Count)
{
return ARC_CALL4(write, FileID, Buffer, N, Count);
}
LONG
ArcSeek(ULONG FileID, struct linux_bigint *Position, enum linux_seekmode SeekMode)
{
return ARC_CALL3(seek, FileID, Position, SeekMode);
}
LONG
ArcMount(char *name, enum linux_mountops op)
{
return ARC_CALL2(mount, name, op);
}
LONG
ArcGetFileInformation(ULONG FileID, struct linux_finfo *Information)
{
return ARC_CALL2(get_finfo, FileID, Information);
}
LONG ArcSetFileInformation(ULONG FileID, ULONG AttributeFlags,
ULONG AttributeMask)
{
return ARC_CALL3(set_finfo, FileID, AttributeFlags, AttributeMask);
}

View File

@ -31,10 +31,6 @@ static struct smatch mach_table[] = {
.arcname = "SGI-IP22",
.liname = "SGI Indy",
.flags = PROM_FLAG_ARCS,
}, {
.arcname = "SGI-IP27",
.liname = "SGI Origin",
.flags = PROM_FLAG_ARCS,
}, {
.arcname = "SGI-IP28",
.liname = "SGI IP28",
@ -87,6 +83,11 @@ const char *get_system_type(void)
return system_type;
}
static pcomponent * __init ArcGetChild(pcomponent *Current)
{
return (pcomponent *) ARC_CALL1(child_component, Current);
}
void __init prom_identify_arch(void)
{
pcomponent *p;
@ -98,13 +99,7 @@ void __init prom_identify_arch(void)
*/
p = ArcGetChild(PROM_NULL_COMPONENT);
if (p == NULL) {
#ifdef CONFIG_SGI_IP27
/* IP27 PROM misbehaves, seems to not implement ARC
GetChild(). So we just assume it's an IP27. */
iname = "SGI-IP27";
#else
iname = "Unknown";
#endif
} else
iname = (char *) (long) p->iname;

View File

@ -18,8 +18,11 @@
/* Master romvec interface. */
struct linux_romvec *romvec;
int prom_argc;
LONG *_prom_argv, *_prom_envp;
#if defined(CONFIG_64BIT) && defined(CONFIG_FW_ARC32)
/* stack for calling 32bit ARC prom */
u64 o32_stk[4096];
#endif
void __init prom_init(void)
{
@ -27,10 +30,6 @@ void __init prom_init(void)
romvec = ROMVECTOR;
prom_argc = fw_arg0;
_prom_argv = (LONG *) fw_arg1;
_prom_envp = (LONG *) fw_arg2;
if (pb->magic != 0x53435241) {
printk(KERN_CRIT "Aieee, bad prom vector magic %08lx\n",
(unsigned long) pb->magic);
@ -38,7 +37,7 @@ void __init prom_init(void)
;
}
prom_init_cmdline();
prom_init_cmdline(fw_arg0, (LONG *)fw_arg1);
prom_identify_arch();
printk(KERN_INFO "PROMLIB: ARC firmware Version %d Revision %d\n",
pb->ver, pb->rev);
@ -49,11 +48,4 @@ void __init prom_init(void)
ArcRead(0, &c, 1, &cnt);
ArcEnterInteractiveMode();
#endif
#ifdef CONFIG_SGI_IP27
{
extern const struct plat_smp_ops ip27_smp_ops;
register_smp_ops(&ip27_smp_ops);
}
#endif
}

View File

@ -158,6 +158,10 @@ void __init prom_meminit(void)
}
}
void __weak __init prom_cleanup(void)
{
}
void __init prom_free_prom_memory(void)
{
int i;
@ -169,4 +173,9 @@ void __init prom_free_prom_memory(void)
free_init_pages("prom memory",
prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]);
}
/*
* at this point it isn't safe to call PROM functions
* give platforms a way to do PROM cleanups
*/
prom_cleanup();
}

View File

@ -20,47 +20,6 @@
#include <asm/sgialib.h>
#include <asm/bootinfo.h>
VOID __noreturn
ArcHalt(VOID)
{
bc_disable();
local_irq_disable();
ARC_CALL0(halt);
unreachable();
}
VOID __noreturn
ArcPowerDown(VOID)
{
bc_disable();
local_irq_disable();
ARC_CALL0(pdown);
unreachable();
}
/* XXX is this a soft reset basically? XXX */
VOID __noreturn
ArcRestart(VOID)
{
bc_disable();
local_irq_disable();
ARC_CALL0(restart);
unreachable();
}
VOID __noreturn
ArcReboot(VOID)
{
bc_disable();
local_irq_disable();
ARC_CALL0(reboot);
unreachable();
}
VOID __noreturn
ArcEnterInteractiveMode(VOID)
{
@ -71,24 +30,6 @@ ArcEnterInteractiveMode(VOID)
unreachable();
}
LONG
ArcSaveConfiguration(VOID)
{
return ARC_CALL0(cfg_save);
}
struct linux_sysid *
ArcGetSystemId(VOID)
{
return (struct linux_sysid *) ARC_CALL0(get_sysid);
}
VOID __init
ArcFlushAllCaches(VOID)
{
ARC_CALL0(cache_flush);
}
DISPLAY_STATUS * __init ArcGetDisplayStatus(ULONG FileID)
{
return (DISPLAY_STATUS *) ARC_CALL1(GetDisplayStatus, FileID);

View File

@ -11,6 +11,21 @@
#include <asm/bcache.h>
#include <asm/setup.h>
#if defined(CONFIG_64BIT) && defined(CONFIG_FW_ARC32)
/*
* For 64bit kernels working with a 32bit ARC PROM pointer arguments
* for ARC calls need to reside in CKEG0/1. But as soon as the kernel
* switches to it's first kernel thread stack is set to an address in
* XKPHYS, so anything on stack can't be used anymore. This is solved
* by using a * static declartion variables are put into BSS, which is
* linked to a CKSEG0 address. Since this is only used on UP platforms
* there is not spinlock needed
*/
#define O32_STATIC static
#else
#define O32_STATIC
#endif
/*
* IP22 boardcache is not compatible with board caches. Thus we disable it
* during romvec action. Since r4xx0.c is always compiled and linked with your
@ -23,8 +38,10 @@
void prom_putchar(char c)
{
ULONG cnt;
CHAR it = c;
O32_STATIC ULONG cnt;
O32_STATIC CHAR it;
it = c;
bc_disable();
ArcWrite(1, &it, 1, &cnt);
@ -33,8 +50,8 @@ void prom_putchar(char c)
char prom_getchar(void)
{
ULONG cnt;
CHAR c;
O32_STATIC ULONG cnt;
O32_STATIC CHAR c;
bc_disable();
ArcRead(0, &c, 1, &cnt);

View File

@ -1,25 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Routines to load into memory and execute stand-along program images using
* ARCS PROM firmware.
*
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
*/
#include <linux/init.h>
#include <asm/sgialib.h>
LONG __init ArcLoad(CHAR *Path, ULONG TopAddr, ULONG *ExecAddr, ULONG *LowAddr)
{
return ARC_CALL4(load, Path, TopAddr, ExecAddr, LowAddr);
}
LONG __init ArcInvoke(ULONG ExecAddr, ULONG StackAddr, ULONG Argc, CHAR *Argv[],
CHAR *Envp[])
{
return ARC_CALL5(invoke, ExecAddr, StackAddr, Argc, Argv, Envp);
}
LONG __init ArcExecute(CHAR *Path, LONG Argc, CHAR *Argv[], CHAR *Envp[])
{
return ARC_CALL4(exec, Path, Argc, Argv, Envp);
}

View File

@ -1,25 +0,0 @@
/*
* 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.
*
* Extracting time information from ARCS prom.
*
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
*/
#include <linux/init.h>
#include <asm/fw/arc/types.h>
#include <asm/sgialib.h>
struct linux_tinfo * __init
ArcGetTime(VOID)
{
return (struct linux_tinfo *) ARC_CALL0(get_tinfo);
}
ULONG __init
ArcGetRelativeTime(VOID)
{
return ARC_CALL0(get_rtime);
}

View File

@ -1,127 +0,0 @@
/*
* 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.
*
* PROM component device tree code.
*
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
* Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
* Copyright (C) 1999 Silicon Graphics, Inc.
*/
#include <linux/init.h>
#include <asm/fw/arc/types.h>
#include <asm/sgialib.h>
#undef DEBUG_PROM_TREE
pcomponent * __init
ArcGetPeer(pcomponent *Current)
{
if (Current == PROM_NULL_COMPONENT)
return PROM_NULL_COMPONENT;
return (pcomponent *) ARC_CALL1(next_component, Current);
}
pcomponent * __init
ArcGetChild(pcomponent *Current)
{
return (pcomponent *) ARC_CALL1(child_component, Current);
}
pcomponent * __init
ArcGetParent(pcomponent *Current)
{
if (Current == PROM_NULL_COMPONENT)
return PROM_NULL_COMPONENT;
return (pcomponent *) ARC_CALL1(parent_component, Current);
}
LONG __init
ArcGetConfigurationData(VOID *Buffer, pcomponent *Current)
{
return ARC_CALL2(component_data, Buffer, Current);
}
pcomponent * __init
ArcAddChild(pcomponent *Current, pcomponent *Template, VOID *ConfigurationData)
{
return (pcomponent *)
ARC_CALL3(child_add, Current, Template, ConfigurationData);
}
LONG __init
ArcDeleteComponent(pcomponent *ComponentToDelete)
{
return ARC_CALL1(comp_del, ComponentToDelete);
}
pcomponent * __init
ArcGetComponent(CHAR *Path)
{
return (pcomponent *)ARC_CALL1(component_by_path, Path);
}
#ifdef DEBUG_PROM_TREE
static char *classes[] = {
"system", "processor", "cache", "adapter", "controller", "peripheral",
"memory"
};
static char *types[] = {
"arc", "cpu", "fpu", "picache", "pdcache", "sicache", "sdcache",
"sccache", "memdev", "eisa adapter", "tc adapter", "scsi adapter",
"dti adapter", "multi-func adapter", "disk controller",
"tp controller", "cdrom controller", "worm controller",
"serial controller", "net controller", "display controller",
"parallel controller", "pointer controller", "keyboard controller",
"audio controller", "misc controller", "disk peripheral",
"floppy peripheral", "tp peripheral", "modem peripheral",
"monitor peripheral", "printer peripheral", "pointer peripheral",
"keyboard peripheral", "terminal peripheral", "line peripheral",
"net peripheral", "misc peripheral", "anonymous"
};
static char *iflags[] = {
"bogus", "read only", "removable", "console in", "console out",
"input", "output"
};
static void __init
dump_component(pcomponent *p)
{
printk("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>",
p, classes[p->class], types[p->type],
iflags[p->iflags], p->vers, p->rev);
printk("key<%08lx>\n\tamask<%08lx>cdsize<%d>ilen<%d>iname<%s>\n",
p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname);
}
static void __init
traverse(pcomponent *p, int op)
{
dump_component(p);
if(ArcGetChild(p))
traverse(ArcGetChild(p), 1);
if(ArcGetPeer(p) && op)
traverse(ArcGetPeer(p), 1);
}
void __init
prom_testtree(void)
{
pcomponent *p;
p = ArcGetChild(PROM_NULL_COMPONENT);
dump_component(p);
p = ArcGetChild(p);
while(p) {
dump_component(p);
p = ArcGetPeer(p);
}
}
#endif /* DEBUG_PROM_TREE */

View File

@ -20,9 +20,9 @@
#include <asm/smp-ops.h>
#include <asm/time.h>
static __initdata const void *fdt;
static __initdata const struct mips_machine *mach;
static __initdata const void *mach_match_data;
static __initconst const void *fdt;
static __initconst const struct mips_machine *mach;
static __initconst const void *mach_match_data;
void __init prom_init(void)
{

View File

@ -20,157 +20,176 @@
#include <asm/compiler.h>
#include <asm/cpu-features.h>
#include <asm/cmpxchg.h>
#include <asm/llsc.h>
#include <asm/sync.h>
#include <asm/war.h>
/*
* Using a branch-likely instruction to check the result of an sc instruction
* works around a bug present in R10000 CPUs prior to revision 3.0 that could
* cause ll-sc sequences to execute non-atomically.
*/
#if R10000_LLSC_WAR
# define __scbeqz "beqzl"
#else
# define __scbeqz "beqz"
#define ATOMIC_OPS(pfx, type) \
static __always_inline type pfx##_read(const pfx##_t *v) \
{ \
return READ_ONCE(v->counter); \
} \
\
static __always_inline void pfx##_set(pfx##_t *v, type i) \
{ \
WRITE_ONCE(v->counter, i); \
} \
\
static __always_inline type pfx##_cmpxchg(pfx##_t *v, type o, type n) \
{ \
return cmpxchg(&v->counter, o, n); \
} \
\
static __always_inline type pfx##_xchg(pfx##_t *v, type n) \
{ \
return xchg(&v->counter, n); \
}
#define ATOMIC_INIT(i) { (i) }
ATOMIC_OPS(atomic, int)
#ifdef CONFIG_64BIT
# define ATOMIC64_INIT(i) { (i) }
ATOMIC_OPS(atomic64, s64)
#endif
#define ATOMIC_INIT(i) { (i) }
/*
* atomic_read - read atomic variable
* @v: pointer of type atomic_t
*
* Atomically reads the value of @v.
*/
#define atomic_read(v) READ_ONCE((v)->counter)
/*
* atomic_set - set atomic variable
* @v: pointer of type atomic_t
* @i: required value
*
* Atomically sets the value of @v to @i.
*/
#define atomic_set(v, i) WRITE_ONCE((v)->counter, (i))
#define ATOMIC_OP(op, c_op, asm_op) \
static __inline__ void atomic_##op(int i, atomic_t * v) \
{ \
if (kernel_uses_llsc) { \
int temp; \
\
loongson_llsc_mb(); \
__asm__ __volatile__( \
" .set push \n" \
" .set "MIPS_ISA_LEVEL" \n" \
"1: ll %0, %1 # atomic_" #op " \n" \
" " #asm_op " %0, %2 \n" \
" sc %0, %1 \n" \
"\t" __scbeqz " %0, 1b \n" \
" .set pop \n" \
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \
: "Ir" (i) : __LLSC_CLOBBER); \
} else { \
unsigned long flags; \
\
raw_local_irq_save(flags); \
v->counter c_op i; \
raw_local_irq_restore(flags); \
} \
#define ATOMIC_OP(pfx, op, type, c_op, asm_op, ll, sc) \
static __inline__ void pfx##_##op(type i, pfx##_t * v) \
{ \
type temp; \
\
if (!kernel_uses_llsc) { \
unsigned long flags; \
\
raw_local_irq_save(flags); \
v->counter c_op i; \
raw_local_irq_restore(flags); \
return; \
} \
\
__asm__ __volatile__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" " __SYNC(full, loongson3_war) " \n" \
"1: " #ll " %0, %1 # " #pfx "_" #op " \n" \
" " #asm_op " %0, %2 \n" \
" " #sc " %0, %1 \n" \
"\t" __SC_BEQZ "%0, 1b \n" \
" .set pop \n" \
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \
: "Ir" (i) : __LLSC_CLOBBER); \
}
#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
static __inline__ int atomic_##op##_return_relaxed(int i, atomic_t * v) \
{ \
int result; \
\
if (kernel_uses_llsc) { \
int temp; \
\
loongson_llsc_mb(); \
__asm__ __volatile__( \
" .set push \n" \
" .set "MIPS_ISA_LEVEL" \n" \
"1: ll %1, %2 # atomic_" #op "_return \n" \
" " #asm_op " %0, %1, %3 \n" \
" sc %0, %2 \n" \
"\t" __scbeqz " %0, 1b \n" \
" " #asm_op " %0, %1, %3 \n" \
" .set pop \n" \
: "=&r" (result), "=&r" (temp), \
"+" GCC_OFF_SMALL_ASM() (v->counter) \
: "Ir" (i) : __LLSC_CLOBBER); \
} else { \
unsigned long flags; \
\
raw_local_irq_save(flags); \
result = v->counter; \
result c_op i; \
v->counter = result; \
raw_local_irq_restore(flags); \
} \
\
return result; \
#define ATOMIC_OP_RETURN(pfx, op, type, c_op, asm_op, ll, sc) \
static __inline__ type pfx##_##op##_return_relaxed(type i, pfx##_t * v) \
{ \
type temp, result; \
\
if (!kernel_uses_llsc) { \
unsigned long flags; \
\
raw_local_irq_save(flags); \
result = v->counter; \
result c_op i; \
v->counter = result; \
raw_local_irq_restore(flags); \
return result; \
} \
\
__asm__ __volatile__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" " __SYNC(full, loongson3_war) " \n" \
"1: " #ll " %1, %2 # " #pfx "_" #op "_return\n" \
" " #asm_op " %0, %1, %3 \n" \
" " #sc " %0, %2 \n" \
"\t" __SC_BEQZ "%0, 1b \n" \
" " #asm_op " %0, %1, %3 \n" \
" .set pop \n" \
: "=&r" (result), "=&r" (temp), \
"+" GCC_OFF_SMALL_ASM() (v->counter) \
: "Ir" (i) : __LLSC_CLOBBER); \
\
return result; \
}
#define ATOMIC_FETCH_OP(op, c_op, asm_op) \
static __inline__ int atomic_fetch_##op##_relaxed(int i, atomic_t * v) \
{ \
int result; \
\
if (kernel_uses_llsc) { \
int temp; \
\
loongson_llsc_mb(); \
__asm__ __volatile__( \
" .set push \n" \
" .set "MIPS_ISA_LEVEL" \n" \
"1: ll %1, %2 # atomic_fetch_" #op " \n" \
" " #asm_op " %0, %1, %3 \n" \
" sc %0, %2 \n" \
"\t" __scbeqz " %0, 1b \n" \
" .set pop \n" \
" move %0, %1 \n" \
: "=&r" (result), "=&r" (temp), \
"+" GCC_OFF_SMALL_ASM() (v->counter) \
: "Ir" (i) : __LLSC_CLOBBER); \
} else { \
unsigned long flags; \
\
raw_local_irq_save(flags); \
result = v->counter; \
v->counter c_op i; \
raw_local_irq_restore(flags); \
} \
\
return result; \
#define ATOMIC_FETCH_OP(pfx, op, type, c_op, asm_op, ll, sc) \
static __inline__ type pfx##_fetch_##op##_relaxed(type i, pfx##_t * v) \
{ \
int temp, result; \
\
if (!kernel_uses_llsc) { \
unsigned long flags; \
\
raw_local_irq_save(flags); \
result = v->counter; \
v->counter c_op i; \
raw_local_irq_restore(flags); \
return result; \
} \
\
__asm__ __volatile__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" " __SYNC(full, loongson3_war) " \n" \
"1: " #ll " %1, %2 # " #pfx "_fetch_" #op "\n" \
" " #asm_op " %0, %1, %3 \n" \
" " #sc " %0, %2 \n" \
"\t" __SC_BEQZ "%0, 1b \n" \
" .set pop \n" \
" move %0, %1 \n" \
: "=&r" (result), "=&r" (temp), \
"+" GCC_OFF_SMALL_ASM() (v->counter) \
: "Ir" (i) : __LLSC_CLOBBER); \
\
return result; \
}
#define ATOMIC_OPS(op, c_op, asm_op) \
ATOMIC_OP(op, c_op, asm_op) \
ATOMIC_OP_RETURN(op, c_op, asm_op) \
ATOMIC_FETCH_OP(op, c_op, asm_op)
#undef ATOMIC_OPS
#define ATOMIC_OPS(pfx, op, type, c_op, asm_op, ll, sc) \
ATOMIC_OP(pfx, op, type, c_op, asm_op, ll, sc) \
ATOMIC_OP_RETURN(pfx, op, type, c_op, asm_op, ll, sc) \
ATOMIC_FETCH_OP(pfx, op, type, c_op, asm_op, ll, sc)
ATOMIC_OPS(add, +=, addu)
ATOMIC_OPS(sub, -=, subu)
ATOMIC_OPS(atomic, add, int, +=, addu, ll, sc)
ATOMIC_OPS(atomic, sub, int, -=, subu, ll, sc)
#define atomic_add_return_relaxed atomic_add_return_relaxed
#define atomic_sub_return_relaxed atomic_sub_return_relaxed
#define atomic_fetch_add_relaxed atomic_fetch_add_relaxed
#define atomic_fetch_sub_relaxed atomic_fetch_sub_relaxed
#undef ATOMIC_OPS
#define ATOMIC_OPS(op, c_op, asm_op) \
ATOMIC_OP(op, c_op, asm_op) \
ATOMIC_FETCH_OP(op, c_op, asm_op)
#ifdef CONFIG_64BIT
ATOMIC_OPS(atomic64, add, s64, +=, daddu, lld, scd)
ATOMIC_OPS(atomic64, sub, s64, -=, dsubu, lld, scd)
# define atomic64_add_return_relaxed atomic64_add_return_relaxed
# define atomic64_sub_return_relaxed atomic64_sub_return_relaxed
# define atomic64_fetch_add_relaxed atomic64_fetch_add_relaxed
# define atomic64_fetch_sub_relaxed atomic64_fetch_sub_relaxed
#endif /* CONFIG_64BIT */
ATOMIC_OPS(and, &=, and)
ATOMIC_OPS(or, |=, or)
ATOMIC_OPS(xor, ^=, xor)
#undef ATOMIC_OPS
#define ATOMIC_OPS(pfx, op, type, c_op, asm_op, ll, sc) \
ATOMIC_OP(pfx, op, type, c_op, asm_op, ll, sc) \
ATOMIC_FETCH_OP(pfx, op, type, c_op, asm_op, ll, sc)
ATOMIC_OPS(atomic, and, int, &=, and, ll, sc)
ATOMIC_OPS(atomic, or, int, |=, or, ll, sc)
ATOMIC_OPS(atomic, xor, int, ^=, xor, ll, sc)
#define atomic_fetch_and_relaxed atomic_fetch_and_relaxed
#define atomic_fetch_or_relaxed atomic_fetch_or_relaxed
#define atomic_fetch_xor_relaxed atomic_fetch_xor_relaxed
#ifdef CONFIG_64BIT
ATOMIC_OPS(atomic64, and, s64, &=, and, lld, scd)
ATOMIC_OPS(atomic64, or, s64, |=, or, lld, scd)
ATOMIC_OPS(atomic64, xor, s64, ^=, xor, lld, scd)
# define atomic64_fetch_and_relaxed atomic64_fetch_and_relaxed
# define atomic64_fetch_or_relaxed atomic64_fetch_or_relaxed
# define atomic64_fetch_xor_relaxed atomic64_fetch_xor_relaxed
#endif
#undef ATOMIC_OPS
#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
@ -184,258 +203,66 @@ ATOMIC_OPS(xor, ^=, xor)
* Atomically test @v and subtract @i if @v is greater or equal than @i.
* The function returns the old value of @v minus @i.
*/
static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
{
int result;
smp_mb__before_llsc();
if (kernel_uses_llsc) {
int temp;
loongson_llsc_mb();
__asm__ __volatile__(
" .set push \n"
" .set "MIPS_ISA_LEVEL" \n"
"1: ll %1, %2 # atomic_sub_if_positive\n"
" .set pop \n"
" subu %0, %1, %3 \n"
" move %1, %0 \n"
" bltz %0, 2f \n"
" .set push \n"
" .set "MIPS_ISA_LEVEL" \n"
" sc %1, %2 \n"
"\t" __scbeqz " %1, 1b \n"
"2: \n"
" .set pop \n"
: "=&r" (result), "=&r" (temp),
"+" GCC_OFF_SMALL_ASM() (v->counter)
: "Ir" (i) : __LLSC_CLOBBER);
} else {
unsigned long flags;
raw_local_irq_save(flags);
result = v->counter;
result -= i;
if (result >= 0)
v->counter = result;
raw_local_irq_restore(flags);
}
smp_llsc_mb();
return result;
#define ATOMIC_SIP_OP(pfx, type, op, ll, sc) \
static __inline__ int pfx##_sub_if_positive(type i, pfx##_t * v) \
{ \
type temp, result; \
\
smp_mb__before_atomic(); \
\
if (!kernel_uses_llsc) { \
unsigned long flags; \
\
raw_local_irq_save(flags); \
result = v->counter; \
result -= i; \
if (result >= 0) \
v->counter = result; \
raw_local_irq_restore(flags); \
smp_mb__after_atomic(); \
return result; \
} \
\
__asm__ __volatile__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" " __SYNC(full, loongson3_war) " \n" \
"1: " #ll " %1, %2 # atomic_sub_if_positive\n" \
" .set pop \n" \
" " #op " %0, %1, %3 \n" \
" move %1, %0 \n" \
" bltz %0, 2f \n" \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" " #sc " %1, %2 \n" \
" " __SC_BEQZ "%1, 1b \n" \
"2: " __SYNC(full, loongson3_war) " \n" \
" .set pop \n" \
: "=&r" (result), "=&r" (temp), \
"+" GCC_OFF_SMALL_ASM() (v->counter) \
: "Ir" (i) \
: __LLSC_CLOBBER); \
\
/* \
* In the Loongson3 workaround case we already have a \
* completion barrier at 2: above, which is needed due to the \
* bltz that can branch to code outside of the LL/SC loop. As \
* such, we don't need to emit another barrier here. \
*/ \
if (!__SYNC_loongson3_war) \
smp_mb__after_atomic(); \
\
return result; \
}
#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
#define atomic_xchg(v, new) (xchg(&((v)->counter), (new)))
/*
* atomic_dec_if_positive - decrement by 1 if old value positive
* @v: pointer of type atomic_t
*/
ATOMIC_SIP_OP(atomic, int, subu, ll, sc)
#define atomic_dec_if_positive(v) atomic_sub_if_positive(1, v)
#ifdef CONFIG_64BIT
#define ATOMIC64_INIT(i) { (i) }
/*
* atomic64_read - read atomic variable
* @v: pointer of type atomic64_t
*
*/
#define atomic64_read(v) READ_ONCE((v)->counter)
/*
* atomic64_set - set atomic variable
* @v: pointer of type atomic64_t
* @i: required value
*/
#define atomic64_set(v, i) WRITE_ONCE((v)->counter, (i))
#define ATOMIC64_OP(op, c_op, asm_op) \
static __inline__ void atomic64_##op(s64 i, atomic64_t * v) \
{ \
if (kernel_uses_llsc) { \
s64 temp; \
\
loongson_llsc_mb(); \
__asm__ __volatile__( \
" .set push \n" \
" .set "MIPS_ISA_LEVEL" \n" \
"1: lld %0, %1 # atomic64_" #op " \n" \
" " #asm_op " %0, %2 \n" \
" scd %0, %1 \n" \
"\t" __scbeqz " %0, 1b \n" \
" .set pop \n" \
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \
: "Ir" (i) : __LLSC_CLOBBER); \
} else { \
unsigned long flags; \
\
raw_local_irq_save(flags); \
v->counter c_op i; \
raw_local_irq_restore(flags); \
} \
}
#define ATOMIC64_OP_RETURN(op, c_op, asm_op) \
static __inline__ s64 atomic64_##op##_return_relaxed(s64 i, atomic64_t * v) \
{ \
s64 result; \
\
if (kernel_uses_llsc) { \
s64 temp; \
\
loongson_llsc_mb(); \
__asm__ __volatile__( \
" .set push \n" \
" .set "MIPS_ISA_LEVEL" \n" \
"1: lld %1, %2 # atomic64_" #op "_return\n" \
" " #asm_op " %0, %1, %3 \n" \
" scd %0, %2 \n" \
"\t" __scbeqz " %0, 1b \n" \
" " #asm_op " %0, %1, %3 \n" \
" .set pop \n" \
: "=&r" (result), "=&r" (temp), \
"+" GCC_OFF_SMALL_ASM() (v->counter) \
: "Ir" (i) : __LLSC_CLOBBER); \
} else { \
unsigned long flags; \
\
raw_local_irq_save(flags); \
result = v->counter; \
result c_op i; \
v->counter = result; \
raw_local_irq_restore(flags); \
} \
\
return result; \
}
#define ATOMIC64_FETCH_OP(op, c_op, asm_op) \
static __inline__ s64 atomic64_fetch_##op##_relaxed(s64 i, atomic64_t * v) \
{ \
s64 result; \
\
if (kernel_uses_llsc) { \
s64 temp; \
\
loongson_llsc_mb(); \
__asm__ __volatile__( \
" .set push \n" \
" .set "MIPS_ISA_LEVEL" \n" \
"1: lld %1, %2 # atomic64_fetch_" #op "\n" \
" " #asm_op " %0, %1, %3 \n" \
" scd %0, %2 \n" \
"\t" __scbeqz " %0, 1b \n" \
" move %0, %1 \n" \
" .set pop \n" \
: "=&r" (result), "=&r" (temp), \
"+" GCC_OFF_SMALL_ASM() (v->counter) \
: "Ir" (i) : __LLSC_CLOBBER); \
} else { \
unsigned long flags; \
\
raw_local_irq_save(flags); \
result = v->counter; \
v->counter c_op i; \
raw_local_irq_restore(flags); \
} \
\
return result; \
}
#define ATOMIC64_OPS(op, c_op, asm_op) \
ATOMIC64_OP(op, c_op, asm_op) \
ATOMIC64_OP_RETURN(op, c_op, asm_op) \
ATOMIC64_FETCH_OP(op, c_op, asm_op)
ATOMIC64_OPS(add, +=, daddu)
ATOMIC64_OPS(sub, -=, dsubu)
#define atomic64_add_return_relaxed atomic64_add_return_relaxed
#define atomic64_sub_return_relaxed atomic64_sub_return_relaxed
#define atomic64_fetch_add_relaxed atomic64_fetch_add_relaxed
#define atomic64_fetch_sub_relaxed atomic64_fetch_sub_relaxed
#undef ATOMIC64_OPS
#define ATOMIC64_OPS(op, c_op, asm_op) \
ATOMIC64_OP(op, c_op, asm_op) \
ATOMIC64_FETCH_OP(op, c_op, asm_op)
ATOMIC64_OPS(and, &=, and)
ATOMIC64_OPS(or, |=, or)
ATOMIC64_OPS(xor, ^=, xor)
#define atomic64_fetch_and_relaxed atomic64_fetch_and_relaxed
#define atomic64_fetch_or_relaxed atomic64_fetch_or_relaxed
#define atomic64_fetch_xor_relaxed atomic64_fetch_xor_relaxed
#undef ATOMIC64_OPS
#undef ATOMIC64_FETCH_OP
#undef ATOMIC64_OP_RETURN
#undef ATOMIC64_OP
/*
* atomic64_sub_if_positive - conditionally subtract integer from atomic
* variable
* @i: integer value to subtract
* @v: pointer of type atomic64_t
*
* Atomically test @v and subtract @i if @v is greater or equal than @i.
* The function returns the old value of @v minus @i.
*/
static __inline__ s64 atomic64_sub_if_positive(s64 i, atomic64_t * v)
{
s64 result;
smp_mb__before_llsc();
if (kernel_uses_llsc) {
s64 temp;
__asm__ __volatile__(
" .set push \n"
" .set "MIPS_ISA_LEVEL" \n"
"1: lld %1, %2 # atomic64_sub_if_positive\n"
" dsubu %0, %1, %3 \n"
" move %1, %0 \n"
" bltz %0, 1f \n"
" scd %1, %2 \n"
"\t" __scbeqz " %1, 1b \n"
"1: \n"
" .set pop \n"
: "=&r" (result), "=&r" (temp),
"+" GCC_OFF_SMALL_ASM() (v->counter)
: "Ir" (i));
} else {
unsigned long flags;
raw_local_irq_save(flags);
result = v->counter;
result -= i;
if (result >= 0)
v->counter = result;
raw_local_irq_restore(flags);
}
smp_llsc_mb();
return result;
}
#define atomic64_cmpxchg(v, o, n) \
((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
#define atomic64_xchg(v, new) (xchg(&((v)->counter), (new)))
/*
* atomic64_dec_if_positive - decrement by 1 if old value positive
* @v: pointer of type atomic64_t
*/
ATOMIC_SIP_OP(atomic64, s64, dsubu, lld, scd)
#define atomic64_dec_if_positive(v) atomic64_sub_if_positive(1, v)
#endif
#endif /* CONFIG_64BIT */
#undef ATOMIC_SIP_OP
#endif /* _ASM_ATOMIC_H */

View File

@ -9,131 +9,26 @@
#define __ASM_BARRIER_H
#include <asm/addrspace.h>
#include <asm/sync.h>
/*
* Sync types defined by the MIPS architecture (document MD00087 table 6.5)
* These values are used with the sync instruction to perform memory barriers.
* Types of ordering guarantees available through the SYNC instruction:
* - Completion Barriers
* - Ordering Barriers
* As compared to the completion barrier, the ordering barrier is a
* lighter-weight operation as it does not require the specified instructions
* before the SYNC to be already completed. Instead it only requires that those
* specified instructions which are subsequent to the SYNC in the instruction
* stream are never re-ordered for processing ahead of the specified
* instructions which are before the SYNC in the instruction stream.
* This potentially reduces how many cycles the barrier instruction must stall
* before it completes.
* Implementations that do not use any of the non-zero values of stype to define
* different barriers, such as ordering barriers, must make those stype values
* act the same as stype zero.
*/
static inline void __sync(void)
{
asm volatile(__SYNC(full, always) ::: "memory");
}
/*
* Completion barriers:
* - Every synchronizable specified memory instruction (loads or stores or both)
* that occurs in the instruction stream before the SYNC instruction must be
* already globally performed before any synchronizable specified memory
* instructions that occur after the SYNC are allowed to be performed, with
* respect to any other processor or coherent I/O module.
*
* - The barrier does not guarantee the order in which instruction fetches are
* performed.
*
* - A stype value of zero will always be defined such that it performs the most
* complete set of synchronization operations that are defined.This means
* stype zero always does a completion barrier that affects both loads and
* stores preceding the SYNC instruction and both loads and stores that are
* subsequent to the SYNC instruction. Non-zero values of stype may be defined
* by the architecture or specific implementations to perform synchronization
* behaviors that are less complete than that of stype zero. If an
* implementation does not use one of these non-zero values to define a
* different synchronization behavior, then that non-zero value of stype must
* act the same as stype zero completion barrier. This allows software written
* for an implementation with a lighter-weight barrier to work on another
* implementation which only implements the stype zero completion barrier.
*
* - A completion barrier is required, potentially in conjunction with SSNOP (in
* Release 1 of the Architecture) or EHB (in Release 2 of the Architecture),
* to guarantee that memory reference results are visible across operating
* mode changes. For example, a completion barrier is required on some
* implementations on entry to and exit from Debug Mode to guarantee that
* memory effects are handled correctly.
*/
static inline void rmb(void)
{
asm volatile(__SYNC(rmb, always) ::: "memory");
}
#define rmb rmb
/*
* stype 0 - A completion barrier that affects preceding loads and stores and
* subsequent loads and stores.
* Older instructions which must reach the load/store ordering point before the
* SYNC instruction completes: Loads, Stores
* Younger instructions which must reach the load/store ordering point only
* after the SYNC instruction completes: Loads, Stores
* Older instructions which must be globally performed when the SYNC instruction
* completes: Loads, Stores
*/
#define STYPE_SYNC 0x0
static inline void wmb(void)
{
asm volatile(__SYNC(wmb, always) ::: "memory");
}
#define wmb wmb
/*
* Ordering barriers:
* - Every synchronizable specified memory instruction (loads or stores or both)
* that occurs in the instruction stream before the SYNC instruction must
* reach a stage in the load/store datapath after which no instruction
* re-ordering is possible before any synchronizable specified memory
* instruction which occurs after the SYNC instruction in the instruction
* stream reaches the same stage in the load/store datapath.
*
* - If any memory instruction before the SYNC instruction in program order,
* generates a memory request to the external memory and any memory
* instruction after the SYNC instruction in program order also generates a
* memory request to external memory, the memory request belonging to the
* older instruction must be globally performed before the time the memory
* request belonging to the younger instruction is globally performed.
*
* - The barrier does not guarantee the order in which instruction fetches are
* performed.
*/
/*
* stype 0x10 - An ordering barrier that affects preceding loads and stores and
* subsequent loads and stores.
* Older instructions which must reach the load/store ordering point before the
* SYNC instruction completes: Loads, Stores
* Younger instructions which must reach the load/store ordering point only
* after the SYNC instruction completes: Loads, Stores
* Older instructions which must be globally performed when the SYNC instruction
* completes: N/A
*/
#define STYPE_SYNC_MB 0x10
/*
* stype 0x14 - A completion barrier specific to global invalidations
*
* When a sync instruction of this type completes any preceding GINVI or GINVT
* operation has been globalized & completed on all coherent CPUs. Anything
* that the GINV* instruction should invalidate will have been invalidated on
* all coherent CPUs when this instruction completes. It is implementation
* specific whether the GINV* instructions themselves will ensure completion,
* or this sync type will.
*
* In systems implementing global invalidates (ie. with Config5.GI == 2 or 3)
* this sync type also requires that previous SYNCI operations have completed.
*/
#define STYPE_GINV 0x14
#ifdef CONFIG_CPU_HAS_SYNC
#define __sync() \
__asm__ __volatile__( \
".set push\n\t" \
".set noreorder\n\t" \
".set mips2\n\t" \
"sync\n\t" \
".set pop" \
: /* no output */ \
: /* no input */ \
: "memory")
#else
#define __sync() do { } while(0)
#endif
#define fast_mb() __sync()
#define __fast_iob() \
__asm__ __volatile__( \
@ -146,17 +41,8 @@
: "m" (*(int *)CKSEG1) \
: "memory")
#ifdef CONFIG_CPU_CAVIUM_OCTEON
# define OCTEON_SYNCW_STR ".set push\n.set arch=octeon\nsyncw\nsyncw\n.set pop\n"
# define __syncw() __asm__ __volatile__(OCTEON_SYNCW_STR : : : "memory")
# define fast_wmb() __syncw()
# define fast_rmb() barrier()
# define fast_mb() __sync()
# define fast_iob() do { } while (0)
#else /* ! CONFIG_CPU_CAVIUM_OCTEON */
# define fast_wmb() __sync()
# define fast_rmb() __sync()
# define fast_mb() __sync()
# ifdef CONFIG_SGI_IP28
# define fast_iob() \
__asm__ __volatile__( \
@ -192,23 +78,14 @@
#endif /* !CONFIG_CPU_HAS_WB */
#define wmb() fast_wmb()
#define rmb() fast_rmb()
#if defined(CONFIG_WEAK_ORDERING)
# ifdef CONFIG_CPU_CAVIUM_OCTEON
# define __smp_mb() __sync()
# define __smp_rmb() barrier()
# define __smp_wmb() __syncw()
# else
# define __smp_mb() __asm__ __volatile__("sync" : : :"memory")
# define __smp_rmb() __asm__ __volatile__("sync" : : :"memory")
# define __smp_wmb() __asm__ __volatile__("sync" : : :"memory")
# endif
# define __smp_mb() __sync()
# define __smp_rmb() rmb()
# define __smp_wmb() wmb()
#else
#define __smp_mb() barrier()
#define __smp_rmb() barrier()
#define __smp_wmb() barrier()
# define __smp_mb() barrier()
# define __smp_rmb() barrier()
# define __smp_wmb() barrier()
#endif
/*
@ -218,13 +95,14 @@
* ordering will be done by smp_llsc_mb() and friends.
*/
#if defined(CONFIG_WEAK_REORDERING_BEYOND_LLSC) && defined(CONFIG_SMP)
#define __WEAK_LLSC_MB " sync \n"
#define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
#define __LLSC_CLOBBER
# define __WEAK_LLSC_MB sync
# define smp_llsc_mb() \
__asm__ __volatile__(__stringify(__WEAK_LLSC_MB) : : :"memory")
# define __LLSC_CLOBBER
#else
#define __WEAK_LLSC_MB " \n"
#define smp_llsc_mb() do { } while (0)
#define __LLSC_CLOBBER "memory"
# define __WEAK_LLSC_MB
# define smp_llsc_mb() do { } while (0)
# define __LLSC_CLOBBER "memory"
#endif
#ifdef CONFIG_CPU_CAVIUM_OCTEON
@ -241,52 +119,22 @@
#define nudge_writes() mb()
#endif
#define __smp_mb__before_atomic() __smp_mb__before_llsc()
#define __smp_mb__after_atomic() smp_llsc_mb()
/*
* Some Loongson 3 CPUs have a bug wherein execution of a memory access (load,
* store or prefetch) in between an LL & SC can cause the SC instruction to
* erroneously succeed, breaking atomicity. Whilst it's unusual to write code
* containing such sequences, this bug bites harder than we might otherwise
* expect due to reordering & speculation:
*
* 1) A memory access appearing prior to the LL in program order may actually
* be executed after the LL - this is the reordering case.
*
* In order to avoid this we need to place a memory barrier (ie. a SYNC
* instruction) prior to every LL instruction, in between it and any earlier
* memory access instructions.
*
* This reordering case is fixed by 3A R2 CPUs, ie. 3A2000 models and later.
*
* 2) If a conditional branch exists between an LL & SC with a target outside
* of the LL-SC loop, for example an exit upon value mismatch in cmpxchg()
* or similar, then misprediction of the branch may allow speculative
* execution of memory accesses from outside of the LL-SC loop.
*
* In order to avoid this we need a memory barrier (ie. a SYNC instruction)
* at each affected branch target, for which we also use loongson_llsc_mb()
* defined below.
*
* This case affects all current Loongson 3 CPUs.
*
* The above described cases cause an error in the cache coherence protocol;
* such that the Invalidate of a competing LL-SC goes 'missing' and SC
* erroneously observes its core still has Exclusive state and lets the SC
* proceed.
*
* Therefore the error only occurs on SMP systems.
* In the Loongson3 LL/SC workaround case, all of our LL/SC loops already have
* a completion barrier immediately preceding the LL instruction. Therefore we
* can skip emitting a barrier from __smp_mb__before_atomic().
*/
#ifdef CONFIG_CPU_LOONGSON3_WORKAROUNDS /* Loongson-3's LLSC workaround */
#define loongson_llsc_mb() __asm__ __volatile__("sync" : : :"memory")
#ifdef CONFIG_CPU_LOONGSON3_WORKAROUNDS
# define __smp_mb__before_atomic()
#else
#define loongson_llsc_mb() do { } while (0)
# define __smp_mb__before_atomic() __smp_mb__before_llsc()
#endif
#define __smp_mb__after_atomic() smp_llsc_mb()
static inline void sync_ginv(void)
{
asm volatile("sync\t%0" :: "i"(STYPE_GINV));
asm volatile(__SYNC(ginv, always));
}
#include <asm-generic/barrier.h>

View File

@ -13,16 +13,55 @@
#error only <linux/bitops.h> can be included directly
#endif
#include <linux/bits.h>
#include <linux/compiler.h>
#include <linux/types.h>
#include <asm/barrier.h>
#include <asm/byteorder.h> /* sigh ... */
#include <asm/compiler.h>
#include <asm/cpu-features.h>
#include <asm/isa-rev.h>
#include <asm/llsc.h>
#include <asm/sgidefs.h>
#include <asm/war.h>
#define __bit_op(mem, insn, inputs...) do { \
unsigned long temp; \
\
asm volatile( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" " __SYNC(full, loongson3_war) " \n" \
"1: " __LL "%0, %1 \n" \
" " insn " \n" \
" " __SC "%0, %1 \n" \
" " __SC_BEQZ "%0, 1b \n" \
" .set pop \n" \
: "=&r"(temp), "+" GCC_OFF_SMALL_ASM()(mem) \
: inputs \
: __LLSC_CLOBBER); \
} while (0)
#define __test_bit_op(mem, ll_dst, insn, inputs...) ({ \
unsigned long orig, temp; \
\
asm volatile( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" " __SYNC(full, loongson3_war) " \n" \
"1: " __LL ll_dst ", %2 \n" \
" " insn " \n" \
" " __SC "%1, %2 \n" \
" " __SC_BEQZ "%1, 1b \n" \
" .set pop \n" \
: "=&r"(orig), "=&r"(temp), \
"+" GCC_OFF_SMALL_ASM()(mem) \
: inputs \
: __LLSC_CLOBBER); \
\
orig; \
})
/*
* These are the "slower" versions of the functions and are in bitops.c.
* These functions call raw_local_irq_{save,restore}().
@ -30,8 +69,6 @@
void __mips_set_bit(unsigned long nr, volatile unsigned long *addr);
void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr);
void __mips_change_bit(unsigned long nr, volatile unsigned long *addr);
int __mips_test_and_set_bit(unsigned long nr,
volatile unsigned long *addr);
int __mips_test_and_set_bit_lock(unsigned long nr,
volatile unsigned long *addr);
int __mips_test_and_clear_bit(unsigned long nr,
@ -52,51 +89,20 @@ int __mips_test_and_change_bit(unsigned long nr,
*/
static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
int bit = nr & SZLONG_MASK;
unsigned long temp;
volatile unsigned long *m = &addr[BIT_WORD(nr)];
int bit = nr % BITS_PER_LONG;
if (kernel_uses_llsc && R10000_LLSC_WAR) {
__asm__ __volatile__(
" .set push \n"
" .set arch=r4000 \n"
"1: " __LL "%0, %1 # set_bit \n"
" or %0, %2 \n"
" " __SC "%0, %1 \n"
" beqzl %0, 1b \n"
" .set pop \n"
: "=&r" (temp), "=" GCC_OFF_SMALL_ASM() (*m)
: "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m)
: __LLSC_CLOBBER);
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
loongson_llsc_mb();
do {
__asm__ __volatile__(
" " __LL "%0, %1 # set_bit \n"
" " __INS "%0, %3, %2, 1 \n"
" " __SC "%0, %1 \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
: "ir" (bit), "r" (~0)
: __LLSC_CLOBBER);
} while (unlikely(!temp));
#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
} else if (kernel_uses_llsc) {
loongson_llsc_mb();
do {
__asm__ __volatile__(
" .set push \n"
" .set "MIPS_ISA_ARCH_LEVEL" \n"
" " __LL "%0, %1 # set_bit \n"
" or %0, %2 \n"
" " __SC "%0, %1 \n"
" .set pop \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
: "ir" (1UL << bit)
: __LLSC_CLOBBER);
} while (unlikely(!temp));
} else
if (!kernel_uses_llsc) {
__mips_set_bit(nr, addr);
return;
}
if ((MIPS_ISA_REV >= 2) && __builtin_constant_p(bit) && (bit >= 16)) {
__bit_op(*m, __INS "%0, %3, %2, 1", "i"(bit), "r"(~0));
return;
}
__bit_op(*m, "or\t%0, %2", "ir"(BIT(bit)));
}
/*
@ -111,51 +117,20 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
*/
static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
int bit = nr & SZLONG_MASK;
unsigned long temp;
volatile unsigned long *m = &addr[BIT_WORD(nr)];
int bit = nr % BITS_PER_LONG;
if (kernel_uses_llsc && R10000_LLSC_WAR) {
__asm__ __volatile__(
" .set push \n"
" .set arch=r4000 \n"
"1: " __LL "%0, %1 # clear_bit \n"
" and %0, %2 \n"
" " __SC "%0, %1 \n"
" beqzl %0, 1b \n"
" .set pop \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
: "ir" (~(1UL << bit))
: __LLSC_CLOBBER);
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
loongson_llsc_mb();
do {
__asm__ __volatile__(
" " __LL "%0, %1 # clear_bit \n"
" " __INS "%0, $0, %2, 1 \n"
" " __SC "%0, %1 \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
: "ir" (bit)
: __LLSC_CLOBBER);
} while (unlikely(!temp));
#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
} else if (kernel_uses_llsc) {
loongson_llsc_mb();
do {
__asm__ __volatile__(
" .set push \n"
" .set "MIPS_ISA_ARCH_LEVEL" \n"
" " __LL "%0, %1 # clear_bit \n"
" and %0, %2 \n"
" " __SC "%0, %1 \n"
" .set pop \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
: "ir" (~(1UL << bit))
: __LLSC_CLOBBER);
} while (unlikely(!temp));
} else
if (!kernel_uses_llsc) {
__mips_clear_bit(nr, addr);
return;
}
if ((MIPS_ISA_REV >= 2) && __builtin_constant_p(bit)) {
__bit_op(*m, __INS "%0, $0, %2, 1", "i"(bit));
return;
}
__bit_op(*m, "and\t%0, %2", "ir"(~BIT(bit)));
}
/*
@ -183,101 +158,15 @@ static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *ad
*/
static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
{
int bit = nr & SZLONG_MASK;
volatile unsigned long *m = &addr[BIT_WORD(nr)];
int bit = nr % BITS_PER_LONG;
if (kernel_uses_llsc && R10000_LLSC_WAR) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
__asm__ __volatile__(
" .set push \n"
" .set arch=r4000 \n"
"1: " __LL "%0, %1 # change_bit \n"
" xor %0, %2 \n"
" " __SC "%0, %1 \n"
" beqzl %0, 1b \n"
" .set pop \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
: "ir" (1UL << bit)
: __LLSC_CLOBBER);
} else if (kernel_uses_llsc) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
loongson_llsc_mb();
do {
__asm__ __volatile__(
" .set push \n"
" .set "MIPS_ISA_ARCH_LEVEL" \n"
" " __LL "%0, %1 # change_bit \n"
" xor %0, %2 \n"
" " __SC "%0, %1 \n"
" .set pop \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
: "ir" (1UL << bit)
: __LLSC_CLOBBER);
} while (unlikely(!temp));
} else
if (!kernel_uses_llsc) {
__mips_change_bit(nr, addr);
}
return;
}
/*
* test_and_set_bit - Set a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
static inline int test_and_set_bit(unsigned long nr,
volatile unsigned long *addr)
{
int bit = nr & SZLONG_MASK;
unsigned long res;
smp_mb__before_llsc();
if (kernel_uses_llsc && R10000_LLSC_WAR) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
__asm__ __volatile__(
" .set push \n"
" .set arch=r4000 \n"
"1: " __LL "%0, %1 # test_and_set_bit \n"
" or %2, %0, %3 \n"
" " __SC "%2, %1 \n"
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
" .set pop \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
: "r" (1UL << bit)
: __LLSC_CLOBBER);
} else if (kernel_uses_llsc) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
loongson_llsc_mb();
do {
__asm__ __volatile__(
" .set push \n"
" .set "MIPS_ISA_ARCH_LEVEL" \n"
" " __LL "%0, %1 # test_and_set_bit \n"
" or %2, %0, %3 \n"
" " __SC "%2, %1 \n"
" .set pop \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
: "r" (1UL << bit)
: __LLSC_CLOBBER);
} while (unlikely(!res));
res = temp & (1UL << bit);
} else
res = __mips_test_and_set_bit(nr, addr);
smp_llsc_mb();
return res != 0;
__bit_op(*m, "xor\t%0, %2", "ir"(BIT(bit)));
}
/*
@ -291,51 +180,39 @@ static inline int test_and_set_bit(unsigned long nr,
static inline int test_and_set_bit_lock(unsigned long nr,
volatile unsigned long *addr)
{
int bit = nr & SZLONG_MASK;
unsigned long res;
volatile unsigned long *m = &addr[BIT_WORD(nr)];
int bit = nr % BITS_PER_LONG;
unsigned long res, orig;
if (kernel_uses_llsc && R10000_LLSC_WAR) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
__asm__ __volatile__(
" .set push \n"
" .set arch=r4000 \n"
"1: " __LL "%0, %1 # test_and_set_bit \n"
" or %2, %0, %3 \n"
" " __SC "%2, %1 \n"
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
" .set pop \n"
: "=&r" (temp), "+m" (*m), "=&r" (res)
: "r" (1UL << bit)
: __LLSC_CLOBBER);
} else if (kernel_uses_llsc) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
loongson_llsc_mb();
do {
__asm__ __volatile__(
" .set push \n"
" .set "MIPS_ISA_ARCH_LEVEL" \n"
" " __LL "%0, %1 # test_and_set_bit \n"
" or %2, %0, %3 \n"
" " __SC "%2, %1 \n"
" .set pop \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
: "r" (1UL << bit)
: __LLSC_CLOBBER);
} while (unlikely(!res));
res = temp & (1UL << bit);
} else
if (!kernel_uses_llsc) {
res = __mips_test_and_set_bit_lock(nr, addr);
} else {
orig = __test_bit_op(*m, "%0",
"or\t%1, %0, %3",
"ir"(BIT(bit)));
res = (orig & BIT(bit)) != 0;
}
smp_llsc_mb();
return res != 0;
return res;
}
/*
* test_and_set_bit - Set a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
static inline int test_and_set_bit(unsigned long nr,
volatile unsigned long *addr)
{
smp_mb__before_atomic();
return test_and_set_bit_lock(nr, addr);
}
/*
* test_and_clear_bit - Clear a bit and return its old value
* @nr: Bit to clear
@ -347,71 +224,30 @@ static inline int test_and_set_bit_lock(unsigned long nr,
static inline int test_and_clear_bit(unsigned long nr,
volatile unsigned long *addr)
{
int bit = nr & SZLONG_MASK;
unsigned long res;
volatile unsigned long *m = &addr[BIT_WORD(nr)];
int bit = nr % BITS_PER_LONG;
unsigned long res, orig;
smp_mb__before_llsc();
smp_mb__before_atomic();
if (kernel_uses_llsc && R10000_LLSC_WAR) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
__asm__ __volatile__(
" .set push \n"
" .set arch=r4000 \n"
"1: " __LL "%0, %1 # test_and_clear_bit \n"
" or %2, %0, %3 \n"
" xor %2, %3 \n"
" " __SC "%2, %1 \n"
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
" .set pop \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
: "r" (1UL << bit)
: __LLSC_CLOBBER);
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
} else if (kernel_uses_llsc && __builtin_constant_p(nr)) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
loongson_llsc_mb();
do {
__asm__ __volatile__(
" " __LL "%0, %1 # test_and_clear_bit \n"
" " __EXT "%2, %0, %3, 1 \n"
" " __INS "%0, $0, %3, 1 \n"
" " __SC "%0, %1 \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
: "ir" (bit)
: __LLSC_CLOBBER);
} while (unlikely(!temp));
#endif
} else if (kernel_uses_llsc) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
loongson_llsc_mb();
do {
__asm__ __volatile__(
" .set push \n"
" .set "MIPS_ISA_ARCH_LEVEL" \n"
" " __LL "%0, %1 # test_and_clear_bit \n"
" or %2, %0, %3 \n"
" xor %2, %3 \n"
" " __SC "%2, %1 \n"
" .set pop \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
: "r" (1UL << bit)
: __LLSC_CLOBBER);
} while (unlikely(!res));
res = temp & (1UL << bit);
} else
if (!kernel_uses_llsc) {
res = __mips_test_and_clear_bit(nr, addr);
} else if ((MIPS_ISA_REV >= 2) && __builtin_constant_p(nr)) {
res = __test_bit_op(*m, "%1",
__EXT "%0, %1, %3, 1;"
__INS "%1, $0, %3, 1",
"i"(bit));
} else {
orig = __test_bit_op(*m, "%0",
"or\t%1, %0, %3;"
"xor\t%1, %1, %3",
"ir"(BIT(bit)));
res = (orig & BIT(bit)) != 0;
}
smp_llsc_mb();
return res != 0;
return res;
}
/*
@ -425,54 +261,29 @@ static inline int test_and_clear_bit(unsigned long nr,
static inline int test_and_change_bit(unsigned long nr,
volatile unsigned long *addr)
{
int bit = nr & SZLONG_MASK;
unsigned long res;
volatile unsigned long *m = &addr[BIT_WORD(nr)];
int bit = nr % BITS_PER_LONG;
unsigned long res, orig;
smp_mb__before_llsc();
smp_mb__before_atomic();
if (kernel_uses_llsc && R10000_LLSC_WAR) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
__asm__ __volatile__(
" .set push \n"
" .set arch=r4000 \n"
"1: " __LL "%0, %1 # test_and_change_bit \n"
" xor %2, %0, %3 \n"
" " __SC "%2, %1 \n"
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
" .set pop \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
: "r" (1UL << bit)
: __LLSC_CLOBBER);
} else if (kernel_uses_llsc) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
loongson_llsc_mb();
do {
__asm__ __volatile__(
" .set push \n"
" .set "MIPS_ISA_ARCH_LEVEL" \n"
" " __LL "%0, %1 # test_and_change_bit \n"
" xor %2, %0, %3 \n"
" " __SC "\t%2, %1 \n"
" .set pop \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
: "r" (1UL << bit)
: __LLSC_CLOBBER);
} while (unlikely(!res));
res = temp & (1UL << bit);
} else
if (!kernel_uses_llsc) {
res = __mips_test_and_change_bit(nr, addr);
} else {
orig = __test_bit_op(*m, "%0",
"xor\t%1, %0, %3",
"ir"(BIT(bit)));
res = (orig & BIT(bit)) != 0;
}
smp_llsc_mb();
return res != 0;
return res;
}
#undef __bit_op
#undef __test_bit_op
#include <asm-generic/bitops/non-atomic.h>
/*

View File

@ -61,7 +61,7 @@
/*
* Valid machtype for Loongson family
*/
enum loongson_machine_type {
enum loongson2ef_machine_type {
MACH_LOONGSON_UNKNOWN,
MACH_LEMOTE_FL2E,
MACH_LEMOTE_FL2F,
@ -70,7 +70,6 @@ enum loongson_machine_type {
MACH_DEXXON_GDIUM2F10,
MACH_LEMOTE_NAS,
MACH_LEMOTE_LL2F,
MACH_LOONGSON_GENERIC,
MACH_LOONGSON_END
};
@ -99,6 +98,7 @@ extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_ad
extern void prom_init(void);
extern void prom_free_prom_memory(void);
extern void prom_cleanup(void);
extern void free_init_pages(const char *what,
unsigned long begin, unsigned long end);

View File

@ -26,9 +26,8 @@ extern void check_bugs64(void);
static inline void check_bugs_early(void)
{
#ifdef CONFIG_64BIT
check_bugs64_early();
#endif
if (IS_ENABLED(CONFIG_CPU_R4X00_BUGS64))
check_bugs64_early();
}
static inline void check_bugs(void)
@ -37,19 +36,18 @@ static inline void check_bugs(void)
cpu_data[cpu].udelay_val = loops_per_jiffy;
check_bugs32();
#ifdef CONFIG_64BIT
check_bugs64();
#endif
if (IS_ENABLED(CONFIG_CPU_R4X00_BUGS64))
check_bugs64();
}
static inline int r4k_daddiu_bug(void)
{
#ifdef CONFIG_64BIT
if (!IS_ENABLED(CONFIG_CPU_R4X00_BUGS64))
return 0;
WARN_ON(daddiu_bug < 0);
return daddiu_bug != 0;
#else
return 0;
#endif
}
#endif /* _ASM_BUGS_H */

View File

@ -11,19 +11,10 @@
#include <linux/bug.h>
#include <linux/irqflags.h>
#include <asm/compiler.h>
#include <asm/llsc.h>
#include <asm/sync.h>
#include <asm/war.h>
/*
* Using a branch-likely instruction to check the result of an sc instruction
* works around a bug present in R10000 CPUs prior to revision 3.0 that could
* cause ll-sc sequences to execute non-atomically.
*/
#if R10000_LLSC_WAR
# define __scbeqz "beqzl"
#else
# define __scbeqz "beqz"
#endif
/*
* These functions doesn't exist, so if they are called you'll either:
*
@ -46,18 +37,18 @@ extern unsigned long __xchg_called_with_bad_pointer(void)
__typeof(*(m)) __ret; \
\
if (kernel_uses_llsc) { \
loongson_llsc_mb(); \
__asm__ __volatile__( \
" .set push \n" \
" .set noat \n" \
" .set push \n" \
" .set " MIPS_ISA_ARCH_LEVEL " \n" \
" " __SYNC(full, loongson3_war) " \n" \
"1: " ld " %0, %2 # __xchg_asm \n" \
" .set pop \n" \
" move $1, %z3 \n" \
" .set " MIPS_ISA_ARCH_LEVEL " \n" \
" " st " $1, %1 \n" \
"\t" __scbeqz " $1, 1b \n" \
"\t" __SC_BEQZ "$1, 1b \n" \
" .set pop \n" \
: "=&r" (__ret), "=" GCC_OFF_SMALL_ASM() (*m) \
: GCC_OFF_SMALL_ASM() (*m), "Jr" (val) \
@ -103,7 +94,13 @@ unsigned long __xchg(volatile void *ptr, unsigned long x, int size)
({ \
__typeof__(*(ptr)) __res; \
\
smp_mb__before_llsc(); \
/* \
* In the Loongson3 workaround case __xchg_asm() already \
* contains a completion barrier prior to the LL, so we don't \
* need to emit an extra one here. \
*/ \
if (!__SYNC_loongson3_war) \
smp_mb__before_llsc(); \
\
__res = (__typeof__(*(ptr))) \
__xchg((ptr), (unsigned long)(x), sizeof(*(ptr))); \
@ -118,25 +115,24 @@ unsigned long __xchg(volatile void *ptr, unsigned long x, int size)
__typeof(*(m)) __ret; \
\
if (kernel_uses_llsc) { \
loongson_llsc_mb(); \
__asm__ __volatile__( \
" .set push \n" \
" .set noat \n" \
" .set push \n" \
" .set "MIPS_ISA_ARCH_LEVEL" \n" \
" " __SYNC(full, loongson3_war) " \n" \
"1: " ld " %0, %2 # __cmpxchg_asm \n" \
" bne %0, %z3, 2f \n" \
" .set pop \n" \
" move $1, %z4 \n" \
" .set "MIPS_ISA_ARCH_LEVEL" \n" \
" " st " $1, %1 \n" \
"\t" __scbeqz " $1, 1b \n" \
"\t" __SC_BEQZ "$1, 1b \n" \
" .set pop \n" \
"2: \n" \
"2: " __SYNC(full, loongson3_war) " \n" \
: "=&r" (__ret), "=" GCC_OFF_SMALL_ASM() (*m) \
: GCC_OFF_SMALL_ASM() (*m), "Jr" (old), "Jr" (new) \
: __LLSC_CLOBBER); \
loongson_llsc_mb(); \
} else { \
unsigned long __flags; \
\
@ -190,9 +186,23 @@ unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
({ \
__typeof__(*(ptr)) __res; \
\
smp_mb__before_llsc(); \
/* \
* In the Loongson3 workaround case __cmpxchg_asm() already \
* contains a completion barrier prior to the LL, so we don't \
* need to emit an extra one here. \
*/ \
if (!__SYNC_loongson3_war) \
smp_mb__before_llsc(); \
\
__res = cmpxchg_local((ptr), (old), (new)); \
smp_llsc_mb(); \
\
/* \
* In the Loongson3 workaround case __cmpxchg_asm() already \
* contains a completion barrier after the SC, so we don't \
* need to emit an extra one here. \
*/ \
if (!__SYNC_loongson3_war) \
smp_llsc_mb(); \
\
__res; \
})
@ -233,11 +243,11 @@ static inline unsigned long __cmpxchg64(volatile void *ptr,
*/
local_irq_save(flags);
loongson_llsc_mb();
asm volatile(
" .set push \n"
" .set " MIPS_ISA_ARCH_LEVEL " \n"
/* Load 64 bits from ptr */
" " __SYNC(full, loongson3_war) " \n"
"1: lld %L0, %3 # __cmpxchg64 \n"
/*
* Split the 64 bit value we loaded into the 2 registers that hold the
@ -269,9 +279,9 @@ static inline unsigned long __cmpxchg64(volatile void *ptr,
/* Attempt to store new at ptr */
" scd %L1, %2 \n"
/* If we failed, loop! */
"\t" __scbeqz " %L1, 1b \n"
"\t" __SC_BEQZ "%L1, 1b \n"
" .set pop \n"
"2: \n"
"2: " __SYNC(full, loongson3_war) " \n"
: "=&r"(ret),
"=&r"(tmp),
"=" GCC_OFF_SMALL_ASM() (*(unsigned long long *)ptr)
@ -279,7 +289,6 @@ static inline unsigned long __cmpxchg64(volatile void *ptr,
"r" (old),
"r" (new)
: "memory");
loongson_llsc_mb();
local_irq_restore(flags);
return ret;
@ -312,6 +321,4 @@ static inline unsigned long __cmpxchg64(volatile void *ptr,
# endif /* !CONFIG_SMP */
#endif /* !CONFIG_64BIT */
#undef __scbeqz
#endif /* __ASM_CMPXCHG_H */

View File

@ -33,7 +33,7 @@ extern void nlm_cop2_restore(struct nlm_cop2_state *);
#define cop2_present 1
#define cop2_lazy_restore 0
#elif defined(CONFIG_CPU_LOONGSON3)
#elif defined(CONFIG_CPU_LOONGSON64)
#define cop2_present 1
#define cop2_lazy_restore 1

View File

@ -15,18 +15,17 @@
static inline int __pure __get_cpu_type(const int cpu_type)
{
switch (cpu_type) {
#if defined(CONFIG_SYS_HAS_CPU_LOONGSON2E) || \
defined(CONFIG_SYS_HAS_CPU_LOONGSON2F)
case CPU_LOONGSON2:
#if defined(CONFIG_SYS_HAS_CPU_LOONGSON2EF)
case CPU_LOONGSON2EF:
#endif
#ifdef CONFIG_SYS_HAS_CPU_LOONGSON3
case CPU_LOONGSON3:
#ifdef CONFIG_SYS_HAS_CPU_LOONGSON64
case CPU_LOONGSON64:
#endif
#if defined(CONFIG_SYS_HAS_CPU_LOONGSON1B) || \
defined(CONFIG_SYS_HAS_CPU_LOONGSON1C)
case CPU_LOONGSON1:
case CPU_LOONGSON32:
#endif
#ifdef CONFIG_SYS_HAS_CPU_MIPS32_R1

View File

@ -91,7 +91,9 @@
#define PRID_IMP_LOONGSON_32 0x4200 /* Loongson-1 */
#define PRID_IMP_R5432 0x5400
#define PRID_IMP_R5500 0x5500
#define PRID_IMP_LOONGSON_64 0x6300 /* Loongson-2/3 */
#define PRID_IMP_LOONGSON_64R 0x6100 /* Reduced Loongson-2 */
#define PRID_IMP_LOONGSON_64C 0x6300 /* Classic Loongson-2 and Loongson-3 */
#define PRID_IMP_LOONGSON_64G 0xc000 /* Generic Loongson-2 and Loongson-3 */
#define PRID_IMP_UNKNOWN 0xff00
@ -310,15 +312,15 @@ enum cpu_type_enum {
*/
CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,
CPU_BMIPS4380, CPU_BMIPS5000, CPU_XBURST, CPU_LOONGSON1, CPU_M14KC,
CPU_BMIPS4380, CPU_BMIPS5000, CPU_XBURST, CPU_LOONGSON32, CPU_M14KC,
CPU_M14KEC, CPU_INTERAPTIV, CPU_P5600, CPU_PROAPTIV, CPU_1074K,
CPU_M5150, CPU_I6400, CPU_P6600, CPU_M6250,
/*
* MIPS64 class processors
*/
CPU_5KC, CPU_5KE, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
CPU_LOONGSON3, CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS,
CPU_5KC, CPU_5KE, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2EF,
CPU_LOONGSON64, CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS,
CPU_CAVIUM_OCTEON2, CPU_CAVIUM_OCTEON3, CPU_XLR, CPU_XLP, CPU_I6500,
CPU_QEMU_GENERIC,

View File

@ -70,7 +70,7 @@ enum fixed_addresses {
#include <asm-generic/fixmap.h>
#define kmap_get_fixmap_pte(vaddr) \
pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
pte_offset_kernel(pmd_offset(pud_offset(p4d_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr)), (vaddr))
/*
* Called from pgtable_init()

View File

@ -16,6 +16,7 @@
#include <asm/barrier.h>
#include <asm/compiler.h>
#include <asm/errno.h>
#include <asm/sync.h>
#include <asm/war.h>
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
@ -32,7 +33,7 @@
" .set arch=r4000 \n" \
"2: sc $1, %2 \n" \
" beqzl $1, 1b \n" \
__WEAK_LLSC_MB \
__stringify(__WEAK_LLSC_MB) " \n" \
"3: \n" \
" .insn \n" \
" .set pop \n" \
@ -50,19 +51,19 @@
"i" (-EFAULT) \
: "memory"); \
} else if (cpu_has_llsc) { \
loongson_llsc_mb(); \
__asm__ __volatile__( \
" .set push \n" \
" .set noat \n" \
" .set push \n" \
" .set "MIPS_ISA_ARCH_LEVEL" \n" \
" " __SYNC(full, loongson3_war) " \n" \
"1: "user_ll("%1", "%4")" # __futex_atomic_op\n" \
" .set pop \n" \
" " insn " \n" \
" .set "MIPS_ISA_ARCH_LEVEL" \n" \
"2: "user_sc("$1", "%2")" \n" \
" beqz $1, 1b \n" \
__WEAK_LLSC_MB \
__stringify(__WEAK_LLSC_MB) " \n" \
"3: \n" \
" .insn \n" \
" .set pop \n" \
@ -147,7 +148,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
" .set arch=r4000 \n"
"2: sc $1, %2 \n"
" beqzl $1, 1b \n"
__WEAK_LLSC_MB
__stringify(__WEAK_LLSC_MB) " \n"
"3: \n"
" .insn \n"
" .set pop \n"
@ -164,13 +165,13 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
"i" (-EFAULT)
: "memory");
} else if (cpu_has_llsc) {
loongson_llsc_mb();
__asm__ __volatile__(
"# futex_atomic_cmpxchg_inatomic \n"
" .set push \n"
" .set noat \n"
" .set push \n"
" .set "MIPS_ISA_ARCH_LEVEL" \n"
" " __SYNC(full, loongson3_war) " \n"
"1: "user_ll("%1", "%3")" \n"
" bne %1, %z4, 3f \n"
" .set pop \n"
@ -178,8 +179,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
" .set "MIPS_ISA_ARCH_LEVEL" \n"
"2: "user_sc("$1", "%2")" \n"
" beqz $1, 1b \n"
__WEAK_LLSC_MB
"3: \n"
"3: " __SYNC_ELSE(full, loongson3_war, __WEAK_LLSC_MB) "\n"
" .insn \n"
" .set pop \n"
" .section .fixup,\"ax\" \n"
@ -194,7 +194,6 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
: GCC_OFF_SMALL_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval),
"i" (-EFAULT)
: "memory");
loongson_llsc_mb();
} else
return -ENOSYS;

View File

@ -158,7 +158,7 @@ do { \
} while (0)
#elif defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \
defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_LOONGSON3_ENHANCEMENT) || \
defined(CONFIG_CPU_LOONGSON2EF) || defined(CONFIG_LOONGSON3_ENHANCEMENT) || \
defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_XLR)
/*

View File

@ -306,7 +306,7 @@ static inline void iounmap(const volatile void __iomem *addr)
#undef __IS_KSEG1
}
#if defined(CONFIG_CPU_CAVIUM_OCTEON) || defined(CONFIG_CPU_LOONGSON3)
#if defined(CONFIG_CPU_CAVIUM_OCTEON) || defined(CONFIG_CPU_LOONGSON64)
#define war_io_reorder_wmb() wmb()
#else
#define war_io_reorder_wmb() barrier()

View File

@ -41,7 +41,7 @@ static inline unsigned long arch_local_irq_save(void)
" .set push \n"
" .set reorder \n"
" .set noat \n"
#if defined(CONFIG_CPU_LOONGSON3) || defined (CONFIG_CPU_LOONGSON1)
#if defined(CONFIG_CPU_LOONGSON64) || defined(CONFIG_CPU_LOONGSON32)
" mfc0 %[flags], $12 \n"
" di \n"
#else

View File

@ -9,20 +9,31 @@
#ifndef __ASM_LLSC_H
#define __ASM_LLSC_H
#include <asm/isa-rev.h>
#if _MIPS_SZLONG == 32
#define SZLONG_LOG 5
#define SZLONG_MASK 31UL
#define __LL "ll "
#define __SC "sc "
#define __INS "ins "
#define __EXT "ext "
#elif _MIPS_SZLONG == 64
#define SZLONG_LOG 6
#define SZLONG_MASK 63UL
#define __LL "lld "
#define __SC "scd "
#define __INS "dins "
#define __EXT "dext "
#endif
/*
* Using a branch-likely instruction to check the result of an sc instruction
* works around a bug present in R10000 CPUs prior to revision 3.0 that could
* cause ll-sc sequences to execute non-atomically.
*/
#if R10000_LLSC_WAR
# define __SC_BEQZ "beqzl "
#elif MIPS_ISA_REV >= 6
# define __SC_BEQZ "beqzc "
#else
# define __SC_BEQZ "beqz "
#endif
#endif /* __ASM_LLSC_H */

View File

@ -10,17 +10,7 @@
#ifndef _ASM_MACH_IP22_SPACES_H
#define _ASM_MACH_IP22_SPACES_H
#ifdef CONFIG_64BIT
#define PAGE_OFFSET 0xffffffff80000000UL
#define CAC_BASE 0xffffffff80000000
#define IO_BASE 0xffffffffa0000000
#define UNCAC_BASE 0xffffffffa0000000
#define MAP_BASE 0xc000000000000000
#endif /* CONFIG_64BIT */
#define PHYS_OFFSET _AC(0x08000000, UL)
#include <asm/mach-generic/spaces.h>

View File

@ -6,7 +6,7 @@
#include <asm/sn/arch.h>
#include <asm/sn/hub.h>
#define pa_to_nid(addr) NASID_TO_COMPACT_NODEID(NASID_GET(addr))
#define pa_to_nid(addr) NASID_GET(addr)
struct hub_data {
kern_vars_t kern_vars;

View File

@ -7,14 +7,13 @@
#include <asm/mmzone.h>
struct cpuinfo_ip27 {
cnodeid_t p_nodeid; /* my node ID in compact-id-space */
nasid_t p_nasid; /* my node ID in numa-as-id-space */
unsigned char p_slice; /* Physical position on node board */
};
extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS];
#define cpu_to_node(cpu) (sn_cpu_info[(cpu)].p_nodeid)
#define cpu_to_node(cpu) (cputonasid(cpu))
#define cpumask_of_node(node) ((node) == -1 ? \
cpu_all_mask : \
&hub_data(node)->h_cpus)
@ -23,7 +22,7 @@ extern int pcibus_to_node(struct pci_bus *);
#define cpumask_of_pcibus(bus) (cpumask_of_node(pcibus_to_node(bus)))
extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
extern unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES];
#define node_distance(from, to) (__node_distances[(from)][(to)])

View File

@ -0,0 +1,83 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* IP30/Octane cpu-features overrides.
*
* Copyright (C) 2003 Ralf Baechle <ralf@linux-mips.org>
* 2004-2007 Stanislaw Skowronek <skylark@unaligned.org>
* 2009 Johannes Dickgreber <tanzy@gmx.de>
* 2015 Joshua Kinard <kumba@gentoo.org>
*
*/
#ifndef __ASM_MACH_IP30_CPU_FEATURE_OVERRIDES_H
#define __ASM_MACH_IP30_CPU_FEATURE_OVERRIDES_H
#include <asm/cpu.h>
/*
* IP30 only supports R1[024]000 processors, all using the same config
*/
#define cpu_has_tlb 1
#define cpu_has_tlbinv 0
#define cpu_has_segments 0
#define cpu_has_eva 0
#define cpu_has_htw 0
#define cpu_has_rixiex 0
#define cpu_has_maar 0
#define cpu_has_rw_llb 0
#define cpu_has_3kex 0
#define cpu_has_4kex 1
#define cpu_has_3k_cache 0
#define cpu_has_4k_cache 1
#define cpu_has_6k_cache 0
#define cpu_has_8k_cache 0
#define cpu_has_tx39_cache 0
#define cpu_has_fpu 1
#define cpu_has_nofpuex 0
#define cpu_has_32fpr 1
#define cpu_has_counter 1
#define cpu_has_watch 1
#define cpu_has_64bits 1
#define cpu_has_divec 0
#define cpu_has_vce 0
#define cpu_has_cache_cdex_p 0
#define cpu_has_cache_cdex_s 0
#define cpu_has_prefetch 1
#define cpu_has_mcheck 0
#define cpu_has_ejtag 0
#define cpu_has_llsc 1
#define cpu_has_mips16 0
#define cpu_has_mdmx 0
#define cpu_has_mips3d 0
#define cpu_has_smartmips 0
#define cpu_has_rixi 0
#define cpu_has_xpa 0
#define cpu_has_vtag_icache 0
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 0
#define cpu_icache_snoops_remote_store 1
#define cpu_has_mips32r1 0
#define cpu_has_mips32r2 0
#define cpu_has_mips64r1 0
#define cpu_has_mips64r2 0
#define cpu_has_mips32r6 0
#define cpu_has_mips64r6 0
#define cpu_has_dsp 0
#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0
#define cpu_has_userlocal 0
#define cpu_has_inclusive_pcaches 1
#define cpu_hwrena_impl_bits 0
#define cpu_has_perf_cntr_intr_bit 0
#define cpu_has_vz 0
#define cpu_has_fre 0
#define cpu_has_cdmm 0
#define cpu_dcache_line_size() 32
#define cpu_icache_line_size() 64
#define cpu_scache_line_size() 128
#endif /* __ASM_MACH_IP30_CPU_FEATURE_OVERRIDES_H */

View File

@ -0,0 +1,87 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* HEART IRQ defines
*
* Copyright (C) 2009 Johannes Dickgreber <tanzy@gmx.de>
* 2014-2016 Joshua Kinard <kumba@gentoo.org>
*
*/
#ifndef __ASM_MACH_IP30_IRQ_H
#define __ASM_MACH_IP30_IRQ_H
/*
* HEART has 64 hardware interrupts, but use 128 to leave room for a few
* software interrupts as well (such as the CPU timer interrupt.
*/
#define NR_IRQS 128
extern void __init ip30_install_ipi(void);
/*
* HEART has 64 interrupt vectors available to it, subdivided into five
* priority levels. They are numbered 0 to 63.
*/
#define HEART_NUM_IRQS 64
/*
* These are the five interrupt priority levels and their corresponding
* CPU IPx interrupt pins.
*
* Level 4 - Error Interrupts.
* Level 3 - HEART timer interrupt.
* Level 2 - CPU IPI, CPU debug, power putton, general device interrupts.
* Level 1 - General device interrupts.
* Level 0 - General device GFX flow control interrupts.
*/
#define HEART_L4_INT_MASK 0xfff8000000000000ULL /* IP6 */
#define HEART_L3_INT_MASK 0x0004000000000000ULL /* IP5 */
#define HEART_L2_INT_MASK 0x0003ffff00000000ULL /* IP4 */
#define HEART_L1_INT_MASK 0x00000000ffff0000ULL /* IP3 */
#define HEART_L0_INT_MASK 0x000000000000ffffULL /* IP2 */
/* HEART L0 Interrupts (Low Priority) */
#define HEART_L0_INT_GENERIC 0
#define HEART_L0_INT_FLOW_CTRL_HWTR_0 1
#define HEART_L0_INT_FLOW_CTRL_HWTR_1 2
/* HEART L2 Interrupts (High Priority) */
#define HEART_L2_INT_RESCHED_CPU_0 46
#define HEART_L2_INT_RESCHED_CPU_1 47
#define HEART_L2_INT_CALL_CPU_0 48
#define HEART_L2_INT_CALL_CPU_1 49
/* HEART L3 Interrupts (Compare/Counter Timer) */
#define HEART_L3_INT_TIMER 50
/* HEART L4 Interrupts (Errors) */
#define HEART_L4_INT_XWID_ERR_9 51
#define HEART_L4_INT_XWID_ERR_A 52
#define HEART_L4_INT_XWID_ERR_B 53
#define HEART_L4_INT_XWID_ERR_C 54
#define HEART_L4_INT_XWID_ERR_D 55
#define HEART_L4_INT_XWID_ERR_E 56
#define HEART_L4_INT_XWID_ERR_F 57
#define HEART_L4_INT_XWID_ERR_XBOW 58
#define HEART_L4_INT_CPU_BUS_ERR_0 59
#define HEART_L4_INT_CPU_BUS_ERR_1 60
#define HEART_L4_INT_CPU_BUS_ERR_2 61
#define HEART_L4_INT_CPU_BUS_ERR_3 62
#define HEART_L4_INT_HEART_EXCP 63
/*
* Power Switch is wired via BaseIO BRIDGE slot #6.
*
* ACFail is wired via BaseIO BRIDGE slot #7.
*/
#define IP30_POWER_IRQ HEART_L2_INT_POWER_BTN
#include_next <irq.h>
#define IP30_HEART_L0_IRQ (MIPS_CPU_IRQ_BASE + 2)
#define IP30_HEART_L1_IRQ (MIPS_CPU_IRQ_BASE + 3)
#define IP30_HEART_L2_IRQ (MIPS_CPU_IRQ_BASE + 4)
#define IP30_HEART_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 5)
#define IP30_HEART_ERR_IRQ (MIPS_CPU_IRQ_BASE + 6)
#endif /* __ASM_MACH_IP30_IRQ_H */

View File

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_MACH_IP30_KERNEL_ENTRY_H
#define __ASM_MACH_IP30_KERNEL_ENTRY_H
.macro kernel_entry_setup
.endm
.macro smp_slave_setup
move gp, a0
.endm
#endif /* __ASM_MACH_IP30_KERNEL_ENTRY_H */

View File

@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2003, 2004 Ralf Baechle
*/
#ifndef __ASM_MACH_IP30_MANGLE_PORT_H
#define __ASM_MACH_IP30_MANGLE_PORT_H
#define __swizzle_addr_b(port) ((port)^3)
#define __swizzle_addr_w(port) ((port)^2)
#define __swizzle_addr_l(port) (port)
#define __swizzle_addr_q(port) (port)
#define ioswabb(a, x) (x)
#define __mem_ioswabb(a, x) (x)
#define ioswabw(a, x) (x)
#define __mem_ioswabw(a, x) cpu_to_le16(x)
#define ioswabl(a, x) (x)
#define __mem_ioswabl(a, x) cpu_to_le32(x)
#define ioswabq(a, x) (x)
#define __mem_ioswabq(a, x) cpu_to_le64(x)
#endif /* __ASM_MACH_IP30_MANGLE_PORT_H */

View File

@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2016 Joshua Kinard <kumba@gentoo.org>
*
*/
#ifndef _ASM_MACH_IP30_SPACES_H
#define _ASM_MACH_IP30_SPACES_H
/*
* Memory in IP30/Octane is offset 512MB in the physical address space.
*/
#define PHYS_OFFSET _AC(0x20000000, UL)
#ifdef CONFIG_64BIT
#define CAC_BASE _AC(0xA800000000000000, UL)
#endif
#include <asm/mach-generic/spaces.h>
#endif /* _ASM_MACH_IP30_SPACES_H */

View File

@ -0,0 +1,26 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
*/
#ifndef __ASM_MIPS_MACH_IP30_WAR_H
#define __ASM_MIPS_MACH_IP30_WAR_H
#define R4600_V1_INDEX_ICACHEOP_WAR 0
#define R4600_V1_HIT_CACHEOP_WAR 0
#define R4600_V2_HIT_CACHEOP_WAR 0
#define MIPS_CACHE_SYNC_WAR 0
#define BCM1250_M3_WAR 0
#define SIBYTE_1956_WAR 0
#define MIPS4K_ICACHE_REFILL_WAR 0
#define MIPS34K_MISSED_ITLB_WAR 0
#define R5432_CP0_INTERRUPT_WAR 0
#define TX49XX_ICACHE_INDEX_INV_WAR 0
#define ICACHE_REFILLS_WORKAROUND_WAR 0
#ifdef CONFIG_CPU_R10000
#define R10000_LLSC_WAR 1
#else
#define R10000_LLSC_WAR 0
#endif
#endif /* __ASM_MIPS_MACH_IP30_WAR_H */

View File

@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2009 Wu Zhangjin <wuzhangjin@gmail.com>
* Copyright (C) 2009 Philippe Vachon <philippe@cowpig.ca>
* Copyright (C) 2009 Zhang Le <r0bertz@gentoo.org>
*
* reference: /proc/cpuinfo,
* arch/mips/kernel/cpu-probe.c(cpu_probe_legacy),
* arch/mips/kernel/proc.c(show_cpuinfo),
* loongson2f user manual.
*/
#ifndef __ASM_MACH_LOONGSON2EF_CPU_FEATURE_OVERRIDES_H
#define __ASM_MACH_LOONGSON2EF_CPU_FEATURE_OVERRIDES_H
#define cpu_has_32fpr 1
#define cpu_has_3k_cache 0
#define cpu_has_4k_cache 1
#define cpu_has_4kex 1
#define cpu_has_64bits 1
#define cpu_has_cache_cdex_p 0
#define cpu_has_cache_cdex_s 0
#define cpu_has_counter 1
#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000)
#define cpu_has_divec 0
#define cpu_has_ejtag 0
#define cpu_has_inclusive_pcaches 1
#define cpu_has_llsc 1
#define cpu_has_mcheck 0
#define cpu_has_mdmx 0
#define cpu_has_mips16 0
#define cpu_has_mips16e2 0
#define cpu_has_mips3d 0
#define cpu_has_mipsmt 0
#define cpu_has_smartmips 0
#define cpu_has_tlb 1
#define cpu_has_tx39_cache 0
#define cpu_has_vce 0
#define cpu_has_veic 0
#define cpu_has_vint 0
#define cpu_has_vtag_icache 0
#define cpu_has_watch 1
#endif /* __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H */

View File

@ -0,0 +1,326 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2009 Lemote, Inc.
* Author: Wu Zhangjin <wuzhangjin@gmail.com>
*/
#ifndef __ASM_MACH_LOONGSON2EF_LOONGSON_H
#define __ASM_MACH_LOONGSON2EF_LOONGSON_H
#include <linux/io.h>
#include <linux/init.h>
#include <linux/irq.h>
/* loongson internal northbridge initialization */
extern void bonito_irq_init(void);
/* machine-specific reboot/halt operation */
extern void mach_prepare_reboot(void);
extern void mach_prepare_shutdown(void);
/* environment arguments from bootloader */
extern u32 cpu_clock_freq;
extern u32 memsize, highmemsize;
/* loongson-specific command line, env and memory initialization */
extern void __init prom_init_memory(void);
extern void __init prom_init_machtype(void);
extern void __init prom_init_env(void);
#ifdef CONFIG_LOONGSON_UART_BASE
extern unsigned long _loongson_uart_base, loongson_uart_base;
extern void prom_init_loongson_uart_base(void);
#endif
static inline void prom_init_uart_base(void)
{
#ifdef CONFIG_LOONGSON_UART_BASE
prom_init_loongson_uart_base();
#endif
}
/* irq operation functions */
extern void bonito_irqdispatch(void);
extern void __init bonito_irq_init(void);
extern void __init mach_init_irq(void);
extern void mach_irq_dispatch(unsigned int pending);
extern int mach_i8259_irq(void);
/* We need this in some places... */
#define delay() ({ \
int x; \
for (x = 0; x < 100000; x++) \
__asm__ __volatile__(""); \
})
#define LOONGSON_REG(x) \
(*(volatile u32 *)((char *)CKSEG1ADDR(LOONGSON_REG_BASE) + (x)))
#define LOONGSON_IRQ_BASE 32
#define LOONGSON2_PERFCNT_IRQ (MIPS_CPU_IRQ_BASE + 6) /* cpu perf counter */
#include <linux/interrupt.h>
static inline void do_perfcnt_IRQ(void)
{
#if IS_ENABLED(CONFIG_OPROFILE)
do_IRQ(LOONGSON2_PERFCNT_IRQ);
#endif
}
#define LOONGSON_FLASH_BASE 0x1c000000
#define LOONGSON_FLASH_SIZE 0x02000000 /* 32M */
#define LOONGSON_FLASH_TOP (LOONGSON_FLASH_BASE+LOONGSON_FLASH_SIZE-1)
#define LOONGSON_LIO0_BASE 0x1e000000
#define LOONGSON_LIO0_SIZE 0x01C00000 /* 28M */
#define LOONGSON_LIO0_TOP (LOONGSON_LIO0_BASE+LOONGSON_LIO0_SIZE-1)
#define LOONGSON_BOOT_BASE 0x1fc00000
#define LOONGSON_BOOT_SIZE 0x00100000 /* 1M */
#define LOONGSON_BOOT_TOP (LOONGSON_BOOT_BASE+LOONGSON_BOOT_SIZE-1)
#define LOONGSON_REG_BASE 0x1fe00000
#define LOONGSON_REG_SIZE 0x00100000 /* 256Bytes + 256Bytes + ??? */
#define LOONGSON_REG_TOP (LOONGSON_REG_BASE+LOONGSON_REG_SIZE-1)
#define LOONGSON_LIO1_BASE 0x1ff00000
#define LOONGSON_LIO1_SIZE 0x00100000 /* 1M */
#define LOONGSON_LIO1_TOP (LOONGSON_LIO1_BASE+LOONGSON_LIO1_SIZE-1)
#define LOONGSON_PCILO0_BASE 0x10000000
#define LOONGSON_PCILO1_BASE 0x14000000
#define LOONGSON_PCILO2_BASE 0x18000000
#define LOONGSON_PCILO_BASE LOONGSON_PCILO0_BASE
#define LOONGSON_PCILO_SIZE 0x0c000000 /* 64M * 3 */
#define LOONGSON_PCILO_TOP (LOONGSON_PCILO0_BASE+LOONGSON_PCILO_SIZE-1)
#define LOONGSON_PCICFG_BASE 0x1fe80000
#define LOONGSON_PCICFG_SIZE 0x00000800 /* 2K */
#define LOONGSON_PCICFG_TOP (LOONGSON_PCICFG_BASE+LOONGSON_PCICFG_SIZE-1)
#define LOONGSON_PCIIO_BASE 0x1fd00000
#define LOONGSON_PCIIO_SIZE 0x00100000 /* 1M */
#define LOONGSON_PCIIO_TOP (LOONGSON_PCIIO_BASE+LOONGSON_PCIIO_SIZE-1)
/* Loongson Register Bases */
#define LOONGSON_PCICONFIGBASE 0x00
#define LOONGSON_REGBASE 0x100
/* PCI Configuration Registers */
#define LOONGSON_PCI_REG(x) LOONGSON_REG(LOONGSON_PCICONFIGBASE + (x))
#define LOONGSON_PCIDID LOONGSON_PCI_REG(0x00)
#define LOONGSON_PCICMD LOONGSON_PCI_REG(0x04)
#define LOONGSON_PCICLASS LOONGSON_PCI_REG(0x08)
#define LOONGSON_PCILTIMER LOONGSON_PCI_REG(0x0c)
#define LOONGSON_PCIBASE0 LOONGSON_PCI_REG(0x10)
#define LOONGSON_PCIBASE1 LOONGSON_PCI_REG(0x14)
#define LOONGSON_PCIBASE2 LOONGSON_PCI_REG(0x18)
#define LOONGSON_PCIBASE3 LOONGSON_PCI_REG(0x1c)
#define LOONGSON_PCIBASE4 LOONGSON_PCI_REG(0x20)
#define LOONGSON_PCIEXPRBASE LOONGSON_PCI_REG(0x30)
#define LOONGSON_PCIINT LOONGSON_PCI_REG(0x3c)
#define LOONGSON_PCI_ISR4C LOONGSON_PCI_REG(0x4c)
#define LOONGSON_PCICMD_PERR_CLR 0x80000000
#define LOONGSON_PCICMD_SERR_CLR 0x40000000
#define LOONGSON_PCICMD_MABORT_CLR 0x20000000
#define LOONGSON_PCICMD_MTABORT_CLR 0x10000000
#define LOONGSON_PCICMD_TABORT_CLR 0x08000000
#define LOONGSON_PCICMD_MPERR_CLR 0x01000000
#define LOONGSON_PCICMD_PERRRESPEN 0x00000040
#define LOONGSON_PCICMD_ASTEPEN 0x00000080
#define LOONGSON_PCICMD_SERREN 0x00000100
#define LOONGSON_PCILTIMER_BUSLATENCY 0x0000ff00
#define LOONGSON_PCILTIMER_BUSLATENCY_SHIFT 8
/* Loongson h/w Configuration */
#define LOONGSON_GENCFG_OFFSET 0x4
#define LOONGSON_GENCFG LOONGSON_REG(LOONGSON_REGBASE + LOONGSON_GENCFG_OFFSET)
#define LOONGSON_GENCFG_DEBUGMODE 0x00000001
#define LOONGSON_GENCFG_SNOOPEN 0x00000002
#define LOONGSON_GENCFG_CPUSELFRESET 0x00000004
#define LOONGSON_GENCFG_FORCE_IRQA 0x00000008
#define LOONGSON_GENCFG_IRQA_ISOUT 0x00000010
#define LOONGSON_GENCFG_IRQA_FROM_INT1 0x00000020
#define LOONGSON_GENCFG_BYTESWAP 0x00000040
#define LOONGSON_GENCFG_UNCACHED 0x00000080
#define LOONGSON_GENCFG_PREFETCHEN 0x00000100
#define LOONGSON_GENCFG_WBEHINDEN 0x00000200
#define LOONGSON_GENCFG_CACHEALG 0x00000c00
#define LOONGSON_GENCFG_CACHEALG_SHIFT 10
#define LOONGSON_GENCFG_PCIQUEUE 0x00001000
#define LOONGSON_GENCFG_CACHESTOP 0x00002000
#define LOONGSON_GENCFG_MSTRBYTESWAP 0x00004000
#define LOONGSON_GENCFG_BUSERREN 0x00008000
#define LOONGSON_GENCFG_NORETRYTIMEOUT 0x00010000
#define LOONGSON_GENCFG_SHORTCOPYTIMEOUT 0x00020000
/* PCI address map control */
#define LOONGSON_PCIMAP LOONGSON_REG(LOONGSON_REGBASE + 0x10)
#define LOONGSON_PCIMEMBASECFG LOONGSON_REG(LOONGSON_REGBASE + 0x14)
#define LOONGSON_PCIMAP_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x18)
/* GPIO Regs - r/w */
#define LOONGSON_GPIODATA LOONGSON_REG(LOONGSON_REGBASE + 0x1c)
#define LOONGSON_GPIOIE LOONGSON_REG(LOONGSON_REGBASE + 0x20)
/* ICU Configuration Regs - r/w */
#define LOONGSON_INTEDGE LOONGSON_REG(LOONGSON_REGBASE + 0x24)
#define LOONGSON_INTSTEER LOONGSON_REG(LOONGSON_REGBASE + 0x28)
#define LOONGSON_INTPOL LOONGSON_REG(LOONGSON_REGBASE + 0x2c)
/* ICU Enable Regs - IntEn & IntISR are r/o. */
#define LOONGSON_INTENSET LOONGSON_REG(LOONGSON_REGBASE + 0x30)
#define LOONGSON_INTENCLR LOONGSON_REG(LOONGSON_REGBASE + 0x34)
#define LOONGSON_INTEN LOONGSON_REG(LOONGSON_REGBASE + 0x38)
#define LOONGSON_INTISR LOONGSON_REG(LOONGSON_REGBASE + 0x3c)
/* ICU */
#define LOONGSON_ICU_MBOXES 0x0000000f
#define LOONGSON_ICU_MBOXES_SHIFT 0
#define LOONGSON_ICU_DMARDY 0x00000010
#define LOONGSON_ICU_DMAEMPTY 0x00000020
#define LOONGSON_ICU_COPYRDY 0x00000040
#define LOONGSON_ICU_COPYEMPTY 0x00000080
#define LOONGSON_ICU_COPYERR 0x00000100
#define LOONGSON_ICU_PCIIRQ 0x00000200
#define LOONGSON_ICU_MASTERERR 0x00000400
#define LOONGSON_ICU_SYSTEMERR 0x00000800
#define LOONGSON_ICU_DRAMPERR 0x00001000
#define LOONGSON_ICU_RETRYERR 0x00002000
#define LOONGSON_ICU_GPIOS 0x01ff0000
#define LOONGSON_ICU_GPIOS_SHIFT 16
#define LOONGSON_ICU_GPINS 0x7e000000
#define LOONGSON_ICU_GPINS_SHIFT 25
#define LOONGSON_ICU_MBOX(N) (1<<(LOONGSON_ICU_MBOXES_SHIFT+(N)))
#define LOONGSON_ICU_GPIO(N) (1<<(LOONGSON_ICU_GPIOS_SHIFT+(N)))
#define LOONGSON_ICU_GPIN(N) (1<<(LOONGSON_ICU_GPINS_SHIFT+(N)))
/* PCI prefetch window base & mask */
#define LOONGSON_MEM_WIN_BASE_L LOONGSON_REG(LOONGSON_REGBASE + 0x40)
#define LOONGSON_MEM_WIN_BASE_H LOONGSON_REG(LOONGSON_REGBASE + 0x44)
#define LOONGSON_MEM_WIN_MASK_L LOONGSON_REG(LOONGSON_REGBASE + 0x48)
#define LOONGSON_MEM_WIN_MASK_H LOONGSON_REG(LOONGSON_REGBASE + 0x4c)
/* PCI_Hit*_Sel_* */
#define LOONGSON_PCI_HIT0_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x50)
#define LOONGSON_PCI_HIT0_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x54)
#define LOONGSON_PCI_HIT1_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x58)
#define LOONGSON_PCI_HIT1_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x5c)
#define LOONGSON_PCI_HIT2_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x60)
#define LOONGSON_PCI_HIT2_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x64)
/* PXArb Config & Status */
#define LOONGSON_PXARB_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x68)
#define LOONGSON_PXARB_STATUS LOONGSON_REG(LOONGSON_REGBASE + 0x6c)
/* Chip Config registor of each physical cpu package, PRid >= Loongson-2F */
#define LOONGSON_CHIPCFG (void __iomem *)TO_UNCAC(0x1fc00180)
/* pcimap */
#define LOONGSON_PCIMAP_PCIMAP_LO0 0x0000003f
#define LOONGSON_PCIMAP_PCIMAP_LO0_SHIFT 0
#define LOONGSON_PCIMAP_PCIMAP_LO1 0x00000fc0
#define LOONGSON_PCIMAP_PCIMAP_LO1_SHIFT 6
#define LOONGSON_PCIMAP_PCIMAP_LO2 0x0003f000
#define LOONGSON_PCIMAP_PCIMAP_LO2_SHIFT 12
#define LOONGSON_PCIMAP_PCIMAP_2 0x00040000
#define LOONGSON_PCIMAP_WIN(WIN, ADDR) \
((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6))
#ifdef CONFIG_CPU_SUPPORTS_CPUFREQ
#include <linux/cpufreq.h>
extern struct cpufreq_frequency_table loongson2_clockmod_table[];
#endif
/*
* address windows configuration module
*
* loongson2e do not have this module
*/
#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
/* address window config module base address */
#define LOONGSON_ADDRWINCFG_BASE 0x3ff00000ul
#define LOONGSON_ADDRWINCFG_SIZE 0x180
extern unsigned long _loongson_addrwincfg_base;
#define LOONGSON_ADDRWINCFG(offset) \
(*(volatile u64 *)(_loongson_addrwincfg_base + (offset)))
#define CPU_WIN0_BASE LOONGSON_ADDRWINCFG(0x00)
#define CPU_WIN1_BASE LOONGSON_ADDRWINCFG(0x08)
#define CPU_WIN2_BASE LOONGSON_ADDRWINCFG(0x10)
#define CPU_WIN3_BASE LOONGSON_ADDRWINCFG(0x18)
#define CPU_WIN0_MASK LOONGSON_ADDRWINCFG(0x20)
#define CPU_WIN1_MASK LOONGSON_ADDRWINCFG(0x28)
#define CPU_WIN2_MASK LOONGSON_ADDRWINCFG(0x30)
#define CPU_WIN3_MASK LOONGSON_ADDRWINCFG(0x38)
#define CPU_WIN0_MMAP LOONGSON_ADDRWINCFG(0x40)
#define CPU_WIN1_MMAP LOONGSON_ADDRWINCFG(0x48)
#define CPU_WIN2_MMAP LOONGSON_ADDRWINCFG(0x50)
#define CPU_WIN3_MMAP LOONGSON_ADDRWINCFG(0x58)
#define PCIDMA_WIN0_BASE LOONGSON_ADDRWINCFG(0x60)
#define PCIDMA_WIN1_BASE LOONGSON_ADDRWINCFG(0x68)
#define PCIDMA_WIN2_BASE LOONGSON_ADDRWINCFG(0x70)
#define PCIDMA_WIN3_BASE LOONGSON_ADDRWINCFG(0x78)
#define PCIDMA_WIN0_MASK LOONGSON_ADDRWINCFG(0x80)
#define PCIDMA_WIN1_MASK LOONGSON_ADDRWINCFG(0x88)
#define PCIDMA_WIN2_MASK LOONGSON_ADDRWINCFG(0x90)
#define PCIDMA_WIN3_MASK LOONGSON_ADDRWINCFG(0x98)
#define PCIDMA_WIN0_MMAP LOONGSON_ADDRWINCFG(0xa0)
#define PCIDMA_WIN1_MMAP LOONGSON_ADDRWINCFG(0xa8)
#define PCIDMA_WIN2_MMAP LOONGSON_ADDRWINCFG(0xb0)
#define PCIDMA_WIN3_MMAP LOONGSON_ADDRWINCFG(0xb8)
#define ADDRWIN_WIN0 0
#define ADDRWIN_WIN1 1
#define ADDRWIN_WIN2 2
#define ADDRWIN_WIN3 3
#define ADDRWIN_MAP_DST_DDR 0
#define ADDRWIN_MAP_DST_PCI 1
#define ADDRWIN_MAP_DST_LIO 1
/*
* s: CPU, PCIDMA
* d: DDR, PCI, LIO
* win: 0, 1, 2, 3
* src: map source
* dst: map destination
* size: ~mask + 1
*/
#define LOONGSON_ADDRWIN_CFG(s, d, w, src, dst, size) do {\
s##_WIN##w##_BASE = (src); \
s##_WIN##w##_MMAP = (dst) | ADDRWIN_MAP_DST_##d; \
s##_WIN##w##_MASK = ~(size-1); \
} while (0)
#define LOONGSON_ADDRWIN_CPUTOPCI(win, src, dst, size) \
LOONGSON_ADDRWIN_CFG(CPU, PCI, win, src, dst, size)
#define LOONGSON_ADDRWIN_CPUTODDR(win, src, dst, size) \
LOONGSON_ADDRWIN_CFG(CPU, DDR, win, src, dst, size)
#define LOONGSON_ADDRWIN_PCITODDR(win, src, dst, size) \
LOONGSON_ADDRWIN_CFG(PCIDMA, DDR, win, src, dst, size)
#endif /* ! CONFIG_CPU_SUPPORTS_ADDRWINCFG */
#endif /* __ASM_MACH_LOONGSON2EF_LOONGSON_H */

View File

@ -4,8 +4,8 @@
* Author: Wu Zhangjin <wuzhangjin@gmail.com>
*/
#ifndef __ASM_MACH_LOONGSON64_MACHINE_H
#define __ASM_MACH_LOONGSON64_MACHINE_H
#ifndef __ASM_MACH_LOONGSON2EF_MACHINE_H
#define __ASM_MACH_LOONGSON2EF_MACHINE_H
#ifdef CONFIG_LEMOTE_FULOONG2E
@ -20,10 +20,4 @@
#endif
#ifdef CONFIG_LOONGSON_MACH3X
#define LOONGSON_MACHTYPE MACH_LOONGSON_GENERIC
#endif /* CONFIG_LOONGSON_MACH3X */
#endif /* __ASM_MACH_LOONGSON64_MACHINE_H */
#endif /* __ASM_MACH_LOONGSON2EF_MACHINE_H */

View File

@ -0,0 +1,36 @@
/*
* 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) 1998, 2001, 03, 07 by Ralf Baechle (ralf@linux-mips.org)
*
* RTC routines for PC style attached Dallas chip.
*/
#ifndef __ASM_MACH_LOONGSON2EF_MC146818RTC_H
#define __ASM_MACH_LOONGSON2EF_MC146818RTC_H
#include <linux/io.h>
#define RTC_PORT(x) (0x70 + (x))
#define RTC_IRQ 8
static inline unsigned char CMOS_READ(unsigned long addr)
{
outb_p(addr, RTC_PORT(0));
return inb_p(RTC_PORT(1));
}
static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
{
outb_p(addr, RTC_PORT(0));
outb_p(data, RTC_PORT(1));
}
#define RTC_ALWAYS_BCD 0
#ifndef mc146818_decode_year
#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970)
#endif
#endif /* __ASM_MACH_LOONGSON2EF_MC146818RTC_H */

View File

@ -4,8 +4,8 @@
* Author: Wu Zhangjin <wuzhangjin@gmail.com>
*/
#ifndef __ASM_MACH_LOONGSON64_MEM_H
#define __ASM_MACH_LOONGSON64_MEM_H
#ifndef __ASM_MACH_LOONGSON2EF_MEM_H
#define __ASM_MACH_LOONGSON2EF_MEM_H
/*
* high memory space
@ -34,4 +34,4 @@
#define LOONGSON_MMIO_MEM_END 0x80000000
#endif
#endif /* __ASM_MACH_LOONGSON64_MEM_H */
#endif /* __ASM_MACH_LOONGSON2EF_MEM_H */

View File

@ -0,0 +1,46 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2008 Zhang Le <r0bertz@gentoo.org>
* Copyright (c) 2009 Wu Zhangjin <wuzhangjin@gmail.com>
*/
#ifndef __ASM_MACH_LOONGSON2EF_PCI_H_
#define __ASM_MACH_LOONGSON2EF_PCI_H_
extern struct pci_ops loongson_pci_ops;
/* this is an offset from mips_io_port_base */
#define LOONGSON_PCI_IO_START 0x00004000UL
#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
/*
* we use address window2 to map cpu address space to pci space
* window2: cpu [1G, 2G] -> pci [1G, 2G]
* why not use window 0 & 1? because they are used by cpu when booting.
* window0: cpu [0, 256M] -> ddr [0, 256M]
* window1: cpu [256M, 512M] -> pci [256M, 512M]
*/
/* the smallest LOONGSON_CPU_MEM_SRC can be 512M */
#define LOONGSON_CPU_MEM_SRC 0x40000000ul /* 1G */
#define LOONGSON_PCI_MEM_DST LOONGSON_CPU_MEM_SRC
#define LOONGSON_PCI_MEM_START LOONGSON_PCI_MEM_DST
#define LOONGSON_PCI_MEM_END (0x80000000ul-1) /* 2G */
#define MMAP_CPUTOPCI_SIZE (LOONGSON_PCI_MEM_END - \
LOONGSON_PCI_MEM_START + 1)
#else /* loongson2f/32bit & loongson2e */
/* this pci memory space is mapped by pcimap in pci.c */
#define LOONGSON_PCI_MEM_START LOONGSON_PCILO1_BASE
#define LOONGSON_PCI_MEM_END (LOONGSON_PCILO1_BASE + 0x04000000 * 2)
/* this is an offset from mips_io_port_base */
#define LOONGSON_PCI_IO_START 0x00004000UL
#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */
#endif /* !__ASM_MACH_LOONGSON2EF_PCI_H_ */

View File

@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_MACH_LOONGSON2EF_SPACES_H_
#define __ASM_MACH_LOONGSON2EF_SPACES_H_
#if defined(CONFIG_64BIT)
#define CAC_BASE _AC(0x9800000000000000, UL)
#endif /* CONFIG_64BIT */
#include <asm/mach-generic/spaces.h>
#endif

View File

@ -1,20 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
*/
#ifndef __ASM_MACH_LOONGSON32_PROM_H
#define __ASM_MACH_LOONGSON32_PROM_H
#include <linux/io.h>
#include <linux/init.h>
#include <linux/irq.h>
/* environment arguments from bootloader */
extern unsigned long memsize, highmemsize;
/* loongson-specific command line, env and memory initialization */
extern char *prom_getenv(char *name);
extern void __init prom_init_cmdline(void);
#endif /* __ASM_MACH_LOONGSON32_PROM_H */

View File

@ -43,11 +43,8 @@
#define cpu_has_vint 0
#define cpu_has_vtag_icache 0
#define cpu_has_watch 1
#ifdef CONFIG_CPU_LOONGSON3
#define cpu_has_wsbh 1
#define cpu_has_ic_fills_f_dc 1
#define cpu_hwrena_impl_bits 0xc0000000
#endif
#endif /* __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H */

View File

@ -4,8 +4,6 @@
#include <boot_param.h>
#ifdef CONFIG_CPU_LOONGSON3
/* cpu core interrupt numbers */
#define MIPS_CPU_IRQ_BASE 56
@ -35,8 +33,6 @@
#define LOONGSON_INT_COREx_INTy(x, y) (1<<(x) | 1<<(y+4)) /* route to int y of core x */
#endif
extern void fixup_irqs(void);
extern void loongson3_ipi_interrupt(struct pt_regs *regs);

View File

@ -17,7 +17,6 @@
* Override macros used in arch/mips/kernel/head.S.
*/
.macro kernel_entry_setup
#ifdef CONFIG_CPU_LOONGSON3
.set push
.set mips64
/* Set LPA on LOONGSON3 config3 */
@ -30,23 +29,29 @@
mtc0 t0, CP0_PAGEGRAIN
/* Enable STFill Buffer */
mfc0 t0, CP0_PRID
/* Loongson-3A R4+ */
andi t1, t0, PRID_IMP_MASK
li t2, PRID_IMP_LOONGSON_64G
beq t1, t2, 1f
nop
/* Loongson-3A R2/R3 */
andi t0, (PRID_IMP_MASK | PRID_REV_MASK)
slti t0, (PRID_IMP_LOONGSON_64 | PRID_REV_LOONGSON3A_R2_0)
bnez t0, 1f
slti t0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0)
bnez t0, 2f
nop
1:
mfc0 t0, CP0_CONFIG6
or t0, 0x100
mtc0 t0, CP0_CONFIG6
1:
2:
_ehb
.set pop
#endif
.endm
/*
* Do SMP slave processor setup.
*/
.macro smp_slave_setup
#ifdef CONFIG_CPU_LOONGSON3
.set push
.set mips64
/* Set LPA on LOONGSON3 config3 */
@ -59,16 +64,23 @@
mtc0 t0, CP0_PAGEGRAIN
/* Enable STFill Buffer */
mfc0 t0, CP0_PRID
/* Loongson-3A R4+ */
andi t1, t0, PRID_IMP_MASK
li t2, PRID_IMP_LOONGSON_64G
beq t1, t2, 1f
nop
/* Loongson-3A R2/R3 */
andi t0, (PRID_IMP_MASK | PRID_REV_MASK)
slti t0, (PRID_IMP_LOONGSON_64 | PRID_REV_LOONGSON3A_R2_0)
bnez t0, 1f
slti t0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0)
bnez t0, 2f
nop
1:
mfc0 t0, CP0_CONFIG6
or t0, 0x100
mtc0 t0, CP0_CONFIG6
1:
2:
_ehb
.set pop
#endif
.endm
#endif /* __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H */

View File

@ -12,8 +12,6 @@
#include <linux/irq.h>
#include <boot_param.h>
/* loongson internal northbridge initialization */
extern void bonito_irq_init(void);
/* machine-specific reboot/halt operation */
extern void mach_prepare_reboot(void);
@ -26,25 +24,9 @@ extern const struct plat_smp_ops loongson3_smp_ops;
/* loongson-specific command line, env and memory initialization */
extern void __init prom_init_memory(void);
extern void __init prom_init_cmdline(void);
extern void __init prom_init_machtype(void);
extern void __init prom_init_env(void);
#ifdef CONFIG_LOONGSON_UART_BASE
extern unsigned long _loongson_uart_base[], loongson_uart_base[];
extern void prom_init_loongson_uart_base(void);
#endif
static inline void prom_init_uart_base(void)
{
#ifdef CONFIG_LOONGSON_UART_BASE
prom_init_loongson_uart_base();
#endif
}
/* irq operation functions */
extern void bonito_irqdispatch(void);
extern void __init bonito_irq_init(void);
extern void __init mach_init_irq(void);
extern void mach_irq_dispatch(unsigned int pending);
extern int mach_i8259_irq(void);
@ -64,17 +46,6 @@ extern int mach_i8259_irq(void);
#define LOONGSON3_REG32(base, x) \
(*(volatile u32 *)((char *)TO_UNCAC(base) + (x)))
#define LOONGSON_IRQ_BASE 32
#define LOONGSON2_PERFCNT_IRQ (MIPS_CPU_IRQ_BASE + 6) /* cpu perf counter */
#include <linux/interrupt.h>
static inline void do_perfcnt_IRQ(void)
{
#if IS_ENABLED(CONFIG_OPROFILE)
do_IRQ(LOONGSON2_PERFCNT_IRQ);
#endif
}
#define LOONGSON_FLASH_BASE 0x1c000000
#define LOONGSON_FLASH_SIZE 0x02000000 /* 32M */
#define LOONGSON_FLASH_TOP (LOONGSON_FLASH_BASE+LOONGSON_FLASH_SIZE-1)
@ -109,11 +80,7 @@ static inline void do_perfcnt_IRQ(void)
#define LOONGSON_PCICFG_SIZE 0x00000800 /* 2K */
#define LOONGSON_PCICFG_TOP (LOONGSON_PCICFG_BASE+LOONGSON_PCICFG_SIZE-1)
#ifdef CONFIG_CPU_LOONGSON3
#define LOONGSON_PCIIO_BASE loongson_sysconf.pci_io_base
#else
#define LOONGSON_PCIIO_BASE 0x1fd00000
#endif
#define LOONGSON_PCIIO_SIZE 0x00100000 /* 1M */
#define LOONGSON_PCIIO_TOP (LOONGSON_PCIIO_BASE+LOONGSON_PCIIO_SIZE-1)
@ -270,86 +237,4 @@ extern u64 loongson_freqctrl[MAX_PACKAGES];
#define LOONGSON_PCIMAP_WIN(WIN, ADDR) \
((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6))
#ifdef CONFIG_CPU_SUPPORTS_CPUFREQ
#include <linux/cpufreq.h>
extern struct cpufreq_frequency_table loongson2_clockmod_table[];
#endif
/*
* address windows configuration module
*
* loongson2e do not have this module
*/
#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
/* address window config module base address */
#define LOONGSON_ADDRWINCFG_BASE 0x3ff00000ul
#define LOONGSON_ADDRWINCFG_SIZE 0x180
extern unsigned long _loongson_addrwincfg_base;
#define LOONGSON_ADDRWINCFG(offset) \
(*(volatile u64 *)(_loongson_addrwincfg_base + (offset)))
#define CPU_WIN0_BASE LOONGSON_ADDRWINCFG(0x00)
#define CPU_WIN1_BASE LOONGSON_ADDRWINCFG(0x08)
#define CPU_WIN2_BASE LOONGSON_ADDRWINCFG(0x10)
#define CPU_WIN3_BASE LOONGSON_ADDRWINCFG(0x18)
#define CPU_WIN0_MASK LOONGSON_ADDRWINCFG(0x20)
#define CPU_WIN1_MASK LOONGSON_ADDRWINCFG(0x28)
#define CPU_WIN2_MASK LOONGSON_ADDRWINCFG(0x30)
#define CPU_WIN3_MASK LOONGSON_ADDRWINCFG(0x38)
#define CPU_WIN0_MMAP LOONGSON_ADDRWINCFG(0x40)
#define CPU_WIN1_MMAP LOONGSON_ADDRWINCFG(0x48)
#define CPU_WIN2_MMAP LOONGSON_ADDRWINCFG(0x50)
#define CPU_WIN3_MMAP LOONGSON_ADDRWINCFG(0x58)
#define PCIDMA_WIN0_BASE LOONGSON_ADDRWINCFG(0x60)
#define PCIDMA_WIN1_BASE LOONGSON_ADDRWINCFG(0x68)
#define PCIDMA_WIN2_BASE LOONGSON_ADDRWINCFG(0x70)
#define PCIDMA_WIN3_BASE LOONGSON_ADDRWINCFG(0x78)
#define PCIDMA_WIN0_MASK LOONGSON_ADDRWINCFG(0x80)
#define PCIDMA_WIN1_MASK LOONGSON_ADDRWINCFG(0x88)
#define PCIDMA_WIN2_MASK LOONGSON_ADDRWINCFG(0x90)
#define PCIDMA_WIN3_MASK LOONGSON_ADDRWINCFG(0x98)
#define PCIDMA_WIN0_MMAP LOONGSON_ADDRWINCFG(0xa0)
#define PCIDMA_WIN1_MMAP LOONGSON_ADDRWINCFG(0xa8)
#define PCIDMA_WIN2_MMAP LOONGSON_ADDRWINCFG(0xb0)
#define PCIDMA_WIN3_MMAP LOONGSON_ADDRWINCFG(0xb8)
#define ADDRWIN_WIN0 0
#define ADDRWIN_WIN1 1
#define ADDRWIN_WIN2 2
#define ADDRWIN_WIN3 3
#define ADDRWIN_MAP_DST_DDR 0
#define ADDRWIN_MAP_DST_PCI 1
#define ADDRWIN_MAP_DST_LIO 1
/*
* s: CPU, PCIDMA
* d: DDR, PCI, LIO
* win: 0, 1, 2, 3
* src: map source
* dst: map destination
* size: ~mask + 1
*/
#define LOONGSON_ADDRWIN_CFG(s, d, w, src, dst, size) do {\
s##_WIN##w##_BASE = (src); \
s##_WIN##w##_MMAP = (dst) | ADDRWIN_MAP_DST_##d; \
s##_WIN##w##_MASK = ~(size-1); \
} while (0)
#define LOONGSON_ADDRWIN_CPUTOPCI(win, src, dst, size) \
LOONGSON_ADDRWIN_CFG(CPU, PCI, win, src, dst, size)
#define LOONGSON_ADDRWIN_CPUTODDR(win, src, dst, size) \
LOONGSON_ADDRWIN_CFG(CPU, DDR, win, src, dst, size)
#define LOONGSON_ADDRWIN_PCITODDR(win, src, dst, size) \
LOONGSON_ADDRWIN_CFG(PCIDMA, DDR, win, src, dst, size)
#endif /* ! CONFIG_CPU_SUPPORTS_ADDRWINCFG */
#endif /* __ASM_MACH_LOONGSON64_LOONGSON_H */

View File

@ -0,0 +1,227 @@
/*
* Read/Write Loongson Extension Registers
*/
#ifndef _LOONGSON_REGS_H_
#define _LOONGSON_REGS_H_
#include <linux/types.h>
#include <linux/bits.h>
#include <asm/mipsregs.h>
#include <asm/cpu.h>
static inline bool cpu_has_cfg(void)
{
return ((read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64G);
}
static inline u32 read_cpucfg(u32 reg)
{
u32 __res;
__asm__ __volatile__(
"parse_r __res,%0\n\t"
"parse_r reg,%1\n\t"
".insn \n\t"
".word (0xc8080118 | (reg << 21) | (__res << 11))\n\t"
:"=r"(__res)
:"r"(reg)
:
);
return __res;
}
/* Bit Domains for CFG registers */
#define LOONGSON_CFG0 0x0
#define LOONGSON_CFG0_PRID GENMASK(31, 0)
#define LOONGSON_CFG1 0x1
#define LOONGSON_CFG1_FP BIT(0)
#define LOONGSON_CFG1_FPREV GENMASK(3, 1)
#define LOONGSON_CFG1_MMI BIT(4)
#define LOONGSON_CFG1_MSA1 BIT(5)
#define LOONGSON_CFG1_MSA2 BIT(6)
#define LOONGSON_CFG1_CGP BIT(7)
#define LOONGSON_CFG1_WRP BIT(8)
#define LOONGSON_CFG1_LSX1 BIT(9)
#define LOONGSON_CFG1_LSX2 BIT(10)
#define LOONGSON_CFG1_LASX BIT(11)
#define LOONGSON_CFG1_R6FXP BIT(12)
#define LOONGSON_CFG1_R6CRCP BIT(13)
#define LOONGSON_CFG1_R6FPP BIT(14)
#define LOONGSON_CFG1_CNT64 BIT(15)
#define LOONGSON_CFG1_LSLDR0 BIT(16)
#define LOONGSON_CFG1_LSPREF BIT(17)
#define LOONGSON_CFG1_LSPREFX BIT(18)
#define LOONGSON_CFG1_LSSYNCI BIT(19)
#define LOONGSON_CFG1_LSUCA BIT(20)
#define LOONGSON_CFG1_LLSYNC BIT(21)
#define LOONGSON_CFG1_TGTSYNC BIT(22)
#define LOONGSON_CFG1_LLEXC BIT(23)
#define LOONGSON_CFG1_SCRAND BIT(24)
#define LOONGSON_CFG1_MUALP BIT(25)
#define LOONGSON_CFG1_KMUALEN BIT(26)
#define LOONGSON_CFG1_ITLBT BIT(27)
#define LOONGSON_CFG1_LSUPERF BIT(28)
#define LOONGSON_CFG1_SFBP BIT(29)
#define LOONGSON_CFG1_CDMAP BIT(30)
#define LOONGSON_CFG2 0x2
#define LOONGSON_CFG2_LEXT1 BIT(0)
#define LOONGSON_CFG2_LEXT2 BIT(1)
#define LOONGSON_CFG2_LEXT3 BIT(2)
#define LOONGSON_CFG2_LSPW BIT(3)
#define LOONGSON_CFG2_LBT1 BIT(4)
#define LOONGSON_CFG2_LBT2 BIT(5)
#define LOONGSON_CFG2_LBT3 BIT(6)
#define LOONGSON_CFG2_LBTMMU BIT(7)
#define LOONGSON_CFG2_LPMP BIT(8)
#define LOONGSON_CFG2_LPMPREV GENMASK(11, 9)
#define LOONGSON_CFG2_LAMO BIT(12)
#define LOONGSON_CFG2_LPIXU BIT(13)
#define LOONGSON_CFG2_LPIXUN BIT(14)
#define LOONGSON_CFG2_LZVP BIT(15)
#define LOONGSON_CFG2_LZVREV GENMASK(18, 16)
#define LOONGSON_CFG2_LGFTP BIT(19)
#define LOONGSON_CFG2_LGFTPREV GENMASK(22, 20)
#define LOONGSON_CFG2_LLFTP BIT(23)
#define LOONGSON_CFG2_LLFTPREV GENMASK(26, 24)
#define LOONGSON_CFG2_LCSRP BIT(27)
#define LOONGSON_CFG2_LDISBLIKELY BIT(28)
#define LOONGSON_CFG3 0x3
#define LOONGSON_CFG3_LCAMP BIT(0)
#define LOONGSON_CFG3_LCAMREV GENMASK(3, 1)
#define LOONGSON_CFG3_LCAMNUM GENMASK(11, 4)
#define LOONGSON_CFG3_LCAMKW GENMASK(19, 12)
#define LOONGSON_CFG3_LCAMVW GENMASK(27, 20)
#define LOONGSON_CFG4 0x4
#define LOONGSON_CFG4_CCFREQ GENMASK(31, 0)
#define LOONGSON_CFG5 0x5
#define LOONGSON_CFG5_CFM GENMASK(15, 0)
#define LOONGSON_CFG5_CFD GENMASK(31, 16)
#define LOONGSON_CFG6 0x6
#define LOONGSON_CFG7 0x7
#define LOONGSON_CFG7_GCCAEQRP BIT(0)
#define LOONGSON_CFG7_UCAWINP BIT(1)
static inline bool cpu_has_csr(void)
{
if (cpu_has_cfg())
return (read_cpucfg(LOONGSON_CFG2) & LOONGSON_CFG2_LCSRP);
return false;
}
static inline u32 csr_readl(u32 reg)
{
u32 __res;
/* RDCSR reg, val */
__asm__ __volatile__(
"parse_r __res,%0\n\t"
"parse_r reg,%1\n\t"
".insn \n\t"
".word (0xc8000118 | (reg << 21) | (__res << 11))\n\t"
:"=r"(__res)
:"r"(reg)
:
);
return __res;
}
static inline u64 csr_readq(u32 reg)
{
u64 __res;
/* DWRCSR reg, val */
__asm__ __volatile__(
"parse_r __res,%0\n\t"
"parse_r reg,%1\n\t"
".insn \n\t"
".word (0xc8020118 | (reg << 21) | (__res << 11))\n\t"
:"=r"(__res)
:"r"(reg)
:
);
return __res;
}
static inline void csr_writel(u32 val, u32 reg)
{
/* WRCSR reg, val */
__asm__ __volatile__(
"parse_r reg,%0\n\t"
"parse_r val,%1\n\t"
".insn \n\t"
".word (0xc8010118 | (reg << 21) | (val << 11))\n\t"
:
:"r"(reg),"r"(val)
:
);
}
static inline void csr_writeq(u64 val, u32 reg)
{
/* DWRCSR reg, val */
__asm__ __volatile__(
"parse_r reg,%0\n\t"
"parse_r val,%1\n\t"
".insn \n\t"
".word (0xc8030118 | (reg << 21) | (val << 11))\n\t"
:
:"r"(reg),"r"(val)
:
);
}
/* Public CSR Register can also be accessed with regular addresses */
#define CSR_PUBLIC_MMIO_BASE 0x1fe00000
#define MMIO_CSR(x) (void *)TO_UNCAC(CSR_PUBLIC_MMIO_BASE + x)
#define LOONGSON_CSR_FEATURES 0x8
#define LOONGSON_CSRF_TEMP BIT(0)
#define LOONGSON_CSRF_NODECNT BIT(1)
#define LOONGSON_CSRF_MSI BIT(2)
#define LOONGSON_CSRF_EXTIOI BIT(3)
#define LOONGSON_CSRF_IPI BIT(4)
#define LOONGSON_CSRF_FREQ BIT(5)
#define LOONGSON_CSR_VENDOR 0x10 /* Vendor name string, should be "Loongson" */
#define LOONGSON_CSR_CPUNAME 0x20 /* Processor name string */
#define LOONGSON_CSR_NODECNT 0x408
#define LOONGSON_CSR_CPUTEMP 0x428
/* PerCore CSR, only accessable by local cores */
#define LOONGSON_CSR_IPI_STATUS 0x1000
#define LOONGSON_CSR_IPI_EN 0x1004
#define LOONGSON_CSR_IPI_SET 0x1008
#define LOONGSON_CSR_IPI_CLEAR 0x100c
#define LOONGSON_CSR_IPI_SEND 0x1040
#define CSR_IPI_SEND_IP_SHIFT 0
#define CSR_IPI_SEND_CPU_SHIFT 16
#define CSR_IPI_SEND_BLOCK BIT(31)
static inline u64 drdtime(void)
{
int rID = 0;
u64 val = 0;
__asm__ __volatile__(
"parse_r rID,%0\n\t"
"parse_r val,%1\n\t"
".insn \n\t"
".word (0xc8090118 | (rID << 21) | (val << 11))\n\t"
:"=r"(rID),"=r"(val)
:
);
return val;
}
#endif

View File

@ -6,8 +6,8 @@
* Huacai Chen, chenhc@lemote.com
* Xiaofu Meng, Shuangshuang Zhang
*/
#ifndef _ASM_MACH_MMZONE_H
#define _ASM_MACH_MMZONE_H
#ifndef _ASM_MACH_LOONGSON64_MMZONE_H
#define _ASM_MACH_LOONGSON64_MMZONE_H
#include <boot_param.h>
#define NODE_ADDRSPACE_SHIFT 44
@ -19,30 +19,9 @@
#define pa_to_nid(addr) (((addr) & 0xf00000000000) >> NODE_ADDRSPACE_SHIFT)
#define nid_to_addrbase(nid) ((nid) << NODE_ADDRSPACE_SHIFT)
#define LEVELS_PER_SLICE 128
extern struct pglist_data *__node_data[];
struct slice_data {
unsigned long irq_enable_mask[2];
int level_to_irq[LEVELS_PER_SLICE];
};
struct hub_data {
cpumask_t h_cpus;
unsigned long slice_map;
unsigned long irq_alloc_mask[2];
struct slice_data slice[2];
};
struct node_data {
struct pglist_data pglist;
struct hub_data hub;
cpumask_t cpumask;
};
extern struct node_data *__node_data[];
#define NODE_DATA(n) (&__node_data[(n)]->pglist)
#define hub_data(n) (&__node_data[(n)]->hub)
#define NODE_DATA(n) (__node_data[n])
extern void setup_zero_pages(void);
extern void __init prom_init_numa_memory(void);

View File

@ -12,39 +12,8 @@ extern struct pci_ops loongson_pci_ops;
/* this is an offset from mips_io_port_base */
#define LOONGSON_PCI_IO_START 0x00004000UL
#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
/*
* we use address window2 to map cpu address space to pci space
* window2: cpu [1G, 2G] -> pci [1G, 2G]
* why not use window 0 & 1? because they are used by cpu when booting.
* window0: cpu [0, 256M] -> ddr [0, 256M]
* window1: cpu [256M, 512M] -> pci [256M, 512M]
*/
/* the smallest LOONGSON_CPU_MEM_SRC can be 512M */
#define LOONGSON_CPU_MEM_SRC 0x40000000ul /* 1G */
#define LOONGSON_PCI_MEM_DST LOONGSON_CPU_MEM_SRC
#define LOONGSON_PCI_MEM_START LOONGSON_PCI_MEM_DST
#define LOONGSON_PCI_MEM_END (0x80000000ul-1) /* 2G */
#define MMAP_CPUTOPCI_SIZE (LOONGSON_PCI_MEM_END - \
LOONGSON_PCI_MEM_START + 1)
#else /* loongson2f/32bit & loongson2e */
/* this pci memory space is mapped by pcimap in pci.c */
#ifdef CONFIG_CPU_LOONGSON3
#define LOONGSON_PCI_MEM_START 0x40000000UL
#define LOONGSON_PCI_MEM_END 0x7effffffUL
#else
#define LOONGSON_PCI_MEM_START LOONGSON_PCILO1_BASE
#define LOONGSON_PCI_MEM_END (LOONGSON_PCILO1_BASE + 0x04000000 * 2)
#endif
/* this is an offset from mips_io_port_base */
#define LOONGSON_PCI_IO_START 0x00004000UL
#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */
#endif /* !__ASM_MACH_LOONGSON64_PCI_H_ */

View File

@ -5,7 +5,9 @@
#ifdef CONFIG_NUMA
#define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2)
#define cpumask_of_node(node) (&__node_data[(node)]->cpumask)
extern cpumask_t __node_cpumask[];
#define cpumask_of_node(node) (&__node_cpumask[node])
struct pci_bus;
extern int pcibus_to_node(struct pci_bus *);

View File

@ -689,6 +689,9 @@
#define MIPS_CONF7_IAR (_ULCAST_(1) << 10)
#define MIPS_CONF7_AR (_ULCAST_(1) << 16)
/* Ingenic HPTLB off bits */
#define XBURST_PAGECTRL_HPTLB_DIS 0xa9000000
/* Ingenic Config7 bits */
#define MIPS_CONF7_BTB_LOOP_EN (_ULCAST_(1) << 4)
@ -1971,6 +1974,9 @@ do { \
#define read_c0_brcm_sleepcount() __read_32bit_c0_register($22, 7)
#define write_c0_brcm_sleepcount(val) __write_32bit_c0_register($22, 7, val)
/* Ingenic page ctrl register */
#define write_c0_page_ctrl(val) __write_32bit_c0_register($5, 4, val)
/*
* Macros to access the guest system control coprocessor
*/

View File

@ -119,12 +119,12 @@ search_module_dbetables(unsigned long addr)
#define MODULE_PROC_FAMILY "RM7000 "
#elif defined CONFIG_CPU_SB1
#define MODULE_PROC_FAMILY "SB1 "
#elif defined CONFIG_CPU_LOONGSON1
#define MODULE_PROC_FAMILY "LOONGSON1 "
#elif defined CONFIG_CPU_LOONGSON2
#define MODULE_PROC_FAMILY "LOONGSON2 "
#elif defined CONFIG_CPU_LOONGSON3
#define MODULE_PROC_FAMILY "LOONGSON3 "
#elif defined CONFIG_CPU_LOONGSON32
#define MODULE_PROC_FAMILY "LOONGSON32 "
#elif defined CONFIG_CPU_LOONGSON2EF
#define MODULE_PROC_FAMILY "LOONGSON2EF "
#elif defined CONFIG_CPU_LOONGSON64
#define MODULE_PROC_FAMILY "LOONGSON64 "
#elif defined CONFIG_CPU_CAVIUM_OCTEON
#define MODULE_PROC_FAMILY "OCTEON "
#elif defined CONFIG_CPU_XLR

View File

@ -807,6 +807,7 @@ struct bridge_controller {
unsigned long intr_addr;
struct irq_domain *domain;
unsigned int pci_int[8];
u32 ioc3_sid[8];
nasid_t nasid;
};

View File

@ -96,9 +96,9 @@ static inline void pud_free(struct mm_struct *mm, pud_t *pud)
free_pages((unsigned long)pud, PUD_ORDER);
}
static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4d, pud_t *pud)
{
set_pgd(pgd, __pgd((unsigned long)pud));
set_p4d(p4d, __p4d((unsigned long)pud));
}
#define __pud_free_tlb(tlb, x, addr) pud_free((tlb)->mm, x)

View File

@ -16,7 +16,6 @@
#include <asm/cachectl.h>
#include <asm/fixmap.h>
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>
#ifdef CONFIG_HIGHMEM
@ -196,14 +195,11 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
#define pte_page(x) pfn_to_page(pte_pfn(x))
#define __pgd_offset(address) pgd_index(address)
#define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
#define __pmd_offset(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
#define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
/* to find an entry in a page-table-directory */

View File

@ -17,11 +17,12 @@
#include <asm/cachectl.h>
#include <asm/fixmap.h>
#define __ARCH_USE_5LEVEL_HACK
#if defined(CONFIG_PAGE_SIZE_64KB) && !defined(CONFIG_MIPS_VA_BITS_48)
#if CONFIG_PGTABLE_LEVELS == 2
#include <asm-generic/pgtable-nopmd.h>
#elif !(defined(CONFIG_PAGE_SIZE_4KB) && defined(CONFIG_MIPS_VA_BITS_48))
#elif CONFIG_PGTABLE_LEVELS == 3
#include <asm-generic/pgtable-nopud.h>
#else
#include <asm-generic/pgtable-nop4d.h>
#endif
/*
@ -186,44 +187,49 @@ extern pud_t invalid_pud_table[PTRS_PER_PUD];
/*
* Empty pgd entries point to the invalid_pud_table.
*/
static inline int pgd_none(pgd_t pgd)
static inline int p4d_none(p4d_t p4d)
{
return pgd_val(pgd) == (unsigned long)invalid_pud_table;
return p4d_val(p4d) == (unsigned long)invalid_pud_table;
}
static inline int pgd_bad(pgd_t pgd)
static inline int p4d_bad(p4d_t p4d)
{
if (unlikely(pgd_val(pgd) & ~PAGE_MASK))
if (unlikely(p4d_val(p4d) & ~PAGE_MASK))
return 1;
return 0;
}
static inline int pgd_present(pgd_t pgd)
static inline int p4d_present(p4d_t p4d)
{
return pgd_val(pgd) != (unsigned long)invalid_pud_table;
return p4d_val(p4d) != (unsigned long)invalid_pud_table;
}
static inline void pgd_clear(pgd_t *pgdp)
static inline void p4d_clear(p4d_t *p4dp)
{
pgd_val(*pgdp) = (unsigned long)invalid_pud_table;
p4d_val(*p4dp) = (unsigned long)invalid_pud_table;
}
#define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
static inline unsigned long pgd_page_vaddr(pgd_t pgd)
static inline unsigned long p4d_page_vaddr(p4d_t p4d)
{
return pgd_val(pgd);
return p4d_val(p4d);
}
static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address)
#define p4d_phys(p4d) virt_to_phys((void *)p4d_val(p4d))
#define p4d_page(p4d) (pfn_to_page(p4d_phys(p4d) >> PAGE_SHIFT))
#define p4d_index(address) (((address) >> P4D_SHIFT) & (PTRS_PER_P4D - 1))
static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address)
{
return (pud_t *)pgd_page_vaddr(*pgd) + pud_index(address);
return (pud_t *)p4d_page_vaddr(*p4d) + pud_index(address);
}
static inline void set_pgd(pgd_t *pgd, pgd_t pgdval)
static inline void set_p4d(p4d_t *p4d, p4d_t p4dval)
{
*pgd = pgdval;
*p4d = p4dval;
}
#endif
@ -314,10 +320,6 @@ static inline void pud_clear(pud_t *pudp)
#define pfn_pmd(pfn, prot) __pmd(((pfn) << _PFN_SHIFT) | pgprot_val(prot))
#endif
#define __pgd_offset(address) pgd_index(address)
#define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
#define __pmd_offset(address) pmd_index(address)
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)

View File

@ -643,17 +643,6 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
#include <asm-generic/pgtable.h>
/*
* uncached accelerated TLB map for video memory access
*/
#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED
#define __HAVE_PHYS_MEM_ACCESS_PROT
struct file;
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot);
#endif
/*
* We provide our own get_unmapped area to cope with the virtual aliasing
* constraints placed on us by the cache architecture.

View File

@ -1,46 +0,0 @@
/*
* 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) 2004 by Ralf Baechle
*
* The cpustart method is a PMC-Sierra's function to start the secondary CPU.
* Stock PMON 2000 has the smpfork, semlock and semunlock methods instead.
*/
#ifndef _ASM_PMON_H
#define _ASM_PMON_H
struct callvectors {
int (*open) (char*, int, int);
int (*close) (int);
int (*read) (int, void*, int);
int (*write) (int, void*, int);
off_t (*lseek) (int, off_t, int);
int (*printf) (const char*, ...);
void (*cacheflush) (void);
char* (*gets) (char*);
union {
int (*smpfork) (unsigned long cp, char *sp);
int (*cpustart) (long, void (*)(void), void *, long);
} _s;
int (*semlock) (int sem);
void (*semunlock) (int sem);
};
extern struct callvectors *debug_vectors;
#define pmon_open(name, flags, mode) debug_vectors->open(name, flage, mode)
#define pmon_close(fd) debug_vectors->close(fd)
#define pmon_read(fd, buf, count) debug_vectors->read(fd, buf, count)
#define pmon_write(fd, buf, count) debug_vectors->write(fd, buf, count)
#define pmon_lseek(fd, off, whence) debug_vectors->lseek(fd, off, whence)
#define pmon_printf(fmt...) debug_vectors->printf(fmt)
#define pmon_cacheflush() debug_vectors->cacheflush()
#define pmon_gets(s) debug_vectors->gets(s)
#define pmon_cpustart(n, f, sp, gp) debug_vectors->_s.cpustart(n, f, sp, gp)
#define pmon_smpfork(cp, sp) debug_vectors->_s.smpfork(cp, sp)
#define pmon_semlock(sem) debug_vectors->semlock(sem)
#define pmon_semunlock(sem) debug_vectors->semunlock(sem)
#endif /* _ASM_PMON_H */

View File

@ -385,7 +385,7 @@ unsigned long get_wchan(struct task_struct *p);
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[29])
#define KSTK_STATUS(tsk) (task_pt_regs(tsk)->cp0_status)
#ifdef CONFIG_CPU_LOONGSON3
#ifdef CONFIG_CPU_LOONGSON64
/*
* Loongson-3's SFB (Store-Fill-Buffer) may buffer writes indefinitely when a
* tight read loop is executed, because reads take priority over writes & the

View File

@ -15,12 +15,14 @@
#include <linux/stringify.h>
#include <asm/asm.h>
#include <asm/asm-eva.h>
#include <asm/cacheops.h>
#include <asm/compiler.h>
#include <asm/cpu-features.h>
#include <asm/cpu-type.h>
#include <asm/mipsmtregs.h>
#include <asm/mmzone.h>
#include <asm/unroll.h>
#include <linux/uaccess.h> /* for uaccess_kernel() */
extern void (*r4k_blast_dcache)(void);
@ -39,16 +41,19 @@ extern void (*r4k_blast_icache)(void);
*/
#define INDEX_BASE CKSEG0
#define cache_op(op,addr) \
#define _cache_op(insn, op, addr) \
__asm__ __volatile__( \
" .set push \n" \
" .set noreorder \n" \
" .set "MIPS_ISA_ARCH_LEVEL" \n" \
" cache %0, %1 \n" \
" " insn("%0", "%1") " \n" \
" .set pop \n" \
: \
: "i" (op), "R" (*(unsigned char *)(addr)))
#define cache_op(op, addr) \
_cache_op(kernel_cache, op, addr)
static inline void flush_icache_line_indexed(unsigned long addr)
{
cache_op(Index_Invalidate_I, addr);
@ -67,7 +72,7 @@ static inline void flush_scache_line_indexed(unsigned long addr)
static inline void flush_icache_line(unsigned long addr)
{
switch (boot_cpu_type()) {
case CPU_LOONGSON2:
case CPU_LOONGSON2EF:
cache_op(Hit_Invalidate_I_Loongson2, addr);
break;
@ -149,7 +154,7 @@ static inline void flush_scache_line(unsigned long addr)
static inline int protected_flush_icache_line(unsigned long addr)
{
switch (boot_cpu_type()) {
case CPU_LOONGSON2:
case CPU_LOONGSON2EF:
return protected_cache_op(Hit_Invalidate_I_Loongson2, addr);
default:
@ -193,338 +198,10 @@ static inline void invalidate_tcache_page(unsigned long addr)
cache_op(Page_Invalidate_T, addr);
}
#ifndef CONFIG_CPU_MIPSR6
#define cache16_unroll32(base,op) \
__asm__ __volatile__( \
" .set push \n" \
" .set noreorder \n" \
" .set mips3 \n" \
" cache %1, 0x000(%0); cache %1, 0x010(%0) \n" \
" cache %1, 0x020(%0); cache %1, 0x030(%0) \n" \
" cache %1, 0x040(%0); cache %1, 0x050(%0) \n" \
" cache %1, 0x060(%0); cache %1, 0x070(%0) \n" \
" cache %1, 0x080(%0); cache %1, 0x090(%0) \n" \
" cache %1, 0x0a0(%0); cache %1, 0x0b0(%0) \n" \
" cache %1, 0x0c0(%0); cache %1, 0x0d0(%0) \n" \
" cache %1, 0x0e0(%0); cache %1, 0x0f0(%0) \n" \
" cache %1, 0x100(%0); cache %1, 0x110(%0) \n" \
" cache %1, 0x120(%0); cache %1, 0x130(%0) \n" \
" cache %1, 0x140(%0); cache %1, 0x150(%0) \n" \
" cache %1, 0x160(%0); cache %1, 0x170(%0) \n" \
" cache %1, 0x180(%0); cache %1, 0x190(%0) \n" \
" cache %1, 0x1a0(%0); cache %1, 0x1b0(%0) \n" \
" cache %1, 0x1c0(%0); cache %1, 0x1d0(%0) \n" \
" cache %1, 0x1e0(%0); cache %1, 0x1f0(%0) \n" \
" .set pop \n" \
: \
: "r" (base), \
"i" (op));
#define cache32_unroll32(base,op) \
__asm__ __volatile__( \
" .set push \n" \
" .set noreorder \n" \
" .set mips3 \n" \
" cache %1, 0x000(%0); cache %1, 0x020(%0) \n" \
" cache %1, 0x040(%0); cache %1, 0x060(%0) \n" \
" cache %1, 0x080(%0); cache %1, 0x0a0(%0) \n" \
" cache %1, 0x0c0(%0); cache %1, 0x0e0(%0) \n" \
" cache %1, 0x100(%0); cache %1, 0x120(%0) \n" \
" cache %1, 0x140(%0); cache %1, 0x160(%0) \n" \
" cache %1, 0x180(%0); cache %1, 0x1a0(%0) \n" \
" cache %1, 0x1c0(%0); cache %1, 0x1e0(%0) \n" \
" cache %1, 0x200(%0); cache %1, 0x220(%0) \n" \
" cache %1, 0x240(%0); cache %1, 0x260(%0) \n" \
" cache %1, 0x280(%0); cache %1, 0x2a0(%0) \n" \
" cache %1, 0x2c0(%0); cache %1, 0x2e0(%0) \n" \
" cache %1, 0x300(%0); cache %1, 0x320(%0) \n" \
" cache %1, 0x340(%0); cache %1, 0x360(%0) \n" \
" cache %1, 0x380(%0); cache %1, 0x3a0(%0) \n" \
" cache %1, 0x3c0(%0); cache %1, 0x3e0(%0) \n" \
" .set pop \n" \
: \
: "r" (base), \
"i" (op));
#define cache64_unroll32(base,op) \
__asm__ __volatile__( \
" .set push \n" \
" .set noreorder \n" \
" .set mips3 \n" \
" cache %1, 0x000(%0); cache %1, 0x040(%0) \n" \
" cache %1, 0x080(%0); cache %1, 0x0c0(%0) \n" \
" cache %1, 0x100(%0); cache %1, 0x140(%0) \n" \
" cache %1, 0x180(%0); cache %1, 0x1c0(%0) \n" \
" cache %1, 0x200(%0); cache %1, 0x240(%0) \n" \
" cache %1, 0x280(%0); cache %1, 0x2c0(%0) \n" \
" cache %1, 0x300(%0); cache %1, 0x340(%0) \n" \
" cache %1, 0x380(%0); cache %1, 0x3c0(%0) \n" \
" cache %1, 0x400(%0); cache %1, 0x440(%0) \n" \
" cache %1, 0x480(%0); cache %1, 0x4c0(%0) \n" \
" cache %1, 0x500(%0); cache %1, 0x540(%0) \n" \
" cache %1, 0x580(%0); cache %1, 0x5c0(%0) \n" \
" cache %1, 0x600(%0); cache %1, 0x640(%0) \n" \
" cache %1, 0x680(%0); cache %1, 0x6c0(%0) \n" \
" cache %1, 0x700(%0); cache %1, 0x740(%0) \n" \
" cache %1, 0x780(%0); cache %1, 0x7c0(%0) \n" \
" .set pop \n" \
: \
: "r" (base), \
"i" (op));
#define cache128_unroll32(base,op) \
__asm__ __volatile__( \
" .set push \n" \
" .set noreorder \n" \
" .set mips3 \n" \
" cache %1, 0x000(%0); cache %1, 0x080(%0) \n" \
" cache %1, 0x100(%0); cache %1, 0x180(%0) \n" \
" cache %1, 0x200(%0); cache %1, 0x280(%0) \n" \
" cache %1, 0x300(%0); cache %1, 0x380(%0) \n" \
" cache %1, 0x400(%0); cache %1, 0x480(%0) \n" \
" cache %1, 0x500(%0); cache %1, 0x580(%0) \n" \
" cache %1, 0x600(%0); cache %1, 0x680(%0) \n" \
" cache %1, 0x700(%0); cache %1, 0x780(%0) \n" \
" cache %1, 0x800(%0); cache %1, 0x880(%0) \n" \
" cache %1, 0x900(%0); cache %1, 0x980(%0) \n" \
" cache %1, 0xa00(%0); cache %1, 0xa80(%0) \n" \
" cache %1, 0xb00(%0); cache %1, 0xb80(%0) \n" \
" cache %1, 0xc00(%0); cache %1, 0xc80(%0) \n" \
" cache %1, 0xd00(%0); cache %1, 0xd80(%0) \n" \
" cache %1, 0xe00(%0); cache %1, 0xe80(%0) \n" \
" cache %1, 0xf00(%0); cache %1, 0xf80(%0) \n" \
" .set pop \n" \
: \
: "r" (base), \
"i" (op));
#else
/*
* MIPS R6 changed the cache opcode and moved to a 8-bit offset field.
* This means we now need to increment the base register before we flush
* more cache lines
*/
#define cache16_unroll32(base,op) \
__asm__ __volatile__( \
" .set push\n" \
" .set noreorder\n" \
" .set mips64r6\n" \
" .set noat\n" \
" cache %1, 0x000(%0); cache %1, 0x010(%0)\n" \
" cache %1, 0x020(%0); cache %1, 0x030(%0)\n" \
" cache %1, 0x040(%0); cache %1, 0x050(%0)\n" \
" cache %1, 0x060(%0); cache %1, 0x070(%0)\n" \
" cache %1, 0x080(%0); cache %1, 0x090(%0)\n" \
" cache %1, 0x0a0(%0); cache %1, 0x0b0(%0)\n" \
" cache %1, 0x0c0(%0); cache %1, 0x0d0(%0)\n" \
" cache %1, 0x0e0(%0); cache %1, 0x0f0(%0)\n" \
" "__stringify(LONG_ADDIU)" $1, %0, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x010($1)\n" \
" cache %1, 0x020($1); cache %1, 0x030($1)\n" \
" cache %1, 0x040($1); cache %1, 0x050($1)\n" \
" cache %1, 0x060($1); cache %1, 0x070($1)\n" \
" cache %1, 0x080($1); cache %1, 0x090($1)\n" \
" cache %1, 0x0a0($1); cache %1, 0x0b0($1)\n" \
" cache %1, 0x0c0($1); cache %1, 0x0d0($1)\n" \
" cache %1, 0x0e0($1); cache %1, 0x0f0($1)\n" \
" .set pop\n" \
: \
: "r" (base), \
"i" (op));
#define cache32_unroll32(base,op) \
__asm__ __volatile__( \
" .set push\n" \
" .set noreorder\n" \
" .set mips64r6\n" \
" .set noat\n" \
" cache %1, 0x000(%0); cache %1, 0x020(%0)\n" \
" cache %1, 0x040(%0); cache %1, 0x060(%0)\n" \
" cache %1, 0x080(%0); cache %1, 0x0a0(%0)\n" \
" cache %1, 0x0c0(%0); cache %1, 0x0e0(%0)\n" \
" "__stringify(LONG_ADDIU)" $1, %0, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x020($1)\n" \
" cache %1, 0x040($1); cache %1, 0x060($1)\n" \
" cache %1, 0x080($1); cache %1, 0x0a0($1)\n" \
" cache %1, 0x0c0($1); cache %1, 0x0e0($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x020($1)\n" \
" cache %1, 0x040($1); cache %1, 0x060($1)\n" \
" cache %1, 0x080($1); cache %1, 0x0a0($1)\n" \
" cache %1, 0x0c0($1); cache %1, 0x0e0($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100\n" \
" cache %1, 0x000($1); cache %1, 0x020($1)\n" \
" cache %1, 0x040($1); cache %1, 0x060($1)\n" \
" cache %1, 0x080($1); cache %1, 0x0a0($1)\n" \
" cache %1, 0x0c0($1); cache %1, 0x0e0($1)\n" \
" .set pop\n" \
: \
: "r" (base), \
"i" (op));
#define cache64_unroll32(base,op) \
__asm__ __volatile__( \
" .set push\n" \
" .set noreorder\n" \
" .set mips64r6\n" \
" .set noat\n" \
" cache %1, 0x000(%0); cache %1, 0x040(%0)\n" \
" cache %1, 0x080(%0); cache %1, 0x0c0(%0)\n" \
" "__stringify(LONG_ADDIU)" $1, %0, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x040($1)\n" \
" cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x040($1)\n" \
" cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x040($1)\n" \
" cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x040($1)\n" \
" cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x040($1)\n" \
" cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x040($1)\n" \
" cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x040($1)\n" \
" cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \
" .set pop\n" \
: \
: "r" (base), \
"i" (op));
#define cache128_unroll32(base,op) \
__asm__ __volatile__( \
" .set push\n" \
" .set noreorder\n" \
" .set mips64r6\n" \
" .set noat\n" \
" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \
" "__stringify(LONG_ADDIU)" $1, %0, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x080($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x080($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x080($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x080($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x080($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x080($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x080($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x080($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x080($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x080($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x080($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x080($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x080($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x080($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x080($1)\n" \
" "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \
" cache %1, 0x000($1); cache %1, 0x080($1)\n" \
" .set pop\n" \
: \
: "r" (base), \
"i" (op));
#endif /* CONFIG_CPU_MIPSR6 */
/*
* Perform the cache operation specified by op using a user mode virtual
* address while in kernel mode.
*/
#define cache16_unroll32_user(base,op) \
__asm__ __volatile__( \
" .set push \n" \
" .set noreorder \n" \
" .set mips0 \n" \
" .set eva \n" \
" cachee %1, 0x000(%0); cachee %1, 0x010(%0) \n" \
" cachee %1, 0x020(%0); cachee %1, 0x030(%0) \n" \
" cachee %1, 0x040(%0); cachee %1, 0x050(%0) \n" \
" cachee %1, 0x060(%0); cachee %1, 0x070(%0) \n" \
" cachee %1, 0x080(%0); cachee %1, 0x090(%0) \n" \
" cachee %1, 0x0a0(%0); cachee %1, 0x0b0(%0) \n" \
" cachee %1, 0x0c0(%0); cachee %1, 0x0d0(%0) \n" \
" cachee %1, 0x0e0(%0); cachee %1, 0x0f0(%0) \n" \
" cachee %1, 0x100(%0); cachee %1, 0x110(%0) \n" \
" cachee %1, 0x120(%0); cachee %1, 0x130(%0) \n" \
" cachee %1, 0x140(%0); cachee %1, 0x150(%0) \n" \
" cachee %1, 0x160(%0); cachee %1, 0x170(%0) \n" \
" cachee %1, 0x180(%0); cachee %1, 0x190(%0) \n" \
" cachee %1, 0x1a0(%0); cachee %1, 0x1b0(%0) \n" \
" cachee %1, 0x1c0(%0); cachee %1, 0x1d0(%0) \n" \
" cachee %1, 0x1e0(%0); cachee %1, 0x1f0(%0) \n" \
" .set pop \n" \
: \
: "r" (base), \
"i" (op));
#define cache32_unroll32_user(base, op) \
__asm__ __volatile__( \
" .set push \n" \
" .set noreorder \n" \
" .set mips0 \n" \
" .set eva \n" \
" cachee %1, 0x000(%0); cachee %1, 0x020(%0) \n" \
" cachee %1, 0x040(%0); cachee %1, 0x060(%0) \n" \
" cachee %1, 0x080(%0); cachee %1, 0x0a0(%0) \n" \
" cachee %1, 0x0c0(%0); cachee %1, 0x0e0(%0) \n" \
" cachee %1, 0x100(%0); cachee %1, 0x120(%0) \n" \
" cachee %1, 0x140(%0); cachee %1, 0x160(%0) \n" \
" cachee %1, 0x180(%0); cachee %1, 0x1a0(%0) \n" \
" cachee %1, 0x1c0(%0); cachee %1, 0x1e0(%0) \n" \
" cachee %1, 0x200(%0); cachee %1, 0x220(%0) \n" \
" cachee %1, 0x240(%0); cachee %1, 0x260(%0) \n" \
" cachee %1, 0x280(%0); cachee %1, 0x2a0(%0) \n" \
" cachee %1, 0x2c0(%0); cachee %1, 0x2e0(%0) \n" \
" cachee %1, 0x300(%0); cachee %1, 0x320(%0) \n" \
" cachee %1, 0x340(%0); cachee %1, 0x360(%0) \n" \
" cachee %1, 0x380(%0); cachee %1, 0x3a0(%0) \n" \
" cachee %1, 0x3c0(%0); cachee %1, 0x3e0(%0) \n" \
" .set pop \n" \
: \
: "r" (base), \
"i" (op));
#define cache64_unroll32_user(base, op) \
__asm__ __volatile__( \
" .set push \n" \
" .set noreorder \n" \
" .set mips0 \n" \
" .set eva \n" \
" cachee %1, 0x000(%0); cachee %1, 0x040(%0) \n" \
" cachee %1, 0x080(%0); cachee %1, 0x0c0(%0) \n" \
" cachee %1, 0x100(%0); cachee %1, 0x140(%0) \n" \
" cachee %1, 0x180(%0); cachee %1, 0x1c0(%0) \n" \
" cachee %1, 0x200(%0); cachee %1, 0x240(%0) \n" \
" cachee %1, 0x280(%0); cachee %1, 0x2c0(%0) \n" \
" cachee %1, 0x300(%0); cachee %1, 0x340(%0) \n" \
" cachee %1, 0x380(%0); cachee %1, 0x3c0(%0) \n" \
" cachee %1, 0x400(%0); cachee %1, 0x440(%0) \n" \
" cachee %1, 0x480(%0); cachee %1, 0x4c0(%0) \n" \
" cachee %1, 0x500(%0); cachee %1, 0x540(%0) \n" \
" cachee %1, 0x580(%0); cachee %1, 0x5c0(%0) \n" \
" cachee %1, 0x600(%0); cachee %1, 0x640(%0) \n" \
" cachee %1, 0x680(%0); cachee %1, 0x6c0(%0) \n" \
" cachee %1, 0x700(%0); cachee %1, 0x740(%0) \n" \
" cachee %1, 0x780(%0); cachee %1, 0x7c0(%0) \n" \
" .set pop \n" \
: \
: "r" (base), \
"i" (op));
#define cache_unroll(times, insn, op, addr, lsize) do { \
int i = 0; \
unroll(times, _cache_op, insn, op, (addr) + (i++ * (lsize))); \
} while (0)
/* build blast_xxx, blast_xxx_page, blast_xxx_page_indexed */
#define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize, extra) \
@ -539,7 +216,8 @@ static inline void extra##blast_##pfx##cache##lsize(void) \
\
for (ws = 0; ws < ws_end; ws += ws_inc) \
for (addr = start; addr < end; addr += lsize * 32) \
cache##lsize##_unroll32(addr|ws, indexop); \
cache_unroll(32, kernel_cache, indexop, \
addr | ws, lsize); \
} \
\
static inline void extra##blast_##pfx##cache##lsize##_page(unsigned long page) \
@ -548,7 +226,7 @@ static inline void extra##blast_##pfx##cache##lsize##_page(unsigned long page) \
unsigned long end = page + PAGE_SIZE; \
\
do { \
cache##lsize##_unroll32(start, hitop); \
cache_unroll(32, kernel_cache, hitop, start, lsize); \
start += lsize * 32; \
} while (start < end); \
} \
@ -565,7 +243,8 @@ static inline void extra##blast_##pfx##cache##lsize##_page_indexed(unsigned long
\
for (ws = 0; ws < ws_end; ws += ws_inc) \
for (addr = start; addr < end; addr += lsize * 32) \
cache##lsize##_unroll32(addr|ws, indexop); \
cache_unroll(32, kernel_cache, indexop, \
addr | ws, lsize); \
}
__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16, )
@ -596,7 +275,7 @@ static inline void blast_##pfx##cache##lsize##_user_page(unsigned long page) \
unsigned long end = page + PAGE_SIZE; \
\
do { \
cache##lsize##_unroll32_user(start, hitop); \
cache_unroll(32, user_cache, hitop, start, lsize); \
start += lsize * 32; \
} while (start < end); \
}
@ -688,7 +367,8 @@ static inline void blast_##pfx##cache##lsize##_node(long node) \
\
for (ws = 0; ws < ws_end; ws += ws_inc) \
for (addr = start; addr < end; addr += lsize * 32) \
cache##lsize##_unroll32(addr|ws, indexop); \
cache_unroll(32, kernel_cache, indexop, \
addr | ws, lsize); \
}
__BUILD_BLAST_CACHE_NODE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16)

View File

@ -0,0 +1,272 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* HEART chip definitions
*
* Copyright (C) 2004-2007 Stanislaw Skowronek <skylark@unaligned.org>
* 2009 Johannes Dickgreber <tanzy@gmx.de>
* 2007-2015 Joshua Kinard <kumba@gentoo.org>
*/
#ifndef __ASM_SGI_HEART_H
#define __ASM_SGI_HEART_H
#include <linux/types.h>
#include <linux/time.h>
/*
* There are 8 DIMM slots on an IP30 system
* board, which are grouped into four banks
*/
#define HEART_MEMORY_BANKS 4
/* HEART can support up to four CPUs */
#define HEART_MAX_CPUS 4
#define HEART_XKPHYS_BASE ((void *)(IO_BASE | 0x000000000ff00000ULL))
/**
* struct ip30_heart_regs - struct that maps IP30 HEART registers.
* @mode: HEART_MODE - Purpose Unknown, machine reset called from here.
* @sdram_mode: HEART_SDRAM_MODE - purpose unknown.
* @mem_refresh: HEART_MEM_REF - purpose unknown.
* @mem_req_arb: HEART_MEM_REQ_ARB - purpose unknown.
* @mem_cfg.q: union for 64bit access to HEART_MEMCFG - 4x 64bit registers.
* @mem_cfg.l: union for 32bit access to HEART_MEMCFG - 8x 32bit registers.
* @fc_mode: HEART_FC_MODE - Purpose Unknown, possibly for GFX flow control.
* @fc_timer_limit: HEART_FC_TIMER_LIMIT - purpose unknown.
* @fc_addr: HEART_FC0_ADDR, HEART_FC1_ADDR - purpose unknown.
* @fc_credit_cnt: HEART_FC0_CR_CNT, HEART_FC1_CR_CNT - purpose unknown.
* @fc_timer: HEART_FC0_TIMER, HEART_FC1_TIMER - purpose unknown.
* @status: HEART_STATUS - HEART status information.
* @bus_err_addr: HEART_BERR_ADDR - likely contains addr of recent SIGBUS.
* @bus_err_misc: HEART_BERR_MISC - purpose unknown.
* @mem_err_addr: HEART_MEMERR_ADDR - likely contains addr of recent mem err.
* @mem_err_data: HEART_MEMERR_DATA - purpose unknown.
* @piur_acc_err: HEART_PIUR_ACC_ERR - likely for access err to HEART regs.
* @mlan_clock_div: HEART_MLAN_CLK_DIV - MicroLAN clock divider.
* @mlan_ctrl: HEART_MLAN_CTL - MicroLAN control.
* @__pad0: 0x0f40 bytes of padding -> next HEART register 0x01000.
* @undefined: Undefined/diag register, write to it triggers PIUR_ACC_ERR.
* @__pad1: 0xeff8 bytes of padding -> next HEART register 0x10000.
* @imr: HEART_IMR0 to HEART_IMR3 - per-cpu interrupt mask register.
* @set_isr: HEART_SET_ISR - set interrupt status register.
* @clear_isr: HEART_CLR_ISR - clear interrupt status register.
* @isr: HEART_ISR - interrupt status register (read-only).
* @imsr: HEART_IMSR - purpose unknown.
* @cause: HEART_CAUSE - HEART cause information.
* @__pad2: 0xffb8 bytes of padding -> next HEART register 0x20000.
* @count: HEART_COUNT - 52-bit counter.
* @__pad3: 0xfff8 bytes of padding -> next HEART register 0x30000.
* @compare: HEART_COMPARE - 24-bit compare.
* @__pad4: 0xfff8 bytes of padding -> next HEART register 0x40000.
* @trigger: HEART_TRIGGER - purpose unknown.
* @__pad5: 0xfff8 bytes of padding -> next HEART register 0x50000.
* @cpuid: HEART_PRID - contains CPU ID of CPU currently accessing HEART.
* @__pad6: 0xfff8 bytes of padding -> next HEART register 0x60000.
* @sync: HEART_SYNC - purpose unknown.
*
* HEART is the main system controller ASIC for IP30 system. It incorporates
* a memory controller, interrupt status/cause/set/clear management, basic
* timer with count/compare, and other functionality. For Linux, not all of
* HEART's functions are fully understood.
*
* Implementation note: All HEART registers are 64bits-wide, but the mem_cfg
* register only reports correct values if queried in 32bits. Hence the need
* for a union. Even though mem_cfg.l has 8 array slots, we only ever query
* up to 4 of those. IP30 has 8 DIMM slots arranged into 4 banks, w/ 2 DIMMs
* per bank. Each 32bit read accesses one of these banks. Perhaps HEART was
* designed to address up to 8 banks (16 DIMMs)? We may never know.
*/
struct ip30_heart_regs { /* 0x0ff00000 */
u64 mode; /* + 0x00000 */
/* Memory */
u64 sdram_mode; /* + 0x00008 */
u64 mem_refresh; /* + 0x00010 */
u64 mem_req_arb; /* + 0x00018 */
union {
u64 q[HEART_MEMORY_BANKS]; /* readq() */
u32 l[HEART_MEMORY_BANKS * 2]; /* readl() */
} mem_cfg; /* + 0x00020 */
/* Flow control (gfx?) */
u64 fc_mode; /* + 0x00040 */
u64 fc_timer_limit; /* + 0x00048 */
u64 fc_addr[2]; /* + 0x00050 */
u64 fc_credit_cnt[2]; /* + 0x00060 */
u64 fc_timer[2]; /* + 0x00070 */
/* Status */
u64 status; /* + 0x00080 */
/* Bus error */
u64 bus_err_addr; /* + 0x00088 */
u64 bus_err_misc; /* + 0x00090 */
/* Memory error */
u64 mem_err_addr; /* + 0x00098 */
u64 mem_err_data; /* + 0x000a0 */
/* Misc */
u64 piur_acc_err; /* + 0x000a8 */
u64 mlan_clock_div; /* + 0x000b0 */
u64 mlan_ctrl; /* + 0x000b8 */
u64 __pad0[0x01e8]; /* + 0x000c0 + 0x0f40 */
/* Undefined */
u64 undefined; /* + 0x01000 */
u64 __pad1[0x1dff]; /* + 0x01008 + 0xeff8 */
/* Interrupts */
u64 imr[HEART_MAX_CPUS]; /* + 0x10000 */
u64 set_isr; /* + 0x10020 */
u64 clear_isr; /* + 0x10028 */
u64 isr; /* + 0x10030 */
u64 imsr; /* + 0x10038 */
u64 cause; /* + 0x10040 */
u64 __pad2[0x1ff7]; /* + 0x10048 + 0xffb8 */
/* Timer */
u64 count; /* + 0x20000 */
u64 __pad3[0x1fff]; /* + 0x20008 + 0xfff8 */
u64 compare; /* + 0x30000 */
u64 __pad4[0x1fff]; /* + 0x30008 + 0xfff8 */
u64 trigger; /* + 0x40000 */
u64 __pad5[0x1fff]; /* + 0x40008 + 0xfff8 */
/* Misc */
u64 cpuid; /* + 0x50000 */
u64 __pad6[0x1fff]; /* + 0x50008 + 0xfff8 */
u64 sync; /* + 0x60000 */
};
/* For timer-related bits. */
#define HEART_NS_PER_CYCLE 80
#define HEART_CYCLES_PER_SEC (NSEC_PER_SEC / HEART_NS_PER_CYCLE)
/*
* XXX: Everything below this comment will either go away or be cleaned
* up to fit in better with Linux. A lot of the bit definitions for
* HEART were derived from IRIX's sys/RACER/heart.h header file.
*/
/* HEART Masks */
#define HEART_ATK_MASK 0x0007ffffffffffff /* HEART attack mask */
#define HEART_ACK_ALL_MASK 0xffffffffffffffff /* Ack everything */
#define HEART_CLR_ALL_MASK 0x0000000000000000 /* Clear all */
#define HEART_BR_ERR_MASK 0x7ff8000000000000 /* BRIDGE error mask */
#define HEART_CPU0_ERR_MASK 0x8ff8000000000000 /* CPU0 error mask */
#define HEART_CPU1_ERR_MASK 0x97f8000000000000 /* CPU1 error mask */
#define HEART_CPU2_ERR_MASK 0xa7f8000000000000 /* CPU2 error mask */
#define HEART_CPU3_ERR_MASK 0xc7f8000000000000 /* CPU3 error mask */
#define HEART_ERR_MASK 0x1ff /* HEART error mask */
#define HEART_ERR_MASK_START 51 /* HEART error start */
#define HEART_ERR_MASK_END 63 /* HEART error end */
/* Bits in the HEART_MODE register. */
#define HM_PROC_DISABLE_SHFT 60
#define HM_PROC_DISABLE_MSK (0xfUL << HM_PROC_DISABLE_SHFT)
#define HM_PROC_DISABLE(x) (0x1UL << (x) + HM_PROC_DISABLE_SHFT)
#define HM_MAX_PSR (0x7UL << 57)
#define HM_MAX_IOSR (0x7UL << 54)
#define HM_MAX_PEND_IOSR (0x7UL << 51)
#define HM_TRIG_SRC_SEL_MSK (0x7UL << 48)
#define HM_TRIG_HEART_EXC (0x0UL << 48)
#define HM_TRIG_REG_BIT (0x1UL << 48)
#define HM_TRIG_SYSCLK (0x2UL << 48)
#define HM_TRIG_MEMCLK_2X (0x3UL << 48)
#define HM_TRIG_MEMCLK (0x4UL << 48)
#define HM_TRIG_IOCLK (0x5UL << 48)
#define HM_PIU_TEST_MODE (0xfUL << 40)
#define HM_GP_FLAG_MSK (0xfUL << 36)
#define HM_GP_FLAG(x) BIT((x) + 36)
#define HM_MAX_PROC_HYST (0xfUL << 32)
#define HM_LLP_WRST_AFTER_RST BIT(28)
#define HM_LLP_LINK_RST BIT(27)
#define HM_LLP_WARM_RST BIT(26)
#define HM_COR_ECC_LCK BIT(25)
#define HM_REDUCED_PWR BIT(24)
#define HM_COLD_RST BIT(23)
#define HM_SW_RST BIT(22)
#define HM_MEM_FORCE_WR BIT(21)
#define HM_DB_ERR_GEN BIT(20)
#define HM_SB_ERR_GEN BIT(19)
#define HM_CACHED_PIO_EN BIT(18)
#define HM_CACHED_PROM_EN BIT(17)
#define HM_PE_SYS_COR_ERE BIT(16)
#define HM_GLOBAL_ECC_EN BIT(15)
#define HM_IO_COH_EN BIT(14)
#define HM_INT_EN BIT(13)
#define HM_DATA_CHK_EN BIT(12)
#define HM_REF_EN BIT(11)
#define HM_BAD_SYSWR_ERE BIT(10)
#define HM_BAD_SYSRD_ERE BIT(9)
#define HM_SYSSTATE_ERE BIT(8)
#define HM_SYSCMD_ERE BIT(7)
#define HM_NCOR_SYS_ERE BIT(6)
#define HM_COR_SYS_ERE BIT(5)
#define HM_DATA_ELMNT_ERE BIT(4)
#define HM_MEM_ADDR_PROC_ERE BIT(3)
#define HM_MEM_ADDR_IO_ERE BIT(2)
#define HM_NCOR_MEM_ERE BIT(1)
#define HM_COR_MEM_ERE BIT(0)
/* Bits in the HEART_MEM_REF register. */
#define HEART_MEMREF_REFS(x) ((0xfUL & (x)) << 16)
#define HEART_MEMREF_PERIOD(x) ((0xffffUL & (x)))
#define HEART_MEMREF_REFS_VAL HEART_MEMREF_REFS(8)
#define HEART_MEMREF_PERIOD_VAL HEART_MEMREF_PERIOD(0x4000)
#define HEART_MEMREF_VAL (HEART_MEMREF_REFS_VAL | \
HEART_MEMREF_PERIOD_VAL)
/* Bits in the HEART_MEM_REQ_ARB register. */
#define HEART_MEMARB_IODIS (1 << 20)
#define HEART_MEMARB_MAXPMWRQS (15 << 16)
#define HEART_MEMARB_MAXPMRRQS (15 << 12)
#define HEART_MEMARB_MAXPMRQS (15 << 8)
#define HEART_MEMARB_MAXRRRQS (15 << 4)
#define HEART_MEMARB_MAXGBRRQS (15)
/* Bits in the HEART_MEMCFG<x> registers. */
#define HEART_MEMCFG_VALID 0x80000000 /* Bank is valid */
#define HEART_MEMCFG_DENSITY 0x01c00000 /* Mem density */
#define HEART_MEMCFG_SIZE_MASK 0x003f0000 /* Mem size mask */
#define HEART_MEMCFG_ADDR_MASK 0x000001ff /* Base addr mask */
#define HEART_MEMCFG_SIZE_SHIFT 16 /* Mem size shift */
#define HEART_MEMCFG_DENSITY_SHIFT 22 /* Density Shift */
#define HEART_MEMCFG_UNIT_SHIFT 25 /* Unit Shift, 32MB */
/* Bits in the HEART_STATUS register */
#define HEART_STAT_HSTL_SDRV BIT(14)
#define HEART_STAT_FC_CR_OUT(x) BIT((x) + 12)
#define HEART_STAT_DIR_CNNCT BIT(11)
#define HEART_STAT_TRITON BIT(10)
#define HEART_STAT_R4K BIT(9)
#define HEART_STAT_BIG_ENDIAN BIT(8)
#define HEART_STAT_PROC_SHFT 4
#define HEART_STAT_PROC_MSK (0xfUL << HEART_STAT_PROC_SHFT)
#define HEART_STAT_PROC_ACTIVE(x) (0x1UL << ((x) + HEART_STAT_PROC_SHFT))
#define HEART_STAT_WIDGET_ID 0xf
/* Bits in the HEART_CAUSE register */
#define HC_PE_SYS_COR_ERR_MSK (0xfUL << 60)
#define HC_PE_SYS_COR_ERR(x) BIT((x) + 60)
#define HC_PIOWDB_OFLOW BIT(44)
#define HC_PIORWRB_OFLOW BIT(43)
#define HC_PIUR_ACC_ERR BIT(42)
#define HC_BAD_SYSWR_ERR BIT(41)
#define HC_BAD_SYSRD_ERR BIT(40)
#define HC_SYSSTATE_ERR_MSK (0xfUL << 36)
#define HC_SYSSTATE_ERR(x) BIT((x) + 36)
#define HC_SYSCMD_ERR_MSK (0xfUL << 32)
#define HC_SYSCMD_ERR(x) BIT((x) + 32)
#define HC_NCOR_SYSAD_ERR_MSK (0xfUL << 28)
#define HC_NCOR_SYSAD_ERR(x) BIT((x) + 28)
#define HC_COR_SYSAD_ERR_MSK (0xfUL << 24)
#define HC_COR_SYSAD_ERR(x) BIT((x) + 24)
#define HC_DATA_ELMNT_ERR_MSK (0xfUL << 20)
#define HC_DATA_ELMNT_ERR(x) BIT((x) + 20)
#define HC_WIDGET_ERR BIT(16)
#define HC_MEM_ADDR_ERR_PROC_MSK (0xfUL << 4)
#define HC_MEM_ADDR_ERR_PROC(x) BIT((x) + 4)
#define HC_MEM_ADDR_ERR_IO BIT(2)
#define HC_NCOR_MEM_ERR BIT(1)
#define HC_COR_MEM_ERR BIT(0)
extern struct ip30_heart_regs __iomem *heart_regs;
#define heart_read ____raw_readq
#define heart_write ____raw_writeq
#endif /* __ASM_SGI_HEART_H */

View File

@ -1,48 +0,0 @@
/*
* 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.
*
* sgi.h: Definitions specific to SGI machines.
*
* Copyright (C) 1996 David S. Miller (dm@sgi.com)
*/
#ifndef _ASM_SGI_SGI_H
#define _ASM_SGI_SGI_H
/* UP=UniProcessor MP=MultiProcessor(capable) */
enum sgi_mach {
ip4, /* R2k UP */
ip5, /* R2k MP */
ip6, /* R3k UP */
ip7, /* R3k MP */
ip9, /* R3k UP */
ip12, /* R3kA UP, Indigo */
ip15, /* R3kA MP */
ip17, /* R4K UP */
ip19, /* R4K MP */
ip20, /* R4K UP, Indigo */
ip21, /* R8k/TFP MP */
ip22, /* R4x00 UP, Indy, Indigo2 */
ip25, /* R10k MP */
ip26, /* R8k/TFP UP, Indigo2 */
ip27, /* R10k MP, R12k MP, R14k MP, Origin 200/2k, Onyx2 */
ip28, /* R10k UP, Indigo2 Impact R10k */
ip30, /* R10k MP, R12k MP, R14k MP, Octane */
ip32, /* R5k UP, RM5200 UP, RM7k UP, R10k UP, R12k UP, O2 */
ip35, /* R14k MP, R16k MP, Origin 300/3k, Onyx3, Fuel, Tezro */
};
extern enum sgi_mach sgimach;
extern void sgi_sysinit(void);
/* Many I/O space registers are byte sized and are contained within
* one byte per word, specifically the MSB, this macro helps out.
*/
#ifdef __MIPSEL__
#define SGI_MSB(regaddr) (regaddr)
#else
#define SGI_MSB(regaddr) ((regaddr) | 0x3)
#endif
#endif /* _ASM_SGI_SGI_H */

View File

@ -15,14 +15,6 @@
#include <asm/sgiarcs.h>
extern struct linux_romvec *romvec;
extern int prom_argc;
extern LONG *_prom_argv, *_prom_envp;
/* A 32-bit ARC PROM pass arguments and environment as 32-bit pointer.
These macros take care of sign extension. */
#define prom_argv(index) ((char *) (long) _prom_argv[(index)])
#define prom_argc(index) ((char *) (long) _prom_argc[(index)])
extern int prom_flags;
@ -47,12 +39,6 @@ extern void prom_meminit(void);
/* PROM device tree library routines. */
#define PROM_NULL_COMPONENT ((pcomponent *) 0)
/* Get sibling component of THIS. */
extern pcomponent *ArcGetPeer(pcomponent *this);
/* Get child component of THIS. */
extern pcomponent *ArcGetChild(pcomponent *this);
/* This is called at prom_init time to identify the
* ARC architecture we are running on
*/
@ -60,22 +46,16 @@ extern void prom_identify_arch(void);
/* Environment variable routines. */
extern PCHAR ArcGetEnvironmentVariable(PCHAR name);
extern LONG ArcSetEnvironmentVariable(PCHAR name, PCHAR value);
/* ARCS command line parsing. */
extern void prom_init_cmdline(void);
extern void prom_init_cmdline(int argc, LONG *argv);
/* File operations. */
extern LONG ArcRead(ULONG fd, PVOID buf, ULONG num, PULONG cnt);
extern LONG ArcWrite(ULONG fd, PVOID buf, ULONG num, PULONG cnt);
/* Misc. routines. */
extern VOID ArcHalt(VOID) __noreturn;
extern VOID ArcPowerDown(VOID) __noreturn;
extern VOID ArcRestart(VOID) __noreturn;
extern VOID ArcReboot(VOID) __noreturn;
extern VOID ArcEnterInteractiveMode(VOID) __noreturn;
extern VOID ArcFlushAllCaches(VOID);
extern DISPLAY_STATUS *ArcGetDisplayStatus(ULONG FileID);
#endif /* _ASM_SGIALIB_H */

View File

@ -12,6 +12,8 @@
#ifndef _ASM_SGIARCS_H
#define _ASM_SGIARCS_H
#include <linux/kernel.h>
#include <asm/types.h>
#include <asm/fw/arc/types.h>
@ -368,110 +370,65 @@ struct linux_smonblock {
#if defined(CONFIG_64BIT) && defined(CONFIG_FW_ARC32)
#define __arc_clobbers \
"$2", "$3" /* ... */, "$8", "$9", "$10", "$11", \
"$12", "$13", "$14", "$15", "$16", "$24", "$25", "$31"
extern long call_o32(long vec, void *stack, ...);
extern u64 o32_stk[4096];
#define O32_STK (&o32_stk[ARRAY_SIZE(o32_stk)])
#define ARC_CALL0(dest) \
({ long __res; \
long __vec = (long) romvec->dest; \
__asm__ __volatile__( \
"dsubu\t$29, 32\n\t" \
"jalr\t%1\n\t" \
"daddu\t$29, 32\n\t" \
"move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \
: "1" (__vec) \
: __arc_clobbers, "$4", "$5", "$6", "$7"); \
(unsigned long) __res; \
__res = call_o32(__vec, O32_STK); \
__res; \
})
#define ARC_CALL1(dest, a1) \
({ long __res; \
register signed int __a1 __asm__("$4") = (int) (long) (a1); \
int __a1 = (int) (long) (a1); \
long __vec = (long) romvec->dest; \
__asm__ __volatile__( \
"dsubu\t$29, 32\n\t" \
"jalr\t%1\n\t" \
"daddu\t$29, 32\n\t" \
"move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \
: "1" (__vec), "r" (__a1) \
: __arc_clobbers, "$5", "$6", "$7"); \
(unsigned long) __res; \
__res = call_o32(__vec, O32_STK, __a1); \
__res; \
})
#define ARC_CALL2(dest, a1, a2) \
({ long __res; \
register signed int __a1 __asm__("$4") = (int) (long) (a1); \
register signed int __a2 __asm__("$5") = (int) (long) (a2); \
int __a1 = (int) (long) (a1); \
int __a2 = (int) (long) (a2); \
long __vec = (long) romvec->dest; \
__asm__ __volatile__( \
"dsubu\t$29, 32\n\t" \
"jalr\t%1\n\t" \
"daddu\t$29, 32\n\t" \
"move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \
: "1" (__vec), "r" (__a1), "r" (__a2) \
: __arc_clobbers, "$6", "$7"); \
__res = call_o32(__vec, O32_STK, __a1, __a2); \
__res; \
})
#define ARC_CALL3(dest, a1, a2, a3) \
({ long __res; \
register signed int __a1 __asm__("$4") = (int) (long) (a1); \
register signed int __a2 __asm__("$5") = (int) (long) (a2); \
register signed int __a3 __asm__("$6") = (int) (long) (a3); \
int __a1 = (int) (long) (a1); \
int __a2 = (int) (long) (a2); \
int __a3 = (int) (long) (a3); \
long __vec = (long) romvec->dest; \
__asm__ __volatile__( \
"dsubu\t$29, 32\n\t" \
"jalr\t%1\n\t" \
"daddu\t$29, 32\n\t" \
"move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \
: "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3) \
: __arc_clobbers, "$7"); \
__res = call_o32(__vec, O32_STK, __a1, __a2, __a3); \
__res; \
})
#define ARC_CALL4(dest, a1, a2, a3, a4) \
({ long __res; \
register signed int __a1 __asm__("$4") = (int) (long) (a1); \
register signed int __a2 __asm__("$5") = (int) (long) (a2); \
register signed int __a3 __asm__("$6") = (int) (long) (a3); \
register signed int __a4 __asm__("$7") = (int) (long) (a4); \
int __a1 = (int) (long) (a1); \
int __a2 = (int) (long) (a2); \
int __a3 = (int) (long) (a3); \
int __a4 = (int) (long) (a4); \
long __vec = (long) romvec->dest; \
__asm__ __volatile__( \
"dsubu\t$29, 32\n\t" \
"jalr\t%1\n\t" \
"daddu\t$29, 32\n\t" \
"move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \
: "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3), \
"r" (__a4) \
: __arc_clobbers); \
__res = call_o32(__vec, O32_STK, __a1, __a2, __a3, __a4); \
__res; \
})
#define ARC_CALL5(dest, a1, a2, a3, a4, a5) \
#define ARC_CALL5(dest, a1, a2, a3, a4, a5) \
({ long __res; \
register signed int __a1 __asm__("$4") = (int) (long) (a1); \
register signed int __a2 __asm__("$5") = (int) (long) (a2); \
register signed int __a3 __asm__("$6") = (int) (long) (a3); \
register signed int __a4 __asm__("$7") = (int) (long) (a4); \
register signed int __a5 = (int) (long) (a5); \
int __a1 = (int) (long) (a1); \
int __a2 = (int) (long) (a2); \
int __a3 = (int) (long) (a3); \
int __a4 = (int) (long) (a4); \
int __a5 = (int) (long) (a5); \
long __vec = (long) romvec->dest; \
__asm__ __volatile__( \
"dsubu\t$29, 32\n\t" \
"sw\t%7, 16($29)\n\t" \
"jalr\t%1\n\t" \
"daddu\t$29, 32\n\t" \
"move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \
: "1" (__vec), \
"r" (__a1), "r" (__a2), "r" (__a3), "r" (__a4), \
"r" (__a5) \
: __arc_clobbers); \
__res = call_o32(__vec, O32_STK, __a1, __a2, __a3, __a4, __a5); \
__res; \
})

View File

@ -26,7 +26,7 @@
#if defined(CONFIG_SGI_IP27)
#define HUB_NIC_ADDR(_cpuid) \
REMOTE_HUB_ADDR(COMPACT_TO_NASID_NODEID(cpu_to_node(_cpuid)), \
REMOTE_HUB_ADDR(cpu_to_node(_cpuid), \
MD_MLAN_CTL)
#endif

View File

@ -19,44 +19,13 @@
#define cputonasid(cpu) (sn_cpu_info[(cpu)].p_nasid)
#define cputoslice(cpu) (sn_cpu_info[(cpu)].p_slice)
#define makespnum(_nasid, _slice) \
(((_nasid) << CPUS_PER_NODE_SHFT) | (_slice))
#define INVALID_NASID (nasid_t)-1
#define INVALID_CNODEID (cnodeid_t)-1
#define INVALID_PNODEID (pnodeid_t)-1
#define INVALID_MODULE (moduleid_t)-1
#define INVALID_PARTID (partid_t)-1
extern nasid_t get_nasid(void);
extern cnodeid_t get_cpu_cnode(cpuid_t);
extern int get_cpu_slice(cpuid_t);
/*
* NO ONE should access these arrays directly. The only reason we refer to
* them here is to avoid the procedure call that would be required in the
* macros below. (Really want private data members here :-)
*/
extern cnodeid_t nasid_to_compact_node[MAX_NASIDS];
extern nasid_t compact_to_nasid_node[MAX_COMPACT_NODES];
/*
* These macros are used by various parts of the kernel to convert
* between the three different kinds of node numbering. At least some
* of them may change to procedure calls in the future, but the macros
* will continue to work. Don't use the arrays above directly.
*/
#define NASID_TO_REGION(nnode) \
((nnode) >> \
(is_fine_dirmode() ? NASID_TO_FINEREG_SHFT : NASID_TO_COARSEREG_SHFT))
extern cnodeid_t nasid_to_compact_node[MAX_NASIDS];
extern nasid_t compact_to_nasid_node[MAX_COMPACT_NODES];
extern cnodeid_t cpuid_to_compact_node[MAXCPUS];
#define NASID_TO_COMPACT_NODEID(nnode) (nasid_to_compact_node[nnode])
#define COMPACT_TO_NASID_NODEID(cnode) (compact_to_nasid_node[cnode])
#define CPUID_TO_COMPACT_NODEID(cpu) (cpuid_to_compact_node[(cpu)])
#endif /* _ASM_SN_ARCH_H */

View File

@ -60,9 +60,7 @@ typedef struct gda {
/* Pointer to a mask of nodes with copies
* of the kernel. */
char g_padding[56]; /* pad out to 128 bytes */
nasid_t g_nasidtable[MAX_COMPACT_NODES]; /* NASID of each node,
* indexed by cnodeid.
*/
nasid_t g_nasidtable[MAX_NUMNODES]; /* NASID of each node */
} gda_t;
#define GDA ((gda_t*) GDA_ADDR(get_nasid()))

View File

@ -10,8 +10,8 @@
#include <asm/xtalk/xtalk.h>
/* ip27-hubio.c */
extern unsigned long hub_pio_map(cnodeid_t cnode, xwidgetnum_t widget,
extern unsigned long hub_pio_map(nasid_t nasid, xwidgetnum_t widget,
unsigned long xtalk_addr, size_t size);
extern void hub_pio_init(cnodeid_t cnode);
extern void hub_pio_init(nasid_t nasid);
#endif /* __ASM_SN_HUB_H */

View File

@ -590,4 +590,13 @@ struct ioc3_etxd {
#define MIDR_DATA_MASK 0x0000ffff
/* subsystem IDs supplied by card detection in pci-xtalk-bridge */
#define IOC3_SUBSYS_IP27_BASEIO6G 0xc300
#define IOC3_SUBSYS_IP27_MIO 0xc301
#define IOC3_SUBSYS_IP27_BASEIO 0xc302
#define IOC3_SUBSYS_IP29_SYSBOARD 0xc303
#define IOC3_SUBSYS_IP30_SYSBOARD 0xc304
#define IOC3_SUBSYS_MENET 0xc305
#define IOC3_SUBSYS_MENET4 0xc306
#endif /* MIPS_SN_IOC3_H */

View File

@ -37,10 +37,10 @@
#define MAPPED_KERN_RO_TO_PHYS(x) \
((unsigned long)MAPPED_ADDR_RO_TO_PHYS(x) | \
MAPPED_KERN_RO_PHYSBASE(get_compact_nodeid()))
MAPPED_KERN_RO_PHYSBASE(get_nasid()))
#define MAPPED_KERN_RW_TO_PHYS(x) \
((unsigned long)MAPPED_ADDR_RW_TO_PHYS(x) | \
MAPPED_KERN_RW_PHYSBASE(get_compact_nodeid()))
MAPPED_KERN_RW_PHYSBASE(get_nasid()))
#else /* CONFIG_MAPPED_KERNEL */

View File

@ -12,25 +12,11 @@
#define _ASM_SN_SN0_ARCH_H
#ifndef SN0XXL /* 128 cpu SMP max */
/*
* This is the maximum number of nodes that can be part of a kernel.
* Effectively, it's the maximum number of compact node ids (cnodeid_t).
*/
#define MAX_COMPACT_NODES 64
/*
* MAXCPUS refers to the maximum number of CPUs in a single kernel.
* This is not necessarily the same as MAXNODES * CPUS_PER_NODE
*/
#define MAXCPUS 128
#else /* SN0XXL system */
#define MAX_COMPACT_NODES 128
#define MAXCPUS 256
#endif /* SN0XXL */
#define MAXCPUS (MAX_NUMNODES * CPUS_PER_NODE)
/*
* This is the maximum number of NASIDS that can be present in a system.
@ -66,7 +52,5 @@
#define SLOT_MIN_MEM_SIZE (32*1024*1024)
#define CPUS_PER_NODE 2 /* CPUs on a single hub */
#define CPUS_PER_NODE_SHFT 1 /* Bits to shift in the node number */
#define CPUS_PER_SUBNODE 2 /* CPUs on a single hub PI */
#endif /* _ASM_SN_SN0_ARCH_H */

View File

@ -7,14 +7,13 @@
extern nasid_t master_nasid;
extern void cpu_node_probe(void);
extern cnodeid_t get_compact_nodeid(void);
extern void hub_rtc_init(cnodeid_t);
extern void hub_rtc_init(nasid_t nasid);
extern void cpu_time_init(void);
extern void per_cpu_init(void);
extern void install_cpu_nmi_handler(int slice);
extern void install_ipi(void);
extern void setup_replication_mask(void);
extern void replicate_kernel_text(void);
extern unsigned long node_getfirstfree(cnodeid_t);
extern unsigned long node_getfirstfree(nasid_t nasid);
#endif /* __ASM_SN_SN_PRIVATE_H */

View File

@ -12,13 +12,9 @@
#include <linux/types.h>
typedef unsigned long cpuid_t;
typedef unsigned long cnodemask_t;
typedef signed short nasid_t; /* node id in numa-as-id space */
typedef signed short cnodeid_t; /* node id in compact-id space */
typedef signed char partid_t; /* partition ID type */
typedef signed short moduleid_t; /* user-visible module number type */
typedef signed short cmoduleid_t; /* kernel compact module id type */
typedef unsigned char clusterid_t; /* Clusterid of the cell */
typedef dev_t vertex_hdl_t; /* hardware graph vertex handle */

View File

@ -10,127 +10,6 @@
#ifndef _ASM_STRING_H
#define _ASM_STRING_H
/*
* Most of the inline functions are rather naive implementations so I just
* didn't bother updating them for 64-bit ...
*/
#ifdef CONFIG_32BIT
#ifndef IN_STRING_C
#define __HAVE_ARCH_STRCPY
static __inline__ char *strcpy(char *__dest, __const__ char *__src)
{
char *__xdest = __dest;
__asm__ __volatile__(
".set\tnoreorder\n\t"
".set\tnoat\n"
"1:\tlbu\t$1,(%1)\n\t"
"addiu\t%1,1\n\t"
"sb\t$1,(%0)\n\t"
"bnez\t$1,1b\n\t"
"addiu\t%0,1\n\t"
".set\tat\n\t"
".set\treorder"
: "=r" (__dest), "=r" (__src)
: "0" (__dest), "1" (__src)
: "memory");
return __xdest;
}
#define __HAVE_ARCH_STRNCPY
static __inline__ char *strncpy(char *__dest, __const__ char *__src, size_t __n)
{
char *__xdest = __dest;
if (__n == 0)
return __xdest;
__asm__ __volatile__(
".set\tnoreorder\n\t"
".set\tnoat\n"
"1:\tlbu\t$1,(%1)\n\t"
"subu\t%2,1\n\t"
"sb\t$1,(%0)\n\t"
"beqz\t$1,2f\n\t"
"addiu\t%0,1\n\t"
"bnez\t%2,1b\n\t"
"addiu\t%1,1\n"
"2:\n\t"
".set\tat\n\t"
".set\treorder"
: "=r" (__dest), "=r" (__src), "=r" (__n)
: "0" (__dest), "1" (__src), "2" (__n)
: "memory");
return __xdest;
}
#define __HAVE_ARCH_STRCMP
static __inline__ int strcmp(__const__ char *__cs, __const__ char *__ct)
{
int __res;
__asm__ __volatile__(
".set\tnoreorder\n\t"
".set\tnoat\n\t"
"lbu\t%2,(%0)\n"
"1:\tlbu\t$1,(%1)\n\t"
"addiu\t%0,1\n\t"
"bne\t$1,%2,2f\n\t"
"addiu\t%1,1\n\t"
"bnez\t%2,1b\n\t"
"lbu\t%2,(%0)\n\t"
#if defined(CONFIG_CPU_R3000)
"nop\n\t"
#endif
"move\t%2,$1\n"
"2:\tsubu\t%2,$1\n"
"3:\t.set\tat\n\t"
".set\treorder"
: "=r" (__cs), "=r" (__ct), "=r" (__res)
: "0" (__cs), "1" (__ct));
return __res;
}
#endif /* !defined(IN_STRING_C) */
#define __HAVE_ARCH_STRNCMP
static __inline__ int
strncmp(__const__ char *__cs, __const__ char *__ct, size_t __count)
{
int __res;
__asm__ __volatile__(
".set\tnoreorder\n\t"
".set\tnoat\n"
"1:\tlbu\t%3,(%0)\n\t"
"beqz\t%2,2f\n\t"
"lbu\t$1,(%1)\n\t"
"subu\t%2,1\n\t"
"bne\t$1,%3,3f\n\t"
"addiu\t%0,1\n\t"
"bnez\t%3,1b\n\t"
"addiu\t%1,1\n"
"2:\n\t"
#if defined(CONFIG_CPU_R3000)
"nop\n\t"
#endif
"move\t%3,$1\n"
"3:\tsubu\t%3,$1\n\t"
".set\tat\n\t"
".set\treorder"
: "=r" (__cs), "=r" (__ct), "=r" (__count), "=r" (__res)
: "0" (__cs), "1" (__ct), "2" (__count));
return __res;
}
#endif /* CONFIG_32BIT */
#define __HAVE_ARCH_MEMSET
extern void *memset(void *__s, int __c, size_t __count);

View File

@ -0,0 +1,207 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __MIPS_ASM_SYNC_H__
#define __MIPS_ASM_SYNC_H__
/*
* sync types are defined by the MIPS64 Instruction Set documentation in Volume
* II-A of the MIPS Architecture Reference Manual, which can be found here:
*
* https://www.mips.com/?do-download=the-mips64-instruction-set-v6-06
*
* Two types of barrier are provided:
*
* 1) Completion barriers, which ensure that a memory operation has actually
* completed & often involve stalling the CPU pipeline to do so.
*
* 2) Ordering barriers, which only ensure that affected memory operations
* won't be reordered in the CPU pipeline in a manner that violates the
* restrictions imposed by the barrier.
*
* Ordering barriers can be more efficient than completion barriers, since:
*
* a) Ordering barriers only require memory access instructions which preceed
* them in program order (older instructions) to reach a point in the
* load/store datapath beyond which reordering is not possible before
* allowing memory access instructions which follow them (younger
* instructions) to be performed. That is, older instructions don't
* actually need to complete - they just need to get far enough that all
* other coherent CPUs will observe their completion before they observe
* the effects of younger instructions.
*
* b) Multiple variants of ordering barrier are provided which allow the
* effects to be restricted to different combinations of older or younger
* loads or stores. By way of example, if we only care that stores older
* than a barrier are observed prior to stores that are younger than a
* barrier & don't care about the ordering of loads then the 'wmb'
* ordering barrier can be used. Limiting the barrier's effects to stores
* allows loads to continue unaffected & potentially allows the CPU to
* make progress faster than if younger loads had to wait for older stores
* to complete.
*/
/*
* No sync instruction at all; used to allow code to nullify the effect of the
* __SYNC() macro without needing lots of #ifdefery.
*/
#define __SYNC_none -1
/*
* A full completion barrier; all memory accesses appearing prior to this sync
* instruction in program order must complete before any memory accesses
* appearing after this sync instruction in program order.
*/
#define __SYNC_full 0x00
/*
* For now we use a full completion barrier to implement all sync types, until
* we're satisfied that lightweight ordering barriers defined by MIPSr6 are
* sufficient to uphold our desired memory model.
*/
#define __SYNC_aq __SYNC_full
#define __SYNC_rl __SYNC_full
#define __SYNC_mb __SYNC_full
/*
* ...except on Cavium Octeon CPUs, which have been using the 'wmb' ordering
* barrier since 2010 & omit 'rmb' barriers because the CPUs don't perform
* speculative reads.
*/
#ifdef CONFIG_CPU_CAVIUM_OCTEON
# define __SYNC_rmb __SYNC_none
# define __SYNC_wmb 0x04
#else
# define __SYNC_rmb __SYNC_full
# define __SYNC_wmb __SYNC_full
#endif
/*
* A GINV sync is a little different; it doesn't relate directly to loads or
* stores, but instead causes synchronization of an icache or TLB global
* invalidation operation triggered by the ginvi or ginvt instructions
* respectively. In cases where we need to know that a ginvi or ginvt operation
* has been performed by all coherent CPUs, we must issue a sync instruction of
* this type. Once this instruction graduates all coherent CPUs will have
* observed the invalidation.
*/
#define __SYNC_ginv 0x14
/* Trivial; indicate that we always need this sync instruction. */
#define __SYNC_always (1 << 0)
/*
* Indicate that we need this sync instruction only on systems with weakly
* ordered memory access. In general this is most MIPS systems, but there are
* exceptions which provide strongly ordered memory.
*/
#ifdef CONFIG_WEAK_ORDERING
# define __SYNC_weak_ordering (1 << 1)
#else
# define __SYNC_weak_ordering 0
#endif
/*
* Indicate that we need this sync instruction only on systems where LL/SC
* don't implicitly provide a memory barrier. In general this is most MIPS
* systems.
*/
#ifdef CONFIG_WEAK_REORDERING_BEYOND_LLSC
# define __SYNC_weak_llsc (1 << 2)
#else
# define __SYNC_weak_llsc 0
#endif
/*
* Some Loongson 3 CPUs have a bug wherein execution of a memory access (load,
* store or prefetch) in between an LL & SC can cause the SC instruction to
* erroneously succeed, breaking atomicity. Whilst it's unusual to write code
* containing such sequences, this bug bites harder than we might otherwise
* expect due to reordering & speculation:
*
* 1) A memory access appearing prior to the LL in program order may actually
* be executed after the LL - this is the reordering case.
*
* In order to avoid this we need to place a memory barrier (ie. a SYNC
* instruction) prior to every LL instruction, in between it and any earlier
* memory access instructions.
*
* This reordering case is fixed by 3A R2 CPUs, ie. 3A2000 models and later.
*
* 2) If a conditional branch exists between an LL & SC with a target outside
* of the LL-SC loop, for example an exit upon value mismatch in cmpxchg()
* or similar, then misprediction of the branch may allow speculative
* execution of memory accesses from outside of the LL-SC loop.
*
* In order to avoid this we need a memory barrier (ie. a SYNC instruction)
* at each affected branch target.
*
* This case affects all current Loongson 3 CPUs.
*
* The above described cases cause an error in the cache coherence protocol;
* such that the Invalidate of a competing LL-SC goes 'missing' and SC
* erroneously observes its core still has Exclusive state and lets the SC
* proceed.
*
* Therefore the error only occurs on SMP systems.
*/
#ifdef CONFIG_CPU_LOONGSON3_WORKAROUNDS
# define __SYNC_loongson3_war (1 << 31)
#else
# define __SYNC_loongson3_war 0
#endif
/*
* Some Cavium Octeon CPUs suffer from a bug that causes a single wmb ordering
* barrier to be ineffective, requiring the use of 2 in sequence to provide an
* effective barrier as noted by commit 6b07d38aaa52 ("MIPS: Octeon: Use
* optimized memory barrier primitives."). Here we specify that the affected
* sync instructions should be emitted twice.
*/
#ifdef CONFIG_CPU_CAVIUM_OCTEON
# define __SYNC_rpt(type) (1 + (type == __SYNC_wmb))
#else
# define __SYNC_rpt(type) 1
#endif
/*
* The main event. Here we actually emit a sync instruction of a given type, if
* reason is non-zero.
*
* In future we have the option of emitting entries in a fixups-style table
* here that would allow us to opportunistically remove some sync instructions
* when we detect at runtime that we're running on a CPU that doesn't need
* them.
*/
#ifdef CONFIG_CPU_HAS_SYNC
# define ____SYNC(_type, _reason, _else) \
.if (( _type ) != -1) && ( _reason ); \
.set push; \
.set MIPS_ISA_LEVEL_RAW; \
.rept __SYNC_rpt(_type); \
sync _type; \
.endr; \
.set pop; \
.else; \
_else; \
.endif
#else
# define ____SYNC(_type, _reason, _else)
#endif
/*
* Preprocessor magic to expand macros used as arguments before we insert them
* into assembly code.
*/
#ifdef __ASSEMBLY__
# define ___SYNC(type, reason, else) \
____SYNC(type, reason, else)
#else
# define ___SYNC(type, reason, else) \
__stringify(____SYNC(type, reason, else))
#endif
#define __SYNC(type, reason) \
___SYNC(__SYNC_##type, __SYNC_##reason, )
#define __SYNC_ELSE(type, reason, else) \
___SYNC(__SYNC_##type, __SYNC_##reason, else)
#endif /* __MIPS_ASM_SYNC_H__ */

View File

@ -0,0 +1,77 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __ASM_UNROLL_H__
#define __ASM_UNROLL_H__
/*
* Explicitly unroll a loop, for use in cases where doing so is performance
* critical.
*
* Ideally we'd rely upon the compiler to provide this but there's no commonly
* available means to do so. For example GCC's "#pragma GCC unroll"
* functionality would be ideal but is only available from GCC 8 onwards. Using
* -funroll-loops is an option but GCC tends to make poor choices when
* compiling our string functions. -funroll-all-loops leads to massive code
* bloat, even if only applied to the string functions.
*/
#define unroll(times, fn, ...) do { \
extern void bad_unroll(void) \
__compiletime_error("Unsupported unroll"); \
\
/* \
* We can't unroll if the number of iterations isn't \
* compile-time constant. Unfortunately GCC versions \
* up until 4.6 tend to miss obvious constants & cause \
* this check to fail, even though they go on to \
* generate reasonable code for the switch statement, \
* so we skip the sanity check for those compilers. \
*/ \
BUILD_BUG_ON((CONFIG_GCC_VERSION >= 40700 || \
CONFIG_CLANG_VERSION >= 80000) && \
!__builtin_constant_p(times)); \
\
switch (times) { \
case 32: fn(__VA_ARGS__); /* fall through */ \
case 31: fn(__VA_ARGS__); /* fall through */ \
case 30: fn(__VA_ARGS__); /* fall through */ \
case 29: fn(__VA_ARGS__); /* fall through */ \
case 28: fn(__VA_ARGS__); /* fall through */ \
case 27: fn(__VA_ARGS__); /* fall through */ \
case 26: fn(__VA_ARGS__); /* fall through */ \
case 25: fn(__VA_ARGS__); /* fall through */ \
case 24: fn(__VA_ARGS__); /* fall through */ \
case 23: fn(__VA_ARGS__); /* fall through */ \
case 22: fn(__VA_ARGS__); /* fall through */ \
case 21: fn(__VA_ARGS__); /* fall through */ \
case 20: fn(__VA_ARGS__); /* fall through */ \
case 19: fn(__VA_ARGS__); /* fall through */ \
case 18: fn(__VA_ARGS__); /* fall through */ \
case 17: fn(__VA_ARGS__); /* fall through */ \
case 16: fn(__VA_ARGS__); /* fall through */ \
case 15: fn(__VA_ARGS__); /* fall through */ \
case 14: fn(__VA_ARGS__); /* fall through */ \
case 13: fn(__VA_ARGS__); /* fall through */ \
case 12: fn(__VA_ARGS__); /* fall through */ \
case 11: fn(__VA_ARGS__); /* fall through */ \
case 10: fn(__VA_ARGS__); /* fall through */ \
case 9: fn(__VA_ARGS__); /* fall through */ \
case 8: fn(__VA_ARGS__); /* fall through */ \
case 7: fn(__VA_ARGS__); /* fall through */ \
case 6: fn(__VA_ARGS__); /* fall through */ \
case 5: fn(__VA_ARGS__); /* fall through */ \
case 4: fn(__VA_ARGS__); /* fall through */ \
case 3: fn(__VA_ARGS__); /* fall through */ \
case 2: fn(__VA_ARGS__); /* fall through */ \
case 1: fn(__VA_ARGS__); /* fall through */ \
case 0: break; \
\
default: \
/* \
* Either the iteration count is unreasonable \
* or we need to add more cases above. \
*/ \
bad_unroll(); \
break; \
} \
} while (0)
#endif /* __ASM_UNROLL_H__ */

Some files were not shown because too many files have changed in this diff Show More